@gradial/aci 0.1.52-rc.8 → 0.1.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +126 -0
- package/README.md +86 -5
- package/dist/astro/error-page.js +1 -0
- package/dist/astro/index.js +4 -0
- package/dist/astro/page.d.ts +5 -2
- package/dist/astro/page.js +35 -23
- package/dist/astro/preview.js +2 -17
- package/dist/audience-data-models.d.ts +308 -197
- package/dist/audience-data-models.js +313 -51
- package/dist/cli/compile-registry.mjs +6 -34
- package/dist/cli/mintlify-render.mjs +8 -0
- package/dist/collect/aci.js +1 -1
- package/dist/collect/aci.js.sha256 +1 -1
- package/dist/collect/api.d.ts +6 -7
- package/dist/collect/api.js +21 -8
- package/dist/collect/assignments.d.ts +7 -9
- package/dist/collect/assignments.js +23 -32
- package/dist/collect/batcher.d.ts +9 -7
- package/dist/collect/batcher.js +6 -5
- package/dist/collect/consent/envelope.d.ts +7 -1
- package/dist/collect/consent/envelope.js +3 -1
- package/dist/collect/consent/mapping.d.ts +2 -0
- package/dist/collect/consent/mapping.js +1 -0
- package/dist/collect/consenthold.d.ts +38 -0
- package/dist/collect/consenthold.js +82 -0
- package/dist/collect/declarative.js +7 -5
- package/dist/collect/gapbuffer.d.ts +13 -4
- package/dist/collect/gapbuffer.js +21 -10
- package/dist/collect/index.js +78 -21
- package/dist/collect/pageviews.d.ts +11 -11
- package/dist/collect/pageviews.js +27 -22
- package/dist/consent-banner/index.d.ts +17 -0
- package/dist/consent-banner/index.js +23 -0
- package/dist/content/index.d.ts +2 -1
- package/dist/content/index.js +4 -1
- package/dist/content/provider.d.ts +16 -2
- package/dist/content/provider.js +5 -1
- package/dist/content/resolve-slots.d.ts +24 -2
- package/dist/content/resolve-slots.js +127 -21
- package/dist/content/types.d.ts +5 -1
- package/dist/edge/expression-capabilities.v1.d.ts +106 -0
- package/dist/edge/expression-capabilities.v1.js +165 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/internal/domain/edge/identity.d.ts +47 -4
- package/dist/internal/domain/edge/identity.js +130 -26
- package/dist/internal/domain/edge/index.d.ts +1 -1
- package/dist/internal/domain/edge/index.js +1 -1
- package/dist/internal/domain/edge/mimic_token.d.ts +14 -0
- package/dist/internal/domain/edge/mimic_token.js +125 -0
- package/dist/internal/domain/edge/personalization-core.d.ts +61 -22
- package/dist/internal/domain/edge/personalization-core.js +790 -200
- package/dist/internal/domain/edge/personalization_index.d.ts +17 -0
- package/dist/internal/domain/edge/personalization_index.js +55 -0
- package/dist/internal/domain/edge/resolve.js +76 -39
- package/dist/internal/domain/edge/testdata/flat_only_validator_v1.d.ts +10 -0
- package/dist/internal/domain/edge/testdata/flat_only_validator_v1.js +253 -0
- package/dist/internal/domain/edge/types.d.ts +82 -78
- package/dist/internal/domain/edge/types.js +3 -3
- package/dist/internal/domain/edge/variant_key.d.ts +4 -0
- package/dist/internal/domain/edge/variant_key.js +56 -0
- package/dist/internal/platform/collectionstore/errors.d.ts +24 -0
- package/dist/internal/platform/collectionstore/errors.js +48 -0
- package/dist/mintlify/blocks.d.ts +6 -0
- package/dist/mintlify/blocks.js +201 -0
- package/dist/mintlify/config.d.ts +3 -0
- package/dist/mintlify/config.js +77 -0
- package/dist/mintlify/index.d.ts +3 -0
- package/dist/mintlify/index.js +2 -0
- package/dist/mintlify/json.d.ts +8 -0
- package/dist/mintlify/json.js +37 -0
- package/dist/mintlify/materialize.d.ts +14 -0
- package/dist/mintlify/materialize.js +254 -0
- package/dist/mintlify/types.d.ts +74 -0
- package/dist/mintlify/types.js +1 -0
- package/dist/mintlify/validate.d.ts +7 -0
- package/dist/mintlify/validate.js +256 -0
- package/dist/next/assignments-navigation.d.ts +4 -0
- package/dist/next/assignments-navigation.js +18 -0
- package/dist/next/assignments-script.d.ts +3 -2
- package/dist/next/assignments-script.js +5 -5
- package/dist/next/error-pages.d.ts +4 -0
- package/dist/next/error-pages.js +4 -0
- package/dist/next/error-seat-payload.d.ts +2 -1
- package/dist/next/error-seat-payload.js +14 -24
- package/dist/next/error-seat.js +7 -2
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +3 -1
- package/dist/next/page.d.ts +2 -1
- package/dist/next/page.js +15 -4
- package/dist/next/release-context.d.ts +30 -0
- package/dist/next/release-context.js +56 -0
- package/dist/next/render.d.ts +1 -1
- package/dist/next/render.js +15 -5
- package/dist/next/server.d.ts +9 -3
- package/dist/next/server.js +17 -32
- package/dist/preview/core.d.ts +1 -0
- package/dist/preview/core.js +27 -0
- package/dist/react/VideoPlayer.d.ts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/registry.d.ts +4 -2
- package/dist/testing/conformance/checks.d.ts +2 -2
- package/dist/testing/conformance/checks.js +2 -0
- package/dist/testing/conformance/index.d.ts +1 -0
- package/dist/testing/conformance/index.js +1 -0
- package/dist/testing/conformance/next-stubs.d.ts +6 -0
- package/dist/testing/conformance/next-stubs.js +9 -0
- package/dist/testing/conformance/preset.d.ts +3 -2
- package/dist/testing/conformance/preset.js +15 -8
- package/dist/testing/conformance/root-identity.d.ts +31 -0
- package/dist/testing/conformance/root-identity.js +361 -0
- package/dist/testing/conformance/stubs/next-image.d.ts +7 -0
- package/dist/testing/conformance/stubs/next-image.js +5 -0
- package/dist/testing/conformance/stubs/next-link.d.ts +7 -0
- package/dist/testing/conformance/stubs/next-link.js +4 -0
- package/dist/testing/conformance/types.d.ts +5 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +4 -3
- package/dist/types/block-ref.js +2 -2
- package/dist/types/component.d.ts +9 -0
- package/dist/types/config.d.ts +0 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/page.d.ts +0 -1
- package/migrations/conformance-registry.md +22 -0
- package/migrations/experiment-goal-ids.md +43 -0
- package/package.json +21 -7
- package/src/cli/compile-registry.mjs +6 -30
- package/src/cli/mintlify-render.mjs +9 -0
- package/src/types/block-ref.test.ts +16 -1
- package/src/types/block-ref.ts +2 -2
- package/src/types/component.ts +10 -0
- package/src/types/config.ts +0 -1
- package/src/types/index.ts +0 -1
- package/src/types/page.ts +0 -1
- package/templates/astro/starter-content/src/components/chrome/Footer.astro +5 -3
- package/templates/astro/starter-content/src/components/chrome/Header.astro +5 -3
- package/templates/astro/starter-content/src/components/elements/Button.astro +5 -2
- package/templates/astro/starter-content/src/components/elements/ButtonBlock.astro +5 -3
- package/templates/astro/starter-content/src/components/sections/ContainerSection.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/FeatureCard.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/FeatureGrid.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/HomeHero.astro +5 -3
- package/templates/astro/starter-content/src/components/sections/PersonalizationChoice.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/StatsBar.astro +4 -3
- package/templates/astro/starter-content/src/fixtures/sections.ts +1 -1
- package/templates/astro/starter-content/src/stories/CompositionStoryFrame.astro +7 -2
- package/templates/astro/template/.aci.yaml.tmpl +0 -1
- package/templates/astro/template/package.json.tmpl +5 -5
- package/templates/astro/template/src/layouts/SiteLayout.astro +2 -2
- package/templates/common/.agents/skills/aci/SKILL.md +58 -1
- package/templates/common/.agents/skills/authoring/SKILL.md +194 -42
- package/templates/common/.agents/skills/authoring/references/block-registry.md +19 -3
- package/templates/common/.agents/skills/authoring/references/contracts.md +9 -30
- package/templates/common/.agents/skills/authoring/references/repo-structure.md +5 -4
- package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +3 -3
- package/templates/common/.agents/skills/dam-delivery/SKILL.md +216 -0
- package/templates/common/.agents/skills/dam-delivery/references/permalink-grammar.md +167 -0
- package/templates/common/.agents/skills/migration/references/canon-migration.md +18 -67
- package/templates/common/.agents/skills/migration/references/selector-map.md +1 -1
- package/templates/common/.content/fragments/navbar/_index.json +24 -0
- package/templates/common/.content/fragments/site-footer/_index.json +61 -0
- package/templates/common/.content/pages/404/_index.json +4 -2
- package/templates/common/.content/pages/_index.json +0 -1
- package/templates/common/.content/pages/error/_index.json +4 -2
- package/templates/common/.content/schemas/site.schema.json +11 -1
- package/templates/common/.content/templates/error.json +24 -0
- package/templates/common/.content/templates/home.json +28 -0
- package/templates/common/.content/templates/site.json +8 -0
- package/templates/common/.content/templates/standard.json +24 -0
- package/templates/common/.nvmrc +1 -1
- package/templates/common/starter-content/.content/config/site.json +1 -1
- package/templates/common/starter-content/.content/dam/README.md +74 -0
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/asset.json +1 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/asset.json +1 -1
- package/templates/common/starter-content/.content/pages/404/_index.json +1 -2
- package/templates/common/starter-content/.content/pages/{home/_index.json → _index.json} +14 -3
- package/templates/common/starter-content/.content/pages/about/_index.json +2 -2
- package/templates/common/starter-content/.content/pages/error/_index.json +1 -2
- package/templates/common/starter-content/.content/patterns/components/button.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/container.json +8 -3
- package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/feature_grid.json +5 -3
- package/templates/common/starter-content/.content/patterns/components/home_hero.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/site-footer.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/site-navigation.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/stats_bar.json +2 -2
- package/templates/common/starter-content/.content/schemas/site.schema.json +11 -1
- package/templates/nextjs/starter-content/src/components/chrome/Footer.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/chrome/Header.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/elements/Button.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/elements/ButtonBlock.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/ContainerSection.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/FeatureCard.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/FeatureGrid.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/HomeHero.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/PersonalizationChoice.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/StatsBar.tsx +4 -3
- package/templates/nextjs/template/.aci.yaml +0 -1
- package/templates/nextjs/template/.aci.yaml.tmpl +0 -1
- package/templates/nextjs/template/package.json.tmpl +4 -3
- package/templates/nextjs/template/src/app/_components/c15t-bridge.ts +30 -0
- package/templates/nextjs/template/src/app/_components/c15t-consent-ui.tsx +37 -0
- package/templates/nextjs/template/src/app/_components/consent-manager.css +63 -0
- package/templates/nextjs/template/src/app/_components/consent-manager.tsx +76 -0
- package/templates/nextjs/template/src/app/fonts/inter/OFL.txt +93 -0
- package/templates/nextjs/template/src/app/fonts/inter/inter-latin.woff2 +0 -0
- package/templates/nextjs/template/src/app/fonts/space-grotesk/OFL.txt +93 -0
- package/templates/nextjs/template/src/app/fonts/space-grotesk/space-grotesk-latin.woff2 +0 -0
- package/templates/nextjs/template/src/app/layout.tsx +12 -7
- package/templates/nextjs/template/tests/conformance.test.ts.tmpl +1 -0
- package/dist/define-layout.d.ts +0 -6
- package/dist/define-layout.js +0 -14
- package/dist/edge/personalization-core.d.ts +0 -11
- package/dist/edge/personalization-core.js +0 -269
- package/dist/internal/domain/edge/compose.d.ts +0 -24
- package/dist/internal/domain/edge/compose.js +0 -89
- package/dist/internal/domain/edge/record/codec.d.ts +0 -71
- package/dist/internal/domain/edge/record/codec.js +0 -401
- package/dist/next/collect-route.d.ts +0 -19
- package/dist/next/collect-route.js +0 -459
- package/dist/next/edge-config.d.ts +0 -1
- package/dist/next/edge-config.js +0 -92
- package/dist/next/envelope-digest.d.ts +0 -21
- package/dist/next/envelope-digest.js +0 -58
- package/dist/next/middleware.d.ts +0 -40
- package/dist/next/middleware.js +0 -475
- package/dist/next/personalization-host.d.ts +0 -134
- package/dist/next/personalization-host.js +0 -270
- package/dist/next/root-layout.d.ts +0 -4
- package/dist/next/root-layout.js +0 -5
- package/dist/next/vercel-collect-sdk-route.d.ts +0 -27
- package/dist/next/vercel-collect-sdk-route.js +0 -181
- package/dist/next/vercel-edge-projection-v1.d.ts +0 -24
- package/dist/next/vercel-edge-projection-v1.js +0 -880
- package/dist/next/vercel-personalization.d.ts +0 -4
- package/dist/next/vercel-personalization.js +0 -4
- package/dist/next/vercel-s3-personalization.d.ts +0 -79
- package/dist/next/vercel-s3-personalization.js +0 -570
- package/dist/types/layout.d.ts +0 -24
- package/src/types/layout.ts +0 -29
- package/templates/astro/starter-content/src/render/RenderPage.astro +0 -67
- package/templates/astro/template/src/cms/contracts/layouts/index.ts +0 -18
- package/templates/common/starter-content/.content/patterns/layouts/default.json +0 -14
- package/templates/nextjs/starter-content/src/components/elements/AtomicBlock.tsx +0 -13
- package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +0 -16
- /package/dist/{types/layout.js → cli/mintlify-render.d.mts} +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/editorial.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/governance.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/versions/v0001.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/editorial.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/governance.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/versions/v0001.json +0 -0
package/dist/next/render.js
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
export async function renderBlock(block, registry, extraProps) {
|
|
2
|
+
export async function renderBlock(block, registry, key, extraProps) {
|
|
3
3
|
const entry = registry.find((r) => r.id === block.component);
|
|
4
4
|
if (!entry) {
|
|
5
|
-
return (_jsxs("div", { className: "mx-auto my-4 max-w-[var(--max-width-container)] rounded-card border-2 border-red-600 bg-red-50 px-5 py-4 font-mono text-sm leading-relaxed text-red-900", children: [_jsx("strong", { children: "Unknown block:" }), " ", _jsx("code", { children: block.component }), _jsx("br", {}), _jsxs("span", { className: "text-red-800 opacity-70", children: ["id: ", block.id] })] },
|
|
5
|
+
return (_jsxs("div", { className: "mx-auto my-4 max-w-[var(--max-width-container)] rounded-card border-2 border-red-600 bg-red-50 px-5 py-4 font-mono text-sm leading-relaxed text-red-900", children: [_jsx("strong", { children: "Unknown block:" }), " ", _jsx("code", { children: block.component }), _jsx("br", {}), _jsxs("span", { className: "text-red-800 opacity-70", children: ["id: ", block.id] })] }, key));
|
|
6
6
|
}
|
|
7
7
|
const Component = entry.component;
|
|
8
8
|
const hasBlockSlots = !!entry.contract.blockSlots;
|
|
9
|
-
|
|
9
|
+
// sdk I-19 (ADR 0051): root identity props are applied last so neither
|
|
10
|
+
// content props nor tenant slotProps can overwrite them.
|
|
11
|
+
const componentProps = {
|
|
12
|
+
...block.props,
|
|
13
|
+
...extraProps,
|
|
14
|
+
'data-aci-block': block.id,
|
|
15
|
+
'data-aci-component': block.component,
|
|
16
|
+
};
|
|
10
17
|
if (hasBlockSlots) {
|
|
11
18
|
componentProps.renderChildren = (blocks) => renderBlocks(blocks, registry, extraProps);
|
|
12
19
|
}
|
|
13
|
-
return _jsx(Component, { ...componentProps },
|
|
20
|
+
return _jsx(Component, { ...componentProps }, key);
|
|
14
21
|
}
|
|
15
22
|
export async function renderBlocks(blocks, registry, extraProps) {
|
|
16
|
-
|
|
23
|
+
// Sibling keys are index+id composites: one fragment placed twice repeats
|
|
24
|
+
// its authored block id, and React reconciliation keys must be unique per
|
|
25
|
+
// sibling (ADR 0051 covers analytics identity, not reconciliation).
|
|
26
|
+
return Promise.all(blocks.map((block, index) => renderBlock(block, registry, `${index}:${block.id}`, extraProps)));
|
|
17
27
|
}
|
package/dist/next/server.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { type ReleaseObjectReader } from '../providers/object.js';
|
|
|
3
3
|
import type { RenderInput } from '../content/types.js';
|
|
4
4
|
export { FragmentNotFoundError, PageNotFoundError, LayoutNotFoundError };
|
|
5
5
|
export interface FetchConfig {
|
|
6
|
-
siteId?: string;
|
|
7
6
|
bucket?: string;
|
|
8
7
|
keyPrefix?: string;
|
|
9
8
|
region?: string;
|
|
@@ -13,8 +12,6 @@ export interface FetchConfig {
|
|
|
13
12
|
roleArn?: string;
|
|
14
13
|
endpoint?: string;
|
|
15
14
|
releaseId?: string;
|
|
16
|
-
edgeConfig?: string;
|
|
17
|
-
deploymentId?: string;
|
|
18
15
|
}
|
|
19
16
|
export interface ServerRenderInput<TPage, TSite extends SiteConfig = SiteConfig> {
|
|
20
17
|
route: string;
|
|
@@ -54,4 +51,13 @@ export declare class DamAssetNotFoundError extends Error {
|
|
|
54
51
|
constructor(assetPath: string, cause?: unknown);
|
|
55
52
|
}
|
|
56
53
|
export declare function getDamAssetResponse(assetPath: string, config?: FetchConfig): Promise<Response>;
|
|
54
|
+
/**
|
|
55
|
+
* The release a read uses: the caller's explicit release (the catch-all passes
|
|
56
|
+
* the one its `/__r/{releaseId}` path names), else the release the hosting
|
|
57
|
+
* router dispatched this request to (release-context.ts — the same release,
|
|
58
|
+
* for code such as the not-found seat that receives no route params), else a
|
|
59
|
+
* process pin. A routed release outranks the pin because the catch-all of the
|
|
60
|
+
* same request renders the routed release regardless of the pin. There is no
|
|
61
|
+
* further source: without one of the three the read fails.
|
|
62
|
+
*/
|
|
57
63
|
export declare function resolveReleaseId(config?: FetchConfig): Promise<string>;
|
package/dist/next/server.js
CHANGED
|
@@ -7,8 +7,7 @@ import { S3ContentProvider } from '../providers/s3.js';
|
|
|
7
7
|
import { VercelReleaseObjectReader } from '../providers/vercel-object-reader.js';
|
|
8
8
|
import { GRADIAL_RENDER_INPUT_HEADER, getPendingRenderInput } from '../runtime/page.js';
|
|
9
9
|
import { attachRenderProofReceipt, selectVerifiedPage, } from '../internal/render-proof.js';
|
|
10
|
-
import {
|
|
11
|
-
import { activeReleaseV1Key, clampDeploymentCompatibleReleaseV1, decodeActiveReleaseV1, decodeDeploymentCompatibilityV1, deploymentCompatibilityKey, } from './vercel-edge-projection-v1.js';
|
|
10
|
+
import { routedRelease } from './release-context.js';
|
|
12
11
|
export { FragmentNotFoundError, PageNotFoundError, LayoutNotFoundError };
|
|
13
12
|
const releaseObjectReaderSymbol = Symbol.for('@gradial/aci.release-object-reader');
|
|
14
13
|
const objectProviders = new WeakMap();
|
|
@@ -44,8 +43,9 @@ export async function getFragment(name, config = {}) {
|
|
|
44
43
|
const runtimeInput = await getPageRuntimeRenderInput();
|
|
45
44
|
if (runtimeInput) {
|
|
46
45
|
const fragments = runtimeInput.fragments || {};
|
|
47
|
-
if (name
|
|
46
|
+
if (Object.hasOwn(fragments, name))
|
|
48
47
|
return fragments[name];
|
|
48
|
+
throw new FragmentNotFoundError(name, new Error('fragment is not bound by the selected page'));
|
|
49
49
|
}
|
|
50
50
|
const provider = await resolveProviderWithFallback(config);
|
|
51
51
|
return await provider.getFragment(name);
|
|
@@ -291,15 +291,25 @@ async function safeResponseText(res) {
|
|
|
291
291
|
return '';
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* The release a read uses: the caller's explicit release (the catch-all passes
|
|
296
|
+
* the one its `/__r/{releaseId}` path names), else the release the hosting
|
|
297
|
+
* router dispatched this request to (release-context.ts — the same release,
|
|
298
|
+
* for code such as the not-found seat that receives no route params), else a
|
|
299
|
+
* process pin. A routed release outranks the pin because the catch-all of the
|
|
300
|
+
* same request renders the routed release regardless of the pin. There is no
|
|
301
|
+
* further source: without one of the three the read fails.
|
|
302
|
+
*/
|
|
294
303
|
export async function resolveReleaseId(config = {}) {
|
|
295
304
|
if (config.releaseId)
|
|
296
305
|
return config.releaseId;
|
|
306
|
+
const routed = await routedRelease();
|
|
307
|
+
if (routed.releaseId)
|
|
308
|
+
return routed.releaseId;
|
|
297
309
|
if (process.env.ACI_RELEASE_ID)
|
|
298
310
|
return process.env.ACI_RELEASE_ID;
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return activeReleaseId;
|
|
302
|
-
throw new Error('ACI release ID is required. Pass releaseId from the release-scoped route or set ACI_RELEASE_ID.');
|
|
311
|
+
throw new Error('ACI release ID is required. Pass releaseId from the release-scoped route or set ACI_RELEASE_ID.'
|
|
312
|
+
+ (routed.rejected ? ` The request carried a release context that was not used: ${routed.rejected}.` : ''));
|
|
303
313
|
}
|
|
304
314
|
async function resolveS3Provider(config) {
|
|
305
315
|
const releaseId = await resolveReleaseId(config);
|
|
@@ -386,34 +396,9 @@ function sameS3ProviderConfig(left, right) {
|
|
|
386
396
|
&& left.roleArn === right.roleArn
|
|
387
397
|
&& left.endpoint === right.endpoint;
|
|
388
398
|
}
|
|
389
|
-
async function activeReleaseFromEdgeConfig(config) {
|
|
390
|
-
const edgeConfig = config.edgeConfig || process.env.EDGE_CONFIG || '';
|
|
391
|
-
const siteId = config.siteId || process.env.ACI_SITE_ID || '';
|
|
392
|
-
if (!edgeConfig || !siteId)
|
|
393
|
-
return '';
|
|
394
|
-
const active = await activeReleasePointer(edgeConfig, siteId);
|
|
395
|
-
if (active == null)
|
|
396
|
-
return '';
|
|
397
|
-
const deploymentId = config.deploymentId || process.env.VERCEL_DEPLOYMENT_ID || '';
|
|
398
|
-
if (!deploymentId)
|
|
399
|
-
return active.releaseId;
|
|
400
|
-
const compatibilityValue = await getEdgeConfigValue(edgeConfig, deploymentCompatibilityKey(siteId, deploymentId));
|
|
401
|
-
if (compatibilityValue == null)
|
|
402
|
-
return active.releaseId;
|
|
403
|
-
return clampDeploymentCompatibleReleaseV1(active, decodeDeploymentCompatibilityV1(compatibilityValue));
|
|
404
|
-
}
|
|
405
|
-
async function getEdgeConfigValue(edgeConfig, key) {
|
|
406
|
-
return getUncachedEdgeConfigValue(edgeConfig, key);
|
|
407
|
-
}
|
|
408
399
|
function releaseKey(config, releaseId) {
|
|
409
400
|
return joinKey(config.keyPrefix || process.env.ACI_S3_KEY_PREFIX || '', 'releases', releaseId);
|
|
410
401
|
}
|
|
411
|
-
async function activeReleasePointer(edgeConfig, siteId) {
|
|
412
|
-
const value = await getEdgeConfigValue(edgeConfig, activeReleaseV1Key(siteId));
|
|
413
|
-
if (value == null)
|
|
414
|
-
return null;
|
|
415
|
-
return decodeActiveReleaseV1(value);
|
|
416
|
-
}
|
|
417
402
|
class InjectedReaderProvider {
|
|
418
403
|
releaseId;
|
|
419
404
|
reader;
|
package/dist/preview/core.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export interface PreviewCookie {
|
|
|
37
37
|
export declare const PREVIEW_TOKEN_COOKIE = "aci_preview";
|
|
38
38
|
export declare const PREVIEW_RELEASE_COOKIE = "aci_preview_release";
|
|
39
39
|
export declare function validatePreviewToken(token: string, signKey: string): Promise<PreviewClaims | null>;
|
|
40
|
+
export declare function parseCookies(header: string): Map<string, string>;
|
|
40
41
|
export declare function extractPreviewToken(source: PreviewTokenSource): string | undefined;
|
|
41
42
|
export declare function previewSignKey(): string | undefined;
|
|
42
43
|
export declare function resolvePreviewContext(options: PreviewResolveOptions): Promise<PreviewContext>;
|
package/dist/preview/core.js
CHANGED
|
@@ -18,6 +18,33 @@ export async function validatePreviewToken(token, signKey) {
|
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
// parseCookies is the SDK-side raw Cookie-header parser for callers that only
|
|
22
|
+
// have the header string (the Astro integration; Next hands us its own parsed
|
|
23
|
+
// cookies). It is deliberately not the canonical edge parser
|
|
24
|
+
// (internal/domain/edge/identity.ts parseCookieHeader): SDK source cannot
|
|
25
|
+
// import internal/domain/edge — assemble-dist re-roots the emitted tree and
|
|
26
|
+
// the relative specifier depth changes — and framework cookie writers
|
|
27
|
+
// URI-encode values, so this one decodes them (falling back to the raw value
|
|
28
|
+
// on a malformed escape rather than throwing mid-request).
|
|
29
|
+
export function parseCookies(header) {
|
|
30
|
+
const cookies = new Map();
|
|
31
|
+
for (const part of header.split(';')) {
|
|
32
|
+
const separator = part.indexOf('=');
|
|
33
|
+
if (separator < 0)
|
|
34
|
+
continue;
|
|
35
|
+
const name = part.slice(0, separator).trim();
|
|
36
|
+
if (!name)
|
|
37
|
+
continue;
|
|
38
|
+
const value = part.slice(separator + 1).trim();
|
|
39
|
+
try {
|
|
40
|
+
cookies.set(name, decodeURIComponent(value));
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
cookies.set(name, value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return cookies;
|
|
47
|
+
}
|
|
21
48
|
export function extractPreviewToken(source) {
|
|
22
49
|
const query = source.query?.get('preview_token');
|
|
23
50
|
if (query)
|
|
@@ -11,21 +11,20 @@ export interface VideoPlayerProps extends Omit<VideoHTMLAttributes<HTMLVideoElem
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function VideoPlayer({ video, ...attrs }: VideoPlayerProps): import("react").DetailedReactHTMLElement<{
|
|
13
13
|
id?: string | undefined | undefined;
|
|
14
|
+
title: string;
|
|
14
15
|
role?: import("react").AriaRole | undefined;
|
|
15
16
|
prefix?: string | undefined | undefined;
|
|
16
|
-
title: string;
|
|
17
17
|
rel?: string | undefined | undefined;
|
|
18
18
|
content?: string | undefined | undefined;
|
|
19
19
|
slot?: string | undefined | undefined;
|
|
20
20
|
style?: import("react").CSSProperties | undefined;
|
|
21
21
|
dir?: string | undefined | undefined;
|
|
22
22
|
hidden?: boolean | undefined | undefined;
|
|
23
|
+
children?: import("react").ReactNode;
|
|
23
24
|
dangerouslySetInnerHTML?: {
|
|
24
25
|
__html: string | TrustedHTML;
|
|
25
26
|
} | undefined | undefined;
|
|
26
|
-
children?: import("react").ReactNode;
|
|
27
27
|
className?: string | undefined | undefined;
|
|
28
|
-
lang?: string | undefined | undefined;
|
|
29
28
|
crossOrigin?: "" | "anonymous" | "use-credentials" | undefined;
|
|
30
29
|
defaultChecked?: boolean | undefined | undefined;
|
|
31
30
|
defaultValue?: string | number | readonly string[] | undefined;
|
|
@@ -38,6 +37,7 @@ export declare function VideoPlayer({ video, ...attrs }: VideoPlayerProps): impo
|
|
|
38
37
|
contextMenu?: string | undefined | undefined;
|
|
39
38
|
draggable?: (boolean | "true" | "false") | undefined;
|
|
40
39
|
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
|
|
40
|
+
lang?: string | undefined | undefined;
|
|
41
41
|
nonce?: string | undefined | undefined;
|
|
42
42
|
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
43
43
|
tabIndex?: number | undefined | undefined;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface ImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, 's
|
|
|
13
13
|
}
|
|
14
14
|
export declare function Image({ image, value, ...attrs }: ImageProps): import("react").DetailedReactHTMLElement<import("../types/image.js").ImageAttrs, HTMLElement> | import("react").DetailedReactHTMLElement<{
|
|
15
15
|
id?: string | undefined | undefined;
|
|
16
|
+
title?: string | undefined | undefined;
|
|
16
17
|
role?: import("react").AriaRole | undefined;
|
|
17
18
|
prefix?: string | undefined | undefined;
|
|
18
19
|
width?: number | string | undefined | undefined;
|
|
@@ -21,7 +22,6 @@ export declare function Image({ image, value, ...attrs }: ImageProps): import("r
|
|
|
21
22
|
srcSet?: string | undefined | undefined;
|
|
22
23
|
loading?: "eager" | "lazy" | undefined | undefined;
|
|
23
24
|
decoding?: "async" | "auto" | "sync" | undefined | undefined;
|
|
24
|
-
title?: string | undefined | undefined;
|
|
25
25
|
rel?: string | undefined | undefined;
|
|
26
26
|
content?: string | undefined | undefined;
|
|
27
27
|
referrerPolicy?: import("react").HTMLAttributeReferrerPolicy | undefined;
|
|
@@ -29,12 +29,11 @@ export declare function Image({ image, value, ...attrs }: ImageProps): import("r
|
|
|
29
29
|
style?: import("react").CSSProperties | undefined;
|
|
30
30
|
dir?: string | undefined | undefined;
|
|
31
31
|
hidden?: boolean | undefined | undefined;
|
|
32
|
+
children?: ReactNode;
|
|
32
33
|
dangerouslySetInnerHTML?: {
|
|
33
34
|
__html: string | TrustedHTML;
|
|
34
35
|
} | undefined | undefined;
|
|
35
|
-
children?: ReactNode;
|
|
36
36
|
className?: string | undefined | undefined;
|
|
37
|
-
lang?: string | undefined | undefined;
|
|
38
37
|
crossOrigin?: "" | "anonymous" | "use-credentials" | undefined;
|
|
39
38
|
fetchPriority?: "high" | "low" | "auto" | undefined | undefined;
|
|
40
39
|
useMap?: string | undefined | undefined;
|
|
@@ -49,6 +48,7 @@ export declare function Image({ image, value, ...attrs }: ImageProps): import("r
|
|
|
49
48
|
contextMenu?: string | undefined | undefined;
|
|
50
49
|
draggable?: (boolean | "true" | "false") | undefined;
|
|
51
50
|
enterKeyHint?: "enter" | "done" | "go" | "next" | "previous" | "search" | "send" | undefined | undefined;
|
|
51
|
+
lang?: string | undefined | undefined;
|
|
52
52
|
nonce?: string | undefined | undefined;
|
|
53
53
|
spellCheck?: (boolean | "true" | "false") | undefined;
|
|
54
54
|
tabIndex?: number | undefined | undefined;
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ComponentContract, InferComponentProps } from './types/component.js';
|
|
1
|
+
import type { ComponentContract, ComponentContractID, InferComponentProps } from './types/component.js';
|
|
2
2
|
export type AnyComponent = (abstract new (...args: any[]) => any) | ((props: any) => any) | Record<string, any>;
|
|
3
3
|
export interface RegistryEntry {
|
|
4
4
|
id: string;
|
|
@@ -6,7 +6,9 @@ export interface RegistryEntry {
|
|
|
6
6
|
contract: ComponentContract;
|
|
7
7
|
}
|
|
8
8
|
export type Registry = readonly RegistryEntry[];
|
|
9
|
-
type ValidatedEntry<T> = T extends readonly [infer C extends ComponentContract, infer Comp] ? Comp extends (props: InferComponentProps<C>) => any ? T : Comp extends (props: InferComponentProps<C> & infer _) => any ? T : Comp extends new (props: InferComponentProps<C>, ...args: any[]) => any ? T : Comp extends Record<string, any> ? T : never : never;
|
|
9
|
+
type ValidatedEntry<T> = T extends readonly [infer C extends ComponentContract, infer Comp] ? Comp extends (props: InferComponentProps<C>) => any ? RootIdentityChecked<C, Comp, T> : Comp extends (props: InferComponentProps<C> & infer _) => any ? RootIdentityChecked<C, Comp, T> : Comp extends new (props: InferComponentProps<C>, ...args: any[]) => any ? RootIdentityChecked<C, Comp, T> : Comp extends Record<string, any> ? T : never : never;
|
|
10
|
+
type DeclaredProps<Comp> = Comp extends (props: infer P) => any ? P : Comp extends abstract new (props: infer P, ...args: any[]) => any ? P : Record<string, any>;
|
|
11
|
+
type RootIdentityChecked<C extends ComponentContract, Comp, T> = 'data-aci-block' extends keyof DeclaredProps<Comp> ? 'data-aci-component' extends keyof DeclaredProps<Comp> ? T : `${ComponentContractID<C>}: props type must extend RootIdentityProps from @gradial/aci` : `${ComponentContractID<C>}: props type must extend RootIdentityProps from @gradial/aci`;
|
|
10
12
|
type ValidatedEntries<T extends readonly (readonly [ComponentContract, AnyComponent])[]> = {
|
|
11
13
|
[K in keyof T]: ValidatedEntry<T[K]>;
|
|
12
14
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConformanceCheckResult, ConformanceCheckName, ConformanceContext } from './types.js';
|
|
1
|
+
import type { ConformanceCheckResult, ConformanceCheckName, ConformanceContext, ConformanceCheckFn } from './types.js';
|
|
2
2
|
export declare function checkConfig(ctx: ConformanceContext): ConformanceCheckResult[];
|
|
3
3
|
export declare function checkRegistry(ctx: ConformanceContext): ConformanceCheckResult[];
|
|
4
4
|
export declare function checkPageEntry(ctx: ConformanceContext): ConformanceCheckResult[];
|
|
@@ -9,4 +9,4 @@ export declare function checkNoRequestTimeAssetRoute(ctx: ConformanceContext): C
|
|
|
9
9
|
export declare function checkBuildSucceeds(ctx: ConformanceContext): ConformanceCheckResult[];
|
|
10
10
|
export declare function checkContentCompile(ctx: ConformanceContext): ConformanceCheckResult[];
|
|
11
11
|
export declare function checkSdkVersion(ctx: ConformanceContext): ConformanceCheckResult[];
|
|
12
|
-
export declare const CHECK_REGISTRY: Record<ConformanceCheckName,
|
|
12
|
+
export declare const CHECK_REGISTRY: Record<ConformanceCheckName, ConformanceCheckFn>;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
10
10
|
import { join, relative } from 'node:path';
|
|
11
11
|
import { execSync } from 'node:child_process';
|
|
12
|
+
import { checkRootIdentity } from './root-identity.js';
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
// Helpers
|
|
14
15
|
// ---------------------------------------------------------------------------
|
|
@@ -445,4 +446,5 @@ export const CHECK_REGISTRY = {
|
|
|
445
446
|
buildSucceeds: checkBuildSucceeds,
|
|
446
447
|
contentCompile: checkContentCompile,
|
|
447
448
|
sdkVersion: checkSdkVersion,
|
|
449
|
+
rootIdentity: checkRootIdentity,
|
|
448
450
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { conformancePreset, runConformanceChecks } from './preset.js';
|
|
2
2
|
export { checkConfig, checkRegistry, checkPageEntry, checkMiddleware, checkNoFileContentProvider, checkNoCustomContent, checkNoRequestTimeAssetRoute, checkBuildSucceeds, checkContentCompile, checkSdkVersion, CHECK_REGISTRY, } from './checks.js';
|
|
3
|
+
export { checkRootIdentity, findRootIdentityFailures, formatRootIdentityFailures, astroAuthoredBlocks, type RootIdentityFailure, } from './root-identity.js';
|
|
3
4
|
export type { ConformanceFramework, ConformanceCheckName, ConformancePresetOptions, ConformanceCheckResult, ConformanceResult, ConformanceContext, ConformanceCheckFn, } from './types.js';
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { conformancePreset, runConformanceChecks } from './preset.js';
|
|
2
2
|
export { checkConfig, checkRegistry, checkPageEntry, checkMiddleware, checkNoFileContentProvider, checkNoCustomContent, checkNoRequestTimeAssetRoute, checkBuildSucceeds, checkContentCompile, checkSdkVersion, CHECK_REGISTRY, } from './checks.js';
|
|
3
|
+
export { checkRootIdentity, findRootIdentityFailures, formatRootIdentityFailures, astroAuthoredBlocks, } from './root-identity.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Node module customization hook for the rootIdentity check: outside Next's
|
|
2
|
+
// bundler, `next/link` and `next/image` resolve to CommonJS interop objects
|
|
3
|
+
// that react-dom/server cannot render. Swap them for plain-element stubs.
|
|
4
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
5
|
+
if (specifier === 'next/link' || specifier === 'next/image') {
|
|
6
|
+
return { url: new URL(`./stubs/${specifier.replace('/', '-')}.js`, import.meta.url).href, shortCircuit: true };
|
|
7
|
+
}
|
|
8
|
+
return nextResolve(specifier, context);
|
|
9
|
+
}
|
|
@@ -2,9 +2,10 @@ import type { ConformancePresetOptions, ConformanceResult } from './types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Run all resolved checks and return an aggregate result.
|
|
4
4
|
* This is the programmatic API — call it directly if you don't want the
|
|
5
|
-
* node:test integration.
|
|
5
|
+
* node:test integration. It is async: the rootIdentity check renders
|
|
6
|
+
* components, so `await` the result before reading `.passed`.
|
|
6
7
|
*/
|
|
7
|
-
export declare function runConformanceChecks(options: ConformancePresetOptions): ConformanceResult
|
|
8
|
+
export declare function runConformanceChecks(options: ConformancePresetOptions): Promise<ConformanceResult>;
|
|
8
9
|
/**
|
|
9
10
|
* Register a conformance test suite using node:test.
|
|
10
11
|
*
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* conformancePreset({
|
|
11
11
|
* framework: 'next',
|
|
12
12
|
* siteId: 'site_mysite',
|
|
13
|
+
* registry: 'src/cms/registry.ts',
|
|
13
14
|
* });
|
|
14
15
|
* ```
|
|
15
16
|
*
|
|
@@ -29,6 +30,9 @@ const ALL_CHECKS = [
|
|
|
29
30
|
'noCustomContent',
|
|
30
31
|
'noRequestTimeAssetRoute',
|
|
31
32
|
'sdkVersion',
|
|
33
|
+
// Renders every registered component (ADR 0051); on Astro it scans dist/,
|
|
34
|
+
// building first when absent.
|
|
35
|
+
'rootIdentity',
|
|
32
36
|
// Expensive checks last — these shell out
|
|
33
37
|
'contentCompile',
|
|
34
38
|
'buildSucceeds',
|
|
@@ -51,19 +55,21 @@ function resolveChecks(input) {
|
|
|
51
55
|
/**
|
|
52
56
|
* Run all resolved checks and return an aggregate result.
|
|
53
57
|
* This is the programmatic API — call it directly if you don't want the
|
|
54
|
-
* node:test integration.
|
|
58
|
+
* node:test integration. It is async: the rootIdentity check renders
|
|
59
|
+
* components, so `await` the result before reading `.passed`.
|
|
55
60
|
*/
|
|
56
|
-
export function runConformanceChecks(options) {
|
|
61
|
+
export async function runConformanceChecks(options) {
|
|
57
62
|
const ctx = {
|
|
58
63
|
framework: options.framework,
|
|
59
64
|
siteId: options.siteId ?? '',
|
|
60
65
|
rootDir: options.rootDir || process.cwd(),
|
|
66
|
+
registry: options.registry,
|
|
61
67
|
};
|
|
62
68
|
const checks = resolveChecks(options.checks);
|
|
63
|
-
const allResults =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
69
|
+
const allResults = [];
|
|
70
|
+
for (const name of checks) {
|
|
71
|
+
allResults.push(...(await CHECK_REGISTRY[name](ctx)));
|
|
72
|
+
}
|
|
67
73
|
const failures = allResults.filter((r) => !r.ok);
|
|
68
74
|
return {
|
|
69
75
|
passed: failures.length === 0,
|
|
@@ -84,11 +90,12 @@ export function conformancePreset(options) {
|
|
|
84
90
|
framework: options.framework,
|
|
85
91
|
siteId: options.siteId ?? '',
|
|
86
92
|
rootDir: options.rootDir || process.cwd(),
|
|
93
|
+
registry: options.registry,
|
|
87
94
|
};
|
|
88
95
|
for (const checkName of checks) {
|
|
89
|
-
await t.test(checkName, () => {
|
|
96
|
+
await t.test(checkName, async () => {
|
|
90
97
|
const checkFn = CHECK_REGISTRY[checkName];
|
|
91
|
-
const results = checkFn(ctx);
|
|
98
|
+
const results = await checkFn(ctx);
|
|
92
99
|
for (const result of results) {
|
|
93
100
|
assert.ok(result.ok, `${result.label}${result.detail ? ` (${result.detail})` : ''}`);
|
|
94
101
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ConformanceCheckResult, ConformanceContext } from './types.js';
|
|
2
|
+
import type { Registry } from '../../registry.js';
|
|
3
|
+
import type { KernelPageBlock } from '../../content/types.js';
|
|
4
|
+
export interface RootIdentityFailure {
|
|
5
|
+
component: string;
|
|
6
|
+
file?: string;
|
|
7
|
+
missing: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Minimal React surface the renderer needs; injected so tests can pass fakes. */
|
|
10
|
+
export interface ReactRuntime {
|
|
11
|
+
renderToStaticMarkup: (element: unknown) => string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Render each block through the SDK renderer and report every component
|
|
15
|
+
* whose root element lacks the identity attributes. `blocks` are the blocks
|
|
16
|
+
* to exercise; registry entries not covered by a block are probed with empty
|
|
17
|
+
* props so an unused component cannot hide a forgotten spread.
|
|
18
|
+
*/
|
|
19
|
+
export declare function findRootIdentityFailures(registry: Registry, blocks: readonly KernelPageBlock[], react: ReactRuntime, fileFor?: (component: string) => string | undefined): Promise<RootIdentityFailure[]>;
|
|
20
|
+
/** The failure message: one line of what, the list, one line of fix. */
|
|
21
|
+
export declare function formatRootIdentityFailures(failures: readonly RootIdentityFailure[], framework: 'next' | 'astro'): string;
|
|
22
|
+
export declare function checkRootIdentity(ctx: ConformanceContext): Promise<ConformanceCheckResult[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Every block the Astro scan must find in dist/: page blocks by their own id,
|
|
25
|
+
* plus fragments (navbar, footer) by fragment id, which is the block id the
|
|
26
|
+
* renderer synthesizes when a layout slot default places them.
|
|
27
|
+
*/
|
|
28
|
+
export declare function astroAuthoredBlocks(contentDir: string): Array<{
|
|
29
|
+
id: string;
|
|
30
|
+
component: string;
|
|
31
|
+
}>;
|