@astryxdesign/cli 0.6.3-canary.8f908ec → 0.6.3-canary.98a2e4e
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/api/docs/_adapter.d.mts +27 -30
- package/api/docs/_adapter.mjs +124 -154
- package/api/docs/detail/detail.d.mts +15 -0
- package/api/docs/detail/detail.mjs +78 -14
- package/api/docs/detail/section/section.mjs +18 -22
- package/api/docs/detail/section/section.test.mjs +3 -4
- package/api/docs/index/index.mjs +5 -6
- package/api/doctor/doctor.mjs +7 -3
- package/api/search/search.mjs +5 -5
- package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +5 -27
- package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +5 -20
- package/package.json +9 -9
- package/api/docs/compiled-topics.test.mjs +0 -78
- package/foundation/doc-compiler/compile.d.mts +0 -162
- package/foundation/doc-compiler/compile.mjs +0 -262
- package/foundation/doc-compiler/doc-compiler.test.mjs +0 -687
- package/foundation/doc-compiler/ir.d.mts +0 -9
- package/foundation/doc-compiler/ir.mjs +0 -287
- package/foundation/doc-compiler/lenses.d.mts +0 -33
- package/foundation/doc-compiler/lenses.mjs +0 -127
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import {describe, it, expect} from 'vitest';
|
|
11
11
|
import {section} from './section.mjs';
|
|
12
12
|
import {AstryxError} from '../../../error.mjs';
|
|
13
|
-
import {loadDocsCatalog,
|
|
13
|
+
import {loadDocsCatalog, loadTopicDoc} from '../../_adapter.mjs';
|
|
14
14
|
|
|
15
15
|
const SLOW = 30_000;
|
|
16
16
|
|
|
@@ -42,8 +42,7 @@ describe('docs.detail.section leaf', () => {
|
|
|
42
42
|
}, SLOW);
|
|
43
43
|
|
|
44
44
|
it('reads a section by its stable key', async () => {
|
|
45
|
-
const
|
|
46
|
-
const {doc} = await lowerTopic(catalog, catalog.resolve('theme'));
|
|
45
|
+
const doc = await loadTopicDoc((await loadDocsCatalog()).resolve('theme'));
|
|
47
46
|
const target = doc.sections[doc.sections.length - 1];
|
|
48
47
|
const res = await section('theme', target.id);
|
|
49
48
|
expect(res.data.title).toBe(target.title);
|
|
@@ -64,7 +63,7 @@ describe('docs.detail.section leaf', () => {
|
|
|
64
63
|
const catalog = await loadDocsCatalog();
|
|
65
64
|
let checked = 0;
|
|
66
65
|
for (const entry of catalog.entries()) {
|
|
67
|
-
const
|
|
66
|
+
const doc = await loadTopicDoc(entry);
|
|
68
67
|
for (const own of doc.sections) {
|
|
69
68
|
if (!own.content.some(block => block.type === 'token-ref')) continue;
|
|
70
69
|
const res = await section(entry.name, own.id, lang ? {lang} : {});
|
package/api/docs/index/index.mjs
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* @file docs.index leaf — the section index of one topic.
|
|
5
5
|
*
|
|
6
|
-
* @input A topic name plus optional {lang, zh, dense, cwd}. Resolves
|
|
7
|
-
* via the shared adapter
|
|
8
|
-
* linked, since the index never inlines a token reference.
|
|
6
|
+
* @input A topic name plus optional {lang, zh, dense, cwd}. Resolves and loads
|
|
7
|
+
* the topic via the shared adapter.
|
|
9
8
|
* @output { type: 'docs.index', data: DocsIndex } — the topic's name, title and
|
|
10
9
|
* description and, for each section, the key it is read by, its title, and a
|
|
11
10
|
* one-line summary. Matches `astryx --json docs <topic> --index`.
|
|
@@ -14,7 +13,7 @@
|
|
|
14
13
|
* read, is the detail leaf.
|
|
15
14
|
*/
|
|
16
15
|
|
|
17
|
-
import {
|
|
16
|
+
import {buildDocsIndexData} from '../../../foundation/discovery/docs-section-key.mjs';
|
|
18
17
|
import {resolveTopicDocs} from '../_adapter.mjs';
|
|
19
18
|
|
|
20
19
|
/**
|
|
@@ -27,6 +26,6 @@ import {resolveTopicDocs} from '../_adapter.mjs';
|
|
|
27
26
|
* @returns {Promise<import('../docs.type.mjs').DocsIndexResponse>}
|
|
28
27
|
*/
|
|
29
28
|
export async function index(topic, options = {}) {
|
|
30
|
-
const {
|
|
31
|
-
return {type: 'docs.index', data:
|
|
29
|
+
const {docsData} = await resolveTopicDocs(topic, options);
|
|
30
|
+
return {type: 'docs.index', data: buildDocsIndexData(docsData)};
|
|
32
31
|
}
|
package/api/doctor/doctor.mjs
CHANGED
|
@@ -34,8 +34,8 @@ import {
|
|
|
34
34
|
docsIndexBytes,
|
|
35
35
|
oversizedDocSections,
|
|
36
36
|
} from '../../foundation/discovery/docs-output-budget.mjs';
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
37
|
+
import {loadTopicDoc, overlayLanguages} from '../docs/_adapter.mjs';
|
|
38
|
+
import {resolveTokenRefs} from '../docs/detail/detail.mjs';
|
|
39
39
|
import {semverCompare, isValidSemver, satisfiesRange} from '../../foundation/env/semver.mjs';
|
|
40
40
|
|
|
41
41
|
/**
|
|
@@ -798,7 +798,11 @@ export async function checkDocsProgressiveDisclosure(ctx) {
|
|
|
798
798
|
for (const lang of [null, ...overlayLanguages(entry)]) {
|
|
799
799
|
const where = lang ? `${entry.name} [${lang}]` : entry.name;
|
|
800
800
|
try {
|
|
801
|
-
const doc =
|
|
801
|
+
const doc = await resolveTokenRefs(
|
|
802
|
+
await loadTopicDoc(entry, {lang}),
|
|
803
|
+
catalog,
|
|
804
|
+
{lang},
|
|
805
|
+
);
|
|
802
806
|
if (lang == null) topics += 1;
|
|
803
807
|
const indexBytes = docsIndexBytes(buildDocsIndexData(doc));
|
|
804
808
|
if (indexBytes > DOC_OUTPUT_BUDGET_BYTES) {
|
package/api/search/search.mjs
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
import {loadIntegrationsSafely} from '../component/_adapter.mjs';
|
|
67
67
|
import {levenshteinDistance} from '../../foundation/text/string-utils.mjs';
|
|
68
68
|
import {discoverTemplates, extractComponents} from '../template/template.mjs';
|
|
69
|
-
import {loadDocsCatalog,
|
|
69
|
+
import {loadDocsCatalog, loadTopicDoc} from '../docs/_adapter.mjs';
|
|
70
70
|
import {AstryxError} from '../error.mjs';
|
|
71
71
|
import {ERROR_CODES} from '../../foundation/response/error-codes.mjs';
|
|
72
72
|
import {setResultCoverage} from './coverage.mjs';
|
|
@@ -732,16 +732,16 @@ async function gatherHooks(coreDir) {
|
|
|
732
732
|
async function gatherDocs(cwd) {
|
|
733
733
|
/** @type {Candidate[]} */
|
|
734
734
|
const candidates = [];
|
|
735
|
-
let
|
|
735
|
+
let entries;
|
|
736
736
|
try {
|
|
737
|
-
|
|
737
|
+
entries = (await loadDocsCatalog(cwd)).entries();
|
|
738
738
|
} catch {
|
|
739
739
|
return candidates;
|
|
740
740
|
}
|
|
741
|
-
for (const entry of
|
|
741
|
+
for (const entry of entries) {
|
|
742
742
|
let doc = null;
|
|
743
743
|
try {
|
|
744
|
-
doc =
|
|
744
|
+
doc = await loadTopicDoc(entry);
|
|
745
745
|
} catch {
|
|
746
746
|
// A topic that cannot be loaded is reported by the commands that own
|
|
747
747
|
// integration issues; search just cannot index it.
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
import {describe, it, expect} from 'vitest';
|
|
4
4
|
|
|
5
5
|
async function applyTransform(source, path = 'test.ts') {
|
|
6
|
-
const {default: transform} =
|
|
7
|
-
await import('../unwrap-authoring-factories.mjs');
|
|
6
|
+
const {default: transform} = await import('../unwrap-authoring-factories.mjs');
|
|
8
7
|
const jscodeshift = (await import('jscodeshift')).default;
|
|
9
8
|
const j = jscodeshift.withParser('tsx');
|
|
10
9
|
const api = {jscodeshift: j, stats: () => {}, report: () => {}};
|
|
@@ -19,7 +18,7 @@ export default createConfig({integrations: ['@acme/widgets']});
|
|
|
19
18
|
`;
|
|
20
19
|
const output = await applyTransform(input);
|
|
21
20
|
expect(output).not.toContain('createConfig');
|
|
22
|
-
expect(output).toContain(
|
|
21
|
+
expect(output).toContain("export default {");
|
|
23
22
|
expect(output).toContain("integrations: ['@acme/widgets']");
|
|
24
23
|
expect(output).not.toContain('type:');
|
|
25
24
|
});
|
|
@@ -133,34 +132,13 @@ export default createComponentDoc();
|
|
|
133
132
|
expect(output).toContain("type: 'component'");
|
|
134
133
|
});
|
|
135
134
|
|
|
136
|
-
it('leaves same-named factories from unrelated packages unchanged', async () => {
|
|
137
|
-
const input = `import {createConfig} from '@acme/eslint';
|
|
138
|
-
export default createConfig({strict: true});
|
|
139
|
-
`;
|
|
140
|
-
expect(await applyTransform(input)).toBe(input);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('keeps an unrelated same-named import when another factory is migrated', async () => {
|
|
144
|
-
const input = `import {createConfig as createLintConfig} from '@acme/eslint';
|
|
145
|
-
import {createDoc} from '@astryxdesign/cli/doc';
|
|
146
|
-
export const lintConfig = createLintConfig({strict: true});
|
|
147
|
-
export const doc = createDoc({name: 'Theming', description: 'How theming works.'});
|
|
148
|
-
`;
|
|
149
|
-
const output = await applyTransform(input);
|
|
150
|
-
expect(output).toContain(
|
|
151
|
-
"import {createConfig as createLintConfig} from '@acme/eslint'",
|
|
152
|
-
);
|
|
153
|
-
expect(output).toContain('createLintConfig({strict: true})');
|
|
154
|
-
expect(output).not.toContain('createDoc');
|
|
155
|
-
expect(output).toContain("type: 'generic'");
|
|
156
|
-
});
|
|
157
|
-
|
|
158
135
|
it('is a no-op when no authoring factory is imported', async () => {
|
|
159
136
|
const input = `import {Button} from '@astryxdesign/core';
|
|
160
137
|
export default Button;
|
|
161
138
|
`;
|
|
162
|
-
const {default: transform} =
|
|
163
|
-
|
|
139
|
+
const {default: transform} = await import(
|
|
140
|
+
'../unwrap-authoring-factories.mjs'
|
|
141
|
+
);
|
|
164
142
|
const jscodeshift = (await import('jscodeshift')).default;
|
|
165
143
|
const j = jscodeshift.withParser('tsx');
|
|
166
144
|
const api = {jscodeshift: j, stats: () => {}, report: () => {}};
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* v0.3.0 removes the authoring factories. Authoring is now types + parsers: an
|
|
7
7
|
* author writes a plain object and stamps its `type` directly. This transform
|
|
8
|
-
* rewrites factory
|
|
9
|
-
*
|
|
10
|
-
* factory imports:
|
|
8
|
+
* rewrites every factory call to the plain object the factory used to return,
|
|
9
|
+
* then drops the now-dead factory imports:
|
|
11
10
|
*
|
|
12
11
|
* createConfig(o) / createIntegration(o) -> o (no discriminant)
|
|
13
12
|
* createComponentDoc(o) -> { ...o, type: 'component' }
|
|
@@ -26,9 +25,8 @@
|
|
|
26
25
|
*
|
|
27
26
|
* Import aliases are followed (`import {createDoc as mk}` → calls to `mk`), and
|
|
28
27
|
* the factory specifiers are removed afterward (the whole import statement goes
|
|
29
|
-
* if nothing else was imported from it).
|
|
30
|
-
*
|
|
31
|
-
* the surviving type imports.
|
|
28
|
+
* if nothing else was imported from it). Run this BEFORE
|
|
29
|
+
* `migrate-authoring-imports`, which repoints the surviving type imports.
|
|
32
30
|
*/
|
|
33
31
|
|
|
34
32
|
export const meta = {
|
|
@@ -37,24 +35,13 @@ export const meta = {
|
|
|
37
35
|
'Rewrites createConfig/createIntegration/createComponentDoc/' +
|
|
38
36
|
'createFunctionDoc/createDoc/createPageTemplate/createBlockTemplate/' +
|
|
39
37
|
'createCodemod/createConfigCodemod calls to the plain object they returned ' +
|
|
40
|
-
|
|
38
|
+
"(stamping the doc/template/codemod `type` discriminant), and removes the " +
|
|
41
39
|
'now-dead factory imports. Authoring is types + parsers in v0.3.0 — there ' +
|
|
42
40
|
'are no factories.',
|
|
43
41
|
pr: '#4612',
|
|
44
42
|
fileExtensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs'],
|
|
45
43
|
};
|
|
46
44
|
|
|
47
|
-
/** Legacy Astryx authoring entrypoints that exported the removed factories. */
|
|
48
|
-
const AUTHORING_SOURCES = new Set([
|
|
49
|
-
'@astryxdesign/cli/config',
|
|
50
|
-
'@astryxdesign/cli/doc',
|
|
51
|
-
'@astryxdesign/cli/integration',
|
|
52
|
-
'@astryxdesign/cli/template',
|
|
53
|
-
'@astryxdesign/cli/codemod',
|
|
54
|
-
'@astryxdesign/core/authoring',
|
|
55
|
-
'@astryxdesign/core/config',
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
45
|
/**
|
|
59
46
|
* Factory name → the `type` discriminant it stamped, or `null` for the config /
|
|
60
47
|
* integration factories, which were pure typed-identity (no discriminant).
|
|
@@ -121,7 +108,6 @@ export default function transformer(file, api) {
|
|
|
121
108
|
/** @type {Map<string, string>} */
|
|
122
109
|
const localToFactory = new Map();
|
|
123
110
|
root.find(j.ImportDeclaration).forEach((/** @type {any} */ path) => {
|
|
124
|
-
if (!AUTHORING_SOURCES.has(path.node.source.value)) return;
|
|
125
111
|
for (const spec of path.node.specifiers ?? []) {
|
|
126
112
|
if (spec.type !== 'ImportSpecifier') continue;
|
|
127
113
|
const importedName = spec.imported?.name;
|
|
@@ -177,7 +163,6 @@ export default function transformer(file, api) {
|
|
|
177
163
|
// Drop the now-dead factory import specifiers; remove any import statement
|
|
178
164
|
// left empty.
|
|
179
165
|
root.find(j.ImportDeclaration).forEach((/** @type {any} */ path) => {
|
|
180
|
-
if (!AUTHORING_SOURCES.has(path.node.source.value)) return;
|
|
181
166
|
const specs = path.node.specifiers ?? [];
|
|
182
167
|
const kept = specs.filter(
|
|
183
168
|
(/** @type {any} */ spec) =>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/cli",
|
|
3
|
-
"version": "0.6.3-canary.
|
|
3
|
+
"version": "0.6.3-canary.98a2e4e",
|
|
4
4
|
"displayName": "CLI",
|
|
5
5
|
"description": "Scaffold projects, browse templates, generate themes, and get agent-ready docs from the command line.",
|
|
6
6
|
"author": "Meta Open Source",
|
|
@@ -100,10 +100,10 @@
|
|
|
100
100
|
"zod": "^4.4.3"
|
|
101
101
|
},
|
|
102
102
|
"peerDependencies": {
|
|
103
|
-
"@astryxdesign/charts": "0.6.3-canary.
|
|
104
|
-
"@astryxdesign/core": "0.6.3-canary.
|
|
105
|
-
"@astryxdesign/lab": "0.6.3-canary.
|
|
106
|
-
"@astryxdesign/theme-neutral": "0.6.3-canary.
|
|
103
|
+
"@astryxdesign/charts": "0.6.3-canary.98a2e4e",
|
|
104
|
+
"@astryxdesign/core": "0.6.3-canary.98a2e4e",
|
|
105
|
+
"@astryxdesign/lab": "0.6.3-canary.98a2e4e",
|
|
106
|
+
"@astryxdesign/theme-neutral": "0.6.3-canary.98a2e4e",
|
|
107
107
|
"gpt-tokenizer": "^3.4.0"
|
|
108
108
|
},
|
|
109
109
|
"peerDependenciesMeta": {
|
|
@@ -121,10 +121,10 @@
|
|
|
121
121
|
}
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
|
-
"@astryxdesign/charts": "0.6.3-canary.
|
|
125
|
-
"@astryxdesign/core": "0.6.3-canary.
|
|
126
|
-
"@astryxdesign/lab": "0.6.3-canary.
|
|
127
|
-
"@astryxdesign/theme-neutral": "0.6.3-canary.
|
|
124
|
+
"@astryxdesign/charts": "0.6.3-canary.98a2e4e",
|
|
125
|
+
"@astryxdesign/core": "0.6.3-canary.98a2e4e",
|
|
126
|
+
"@astryxdesign/lab": "0.6.3-canary.98a2e4e",
|
|
127
|
+
"@astryxdesign/theme-neutral": "0.6.3-canary.98a2e4e",
|
|
128
128
|
"@heroicons/react": "^2.2.0",
|
|
129
129
|
"@stylexjs/stylex": "^0.19.0",
|
|
130
130
|
"@types/babel__core": "^7.20.5",
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @file Every shipped topic compiles to a plain-JSON node that answers every
|
|
5
|
-
* docs read exactly as the live one does, and no read can change another read
|
|
6
|
-
* of the same catalog.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import {describe, expect, it} from 'vitest';
|
|
10
|
-
import {parseCompiledReferenceNode} from '../../foundation/doc-compiler/ir.mjs';
|
|
11
|
-
import {detailView, indexView} from '../../foundation/doc-compiler/lenses.mjs';
|
|
12
|
-
import {
|
|
13
|
-
compileTopic,
|
|
14
|
-
loadDocsCatalog,
|
|
15
|
-
lowerTopic,
|
|
16
|
-
overlayLanguages,
|
|
17
|
-
} from './_adapter.mjs';
|
|
18
|
-
|
|
19
|
-
const SLOW = 60_000;
|
|
20
|
-
|
|
21
|
-
describe('every shipped topic compiles to plain JSON', () => {
|
|
22
|
-
it(
|
|
23
|
-
'survives a JSON round trip with identical responses in every language',
|
|
24
|
-
async () => {
|
|
25
|
-
const catalog = await loadDocsCatalog();
|
|
26
|
-
let compiled = 0;
|
|
27
|
-
for (const entry of catalog.entries()) {
|
|
28
|
-
for (const lang of [null, ...overlayLanguages(entry)]) {
|
|
29
|
-
const lowered = await lowerTopic(catalog, entry, lang);
|
|
30
|
-
expect(parseCompiledReferenceNode(lowered)).toBe(lowered);
|
|
31
|
-
const node = await compileTopic(catalog, entry, lang);
|
|
32
|
-
expect(parseCompiledReferenceNode(node)).toBe(node);
|
|
33
|
-
const copy = parseCompiledReferenceNode(
|
|
34
|
-
JSON.parse(JSON.stringify(node)),
|
|
35
|
-
);
|
|
36
|
-
expect(JSON.stringify(detailView(copy))).toBe(
|
|
37
|
-
JSON.stringify(detailView(node)),
|
|
38
|
-
);
|
|
39
|
-
expect(JSON.stringify(indexView(copy))).toBe(
|
|
40
|
-
JSON.stringify(indexView(node)),
|
|
41
|
-
);
|
|
42
|
-
compiled += 1;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
expect(compiled).toBeGreaterThan(catalog.entries().length);
|
|
46
|
-
},
|
|
47
|
-
SLOW,
|
|
48
|
-
);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('reads that share a catalog', () => {
|
|
52
|
-
it(
|
|
53
|
-
'never let one read change another',
|
|
54
|
-
async () => {
|
|
55
|
-
const catalog = await loadDocsCatalog();
|
|
56
|
-
const tokens = catalog.resolve('tokens');
|
|
57
|
-
const first = detailView(await compileTopic(catalog, tokens));
|
|
58
|
-
for (const section of first.sections) {
|
|
59
|
-
section.title = 'EDITED';
|
|
60
|
-
for (const block of section.content) {
|
|
61
|
-
if (typeof block.text === 'string') block.text = 'EDITED';
|
|
62
|
-
if (Array.isArray(block.rows)) block.rows.push(['EDITED']);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
const again = detailView(await compileTopic(catalog, tokens));
|
|
66
|
-
const index = indexView(await lowerTopic(catalog, tokens));
|
|
67
|
-
const spacing = detailView(
|
|
68
|
-
await compileTopic(catalog, catalog.resolve('spacing')),
|
|
69
|
-
);
|
|
70
|
-
for (const read of [again, index, spacing]) {
|
|
71
|
-
expect(JSON.stringify(read)).not.toContain('EDITED');
|
|
72
|
-
}
|
|
73
|
-
const lowered = await lowerTopic(catalog, tokens);
|
|
74
|
-
expect(Object.isFrozen(lowered.doc.sections[0].content)).toBe(true);
|
|
75
|
-
},
|
|
76
|
-
SLOW,
|
|
77
|
-
);
|
|
78
|
-
});
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
|
-
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* One authored file, as discovery loaded it.
|
|
6
|
-
* @typedef {object} AuthoredFile
|
|
7
|
-
* @property {string} file the file's name, for messages only
|
|
8
|
-
* @property {any} [doc] the parsed doc, when it loaded
|
|
9
|
-
* @property {unknown} [error] why it did not load or parse
|
|
10
|
-
* @property {any} [overlay] the language overlay's export, when one applies
|
|
11
|
-
* @property {unknown} [overlayError] why the overlay did not load
|
|
12
|
-
*/
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {object} ReferenceTopicInput
|
|
15
|
-
* @property {string} id the topic's name in the catalog
|
|
16
|
-
* @property {string} provider the package that owns the topic
|
|
17
|
-
* @property {string | null} replaces the topic it took the place of
|
|
18
|
-
* @property {string | null} lang the overlay language, or null for authored text
|
|
19
|
-
* @property {AuthoredFile} base
|
|
20
|
-
* @property {Array<AuthoredFile & {provider: string}>} extensions in merge order
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* A token reference after linking: the target section's content, or why it
|
|
24
|
-
* has none.
|
|
25
|
-
* @typedef {{status: 'resolved', topic: string, section: string, previewType?: string, content: any[]}
|
|
26
|
-
* | {status: 'unknown-topic'}
|
|
27
|
-
* | {status: 'unknown-section'}} TokenRefResolution
|
|
28
|
-
*/
|
|
29
|
-
/**
|
|
30
|
-
* @typedef {object} CompiledReferenceNode
|
|
31
|
-
* @property {number} schemaVersion
|
|
32
|
-
* @property {'reference'} kind
|
|
33
|
-
* @property {'lowered' | 'linked'} stage `linked` once every token reference
|
|
34
|
-
* carries its resolution; a lowered node carries none
|
|
35
|
-
* @property {string} id the topic's name in the catalog
|
|
36
|
-
* @property {string | null} lang
|
|
37
|
-
* @property {{provider: string, replaces: string | null, extensions: string[]}} provenance
|
|
38
|
-
* @property {Record<string, string>} sourceTitles section key -> authored title
|
|
39
|
-
* @property {any} doc the topic: authored fields in authored order, every
|
|
40
|
-
* section keyed; a linked node's token references carry `resolved`
|
|
41
|
-
*/
|
|
42
|
-
/**
|
|
43
|
-
* Lower one topic: overlay each file, merge the extensions in order, and stamp
|
|
44
|
-
* every section with its key.
|
|
45
|
-
* @param {ReferenceTopicInput} input
|
|
46
|
-
* @returns {CompiledReferenceNode}
|
|
47
|
-
*/
|
|
48
|
-
export function lowerReferenceTopic(input: ReferenceTopicInput): CompiledReferenceNode;
|
|
49
|
-
/**
|
|
50
|
-
* Link every section of a lowered node.
|
|
51
|
-
* @param {CompiledReferenceNode} node
|
|
52
|
-
* @param {(topic: string) => Promise<CompiledReferenceNode | null>} lowerTarget
|
|
53
|
-
* the lowered node a reference names, or null when no topic has that name
|
|
54
|
-
* @returns {Promise<CompiledReferenceNode>}
|
|
55
|
-
*/
|
|
56
|
-
export function linkReferenceTopic(node: CompiledReferenceNode, lowerTarget: (topic: string) => Promise<CompiledReferenceNode | null>): Promise<CompiledReferenceNode>;
|
|
57
|
-
/**
|
|
58
|
-
* Resolve the token references in one section. A section with none comes back
|
|
59
|
-
* as it went in.
|
|
60
|
-
* @template {{content: any[]}} S
|
|
61
|
-
* @param {S} section
|
|
62
|
-
* @param {(topic: string) => Promise<CompiledReferenceNode | null>} lowerTarget
|
|
63
|
-
* @returns {Promise<S>}
|
|
64
|
-
*/
|
|
65
|
-
export function linkReferenceSection<S extends {
|
|
66
|
-
content: any[];
|
|
67
|
-
}>(section: S, lowerTarget: (topic: string) => Promise<CompiledReferenceNode | null>): Promise<S>;
|
|
68
|
-
/** Bumped whenever the shape of a compiled node changes. */
|
|
69
|
-
export const COMPILED_DOC_SCHEMA_VERSION: 1;
|
|
70
|
-
/**
|
|
71
|
-
* One authored file, as discovery loaded it.
|
|
72
|
-
*/
|
|
73
|
-
export type AuthoredFile = {
|
|
74
|
-
/**
|
|
75
|
-
* the file's name, for messages only
|
|
76
|
-
*/
|
|
77
|
-
file: string;
|
|
78
|
-
/**
|
|
79
|
-
* the parsed doc, when it loaded
|
|
80
|
-
*/
|
|
81
|
-
doc?: any;
|
|
82
|
-
/**
|
|
83
|
-
* why it did not load or parse
|
|
84
|
-
*/
|
|
85
|
-
error?: unknown;
|
|
86
|
-
/**
|
|
87
|
-
* the language overlay's export, when one applies
|
|
88
|
-
*/
|
|
89
|
-
overlay?: any;
|
|
90
|
-
/**
|
|
91
|
-
* why the overlay did not load
|
|
92
|
-
*/
|
|
93
|
-
overlayError?: unknown;
|
|
94
|
-
};
|
|
95
|
-
export type ReferenceTopicInput = {
|
|
96
|
-
/**
|
|
97
|
-
* the topic's name in the catalog
|
|
98
|
-
*/
|
|
99
|
-
id: string;
|
|
100
|
-
/**
|
|
101
|
-
* the package that owns the topic
|
|
102
|
-
*/
|
|
103
|
-
provider: string;
|
|
104
|
-
/**
|
|
105
|
-
* the topic it took the place of
|
|
106
|
-
*/
|
|
107
|
-
replaces: string | null;
|
|
108
|
-
/**
|
|
109
|
-
* the overlay language, or null for authored text
|
|
110
|
-
*/
|
|
111
|
-
lang: string | null;
|
|
112
|
-
base: AuthoredFile;
|
|
113
|
-
/**
|
|
114
|
-
* in merge order
|
|
115
|
-
*/
|
|
116
|
-
extensions: Array<AuthoredFile & {
|
|
117
|
-
provider: string;
|
|
118
|
-
}>;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* A token reference after linking: the target section's content, or why it
|
|
122
|
-
* has none.
|
|
123
|
-
*/
|
|
124
|
-
export type TokenRefResolution = {
|
|
125
|
-
status: "resolved";
|
|
126
|
-
topic: string;
|
|
127
|
-
section: string;
|
|
128
|
-
previewType?: string;
|
|
129
|
-
content: any[];
|
|
130
|
-
} | {
|
|
131
|
-
status: "unknown-topic";
|
|
132
|
-
} | {
|
|
133
|
-
status: "unknown-section";
|
|
134
|
-
};
|
|
135
|
-
export type CompiledReferenceNode = {
|
|
136
|
-
schemaVersion: number;
|
|
137
|
-
kind: "reference";
|
|
138
|
-
/**
|
|
139
|
-
* `linked` once every token reference
|
|
140
|
-
* carries its resolution; a lowered node carries none
|
|
141
|
-
*/
|
|
142
|
-
stage: "lowered" | "linked";
|
|
143
|
-
/**
|
|
144
|
-
* the topic's name in the catalog
|
|
145
|
-
*/
|
|
146
|
-
id: string;
|
|
147
|
-
lang: string | null;
|
|
148
|
-
provenance: {
|
|
149
|
-
provider: string;
|
|
150
|
-
replaces: string | null;
|
|
151
|
-
extensions: string[];
|
|
152
|
-
};
|
|
153
|
-
/**
|
|
154
|
-
* section key -> authored title
|
|
155
|
-
*/
|
|
156
|
-
sourceTitles: Record<string, string>;
|
|
157
|
-
/**
|
|
158
|
-
* the topic: authored fields in authored order, every
|
|
159
|
-
* section keyed; a linked node's token references carry `resolved`
|
|
160
|
-
*/
|
|
161
|
-
doc: any;
|
|
162
|
-
};
|