@estokad/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -0
- package/README.md +85 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +116 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/codegen.d.ts +6 -0
- package/dist/commands/codegen.d.ts.map +1 -0
- package/dist/commands/codegen.js +64 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/diff.d.ts +3 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +66 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +72 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pull.d.ts +3 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +64 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +6 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +92 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +104 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +34 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +55 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +21 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +69 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/diff.d.ts +36 -0
- package/dist/lib/diff.d.ts.map +1 -0
- package/dist/lib/diff.js +191 -0
- package/dist/lib/diff.js.map +1 -0
- package/dist/lib/schemas.d.ts +6 -0
- package/dist/lib/schemas.d.ts.map +1 -0
- package/dist/lib/schemas.js +70 -0
- package/dist/lib/schemas.js.map +1 -0
- package/dist/lib/state.d.ts +4 -0
- package/dist/lib/state.d.ts.map +1 -0
- package/dist/lib/state.js +32 -0
- package/dist/lib/state.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// `estokad push` — load local schemas, compile, send to the workspace.
|
|
2
|
+
//
|
|
3
|
+
// Steps, with progress lines that match what `docs/schema-system.md` § 7
|
|
4
|
+
// promises:
|
|
5
|
+
// 1. Load schemas/*.ts.
|
|
6
|
+
// 2. Read .estokad/schema-state.json (preserves UUIDs across runs).
|
|
7
|
+
// 3. compile() — produces TypeIR[].
|
|
8
|
+
// 4. PUT /v1/{workspace}/management/content-types — server upserts and
|
|
9
|
+
// soft-deletes types not in the request.
|
|
10
|
+
// 5. Write schema-state.json with the freshly returned IR.
|
|
11
|
+
//
|
|
12
|
+
// M1.2c added the `--migrate` flag, which sets `?migrate=true` on the
|
|
13
|
+
// push and tells the server to override its migration-conflict check. A
|
|
14
|
+
// push without `--migrate` that would invalidate existing entries comes
|
|
15
|
+
// back as 422 with a per-type breakdown; the operator inspects, fixes
|
|
16
|
+
// any blockers, and re-runs (with or without `--migrate`).
|
|
17
|
+
import { compile } from '@estokad/schema';
|
|
18
|
+
import kleur from 'kleur';
|
|
19
|
+
import { ApiError, createApiClient } from '../lib/api.js';
|
|
20
|
+
import { ConfigError, loadConfig } from '../lib/config.js';
|
|
21
|
+
import { loadSchemas, SchemaLoadError } from '../lib/schemas.js';
|
|
22
|
+
import { readState, writeState } from '../lib/state.js';
|
|
23
|
+
export async function runPush(cwd, overrides, options = {}) {
|
|
24
|
+
let config;
|
|
25
|
+
try {
|
|
26
|
+
config = await loadConfig(cwd, overrides);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (err instanceof ConfigError) {
|
|
30
|
+
console.error(kleur.red(' ' + err.message));
|
|
31
|
+
return 2;
|
|
32
|
+
}
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
console.warn(kleur.dim(` workspace ${config.workspace} @ ${config.apiUrl}`));
|
|
36
|
+
let definitions;
|
|
37
|
+
try {
|
|
38
|
+
definitions = await loadSchemas(config.schemas);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof SchemaLoadError) {
|
|
42
|
+
console.error(kleur.red(' ' + err.message));
|
|
43
|
+
return 2;
|
|
44
|
+
}
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
console.warn(kleur.cyan(' ✓ ') + `loaded ${definitions.length} definitions from ${config.schemas}`);
|
|
48
|
+
const state = await readState(config.state);
|
|
49
|
+
const ir = compile(definitions, state ? { state } : {});
|
|
50
|
+
console.warn(kleur.cyan(' ✓ ') + `compiled to JSON IR (${ir.length} types)`);
|
|
51
|
+
const api = createApiClient({
|
|
52
|
+
apiUrl: config.apiUrl,
|
|
53
|
+
workspace: config.workspace,
|
|
54
|
+
apiKey: config.apiKey,
|
|
55
|
+
});
|
|
56
|
+
let saved;
|
|
57
|
+
try {
|
|
58
|
+
saved = await api.putContentTypes(ir, { migrate: options.migrate ?? false });
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
if (err instanceof ApiError) {
|
|
62
|
+
// Highlight the migration-conflict response shape so the operator
|
|
63
|
+
// sees what to fix (or knows to re-run with --migrate).
|
|
64
|
+
if (err.status === 422 && err.body.includes('migration_conflicts')) {
|
|
65
|
+
console.error(kleur.red(' ✗ push refused — existing entries fail the new schema.'));
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(err.body);
|
|
68
|
+
for (const c of parsed.conflicts ?? []) {
|
|
69
|
+
console.error(kleur.yellow(` • ${c.typeName}: ${c.entriesAffected} entry/entries affected`));
|
|
70
|
+
for (const s of c.samples.slice(0, 3)) {
|
|
71
|
+
const detail = s.issues.map((i) => `${i.path}: ${i.message}`).join('; ');
|
|
72
|
+
console.error(kleur.dim(` ${s.entryId.slice(0, 8)}… ${detail}`));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
console.error(kleur.dim(' Re-run with --migrate to push anyway (existing rows keep their data).'));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
console.error(kleur.dim(' ' + err.body));
|
|
79
|
+
}
|
|
80
|
+
return 4;
|
|
81
|
+
}
|
|
82
|
+
console.error(kleur.red(` ✗ push failed (${err.status}): ${err.body}`));
|
|
83
|
+
return 3;
|
|
84
|
+
}
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
console.warn(kleur.cyan(' ✓ ') + `pushed to ${config.workspace}@${config.region} (${saved.length} types)`);
|
|
88
|
+
await writeState(config.state, ir);
|
|
89
|
+
console.warn(kleur.cyan(' ✓ ') + `state saved to ${config.state}`);
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAaA,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIhF,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAuExF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// `estokad status` — surface drift between local schemas and the remote.
|
|
2
|
+
//
|
|
3
|
+
// What it prints, per docs/schema-system.md § 7:
|
|
4
|
+
// * config summary (workspace, region, API URL)
|
|
5
|
+
// * local: number of definitions, hash of the compiled IR
|
|
6
|
+
// * remote: number of types, hash of the joined remote schema
|
|
7
|
+
// * drift indicator: in-sync / drift detected / unreachable
|
|
8
|
+
import { compile } from '@estokad/schema';
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
import kleur from 'kleur';
|
|
11
|
+
import { ApiError, createApiClient } from '../lib/api.js';
|
|
12
|
+
import { ConfigError, loadConfig } from '../lib/config.js';
|
|
13
|
+
import { loadSchemas, SchemaLoadError } from '../lib/schemas.js';
|
|
14
|
+
import { readState } from '../lib/state.js';
|
|
15
|
+
export async function runStatus(cwd, overrides) {
|
|
16
|
+
let config;
|
|
17
|
+
try {
|
|
18
|
+
config = await loadConfig(cwd, overrides);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err instanceof ConfigError) {
|
|
22
|
+
console.error(kleur.red(' ' + err.message));
|
|
23
|
+
return 2;
|
|
24
|
+
}
|
|
25
|
+
throw err;
|
|
26
|
+
}
|
|
27
|
+
console.warn(kleur.bold(' estokad status'));
|
|
28
|
+
console.warn(kleur.dim(` workspace ${config.workspace} @ ${config.apiUrl}`));
|
|
29
|
+
console.warn(kleur.dim(` region ${config.region}`));
|
|
30
|
+
// Local
|
|
31
|
+
let localHash = '(no schemas)';
|
|
32
|
+
let localCount = 0;
|
|
33
|
+
try {
|
|
34
|
+
const definitions = await loadSchemas(config.schemas);
|
|
35
|
+
const state = await readState(config.state);
|
|
36
|
+
const ir = compile(definitions, state ? { state } : {});
|
|
37
|
+
localCount = ir.length;
|
|
38
|
+
localHash = hashIR(ir);
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof SchemaLoadError) {
|
|
42
|
+
console.warn(kleur.yellow(' local ') + err.message);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw err;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
console.warn(` local ${localCount} types · ${kleur.dim(localHash.slice(0, 16))}`);
|
|
49
|
+
// Remote
|
|
50
|
+
const api = createApiClient({
|
|
51
|
+
apiUrl: config.apiUrl,
|
|
52
|
+
workspace: config.workspace,
|
|
53
|
+
apiKey: config.apiKey,
|
|
54
|
+
});
|
|
55
|
+
let remoteHashes = [];
|
|
56
|
+
let remoteCount = 0;
|
|
57
|
+
try {
|
|
58
|
+
const remote = await api.listContentTypes();
|
|
59
|
+
remoteCount = remote.length;
|
|
60
|
+
remoteHashes = remote.map((t) => t.schemaHash);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err instanceof ApiError) {
|
|
64
|
+
console.warn(kleur.yellow(` remote unreachable (${err.status})`));
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
if (err instanceof Error) {
|
|
68
|
+
console.warn(kleur.yellow(` remote unreachable (${err.message})`));
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
throw err;
|
|
72
|
+
}
|
|
73
|
+
const remoteHash = hashStrings(remoteHashes);
|
|
74
|
+
console.warn(` remote ${remoteCount} types · ${kleur.dim(remoteHash.slice(0, 16))}`);
|
|
75
|
+
// Drift
|
|
76
|
+
if (localCount === 0) {
|
|
77
|
+
console.warn(kleur.yellow(' drift no local schemas to compare'));
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
if (localCount === remoteCount && localHash === remoteHash) {
|
|
81
|
+
console.warn(kleur.green(' drift in sync'));
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
console.warn(kleur.yellow(' drift run `estokad push` to sync'));
|
|
85
|
+
return 0;
|
|
86
|
+
}
|
|
87
|
+
function hashIR(ir) {
|
|
88
|
+
// Hash each type's stable shape (id + serialized fields), then join.
|
|
89
|
+
const perType = ir
|
|
90
|
+
.map((t) => createHash('sha256').update(JSON.stringify(t, sortKeys)).digest('hex'))
|
|
91
|
+
.sort();
|
|
92
|
+
return hashStrings(perType);
|
|
93
|
+
}
|
|
94
|
+
function hashStrings(items) {
|
|
95
|
+
const sorted = [...items].sort();
|
|
96
|
+
return createHash('sha256').update(sorted.join('|')).digest('hex');
|
|
97
|
+
}
|
|
98
|
+
function sortKeys(_, value) {
|
|
99
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
100
|
+
return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)));
|
|
101
|
+
}
|
|
102
|
+
return value;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { runDiff } from './commands/diff.js';
|
|
2
|
+
export { runInit } from './commands/init.js';
|
|
3
|
+
export { runPull } from './commands/pull.js';
|
|
4
|
+
export { runPush } from './commands/push.js';
|
|
5
|
+
export { runStatus } from './commands/status.js';
|
|
6
|
+
export { ConfigError, loadConfig } from './lib/config.js';
|
|
7
|
+
export type { ConfigOverrides, ResolvedConfig } from './lib/config.js';
|
|
8
|
+
export { createApiClient, ApiError } from './lib/api.js';
|
|
9
|
+
export type { ApiClient, ApiClientOptions } from './lib/api.js';
|
|
10
|
+
export { diffIR, formatDiff } from './lib/diff.js';
|
|
11
|
+
export type { DiffEntry, DiffResult } from './lib/diff.js';
|
|
12
|
+
export { loadSchemas, SchemaLoadError } from './lib/schemas.js';
|
|
13
|
+
export { readState, writeState } from './lib/state.js';
|
|
14
|
+
export interface Config {
|
|
15
|
+
readonly workspace: string;
|
|
16
|
+
readonly region?: string;
|
|
17
|
+
readonly apiUrl: string;
|
|
18
|
+
readonly apiKey?: string;
|
|
19
|
+
readonly schemas?: string;
|
|
20
|
+
readonly state?: string;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACxD,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAClD,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAGtD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Library exports — for consumers who want to programmatically use the CLI's
|
|
2
|
+
// pieces (e.g. integrating push into a larger build pipeline). The bin in
|
|
3
|
+
// dist/cli.js is the user-facing surface.
|
|
4
|
+
export { runDiff } from './commands/diff.js';
|
|
5
|
+
export { runInit } from './commands/init.js';
|
|
6
|
+
export { runPull } from './commands/pull.js';
|
|
7
|
+
export { runPush } from './commands/push.js';
|
|
8
|
+
export { runStatus } from './commands/status.js';
|
|
9
|
+
export { ConfigError, loadConfig } from './lib/config.js';
|
|
10
|
+
export { createApiClient, ApiError } from './lib/api.js';
|
|
11
|
+
export { diffIR, formatDiff } from './lib/diff.js';
|
|
12
|
+
export { loadSchemas, SchemaLoadError } from './lib/schemas.js';
|
|
13
|
+
export { readState, writeState } from './lib/state.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0EAA0E;AAC1E,0CAA0C;AAE1C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEzD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAExD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAElD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { TypeIR } from '@estokad/schema';
|
|
2
|
+
interface RemoteContentType {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly title: string;
|
|
6
|
+
readonly schemaHash: string;
|
|
7
|
+
readonly schema?: TypeIR;
|
|
8
|
+
readonly isSingleton?: boolean;
|
|
9
|
+
readonly isEmbedded?: boolean;
|
|
10
|
+
readonly source?: string;
|
|
11
|
+
readonly updatedAt?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface PutContentTypesOptions {
|
|
14
|
+
/** Sets `?migrate=true` on the request — tells the server to push
|
|
15
|
+
* even when existing entries fail the new schema. (M1.2c) */
|
|
16
|
+
readonly migrate?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ApiClient {
|
|
19
|
+
readonly listContentTypes: () => Promise<RemoteContentType[]>;
|
|
20
|
+
readonly putContentTypes: (types: ReadonlyArray<TypeIR>, options?: PutContentTypesOptions) => Promise<RemoteContentType[]>;
|
|
21
|
+
}
|
|
22
|
+
export interface ApiClientOptions {
|
|
23
|
+
readonly apiUrl: string;
|
|
24
|
+
readonly workspace: string;
|
|
25
|
+
readonly apiKey: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function createApiClient(options: ApiClientOptions): ApiClient;
|
|
28
|
+
export declare class ApiError extends Error {
|
|
29
|
+
readonly status: number;
|
|
30
|
+
readonly body: string;
|
|
31
|
+
constructor(status: number, body: string);
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAE7C,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC;kEAC8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAA;IAC7D,QAAQ,CAAC,eAAe,EAAE,CACxB,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,sBAAsB,KAC7B,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CA+BpE;AAUD,qBAAa,QAAS,SAAQ,KAAK;aAEf,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAK/B"}
|
package/dist/lib/api.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Thin HTTP client for the management API.
|
|
2
|
+
//
|
|
3
|
+
// Uses Node's built-in fetch (Node 18+). No retry logic yet — the CLI is
|
|
4
|
+
// always interactive; if the network blips, the user re-runs the command.
|
|
5
|
+
// Real retry/backoff lands when bulk content imports arrive (M1.3+).
|
|
6
|
+
export function createApiClient(options) {
|
|
7
|
+
const base = `${options.apiUrl.replace(/\/$/, '')}/v1/${encodeURIComponent(options.workspace)}/management`;
|
|
8
|
+
const headers = {
|
|
9
|
+
Authorization: `Bearer ${options.apiKey}`,
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
Accept: 'application/json',
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
async listContentTypes() {
|
|
15
|
+
const res = await fetch(`${base}/content-types`, { headers });
|
|
16
|
+
if (!res.ok) {
|
|
17
|
+
throw new ApiError(res.status, await safeText(res));
|
|
18
|
+
}
|
|
19
|
+
const body = (await res.json());
|
|
20
|
+
return body.types;
|
|
21
|
+
},
|
|
22
|
+
async putContentTypes(types, opts) {
|
|
23
|
+
const url = opts?.migrate ? `${base}/content-types?migrate=true` : `${base}/content-types`;
|
|
24
|
+
const res = await fetch(url, {
|
|
25
|
+
method: 'PUT',
|
|
26
|
+
headers,
|
|
27
|
+
body: JSON.stringify({ types }),
|
|
28
|
+
});
|
|
29
|
+
if (!res.ok) {
|
|
30
|
+
throw new ApiError(res.status, await safeText(res));
|
|
31
|
+
}
|
|
32
|
+
const body = (await res.json());
|
|
33
|
+
return body.types;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function safeText(res) {
|
|
38
|
+
try {
|
|
39
|
+
return await res.text();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return res.statusText;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class ApiError extends Error {
|
|
46
|
+
status;
|
|
47
|
+
body;
|
|
48
|
+
constructor(status, body) {
|
|
49
|
+
super(`API ${status}: ${body}`);
|
|
50
|
+
this.status = status;
|
|
51
|
+
this.body = body;
|
|
52
|
+
this.name = 'ApiError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,qEAAqE;AAoCrE,MAAM,UAAU,eAAe,CAAC,OAAyB;IACvD,MAAM,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,aAAa,CAAA;IAC1G,MAAM,OAAO,GAAG;QACd,aAAa,EAAE,UAAU,OAAO,CAAC,MAAM,EAAE;QACzC,cAAc,EAAE,kBAAkB;QAClC,MAAM,EAAE,kBAAkB;KAC3B,CAAA;IAED,OAAO;QACL,KAAK,CAAC,gBAAgB;YACpB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,gBAAgB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;YAC7D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;YACrD,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmC,CAAA;YACjE,OAAO,IAAI,CAAC,KAAK,CAAA;QACnB,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI;YAC/B,MAAM,GAAG,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,6BAA6B,CAAC,CAAC,CAAC,GAAG,IAAI,gBAAgB,CAAA;YAC1F,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC3B,MAAM,EAAE,KAAK;gBACb,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;aAChC,CAAC,CAAA;YACF,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAA;YACrD,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmC,CAAA;YACjE,OAAO,IAAI,CAAC,KAAK,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,GAAa;IACnC,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC,UAAU,CAAA;IACvB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,QAAS,SAAQ,KAAK;IAEf;IACA;IAFlB,YACkB,MAAc,EACd,IAAY;QAE5B,KAAK,CAAC,OAAO,MAAM,KAAK,IAAI,EAAE,CAAC,CAAA;QAHf,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;QAG5B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ResolvedConfig {
|
|
2
|
+
readonly workspace: string;
|
|
3
|
+
readonly region: string;
|
|
4
|
+
readonly apiUrl: string;
|
|
5
|
+
readonly apiKey: string;
|
|
6
|
+
readonly schemas: string;
|
|
7
|
+
readonly state: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ConfigOverrides {
|
|
10
|
+
readonly workspace?: string;
|
|
11
|
+
readonly region?: string;
|
|
12
|
+
readonly apiUrl?: string;
|
|
13
|
+
readonly apiKey?: string;
|
|
14
|
+
readonly schemas?: string;
|
|
15
|
+
readonly state?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function loadConfig(cwd: string, overrides?: ConfigOverrides): Promise<ResolvedConfig>;
|
|
18
|
+
export declare class ConfigError extends Error {
|
|
19
|
+
constructor(message: string);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAiBD,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,GAAE,eAAoB,GAC9B,OAAO,CAAC,cAAc,CAAC,CA2BzB;AA8BD,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Resolve the CLI's runtime config: workspace, region, API endpoint, key,
|
|
2
|
+
// schemas dir, and state file path.
|
|
3
|
+
//
|
|
4
|
+
// Precedence (highest first):
|
|
5
|
+
// 1. Command-line flags (handled by commander; passed as overrides here)
|
|
6
|
+
// 2. Environment variables (ESTOKAD_*)
|
|
7
|
+
// 3. estokad.config.ts/.js at the repo root
|
|
8
|
+
// 4. Documented defaults
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import { resolve } from 'node:path';
|
|
11
|
+
import { createJiti } from 'jiti';
|
|
12
|
+
const DEFAULTS = {
|
|
13
|
+
region: 'eu-fra-1',
|
|
14
|
+
schemas: './schemas',
|
|
15
|
+
state: './.estokad/schema-state.json',
|
|
16
|
+
};
|
|
17
|
+
export async function loadConfig(cwd, overrides = {}) {
|
|
18
|
+
const fileConfig = await loadFileConfig(cwd);
|
|
19
|
+
const workspace = pick('workspace', overrides, fileConfig, 'ESTOKAD_WORKSPACE');
|
|
20
|
+
const apiUrl = pick('apiUrl', overrides, fileConfig, 'ESTOKAD_API_URL');
|
|
21
|
+
const apiKey = pick('apiKey', overrides, fileConfig, 'ESTOKAD_API_KEY');
|
|
22
|
+
if (!workspace)
|
|
23
|
+
throw new ConfigError('workspace is required (set in estokad.config.ts or ESTOKAD_WORKSPACE env)');
|
|
24
|
+
if (!apiUrl)
|
|
25
|
+
throw new ConfigError('apiUrl is required (set in estokad.config.ts or ESTOKAD_API_URL env)');
|
|
26
|
+
if (!apiKey)
|
|
27
|
+
throw new ConfigError('apiKey is required (set ESTOKAD_API_KEY env)');
|
|
28
|
+
const region = pick('region', overrides, fileConfig, 'ESTOKAD_REGION') ?? DEFAULTS.region;
|
|
29
|
+
const schemas = pick('schemas', overrides, fileConfig) ?? DEFAULTS.schemas;
|
|
30
|
+
const state = pick('state', overrides, fileConfig) ?? DEFAULTS.state;
|
|
31
|
+
return {
|
|
32
|
+
workspace,
|
|
33
|
+
region,
|
|
34
|
+
apiUrl,
|
|
35
|
+
apiKey,
|
|
36
|
+
schemas: resolve(cwd, schemas),
|
|
37
|
+
state: resolve(cwd, state),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function loadFileConfig(cwd) {
|
|
41
|
+
const candidates = ['estokad.config.ts', 'estokad.config.js', 'estokad.config.mjs'];
|
|
42
|
+
for (const name of candidates) {
|
|
43
|
+
const path = resolve(cwd, name);
|
|
44
|
+
if (existsSync(path)) {
|
|
45
|
+
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
46
|
+
const mod = await jiti.import(path);
|
|
47
|
+
return ('default' in mod && mod.default ? mod.default : mod) ?? {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
function pick(key, overrides, file, envVar) {
|
|
53
|
+
const fromOverride = overrides[key];
|
|
54
|
+
if (fromOverride)
|
|
55
|
+
return fromOverride;
|
|
56
|
+
if (envVar) {
|
|
57
|
+
const fromEnv = process.env[envVar];
|
|
58
|
+
if (fromEnv)
|
|
59
|
+
return fromEnv;
|
|
60
|
+
}
|
|
61
|
+
return file[key];
|
|
62
|
+
}
|
|
63
|
+
export class ConfigError extends Error {
|
|
64
|
+
constructor(message) {
|
|
65
|
+
super(message);
|
|
66
|
+
this.name = 'ConfigError';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { FieldIR, TypeIR } from '@estokad/schema';
|
|
2
|
+
export type DiffEntry = {
|
|
3
|
+
kind: 'type-added';
|
|
4
|
+
name: string;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'type-removed';
|
|
7
|
+
name: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'type-renamed';
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'field-added';
|
|
14
|
+
type: string;
|
|
15
|
+
field: FieldIR;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'field-removed';
|
|
18
|
+
type: string;
|
|
19
|
+
field: FieldIR;
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'field-renamed';
|
|
22
|
+
type: string;
|
|
23
|
+
from: string;
|
|
24
|
+
to: string;
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'field-changed';
|
|
27
|
+
type: string;
|
|
28
|
+
field: string;
|
|
29
|
+
details: ReadonlyArray<string>;
|
|
30
|
+
};
|
|
31
|
+
export interface DiffResult {
|
|
32
|
+
readonly entries: ReadonlyArray<DiffEntry>;
|
|
33
|
+
}
|
|
34
|
+
export declare function diffIR(local: ReadonlyArray<TypeIR>, remote: ReadonlyArray<TypeIR>): DiffResult;
|
|
35
|
+
export declare function formatDiff(result: DiffResult): string;
|
|
36
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/lib/diff.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAEtD,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,CAAA;AAE1F,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAC3C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,UAAU,CAmC9F;AA8GD,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAuCrD"}
|