@gradial/aci 0.1.52-rc.9 → 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
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { canonicalize, isExternalReference, isObject } from './json.js';
|
|
3
|
+
export function toDocsJSON(site) {
|
|
4
|
+
const { $schema: _schema, ...configuration } = site;
|
|
5
|
+
return canonicalize({
|
|
6
|
+
$schema: 'https://mintlify.com/docs.json',
|
|
7
|
+
...(typeof configuration.theme === 'string' ? {} : { theme: 'mint' }),
|
|
8
|
+
...configuration,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export function resolveConfigReferences(configuration, fragments) {
|
|
12
|
+
const byPath = new Map();
|
|
13
|
+
for (const fragment of fragments) {
|
|
14
|
+
if (byPath.has(fragment.path))
|
|
15
|
+
throw new Error(`ACI Mintlify config fragment path is duplicated: ${fragment.path}`);
|
|
16
|
+
byPath.set(fragment.path, fragment.value);
|
|
17
|
+
}
|
|
18
|
+
return resolveConfigValue(configuration, 'docs.json', byPath, new Set());
|
|
19
|
+
}
|
|
20
|
+
function resolveConfigValue(value, currentPath, fragments, stack) {
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
return value.map((entry) => resolveConfigValue(entry, currentPath, fragments, stack));
|
|
23
|
+
if (!isObject(value))
|
|
24
|
+
return value;
|
|
25
|
+
if (typeof value.$ref === 'string' && !isExternalReference(value.$ref)) {
|
|
26
|
+
const reference = resolveConfigReferencePath(currentPath, value.$ref);
|
|
27
|
+
const target = fragments.get(reference.path);
|
|
28
|
+
if (target === undefined)
|
|
29
|
+
throw new Error(`ACI Mintlify config reference is missing: ${value.$ref} from ${currentPath}`);
|
|
30
|
+
const cycleKey = `${reference.path}#${reference.pointer.join('/')}`;
|
|
31
|
+
if (stack.has(cycleKey))
|
|
32
|
+
throw new Error(`ACI Mintlify config reference cycle includes: ${cycleKey}`);
|
|
33
|
+
const nextStack = new Set(stack).add(cycleKey);
|
|
34
|
+
const selected = resolveJSONPointer(target, reference.pointer, value.$ref);
|
|
35
|
+
const resolvedTarget = resolveConfigValue(selected, reference.path, fragments, nextStack);
|
|
36
|
+
const siblings = Object.fromEntries(Object.entries(value)
|
|
37
|
+
.filter(([key]) => key !== '$ref')
|
|
38
|
+
.map(([key, child]) => [key, resolveConfigValue(child, currentPath, fragments, stack)]));
|
|
39
|
+
if (Object.keys(siblings).length === 0)
|
|
40
|
+
return resolvedTarget;
|
|
41
|
+
if (!isObject(resolvedTarget))
|
|
42
|
+
throw new Error(`ACI Mintlify config reference with sibling keys must resolve to an object: ${value.$ref}`);
|
|
43
|
+
return { ...resolvedTarget, ...siblings };
|
|
44
|
+
}
|
|
45
|
+
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, resolveConfigValue(child, currentPath, fragments, stack)]));
|
|
46
|
+
}
|
|
47
|
+
function resolveConfigReferencePath(currentPath, reference) {
|
|
48
|
+
const [rawPath, rawPointer = ''] = reference.split('#', 2);
|
|
49
|
+
if (!rawPath)
|
|
50
|
+
throw new Error(`ACI Mintlify local config reference requires a file path: ${reference}`);
|
|
51
|
+
const resolved = path.posix.normalize(path.posix.join(path.posix.dirname(currentPath), rawPath));
|
|
52
|
+
if (resolved.startsWith('../') || resolved.startsWith('/') || !resolved.endsWith('.json')) {
|
|
53
|
+
throw new Error(`ACI Mintlify config reference path is invalid: ${reference}`);
|
|
54
|
+
}
|
|
55
|
+
const pointer = rawPointer === '' ? [] : rawPointer.startsWith('/')
|
|
56
|
+
? rawPointer.slice(1).split('/').map((part) => part.replaceAll('~1', '/').replaceAll('~0', '~'))
|
|
57
|
+
: (() => { throw new Error(`ACI Mintlify config reference pointer is invalid: ${reference}`); })();
|
|
58
|
+
return { path: resolved, pointer };
|
|
59
|
+
}
|
|
60
|
+
function resolveJSONPointer(value, pointer, reference) {
|
|
61
|
+
let current = value;
|
|
62
|
+
for (const part of pointer) {
|
|
63
|
+
if (Array.isArray(current)) {
|
|
64
|
+
const index = Number(part);
|
|
65
|
+
if (!Number.isInteger(index) || index < 0 || index >= current.length)
|
|
66
|
+
throw new Error(`ACI Mintlify config reference pointer is missing: ${reference}`);
|
|
67
|
+
current = current[index];
|
|
68
|
+
}
|
|
69
|
+
else if (isObject(current) && Object.hasOwn(current, part)) {
|
|
70
|
+
current = current[part];
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new Error(`ACI Mintlify config reference pointer is missing: ${reference}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return current;
|
|
77
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { materializeMintlifySite, resolveMintlifyDocument, loadMintlifySource, loadCompiledMintlifySource, } from './materialize.js';
|
|
2
|
+
export { renderDocument, renderSnippet } from './blocks.js';
|
|
3
|
+
export type { MintlifyAPISpec, MintlifyBlock, MintlifyConfigFragment, MintlifyDocument, MintlifyJSONValue, MintlifyNavigationGroup, MintlifySite, MintlifySnippet, MintlifySource, } from './types.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MintlifyJSONValue } from './types.js';
|
|
2
|
+
export declare function isObject(value: unknown): value is Record<string, unknown>;
|
|
3
|
+
export declare function nonEmptyString(value: unknown): value is string;
|
|
4
|
+
export declare function isMintlifyJSONValue(value: unknown): value is MintlifyJSONValue;
|
|
5
|
+
export declare function canonicalize(value: MintlifyJSONValue): MintlifyJSONValue;
|
|
6
|
+
export declare function isExternalReference(value: string): boolean;
|
|
7
|
+
export declare function cleanDocumentPath(value: string): string;
|
|
8
|
+
export declare function cleanFilePath(value: string, extension: string): string;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function isObject(value) {
|
|
2
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
3
|
+
}
|
|
4
|
+
export function nonEmptyString(value) {
|
|
5
|
+
return typeof value === 'string' && value.trim().length > 0;
|
|
6
|
+
}
|
|
7
|
+
export function isMintlifyJSONValue(value) {
|
|
8
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
9
|
+
return true;
|
|
10
|
+
if (typeof value === 'number')
|
|
11
|
+
return Number.isFinite(value);
|
|
12
|
+
if (Array.isArray(value))
|
|
13
|
+
return value.every(isMintlifyJSONValue);
|
|
14
|
+
return isObject(value) && Object.values(value).every(isMintlifyJSONValue);
|
|
15
|
+
}
|
|
16
|
+
export function canonicalize(value) {
|
|
17
|
+
if (Array.isArray(value))
|
|
18
|
+
return value.map(canonicalize);
|
|
19
|
+
if (!isObject(value))
|
|
20
|
+
return value;
|
|
21
|
+
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, canonicalize(child)]));
|
|
22
|
+
}
|
|
23
|
+
export function isExternalReference(value) {
|
|
24
|
+
return /^(?:https?:)?\/\//i.test(value) || value.startsWith('mailto:');
|
|
25
|
+
}
|
|
26
|
+
export function cleanDocumentPath(value) {
|
|
27
|
+
const normalized = value.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '');
|
|
28
|
+
if (!normalized || normalized.endsWith('.md') || normalized.endsWith('.mdx') || normalized.split('/').some((part) => !part || part === '.' || part === '..'))
|
|
29
|
+
return '';
|
|
30
|
+
return normalized;
|
|
31
|
+
}
|
|
32
|
+
export function cleanFilePath(value, extension) {
|
|
33
|
+
const normalized = value.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '');
|
|
34
|
+
if (!normalized.endsWith(extension) || normalized.split('/').some((part) => !part || part === '.' || part === '..'))
|
|
35
|
+
return '';
|
|
36
|
+
return normalized;
|
|
37
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MaterializeMintlifySiteOptions, MintlifyDocument, MintlifySource } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reads a site and its documents from ACI's portable JSON content tree.
|
|
4
|
+
* The source shape is standard ACI content: `config/mintlify.json`, resources
|
|
5
|
+
* below `pages/` and `fragments/`; the generated Mintlify tree is not
|
|
6
|
+
* source content and must live outside this directory.
|
|
7
|
+
*/
|
|
8
|
+
export declare function loadMintlifySource(sourceDir: string): Promise<MintlifySource>;
|
|
9
|
+
/** Loads resolved pages/fragments from ACI compiler output for framework projection. */
|
|
10
|
+
export declare function loadCompiledMintlifySource(sourceDir: string, compiledDir: string): Promise<MintlifySource>;
|
|
11
|
+
/** Materializes one exact Mintlify site from ACI source content. */
|
|
12
|
+
export declare function materializeMintlifySite(options: MaterializeMintlifySiteOptions): Promise<void>;
|
|
13
|
+
/** Project a runtime page using only its selected, immutable fragment bindings. */
|
|
14
|
+
export declare function resolveMintlifyDocument(value: unknown, fragments: Record<string, unknown>, documentPath: string, layout: unknown): Promise<MintlifyDocument>;
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { resolveSlots, resolveFragmentNodes } from '../content/resolve-slots.js';
|
|
2
|
+
import { FragmentNotFoundError } from '../content/provider.js';
|
|
3
|
+
import { mkdir, readFile, readdir, writeFile, } from 'node:fs/promises';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { resolveConfigReferences, toDocsJSON } from './config.js';
|
|
6
|
+
import { renderDocument, renderSnippet } from './blocks.js';
|
|
7
|
+
import { canonicalize, isObject, } from './json.js';
|
|
8
|
+
import { validateAPISpec, validateConfigFragment, validateDocument, validateSite, validateSnippet, validateSource, } from './validate.js';
|
|
9
|
+
/**
|
|
10
|
+
* Reads a site and its documents from ACI's portable JSON content tree.
|
|
11
|
+
* The source shape is standard ACI content: `config/mintlify.json`, resources
|
|
12
|
+
* below `pages/` and `fragments/`; the generated Mintlify tree is not
|
|
13
|
+
* source content and must live outside this directory.
|
|
14
|
+
*/
|
|
15
|
+
export async function loadMintlifySource(sourceDir) {
|
|
16
|
+
const sitePath = path.join(sourceDir, 'config', 'mintlify.json');
|
|
17
|
+
const pagesDir = path.join(sourceDir, 'pages');
|
|
18
|
+
const [site, pageResources, fragmentResources, configFragments, apiSpecs] = await Promise.all([
|
|
19
|
+
readJSON(sitePath),
|
|
20
|
+
readIndexResources(pagesDir),
|
|
21
|
+
readOptionalIndexResources(path.join(sourceDir, 'fragments')),
|
|
22
|
+
readOptionalJSONResources(path.join(sourceDir, 'config', 'mintlify')),
|
|
23
|
+
readOptionalJSONResources(path.join(sourceDir, 'data', 'mintlify-api')),
|
|
24
|
+
]);
|
|
25
|
+
const sourceFragments = new Map(fragmentResources.map(({ value, relative }) => [relative.slice(0, -'/_index.json'.length), value]));
|
|
26
|
+
const getFragment = async (id) => {
|
|
27
|
+
if (!sourceFragments.has(id))
|
|
28
|
+
throw new FragmentNotFoundError(id);
|
|
29
|
+
return sourceFragments.get(id);
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
site: validateSite(site, sitePath),
|
|
33
|
+
documents: await Promise.all(pageResources.map(async ({ value, file, relative }) => validateDocument(await expandDocument(value, getFragment), file, relative === '_index.json' ? 'index' : relative.slice(0, -'/_index.json'.length)))),
|
|
34
|
+
snippets: await Promise.all(fragmentResources.map(async ({ value, file, relative }) => {
|
|
35
|
+
const id = relative.slice(0, -'/_index.json'.length);
|
|
36
|
+
return validateSnippet(await expandSnippet(value, id, getFragment), file, `${id}.mdx`);
|
|
37
|
+
})),
|
|
38
|
+
configFragments: configFragments.map(({ value, file }) => validateConfigFragment(value, file)),
|
|
39
|
+
apiSpecs: apiSpecs.map(({ value, file }) => validateAPISpec(value, file)),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Loads resolved pages/fragments from ACI compiler output for framework projection. */
|
|
43
|
+
export async function loadCompiledMintlifySource(sourceDir, compiledDir) {
|
|
44
|
+
const sitePath = path.join(sourceDir, 'config', 'mintlify.json');
|
|
45
|
+
const manifestPath = path.join(compiledDir, 'manifest.json');
|
|
46
|
+
const [siteValue, manifestValue, configFragments, apiSpecs] = await Promise.all([
|
|
47
|
+
readJSON(sitePath), readJSON(manifestPath),
|
|
48
|
+
readOptionalJSONResources(path.join(sourceDir, 'config', 'mintlify')),
|
|
49
|
+
readOptionalJSONResources(path.join(sourceDir, 'data', 'mintlify-api')),
|
|
50
|
+
]);
|
|
51
|
+
if (!isObject(manifestValue) || !isObject(manifestValue.routes) || !isObject(manifestValue.fragments)) {
|
|
52
|
+
throw new Error(`ACI compiled manifest is invalid: ${manifestPath}`);
|
|
53
|
+
}
|
|
54
|
+
const fragments = await Promise.all(Object.entries(manifestValue.fragments).map(async ([id, entry]) => {
|
|
55
|
+
if (!isObject(entry) || typeof entry.payloadRef !== 'string')
|
|
56
|
+
throw new Error(`ACI compiled fragment is invalid: ${id}`);
|
|
57
|
+
return { id, entry, value: await readJSON(safeOutputPath(compiledDir, entry.payloadRef)) };
|
|
58
|
+
}));
|
|
59
|
+
const byId = new Map(fragments.map(({ id, value }) => [id, value]));
|
|
60
|
+
const getFragment = async (id) => {
|
|
61
|
+
if (!byId.has(id))
|
|
62
|
+
throw new FragmentNotFoundError(id);
|
|
63
|
+
return byId.get(id);
|
|
64
|
+
};
|
|
65
|
+
const documents = await Promise.all(Object.entries(manifestValue.routes).map(async ([slug, entry]) => {
|
|
66
|
+
if (!isObject(entry) || typeof entry.payloadRef !== 'string')
|
|
67
|
+
throw new Error(`ACI compiled route is invalid: ${slug}`);
|
|
68
|
+
const value = await readJSON(safeOutputPath(compiledDir, entry.payloadRef));
|
|
69
|
+
const layout = isObject(value) && typeof value.layout === 'string' && isObject(manifestValue.layouts)
|
|
70
|
+
? manifestValue.layouts[value.layout] : undefined;
|
|
71
|
+
const plan = requireMintlifyLayout(value, layout, entry.payloadRef);
|
|
72
|
+
return validateDocument(await expandDocument(value, getFragment, plan), entry.payloadRef, slug || 'index');
|
|
73
|
+
}));
|
|
74
|
+
const snippets = await Promise.all(fragments.map(async ({ id, entry, value }) => validateSnippet(await expandSnippet(value, id, getFragment), String(entry.payloadRef), `${id}.mdx`)));
|
|
75
|
+
return {
|
|
76
|
+
site: validateSite(siteValue, sitePath), documents, snippets,
|
|
77
|
+
configFragments: configFragments.map(({ value, file }) => validateConfigFragment(value, file)),
|
|
78
|
+
apiSpecs: apiSpecs.map(({ value, file }) => validateAPISpec(value, file)),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Materializes one exact Mintlify site from ACI source content. */
|
|
82
|
+
export async function materializeMintlifySite(options) {
|
|
83
|
+
const outputDir = path.resolve(options.outputDir);
|
|
84
|
+
const site = validateSite(options.site, 'site');
|
|
85
|
+
const getFragment = fragmentLoader(options.snippets ?? []);
|
|
86
|
+
const documents = await Promise.all(options.documents.map(async (document, index) => validateDocument(await expandDocument(document, getFragment), `documents[${index}]`, document.path)));
|
|
87
|
+
const snippets = await Promise.all((options.snippets ?? []).map(async (snippet, index) => validateSnippet(await expandSnippet(snippet, snippet.id, getFragment), `snippets[${index}]`, snippet.path)));
|
|
88
|
+
const configFragments = (options.configFragments ?? []).map((fragment, index) => validateConfigFragment(fragment, `configFragments[${index}]`));
|
|
89
|
+
const apiSpecs = (options.apiSpecs ?? []).map((spec, index) => validateAPISpec(spec, `apiSpecs[${index}]`));
|
|
90
|
+
const nativeConfig = toDocsJSON(site);
|
|
91
|
+
const resolvedConfig = resolveConfigReferences(nativeConfig, configFragments);
|
|
92
|
+
validateSource(resolvedConfig, documents, snippets, apiSpecs);
|
|
93
|
+
const generated = new Map();
|
|
94
|
+
addGenerated(generated, 'docs.json', `${JSON.stringify(nativeConfig, null, 2)}\n`);
|
|
95
|
+
for (const fragment of configFragments) {
|
|
96
|
+
addGenerated(generated, fragment.path, `${JSON.stringify(canonicalize(fragment.value), null, 2)}\n`);
|
|
97
|
+
}
|
|
98
|
+
for (const snippet of snippets) {
|
|
99
|
+
addGenerated(generated, snippet.path, renderSnippet(snippet));
|
|
100
|
+
}
|
|
101
|
+
for (const spec of apiSpecs) {
|
|
102
|
+
addGenerated(generated, spec.path, spec.source.replace(/\r\n/g, '\n').replace(/\n*$/, '\n'));
|
|
103
|
+
}
|
|
104
|
+
for (const document of documents) {
|
|
105
|
+
addGenerated(generated, `${document.path}.mdx`, renderDocument(document));
|
|
106
|
+
}
|
|
107
|
+
await mkdir(outputDir, { recursive: true });
|
|
108
|
+
for (const [relativePath, contents] of generated) {
|
|
109
|
+
const destination = safeOutputPath(outputDir, relativePath);
|
|
110
|
+
await mkdir(path.dirname(destination), { recursive: true });
|
|
111
|
+
await writeFile(destination, contents, 'utf8');
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function addGenerated(generated, outputPath, contents) {
|
|
115
|
+
if (generated.has(outputPath))
|
|
116
|
+
throw new Error(`ACI Mintlify generated output path is duplicated: ${outputPath}`);
|
|
117
|
+
generated.set(outputPath, contents);
|
|
118
|
+
}
|
|
119
|
+
async function readDocuments(directory) {
|
|
120
|
+
let entries;
|
|
121
|
+
try {
|
|
122
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
throw new Error(`ACI Mintlify documents directory is required: ${directory}`, { cause: error });
|
|
126
|
+
}
|
|
127
|
+
const results = [];
|
|
128
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
129
|
+
const file = path.join(directory, entry.name);
|
|
130
|
+
if (entry.isDirectory())
|
|
131
|
+
results.push(...await readDocuments(file));
|
|
132
|
+
else if (entry.isFile() && entry.name.endsWith('.json'))
|
|
133
|
+
results.push({ file, value: await readJSON(file) });
|
|
134
|
+
}
|
|
135
|
+
return results;
|
|
136
|
+
}
|
|
137
|
+
async function readIndexResources(directory, root = directory) {
|
|
138
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
139
|
+
const results = [];
|
|
140
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
141
|
+
const file = path.join(directory, entry.name);
|
|
142
|
+
if (entry.isDirectory())
|
|
143
|
+
results.push(...await readIndexResources(file, root));
|
|
144
|
+
else if (entry.isFile() && entry.name === '_index.json')
|
|
145
|
+
results.push({ file, relative: path.relative(root, file).split(path.sep).join('/'), value: await readJSON(file) });
|
|
146
|
+
}
|
|
147
|
+
return results;
|
|
148
|
+
}
|
|
149
|
+
async function readOptionalIndexResources(directory) {
|
|
150
|
+
try {
|
|
151
|
+
return await readIndexResources(directory);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
if (error.code === 'ENOENT')
|
|
155
|
+
return [];
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async function readOptionalJSONResources(directory) {
|
|
160
|
+
try {
|
|
161
|
+
return await readDocuments(directory);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
if (error.cause && error.cause.code === 'ENOENT')
|
|
165
|
+
return [];
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
async function readJSON(file) {
|
|
170
|
+
try {
|
|
171
|
+
return JSON.parse(await readFile(file, 'utf8'));
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
throw new Error(`ACI Mintlify source is not valid JSON: ${file}`, { cause: error });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function safeOutputPath(root, relativePath) {
|
|
178
|
+
const target = path.resolve(root, relativePath);
|
|
179
|
+
if (target === root || !target.startsWith(`${root}${path.sep}`))
|
|
180
|
+
throw new Error(`ACI Mintlify generated path escapes output directory: ${relativePath}`);
|
|
181
|
+
return target;
|
|
182
|
+
}
|
|
183
|
+
function fragmentLoader(fragments) {
|
|
184
|
+
const byId = new Map();
|
|
185
|
+
for (const fragment of fragments) {
|
|
186
|
+
if (!isObject(fragment) || typeof fragment.id !== 'string')
|
|
187
|
+
continue;
|
|
188
|
+
if (byId.has(fragment.id))
|
|
189
|
+
throw new Error(`ACI fragment ID is duplicated: ${fragment.id}`);
|
|
190
|
+
byId.set(fragment.id, fragment);
|
|
191
|
+
}
|
|
192
|
+
return async (id) => {
|
|
193
|
+
const fragment = byId.get(id);
|
|
194
|
+
if (!fragment)
|
|
195
|
+
throw new FragmentNotFoundError(id);
|
|
196
|
+
return fragment;
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function requireMintlifyLayout(page, value, label) {
|
|
200
|
+
if (!isObject(page) || !isObject(value) || typeof value.name !== 'string'
|
|
201
|
+
|| page.layout !== value.name || !Array.isArray(value.slots)) {
|
|
202
|
+
throw new Error(`ACI Mintlify document ${label} requires its exact bound template render plan`);
|
|
203
|
+
}
|
|
204
|
+
for (const slot of value.slots) {
|
|
205
|
+
if (!isObject(slot) || slot.name !== 'main') {
|
|
206
|
+
throw new Error(`ACI Mintlify template ${value.name} has unsupported region ${JSON.stringify(isObject(slot) ? slot.name : slot)}; only main is supported (${label})`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (value.slots.length !== 1)
|
|
210
|
+
throw new Error(`ACI Mintlify template ${value.name} must declare exactly one main region (${label})`);
|
|
211
|
+
if (value.defaults !== undefined) {
|
|
212
|
+
if (!isObject(value.defaults))
|
|
213
|
+
throw new Error(`ACI Mintlify template ${value.name} has invalid defaults (${label})`);
|
|
214
|
+
for (const [region, nodes] of Object.entries(value.defaults)) {
|
|
215
|
+
if (region !== 'main')
|
|
216
|
+
throw new Error(`ACI Mintlify template ${value.name} has unsupported default region ${JSON.stringify(region)}; only main is supported (${label})`);
|
|
217
|
+
if (!Array.isArray(nodes))
|
|
218
|
+
throw new Error(`ACI Mintlify template ${value.name} has invalid main defaults (${label})`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
223
|
+
async function expandDocument(value, getFragment, layout) {
|
|
224
|
+
if (!isObject(value) || !isObject(value.regions))
|
|
225
|
+
return value;
|
|
226
|
+
if (Object.hasOwn(value.regions, 'main') && !Array.isArray(value.regions.main))
|
|
227
|
+
return value;
|
|
228
|
+
if (layout) {
|
|
229
|
+
const resolved = await resolveSlots(layout, value.regions, getFragment);
|
|
230
|
+
// Preserve unexpected authored keys so validateDocument can refuse them.
|
|
231
|
+
return { ...value, regions: { ...value.regions, main: resolved.main ?? [] } };
|
|
232
|
+
}
|
|
233
|
+
if (!Array.isArray(value.regions.main))
|
|
234
|
+
return value;
|
|
235
|
+
return { ...value, regions: { ...value.regions, main: await resolveFragmentNodes(value.regions.main, getFragment) } };
|
|
236
|
+
}
|
|
237
|
+
/** Project a runtime page using only its selected, immutable fragment bindings. */
|
|
238
|
+
export async function resolveMintlifyDocument(value, fragments, documentPath, layout) {
|
|
239
|
+
const getFragment = async (id) => {
|
|
240
|
+
if (!Object.hasOwn(fragments, id))
|
|
241
|
+
throw new FragmentNotFoundError(id);
|
|
242
|
+
return fragments[id];
|
|
243
|
+
};
|
|
244
|
+
const plan = requireMintlifyLayout(value, layout, documentPath);
|
|
245
|
+
return validateDocument(await expandDocument(value, getFragment, plan), documentPath, documentPath);
|
|
246
|
+
}
|
|
247
|
+
// Standalone snippets traverse the root reference too, so a root self-reference
|
|
248
|
+
// uses the same ancestry/depth checks as a page placement.
|
|
249
|
+
async function expandSnippet(value, id, getFragment) {
|
|
250
|
+
if (!isObject(value))
|
|
251
|
+
return value;
|
|
252
|
+
const [block] = await resolveFragmentNodes([{ kind: 'fragment-ref', fragmentId: id }], getFragment);
|
|
253
|
+
return { ...value, id: value.id ?? id, block };
|
|
254
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { FragmentRefNode } from '../types/page.js';
|
|
2
|
+
export type MintlifyJSONValue = null | boolean | number | string | MintlifyJSONValue[] | {
|
|
3
|
+
[key: string]: MintlifyJSONValue;
|
|
4
|
+
};
|
|
5
|
+
export interface MintlifyNavigationGroup {
|
|
6
|
+
group: string;
|
|
7
|
+
pages: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Native Mintlify docs.json configuration from `.content/config/mintlify.json`. */
|
|
10
|
+
export type MintlifySite = Record<string, MintlifyJSONValue>;
|
|
11
|
+
export interface MintlifyBlock {
|
|
12
|
+
$type: 'component';
|
|
13
|
+
id: string;
|
|
14
|
+
component: 'mintlify.markdown' | 'mintlify.mdx' | 'mintlify.anchor' | 'mintlify.steps' | 'mintlify.step' | 'mintlify.card-group' | 'mintlify.card' | 'mintlify.accordion-group' | 'mintlify.accordion' | 'mintlify.callout' | 'mintlify.tabs' | 'mintlify.tab' | 'mintlify.snippet-ref';
|
|
15
|
+
props: {
|
|
16
|
+
source?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
variant?: 'info' | 'warning' | 'note' | 'tip' | 'check';
|
|
19
|
+
children?: MintlifyBlock[];
|
|
20
|
+
[key: string]: MintlifyJSONValue | MintlifyBlock[] | undefined;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface MintlifyDocument {
|
|
24
|
+
$type: 'page';
|
|
25
|
+
id: string;
|
|
26
|
+
status: string;
|
|
27
|
+
path: string;
|
|
28
|
+
metadata: {
|
|
29
|
+
title: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
mintlify?: {
|
|
32
|
+
sidebarTitle?: string;
|
|
33
|
+
icon?: string;
|
|
34
|
+
frontmatter?: Record<string, MintlifyJSONValue>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
regions: {
|
|
38
|
+
main: MintlifyBlock[];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface MintlifySnippet {
|
|
42
|
+
$type: 'fragment';
|
|
43
|
+
id: string;
|
|
44
|
+
path: string;
|
|
45
|
+
block: MintlifyBlock;
|
|
46
|
+
}
|
|
47
|
+
export interface MintlifyConfigFragment {
|
|
48
|
+
$type: 'mintlify.config-fragment';
|
|
49
|
+
schemaVersion: 1;
|
|
50
|
+
path: string;
|
|
51
|
+
value: MintlifyJSONValue;
|
|
52
|
+
}
|
|
53
|
+
export interface MintlifyAPISpec {
|
|
54
|
+
$type: 'mintlify.api-spec';
|
|
55
|
+
schemaVersion: 1;
|
|
56
|
+
path: string;
|
|
57
|
+
format: 'openapi' | 'asyncapi' | 'graphql';
|
|
58
|
+
source: string;
|
|
59
|
+
}
|
|
60
|
+
export interface MintlifySource {
|
|
61
|
+
site: MintlifySite;
|
|
62
|
+
documents: MintlifyDocument[];
|
|
63
|
+
snippets?: MintlifySnippet[];
|
|
64
|
+
configFragments?: MintlifyConfigFragment[];
|
|
65
|
+
apiSpecs?: MintlifyAPISpec[];
|
|
66
|
+
}
|
|
67
|
+
export interface MaterializeMintlifySiteOptions extends Omit<MintlifySource, 'documents'> {
|
|
68
|
+
documents: Array<Omit<MintlifyDocument, 'regions'> & {
|
|
69
|
+
regions: {
|
|
70
|
+
main: Array<MintlifyBlock | FragmentRefNode>;
|
|
71
|
+
};
|
|
72
|
+
}>;
|
|
73
|
+
outputDir: string;
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MintlifyAPISpec, MintlifyConfigFragment, MintlifyDocument, MintlifyJSONValue, MintlifySite, MintlifySnippet } from './types.js';
|
|
2
|
+
export declare function validateSource(site: MintlifyJSONValue, documents: MintlifyDocument[], snippets: MintlifySnippet[], apiSpecs: MintlifyAPISpec[]): void;
|
|
3
|
+
export declare function validateSite(value: unknown, label: string): MintlifySite;
|
|
4
|
+
export declare function validateDocument(value: unknown, label: string, sourcePath?: string): MintlifyDocument;
|
|
5
|
+
export declare function validateSnippet(value: unknown, label: string, sourcePath?: string): MintlifySnippet;
|
|
6
|
+
export declare function validateConfigFragment(value: unknown, label: string): MintlifyConfigFragment;
|
|
7
|
+
export declare function validateAPISpec(value: unknown, label: string): MintlifyAPISpec;
|