@gate-forge/pack-playwright 0.3.0 → 0.6.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/dist/constants.d.ts +16 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +17 -1
- package/dist/constants.js.map +1 -1
- package/dist/discovery/inference.d.ts.map +1 -1
- package/dist/discovery/inference.js +24 -0
- package/dist/discovery/inference.js.map +1 -1
- package/dist/discovery/static-discovery.d.ts +7 -0
- package/dist/discovery/static-discovery.d.ts.map +1 -1
- package/dist/discovery/static-discovery.js +33 -2
- package/dist/discovery/static-discovery.js.map +1 -1
- package/dist/fixture/evidence.d.ts +14 -0
- package/dist/fixture/evidence.d.ts.map +1 -1
- package/dist/fixture/evidence.js +23 -0
- package/dist/fixture/evidence.js.map +1 -1
- package/dist/fixture/witness-client.d.ts +15 -1
- package/dist/fixture/witness-client.d.ts.map +1 -1
- package/dist/fixture/witness-client.js +18 -0
- package/dist/fixture/witness-client.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/supervisor/client.d.ts +16 -1
- package/dist/supervisor/client.d.ts.map +1 -1
- package/dist/supervisor/client.js +19 -0
- package/dist/supervisor/client.js.map +1 -1
- package/dist/supervisor/drain.d.ts +7 -3
- package/dist/supervisor/drain.d.ts.map +1 -1
- package/dist/supervisor/drain.js +70 -2
- package/dist/supervisor/drain.js.map +1 -1
- package/dist/surface.d.ts +67 -8
- package/dist/surface.d.ts.map +1 -1
- package/dist/surface.js +132 -34
- package/dist/surface.js.map +1 -1
- package/dist/witness/adapter-registry.d.ts +16 -0
- package/dist/witness/adapter-registry.d.ts.map +1 -1
- package/dist/witness/adapter-registry.js +103 -0
- package/dist/witness/adapter-registry.js.map +1 -1
- package/dist/witness/behavior-request.d.ts +80 -0
- package/dist/witness/behavior-request.d.ts.map +1 -0
- package/dist/witness/behavior-request.js +277 -0
- package/dist/witness/behavior-request.js.map +1 -0
- package/dist/witness/behavior.d.ts +52 -0
- package/dist/witness/behavior.d.ts.map +1 -0
- package/dist/witness/behavior.js +118 -0
- package/dist/witness/behavior.js.map +1 -0
- package/dist/witness/browser.d.ts +43 -1
- package/dist/witness/browser.d.ts.map +1 -1
- package/dist/witness/browser.js +55 -4
- package/dist/witness/browser.js.map +1 -1
- package/dist/witness/fixture-provider.d.ts +86 -0
- package/dist/witness/fixture-provider.d.ts.map +1 -0
- package/dist/witness/fixture-provider.js +109 -0
- package/dist/witness/fixture-provider.js.map +1 -0
- package/dist/witness/server.d.ts.map +1 -1
- package/dist/witness/server.js +1238 -3
- package/dist/witness/server.js.map +1 -1
- package/dist/witness/types.d.ts +243 -0
- package/dist/witness/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/python/__pycache__/gateforge_persistence_intents.cpython-312.pyc +0 -0
package/dist/surface.js
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
* closed (elements never match) instead of manufacturing proof.
|
|
13
13
|
*/
|
|
14
14
|
/**
|
|
15
|
-
* The surface-descriptor contract version this pack speaks.
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* instead of silently misreading selectors.
|
|
15
|
+
* The surface-descriptor contract version this pack speaks. Version 2
|
|
16
|
+
* adds opt-in `create.steps[]` (wizard flows); version 1 descriptors
|
|
17
|
+
* keep working unchanged (steps forbidden under v1).
|
|
19
18
|
*/
|
|
20
|
-
export const SURFACE_DESCRIPTOR_VERSION =
|
|
19
|
+
export const SURFACE_DESCRIPTOR_VERSION = 2;
|
|
20
|
+
/** Legacy surface-descriptor version (single-form create only). */
|
|
21
|
+
export const SURFACE_DESCRIPTOR_VERSION_1 = 1;
|
|
21
22
|
/**
|
|
22
23
|
* Substitutes `{id}` in a consumer-declared selector/path template with
|
|
23
24
|
* the entity id. Fail closed on ids that could break selector context
|
|
@@ -46,33 +47,14 @@ export function renderSurfaceTemplate(template, entityId) {
|
|
|
46
47
|
* Error: naming the first structural problem found.
|
|
47
48
|
*/
|
|
48
49
|
export function validateSurface(surface) {
|
|
49
|
-
const requireSelectorMap = (where, map) => {
|
|
50
|
-
if (typeof map !== 'object' || map === null || Array.isArray(map)) {
|
|
51
|
-
throw new Error(`surface.${where} must be a record of field name → selector`);
|
|
52
|
-
}
|
|
53
|
-
for (const [field, selector] of Object.entries(map)) {
|
|
54
|
-
if (typeof selector !== 'string' || selector.length === 0) {
|
|
55
|
-
throw new Error(`surface.${where}.${field} must be a non-empty selector string`);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
const requireIndexMap = (where, map) => {
|
|
60
|
-
if (typeof map !== 'object' || map === null || Array.isArray(map)) {
|
|
61
|
-
throw new Error(`surface.${where} must be a record of field name → cell index`);
|
|
62
|
-
}
|
|
63
|
-
for (const [field, index] of Object.entries(map)) {
|
|
64
|
-
if (!Number.isInteger(index) || index < 0) {
|
|
65
|
-
throw new Error(`surface.${where}.${field} must be a non-negative integer cell index`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
50
|
if (typeof surface !== 'object' || surface === null || Array.isArray(surface)) {
|
|
70
51
|
throw new Error('surface must be a SurfaceDescriptor object declared by the consumer');
|
|
71
52
|
}
|
|
72
|
-
if (surface.schemaVersion !== SURFACE_DESCRIPTOR_VERSION) {
|
|
53
|
+
if (surface.schemaVersion !== SURFACE_DESCRIPTOR_VERSION_1 && surface.schemaVersion !== SURFACE_DESCRIPTOR_VERSION) {
|
|
73
54
|
throw new Error(`surface.schemaVersion ${String(surface.schemaVersion)} is not supported: this pack speaks ` +
|
|
74
|
-
`surface-descriptor
|
|
75
|
-
|
|
55
|
+
`surface-descriptor versions ${String(SURFACE_DESCRIPTOR_VERSION_1)} (legacy single-form ` +
|
|
56
|
+
`create) and ${String(SURFACE_DESCRIPTOR_VERSION)} (wizard steps allowed) — redeclare ` +
|
|
57
|
+
'the surface against a current version');
|
|
76
58
|
}
|
|
77
59
|
for (const section of ['list', 'create', 'edit', 'archive', 'status', 'afterAction']) {
|
|
78
60
|
if (typeof surface[section] !== 'object' || surface[section] === null) {
|
|
@@ -88,12 +70,7 @@ export function validateSurface(surface) {
|
|
|
88
70
|
throw new Error('surface.list.idCellIndex must be a non-negative integer');
|
|
89
71
|
}
|
|
90
72
|
requireIndexMap('list.fieldCellIndexes', surface.list.fieldCellIndexes);
|
|
91
|
-
|
|
92
|
-
if (typeof surface.create[key] !== 'string' || surface.create[key].length === 0) {
|
|
93
|
-
throw new Error(`surface.create.${key} must be a non-empty string`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
requireSelectorMap('create.fields', surface.create.fields);
|
|
73
|
+
validateCreateFlow(surface.schemaVersion, surface.create);
|
|
97
74
|
for (const key of ['linkSelector', 'formReadySelectorTemplate', 'saveSelectorTemplate']) {
|
|
98
75
|
if (typeof surface.edit[key] !== 'string' || surface.edit[key].length === 0) {
|
|
99
76
|
throw new Error(`surface.edit.${key} must be a non-empty string`);
|
|
@@ -113,6 +90,127 @@ export function validateSurface(surface) {
|
|
|
113
90
|
requireSelectorMap('deleteFields', surface.deleteFields);
|
|
114
91
|
return surface;
|
|
115
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Requires a field name → selector record (module-level: shared by the
|
|
95
|
+
* descriptor validator and the create-flow validator).
|
|
96
|
+
*/
|
|
97
|
+
function requireSelectorMap(where, map) {
|
|
98
|
+
if (typeof map !== 'object' || map === null || Array.isArray(map)) {
|
|
99
|
+
throw new Error(`surface.${where} must be a record of field name → selector`);
|
|
100
|
+
}
|
|
101
|
+
for (const [field, selector] of Object.entries(map)) {
|
|
102
|
+
if (typeof selector !== 'string' || selector.length === 0) {
|
|
103
|
+
throw new Error(`surface.${where}.${field} must be a non-empty selector string`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Requires a field name → cell index record (module-level: shared by
|
|
109
|
+
* the descriptor validator and the create-flow validator).
|
|
110
|
+
*/
|
|
111
|
+
function requireIndexMap(where, map) {
|
|
112
|
+
if (typeof map !== 'object' || map === null || Array.isArray(map)) {
|
|
113
|
+
throw new Error(`surface.${where} must be a record of field name → cell index`);
|
|
114
|
+
}
|
|
115
|
+
for (const [field, index] of Object.entries(map)) {
|
|
116
|
+
if (!Number.isInteger(index) || index < 0) {
|
|
117
|
+
throw new Error(`surface.${where}.${field} must be a non-negative integer cell index`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validates the create flow: legacy single-form trio, or (v2 only) a
|
|
123
|
+
* wizard step walk. Mixed shapes are refused fail-closed — the engine
|
|
124
|
+
* never drives half a form and half a wizard.
|
|
125
|
+
*/
|
|
126
|
+
function validateCreateFlow(schemaVersion, create) {
|
|
127
|
+
if (typeof create !== 'object' || create === null || Array.isArray(create)) {
|
|
128
|
+
throw new Error('surface.create must be an object (legacy form or v2 steps)');
|
|
129
|
+
}
|
|
130
|
+
const record = create;
|
|
131
|
+
if ('steps' in record) {
|
|
132
|
+
if (schemaVersion !== SURFACE_DESCRIPTOR_VERSION) {
|
|
133
|
+
throw new Error('surface.create.steps requires surface-descriptor version ' +
|
|
134
|
+
`${String(SURFACE_DESCRIPTOR_VERSION)} (declared ${String(schemaVersion)})`);
|
|
135
|
+
}
|
|
136
|
+
for (const legacy of ['formPath', 'formReadySelector', 'submitSelector']) {
|
|
137
|
+
if (record[legacy] !== undefined) {
|
|
138
|
+
throw new Error(`surface.create mixes wizard steps with legacy '${legacy}' — declare steps or the ` +
|
|
139
|
+
'single form, never both');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
requireSelectorMap('create.fields', create.fields);
|
|
143
|
+
validateSteps(create.steps, create.fields);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
for (const key of ['formPath', 'formReadySelector', 'submitSelector']) {
|
|
147
|
+
if (typeof create[key] !== 'string' || create[key].length === 0) {
|
|
148
|
+
throw new Error(`surface.create.${key} must be a non-empty string`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
requireSelectorMap('create.fields', create.fields);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Validates one wizard step walk: non-empty, closed operation set,
|
|
155
|
+
* non-empty selectors/paths, fills carrying exactly one of
|
|
156
|
+
* field/value with the field in the declared vocabulary.
|
|
157
|
+
*/
|
|
158
|
+
function validateSteps(steps, fields) {
|
|
159
|
+
if (!Array.isArray(steps) || steps.length === 0) {
|
|
160
|
+
throw new Error('surface.create.steps must be a non-empty array of wizard steps');
|
|
161
|
+
}
|
|
162
|
+
steps.forEach((step, index) => {
|
|
163
|
+
const where = `surface.create.steps[${String(index)}]`;
|
|
164
|
+
if (typeof step !== 'object' || step === null || Array.isArray(step)) {
|
|
165
|
+
throw new Error(`${where} must be a single-operation step object`);
|
|
166
|
+
}
|
|
167
|
+
const keys = Object.keys(step);
|
|
168
|
+
if (keys.length !== 1) {
|
|
169
|
+
throw new Error(`${where} must carry exactly one operation (goto/click/fill/check/press/waitFor)`);
|
|
170
|
+
}
|
|
171
|
+
const operation = keys[0];
|
|
172
|
+
const value = step[operation];
|
|
173
|
+
switch (operation) {
|
|
174
|
+
case 'goto':
|
|
175
|
+
case 'click':
|
|
176
|
+
case 'check':
|
|
177
|
+
case 'waitFor':
|
|
178
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
179
|
+
throw new Error(`${where}.${operation} must be a non-empty string`);
|
|
180
|
+
}
|
|
181
|
+
if (operation === 'goto' && !value.startsWith('/')) {
|
|
182
|
+
throw new Error(`${where}.goto must be an app-relative path starting with '/'`);
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
case 'press':
|
|
186
|
+
if (value !== 'Escape' && value !== 'Enter') {
|
|
187
|
+
throw new Error(`${where}.press must be 'Escape' or 'Enter'`);
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
case 'fill': {
|
|
191
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
192
|
+
throw new Error(`${where}.fill must be {selector, field?/value?}`);
|
|
193
|
+
}
|
|
194
|
+
const fill = value;
|
|
195
|
+
if (typeof fill['selector'] !== 'string' || fill['selector'].length === 0) {
|
|
196
|
+
throw new Error(`${where}.fill.selector must be a non-empty string`);
|
|
197
|
+
}
|
|
198
|
+
const hasField = typeof fill['field'] === 'string' && fill['field'].length > 0;
|
|
199
|
+
const hasValue = typeof fill['value'] === 'string';
|
|
200
|
+
if (hasField === hasValue) {
|
|
201
|
+
throw new Error(`${where}.fill needs exactly one of field/value (a test-input reference or a map literal)`);
|
|
202
|
+
}
|
|
203
|
+
if (hasField && !Object.prototype.hasOwnProperty.call(fields, fill['field'])) {
|
|
204
|
+
throw new Error(`${where}.fill.field '${fill['field']}' is not in the declared create.fields ` +
|
|
205
|
+
`vocabulary (${Object.keys(fields).sort().join(', ') || '<none>'})`);
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
default:
|
|
210
|
+
throw new Error(`${where} carries unknown operation '${String(operation)}' (allowed: goto/click/fill/check/press/waitFor)`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
116
214
|
/**
|
|
117
215
|
* Fills descriptor input fields exactly: every declared key must be a
|
|
118
216
|
* selector-known field with a string value (fail closed — the engine
|
package/dist/surface.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH
|
|
1
|
+
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,22 @@ export declare function validateAdapter(module: unknown, name: string): Evidence
|
|
|
33
33
|
export declare class AdapterRegistryError extends Error {
|
|
34
34
|
constructor(message: string);
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Validates one adapter's optional `observe` binding (Observe channel,
|
|
38
|
+
* Phase 2): a plain object with per-operation `{method, path}`
|
|
39
|
+
* entries. Method must be a concrete uppercase verb; path must be an
|
|
40
|
+
* absolute backend-facing path whose only template segment is `{id}` —
|
|
41
|
+
* required on read/update/delete (the entity-id carrier), forbidden on
|
|
42
|
+
* create (create ids come from the adapter list-diff, never from a
|
|
43
|
+
* path guess).
|
|
44
|
+
*
|
|
45
|
+
* Args:
|
|
46
|
+
* value: the adapter's `observe` export.
|
|
47
|
+
*
|
|
48
|
+
* Returns:
|
|
49
|
+
* string | null: the contract-violation description, or null when valid.
|
|
50
|
+
*/
|
|
51
|
+
export declare function validateObserveBinding(value: unknown): string | null;
|
|
36
52
|
/** The transport the witness hands to adapter `read` calls (GET-only). */
|
|
37
53
|
export declare function makeAdapterContext(baseUrl: string, resourceId: string, get: AdapterContext['get'], headers?: Record<string, string>): AdapterContext;
|
|
38
54
|
//# sourceMappingURL=adapter-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../src/witness/adapter-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../src/witness/adapter-registry.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA6BrF;AAqBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CA6E9E;AAED,kEAAkE;AAClE,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAgBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CA2CpE;AAED,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,EAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,cAAc,CAEhB"}
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
* deletion: 'hard' | 'archive',
|
|
13
13
|
* environmentFingerprint: '…', // must match the target's marker header
|
|
14
14
|
* baseUrl: 'http://…', // optional override of the witness adapter base
|
|
15
|
+
* list: async (ctx) => bodies, // optional: powers create pre-observations + Observe snapshots
|
|
16
|
+
* observe: { // optional: Observe-channel mutation bindings (Phase 2)
|
|
17
|
+
* create: { method: 'POST', path: '/api/v2/accounts' },
|
|
18
|
+
* update: { method: 'PATCH', path: '/api/v2/accounts/{id}' },
|
|
19
|
+
* },
|
|
15
20
|
* probeServer: async (ctx, subject) => ({ found, fields }), // optional: the
|
|
16
21
|
* // SERVER-WITNESSED persistence channel probe — executed
|
|
17
22
|
* // ONLY in this trusted witness process
|
|
@@ -127,6 +132,25 @@ export function validateAdapter(module, name) {
|
|
|
127
132
|
if (adapter['probeServer'] !== undefined && typeof adapter['probeServer'] !== 'function') {
|
|
128
133
|
problems.push('probeServer must be an async function (ctx, subject) => {found, fields} when present');
|
|
129
134
|
}
|
|
135
|
+
// Observe binding (Observe channel, Phase 2): OPTIONAL — an adapter
|
|
136
|
+
// without it serves no observe obligation. Present-but-malformed is a
|
|
137
|
+
// load-time contract violation (fail closed), validated by
|
|
138
|
+
// validateObserveBinding below.
|
|
139
|
+
if (adapter['observe'] !== undefined) {
|
|
140
|
+
const observeProblem = validateObserveBinding(adapter['observe']);
|
|
141
|
+
if (observeProblem !== null)
|
|
142
|
+
problems.push(observeProblem);
|
|
143
|
+
}
|
|
144
|
+
// Trusted scope/barrier observation (plan 2026-09-19 §4.4, Phase 4):
|
|
145
|
+
// OPTIONAL — adapters lacking these methods still serve legacy proofs
|
|
146
|
+
// but cannot satisfy strong contracts requiring scoped observation.
|
|
147
|
+
// Present-but-not-a-function is a load-time violation (fail closed).
|
|
148
|
+
if (adapter['snapshotScope'] !== undefined && typeof adapter['snapshotScope'] !== 'function') {
|
|
149
|
+
problems.push('snapshotScope must be an async function (ctx, {scope, fixtureNamespace}) => ScopeSnapshot when present');
|
|
150
|
+
}
|
|
151
|
+
if (adapter['awaitBarrier'] !== undefined && typeof adapter['awaitBarrier'] !== 'function') {
|
|
152
|
+
problems.push('awaitBarrier must be an async function (ctx, {scope, fixtureNamespace, operationId, deadlineMs}) when present');
|
|
153
|
+
}
|
|
130
154
|
if (problems.length > 0) {
|
|
131
155
|
throw new AdapterRegistryError(`adapter '${name}' violates the adapter contract: ${problems.join('; ')}`);
|
|
132
156
|
}
|
|
@@ -142,6 +166,15 @@ export function validateAdapter(module, name) {
|
|
|
142
166
|
...(adapter['probeServer'] !== undefined
|
|
143
167
|
? { probeServer: adapter['probeServer'] }
|
|
144
168
|
: {}),
|
|
169
|
+
...(adapter['observe'] !== undefined
|
|
170
|
+
? { observe: adapter['observe'] }
|
|
171
|
+
: {}),
|
|
172
|
+
...(adapter['snapshotScope'] !== undefined
|
|
173
|
+
? { snapshotScope: adapter['snapshotScope'] }
|
|
174
|
+
: {}),
|
|
175
|
+
...(adapter['awaitBarrier'] !== undefined
|
|
176
|
+
? { awaitBarrier: adapter['awaitBarrier'] }
|
|
177
|
+
: {}),
|
|
145
178
|
};
|
|
146
179
|
}
|
|
147
180
|
/** Fail-closed adapter-loading error (witness startup aborts). */
|
|
@@ -151,6 +184,76 @@ export class AdapterRegistryError extends Error {
|
|
|
151
184
|
this.name = 'AdapterRegistryError';
|
|
152
185
|
}
|
|
153
186
|
}
|
|
187
|
+
/** Concrete HTTP methods an observe binding may name (uppercase). */
|
|
188
|
+
const OBSERVE_METHODS = new Set([
|
|
189
|
+
'GET',
|
|
190
|
+
'HEAD',
|
|
191
|
+
'POST',
|
|
192
|
+
'PUT',
|
|
193
|
+
'PATCH',
|
|
194
|
+
'DELETE',
|
|
195
|
+
'OPTIONS',
|
|
196
|
+
]);
|
|
197
|
+
/** Observe-eligible operations (the CRUD verbs the grader knows). */
|
|
198
|
+
const OBSERVE_OPERATIONS = ['create', 'read', 'update', 'delete'];
|
|
199
|
+
/**
|
|
200
|
+
* Validates one adapter's optional `observe` binding (Observe channel,
|
|
201
|
+
* Phase 2): a plain object with per-operation `{method, path}`
|
|
202
|
+
* entries. Method must be a concrete uppercase verb; path must be an
|
|
203
|
+
* absolute backend-facing path whose only template segment is `{id}` —
|
|
204
|
+
* required on read/update/delete (the entity-id carrier), forbidden on
|
|
205
|
+
* create (create ids come from the adapter list-diff, never from a
|
|
206
|
+
* path guess).
|
|
207
|
+
*
|
|
208
|
+
* Args:
|
|
209
|
+
* value: the adapter's `observe` export.
|
|
210
|
+
*
|
|
211
|
+
* Returns:
|
|
212
|
+
* string | null: the contract-violation description, or null when valid.
|
|
213
|
+
*/
|
|
214
|
+
export function validateObserveBinding(value) {
|
|
215
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
216
|
+
return 'observe must be an object {create?/read?/update?/delete?: {method, path}} when present';
|
|
217
|
+
}
|
|
218
|
+
const binding = value;
|
|
219
|
+
for (const key of Object.keys(binding)) {
|
|
220
|
+
if (!OBSERVE_OPERATIONS.includes(key)) {
|
|
221
|
+
return `observe carries unknown operation '${key}' (allowed: ${OBSERVE_OPERATIONS.join(', ')})`;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
for (const operation of OBSERVE_OPERATIONS) {
|
|
225
|
+
const entry = binding[operation];
|
|
226
|
+
if (entry === undefined)
|
|
227
|
+
continue;
|
|
228
|
+
if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
|
|
229
|
+
return `observe.${operation} must be {method, path}`;
|
|
230
|
+
}
|
|
231
|
+
const { method, path } = entry;
|
|
232
|
+
if (typeof method !== 'string' || !OBSERVE_METHODS.has(method)) {
|
|
233
|
+
return (`observe.${operation}.method must be a concrete uppercase HTTP verb ` +
|
|
234
|
+
`(${[...OBSERVE_METHODS].sort().join(', ')})`);
|
|
235
|
+
}
|
|
236
|
+
if (typeof path !== 'string' || !path.startsWith('/')) {
|
|
237
|
+
return `observe.${operation}.path must be an absolute backend-facing path starting with '/'`;
|
|
238
|
+
}
|
|
239
|
+
if (path.includes('//') || /[\s?#]/.test(path)) {
|
|
240
|
+
return `observe.${operation}.path must be a plain path template (no duplicate slashes, query, fragment, or whitespace)`;
|
|
241
|
+
}
|
|
242
|
+
const segments = path.split('/').filter((segment) => segment.length > 0);
|
|
243
|
+
const idSegments = segments.filter((segment) => segment === '{id}').length;
|
|
244
|
+
const braced = segments.filter((segment) => segment.startsWith('{') || segment.endsWith('}'));
|
|
245
|
+
if (braced.length !== idSegments) {
|
|
246
|
+
return `observe.${operation}.path may template only the '{id}' segment (got '${path}')`;
|
|
247
|
+
}
|
|
248
|
+
if (operation === 'create' && idSegments > 0) {
|
|
249
|
+
return `observe.create.path must not template '{id}' (create ids come from the adapter list-diff, got '${path}')`;
|
|
250
|
+
}
|
|
251
|
+
if (operation !== 'create' && idSegments !== 1) {
|
|
252
|
+
return `observe.${operation}.path must carry exactly one '{id}' segment binding the entity id (got '${path}')`;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
154
257
|
/** The transport the witness hands to adapter `read` calls (GET-only). */
|
|
155
258
|
export function makeAdapterContext(baseUrl, resourceId, get, headers) {
|
|
156
259
|
return Object.freeze({ baseUrl, resourceId, get, ...(headers ? { headers } : {}) });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../src/witness/adapter-registry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../src/witness/adapter-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { CredentialMaterial, FixtureLease } from './fixture-provider.js';
|
|
2
|
+
/** Proof-input bound (request and response bodies alike). */
|
|
3
|
+
export declare const BEHAVIOR_BODY_LIMIT_BYTES: number;
|
|
4
|
+
/** Typed driver failure (always a blocking diagnostic, never proof). */
|
|
5
|
+
export declare class BehaviorDriverError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/** Approved request action shape (subset used by the Phase 5 driver). */
|
|
9
|
+
export interface BehaviorRequestAction {
|
|
10
|
+
kind: 'request';
|
|
11
|
+
method: string;
|
|
12
|
+
pathTemplate: string;
|
|
13
|
+
path: Record<string, {
|
|
14
|
+
from: string;
|
|
15
|
+
value?: unknown;
|
|
16
|
+
key?: string;
|
|
17
|
+
}>;
|
|
18
|
+
query: Record<string, {
|
|
19
|
+
from: string;
|
|
20
|
+
value?: unknown;
|
|
21
|
+
key?: string;
|
|
22
|
+
}>;
|
|
23
|
+
body: {
|
|
24
|
+
encoding: string;
|
|
25
|
+
fields?: Record<string, {
|
|
26
|
+
from: string;
|
|
27
|
+
value?: unknown;
|
|
28
|
+
key?: string;
|
|
29
|
+
}>;
|
|
30
|
+
fixture?: string;
|
|
31
|
+
};
|
|
32
|
+
credentialVariant: 'valid' | 'missing' | 'corrupted';
|
|
33
|
+
signatureProfile?: string;
|
|
34
|
+
}
|
|
35
|
+
/** What the driver observed (headers excluded — they carry secrets). */
|
|
36
|
+
export interface DrivenRequest {
|
|
37
|
+
engineRequestId: string;
|
|
38
|
+
method: string;
|
|
39
|
+
path: string;
|
|
40
|
+
query: Record<string, unknown>;
|
|
41
|
+
/** Submitted body as observed (parsed JSON or form map). */
|
|
42
|
+
body: unknown;
|
|
43
|
+
status: number | null;
|
|
44
|
+
/** Response body as observed (parsed JSON or text). */
|
|
45
|
+
responseBody: unknown;
|
|
46
|
+
requestDigest: string;
|
|
47
|
+
responseDigest: string | null;
|
|
48
|
+
}
|
|
49
|
+
export interface DriveBehaviorRequestInput {
|
|
50
|
+
/** Approved request action from the bound catalog. */
|
|
51
|
+
action: BehaviorRequestAction;
|
|
52
|
+
/** Trusted lease (subjects + actors resolve here). */
|
|
53
|
+
lease: FixtureLease;
|
|
54
|
+
/** Actor profile key from the case definition. */
|
|
55
|
+
actorProfile: string;
|
|
56
|
+
/** Approved subject origin (the app under test; loopback only). */
|
|
57
|
+
origin: string;
|
|
58
|
+
/** Resolve engine-side credential material (never suite-visible). */
|
|
59
|
+
resolveCredential: (credentialRef: string) => Promise<CredentialMaterial | null> | CredentialMaterial | null;
|
|
60
|
+
/** Fetch timeout in milliseconds. */
|
|
61
|
+
timeoutMs: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Drives one approved request and captures the bounded observation.
|
|
65
|
+
*
|
|
66
|
+
* Args:
|
|
67
|
+
* input: action, lease, actor profile, origin, credential resolver,
|
|
68
|
+
* and timeout.
|
|
69
|
+
*
|
|
70
|
+
* Returns:
|
|
71
|
+
* DrivenRequest: method/path/query/body/status/response plus
|
|
72
|
+
* identity digests (headers never leave the driver).
|
|
73
|
+
*
|
|
74
|
+
* Throws:
|
|
75
|
+
* BehaviorDriverError: unsupported encoding, unresolvable value,
|
|
76
|
+
* non-loopback origin, timeout, over-limit body, or transport
|
|
77
|
+
* failure — always a blocking diagnostic, never proof.
|
|
78
|
+
*/
|
|
79
|
+
export declare function driveBehaviorRequest(input: DriveBehaviorRequestInput): Promise<DrivenRequest>;
|
|
80
|
+
//# sourceMappingURL=behavior-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"behavior-request.d.ts","sourceRoot":"","sources":["../../src/witness/behavior-request.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE9E,6DAA6D;AAC7D,eAAO,MAAM,yBAAyB,QAAa,CAAC;AAEpD,wEAAwE;AACxE,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED,yEAAyE;AACzE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,OAAO,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvH,iBAAiB,EAAE,OAAO,GAAG,SAAS,GAAG,WAAW,CAAC;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4DAA4D;IAC5D,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uDAAuD;IACvD,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAuED,MAAM,WAAW,yBAAyB;IACxC,sDAAsD;IACtD,MAAM,EAAE,qBAAqB,CAAC;IAC9B,sDAAsD;IACtD,KAAK,EAAE,YAAY,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,iBAAiB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,kBAAkB,GAAG,IAAI,CAAC;IAC7G,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,aAAa,CAAC,CAqKnG"}
|