@positronic/spec 0.0.52 → 0.0.54
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/api.d.ts +41 -12
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +192 -46
- package/dist/api.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/src/api.js +417 -56
- package/dist/src/index.js +1 -1
- package/package.json +1 -1
package/dist/api.d.ts
CHANGED
|
@@ -113,29 +113,29 @@ export declare const brains: {
|
|
|
113
113
|
*/
|
|
114
114
|
killSuspended(fetch: Fetch, loopBrainIdentifier: string, webhookSlug: string, webhookPayload: Record<string, any>): Promise<boolean>;
|
|
115
115
|
/**
|
|
116
|
-
* Test that
|
|
117
|
-
* Requires a brain with
|
|
116
|
+
* Test that agent steps emit proper AGENT_* events in the SSE stream.
|
|
117
|
+
* Requires a brain with an agent step that will pause on a webhook.
|
|
118
118
|
*
|
|
119
119
|
* Expected events before webhook pause:
|
|
120
|
-
* -
|
|
121
|
-
* -
|
|
122
|
-
* -
|
|
123
|
-
* -
|
|
120
|
+
* - AGENT_START (with prompt and optional system)
|
|
121
|
+
* - AGENT_ITERATION
|
|
122
|
+
* - AGENT_TOOL_CALL
|
|
123
|
+
* - AGENT_WEBHOOK (before WEBHOOK event)
|
|
124
124
|
* - WEBHOOK
|
|
125
125
|
*/
|
|
126
|
-
|
|
126
|
+
watchAgentEvents(fetch: Fetch, agentBrainIdentifier: string): Promise<boolean>;
|
|
127
127
|
/**
|
|
128
|
-
* Test full
|
|
129
|
-
* 1. Start
|
|
128
|
+
* Test full agent webhook resumption flow:
|
|
129
|
+
* 1. Start an agent brain that will pause on a webhook
|
|
130
130
|
* 2. Verify it pauses with WEBHOOK event
|
|
131
131
|
* 3. Trigger the webhook with a response
|
|
132
|
-
* 4. Verify the brain resumes and emits WEBHOOK_RESPONSE and
|
|
132
|
+
* 4. Verify the brain resumes and emits WEBHOOK_RESPONSE and AGENT_TOOL_RESULT
|
|
133
133
|
*
|
|
134
134
|
* Requires:
|
|
135
|
-
* - A brain with
|
|
135
|
+
* - A brain with an agent step that calls a tool returning { waitFor: webhook(...) }
|
|
136
136
|
* - The webhook slug and identifier to trigger
|
|
137
137
|
*/
|
|
138
|
-
|
|
138
|
+
agentWebhookResume(fetch: Fetch, agentBrainIdentifier: string, webhookSlug: string, webhookPayload: Record<string, any>): Promise<boolean>;
|
|
139
139
|
/**
|
|
140
140
|
* Test that inner brain COMPLETE events don't overwrite outer brain status.
|
|
141
141
|
*
|
|
@@ -208,6 +208,20 @@ export declare const webhooks: {
|
|
|
208
208
|
* Test POST /webhooks/:slug with non-existent webhook - Should return 404
|
|
209
209
|
*/
|
|
210
210
|
notFound(fetch: Fetch, slug: string): Promise<boolean>;
|
|
211
|
+
/**
|
|
212
|
+
* Test POST /webhooks/system/ui-form - Built-in webhook for UI form submissions.
|
|
213
|
+
* This is used by pages generated via .ui() steps to submit form data.
|
|
214
|
+
*
|
|
215
|
+
* The endpoint:
|
|
216
|
+
* - Accepts form data (application/x-www-form-urlencoded or multipart/form-data)
|
|
217
|
+
* - Requires an `identifier` query parameter to match the waiting brain
|
|
218
|
+
* - Returns { received: true, action: 'resumed' | 'not_found', ... }
|
|
219
|
+
*/
|
|
220
|
+
uiForm(fetch: Fetch, identifier: string, formData: Record<string, string | string[]>): Promise<boolean>;
|
|
221
|
+
/**
|
|
222
|
+
* Test POST /webhooks/system/ui-form with missing identifier - Should return 400
|
|
223
|
+
*/
|
|
224
|
+
uiFormMissingIdentifier(fetch: Fetch): Promise<boolean>;
|
|
211
225
|
};
|
|
212
226
|
export declare const pages: {
|
|
213
227
|
/**
|
|
@@ -253,5 +267,20 @@ export declare const pages: {
|
|
|
253
267
|
*/
|
|
254
268
|
deletePreservesResources(fetch: Fetch): Promise<boolean>;
|
|
255
269
|
};
|
|
270
|
+
/**
|
|
271
|
+
* Bundle API Tests
|
|
272
|
+
*
|
|
273
|
+
* Tests for the /bundle/components.js endpoint which serves the component bundle.
|
|
274
|
+
*
|
|
275
|
+
* NOTE: These tests only verify the API endpoint behavior. The bundle build and
|
|
276
|
+
* upload process is backend-specific and must be tested separately by each
|
|
277
|
+
* backend implementation.
|
|
278
|
+
*/
|
|
279
|
+
export declare const bundle: {
|
|
280
|
+
/**
|
|
281
|
+
* Test GET /bundle/components.js - Serve the component bundle
|
|
282
|
+
*/
|
|
283
|
+
get(fetch: Fetch): Promise<boolean>;
|
|
284
|
+
};
|
|
256
285
|
export {};
|
|
257
286
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,KAAK,KAAK,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErD,wBAAsB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAyB/D;AAED,eAAO,MAAM,SAAS;IACpB;;OAEG;gBACe,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAyE1C;;OAEG;kBACiB,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAwE5C;;OAEG;kBACiB,KAAK,OAAO,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBzD;;OAEG;qBACoB,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IA0C/C;;OAEG;mCACkC,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IA6F7D;;OAEG;iCACgC,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;CA2E5D,CAAC;AAEF,eAAO,MAAM,MAAM;IACjB;;OAEG;eACc,KAAK,cAAc,MAAM,YAAY,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAwCrG;;OAEG;0BAEM,KAAK,cACA,MAAM,WACT,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmCzB;;OAEG;uBAEM,KAAK,yBACW,MAAM,GAC5B,OAAO,CAAC,OAAO,CAAC;IAuDnB;;OAEG;iBACgB,KAAK,SAAS,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2D1D;;OAEG;mBAEM,KAAK,cACA,MAAM,UACV,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;IA2DnB;;OAEG;oBACmB,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAsD9C;;OAEG;gBACe,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IA6D1C;;;;;OAKG;kBACiB,KAAK,SAAS,MAAM,GAAG,OAAO,CAAC;QACjD,MAAM,EAAE,KAAK,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;QACH,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,IAAI,CAAC;IAqET;;;OAGG;wBACuB,KAAK,cAAc,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqFtE;;OAEG;sBACqB,KAAK,cAAc,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsEpE;;OAEG;kBACiB,KAAK,SAAS,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA0F3D;;OAEG;0BACyB,KAAK,oBAAoB,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA4B9E;;;OAGG;iCAEM,KAAK,uBACS,MAAM,GAC1B,OAAO,CAAC,OAAO,CAAC;IAkDnB;;OAEG;wBAEM,KAAK,uBACS,MAAM,GAC1B,OAAO,CAAC,OAAO,CAAC;IA+DnB;;OAEG;iBAEM,KAAK,cACA,MAAM,UACV,MAAM,aACH,MAAM,eACJ,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAuCzB;;OAEG;gBACe,KAAK,SAAS,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBzD;;;;;;;;OAQG;yBAEM,KAAK,uBACS,MAAM,eACd,MAAM,kBACH,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAClC,OAAO,CAAC,OAAO,CAAC;IAwLnB;;;;;;;;;;OAUG;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -1048,23 +1048,23 @@ export const brains = {
|
|
|
1048
1048
|
}
|
|
1049
1049
|
},
|
|
1050
1050
|
/**
|
|
1051
|
-
* Test that
|
|
1052
|
-
* Requires a brain with
|
|
1051
|
+
* Test that agent steps emit proper AGENT_* events in the SSE stream.
|
|
1052
|
+
* Requires a brain with an agent step that will pause on a webhook.
|
|
1053
1053
|
*
|
|
1054
1054
|
* Expected events before webhook pause:
|
|
1055
|
-
* -
|
|
1056
|
-
* -
|
|
1057
|
-
* -
|
|
1058
|
-
* -
|
|
1055
|
+
* - AGENT_START (with prompt and optional system)
|
|
1056
|
+
* - AGENT_ITERATION
|
|
1057
|
+
* - AGENT_TOOL_CALL
|
|
1058
|
+
* - AGENT_WEBHOOK (before WEBHOOK event)
|
|
1059
1059
|
* - WEBHOOK
|
|
1060
1060
|
*/
|
|
1061
|
-
async
|
|
1061
|
+
async watchAgentEvents(fetch, agentBrainIdentifier) {
|
|
1062
1062
|
try {
|
|
1063
|
-
// Start the
|
|
1063
|
+
// Start the agent brain
|
|
1064
1064
|
const runRequest = new Request('http://example.com/brains/runs', {
|
|
1065
1065
|
method: 'POST',
|
|
1066
1066
|
headers: { 'Content-Type': 'application/json' },
|
|
1067
|
-
body: JSON.stringify({ identifier:
|
|
1067
|
+
body: JSON.stringify({ identifier: agentBrainIdentifier }),
|
|
1068
1068
|
});
|
|
1069
1069
|
const runResponse = await fetch(runRequest);
|
|
1070
1070
|
if (runResponse.status !== 201) {
|
|
@@ -1120,72 +1120,72 @@ export const brains = {
|
|
|
1120
1120
|
await reader.cancel();
|
|
1121
1121
|
}
|
|
1122
1122
|
}
|
|
1123
|
-
// Verify required
|
|
1124
|
-
const
|
|
1125
|
-
if (!
|
|
1126
|
-
console.error('Missing
|
|
1123
|
+
// Verify required agent events are present
|
|
1124
|
+
const hasAgentStart = events.some((e) => e.type === BRAIN_EVENTS.AGENT_START);
|
|
1125
|
+
if (!hasAgentStart) {
|
|
1126
|
+
console.error('Missing AGENT_START event in SSE stream');
|
|
1127
1127
|
return false;
|
|
1128
1128
|
}
|
|
1129
|
-
// Verify
|
|
1130
|
-
const
|
|
1131
|
-
if (!
|
|
1132
|
-
console.error('
|
|
1129
|
+
// Verify AGENT_START has prompt field
|
|
1130
|
+
const agentStartEvent = events.find((e) => e.type === BRAIN_EVENTS.AGENT_START);
|
|
1131
|
+
if (!agentStartEvent.prompt || typeof agentStartEvent.prompt !== 'string') {
|
|
1132
|
+
console.error('AGENT_START event missing prompt field');
|
|
1133
1133
|
return false;
|
|
1134
1134
|
}
|
|
1135
|
-
const
|
|
1136
|
-
if (!
|
|
1137
|
-
console.error('Missing
|
|
1135
|
+
const hasAgentIteration = events.some((e) => e.type === BRAIN_EVENTS.AGENT_ITERATION);
|
|
1136
|
+
if (!hasAgentIteration) {
|
|
1137
|
+
console.error('Missing AGENT_ITERATION event in SSE stream');
|
|
1138
1138
|
return false;
|
|
1139
1139
|
}
|
|
1140
|
-
const
|
|
1141
|
-
if (!
|
|
1142
|
-
console.error('Missing
|
|
1140
|
+
const hasAgentToolCall = events.some((e) => e.type === BRAIN_EVENTS.AGENT_TOOL_CALL);
|
|
1141
|
+
if (!hasAgentToolCall) {
|
|
1142
|
+
console.error('Missing AGENT_TOOL_CALL event in SSE stream');
|
|
1143
1143
|
return false;
|
|
1144
1144
|
}
|
|
1145
|
-
// If we got a WEBHOOK event, verify
|
|
1145
|
+
// If we got a WEBHOOK event, verify AGENT_WEBHOOK came before it
|
|
1146
1146
|
const webhookIndex = events.findIndex((e) => e.type === BRAIN_EVENTS.WEBHOOK);
|
|
1147
1147
|
if (webhookIndex !== -1) {
|
|
1148
|
-
const
|
|
1149
|
-
if (
|
|
1150
|
-
console.error('Missing
|
|
1148
|
+
const agentWebhookIndex = events.findIndex((e) => e.type === BRAIN_EVENTS.AGENT_WEBHOOK);
|
|
1149
|
+
if (agentWebhookIndex === -1) {
|
|
1150
|
+
console.error('Missing AGENT_WEBHOOK event before WEBHOOK event');
|
|
1151
1151
|
return false;
|
|
1152
1152
|
}
|
|
1153
|
-
if (
|
|
1154
|
-
console.error('
|
|
1153
|
+
if (agentWebhookIndex >= webhookIndex) {
|
|
1154
|
+
console.error('AGENT_WEBHOOK event must come before WEBHOOK event');
|
|
1155
1155
|
return false;
|
|
1156
1156
|
}
|
|
1157
|
-
// Verify
|
|
1158
|
-
const
|
|
1159
|
-
if (!
|
|
1160
|
-
console.error('
|
|
1157
|
+
// Verify AGENT_WEBHOOK has required fields
|
|
1158
|
+
const agentWebhookEvent = events[agentWebhookIndex];
|
|
1159
|
+
if (!agentWebhookEvent.toolCallId || !agentWebhookEvent.toolName) {
|
|
1160
|
+
console.error('AGENT_WEBHOOK event missing toolCallId or toolName fields');
|
|
1161
1161
|
return false;
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
1164
|
return true;
|
|
1165
1165
|
}
|
|
1166
1166
|
catch (error) {
|
|
1167
|
-
console.error(`Failed to test
|
|
1167
|
+
console.error(`Failed to test agent events for ${agentBrainIdentifier}:`, error);
|
|
1168
1168
|
return false;
|
|
1169
1169
|
}
|
|
1170
1170
|
},
|
|
1171
1171
|
/**
|
|
1172
|
-
* Test full
|
|
1173
|
-
* 1. Start
|
|
1172
|
+
* Test full agent webhook resumption flow:
|
|
1173
|
+
* 1. Start an agent brain that will pause on a webhook
|
|
1174
1174
|
* 2. Verify it pauses with WEBHOOK event
|
|
1175
1175
|
* 3. Trigger the webhook with a response
|
|
1176
|
-
* 4. Verify the brain resumes and emits WEBHOOK_RESPONSE and
|
|
1176
|
+
* 4. Verify the brain resumes and emits WEBHOOK_RESPONSE and AGENT_TOOL_RESULT
|
|
1177
1177
|
*
|
|
1178
1178
|
* Requires:
|
|
1179
|
-
* - A brain with
|
|
1179
|
+
* - A brain with an agent step that calls a tool returning { waitFor: webhook(...) }
|
|
1180
1180
|
* - The webhook slug and identifier to trigger
|
|
1181
1181
|
*/
|
|
1182
|
-
async
|
|
1182
|
+
async agentWebhookResume(fetch, agentBrainIdentifier, webhookSlug, webhookPayload) {
|
|
1183
1183
|
try {
|
|
1184
|
-
// Step 1: Start the
|
|
1184
|
+
// Step 1: Start the agent brain
|
|
1185
1185
|
const runRequest = new Request('http://example.com/brains/runs', {
|
|
1186
1186
|
method: 'POST',
|
|
1187
1187
|
headers: { 'Content-Type': 'application/json' },
|
|
1188
|
-
body: JSON.stringify({ identifier:
|
|
1188
|
+
body: JSON.stringify({ identifier: agentBrainIdentifier }),
|
|
1189
1189
|
});
|
|
1190
1190
|
const runResponse = await fetch(runRequest);
|
|
1191
1191
|
if (runResponse.status !== 201) {
|
|
@@ -1313,10 +1313,10 @@ export const brains = {
|
|
|
1313
1313
|
console.error('Missing WEBHOOK_RESPONSE event after resume');
|
|
1314
1314
|
return false;
|
|
1315
1315
|
}
|
|
1316
|
-
// Verify
|
|
1317
|
-
const
|
|
1318
|
-
if (!
|
|
1319
|
-
console.error('Missing
|
|
1316
|
+
// Verify AGENT_TOOL_RESULT event is present (with the webhook response as result)
|
|
1317
|
+
const hasAgentToolResult = resumeEvents.some((e) => e.type === BRAIN_EVENTS.AGENT_TOOL_RESULT);
|
|
1318
|
+
if (!hasAgentToolResult) {
|
|
1319
|
+
console.error('Missing AGENT_TOOL_RESULT event after resume');
|
|
1320
1320
|
return false;
|
|
1321
1321
|
}
|
|
1322
1322
|
// Verify brain completed successfully
|
|
@@ -1332,7 +1332,7 @@ export const brains = {
|
|
|
1332
1332
|
return true;
|
|
1333
1333
|
}
|
|
1334
1334
|
catch (error) {
|
|
1335
|
-
console.error(`Failed to test
|
|
1335
|
+
console.error(`Failed to test agent webhook resume for ${agentBrainIdentifier}:`, error);
|
|
1336
1336
|
return false;
|
|
1337
1337
|
}
|
|
1338
1338
|
},
|
|
@@ -1974,6 +1974,97 @@ export const webhooks = {
|
|
|
1974
1974
|
return false;
|
|
1975
1975
|
}
|
|
1976
1976
|
},
|
|
1977
|
+
/**
|
|
1978
|
+
* Test POST /webhooks/system/ui-form - Built-in webhook for UI form submissions.
|
|
1979
|
+
* This is used by pages generated via .ui() steps to submit form data.
|
|
1980
|
+
*
|
|
1981
|
+
* The endpoint:
|
|
1982
|
+
* - Accepts form data (application/x-www-form-urlencoded or multipart/form-data)
|
|
1983
|
+
* - Requires an `identifier` query parameter to match the waiting brain
|
|
1984
|
+
* - Returns { received: true, action: 'resumed' | 'not_found', ... }
|
|
1985
|
+
*/
|
|
1986
|
+
async uiForm(fetch, identifier, formData) {
|
|
1987
|
+
try {
|
|
1988
|
+
// Build URLSearchParams from form data
|
|
1989
|
+
const params = new URLSearchParams();
|
|
1990
|
+
for (const [key, value] of Object.entries(formData)) {
|
|
1991
|
+
if (Array.isArray(value)) {
|
|
1992
|
+
for (const v of value) {
|
|
1993
|
+
params.append(`${key}[]`, v);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
else {
|
|
1997
|
+
params.append(key, value);
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
const request = new Request(`http://example.com/webhooks/system/ui-form?identifier=${encodeURIComponent(identifier)}`, {
|
|
2001
|
+
method: 'POST',
|
|
2002
|
+
headers: {
|
|
2003
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
2004
|
+
},
|
|
2005
|
+
body: params.toString(),
|
|
2006
|
+
});
|
|
2007
|
+
const response = await fetch(request);
|
|
2008
|
+
// Accept 200 (found and processed) or 404 (no brain waiting)
|
|
2009
|
+
if (response.status !== 200 && response.status !== 404) {
|
|
2010
|
+
console.error(`POST /webhooks/system/ui-form returned ${response.status}, expected 200 or 404`);
|
|
2011
|
+
return false;
|
|
2012
|
+
}
|
|
2013
|
+
const data = (await response.json());
|
|
2014
|
+
// Validate response structure
|
|
2015
|
+
if (typeof data.received !== 'boolean') {
|
|
2016
|
+
console.error(`Expected received to be boolean, got ${typeof data.received}`);
|
|
2017
|
+
return false;
|
|
2018
|
+
}
|
|
2019
|
+
if (!data.action || typeof data.action !== 'string') {
|
|
2020
|
+
console.error(`Expected action to be string, got ${typeof data.action}`);
|
|
2021
|
+
return false;
|
|
2022
|
+
}
|
|
2023
|
+
// Action should be 'resumed' or 'not_found'
|
|
2024
|
+
if (data.action !== 'resumed' && data.action !== 'not_found') {
|
|
2025
|
+
console.error(`Expected action to be 'resumed' or 'not_found', got '${data.action}'`);
|
|
2026
|
+
return false;
|
|
2027
|
+
}
|
|
2028
|
+
return true;
|
|
2029
|
+
}
|
|
2030
|
+
catch (error) {
|
|
2031
|
+
console.error('Failed to test POST /webhooks/system/ui-form:', error);
|
|
2032
|
+
return false;
|
|
2033
|
+
}
|
|
2034
|
+
},
|
|
2035
|
+
/**
|
|
2036
|
+
* Test POST /webhooks/system/ui-form with missing identifier - Should return 400
|
|
2037
|
+
*/
|
|
2038
|
+
async uiFormMissingIdentifier(fetch) {
|
|
2039
|
+
try {
|
|
2040
|
+
const request = new Request('http://example.com/webhooks/system/ui-form', {
|
|
2041
|
+
method: 'POST',
|
|
2042
|
+
headers: {
|
|
2043
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
2044
|
+
},
|
|
2045
|
+
body: 'test=data',
|
|
2046
|
+
});
|
|
2047
|
+
const response = await fetch(request);
|
|
2048
|
+
if (response.status !== 400) {
|
|
2049
|
+
console.error(`POST /webhooks/system/ui-form without identifier returned ${response.status}, expected 400`);
|
|
2050
|
+
return false;
|
|
2051
|
+
}
|
|
2052
|
+
const data = (await response.json());
|
|
2053
|
+
if (!data.error || typeof data.error !== 'string') {
|
|
2054
|
+
console.error(`Expected error to be string, got ${typeof data.error}`);
|
|
2055
|
+
return false;
|
|
2056
|
+
}
|
|
2057
|
+
if (!data.error.toLowerCase().includes('identifier')) {
|
|
2058
|
+
console.error(`Expected error message to mention identifier, got: ${data.error}`);
|
|
2059
|
+
return false;
|
|
2060
|
+
}
|
|
2061
|
+
return true;
|
|
2062
|
+
}
|
|
2063
|
+
catch (error) {
|
|
2064
|
+
console.error('Failed to test POST /webhooks/system/ui-form without identifier:', error);
|
|
2065
|
+
return false;
|
|
2066
|
+
}
|
|
2067
|
+
},
|
|
1977
2068
|
};
|
|
1978
2069
|
export const pages = {
|
|
1979
2070
|
/**
|
|
@@ -2306,4 +2397,59 @@ export const pages = {
|
|
|
2306
2397
|
}
|
|
2307
2398
|
},
|
|
2308
2399
|
};
|
|
2400
|
+
/**
|
|
2401
|
+
* Bundle API Tests
|
|
2402
|
+
*
|
|
2403
|
+
* Tests for the /bundle/components.js endpoint which serves the component bundle.
|
|
2404
|
+
*
|
|
2405
|
+
* NOTE: These tests only verify the API endpoint behavior. The bundle build and
|
|
2406
|
+
* upload process is backend-specific and must be tested separately by each
|
|
2407
|
+
* backend implementation.
|
|
2408
|
+
*/
|
|
2409
|
+
export const bundle = {
|
|
2410
|
+
/**
|
|
2411
|
+
* Test GET /bundle/components.js - Serve the component bundle
|
|
2412
|
+
*/
|
|
2413
|
+
async get(fetch) {
|
|
2414
|
+
try {
|
|
2415
|
+
const request = new Request('http://example.com/bundle/components.js', {
|
|
2416
|
+
method: 'GET',
|
|
2417
|
+
});
|
|
2418
|
+
const response = await fetch(request);
|
|
2419
|
+
// Bundle may or may not exist depending on project setup
|
|
2420
|
+
// 200 = bundle exists and served correctly
|
|
2421
|
+
// 404 = bundle not found (expected if no components/ directory)
|
|
2422
|
+
if (response.status !== 200 && response.status !== 404) {
|
|
2423
|
+
console.error(`GET /bundle/components.js returned unexpected status ${response.status}`);
|
|
2424
|
+
return false;
|
|
2425
|
+
}
|
|
2426
|
+
const contentType = response.headers.get('Content-Type');
|
|
2427
|
+
if (!contentType || !contentType.includes('application/javascript')) {
|
|
2428
|
+
console.error(`Expected Content-Type application/javascript, got ${contentType}`);
|
|
2429
|
+
return false;
|
|
2430
|
+
}
|
|
2431
|
+
// If 200, verify we got some content
|
|
2432
|
+
if (response.status === 200) {
|
|
2433
|
+
const content = await response.text();
|
|
2434
|
+
if (!content || content.length === 0) {
|
|
2435
|
+
console.error('Bundle endpoint returned 200 but empty content');
|
|
2436
|
+
return false;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
// If 404, verify we got the helpful error message
|
|
2440
|
+
if (response.status === 404) {
|
|
2441
|
+
const content = await response.text();
|
|
2442
|
+
if (!content.includes('Bundle not found')) {
|
|
2443
|
+
console.error('Bundle 404 response missing helpful error message');
|
|
2444
|
+
return false;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
return true;
|
|
2448
|
+
}
|
|
2449
|
+
catch (error) {
|
|
2450
|
+
console.error(`Failed to test GET /bundle/components.js:`, error);
|
|
2451
|
+
return false;
|
|
2452
|
+
}
|
|
2453
|
+
},
|
|
2454
|
+
};
|
|
2309
2455
|
//# sourceMappingURL=api.js.map
|