@gradial/aci 0.1.50 → 0.1.51-ssr.3

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +0 -21
  2. package/README.md +13 -20
  3. package/dist/astro/assets.d.ts +6 -6
  4. package/dist/astro/assets.js +6 -6
  5. package/dist/astro/index.d.ts +0 -2
  6. package/dist/astro/index.js +0 -4
  7. package/dist/cli/emit-error-pages.mjs +0 -1
  8. package/dist/cli/verify-next-cdn-routes.mjs +3 -4
  9. package/dist/collect/aci.js +1 -1
  10. package/dist/collect/aci.js.sha256 +1 -1
  11. package/dist/collect/batcher.d.ts +0 -6
  12. package/dist/collect/index.js +0 -9
  13. package/dist/collect/webvitals.d.ts +0 -3
  14. package/dist/collect/webvitals.js +11 -21
  15. package/dist/content/cache.d.ts +1 -9
  16. package/dist/content/cache.js +2 -37
  17. package/dist/content/error-pages.d.ts +1 -2
  18. package/dist/content/index.d.ts +0 -1
  19. package/dist/content/index.js +0 -1
  20. package/dist/index.d.ts +0 -1
  21. package/dist/internal/domain/edge/identity.d.ts +14 -0
  22. package/dist/internal/domain/edge/identity.js +214 -0
  23. package/dist/internal/domain/edge/index.d.ts +4 -0
  24. package/dist/internal/domain/edge/index.js +6 -0
  25. package/dist/internal/domain/edge/personalization-core.d.ts +24 -0
  26. package/dist/{edge → internal/domain/edge}/personalization-core.js +165 -64
  27. package/dist/internal/domain/edge/record/codec.d.ts +71 -0
  28. package/dist/internal/domain/edge/record/codec.js +401 -0
  29. package/dist/internal/domain/edge/resolve.d.ts +2 -0
  30. package/dist/internal/domain/edge/resolve.js +76 -0
  31. package/dist/{next/personalization-host.d.ts → internal/domain/edge/types.d.ts} +110 -63
  32. package/dist/internal/domain/edge/types.js +7 -0
  33. package/dist/internal/platform/collectionstore/errors.d.ts +5 -0
  34. package/dist/internal/platform/collectionstore/errors.js +7 -0
  35. package/dist/next/config.d.ts +0 -8
  36. package/dist/next/config.js +3 -78
  37. package/dist/next/error-pages.d.ts +2 -3
  38. package/dist/next/error-pages.js +5 -5
  39. package/dist/next/error-seat.d.ts +2 -3
  40. package/dist/next/index.d.ts +2 -2
  41. package/dist/next/index.js +1 -2
  42. package/dist/next/page.d.ts +3 -13
  43. package/dist/next/page.js +39 -51
  44. package/dist/next/server.d.ts +12 -32
  45. package/dist/next/server.js +66 -328
  46. package/dist/providers/object.d.ts +24 -0
  47. package/dist/providers/object.js +105 -0
  48. package/dist/providers/vercel-object-reader.d.ts +20 -0
  49. package/dist/providers/vercel-object-reader.js +45 -0
  50. package/dist/testing/conformance/checks.d.ts +1 -1
  51. package/dist/testing/conformance/checks.js +14 -152
  52. package/dist/testing/conformance/index.d.ts +1 -1
  53. package/dist/testing/conformance/index.js +1 -1
  54. package/dist/testing/conformance/preset.js +1 -1
  55. package/dist/testing/conformance/types.d.ts +1 -1
  56. package/dist/types/config.d.ts +0 -4
  57. package/dist/types/index.d.ts +0 -2
  58. package/dist/types/index.js +0 -2
  59. package/dist/types/page.d.ts +0 -10
  60. package/package.json +11 -35
  61. package/src/cli/emit-error-pages.mjs +0 -1
  62. package/src/cli/verify-next-cdn-routes.mjs +8 -11
  63. package/src/types/config.ts +0 -5
  64. package/src/types/index.ts +0 -2
  65. package/src/types/page.ts +0 -11
  66. package/templates/astro/template/.aci.yaml.tmpl +0 -11
  67. package/templates/common/.agents/skills/aci/SKILL.md +8 -9
  68. package/templates/common/.agents/skills/authoring/SKILL.md +3 -4
  69. package/templates/common/.agents/skills/authoring/references/block-registry.md +13 -36
  70. package/templates/common/.agents/skills/authoring/references/contracts.md +10 -17
  71. package/templates/common/.agents/skills/authoring/references/repo-structure.md +2 -2
  72. package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +45 -95
  73. package/templates/common/.agents/skills/migration/references/canon-migration.md +17 -37
  74. package/templates/nextjs/template/.aci.yaml.tmpl +0 -11
  75. package/templates/nextjs/template/README.md.tmpl +0 -1
  76. package/templates/nextjs/template/src/app/[[...slug]]/page.tsx +1 -1
  77. package/dist/collect/deviceclass.d.ts +0 -12
  78. package/dist/collect/deviceclass.js +0 -27
  79. package/dist/content/assets.d.ts +0 -18
  80. package/dist/content/assets.js +0 -66
  81. package/dist/edge/personalization-core.d.ts +0 -11
  82. package/dist/internal/render-proof.d.ts +0 -1
  83. package/dist/internal/render-proof.js +0 -197
  84. package/dist/next/asset-route.d.ts +0 -10
  85. package/dist/next/asset-route.js +0 -45
  86. package/dist/next/collect-route.d.ts +0 -19
  87. package/dist/next/collect-route.js +0 -459
  88. package/dist/next/edge-config.d.ts +0 -1
  89. package/dist/next/edge-config.js +0 -92
  90. package/dist/next/envelope-digest.d.ts +0 -21
  91. package/dist/next/envelope-digest.js +0 -58
  92. package/dist/next/middleware.d.ts +0 -40
  93. package/dist/next/middleware.js +0 -475
  94. package/dist/next/personalization-host.js +0 -270
  95. package/dist/next/vercel-collect-sdk-route.d.ts +0 -27
  96. package/dist/next/vercel-collect-sdk-route.js +0 -181
  97. package/dist/next/vercel-edge-projection-v1.d.ts +0 -24
  98. package/dist/next/vercel-edge-projection-v1.js +0 -880
  99. package/dist/next/vercel-personalization.d.ts +0 -4
  100. package/dist/next/vercel-personalization.js +0 -4
  101. package/dist/next/vercel-s3-personalization.d.ts +0 -79
  102. package/dist/next/vercel-s3-personalization.js +0 -570
  103. package/dist/providers/s3.d.ts +0 -47
  104. package/dist/providers/s3.js +0 -434
  105. package/dist/types/render-mode.d.ts +0 -2
  106. package/dist/types/render-mode.js +0 -1
  107. package/dist/types/renderer.d.ts +0 -71
  108. package/dist/types/renderer.js +0 -1
  109. package/src/types/render-mode.ts +0 -10
  110. package/src/types/renderer.ts +0 -83
  111. package/templates/nextjs/starter-content/src/middleware.ts +0 -49
  112. package/templates/nextjs/template/src/app/gradial/assets/[...path]/route.ts +0 -1
  113. package/templates/nextjs/template/src/middleware.ts +0 -49
  114. package/templates/nextjs/template/src/middleware.ts.tmpl +0 -40
@@ -230,8 +230,8 @@ export function checkPageEntry(ctx) {
230
230
  const hasForceDynamic = normalized.includes("dynamic = 'force-dynamic'") ||
231
231
  normalized.includes('dynamic = "force-dynamic"');
232
232
  results.push(hasForceDynamic
233
- ? ok('pageEntry', 'page exports force-dynamic', rel)
234
- : fail('pageEntry', 'page exports force-dynamic', rel + ' should export const dynamic = "force-dynamic"'));
233
+ ? ok('pageEntry', 'page exports force-dynamic for compiler snapshots', rel)
234
+ : fail('pageEntry', 'page exports force-dynamic for compiler snapshots', rel + ' should export const dynamic = "force-dynamic"'));
235
235
  const hasGenerateStaticParams = pageFile.content.includes('generateStaticParams');
236
236
  results.push(!hasGenerateStaticParams
237
237
  ? ok('pageEntry', 'page does not use generateStaticParams', rel)
@@ -239,7 +239,7 @@ export function checkPageEntry(ctx) {
239
239
  return results;
240
240
  }
241
241
  // ---------------------------------------------------------------------------
242
- // Check: middleware — presence and siteId (Next)
242
+ // Check: middleware — provider-owned EdgeRouter exclusivity (Next)
243
243
  // ---------------------------------------------------------------------------
244
244
  export function checkMiddleware(ctx) {
245
245
  const results = [];
@@ -252,135 +252,11 @@ export function checkMiddleware(ctx) {
252
252
  'middleware.ts',
253
253
  'middleware.js',
254
254
  ]);
255
- if (!middlewareFile) {
256
- results.push(fail('middleware', 'next middleware.ts exists', 'expected src/middleware.ts or middleware.ts'));
257
- return results;
258
- }
259
- const rel = relative(ctx.rootDir, middlewareFile.path);
260
- results.push(ok('middleware', 'next middleware.ts exists', rel));
261
- const usesSDKMiddleware = middlewareFile.content.includes('createGradialMiddleware') ||
262
- middlewareFile.content.includes('@gradial/aci/next/middleware');
263
- results.push(usesSDKMiddleware
264
- ? ok('middleware', 'middleware uses createGradialMiddleware', rel)
265
- : fail('middleware', 'middleware uses createGradialMiddleware', rel + ' should use createGradialMiddleware from @gradial/aci/next/middleware'));
266
- // Middleware must NOT pass a siteId — the SDK reads process.env.ACI_SITE_ID
267
- // internally. Any siteId arg is stale config that should be removed.
268
- {
269
- const label = 'middleware does not pass siteId';
270
- const callIdx = middlewareFile.content.indexOf('createGradialMiddleware(');
271
- const region = callIdx >= 0 ? middlewareFile.content.slice(callIdx) : middlewareFile.content;
272
- const passesSiteId = /siteId\s*:/.test(region);
273
- results.push(!passesSiteId
274
- ? ok('middleware', label, rel)
275
- : fail('middleware', label, `${rel}: remove siteId from createGradialMiddleware() — the SDK reads process.env.ACI_SITE_ID internally; the platform injects it per deployment`));
276
- }
277
- // Check that the middleware matcher is inlined (not imported) and matches
278
- // the SDK's canonical value. Next.js requires config.matcher to be
279
- // statically analyzable, so importing the matcher from the SDK breaks the
280
- // build. Instead the template inlines the value and this check detects drift.
281
- const canonicalMatcher = String.raw `[
282
- '/((?!_next(?:/|$)|api(?:/|$)|collect(?:/|$)|gradial/assets(?:/|$)|favicon\\.ico$).*)',
283
- {
284
- source: '/:path*',
285
- has: [{ type: 'header', key: 'x-gradial-framework-origin-auth' }],
286
- },
287
- {
288
- source: '/:path*',
289
- has: [{ type: 'header', key: 'x-baremetal-site-id' }],
290
- },
291
- {
292
- source: '/:path*',
293
- has: [{ type: 'header', key: 'x-baremetal-release-id' }],
294
- },
295
- {
296
- source: '/:path*',
297
- has: [{ type: 'header', key: 'x-aci-content-ref' }],
298
- },
299
- {
300
- source: '/:path*',
301
- has: [{ type: 'header', key: 'x-baremetal-content-base-url' }],
302
- },
303
- {
304
- source: '/:path*',
305
- has: [{ type: 'header', key: 'x-aci-content-path' }],
306
- },
307
- {
308
- source: '/:path*',
309
- has: [{ type: 'header', key: 'x-aci-routed-path' }],
310
- },
311
- {
312
- source: '/:path*',
313
- has: [{ type: 'header', key: 'x-aci-variant-key' }],
314
- },
315
- {
316
- source: '/:path*',
317
- has: [{ type: 'query', key: '__aci_content_path' }],
318
- },
319
- ]`;
320
- // Check for actual import/usage of aciMiddlewareMatcher (not just a mention
321
- // in a comment). Look for `matcher: aciMiddlewareMatcher` or
322
- // `import { ... aciMiddlewareMatcher ... }`.
323
- const hasImportedMatcher = /matcher\s*:\s*aciMiddlewareMatcher/.test(middlewareFile.content) ||
324
- /import\s+.*aciMiddlewareMatcher.*from/.test(middlewareFile.content);
325
- if (hasImportedMatcher) {
326
- results.push(fail('middleware', 'middleware matcher is inlined (not imported)', rel + ' should inline the matcher value for Next.js static analysis; see @gradial/aci/next/middleware for the canonical value'));
327
- }
328
- else {
329
- // Verify the inlined value matches the SDK canonical
330
- const matcherLiteral = extractArrayPropertyLiteral(middlewareFile.content, 'matcher');
331
- if (matcherLiteral) {
332
- const normalizedInlined = matcherLiteral.replace(/\s+/g, '');
333
- const normalizedCanonical = canonicalMatcher.replace(/\s+/g, '');
334
- results.push(normalizedInlined === normalizedCanonical
335
- ? ok('middleware', 'middleware matcher matches SDK canonical', rel)
336
- : fail('middleware', 'middleware matcher matches SDK canonical', `${rel}: inlined matcher does not match SDK's aciMiddlewareMatcher; expected ${canonicalMatcher}`));
337
- }
338
- else {
339
- results.push(fail('middleware', 'middleware matcher is defined', rel + ' should define config.matcher'));
340
- }
255
+ if (middlewareFile) {
256
+ const rel = relative(ctx.rootDir, middlewareFile.path);
257
+ return [fail('middleware', 'customer middleware is absent', `${rel} conflicts with the provider-owned ACI EdgeRouter; remove it`)];
341
258
  }
342
- return results;
343
- }
344
- function extractArrayPropertyLiteral(content, propertyName) {
345
- const property = new RegExp(`\\b${propertyName}\\s*:`).exec(content);
346
- if (!property)
347
- return null;
348
- const start = content.indexOf('[', property.index + property[0].length);
349
- if (start < 0)
350
- return null;
351
- let depth = 0;
352
- let quote = '';
353
- let escaped = false;
354
- for (let index = start; index < content.length; index += 1) {
355
- const character = content[index];
356
- if (quote) {
357
- if (escaped) {
358
- escaped = false;
359
- }
360
- else if (character === '\\') {
361
- escaped = true;
362
- }
363
- else if (character === quote) {
364
- quote = '';
365
- }
366
- continue;
367
- }
368
- if (character === "'" || character === '"' || character === '`') {
369
- quote = character;
370
- continue;
371
- }
372
- if (character === '[') {
373
- depth += 1;
374
- continue;
375
- }
376
- if (character === ']') {
377
- depth -= 1;
378
- if (depth === 0) {
379
- return content.slice(start, index + 1);
380
- }
381
- }
382
- }
383
- return null;
259
+ return [ok('middleware', 'customer middleware is absent', 'routing is owned by the hosting provider ACI EdgeRouter')];
384
260
  }
385
261
  // ---------------------------------------------------------------------------
386
262
  // Check: noFileContentProvider — no direct FileContentProvider imports in app code
@@ -449,9 +325,9 @@ export function checkNoCustomContent(ctx) {
449
325
  return results;
450
326
  }
451
327
  // ---------------------------------------------------------------------------
452
- // Check: noLegacyAssetRoute — no legacy asset route pattern
328
+ // Check: noRequestTimeAssetRoute — asset delivery is host-owned
453
329
  // ---------------------------------------------------------------------------
454
- export function checkNoLegacyAssetRoute(ctx) {
330
+ export function checkNoRequestTimeAssetRoute(ctx) {
455
331
  const results = [];
456
332
  if (ctx.framework !== 'next') {
457
333
  return results;
@@ -459,35 +335,21 @@ export function checkNoLegacyAssetRoute(ctx) {
459
335
  const appRoot = existsSync(join(ctx.rootDir, 'src', 'app'))
460
336
  ? join(ctx.rootDir, 'src', 'app')
461
337
  : join(ctx.rootDir, 'app');
462
- // The legacy pattern uses [releaseId] segment; the canonical pattern uses just [...path]
463
- const legacyRoute = findFirstExisting(appRoot, [
338
+ const requestTimeAssetRoute = findFirstExisting(appRoot, [
464
339
  'gradial/assets/[releaseId]/[...path]/route.ts',
465
340
  'gradial/assets/[releaseId]/[...path]/route.tsx',
466
341
  'gradial/assets/[releaseId]/[...path]/route.js',
467
342
  'gradial/assets/[releaseId]/[...path]/route.jsx',
468
- ]);
469
- if (legacyRoute) {
470
- results.push(fail('noLegacyAssetRoute', 'no legacy asset route with [releaseId] segment', 'found legacy route at ' + relative(ctx.rootDir, legacyRoute.path) + '; use gradial/assets/[...path]/route.ts instead'));
471
- }
472
- else {
473
- results.push(ok('noLegacyAssetRoute', 'no legacy asset route with [releaseId] segment'));
474
- }
475
- // Verify the canonical asset route exists
476
- const canonicalRoute = findFirstExisting(appRoot, [
477
343
  'gradial/assets/[...path]/route.ts',
478
344
  'gradial/assets/[...path]/route.tsx',
479
345
  'gradial/assets/[...path]/route.js',
480
346
  'gradial/assets/[...path]/route.jsx',
481
347
  ]);
482
- if (canonicalRoute) {
483
- results.push(ok('noLegacyAssetRoute', 'canonical asset route exists', relative(ctx.rootDir, canonicalRoute.path)));
484
- const usesSDKHandler = canonicalRoute.content.includes('@gradial/aci/next/asset-route');
485
- results.push(usesSDKHandler
486
- ? ok('noLegacyAssetRoute', 'asset route uses SDK handler', relative(ctx.rootDir, canonicalRoute.path))
487
- : fail('noLegacyAssetRoute', 'asset route uses SDK handler', relative(ctx.rootDir, canonicalRoute.path) + ' should import from @gradial/aci/next/asset-route'));
348
+ if (requestTimeAssetRoute) {
349
+ results.push(fail('noRequestTimeAssetRoute', 'no Next request-time asset route', 'found retired asset route at ' + relative(ctx.rootDir, requestTimeAssetRoute.path) + '; host gateways serve immutable assets directly'));
488
350
  }
489
351
  else {
490
- results.push(fail('noLegacyAssetRoute', 'canonical asset route exists', 'expected gradial/assets/[...path]/route.ts'));
352
+ results.push(ok('noRequestTimeAssetRoute', 'no Next request-time asset route'));
491
353
  }
492
354
  return results;
493
355
  }
@@ -579,7 +441,7 @@ export const CHECK_REGISTRY = {
579
441
  middleware: checkMiddleware,
580
442
  noFileContentProvider: checkNoFileContentProvider,
581
443
  noCustomContent: checkNoCustomContent,
582
- noLegacyAssetRoute: checkNoLegacyAssetRoute,
444
+ noRequestTimeAssetRoute: checkNoRequestTimeAssetRoute,
583
445
  buildSucceeds: checkBuildSucceeds,
584
446
  contentCompile: checkContentCompile,
585
447
  sdkVersion: checkSdkVersion,
@@ -1,3 +1,3 @@
1
1
  export { conformancePreset, runConformanceChecks } from './preset.js';
2
- export { checkConfig, checkRegistry, checkPageEntry, checkMiddleware, checkNoFileContentProvider, checkNoCustomContent, checkNoLegacyAssetRoute, checkBuildSucceeds, checkContentCompile, checkSdkVersion, CHECK_REGISTRY, } from './checks.js';
2
+ export { checkConfig, checkRegistry, checkPageEntry, checkMiddleware, checkNoFileContentProvider, checkNoCustomContent, checkNoRequestTimeAssetRoute, checkBuildSucceeds, checkContentCompile, checkSdkVersion, CHECK_REGISTRY, } from './checks.js';
3
3
  export type { ConformanceFramework, ConformanceCheckName, ConformancePresetOptions, ConformanceCheckResult, ConformanceResult, ConformanceContext, ConformanceCheckFn, } from './types.js';
@@ -1,2 +1,2 @@
1
1
  export { conformancePreset, runConformanceChecks } from './preset.js';
2
- export { checkConfig, checkRegistry, checkPageEntry, checkMiddleware, checkNoFileContentProvider, checkNoCustomContent, checkNoLegacyAssetRoute, checkBuildSucceeds, checkContentCompile, checkSdkVersion, CHECK_REGISTRY, } from './checks.js';
2
+ export { checkConfig, checkRegistry, checkPageEntry, checkMiddleware, checkNoFileContentProvider, checkNoCustomContent, checkNoRequestTimeAssetRoute, checkBuildSucceeds, checkContentCompile, checkSdkVersion, CHECK_REGISTRY, } from './checks.js';
@@ -27,7 +27,7 @@ const ALL_CHECKS = [
27
27
  'middleware',
28
28
  'noFileContentProvider',
29
29
  'noCustomContent',
30
- 'noLegacyAssetRoute',
30
+ 'noRequestTimeAssetRoute',
31
31
  'sdkVersion',
32
32
  // Expensive checks last — these shell out
33
33
  'contentCompile',
@@ -7,7 +7,7 @@
7
7
  /** Supported framework identifiers. */
8
8
  export type ConformanceFramework = 'next' | 'astro';
9
9
  /** Individual check names that can be enabled/disabled. */
10
- export type ConformanceCheckName = 'config' | 'registry' | 'pageEntry' | 'middleware' | 'noFileContentProvider' | 'noCustomContent' | 'noLegacyAssetRoute' | 'buildSucceeds' | 'contentCompile' | 'sdkVersion';
10
+ export type ConformanceCheckName = 'config' | 'registry' | 'pageEntry' | 'middleware' | 'noFileContentProvider' | 'noCustomContent' | 'noRequestTimeAssetRoute' | 'buildSucceeds' | 'contentCompile' | 'sdkVersion';
11
11
  /**
12
12
  * Options for the conformance preset.
13
13
  *
@@ -1,4 +1,3 @@
1
- import type { RenderCapabilities } from './renderer.js';
2
1
  export interface Config {
3
2
  version: '1';
4
3
  siteId: string;
@@ -11,15 +10,12 @@ export interface Config {
11
10
  componentRegistry: string;
12
11
  dataRegistry?: string;
13
12
  layoutRegistry: string;
14
- capabilities: RenderCapabilities;
15
13
  routes: RouteConfig;
16
14
  dam?: DAMConfig;
17
15
  externalDependencies?: ExternalDependency[];
18
- rendererProtocol: 'http' | 'stdio-json';
19
16
  }
20
17
  export interface RouteConfig {
21
18
  cmsManaged: string;
22
- frameworkOwned?: string[];
23
19
  }
24
20
  export interface ExternalDependency {
25
21
  name: string;
@@ -4,8 +4,6 @@ export * from './data.js';
4
4
  export * from './layout.js';
5
5
  export * from './page.js';
6
6
  export * from './rich-text.js';
7
- export * from './renderer.js';
8
- export * from './render-mode.js';
9
7
  export * from './image.js';
10
8
  export * from './video.js';
11
9
  export * from './media.js';
@@ -4,8 +4,6 @@ export * from './data.js';
4
4
  export * from './layout.js';
5
5
  export * from './page.js';
6
6
  export * from './rich-text.js';
7
- export * from './renderer.js';
8
- export * from './render-mode.js';
9
7
  export * from './image.js';
10
8
  export * from './video.js';
11
9
  export * from './media.js';
@@ -1,4 +1,3 @@
1
- import type { VaryDimension } from './render-mode.js';
2
1
  import type { TaxonomyAssignments } from './data.js';
3
2
  export interface PageDocument {
4
3
  path: string;
@@ -29,15 +28,6 @@ export interface BlockNode {
29
28
  id: string;
30
29
  component: string;
31
30
  props: Record<string, unknown>;
32
- renderHints: BlockRenderHints;
33
- contentPath?: string;
34
- }
35
- export interface BlockRenderHints {
36
- canStatic: boolean;
37
- needsSSR: boolean;
38
- isIsland: boolean;
39
- islandMode?: 'ssr' | 'client';
40
- varyDimensions?: VaryDimension[];
41
31
  }
42
32
  export interface FragmentRefNode {
43
33
  kind: 'fragment-ref';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradial/aci",
3
- "version": "0.1.50",
3
+ "version": "0.1.51-ssr.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/gradial/bare-metal-go.git",
@@ -45,9 +45,9 @@
45
45
  "types": "./dist/providers/file.d.ts",
46
46
  "import": "./dist/providers/file.js"
47
47
  },
48
- "./providers/s3": {
49
- "types": "./dist/providers/s3.d.ts",
50
- "import": "./dist/providers/s3.js"
48
+ "./providers/object": {
49
+ "types": "./dist/providers/object.d.ts",
50
+ "import": "./dist/providers/object.js"
51
51
  },
52
52
  "./dev": {
53
53
  "types": "./dist/dev/index.d.ts",
@@ -67,26 +67,6 @@
67
67
  "import": "./dist/next/config.js",
68
68
  "default": "./dist/next/config.js"
69
69
  },
70
- "./next/middleware": {
71
- "types": "./dist/next/middleware.d.ts",
72
- "import": "./dist/next/middleware.js",
73
- "default": "./dist/next/middleware.js"
74
- },
75
- "./next/vercel-personalization": {
76
- "types": "./dist/next/vercel-personalization.d.ts",
77
- "import": "./dist/next/vercel-personalization.js",
78
- "default": "./dist/next/vercel-personalization.js"
79
- },
80
- "./next/vercel-collect-sdk-route": {
81
- "types": "./dist/next/vercel-collect-sdk-route.d.ts",
82
- "import": "./dist/next/vercel-collect-sdk-route.js",
83
- "default": "./dist/next/vercel-collect-sdk-route.js"
84
- },
85
- "./next/asset-route": {
86
- "types": "./dist/next/asset-route.d.ts",
87
- "import": "./dist/next/asset-route.js",
88
- "default": "./dist/next/asset-route.js"
89
- },
90
70
  "./next/dev-refresh": {
91
71
  "types": "./dist/next/dev-refresh.d.ts",
92
72
  "import": "./dist/next/dev-refresh.js"
@@ -119,7 +99,7 @@
119
99
  }
120
100
  },
121
101
  "scripts": {
122
- "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json && node scripts/assert-render-proof-public-surface.mjs && node scripts/build-collect.mjs",
102
+ "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json && node scripts/assemble-dist.mjs && node scripts/build-collect.mjs",
123
103
  "test": "node --import tsx --test \"src/**/*.test.ts\" \"src/**/*.test.tsx\"",
124
104
  "build:collect": "node scripts/build-collect.mjs",
125
105
  "generate-default-error-page": "node scripts/generate-default-error-page.mjs",
@@ -136,16 +116,12 @@
136
116
  "ws": "^8.18.0"
137
117
  },
138
118
  "peerDependencies": {
139
- "@vercel/edge-config": "^1.4.3",
140
119
  "next": "^15.0.0",
141
120
  "react": "^18.0.0 || ^19.0.0",
142
121
  "react-dom": "^18.0.0 || ^19.0.0",
143
122
  "zod": "^4.0.0"
144
123
  },
145
124
  "peerDependenciesMeta": {
146
- "@vercel/edge-config": {
147
- "optional": true
148
- },
149
125
  "next": {
150
126
  "optional": true
151
127
  },
@@ -170,11 +146,11 @@
170
146
  "zod": "^4.0.0"
171
147
  },
172
148
  "optionalDependencies": {
173
- "@gradial/aci-cli-darwin-arm64": "0.1.50",
174
- "@gradial/aci-cli-darwin-x64": "0.1.50",
175
- "@gradial/aci-cli-linux-arm64": "0.1.50",
176
- "@gradial/aci-cli-linux-x64": "0.1.50",
177
- "@gradial/aci-cli-win32-arm64": "0.1.50",
178
- "@gradial/aci-cli-win32-x64": "0.1.50"
149
+ "@gradial/aci-cli-darwin-arm64": "0.1.51-ssr.3",
150
+ "@gradial/aci-cli-darwin-x64": "0.1.51-ssr.3",
151
+ "@gradial/aci-cli-linux-arm64": "0.1.51-ssr.3",
152
+ "@gradial/aci-cli-linux-x64": "0.1.51-ssr.3",
153
+ "@gradial/aci-cli-win32-arm64": "0.1.51-ssr.3",
154
+ "@gradial/aci-cli-win32-x64": "0.1.51-ssr.3"
179
155
  }
180
156
  }
@@ -363,7 +363,6 @@ function postProcess(html, instrumentationTag) {
363
363
  // data-aci-assignments tag (REQ-11) in one sweep.
364
364
  out = out.replace(/<script\b[\s\S]*?<\/script>/gi, '');
365
365
  out = out.replace(/<link\b[^>]*rel="(?:preload|modulepreload|prefetch)"[^>]*>/gi, '');
366
- out = out.replace(/<meta\b[^>]*name="aci-render-proof"[^>]*>/gi, '');
367
366
  out = inlineStylesheets(out);
368
367
  return stampInstrumentation(out, instrumentationTag);
369
368
  }
@@ -31,12 +31,10 @@ function checkMissing(label, relativePath, message) {
31
31
  checks.push(`✓ ${label}`);
32
32
  }
33
33
 
34
- checkFile(
35
- 'middleware is configured',
34
+ checkMissing(
35
+ 'customer middleware is absent',
36
36
  'src/middleware.ts',
37
- (content) => (content.includes('@gradial/aci/next/middleware') || content.includes('createGradialMiddleware'))
38
- && !content.includes('|__r'),
39
- 'Expected src/middleware.ts to use @gradial/aci/next/middleware and not exclude __r; middleware blocks direct /__r requests.',
37
+ 'The hosting provider injects the ACI EdgeRouter as the sole routing middleware.',
40
38
  );
41
39
 
42
40
  checkFile(
@@ -52,17 +50,16 @@ checkMissing(
52
50
  'Use src/app/[[...slug]]/page.tsx (optional catch-all). The required [...slug] form breaks file-provider local dev where "/" arrives with an empty slug.',
53
51
  );
54
52
 
55
- checkFile(
56
- 'canonical asset route exists',
53
+ checkMissing(
54
+ 'request-time asset route is removed',
57
55
  'src/app/gradial/assets/[...path]/route.ts',
58
- (content) => content.includes('@gradial/aci/next/asset-route'),
59
- 'Expected the canonical asset route to use @gradial/aci/next/asset-route.',
56
+ 'Host gateways serve immutable assets directly; do not proxy them through Next.',
60
57
  );
61
58
 
62
59
  checkMissing(
63
- 'legacy release-scoped asset route is removed',
60
+ 'release-scoped request-time asset route is removed',
64
61
  'src/app/gradial/assets/[releaseId]/[...path]/route.ts',
65
- 'Release-scoped asset URLs are produced by withAci() rewrites into the canonical src/app/gradial/assets/[...path]/route.ts; do not add a [releaseId] route.',
62
+ 'Host gateways serve immutable assets directly; do not add a release-scoped Next asset route.',
66
63
  );
67
64
 
68
65
  checkMissing(
@@ -1,5 +1,3 @@
1
- import type { RenderCapabilities } from './renderer.js';
2
-
3
1
  export interface Config {
4
2
  version: '1';
5
3
  siteId: string;
@@ -12,16 +10,13 @@ export interface Config {
12
10
  componentRegistry: string;
13
11
  dataRegistry?: string;
14
12
  layoutRegistry: string;
15
- capabilities: RenderCapabilities;
16
13
  routes: RouteConfig;
17
14
  dam?: DAMConfig;
18
15
  externalDependencies?: ExternalDependency[];
19
- rendererProtocol: 'http' | 'stdio-json';
20
16
  }
21
17
 
22
18
  export interface RouteConfig {
23
19
  cmsManaged: string;
24
- frameworkOwned?: string[];
25
20
  }
26
21
 
27
22
  export interface ExternalDependency {
@@ -4,8 +4,6 @@ export * from './data.js';
4
4
  export * from './layout.js';
5
5
  export * from './page.js';
6
6
  export * from './rich-text.js';
7
- export * from './renderer.js';
8
- export * from './render-mode.js';
9
7
  export * from './image.js';
10
8
  export * from './video.js';
11
9
  export * from './media.js';
package/src/types/page.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { VaryDimension } from './render-mode.js';
2
1
  import type { TaxonomyAssignments } from './data.js';
3
2
 
4
3
  export interface PageDocument {
@@ -30,16 +29,6 @@ export interface BlockNode {
30
29
  id: string;
31
30
  component: string;
32
31
  props: Record<string, unknown>;
33
- renderHints: BlockRenderHints;
34
- contentPath?: string;
35
- }
36
-
37
- export interface BlockRenderHints {
38
- canStatic: boolean;
39
- needsSSR: boolean;
40
- isIsland: boolean;
41
- islandMode?: 'ssr' | 'client';
42
- varyDimensions?: VaryDimension[];
43
32
  }
44
33
 
45
34
  export interface FragmentRefNode {
@@ -11,18 +11,7 @@ source:
11
11
  componentRegistry: ./src/cms/contracts/components/index.ts
12
12
  layoutRegistry: ./src/cms/contracts/layouts/index.ts
13
13
 
14
- capabilities:
15
- staticRender: true
16
- ssr: true
17
- ssrIslands: true
18
- clientIslands: true
19
- fragmentRender: true
20
-
21
14
  routes:
22
15
  cmsManaged: "/[...slug]"
23
- frameworkOwned:
24
- - "/api/*"
25
- - "/_astro/*"
26
- - "/storybook/*"
27
16
 
28
17
  rendererProtocol: stdio-json
@@ -12,7 +12,7 @@ description: Onboarding, running builds, validating, and troubleshooting ACI sit
12
12
  # Astro is standard for new customer sites
13
13
  aci init my-site --template astro-starter
14
14
 
15
- # Next.js is for specific SSR properties
15
+ # Next.js is for sites that need its framework/build ecosystem
16
16
  aci init my-site --template next-starter
17
17
 
18
18
  # With demo content, components, and stories
@@ -65,12 +65,11 @@ Each framework uses a packaged SDK adapter for ACI dev/build behavior:
65
65
  - **Astro**: `withAci()` in `astro.config.mjs`
66
66
  - **Next.js**: `withAci()` in `next.config.ts`
67
67
 
68
- These adapters own canonical ACI behavior: content watch/reload, local DAM
69
- derivative serving at `/.gradial-dam/*`, asset path rewrites, output mode,
70
- outputFileTracingRoot, base-path/build-mode/dist-dir env injection, CDN
71
- headers, and content-watch plugin. Repos should pass an empty `withAci()`
72
- call and rely on SDK defaults. Use `passthroughRoutes` only for
73
- site-specific non-CMS routes.
68
+ These adapters own canonical local-dev and publish-time behavior: content
69
+ watch/reload, local DAM derivative paths, optional direct asset-origin rewrites,
70
+ standalone output, error-page payloads, and framework build integration. Repos
71
+ should pass an empty `withAci()` call and rely on SDK defaults. Hosted CMS
72
+ routing and immutable artifact delivery remain outside the framework.
74
73
 
75
74
  Only Next.js and Astro are supported. SvelteKit support has been removed.
76
75
 
@@ -140,10 +139,10 @@ Default checks validate:
140
139
  - `config` -- `withAci()` present in config
141
140
  - `registry` -- `createRegistry()` usage (no hand-rolled maps)
142
141
  - `pageEntry` -- `createPage(registry)` usage in catch-all route
143
- - `middleware` -- `createGradialMiddleware({ siteId })` with correct siteId
142
+ - `middleware` -- no customer middleware implementing a second CMS decision path
144
143
  - `noFileContentProvider` -- no direct `FileContentProvider` imports in app code
145
144
  - `noCustomContent` -- no `src/lib/content.ts` shim
146
- - `noLegacyAssetRoute` -- no `[releaseId]` segment in asset route path
145
+ - `noRequestTimeAssetRoute` -- no Next asset-delivery route; host gateways own immutable assets
147
146
  - `sdkVersion` -- SDK version compatibility
148
147
 
149
148
  Optional (disabled by default):
@@ -702,10 +702,9 @@ files list.
702
702
  ## Deep Dive: SDK Server Functions
703
703
 
704
704
  Read `references/sdk-server-functions.md` for `@gradial/aci/next`
705
- server-side functions (`createPage`, `getSiteConfig`, `getFragment`,
706
- etc.), the three-tier content resolution chain, and the critical rule
707
- against importing `FileContentProvider` or `S3ContentProvider`
708
- directly in app code.
705
+ server-side functions (`createPage`, `getSiteConfig`, `getFragment`, etc.), the
706
+ compiler-input/local-file build boundary, and the rule against constructing
707
+ content providers directly in app code.
709
708
 
710
709
  ## Deep Dive: Block Slots
711
710