Vendor the IO engine from docmost-sync into packages/git-sync/src/engine: - git.ts (VaultGit, execFile shell-out — verbatim) - pull.ts (readExisting, computePullActions, applyPullActions) - push.ts (classifyRenameMoves, computePushActions, applyPushActions, runPush) - settings.ts adapted (pure parseSettings + Settings type; no process.env binding — the server builds Settings from EnvironmentService later), config-errors.ts. CLI main()/import.meta entrypoints dropped (server drives in-process). Client seam: new engine/client.types.ts defines GitSyncClient; pull.ts/push.ts now use Pick<GitSyncClient, ...> instead of the non-vendored DocmostClient. Engine logic byte-identical except a zod4-compat fix in config-errors (zod4 dropped the issue.received==='undefined' signal; match /received undefined/ on the message). Ported the engine unit tests (compute/apply pull+push actions, classify-rename- moves, run-push, settings, config-errors) incl. real-git temp-repo tests: 431 pass / 3 expected-fail (was 314/3). REST/CLI-coupled upstream tests skipped (noted). CJS build clean. No apps/server wiring yet (next step). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2.4 KiB
JavaScript
54 lines
2.4 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.loadSettingsOrExit = loadSettingsOrExit;
|
|
const zod_1 = require("zod");
|
|
// Turn a ZodError from settings validation into a clear, actionable startup
|
|
// message that names the offending env var(s), then exit(1) — no raw stack
|
|
// trace. Mirrors the Python new-project skeleton's load_settings_or_exit.
|
|
// A non-ZodError is left to propagate unchanged.
|
|
function loadSettingsOrExit(factory) {
|
|
try {
|
|
return factory();
|
|
}
|
|
catch (err) {
|
|
if (!(err instanceof zod_1.ZodError))
|
|
throw err;
|
|
const missing = [];
|
|
const invalid = [];
|
|
for (const issue of err.issues) {
|
|
const name = issue.path.length ? String(issue.path[0]) : '?';
|
|
// A missing required variable surfaces as an `invalid_type` issue whose
|
|
// received value was `undefined`. zod 3 exposed `issue.received` directly;
|
|
// zod 4 dropped that field and instead folds it into the message
|
|
// ("expected string, received undefined"). Detect both shapes so the
|
|
// missing-vs-invalid split holds across zod majors. NOTE: an invalid (but
|
|
// present) value uses a different code (invalid_format / invalid_value) or
|
|
// an `invalid_type` message that reports a non-undefined received (e.g.
|
|
// "received NaN" from a coerced number), so neither is misread as missing.
|
|
const i = issue;
|
|
const isMissing = issue.code === 'invalid_type' &&
|
|
(i.received === 'undefined' ||
|
|
/received undefined/i.test(i.message ?? ''));
|
|
if (isMissing)
|
|
missing.push(name);
|
|
else
|
|
invalid.push(`${name}: ${issue.message}`);
|
|
}
|
|
const lines = ['Configuration error in environment / .env:'];
|
|
if (missing.length) {
|
|
lines.push(' Missing required variable(s):');
|
|
for (const n of [...new Set(missing)])
|
|
lines.push(` - ${n}`);
|
|
}
|
|
if (invalid.length) {
|
|
lines.push(' Invalid value(s):');
|
|
for (const item of invalid)
|
|
lines.push(` - ${item}`);
|
|
}
|
|
lines.push('');
|
|
lines.push('Set them in .env (see .env.example) and try again.');
|
|
process.stderr.write(lines.join('\n') + '\n');
|
|
process.exit(1);
|
|
}
|
|
}
|