@rsc-kit/core 0.28.1 → 0.29.1

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.
@@ -24,7 +24,7 @@ import { pathToFileURL } from 'node:url';
24
24
  import { httpHostCalls } from './hostCalls.js';
25
25
  import { isNotFoundSignal } from './notFound.js';
26
26
  import { withRedirect } from './redirect.js';
27
- import { withRequest } from './request.js';
27
+ import { withRequest, withResponseDraft } from './request.js';
28
28
  import { ServerAuthenticationError, ServerAuthorizationError } from './js/errors.js';
29
29
  /**
30
30
  * What the adapter registers, and what each must do. Names are fixed; how
@@ -45,10 +45,16 @@ export const CASES = {
45
45
  'Conformance.revalidate': 'Mark the region "orders" stale, and return "ok".',
46
46
  'Conformance.fail': 'Fail unexpectedly: an ordinary error, not a refusal.',
47
47
  'Conformance.authorization': "Return the request's Authorization header, as the renderer forwarded it.",
48
- '__rsc.middleware': 'Guards: "conformance-allow" passes; "conformance-deny" refuses; a name with no guard refuses.',
48
+ 'Conformance.cookie': "Return the request's Cookie header, as the renderer forwarded it.",
49
+ 'Conformance.login': 'Set a cookie named "conformance_login" on the response, the way a login sets its session cookie, and return "ok".',
50
+ 'Conformance.double': 'Take one integer and return it doubled. Arguments that do not fit - a string, none - fail it: a 500, not a refusal.',
51
+ 'Conformance.invalidNested': 'Refuse the input with errors on the nested field "address.city" and on the form itself, under "".',
52
+ '__rsc.middleware': 'Guards, run in the order named, stopping at the first that does not pass: "conformance-allow" passes; ' +
53
+ '"conformance-deny" refuses; "conformance-redirect" sends the visitor to /conformance-login; a name with no guard refuses.',
49
54
  'Conformance.change': 'Say the name "conformance:changed" changed, the way the adapter does from a webhook, and return "ok".',
50
- '__rsc.changed': 'Given { since: { name: version }, wait }: answer { versions } with every name whose version differs from since now. ' +
51
- 'A name never changed is at 0. May hold the call up to wait ms for one to differ; may answer at once.',
55
+ '__rsc.changed': 'Given { since: { name: version }, wait }: answer { versions } with every name whose version differs from since now, ' +
56
+ 'and no other. A name never changed is at 0. A change moves a version to the larger of one past it and the time in ' +
57
+ 'ms - never + 1 alone. May hold the call up to wait ms for one to differ; may answer at once.',
52
58
  };
53
59
  const INSTANT = Date.parse('2026-01-02T03:04:05Z');
54
60
  const ECHOES = [null, 0, -1.5, 'héllo ✓ "quoted"', [1, 'a', null], { a: { b: [true, false] }, c: '' }];
@@ -59,7 +65,7 @@ const ECHOES = [null, 0, -1.5, 'héllo ✓ "quoted"', [1, 'a', null], { a: { b:
59
65
  * its onRevalidate - so the revalidation case can read it.
60
66
  */
61
67
  export async function conformance(call, options) {
62
- const { revalidated, manifest, wrongSecret } = options;
68
+ const { revalidated, manifest, wrongSecret, raw } = options;
63
69
  const results = [];
64
70
  const types = typeof manifest === 'string' ? JSON.parse(readFileSync(manifest, 'utf-8')) : manifest;
65
71
  const check = async (name, run) => {
@@ -98,6 +104,11 @@ export async function conformance(call, options) {
98
104
  const missing = Object.keys(CASES).filter((n) => !n.startsWith('__') && !types.functions?.includes(n));
99
105
  expect(missing.length === 0, 'not in functions: ' + missing.join(', '));
100
106
  });
107
+ await check('the manifest\'s actions is an object, even with none', async () => {
108
+ if (!types)
109
+ return;
110
+ expect(typeof types.actions === 'object' && types.actions !== null && !Array.isArray(types.actions), 'actions is ' + JSON.stringify(types.actions));
111
+ });
101
112
  await check('a value of any JSON shape comes back unchanged', async () => {
102
113
  for (const value of ECHOES) {
103
114
  const back = await call('Conformance.echo', value);
@@ -148,6 +159,11 @@ export async function conformance(call, options) {
148
159
  expect(taken?.location === '/login', 'redirect ' + JSON.stringify(taken));
149
160
  expect(taken.status >= 300 && taken.status < 400, 'status ' + taken?.status);
150
161
  });
162
+ await check('in a batch, a revalidation stays with its own call', async () => {
163
+ const before = revalidated.length;
164
+ await Promise.all([call('Conformance.revalidate'), call('Conformance.echo', 1), call('Conformance.echo', 2)]);
165
+ expect(revalidated.length - before === 1, 'revalidated ' + JSON.stringify(revalidated.slice(before)));
166
+ });
151
167
  await check('a revalidation rides with the result', async () => {
152
168
  const value = await call('Conformance.revalidate');
153
169
  expect(value === 'ok', 'got ' + JSON.stringify(value));
@@ -161,6 +177,35 @@ export async function conformance(call, options) {
161
177
  const value = await withRequest(new Request('https://app.test/', { headers: { authorization: 'Bearer conformance' } }), () => call('Conformance.authorization'));
162
178
  expect(value === 'Bearer conformance', 'got ' + JSON.stringify(value));
163
179
  });
180
+ await check('the visitor\'s Cookie header is forwarded', async () => {
181
+ const value = await withRequest(new Request('https://app.test/', { headers: { cookie: 'conformance=1; other=2' } }), () => call('Conformance.cookie'));
182
+ expect(typeof value === 'string' && value.includes('conformance=1') && value.includes('other=2'), 'got ' + JSON.stringify(value));
183
+ });
184
+ await check('a cookie set during a call - a login - reaches the page\'s response', async () => {
185
+ const cookies = await withRequest(new Request('https://app.test/'), () => withResponseDraft(async ({ taken }) => {
186
+ const value = await call('Conformance.login');
187
+ expect(value === 'ok', 'got ' + JSON.stringify(value));
188
+ return taken().getSetCookie();
189
+ }));
190
+ expect(cookies.some((c) => c.startsWith('conformance_login=')), 'Set-Cookie ' + JSON.stringify(cookies));
191
+ });
192
+ await check('arguments are decoded to their types', async () => {
193
+ const value = await call('Conformance.double', 21);
194
+ expect(value === 42, 'got ' + JSON.stringify(value));
195
+ });
196
+ await check('arguments that do not fit fail the call, not refuse it', async () => {
197
+ for (const args of [['twenty-one'], []]) {
198
+ const error = await rejection(() => call('Conformance.double', ...args));
199
+ const fields = error;
200
+ expect(error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) &&
201
+ !fields.refusalStatus && fields.errors === undefined && !isNotFoundSignal(error), `with ${JSON.stringify(args)}: got ` + String(error));
202
+ }
203
+ });
204
+ await check('refused input names nested fields with dots, and the form under ""', async () => {
205
+ const error = (await rejection(() => call('Conformance.invalidNested')));
206
+ expect(Array.isArray(error.errors?.['address.city']) && error.errors['address.city'].length > 0, 'errors ' + JSON.stringify(error.errors));
207
+ expect(Array.isArray(error.errors?.['']) && error.errors[''].length > 0, 'errors ' + JSON.stringify(error.errors));
208
+ });
164
209
  await check('calls in one batch are each answered, a refusal only its own', async () => {
165
210
  const [a, b, c] = await Promise.allSettled([
166
211
  call('Conformance.echo', 1),
@@ -179,6 +224,24 @@ export async function conformance(call, options) {
179
224
  const value = await call('__rsc.middleware', ['conformance-deny']).catch((e) => e);
180
225
  expect(value !== true, 'it answered true');
181
226
  });
227
+ await check('a guard can send the visitor somewhere else', async () => {
228
+ const taken = await withRedirect(async (seen) => {
229
+ await call('__rsc.middleware', ['conformance-redirect']).catch(() => { });
230
+ return seen();
231
+ });
232
+ expect(taken?.location === '/conformance-login', 'redirect ' + JSON.stringify(taken));
233
+ });
234
+ await check('guards run in order and stop at the first that does not pass', async () => {
235
+ const after = await call('__rsc.middleware', ['conformance-allow', 'conformance-deny']).catch((e) => e);
236
+ expect(after !== true, 'allow then deny answered true');
237
+ // Deny first: the redirect after it must never be asked.
238
+ const taken = await withRedirect(async (seen) => {
239
+ const value = await call('__rsc.middleware', ['conformance-deny', 'conformance-redirect']).catch((e) => e);
240
+ expect(value !== true, 'deny then redirect answered true');
241
+ return seen();
242
+ });
243
+ expect(taken === null, 'the guard after a refusal ran: redirected to ' + JSON.stringify(taken));
244
+ });
182
245
  await check('a guard nobody registered refuses: fail closed', async () => {
183
246
  const value = await call('__rsc.middleware', ['conformance-nobody-registered-this']).catch((e) => e);
184
247
  expect(value !== true, 'it answered true');
@@ -201,6 +264,23 @@ export async function conformance(call, options) {
201
264
  const moved = await versionsOf({ since: { 'conformance:changed': before } });
202
265
  expect(typeof moved['conformance:changed'] === 'number' && moved['conformance:changed'] !== before, 'from ' + before + ': ' + JSON.stringify(moved));
203
266
  });
267
+ await check('a version is the time of the change, and never comes round again', async () => {
268
+ // The larger of one past the old version and the time in ms: a counter
269
+ // repeats once a pruned name starts again from 0, and a tab holding the
270
+ // old value misses the next change. A minute's leeway for clock skew.
271
+ const started = Date.now();
272
+ await call('Conformance.change');
273
+ const first = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0;
274
+ expect(first >= started - 60_000, `a change at ${started} moved the version to ${first}: not a time in ms`);
275
+ await call('Conformance.change');
276
+ const second = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0;
277
+ expect(second > first, `a second change moved ${first} to ${second}`);
278
+ });
279
+ await check('only the names that differ are answered', async () => {
280
+ const current = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0;
281
+ const answer = await versionsOf({ since: { 'conformance:changed': current, 'conformance:never': 5 } });
282
+ expect(JSON.stringify(answer) === JSON.stringify({ 'conformance:never': 0 }), 'got ' + JSON.stringify(answer));
283
+ });
204
284
  await check('waiting for a name to change is bounded by wait', async () => {
205
285
  const started = Date.now();
206
286
  const none = await versionsOf({ since: { 'conformance:never': 0 }, wait: 300 });
@@ -208,6 +288,31 @@ export async function conformance(call, options) {
208
288
  expect(Object.keys(none).length === 0, 'got ' + JSON.stringify(none));
209
289
  expect(took < 3_000, 'took ' + took + 'ms');
210
290
  });
291
+ if (raw) {
292
+ const statusOf = async (body, secret = true) => (await raw(body, { secret })).status;
293
+ await check('a call with no secret at all is refused, 403', async () => {
294
+ const status = await statusOf(JSON.stringify({ function: 'Conformance.echo', args: [1] }), false);
295
+ expect(status === 403, 'answered ' + status);
296
+ });
297
+ await check('a function nobody registered is a 404', async () => {
298
+ const status = await statusOf(JSON.stringify({ function: 'Conformance.nobodyRegisteredThis', args: [] }));
299
+ expect(status === 404, 'answered ' + status);
300
+ });
301
+ await check('a malformed call is a 400: not JSON, no function, args not a list', async () => {
302
+ for (const body of ['not json', JSON.stringify({ args: [] }), JSON.stringify({ function: 'Conformance.echo', args: 'x' })]) {
303
+ const status = await statusOf(body);
304
+ expect(status === 400, `${body} answered ${status}`);
305
+ }
306
+ });
307
+ await check('a batch of more than 50 is refused, 413, before any call runs', async () => {
308
+ const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0;
309
+ const calls = Array.from({ length: 51 }, () => ({ function: 'Conformance.change', args: [] }));
310
+ const status = await statusOf(JSON.stringify({ calls }));
311
+ const after = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0;
312
+ expect(status === 413, 'answered ' + status);
313
+ expect(after === before, 'calls ran: conformance:changed moved from ' + before + ' to ' + after);
314
+ });
315
+ }
211
316
  if (wrongSecret) {
212
317
  await check('a call with the wrong secret is refused', async () => {
213
318
  const value = await wrongSecret('Conformance.echo', 'should not run').catch((e) => e);
@@ -225,10 +330,16 @@ export async function runConformance(options) {
225
330
  fetch: options.fetch,
226
331
  onRevalidate: (targets) => revalidated.push(targets),
227
332
  });
333
+ const doFetch = options.fetch ?? globalThis.fetch;
228
334
  return await conformance(client(options.secret), {
229
335
  revalidated,
230
336
  manifest: options.manifest,
231
337
  wrongSecret: client(options.secret + '-wrong'),
338
+ raw: (body, { secret = true } = {}) => doFetch(options.endpoint, {
339
+ method: 'POST',
340
+ headers: { 'content-type': 'application/json', ...(secret ? { 'x-rsc-host-secret': options.secret } : {}) },
341
+ body,
342
+ }),
232
343
  });
233
344
  }
234
345
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// The contract every backend adapter keeps, as a suite it runs against itself.\n//\n// A backend answers rpc(), actions and guards over one endpoint, and every\n// difference between how it and the engine read that wire is a bug in an\n// app that nobody wrote: a nil slice arriving as null where the type said a\n// list, a timestamp the type called unknown, a refusal that did not come out\n// as the error a page checks for. Each was found by an app, one at a time.\n// This finds them before an adapter ships.\n//\n// The adapter registers the Conformance.* functions described in CASES, in\n// its own language, the way an app would write them; this calls them through\n// the real client and checks what arrives. Where the adapter's manifest types\n// a function, every value it sends is checked against that type too.\n//\n// rsc-kit-conformance --endpoint http://127.0.0.1:8080/__rsc/host-call \\\n// --secret test-secret --manifest rsc-host.json\n//\n// The test host's hostReply passes the same suite (conformance.test.ts), so\n// a page test faking the backend fakes what a real adapter does.\n\nimport { readFileSync } from 'node:fs'\nimport { argv, exit, stderr, stdout } from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { httpHostCalls } from './hostCalls.js'\nimport { isNotFoundSignal } from './notFound.js'\nimport { withRedirect } from './redirect.js'\nimport { withRequest } from './request.js'\nimport { ServerAuthenticationError, ServerAuthorizationError } from './js/errors.js'\n\ntype Schema = Record<string, unknown>\n\n/** A host-call client: the real one in a run, the test host's in core's own test. */\nexport type ConformanceCall = (name: string, ...args: unknown[]) => Promise<unknown>\n\nexport interface ConformanceOptions {\n /** The adapter's host-call endpoint, e.g. http://127.0.0.1:8080/__rsc/host-call. */\n endpoint: string\n /** The secret the adapter checks. */\n secret: string\n /** The adapter's rsc-host.json, parsed or as a path: its types are checked against what arrives. */\n manifest?: string | { functions?: string[]; types?: Record<string, { result?: Schema }>; defs?: Record<string, Schema> }\n /** For a test: the fetch the client uses. */\n fetch?: typeof fetch\n}\n\nexport interface ConformanceResult {\n case: string\n ok: boolean\n /** What went wrong, when it did. */\n detail?: string\n}\n\n/**\n * What the adapter registers, and what each must do. Names are fixed; how\n * they are written is the adapter's - the point is that they are written the\n * way an app's would be, with the adapter's ordinary API.\n */\nexport const CASES = {\n 'Conformance.echo': 'Return its one argument unchanged: any JSON value, nested.',\n 'Conformance.emptyList': 'Return an empty list of objects, the way the language makes \"no rows\" (Go: a nil slice).',\n 'Conformance.time': \"Return the instant 2026-01-02T03:04:05Z as the language's own time value.\",\n 'Conformance.noTime': \"Return an absent time: a nil pointer, a null Carbon, typed as a time or nothing.\",\n 'Conformance.unauthenticated': 'Refuse as not signed in, the way the framework does.',\n 'Conformance.unauthorized': 'Refuse as signed in but not allowed.',\n 'Conformance.notFound': \"Refuse as not found (404), the way the framework does: Go's Refuse(404), Laravel's abort(404).\",\n 'Conformance.refuse': 'Refuse with status 429 and the message \"Slow down.\"',\n 'Conformance.invalid': 'Refuse the input: a validation error on the field \"name\".',\n 'Conformance.redirect': 'Send the visitor to /login.',\n 'Conformance.revalidate': 'Mark the region \"orders\" stale, and return \"ok\".',\n 'Conformance.fail': 'Fail unexpectedly: an ordinary error, not a refusal.',\n 'Conformance.authorization': \"Return the request's Authorization header, as the renderer forwarded it.\",\n '__rsc.middleware': 'Guards: \"conformance-allow\" passes; \"conformance-deny\" refuses; a name with no guard refuses.',\n 'Conformance.change': 'Say the name \"conformance:changed\" changed, the way the adapter does from a webhook, and return \"ok\".',\n '__rsc.changed':\n 'Given { since: { name: version }, wait }: answer { versions } with every name whose version differs from since now. ' +\n 'A name never changed is at 0. May hold the call up to wait ms for one to differ; may answer at once.',\n} as const\n\nconst INSTANT = Date.parse('2026-01-02T03:04:05Z')\n\nconst ECHOES: unknown[] = [null, 0, -1.5, 'héllo ✓ \"quoted\"', [1, 'a', null], { a: { b: [true, false] }, c: '' }]\n\n/**\n * Run the suite against a client. Every case runs; none stops another.\n *\n * `revalidated` is where the client records what each call marked stale -\n * its onRevalidate - so the revalidation case can read it.\n */\nexport async function conformance(\n call: ConformanceCall,\n options: { revalidated: string[][]; manifest?: ConformanceOptions['manifest']; wrongSecret?: ConformanceCall },\n): Promise<ConformanceResult[]> {\n const { revalidated, manifest, wrongSecret } = options\n const results: ConformanceResult[] = []\n const types = typeof manifest === 'string' ? JSON.parse(readFileSync(manifest, 'utf-8')) : manifest\n\n const check = async (name: string, run: () => Promise<void>) => {\n try {\n await run()\n results.push({ case: name, ok: true })\n } catch (error) {\n results.push({ case: name, ok: false, detail: error instanceof Error ? error.message : String(error) })\n }\n }\n\n const expect = (ok: boolean, detail: string) => {\n if (!ok) throw new Error(detail)\n }\n\n const rejection = async (run: () => Promise<unknown>): Promise<unknown> => {\n try {\n const value = await run()\n\n throw new Error('answered ' + JSON.stringify(value) + ' instead of refusing')\n } catch (error) {\n return error\n }\n }\n\n /** The value against the type the adapter's manifest declares, when it declares one. */\n const typed = (name: string, value: unknown) => {\n const schema = types?.types?.[name]?.result\n\n if (!schema) return\n\n const problem = conformsTo(value, schema, types?.defs ?? {}, 'result')\n\n expect(problem === null, `the manifest types ${name}'s result, and what arrived does not fit it: ${problem}`)\n }\n\n await check('the manifest lists every Conformance function', async () => {\n if (!types) return\n\n const missing = Object.keys(CASES).filter((n) => !n.startsWith('__') && !types.functions?.includes(n))\n\n expect(missing.length === 0, 'not in functions: ' + missing.join(', '))\n })\n\n await check('a value of any JSON shape comes back unchanged', async () => {\n for (const value of ECHOES) {\n const back = await call('Conformance.echo', value)\n\n expect(JSON.stringify(back) === JSON.stringify(value), `sent ${JSON.stringify(value)}, got ${JSON.stringify(back)}`)\n }\n })\n\n await check('\"no rows\" is an empty list, never null', async () => {\n const value = await call('Conformance.emptyList')\n\n expect(Array.isArray(value) && value.length === 0, 'got ' + JSON.stringify(value))\n typed('Conformance.emptyList', value)\n })\n\n await check('a time is an ISO 8601 string of the same instant', async () => {\n const value = await call('Conformance.time')\n\n expect(typeof value === 'string' && Date.parse(value) === INSTANT, 'got ' + JSON.stringify(value))\n typed('Conformance.time', value)\n })\n\n await check('an absent time is null', async () => {\n const value = await call('Conformance.noTime')\n\n expect(value === null, 'got ' + JSON.stringify(value))\n typed('Conformance.noTime', value)\n })\n\n await check('not signed in is the engine\\'s ServerAuthenticationError', async () => {\n const error = await rejection(() => call('Conformance.unauthenticated'))\n\n expect(error instanceof ServerAuthenticationError, 'got ' + String(error))\n })\n\n await check('not allowed is the engine\\'s ServerAuthorizationError', async () => {\n const error = await rejection(() => call('Conformance.unauthorized'))\n\n expect(error instanceof ServerAuthorizationError, 'got ' + String(error))\n })\n\n await check('not found is the engine\\'s notFound()', async () => {\n const error = await rejection(() => call('Conformance.notFound'))\n\n expect(isNotFoundSignal(error), 'got ' + String(error))\n })\n\n await check('a refusal keeps its status and its message', async () => {\n const error = (await rejection(() => call('Conformance.refuse'))) as Error & { refusalStatus?: number }\n\n expect(error.refusalStatus === 429, 'status ' + String(error.refusalStatus))\n expect(String(error.message).includes('Slow down.'), 'message ' + JSON.stringify(error.message))\n })\n\n await check('refused input names its field', async () => {\n const error = (await rejection(() => call('Conformance.invalid'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.name) && error.errors.name.length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('a redirect is the engine\\'s redirect, to where it said', async () => {\n const taken = await withRedirect(async (seen) => {\n await rejection(() => call('Conformance.redirect'))\n\n return seen()\n })\n\n expect(taken?.location === '/login', 'redirect ' + JSON.stringify(taken))\n expect(taken!.status >= 300 && taken!.status < 400, 'status ' + taken?.status)\n })\n\n await check('a revalidation rides with the result', async () => {\n const value = await call('Conformance.revalidate')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n expect(revalidated.some((r) => r.includes('orders')), 'revalidated ' + JSON.stringify(revalidated))\n })\n\n await check('an unexpected failure is an error, not a refusal', async () => {\n const error = (await rejection(() => call('Conformance.fail'))) as Error & { refusalStatus?: number }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) && !error.refusalStatus && !isNotFoundSignal(error),\n 'got ' + String(error),\n )\n })\n\n await check('the visitor\\'s Authorization header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { authorization: 'Bearer conformance' } }), () =>\n call('Conformance.authorization'),\n )\n\n expect(value === 'Bearer conformance', 'got ' + JSON.stringify(value))\n })\n\n await check('calls in one batch are each answered, a refusal only its own', async () => {\n const [a, b, c] = await Promise.allSettled([\n call('Conformance.echo', 1),\n call('Conformance.unauthenticated'),\n call('Conformance.echo', 2),\n ])\n\n expect(a.status === 'fulfilled' && a.value === 1, 'first ' + JSON.stringify(a))\n expect(b.status === 'rejected' && b.reason instanceof ServerAuthenticationError, 'second ' + String((b as PromiseRejectedResult).reason))\n expect(c.status === 'fulfilled' && c.value === 2, 'third ' + JSON.stringify(c))\n })\n\n await check('a guard that passes answers true', async () => {\n const value = await call('__rsc.middleware', ['conformance-allow'])\n\n expect(value === true, 'got ' + JSON.stringify(value))\n })\n\n await check('a guard that refuses refuses', async () => {\n const value = await call('__rsc.middleware', ['conformance-deny']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n await check('a guard nobody registered refuses: fail closed', async () => {\n const value = await call('__rsc.middleware', ['conformance-nobody-registered-this']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n const versionsOf = async (query: { since: Record<string, number>; wait?: number }) => {\n const answer = (await call('__rsc.changed', query)) as { versions?: Record<string, number> } | null\n\n expect(typeof answer?.versions === 'object' && answer.versions !== null, 'got ' + JSON.stringify(answer))\n\n return answer!.versions!\n }\n\n await check('a name nobody changed is at version 0, and unchanged from 0', async () => {\n const all = await versionsOf({ since: { 'conformance:never': -1 } })\n\n expect(all['conformance:never'] === 0, 'from -1: ' + JSON.stringify(all))\n\n const none = await versionsOf({ since: { 'conformance:never': 0 } })\n\n expect(Object.keys(none).length === 0, 'from 0: ' + JSON.stringify(none))\n })\n\n await check('saying a name changed moves its version', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const value = await call('Conformance.change')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n const moved = await versionsOf({ since: { 'conformance:changed': before } })\n\n expect(typeof moved['conformance:changed'] === 'number' && moved['conformance:changed'] !== before, 'from ' + before + ': ' + JSON.stringify(moved))\n })\n\n await check('waiting for a name to change is bounded by wait', async () => {\n const started = Date.now()\n const none = await versionsOf({ since: { 'conformance:never': 0 }, wait: 300 })\n const took = Date.now() - started\n\n expect(Object.keys(none).length === 0, 'got ' + JSON.stringify(none))\n expect(took < 3_000, 'took ' + took + 'ms')\n })\n\n if (wrongSecret) {\n await check('a call with the wrong secret is refused', async () => {\n const value = await wrongSecret('Conformance.echo', 'should not run').catch((e: unknown) => e)\n\n expect(value !== 'should not run', 'it ran')\n })\n }\n\n return results\n}\n\n/** Run the suite against an adapter's endpoint. */\nexport async function runConformance(options: ConformanceOptions): Promise<ConformanceResult[]> {\n const revalidated: string[][] = []\n const client = (secret: string) =>\n httpHostCalls({\n endpoint: options.endpoint,\n secret,\n fetch: options.fetch,\n onRevalidate: (targets) => revalidated.push(targets),\n })\n\n return await conformance(client(options.secret), {\n revalidated,\n manifest: options.manifest,\n wrongSecret: client(options.secret + '-wrong'),\n })\n}\n\n/**\n * Whether a value fits the JSON Schema subset the manifest uses. Null when it\n * does; otherwise where and why it does not.\n */\nexport function conformsTo(value: unknown, schema: Schema, defs: Record<string, Schema>, at: string): string | null {\n if (!schema || Object.keys(schema).length === 0) return null\n\n const ref = schema.$ref\n\n if (typeof ref === 'string' && ref.startsWith('#/defs/')) {\n const target = defs[ref.slice(7)]\n\n return target ? conformsTo(value, target, defs, at) : `${at}: ${ref} is not in defs`\n }\n\n if (Array.isArray(schema.anyOf)) {\n const fits = (schema.anyOf as Schema[]).some((s) => conformsTo(value, s, defs, at) === null)\n\n return fits ? null : `${at}: ${JSON.stringify(value)} is none of ${JSON.stringify(schema.anyOf)}`\n }\n\n if (Array.isArray(schema.enum)) {\n return (schema.enum as unknown[]).includes(value) ? null : `${at}: ${JSON.stringify(value)} is not one of ${JSON.stringify(schema.enum)}`\n }\n\n const kind = Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value\n\n switch (schema.type) {\n case 'string':\n if (kind !== 'string') return `${at}: expected a string, got ${JSON.stringify(value)}`\n if (schema.format === 'date-time' && Number.isNaN(Date.parse(value as string))) return `${at}: ${JSON.stringify(value)} is not a date-time`\n return null\n case 'integer':\n return Number.isInteger(value) ? null : `${at}: expected an integer, got ${JSON.stringify(value)}`\n case 'number':\n return kind === 'number' ? null : `${at}: expected a number, got ${JSON.stringify(value)}`\n case 'boolean':\n return kind === 'boolean' ? null : `${at}: expected a boolean, got ${JSON.stringify(value)}`\n case 'null':\n return value === null ? null : `${at}: expected null, got ${JSON.stringify(value)}`\n case 'array': {\n if (kind !== 'array') return `${at}: expected an array, got ${JSON.stringify(value)}`\n for (const [i, item] of (value as unknown[]).entries()) {\n const problem = conformsTo(item, schema.items as Schema, defs, `${at}[${i}]`)\n if (problem) return problem\n }\n return null\n }\n case 'object': {\n if (kind !== 'object') return `${at}: expected an object, got ${JSON.stringify(value)}`\n const object = value as Record<string, unknown>\n const properties = (schema.properties ?? {}) as Record<string, Schema>\n for (const name of (schema.required as string[] | undefined) ?? []) {\n if (!(name in object)) return `${at}.${name}: required, and missing`\n }\n for (const [name, s] of Object.entries(properties)) {\n if (name in object) {\n const problem = conformsTo(object[name], s, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n const extra = schema.additionalProperties as Schema | undefined\n if (extra && !schema.properties) {\n for (const [name, item] of Object.entries(object)) {\n const problem = conformsTo(item, extra, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n return null\n }\n default:\n return null\n }\n}\n\n/** Print a result table, and say whether the adapter conforms. */\nexport function report(results: ConformanceResult[]): boolean {\n for (const r of results) {\n stdout.write(` ${r.ok ? '✓' : '✗'} ${r.case}${r.ok ? '' : '\\n ' + r.detail}\\n`)\n }\n\n const failed = results.filter((r) => !r.ok).length\n\n stdout.write(failed === 0 ? `\\n conforms: ${results.length} cases\\n` : `\\n ${failed} of ${results.length} cases failed\\n`)\n\n return failed === 0\n}\n\n// Run as a command, not when imported.\nif (import.meta.url === pathToFileURL(argv[1] ?? '').href || argv[1]?.endsWith('rsc-kit-conformance')) {\n const flag = (name: string) => {\n const at = argv.indexOf('--' + name)\n\n return at === -1 ? undefined : argv[at + 1]\n }\n\n const endpoint = flag('endpoint')\n const secret = flag('secret')\n\n if (!endpoint || !secret) {\n stderr.write('usage: rsc-kit-conformance --endpoint <url> --secret <secret> [--manifest rsc-host.json]\\n')\n exit(2)\n }\n\n runConformance({ endpoint, secret, manifest: flag('manifest') })\n .then((results) => exit(report(results) ? 0 : 1))\n .catch((error: unknown) => {\n stderr.write('rsc-kit-conformance: ' + (error instanceof Error ? error.message : String(error)) + '\\n')\n exit(1)\n })\n}\n"]}
1
+ {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// The contract every backend adapter keeps, as a suite it runs against itself.\n//\n// A backend answers rpc(), actions and guards over one endpoint, and every\n// difference between how it and the engine read that wire is a bug in an\n// app that nobody wrote: a nil slice arriving as null where the type said a\n// list, a timestamp the type called unknown, a refusal that did not come out\n// as the error a page checks for. Each was found by an app, one at a time.\n// This finds them before an adapter ships.\n//\n// The adapter registers the Conformance.* functions described in CASES, in\n// its own language, the way an app would write them; this calls them through\n// the real client and checks what arrives. Where the adapter's manifest types\n// a function, every value it sends is checked against that type too.\n//\n// rsc-kit-conformance --endpoint http://127.0.0.1:8080/__rsc/host-call \\\n// --secret test-secret --manifest rsc-host.json\n//\n// The test host's hostReply passes the same suite (conformance.test.ts), so\n// a page test faking the backend fakes what a real adapter does.\n\nimport { readFileSync } from 'node:fs'\nimport { argv, exit, stderr, stdout } from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { httpHostCalls } from './hostCalls.js'\nimport { isNotFoundSignal } from './notFound.js'\nimport { withRedirect } from './redirect.js'\nimport { withRequest, withResponseDraft } from './request.js'\nimport { ServerAuthenticationError, ServerAuthorizationError } from './js/errors.js'\n\ntype Schema = Record<string, unknown>\n\n/** A host-call client: the real one in a run, the test host's in core's own test. */\nexport type ConformanceCall = (name: string, ...args: unknown[]) => Promise<unknown>\n\nexport interface ConformanceOptions {\n /** The adapter's host-call endpoint, e.g. http://127.0.0.1:8080/__rsc/host-call. */\n endpoint: string\n /** The secret the adapter checks. */\n secret: string\n /** The adapter's rsc-host.json, parsed or as a path: its types are checked against what arrives. */\n manifest?:\n | string\n | { actions?: unknown; functions?: string[]; types?: Record<string, { result?: Schema }>; defs?: Record<string, Schema> }\n /** For a test: the fetch the client uses. */\n fetch?: typeof fetch\n}\n\nexport interface ConformanceResult {\n case: string\n ok: boolean\n /** What went wrong, when it did. */\n detail?: string\n}\n\n/**\n * What the adapter registers, and what each must do. Names are fixed; how\n * they are written is the adapter's - the point is that they are written the\n * way an app's would be, with the adapter's ordinary API.\n */\nexport const CASES = {\n 'Conformance.echo': 'Return its one argument unchanged: any JSON value, nested.',\n 'Conformance.emptyList': 'Return an empty list of objects, the way the language makes \"no rows\" (Go: a nil slice).',\n 'Conformance.time': \"Return the instant 2026-01-02T03:04:05Z as the language's own time value.\",\n 'Conformance.noTime': \"Return an absent time: a nil pointer, a null Carbon, typed as a time or nothing.\",\n 'Conformance.unauthenticated': 'Refuse as not signed in, the way the framework does.',\n 'Conformance.unauthorized': 'Refuse as signed in but not allowed.',\n 'Conformance.notFound': \"Refuse as not found (404), the way the framework does: Go's Refuse(404), Laravel's abort(404).\",\n 'Conformance.refuse': 'Refuse with status 429 and the message \"Slow down.\"',\n 'Conformance.invalid': 'Refuse the input: a validation error on the field \"name\".',\n 'Conformance.redirect': 'Send the visitor to /login.',\n 'Conformance.revalidate': 'Mark the region \"orders\" stale, and return \"ok\".',\n 'Conformance.fail': 'Fail unexpectedly: an ordinary error, not a refusal.',\n 'Conformance.authorization': \"Return the request's Authorization header, as the renderer forwarded it.\",\n 'Conformance.cookie': \"Return the request's Cookie header, as the renderer forwarded it.\",\n 'Conformance.login': 'Set a cookie named \"conformance_login\" on the response, the way a login sets its session cookie, and return \"ok\".',\n 'Conformance.double': 'Take one integer and return it doubled. Arguments that do not fit - a string, none - fail it: a 500, not a refusal.',\n 'Conformance.invalidNested': 'Refuse the input with errors on the nested field \"address.city\" and on the form itself, under \"\".',\n '__rsc.middleware':\n 'Guards, run in the order named, stopping at the first that does not pass: \"conformance-allow\" passes; ' +\n '\"conformance-deny\" refuses; \"conformance-redirect\" sends the visitor to /conformance-login; a name with no guard refuses.',\n 'Conformance.change': 'Say the name \"conformance:changed\" changed, the way the adapter does from a webhook, and return \"ok\".',\n '__rsc.changed':\n 'Given { since: { name: version }, wait }: answer { versions } with every name whose version differs from since now, ' +\n 'and no other. A name never changed is at 0. A change moves a version to the larger of one past it and the time in ' +\n 'ms - never + 1 alone. May hold the call up to wait ms for one to differ; may answer at once.',\n} as const\n\nconst INSTANT = Date.parse('2026-01-02T03:04:05Z')\n\nconst ECHOES: unknown[] = [null, 0, -1.5, 'héllo ✓ \"quoted\"', [1, 'a', null], { a: { b: [true, false] }, c: '' }]\n\n/**\n * Run the suite against a client. Every case runs; none stops another.\n *\n * `revalidated` is where the client records what each call marked stale -\n * its onRevalidate - so the revalidation case can read it.\n */\nexport async function conformance(\n call: ConformanceCall,\n options: {\n revalidated: string[][]\n manifest?: ConformanceOptions['manifest']\n wrongSecret?: ConformanceCall\n /**\n * A POST straight to the endpoint, for what the client never sends:\n * malformed bodies, an oversized batch, no secret at all. `secret: false`\n * leaves the header off.\n */\n raw?: (body: string, options?: { secret?: boolean }) => Promise<Response>\n },\n): Promise<ConformanceResult[]> {\n const { revalidated, manifest, wrongSecret, raw } = options\n const results: ConformanceResult[] = []\n const types = typeof manifest === 'string' ? JSON.parse(readFileSync(manifest, 'utf-8')) : manifest\n\n const check = async (name: string, run: () => Promise<void>) => {\n try {\n await run()\n results.push({ case: name, ok: true })\n } catch (error) {\n results.push({ case: name, ok: false, detail: error instanceof Error ? error.message : String(error) })\n }\n }\n\n const expect = (ok: boolean, detail: string) => {\n if (!ok) throw new Error(detail)\n }\n\n const rejection = async (run: () => Promise<unknown>): Promise<unknown> => {\n try {\n const value = await run()\n\n throw new Error('answered ' + JSON.stringify(value) + ' instead of refusing')\n } catch (error) {\n return error\n }\n }\n\n /** The value against the type the adapter's manifest declares, when it declares one. */\n const typed = (name: string, value: unknown) => {\n const schema = types?.types?.[name]?.result\n\n if (!schema) return\n\n const problem = conformsTo(value, schema, types?.defs ?? {}, 'result')\n\n expect(problem === null, `the manifest types ${name}'s result, and what arrived does not fit it: ${problem}`)\n }\n\n await check('the manifest lists every Conformance function', async () => {\n if (!types) return\n\n const missing = Object.keys(CASES).filter((n) => !n.startsWith('__') && !types.functions?.includes(n))\n\n expect(missing.length === 0, 'not in functions: ' + missing.join(', '))\n })\n\n await check('the manifest\\'s actions is an object, even with none', async () => {\n if (!types) return\n\n expect(\n typeof types.actions === 'object' && types.actions !== null && !Array.isArray(types.actions),\n 'actions is ' + JSON.stringify(types.actions),\n )\n })\n\n await check('a value of any JSON shape comes back unchanged', async () => {\n for (const value of ECHOES) {\n const back = await call('Conformance.echo', value)\n\n expect(JSON.stringify(back) === JSON.stringify(value), `sent ${JSON.stringify(value)}, got ${JSON.stringify(back)}`)\n }\n })\n\n await check('\"no rows\" is an empty list, never null', async () => {\n const value = await call('Conformance.emptyList')\n\n expect(Array.isArray(value) && value.length === 0, 'got ' + JSON.stringify(value))\n typed('Conformance.emptyList', value)\n })\n\n await check('a time is an ISO 8601 string of the same instant', async () => {\n const value = await call('Conformance.time')\n\n expect(typeof value === 'string' && Date.parse(value) === INSTANT, 'got ' + JSON.stringify(value))\n typed('Conformance.time', value)\n })\n\n await check('an absent time is null', async () => {\n const value = await call('Conformance.noTime')\n\n expect(value === null, 'got ' + JSON.stringify(value))\n typed('Conformance.noTime', value)\n })\n\n await check('not signed in is the engine\\'s ServerAuthenticationError', async () => {\n const error = await rejection(() => call('Conformance.unauthenticated'))\n\n expect(error instanceof ServerAuthenticationError, 'got ' + String(error))\n })\n\n await check('not allowed is the engine\\'s ServerAuthorizationError', async () => {\n const error = await rejection(() => call('Conformance.unauthorized'))\n\n expect(error instanceof ServerAuthorizationError, 'got ' + String(error))\n })\n\n await check('not found is the engine\\'s notFound()', async () => {\n const error = await rejection(() => call('Conformance.notFound'))\n\n expect(isNotFoundSignal(error), 'got ' + String(error))\n })\n\n await check('a refusal keeps its status and its message', async () => {\n const error = (await rejection(() => call('Conformance.refuse'))) as Error & { refusalStatus?: number }\n\n expect(error.refusalStatus === 429, 'status ' + String(error.refusalStatus))\n expect(String(error.message).includes('Slow down.'), 'message ' + JSON.stringify(error.message))\n })\n\n await check('refused input names its field', async () => {\n const error = (await rejection(() => call('Conformance.invalid'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.name) && error.errors.name.length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('a redirect is the engine\\'s redirect, to where it said', async () => {\n const taken = await withRedirect(async (seen) => {\n await rejection(() => call('Conformance.redirect'))\n\n return seen()\n })\n\n expect(taken?.location === '/login', 'redirect ' + JSON.stringify(taken))\n expect(taken!.status >= 300 && taken!.status < 400, 'status ' + taken?.status)\n })\n\n await check('in a batch, a revalidation stays with its own call', async () => {\n const before = revalidated.length\n\n await Promise.all([call('Conformance.revalidate'), call('Conformance.echo', 1), call('Conformance.echo', 2)])\n\n expect(revalidated.length - before === 1, 'revalidated ' + JSON.stringify(revalidated.slice(before)))\n })\n\n await check('a revalidation rides with the result', async () => {\n const value = await call('Conformance.revalidate')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n expect(revalidated.some((r) => r.includes('orders')), 'revalidated ' + JSON.stringify(revalidated))\n })\n\n await check('an unexpected failure is an error, not a refusal', async () => {\n const error = (await rejection(() => call('Conformance.fail'))) as Error & { refusalStatus?: number }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) && !error.refusalStatus && !isNotFoundSignal(error),\n 'got ' + String(error),\n )\n })\n\n await check('the visitor\\'s Authorization header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { authorization: 'Bearer conformance' } }), () =>\n call('Conformance.authorization'),\n )\n\n expect(value === 'Bearer conformance', 'got ' + JSON.stringify(value))\n })\n\n await check('the visitor\\'s Cookie header is forwarded', async () => {\n const value = await withRequest(new Request('https://app.test/', { headers: { cookie: 'conformance=1; other=2' } }), () =>\n call('Conformance.cookie'),\n )\n\n expect(typeof value === 'string' && value.includes('conformance=1') && value.includes('other=2'), 'got ' + JSON.stringify(value))\n })\n\n await check('a cookie set during a call - a login - reaches the page\\'s response', async () => {\n const cookies = await withRequest(new Request('https://app.test/'), () =>\n withResponseDraft(async ({ taken }) => {\n const value = await call('Conformance.login')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n return taken().getSetCookie()\n }),\n )\n\n expect(cookies.some((c) => c.startsWith('conformance_login=')), 'Set-Cookie ' + JSON.stringify(cookies))\n })\n\n await check('arguments are decoded to their types', async () => {\n const value = await call('Conformance.double', 21)\n\n expect(value === 42, 'got ' + JSON.stringify(value))\n })\n\n await check('arguments that do not fit fail the call, not refuse it', async () => {\n for (const args of [['twenty-one'], []]) {\n const error: unknown = await rejection(() => call('Conformance.double', ...args))\n const fields = error as { refusalStatus?: number; errors?: unknown }\n\n expect(\n error instanceof Error && !(error instanceof ServerAuthenticationError) && !(error instanceof ServerAuthorizationError) &&\n !fields.refusalStatus && fields.errors === undefined && !isNotFoundSignal(error),\n `with ${JSON.stringify(args)}: got ` + String(error),\n )\n }\n })\n\n await check('refused input names nested fields with dots, and the form under \"\"', async () => {\n const error = (await rejection(() => call('Conformance.invalidNested'))) as { errors?: Record<string, string[]> }\n\n expect(Array.isArray(error.errors?.['address.city']) && error.errors['address.city'].length > 0, 'errors ' + JSON.stringify(error.errors))\n expect(Array.isArray(error.errors?.['']) && error.errors[''].length > 0, 'errors ' + JSON.stringify(error.errors))\n })\n\n await check('calls in one batch are each answered, a refusal only its own', async () => {\n const [a, b, c] = await Promise.allSettled([\n call('Conformance.echo', 1),\n call('Conformance.unauthenticated'),\n call('Conformance.echo', 2),\n ])\n\n expect(a.status === 'fulfilled' && a.value === 1, 'first ' + JSON.stringify(a))\n expect(b.status === 'rejected' && b.reason instanceof ServerAuthenticationError, 'second ' + String((b as PromiseRejectedResult).reason))\n expect(c.status === 'fulfilled' && c.value === 2, 'third ' + JSON.stringify(c))\n })\n\n await check('a guard that passes answers true', async () => {\n const value = await call('__rsc.middleware', ['conformance-allow'])\n\n expect(value === true, 'got ' + JSON.stringify(value))\n })\n\n await check('a guard that refuses refuses', async () => {\n const value = await call('__rsc.middleware', ['conformance-deny']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n await check('a guard can send the visitor somewhere else', async () => {\n const taken = await withRedirect(async (seen) => {\n await call('__rsc.middleware', ['conformance-redirect']).catch(() => {})\n\n return seen()\n })\n\n expect(taken?.location === '/conformance-login', 'redirect ' + JSON.stringify(taken))\n })\n\n await check('guards run in order and stop at the first that does not pass', async () => {\n const after = await call('__rsc.middleware', ['conformance-allow', 'conformance-deny']).catch((e: unknown) => e)\n\n expect(after !== true, 'allow then deny answered true')\n\n // Deny first: the redirect after it must never be asked.\n const taken = await withRedirect(async (seen) => {\n const value = await call('__rsc.middleware', ['conformance-deny', 'conformance-redirect']).catch((e: unknown) => e)\n\n expect(value !== true, 'deny then redirect answered true')\n\n return seen()\n })\n\n expect(taken === null, 'the guard after a refusal ran: redirected to ' + JSON.stringify(taken))\n })\n\n await check('a guard nobody registered refuses: fail closed', async () => {\n const value = await call('__rsc.middleware', ['conformance-nobody-registered-this']).catch((e: unknown) => e)\n\n expect(value !== true, 'it answered true')\n })\n\n const versionsOf = async (query: { since: Record<string, number>; wait?: number }) => {\n const answer = (await call('__rsc.changed', query)) as { versions?: Record<string, number> } | null\n\n expect(typeof answer?.versions === 'object' && answer.versions !== null, 'got ' + JSON.stringify(answer))\n\n return answer!.versions!\n }\n\n await check('a name nobody changed is at version 0, and unchanged from 0', async () => {\n const all = await versionsOf({ since: { 'conformance:never': -1 } })\n\n expect(all['conformance:never'] === 0, 'from -1: ' + JSON.stringify(all))\n\n const none = await versionsOf({ since: { 'conformance:never': 0 } })\n\n expect(Object.keys(none).length === 0, 'from 0: ' + JSON.stringify(none))\n })\n\n await check('saying a name changed moves its version', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const value = await call('Conformance.change')\n\n expect(value === 'ok', 'got ' + JSON.stringify(value))\n\n const moved = await versionsOf({ since: { 'conformance:changed': before } })\n\n expect(typeof moved['conformance:changed'] === 'number' && moved['conformance:changed'] !== before, 'from ' + before + ': ' + JSON.stringify(moved))\n })\n\n await check('a version is the time of the change, and never comes round again', async () => {\n // The larger of one past the old version and the time in ms: a counter\n // repeats once a pruned name starts again from 0, and a tab holding the\n // old value misses the next change. A minute's leeway for clock skew.\n const started = Date.now()\n\n await call('Conformance.change')\n\n const first = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(first >= started - 60_000, `a change at ${started} moved the version to ${first}: not a time in ms`)\n\n await call('Conformance.change')\n\n const second = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(second > first, `a second change moved ${first} to ${second}`)\n })\n\n await check('only the names that differ are answered', async () => {\n const current = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const answer = await versionsOf({ since: { 'conformance:changed': current, 'conformance:never': 5 } })\n\n expect(JSON.stringify(answer) === JSON.stringify({ 'conformance:never': 0 }), 'got ' + JSON.stringify(answer))\n })\n\n await check('waiting for a name to change is bounded by wait', async () => {\n const started = Date.now()\n const none = await versionsOf({ since: { 'conformance:never': 0 }, wait: 300 })\n const took = Date.now() - started\n\n expect(Object.keys(none).length === 0, 'got ' + JSON.stringify(none))\n expect(took < 3_000, 'took ' + took + 'ms')\n })\n\n if (raw) {\n const statusOf = async (body: string, secret = true) => (await raw(body, { secret })).status\n\n await check('a call with no secret at all is refused, 403', async () => {\n const status = await statusOf(JSON.stringify({ function: 'Conformance.echo', args: [1] }), false)\n\n expect(status === 403, 'answered ' + status)\n })\n\n await check('a function nobody registered is a 404', async () => {\n const status = await statusOf(JSON.stringify({ function: 'Conformance.nobodyRegisteredThis', args: [] }))\n\n expect(status === 404, 'answered ' + status)\n })\n\n await check('a malformed call is a 400: not JSON, no function, args not a list', async () => {\n for (const body of ['not json', JSON.stringify({ args: [] }), JSON.stringify({ function: 'Conformance.echo', args: 'x' })]) {\n const status = await statusOf(body)\n\n expect(status === 400, `${body} answered ${status}`)\n }\n })\n\n await check('a batch of more than 50 is refused, 413, before any call runs', async () => {\n const before = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n const calls = Array.from({ length: 51 }, () => ({ function: 'Conformance.change', args: [] }))\n const status = await statusOf(JSON.stringify({ calls }))\n const after = (await versionsOf({ since: { 'conformance:changed': -1 } }))['conformance:changed'] ?? 0\n\n expect(status === 413, 'answered ' + status)\n expect(after === before, 'calls ran: conformance:changed moved from ' + before + ' to ' + after)\n })\n }\n\n if (wrongSecret) {\n await check('a call with the wrong secret is refused', async () => {\n const value = await wrongSecret('Conformance.echo', 'should not run').catch((e: unknown) => e)\n\n expect(value !== 'should not run', 'it ran')\n })\n }\n\n return results\n}\n\n/** Run the suite against an adapter's endpoint. */\nexport async function runConformance(options: ConformanceOptions): Promise<ConformanceResult[]> {\n const revalidated: string[][] = []\n const client = (secret: string) =>\n httpHostCalls({\n endpoint: options.endpoint,\n secret,\n fetch: options.fetch,\n onRevalidate: (targets) => revalidated.push(targets),\n })\n\n const doFetch = options.fetch ?? globalThis.fetch\n\n return await conformance(client(options.secret), {\n revalidated,\n manifest: options.manifest,\n wrongSecret: client(options.secret + '-wrong'),\n raw: (body, { secret = true } = {}) =>\n doFetch(options.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...(secret ? { 'x-rsc-host-secret': options.secret } : {}) },\n body,\n }),\n })\n}\n\n/**\n * Whether a value fits the JSON Schema subset the manifest uses. Null when it\n * does; otherwise where and why it does not.\n */\nexport function conformsTo(value: unknown, schema: Schema, defs: Record<string, Schema>, at: string): string | null {\n if (!schema || Object.keys(schema).length === 0) return null\n\n const ref = schema.$ref\n\n if (typeof ref === 'string' && ref.startsWith('#/defs/')) {\n const target = defs[ref.slice(7)]\n\n return target ? conformsTo(value, target, defs, at) : `${at}: ${ref} is not in defs`\n }\n\n if (Array.isArray(schema.anyOf)) {\n const fits = (schema.anyOf as Schema[]).some((s) => conformsTo(value, s, defs, at) === null)\n\n return fits ? null : `${at}: ${JSON.stringify(value)} is none of ${JSON.stringify(schema.anyOf)}`\n }\n\n if (Array.isArray(schema.enum)) {\n return (schema.enum as unknown[]).includes(value) ? null : `${at}: ${JSON.stringify(value)} is not one of ${JSON.stringify(schema.enum)}`\n }\n\n const kind = Array.isArray(value) ? 'array' : value === null ? 'null' : typeof value\n\n switch (schema.type) {\n case 'string':\n if (kind !== 'string') return `${at}: expected a string, got ${JSON.stringify(value)}`\n if (schema.format === 'date-time' && Number.isNaN(Date.parse(value as string))) return `${at}: ${JSON.stringify(value)} is not a date-time`\n return null\n case 'integer':\n return Number.isInteger(value) ? null : `${at}: expected an integer, got ${JSON.stringify(value)}`\n case 'number':\n return kind === 'number' ? null : `${at}: expected a number, got ${JSON.stringify(value)}`\n case 'boolean':\n return kind === 'boolean' ? null : `${at}: expected a boolean, got ${JSON.stringify(value)}`\n case 'null':\n return value === null ? null : `${at}: expected null, got ${JSON.stringify(value)}`\n case 'array': {\n if (kind !== 'array') return `${at}: expected an array, got ${JSON.stringify(value)}`\n for (const [i, item] of (value as unknown[]).entries()) {\n const problem = conformsTo(item, schema.items as Schema, defs, `${at}[${i}]`)\n if (problem) return problem\n }\n return null\n }\n case 'object': {\n if (kind !== 'object') return `${at}: expected an object, got ${JSON.stringify(value)}`\n const object = value as Record<string, unknown>\n const properties = (schema.properties ?? {}) as Record<string, Schema>\n for (const name of (schema.required as string[] | undefined) ?? []) {\n if (!(name in object)) return `${at}.${name}: required, and missing`\n }\n for (const [name, s] of Object.entries(properties)) {\n if (name in object) {\n const problem = conformsTo(object[name], s, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n const extra = schema.additionalProperties as Schema | undefined\n if (extra && !schema.properties) {\n for (const [name, item] of Object.entries(object)) {\n const problem = conformsTo(item, extra, defs, `${at}.${name}`)\n if (problem) return problem\n }\n }\n return null\n }\n default:\n return null\n }\n}\n\n/** Print a result table, and say whether the adapter conforms. */\nexport function report(results: ConformanceResult[]): boolean {\n for (const r of results) {\n stdout.write(` ${r.ok ? '✓' : '✗'} ${r.case}${r.ok ? '' : '\\n ' + r.detail}\\n`)\n }\n\n const failed = results.filter((r) => !r.ok).length\n\n stdout.write(failed === 0 ? `\\n conforms: ${results.length} cases\\n` : `\\n ${failed} of ${results.length} cases failed\\n`)\n\n return failed === 0\n}\n\n// Run as a command, not when imported.\nif (import.meta.url === pathToFileURL(argv[1] ?? '').href || argv[1]?.endsWith('rsc-kit-conformance')) {\n const flag = (name: string) => {\n const at = argv.indexOf('--' + name)\n\n return at === -1 ? undefined : argv[at + 1]\n }\n\n const endpoint = flag('endpoint')\n const secret = flag('secret')\n\n if (!endpoint || !secret) {\n stderr.write('usage: rsc-kit-conformance --endpoint <url> --secret <secret> [--manifest rsc-host.json]\\n')\n exit(2)\n }\n\n runConformance({ endpoint, secret, manifest: flag('manifest') })\n .then((results) => exit(report(results) ? 0 : 1))\n .catch((error: unknown) => {\n stderr.write('rsc-kit-conformance: ' + (error instanceof Error ? error.message : String(error)) + '\\n')\n exit(1)\n })\n}\n"]}
package/dist/host.js CHANGED
@@ -66,7 +66,7 @@ export { redirect } from "./redirect.js";
66
66
  export { matchIntercept, matchRoute, sharedDepth } from "./routing.js";
67
67
  import { FLIGHT_TYPE, HEADER, HTML_TYPE, PER_CLIENT, PER_REQUEST, REVALIDATE, VARY_ON_RSC, } from "./headers.js";
68
68
  import { ServerAuthenticationError, ServerAuthorizationError, } from "./js/errors.js";
69
- import { assertSigningSecret, changes } from "./changed.js";
69
+ import { assertSigningSecret, serveChanges } from "./changed.js";
70
70
  /**
71
71
  * The answer to a redirect that was decided before anything was written.
72
72
  *
@@ -736,8 +736,10 @@ export function createRscHandler(options) {
736
736
  // A tab waiting to hear that a name its page refreshes on has changed.
737
737
  // Signed names are its own authorization: the render that handed them
738
738
  // out ran under the page's guards.
739
- if (request.method === "GET" && url.pathname === HEADER.changesPath) {
740
- return await changes(request);
739
+ // On Workers with RSC_CHANGES_HUB, held by the hub rather than here; a
740
+ // hub's own poke is the one POST.
741
+ if (url.pathname === HEADER.changesPath) {
742
+ return await serveChanges(request);
741
743
  }
742
744
  // The two halves an edge cache needs: hand it a shell it may keep, and
743
745
  // finish that shell for a visitor it cannot answer for itself.