@astryxdesign/cli 0.7.2-canary.fbc03f7 → 0.7.2-canary.fdd384f
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/README.md +9 -8
- package/api/build/help/help.mjs +1 -1
- package/api/component/_adapter.d.mts +41 -1
- package/api/component/_adapter.mjs +93 -7
- package/api/component/component.mjs +22 -5
- package/api/component/integration-export-name.test.mjs +644 -0
- package/api/docs/_adapter.d.mts +11 -0
- package/api/docs/_adapter.mjs +244 -1
- package/api/docs/integrationDocs.test.mjs +124 -0
- package/api/doctor/theme-checks.mjs +1 -1
- package/api/gap-report/gap-report.mjs +67 -4
- package/api/index.d.mts +2 -0
- package/api/index.mjs +2 -0
- package/api/init/run/run.mjs +2 -2
- package/api/integration/_adapter.d.mts +12 -0
- package/api/integration/_adapter.mjs +54 -0
- package/api/integration/add-contribution.component-names.test.mjs +66 -0
- package/api/integration/add-contribution.mjs +8 -4
- package/api/integration/add-contribution.test.mjs +4 -2
- package/api/integration/authoring-checks.mjs +11 -2
- package/api/integration/authoring-checks.test.mjs +39 -0
- package/api/integration/authoring-checks.type.d.mts +9 -0
- package/api/integration/authoring-checks.type.mjs +14 -1
- package/api/integration/check/check.d.mts +96 -0
- package/api/integration/check/check.mjs +357 -0
- package/api/integration/check/check.test.mjs +489 -0
- package/api/integration/integration-check.type.d.mts +118 -0
- package/api/integration/integration-check.type.mjs +84 -0
- package/api/integration/integrationCheck.doc.d.mts +10 -0
- package/api/integration/integrationCheck.doc.mjs +73 -0
- package/api/integration/integrationComponentConflicts.doc.mjs +36 -5
- package/api/integration/pack-check.mjs +51 -97
- package/api/integration/pack-check.test.mjs +359 -0
- package/api/integration/validate-integration.mjs +8 -0
- package/api/integration/validate-integration.test.mjs +11 -0
- package/api/integration/validate-integration.type.d.mts +8 -0
- package/api/integration/validate-integration.type.mjs +12 -1
- package/api/integration/validateIntegration.doc.mjs +17 -3
- package/api/search/search.d.mts +9 -0
- package/api/search/search.integration-check.test.mjs +24 -0
- package/api/search/search.mjs +100 -13
- package/api/swizzle/copy/copy.mjs +28 -14
- package/api/theme/build/build.family.test.mjs +54 -6
- package/api/theme/build/build.mjs +114 -17
- package/api/theme/themeBuild.doc.mjs +4 -4
- package/assets/docs/README.md +10 -0
- package/assets/docs/author-a-theme.doc.mjs +1 -1
- package/assets/docs/getting-started.doc.mjs +3 -3
- package/assets/docs/theme.doc.dense.mjs +1 -1
- package/assets/docs/theme.doc.mjs +1 -1
- package/assets/docs/theme.doc.zh.mjs +1 -1
- package/assets/docs/tree/add-a-component.doc.mjs +10 -0
- package/assets/docs/tree/block-template.doc.mjs +2 -2
- package/assets/docs/tree/check-the-props.doc.mjs +196 -0
- package/assets/docs/tree/check-your-docs.doc.mjs +44 -3
- package/assets/docs/tree/checks.doc.mjs +21 -13
- package/assets/docs/tree/component-family.doc.mjs +5 -1
- package/assets/docs/tree/component-imports.doc.mjs +8 -0
- package/assets/docs/tree/describe-the-component.doc.mjs +1 -1
- package/assets/docs/tree/links.doc.mjs +2 -2
- package/assets/docs/tree/page-template.doc.mjs +1 -1
- package/assets/docs/tree/quick-start.doc.mjs +1 -1
- package/assets/docs/tree/replace-a-core-template.doc.mjs +1 -1
- package/assets/docs/tree/single-component.doc.mjs +3 -2
- package/assets/docs/tree/troubleshooting.doc.mjs +9 -1
- package/assets/docs/tree/type-scale.doc.mjs +3 -3
- package/assets/docs/tree/versioning.doc.mjs +1 -0
- package/assets/docs/tree/write-the-template-file.doc.mjs +2 -1
- package/assets/docs/use-a-theme.doc.mjs +2 -2
- package/assets/theme.template.ts +1 -1
- package/authoring/doctypes/component/component.doc.mjs +2 -2
- package/authoring/doctypes/component/type.ts +6 -3
- package/authoring/doctypes/template/integration-template.doc.d.mts +11 -0
- package/authoring/doctypes/template/integration-template.doc.mjs +49 -0
- package/authoring/doctypes/template/parse.d.mts +6 -2
- package/authoring/doctypes/template/parse.mjs +3 -1
- package/authoring/doctypes/template/template.doc.mjs +1 -1
- package/authoring/doctypes/template/type.ts +22 -0
- package/authoring/index.d.ts +1 -0
- package/authoring/integration/integration.doc.mjs +8 -1
- package/authoring/integration/parse.test.mjs +10 -0
- package/authoring/integration/schema.d.mts +2 -0
- package/authoring/integration/schema.mjs +1 -0
- package/authoring/integration/type.ts +4 -0
- package/clients/cli/commands/build-theme.batch-report.test.mjs +3 -1
- package/clients/cli/commands/build-theme.mjs +1 -1
- package/clients/cli/commands/build-theme.path-safety.test.mjs +155 -21
- package/clients/cli/commands/doctor-integration-components.doc.mjs +15 -4
- package/clients/cli/commands/doctor-integration-validate.doc.mjs +11 -2
- package/clients/cli/commands/doctor-integration.test.mjs +837 -0
- package/clients/cli/commands/doctor.mjs +190 -0
- package/clients/cli/commands/integration-check.doc.mjs +85 -0
- package/clients/cli/commands/integration-check.test.mjs +267 -0
- package/clients/cli/commands/integration.doc.mjs +6 -2
- package/clients/cli/commands/integration.mjs +107 -1
- package/clients/cli/commands/text-json-parity.test.mjs +5 -0
- package/clients/cli/commands/theme-build.doc.mjs +2 -2
- package/clients/cli/index.mjs +1 -0
- package/foundation/config/project.mjs +82 -0
- package/foundation/discovery/authoring-self-docs.mjs +1 -0
- package/foundation/discovery/component-discovery.d.mts +178 -10
- package/foundation/discovery/component-discovery.export-names.test.mjs +760 -0
- package/foundation/discovery/component-discovery.mjs +659 -62
- package/foundation/discovery/component-replacement.mjs +18 -0
- package/foundation/discovery/component-replacement.test.mjs +40 -0
- package/foundation/discovery/doc-types.d.mts +157 -0
- package/foundation/discovery/doc-types.mjs +1224 -0
- package/foundation/discovery/doc-types.test.mjs +652 -0
- package/foundation/discovery/docs-discovery.d.mts +81 -0
- package/foundation/discovery/docs-discovery.mjs +57 -0
- package/foundation/discovery/integration-doc-files.d.mts +22 -0
- package/foundation/discovery/integration-doc-files.mjs +231 -0
- package/foundation/discovery/integration-doc-files.test.mjs +246 -0
- package/foundation/discovery/module-exports.d.mts +27 -0
- package/foundation/discovery/module-exports.mjs +356 -31
- package/foundation/discovery/module-exports.test.mjs +172 -0
- package/foundation/discovery/package-tsconfig.d.mts +14 -0
- package/foundation/discovery/package-tsconfig.mjs +228 -0
- package/foundation/discovery/package-tsconfig.test.mjs +210 -0
- package/foundation/discovery/project-typescript.d.mts +23 -0
- package/foundation/discovery/project-typescript.mjs +61 -0
- package/foundation/discovery/prop-drift.d.mts +278 -0
- package/foundation/discovery/prop-drift.mjs +2263 -0
- package/foundation/discovery/prop-drift.test.mjs +2219 -0
- package/foundation/discovery/type-match.d.mts +53 -0
- package/foundation/discovery/type-match.mjs +660 -0
- package/foundation/discovery/type-match.test.mjs +169 -0
- package/foundation/discovery/type-text.d.mts +68 -0
- package/foundation/discovery/type-text.mjs +658 -0
- package/foundation/discovery/type-text.test.mjs +196 -0
- package/foundation/discovery/unresolved-references.d.mts +62 -0
- package/foundation/discovery/unresolved-references.mjs +790 -0
- package/foundation/discovery/unresolved-references.test.mjs +567 -0
- package/foundation/doc-compiler/doc-loads.test.mjs +6 -0
- package/foundation/doc-compiler/links.d.mts +9 -5
- package/foundation/doc-compiler/links.mjs +4 -2
- package/foundation/integrations/contribution-inventory.mjs +6 -1
- package/foundation/response/response-types.doc.mjs +7 -2
- package/package.json +9 -9
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file A documented type judged against the type the code declares: a match
|
|
5
|
+
* or a mismatch only where both sides read exactly, else not compared.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as os from 'node:os';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import {createRequire} from 'node:module';
|
|
12
|
+
import {afterAll, describe, expect, it} from 'vitest';
|
|
13
|
+
import {judgeType} from './type-match.mjs';
|
|
14
|
+
|
|
15
|
+
const ts = createRequire(import.meta.url)('typescript');
|
|
16
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-type-match-'));
|
|
17
|
+
afterAll(() => fs.rmSync(dir, {recursive: true, force: true}));
|
|
18
|
+
// React's types, as a global `React` namespace the way they declare it.
|
|
19
|
+
const reactTypes = path.join(dir, 'node_modules', '@types', 'react');
|
|
20
|
+
fs.mkdirSync(reactTypes, {recursive: true});
|
|
21
|
+
fs.writeFileSync(
|
|
22
|
+
path.join(reactTypes, 'index.d.ts'),
|
|
23
|
+
'export = React;\nexport as namespace React;\ndeclare namespace React {\n type Key = string | number | bigint;\n interface KeyboardEvent<T = Element> { key: string; currentTarget: T }\n}\n',
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Judges documented types against the props of `Props` in `source`.
|
|
28
|
+
* @param {string} source
|
|
29
|
+
* @returns {(prop: string, docType: string) => string}
|
|
30
|
+
*/
|
|
31
|
+
function judgeIn(source) {
|
|
32
|
+
const file = path.join(dir, 'props.ts');
|
|
33
|
+
fs.writeFileSync(file, source);
|
|
34
|
+
const program = ts.createProgram([file], {
|
|
35
|
+
strict: true,
|
|
36
|
+
noEmit: true,
|
|
37
|
+
typeRoots: [path.join(dir, 'node_modules', '@types')],
|
|
38
|
+
types: ['react'],
|
|
39
|
+
});
|
|
40
|
+
const checker = program.getTypeChecker();
|
|
41
|
+
const props = checker.getTypeAtLocation(
|
|
42
|
+
program
|
|
43
|
+
.getSourceFile(file)
|
|
44
|
+
.statements.find(
|
|
45
|
+
(/** @type {any} */ s) =>
|
|
46
|
+
ts.isInterfaceDeclaration(s) && s.name.text === 'Props',
|
|
47
|
+
).name,
|
|
48
|
+
);
|
|
49
|
+
return (prop, docType) => {
|
|
50
|
+
const symbol = checker.getPropertyOfType(props, prop);
|
|
51
|
+
const declaration = symbol.valueDeclaration;
|
|
52
|
+
return judgeType(docType, [checker.getTypeOfSymbol(symbol)], {
|
|
53
|
+
ts,
|
|
54
|
+
checker,
|
|
55
|
+
location: declaration,
|
|
56
|
+
optional: (symbol.flags & ts.SymbolFlags.Optional) !== 0,
|
|
57
|
+
isDefaultLibrary: (/** @type {any} */ f) =>
|
|
58
|
+
program.isSourceFileDefaultLibrary(f),
|
|
59
|
+
written: [[declaration.type.getText()]],
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
describe('judgeType', () => {
|
|
65
|
+
it("judges exact parts in any order, names for them, a mutable array for a readonly one, an enum member beside its value, literals that hold `|` or `readonly`, `React.X` as React's own, and a member another covers, and compares no other form", () => {
|
|
66
|
+
const judge = judgeIn(`enum Color { Red = 'red', Blue = 'blue' }
|
|
67
|
+
enum Hue { Red = 'red', Blue = 'blue' }
|
|
68
|
+
enum Letter { A = 'a', B = 'b' }
|
|
69
|
+
enum Odd { Lone = '\\uD800' }
|
|
70
|
+
type Size = 'sm' | 'md';
|
|
71
|
+
type Key = 'a' | 'b';
|
|
72
|
+
export interface Props {
|
|
73
|
+
label: string;
|
|
74
|
+
size?: Size;
|
|
75
|
+
tags: readonly string[];
|
|
76
|
+
names: string[];
|
|
77
|
+
color: Color;
|
|
78
|
+
count: number | null;
|
|
79
|
+
onPick: (value: string) => void;
|
|
80
|
+
pair: 'a' | 'b';
|
|
81
|
+
letter: Letter | 'a' | 'b';
|
|
82
|
+
bracket: 'readonly[x';
|
|
83
|
+
onMode: (mode: 'readonly' | 'edit') => void;
|
|
84
|
+
onKey: (event: KeyboardEvent) => void;
|
|
85
|
+
onReactKey: (event: React.KeyboardEvent) => void;
|
|
86
|
+
rowKey: string | number | bigint;
|
|
87
|
+
pick: Key;
|
|
88
|
+
odd: Odd;
|
|
89
|
+
list: (string | number)[];
|
|
90
|
+
frozen: readonly (string | number)[];
|
|
91
|
+
bag: object;
|
|
92
|
+
nothing: void;
|
|
93
|
+
}
|
|
94
|
+
`);
|
|
95
|
+
expect(
|
|
96
|
+
[
|
|
97
|
+
['label', 'string'],
|
|
98
|
+
['label', 'number'],
|
|
99
|
+
['size', "'md' | 'sm'"],
|
|
100
|
+
['size', 'Size'],
|
|
101
|
+
['size', "'sm'"],
|
|
102
|
+
['size', "Size = 'sm'"],
|
|
103
|
+
['tags', 'string[]'],
|
|
104
|
+
['names', 'readonly string[]'],
|
|
105
|
+
['color', 'Color'],
|
|
106
|
+
['color', 'Hue'],
|
|
107
|
+
['color', "'red' | 'blue'"],
|
|
108
|
+
['count', 'number | null'],
|
|
109
|
+
['count', 'number'],
|
|
110
|
+
['onPick', '(value: string) => void'],
|
|
111
|
+
['onPick', '() => void'],
|
|
112
|
+
['pair', `"a'|'b"`],
|
|
113
|
+
['pair', "Letter | 'a' | 'b'"],
|
|
114
|
+
['letter', "'a' | 'b'"],
|
|
115
|
+
['bracket', "'[x'"],
|
|
116
|
+
['onMode', "(mode: 'edit' | 'readonly') => void"],
|
|
117
|
+
['onKey', '(event: KeyboardEvent) => void'],
|
|
118
|
+
['onKey', '(event: React.KeyboardEvent) => void'],
|
|
119
|
+
['onReactKey', '(e: React.KeyboardEvent) => void'],
|
|
120
|
+
['rowKey', 'React.Key'],
|
|
121
|
+
['pick', 'Key'],
|
|
122
|
+
['pick', 'React.Key'],
|
|
123
|
+
['odd', 'Odd'],
|
|
124
|
+
['odd', 'Odd | null'],
|
|
125
|
+
['list', 'string[] | (string | number)[]'],
|
|
126
|
+
['frozen', 'string[] | readonly (string | number)[]'],
|
|
127
|
+
['list', 'readonly string[] | (string | number)[]'],
|
|
128
|
+
['bag', 'object | string[]'],
|
|
129
|
+
['nothing', 'void | undefined'],
|
|
130
|
+
['label', 'any text'],
|
|
131
|
+
].map(([prop, docType]) => `${prop}: ${docType} ${judge(prop, docType)}`),
|
|
132
|
+
).toEqual([
|
|
133
|
+
'label: string match',
|
|
134
|
+
'label: number mismatch',
|
|
135
|
+
"size: 'md' | 'sm' match",
|
|
136
|
+
'size: Size match',
|
|
137
|
+
"size: 'sm' mismatch",
|
|
138
|
+
"size: Size = 'sm' match",
|
|
139
|
+
'tags: string[] match',
|
|
140
|
+
'names: readonly string[] mismatch',
|
|
141
|
+
'color: Color match',
|
|
142
|
+
'color: Hue mismatch',
|
|
143
|
+
"color: 'red' | 'blue' mismatch",
|
|
144
|
+
'count: number | null match',
|
|
145
|
+
'count: number mismatch',
|
|
146
|
+
'onPick: (value: string) => void match',
|
|
147
|
+
'onPick: () => void not_compared',
|
|
148
|
+
`pair: "a'|'b" mismatch`,
|
|
149
|
+
"pair: Letter | 'a' | 'b' match",
|
|
150
|
+
"letter: 'a' | 'b' match",
|
|
151
|
+
"bracket: '[x' mismatch",
|
|
152
|
+
"onMode: (mode: 'edit' | 'readonly') => void match",
|
|
153
|
+
'onKey: (event: KeyboardEvent) => void match',
|
|
154
|
+
'onKey: (event: React.KeyboardEvent) => void not_compared',
|
|
155
|
+
'onReactKey: (e: React.KeyboardEvent) => void match',
|
|
156
|
+
'rowKey: React.Key match',
|
|
157
|
+
'pick: Key match',
|
|
158
|
+
'pick: React.Key mismatch',
|
|
159
|
+
'odd: Odd match',
|
|
160
|
+
'odd: Odd | null mismatch',
|
|
161
|
+
'list: string[] | (string | number)[] match',
|
|
162
|
+
'frozen: string[] | readonly (string | number)[] match',
|
|
163
|
+
'list: readonly string[] | (string | number)[] mismatch',
|
|
164
|
+
'bag: object | string[] match',
|
|
165
|
+
'nothing: void | undefined match',
|
|
166
|
+
'label: any text not_compared',
|
|
167
|
+
]);
|
|
168
|
+
});
|
|
169
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
* Why the project's TypeScript is too old for this module (before 4.8, the
|
|
6
|
+
* oldest every printed form is tested on), or null.
|
|
7
|
+
* @param {{version?: string}} ts
|
|
8
|
+
* @returns {string | null}
|
|
9
|
+
*/
|
|
10
|
+
export function typeTextTooOld(ts: {
|
|
11
|
+
version?: string;
|
|
12
|
+
}): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Canonical type text: the members of the type's top-level union, sorted.
|
|
15
|
+
* The result is cached and frozen, so no caller can change it for the next.
|
|
16
|
+
* @param {string} text
|
|
17
|
+
* @param {{ts: any, optional?: boolean}} options `ts` is the project's own
|
|
18
|
+
* `typescript`; with `optional`, `undefined` is dropped, as an optional
|
|
19
|
+
* prop takes it anyway
|
|
20
|
+
* @returns {readonly string[]}
|
|
21
|
+
*/
|
|
22
|
+
export function normalizeTypeText(text: string, options: {
|
|
23
|
+
ts: any;
|
|
24
|
+
optional?: boolean;
|
|
25
|
+
}): readonly string[];
|
|
26
|
+
/**
|
|
27
|
+
* @file Loose comparison of TypeScript type text, for checking a documented
|
|
28
|
+
* prop type against the type its source declares.
|
|
29
|
+
*
|
|
30
|
+
* {@link normalizeTypeText} parses the text with the project's own TypeScript
|
|
31
|
+
* and prints the type canonically, so grouping always comes from the parse.
|
|
32
|
+
* Two texts are the same type here when they print the same. The printer
|
|
33
|
+
* merges only what TypeScript reads as one type:
|
|
34
|
+
* - comments, whitespace, parentheses that change nothing, and quote style;
|
|
35
|
+
* - the names of function and tuple parameters (a `this` parameter is kept,
|
|
36
|
+
* and a type predicate names its parameter by place);
|
|
37
|
+
* - the order of a union's members and of an object type's properties;
|
|
38
|
+
* - `Array<T>` and `T[]`; a `React.` qualifier;
|
|
39
|
+
* - `true | false` and `boolean`; a string, number or boolean literal beside
|
|
40
|
+
* its primitive; `never` among other union members; and `undefined` on an
|
|
41
|
+
* optional prop.
|
|
42
|
+
* It also sets `readonly`, `Readonly<…>` and `ReadonlyArray<…>` aside: the
|
|
43
|
+
* prop type judgment compares text that writes `readonly` exactly instead.
|
|
44
|
+
* Below the top of a type, a function or conditional type is always printed
|
|
45
|
+
* in parentheses, and a union or intersection wherever its members would
|
|
46
|
+
* otherwise bind differently. Any form the printer does not know is kept as
|
|
47
|
+
* written (comments and whitespace aside), so it never reads as another
|
|
48
|
+
* type. Text that does not parse as one type comes back marked with
|
|
49
|
+
* {@link UNPARSED}, which no printed type starts with, so it never matches.
|
|
50
|
+
* {@link typeTextTooOld} says when the project's TypeScript is too old to
|
|
51
|
+
* read type text with.
|
|
52
|
+
*
|
|
53
|
+
* @input Type text as written in a doc or a source file, or printed by the
|
|
54
|
+
* TypeScript compiler, and the project's own `typescript`.
|
|
55
|
+
* @output The canonical members of the type's top-level union, sorted.
|
|
56
|
+
* @position Used by the prop type judgment (type-match.mjs).
|
|
57
|
+
*/
|
|
58
|
+
/** Marks text that does not parse as one type: no printed type has it. */
|
|
59
|
+
export const UNPARSED: "\0";
|
|
60
|
+
export type Printed = {
|
|
61
|
+
text: string;
|
|
62
|
+
level: number;
|
|
63
|
+
/**
|
|
64
|
+
* a literal
|
|
65
|
+
* its primitive absorbs in a union
|
|
66
|
+
*/
|
|
67
|
+
literal?: "string" | "number" | "boolean" | "other" | undefined;
|
|
68
|
+
};
|