@chatlychat/cli 0.4.1 → 0.5.2
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/dist/commands/auth.d.ts +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +40 -3
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/deliveries.d.ts +18 -0
- package/dist/commands/deliveries.d.ts.map +1 -0
- package/dist/commands/deliveries.js +46 -0
- package/dist/commands/deliveries.js.map +1 -0
- package/dist/commands/init.d.ts +29 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +176 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/integrations.d.ts +27 -0
- package/dist/commands/integrations.d.ts.map +1 -1
- package/dist/commands/integrations.js +145 -4
- package/dist/commands/integrations.js.map +1 -1
- package/dist/commands/platform-as-code.d.ts +54 -0
- package/dist/commands/platform-as-code.d.ts.map +1 -0
- package/dist/commands/platform-as-code.js +185 -0
- package/dist/commands/platform-as-code.js.map +1 -0
- package/dist/commands/workspace-as-code.d.ts +52 -11
- package/dist/commands/workspace-as-code.d.ts.map +1 -1
- package/dist/commands/workspace-as-code.js +70 -189
- package/dist/commands/workspace-as-code.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +36 -1
- package/dist/help.js.map +1 -1
- package/dist/init/shared.d.ts +61 -0
- package/dist/init/shared.d.ts.map +1 -0
- package/dist/init/shared.js +110 -0
- package/dist/init/shared.js.map +1 -0
- package/dist/init/templates.d.ts +29 -0
- package/dist/init/templates.d.ts.map +1 -0
- package/dist/init/templates.js +362 -0
- package/dist/init/templates.js.map +1 -0
- package/dist/pac/platform-document.d.ts +65 -0
- package/dist/pac/platform-document.d.ts.map +1 -0
- package/dist/pac/platform-document.js +149 -0
- package/dist/pac/platform-document.js.map +1 -0
- package/dist/pac/platform-live.d.ts +65 -0
- package/dist/pac/platform-live.d.ts.map +1 -0
- package/dist/pac/platform-live.js +263 -0
- package/dist/pac/platform-live.js.map +1 -0
- package/dist/pac/platform-resources.d.ts +141 -0
- package/dist/pac/platform-resources.d.ts.map +1 -0
- package/dist/pac/platform-resources.js +509 -0
- package/dist/pac/platform-resources.js.map +1 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +26 -2
- package/dist/run.js.map +1 -1
- package/dist/wac/apply.d.ts.map +1 -1
- package/dist/wac/apply.js +56 -16
- package/dist/wac/apply.js.map +1 -1
- package/dist/wac/diff-warnings.d.ts +35 -0
- package/dist/wac/diff-warnings.d.ts.map +1 -0
- package/dist/wac/diff-warnings.js +88 -0
- package/dist/wac/diff-warnings.js.map +1 -0
- package/dist/wac/diff.d.ts +40 -70
- package/dist/wac/diff.d.ts.map +1 -1
- package/dist/wac/diff.js +114 -91
- package/dist/wac/diff.js.map +1 -1
- package/dist/wac/document-key.d.ts +30 -0
- package/dist/wac/document-key.d.ts.map +1 -0
- package/dist/wac/document-key.js +87 -0
- package/dist/wac/document-key.js.map +1 -0
- package/dist/wac/document.d.ts +75 -65
- package/dist/wac/document.d.ts.map +1 -1
- package/dist/wac/document.js +60 -46
- package/dist/wac/document.js.map +1 -1
- package/dist/wac/execute.d.ts +25 -0
- package/dist/wac/execute.d.ts.map +1 -0
- package/dist/wac/execute.js +126 -0
- package/dist/wac/execute.js.map +1 -0
- package/dist/wac/load.d.ts +17 -0
- package/dist/wac/load.d.ts.map +1 -0
- package/dist/wac/load.js +92 -0
- package/dist/wac/load.js.map +1 -0
- package/dist/wac/resource-def.d.ts +89 -1
- package/dist/wac/resource-def.d.ts.map +1 -1
- package/dist/wac/resource-def.js +4 -0
- package/dist/wac/resource-def.js.map +1 -1
- package/dist/wac/resources.d.ts +9 -11
- package/dist/wac/resources.d.ts.map +1 -1
- package/dist/wac/resources.js +93 -27
- package/dist/wac/resources.js.map +1 -1
- package/dist/wac/values.d.ts +20 -0
- package/dist/wac/values.d.ts.map +1 -1
- package/dist/wac/values.js +46 -0
- package/dist/wac/values.js.map +1 -1
- package/package.json +4 -3
package/dist/wac/apply.js
CHANGED
|
@@ -62,8 +62,34 @@
|
|
|
62
62
|
* result.
|
|
63
63
|
*/
|
|
64
64
|
import { looksLikeCredential, routeForField } from './resources.js';
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Substitute `{id}` and any other placeholder a nested route carries.
|
|
67
|
+
*
|
|
68
|
+
* Every workspace-level route has exactly one placeholder and `params` is
|
|
69
|
+
* empty for all of them. The Platform API's are nested
|
|
70
|
+
* (`/v1/platform/workspaces/{workspaceId}/users/{id}`), so the parent's id
|
|
71
|
+
* comes in through `params`.
|
|
72
|
+
*
|
|
73
|
+
* **An unfilled placeholder throws.** It is tempting to leave it, since the
|
|
74
|
+
* server would answer 404 and `apply` reports a failure either way — but the
|
|
75
|
+
* message would name a path containing a literal `{workspaceId}`, and a 404
|
|
76
|
+
* reads as "the resource is gone" rather than "this CLI built a broken URL".
|
|
77
|
+
* Worse, `encodeURIComponent` would not be reached for the braces, so the
|
|
78
|
+
* request would go out looking almost right. A thrown error is caught by
|
|
79
|
+
* `execute`'s per-op try and reported against the resource that produced it.
|
|
80
|
+
*/
|
|
81
|
+
function fill(path, id, params = {}) {
|
|
82
|
+
let out = path.replace('{id}', encodeURIComponent(id));
|
|
83
|
+
for (const [name, value] of Object.entries(params)) {
|
|
84
|
+
out = out.replaceAll(`{${name}}`, encodeURIComponent(value));
|
|
85
|
+
}
|
|
86
|
+
const unfilled = /\{([A-Za-z_][A-Za-z0-9_]*)\}/.exec(out);
|
|
87
|
+
if (unfilled !== null) {
|
|
88
|
+
throw new Error(`cannot build the request path: ${path} still has {${String(unfilled[1])}} unfilled. ` +
|
|
89
|
+
'That placeholder is a parent id this plan could not resolve — the reference that ' +
|
|
90
|
+
'supplies it either failed above or is missing from the document.');
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
67
93
|
}
|
|
68
94
|
/**
|
|
69
95
|
* The writes one plan item needs, in order.
|
|
@@ -77,22 +103,33 @@ export function writesFor(def, item, refIds, opts) {
|
|
|
77
103
|
if (!opts.prune || def.remove === null || opts.pruneUnsafe.includes(def.type)) {
|
|
78
104
|
return [];
|
|
79
105
|
}
|
|
80
|
-
return [{ method: 'DELETE', path: fill(def.remove.path, item.liveId ?? '') }];
|
|
106
|
+
return [{ method: 'DELETE', path: fill(def.remove.path, item.liveId ?? '', item.pathParams) }];
|
|
81
107
|
}
|
|
82
108
|
if (item.row === undefined || (item.action !== 'create' && item.action !== 'update')) {
|
|
83
109
|
return [];
|
|
84
110
|
}
|
|
85
|
-
/*
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
/*
|
|
112
|
+
* References: resolved at plan time where possible, here where not.
|
|
113
|
+
*
|
|
114
|
+
* Two destinations, and keeping them apart is the point. A BODY ref becomes
|
|
115
|
+
* a field in the request (`botRoutes` sends `botId`); a PATH ref becomes a
|
|
116
|
+
* segment of the URL and must NOT appear in the body, because
|
|
117
|
+
* `POST /v1/platform/workspaces/{id}/users` validates with a plain
|
|
118
|
+
* `z.object` and zod strips a key it has never heard of — a 201 that
|
|
119
|
+
* silently ignored half the request is the failure CLAUDE.md names twice.
|
|
120
|
+
*/
|
|
121
|
+
const wired = { ...item.resolved };
|
|
122
|
+
const pathWired = { ...item.pathParams };
|
|
90
123
|
for (const [wire, ref] of Object.entries(item.row.refs)) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (id !== undefined) {
|
|
94
|
-
|
|
124
|
+
const id = refIds.get(`${ref.type}/${ref.key}`);
|
|
125
|
+
if (ref.pathParam === true) {
|
|
126
|
+
if (pathWired[wire] === undefined && id !== undefined) {
|
|
127
|
+
pathWired[wire] = id;
|
|
95
128
|
}
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (wired[wire] === undefined && id !== undefined) {
|
|
132
|
+
wired[wire] = id;
|
|
96
133
|
}
|
|
97
134
|
}
|
|
98
135
|
if (item.action === 'create') {
|
|
@@ -102,7 +139,7 @@ export function writesFor(def, item, refIds, opts) {
|
|
|
102
139
|
return [
|
|
103
140
|
{
|
|
104
141
|
method: 'POST',
|
|
105
|
-
path: def.create.path,
|
|
142
|
+
path: fill(def.create.path, '', pathWired),
|
|
106
143
|
body: { ...item.row.body, ...wired },
|
|
107
144
|
},
|
|
108
145
|
];
|
|
@@ -119,7 +156,7 @@ export function writesFor(def, item, refIds, opts) {
|
|
|
119
156
|
return [
|
|
120
157
|
{
|
|
121
158
|
method: 'POST',
|
|
122
|
-
path: def.create.path,
|
|
159
|
+
path: fill(def.create.path, '', pathWired),
|
|
123
160
|
body: { id: liveId, ...item.row.body, ...wired },
|
|
124
161
|
},
|
|
125
162
|
];
|
|
@@ -157,6 +194,7 @@ export function writesFor(def, item, refIds, opts) {
|
|
|
157
194
|
* first would make it unreproducible as well, and a flaky request sequence
|
|
158
195
|
* is a thing nobody can debug from a log.
|
|
159
196
|
*/
|
|
197
|
+
const changed = new Map(item.changes.map((c) => [c.name, c.to]));
|
|
160
198
|
const ops = [];
|
|
161
199
|
for (const route of def.update) {
|
|
162
200
|
const body = {};
|
|
@@ -164,12 +202,14 @@ export function writesFor(def, item, refIds, opts) {
|
|
|
164
202
|
if (routeForField(def, field) !== route) {
|
|
165
203
|
continue;
|
|
166
204
|
}
|
|
167
|
-
|
|
205
|
+
// The diff's value for a field wins over the document's: a merge field with
|
|
206
|
+
// redacted leaves was planned WITHOUT them (unless `--write-only`).
|
|
207
|
+
body[field] = wired[field] ?? changed.get(field) ?? item.row.body[field];
|
|
168
208
|
}
|
|
169
209
|
if (Object.keys(body).length === 0) {
|
|
170
210
|
continue;
|
|
171
211
|
}
|
|
172
|
-
ops.push({ method: route.method, path: fill(route.path, liveId), body });
|
|
212
|
+
ops.push({ method: route.method, path: fill(route.path, liveId, pathWired), body });
|
|
173
213
|
}
|
|
174
214
|
return ops;
|
|
175
215
|
}
|
package/dist/wac/apply.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/wac/apply.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AAmCtF,SAAS,IAAI,CAAC,IAAY,EAAE,EAAU;
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/wac/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The warnings `buildPlan` prints above a plan, one section at a time.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `diff.ts` when CHT-F04's path parameters pushed that file past
|
|
5
|
+
* the 650-line ceiling. It is a real seam rather than a cut: nothing here
|
|
6
|
+
* decides an action. These functions only observe — a truncated list, rows
|
|
7
|
+
* with no natural key, a key on two rows, a field no live row carries — and
|
|
8
|
+
* the plan is the same with or without them.
|
|
9
|
+
*/
|
|
10
|
+
import { type ResourceDef } from './resources.js';
|
|
11
|
+
import type { LiveIndex, LiveSection } from './diff.js';
|
|
12
|
+
import type { DocumentRow } from './document.js';
|
|
13
|
+
export declare function sectionWarnings(def: ResourceDef, rows: ReadonlyArray<DocumentRow>, live: LiveSection, index: LiveIndex): ReadonlyArray<string>;
|
|
14
|
+
/**
|
|
15
|
+
* A field the document declares that NO live row carries.
|
|
16
|
+
*
|
|
17
|
+
* This is what stands in for a per-resource field allow-list, and it is
|
|
18
|
+
* better evidence than one: the vocabulary comes from the server on every
|
|
19
|
+
* run, so it cannot drift out of step with an API that shipped a field
|
|
20
|
+
* yesterday. CLAUDE.md's `helpProfile` / `profile` bug — a key zod strips,
|
|
21
|
+
* answering 200 while doing nothing — is exactly what it catches, and
|
|
22
|
+
* `unwritable` in `resources.ts` catches the mirror case (a field the server
|
|
23
|
+
* returns and no write path accepts).
|
|
24
|
+
*
|
|
25
|
+
* Two limits, both reported rather than hidden:
|
|
26
|
+
*
|
|
27
|
+
* - With no live rows there is nothing to compare against, so a brand-new
|
|
28
|
+
* workspace gets no warnings at all.
|
|
29
|
+
* - A legitimately optional field nobody in this workspace has set produces
|
|
30
|
+
* a false positive. That is why it is a warning and not a refusal: being
|
|
31
|
+
* wrong costs one line of output, where refusing wrongly costs a config
|
|
32
|
+
* file that cannot be applied.
|
|
33
|
+
*/
|
|
34
|
+
export declare function vocabularyWarnings(def: ResourceDef, rows: ReadonlyArray<DocumentRow>, liveRows: ReadonlyArray<Record<string, unknown>>): ReadonlyArray<string>;
|
|
35
|
+
//# sourceMappingURL=diff-warnings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-warnings.d.ts","sourceRoot":"","sources":["../../src/wac/diff-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAkC,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElF,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,EAChC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,SAAS,GACf,aAAa,CAAC,MAAM,CAAC,CAgCvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,aAAa,CAAC,WAAW,CAAC,EAChC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC/C,aAAa,CAAC,MAAM,CAAC,CAgCvB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The warnings `buildPlan` prints above a plan, one section at a time.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `diff.ts` when CHT-F04's path parameters pushed that file past
|
|
5
|
+
* the 650-line ceiling. It is a real seam rather than a cut: nothing here
|
|
6
|
+
* decides an action. These functions only observe — a truncated list, rows
|
|
7
|
+
* with no natural key, a key on two rows, a field no live row carries — and
|
|
8
|
+
* the plan is the same with or without them.
|
|
9
|
+
*/
|
|
10
|
+
import { looksLikeCredential, projected } from './resources.js';
|
|
11
|
+
/* ── Warnings ─────────────────────────────────────────────────────────── */
|
|
12
|
+
export function sectionWarnings(def, rows, live, index) {
|
|
13
|
+
const out = [];
|
|
14
|
+
if (live.possiblyTruncated === true) {
|
|
15
|
+
out.push(`${def.type}: the list route is @PaginationExempt and answered at its cap, so there may ` +
|
|
16
|
+
'be rows this plan cannot see. `--prune` is refused for this type while that holds — ' +
|
|
17
|
+
'a row past the cap is invisible, not absent.');
|
|
18
|
+
}
|
|
19
|
+
if (index.keyless > 0) {
|
|
20
|
+
out.push(`${def.type}: ${String(index.keyless)} ${def.label}(s) on the server have no ` +
|
|
21
|
+
`\`${def.naturalKey}\`, so this file can neither match nor prune them. They are not ` +
|
|
22
|
+
'listed below at all — ' +
|
|
23
|
+
(def.keylessHint ?? 'give them one in the dashboard to bring them under management.'));
|
|
24
|
+
}
|
|
25
|
+
for (const key of index.ambiguous) {
|
|
26
|
+
out.push(`${def.type}: ${def.naturalKey} "${key}" is on more than one ${def.label}` +
|
|
27
|
+
(def.keyEnforced
|
|
28
|
+
? '.'
|
|
29
|
+
: ` — the database does not make \`${def.naturalKey}\` unique for this resource, so ` +
|
|
30
|
+
'only this file does.'));
|
|
31
|
+
}
|
|
32
|
+
out.push(...vocabularyWarnings(def, rows, live.rows));
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A field the document declares that NO live row carries.
|
|
37
|
+
*
|
|
38
|
+
* This is what stands in for a per-resource field allow-list, and it is
|
|
39
|
+
* better evidence than one: the vocabulary comes from the server on every
|
|
40
|
+
* run, so it cannot drift out of step with an API that shipped a field
|
|
41
|
+
* yesterday. CLAUDE.md's `helpProfile` / `profile` bug — a key zod strips,
|
|
42
|
+
* answering 200 while doing nothing — is exactly what it catches, and
|
|
43
|
+
* `unwritable` in `resources.ts` catches the mirror case (a field the server
|
|
44
|
+
* returns and no write path accepts).
|
|
45
|
+
*
|
|
46
|
+
* Two limits, both reported rather than hidden:
|
|
47
|
+
*
|
|
48
|
+
* - With no live rows there is nothing to compare against, so a brand-new
|
|
49
|
+
* workspace gets no warnings at all.
|
|
50
|
+
* - A legitimately optional field nobody in this workspace has set produces
|
|
51
|
+
* a false positive. That is why it is a warning and not a refusal: being
|
|
52
|
+
* wrong costs one line of output, where refusing wrongly costs a config
|
|
53
|
+
* file that cannot be applied.
|
|
54
|
+
*/
|
|
55
|
+
export function vocabularyWarnings(def, rows, liveRows) {
|
|
56
|
+
if (liveRows.length === 0 || rows.length === 0) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
const serverFields = new Set();
|
|
60
|
+
for (const raw of liveRows) {
|
|
61
|
+
for (const field of Object.keys(projected(def, raw))) {
|
|
62
|
+
serverFields.add(field);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const unknown = new Set();
|
|
66
|
+
for (const row of rows) {
|
|
67
|
+
for (const field of Object.keys(row.body)) {
|
|
68
|
+
if (serverFields.has(field) || def.opaque.includes(field)) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// A credential-looking name is write-only by nature, not a typo.
|
|
72
|
+
if (looksLikeCredential(field)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
unknown.add(field);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (unknown.size === 0) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
return [
|
|
82
|
+
`${def.type}: ${[...unknown].map((f) => `\`${f}\``).join(', ')} — no ${def.label} on this ` +
|
|
83
|
+
`server carries ${unknown.size === 1 ? 'that field' : 'those fields'}. The API validates ` +
|
|
84
|
+
'with zod and zod STRIPS an unknown key, so a misspelling is a 200 that did nothing. ' +
|
|
85
|
+
`The fields it does return: ${[...serverFields].sort().join(', ')}.`,
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=diff-warnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-warnings.js","sourceRoot":"","sources":["../../src/wac/diff-warnings.ts"],"names":[],"mappings":"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"}
|
package/dist/wac/diff.d.ts
CHANGED
|
@@ -1,55 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The diff. Pure: a document plus the live rows in, a plan out.
|
|
3
|
-
*
|
|
4
|
-
* No transport, no filesystem, no clock, nothing injected. That is not
|
|
5
|
-
* fastidiousness — it is what lets the spec drive this with literal objects,
|
|
6
|
-
* and it is half the proof that `chatly plan` writes nothing: the function
|
|
7
|
-
* that decides what WOULD change has no way to change anything. The other
|
|
8
|
-
* half is a recording transport asserting zero non-GET requests, in
|
|
9
|
-
* `wac.spec.ts`.
|
|
10
|
-
*
|
|
11
|
-
* ═══ WHAT A DIFF MUST NOT DO ══════════════════════════════════════════════
|
|
12
|
-
*
|
|
13
|
-
* Report a change that is not one. A plan that says "3 to change" against a
|
|
14
|
-
* workspace nobody has touched is a plan people stop reading, and then
|
|
15
|
-
* `apply` gets run blind — which is the failure this whole feature exists to
|
|
16
|
-
* prevent. Four rules come out of that:
|
|
17
|
-
*
|
|
18
|
-
* 1. ONLY the fields the document declares are compared. A server field the
|
|
19
|
-
* file says nothing about is unmanaged and is never mentioned. So a
|
|
20
|
-
* document can describe four fields of a bot and leave the other twenty
|
|
21
|
-
* to the dashboard, which is how a team actually works.
|
|
22
|
-
*
|
|
23
|
-
* 2. A field that cannot be READ BACK is never compared. Two kinds, both
|
|
24
|
-
* handled: the ones declared `opaque` (a customer card's `headers` are
|
|
25
|
-
* write-only by design — the read shape returns `headerNames`, names and
|
|
26
|
-
* never values, because that is where the bearer token is), and the ones
|
|
27
|
-
* the server hands back as the literal `__redacted__`, detected at
|
|
28
|
-
* runtime so a field nobody told this file about still cannot produce a
|
|
29
|
-
* phantom change. Each is reported once, as a note, saying it is
|
|
30
|
-
* unknowable rather than unchanged.
|
|
31
|
-
*
|
|
32
|
-
* 3. `undefined` and absent are one state. JSON has no `undefined`, so a key
|
|
33
|
-
* the server omits and a key it sends as `undefined` are the same thing,
|
|
34
|
-
* and only `null` is a value.
|
|
35
|
-
*
|
|
36
|
-
* 4. The live row is PROJECTED into the document's vocabulary first. A bot's
|
|
37
|
-
* `webhookUrl` comes back under `externalAgent`; an email template's
|
|
38
|
-
* customised copy comes back under `override`. Comparing against the
|
|
39
|
-
* un-projected row reports a change on every run, for ever. See
|
|
40
|
-
* `resources.ts`.
|
|
41
|
-
*
|
|
42
|
-
* ═══ AND WHAT IT MUST DO ══════════════════════════════════════════════════
|
|
43
|
-
*
|
|
44
|
-
* Refuse to guess. Two live rows with one natural key, a reference to a bot
|
|
45
|
-
* that neither exists nor is being created, a changed field no route can
|
|
46
|
-
* write — each produces a `blocked` item that `apply` will not touch, with
|
|
47
|
-
* the reason on the line. The alternative in every case is picking one and
|
|
48
|
-
* being wrong silently, which is how the wrong resource gets overwritten.
|
|
49
|
-
*/
|
|
50
1
|
import { type Action, type ResourceDef, type UpdateRoute } from './resources.js';
|
|
51
2
|
import type { DocumentRow, WacDocument } from './document.js';
|
|
52
3
|
export { isRedacted, REDACTED, sameValue } from './values.js';
|
|
4
|
+
export { vocabularyWarnings } from './diff-warnings.js';
|
|
53
5
|
export interface FieldChange {
|
|
54
6
|
readonly name: string;
|
|
55
7
|
/** Absent on a create. */
|
|
@@ -74,6 +26,21 @@ export interface PlanItem {
|
|
|
74
26
|
readonly row: DocumentRow | undefined;
|
|
75
27
|
/** Wire field → id, for references already resolvable at plan time. */
|
|
76
28
|
readonly resolved: Readonly<Record<string, string>>;
|
|
29
|
+
/**
|
|
30
|
+
* Placeholder → id for a reference that fills the ROUTE PATH rather than
|
|
31
|
+
* the body (`ResourceRef.pathParam`).
|
|
32
|
+
*
|
|
33
|
+
* Separate from `resolved` because the two have opposite treatment: a body
|
|
34
|
+
* ref is COMPARED against the live row, and a path ref must never be — the
|
|
35
|
+
* live row has no such field, so a diff on it would report a change every
|
|
36
|
+
* run. Empty for every workspace-level resource, which declares no path
|
|
37
|
+
* refs at all.
|
|
38
|
+
*
|
|
39
|
+
* Carried on an ORPHAN too, where there is no document row to resolve from:
|
|
40
|
+
* the parent's id is read off the live row, because `--prune` needs it to
|
|
41
|
+
* build the DELETE path.
|
|
42
|
+
*/
|
|
43
|
+
readonly pathParams: Readonly<Record<string, string>>;
|
|
77
44
|
/** `type/key` for each reference, so apply can skip a failed dependency. */
|
|
78
45
|
readonly dependsOn: ReadonlyArray<string>;
|
|
79
46
|
}
|
|
@@ -90,6 +57,14 @@ export interface LiveSection {
|
|
|
90
57
|
/** The route caps its answer and the answer came back at the cap. */
|
|
91
58
|
readonly possiblyTruncated?: boolean;
|
|
92
59
|
}
|
|
60
|
+
export interface LiveIndex {
|
|
61
|
+
/** Normalised key → projected row. */
|
|
62
|
+
readonly byKey: ReadonlyMap<string, Record<string, unknown>>;
|
|
63
|
+
/** Keys that appeared more than once: matched to nothing, on purpose. */
|
|
64
|
+
readonly ambiguous: ReadonlySet<string>;
|
|
65
|
+
/** Rows whose natural key is null/absent: invisible to this file. */
|
|
66
|
+
readonly keyless: number;
|
|
67
|
+
}
|
|
93
68
|
/**
|
|
94
69
|
* Build the plan.
|
|
95
70
|
*
|
|
@@ -109,29 +84,24 @@ export interface PlanOptions {
|
|
|
109
84
|
* ever tell you that for you.
|
|
110
85
|
*/
|
|
111
86
|
readonly writeOnly?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Live rows of a type the document REFERENCES without declaring a section
|
|
89
|
+
* for it — resolvable by a reference, never planned, never an orphan.
|
|
90
|
+
*
|
|
91
|
+
* The platform document's adoption shape needs it (CHT-F04): an `apiKeys`
|
|
92
|
+
* row naming `workspace: "acme"` for a tenant somebody else created, with
|
|
93
|
+
* no `workspaces:` section at all. Without this, `known` holds only
|
|
94
|
+
* declared types and the row is blocked as naming something "neither on
|
|
95
|
+
* the server nor created by this plan" — which is false, the tenant is on
|
|
96
|
+
* the server. Declaring the section instead would turn every other tenant
|
|
97
|
+
* into an orphan line. Empty for the workspace document.
|
|
98
|
+
*/
|
|
99
|
+
readonly referenced?: ReadonlyArray<{
|
|
100
|
+
readonly def: ResourceDef;
|
|
101
|
+
readonly section: LiveSection;
|
|
102
|
+
}>;
|
|
112
103
|
}
|
|
113
104
|
export declare function buildPlan(doc: WacDocument, live: ReadonlyMap<string, LiveSection>, opts?: PlanOptions): Plan;
|
|
114
|
-
/**
|
|
115
|
-
* A field the document declares that NO live row carries.
|
|
116
|
-
*
|
|
117
|
-
* This is what stands in for a per-resource field allow-list, and it is
|
|
118
|
-
* better evidence than one: the vocabulary comes from the server on every
|
|
119
|
-
* run, so it cannot drift out of step with an API that shipped a field
|
|
120
|
-
* yesterday. CLAUDE.md's `helpProfile` / `profile` bug — a key zod strips,
|
|
121
|
-
* answering 200 while doing nothing — is exactly what it catches, and
|
|
122
|
-
* `unwritable` in `resources.ts` catches the mirror case (a field the server
|
|
123
|
-
* returns and no write path accepts).
|
|
124
|
-
*
|
|
125
|
-
* Two limits, both reported rather than hidden:
|
|
126
|
-
*
|
|
127
|
-
* - With no live rows there is nothing to compare against, so a brand-new
|
|
128
|
-
* workspace gets no warnings at all.
|
|
129
|
-
* - A legitimately optional field nobody in this workspace has set produces
|
|
130
|
-
* a false positive. That is why it is a warning and not a refusal: being
|
|
131
|
-
* wrong costs one line of output, where refusing wrongly costs a config
|
|
132
|
-
* file that cannot be applied.
|
|
133
|
-
*/
|
|
134
|
-
export declare function vocabularyWarnings(def: ResourceDef, rows: ReadonlyArray<DocumentRow>, liveRows: ReadonlyArray<Record<string, unknown>>): ReadonlyArray<string>;
|
|
135
105
|
/** Counts for the summary line. */
|
|
136
106
|
export declare function tally(plan: Plan): Record<Action, number>;
|
|
137
107
|
//# sourceMappingURL=diff.d.ts.map
|
package/dist/wac/diff.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/wac/diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/wac/diff.ts"],"names":[],"mappings":"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"}
|