@astryxdesign/cli 0.6.3-canary.f22695a → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/README.md +1 -2
  2. package/api/build/build.type.d.mts +2 -2
  3. package/api/build/build.type.mjs +2 -2
  4. package/api/component/component.type.d.mts +6 -6
  5. package/api/component/component.type.mjs +19 -19
  6. package/api/discover/discover.type.d.mts +4 -4
  7. package/api/discover/discover.type.mjs +10 -10
  8. package/api/docs/_adapter.d.mts +24 -37
  9. package/api/docs/_adapter.mjs +83 -169
  10. package/api/docs/detail/detail.mjs +63 -14
  11. package/api/docs/detail/section/section.d.mts +1 -1
  12. package/api/docs/detail/section/section.mjs +20 -44
  13. package/api/docs/detail/section/section.test.mjs +0 -41
  14. package/api/docs/docs.d.mts +2 -7
  15. package/api/docs/docs.doc.mjs +10 -27
  16. package/api/docs/docs.mjs +9 -16
  17. package/api/docs/docs.test.mjs +0 -6
  18. package/api/docs/docs.type.d.mts +3 -40
  19. package/api/docs/docs.type.mjs +8 -36
  20. package/api/docs/integrationDocs.test.mjs +0 -106
  21. package/api/doctor/doctor.d.mts +0 -48
  22. package/api/doctor/doctor.mjs +0 -232
  23. package/api/doctor/doctor.test.mjs +0 -196
  24. package/api/hook/hook.type.d.mts +3 -3
  25. package/api/hook/hook.type.mjs +11 -11
  26. package/api/hook/list/list.d.mts +1 -1
  27. package/api/integration/add-contribution.mjs +3 -5
  28. package/api/integration/add-contribution.test.mjs +4 -4
  29. package/api/integration/integration-authoring.type.d.mts +1 -1
  30. package/api/integration/pack-check.mjs +7 -49
  31. package/api/integration/pack-check.test.mjs +0 -249
  32. package/api/search/search.d.mts +1 -1
  33. package/api/search/search.mjs +5 -5
  34. package/api/search/search.type.d.mts +2 -2
  35. package/api/search/search.type.mjs +1 -1
  36. package/api/swizzle/swizzle.type.d.mts +2 -2
  37. package/api/swizzle/swizzle.type.mjs +2 -2
  38. package/api/template/template.d.mts +1 -1
  39. package/api/template/template.type.d.mts +6 -6
  40. package/api/template/template.type.mjs +12 -12
  41. package/api/theme/build/build.mjs +6 -20
  42. package/api/theme/build/build.test.mjs +0 -127
  43. package/api/theme/palette/generate/generate.mjs +1 -1
  44. package/api/theme/palette/generate/generator.d.mts +13 -10
  45. package/api/theme/palette/generate/generator.mjs +3 -7
  46. package/api/theme/theme.type.d.mts +11 -170
  47. package/api/theme/theme.type.mjs +27 -94
  48. package/api/upgrade/_adapter.mjs +5 -71
  49. package/api/upgrade/upgrade.doc.mjs +3 -4
  50. package/api/upgrade/upgrade.type.d.mts +5 -5
  51. package/api/upgrade/upgrade.type.mjs +11 -11
  52. package/assets/codemods/integration-discovery.mjs +2 -40
  53. package/assets/codemods/integration-discovery.test.mjs +0 -58
  54. package/assets/codemods/transforms/v0.3.0/__tests__/unwrap-authoring-factories.test.mjs +5 -27
  55. package/assets/codemods/transforms/v0.3.0/unwrap-authoring-factories.mjs +5 -20
  56. package/assets/docs/README.md +0 -9
  57. package/assets/docs/cli-integrations.doc.mjs +15 -86
  58. package/assets/docs/styling-libraries.doc.mjs +1 -1
  59. package/assets/docs/working-with-ai.doc.mjs +1 -1
  60. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.doc.mjs +3 -19
  61. package/assets/templates/blocks/components/Toolbar/ToolbarTableFilter.tsx +65 -383
  62. package/authoring/_shared/contract.ts +0 -22
  63. package/authoring/codemod/codemod.doc.mjs +1 -6
  64. package/authoring/codemod/parse.d.mts +8 -8
  65. package/authoring/codemod/parse.mjs +6 -8
  66. package/authoring/config/parse.d.mts +13 -13
  67. package/authoring/config/parse.mjs +8 -8
  68. package/authoring/config/type.ts +3 -3
  69. package/authoring/debug/parse.d.mts +5 -5
  70. package/authoring/debug/parse.mjs +3 -3
  71. package/authoring/doctypes/_schema.d.mts +23 -788
  72. package/authoring/doctypes/_schema.mjs +39 -492
  73. package/authoring/doctypes/base/type.ts +0 -40
  74. package/authoring/doctypes/command/command.doc.mjs +2 -3
  75. package/authoring/doctypes/command/parse.d.mts +2 -2
  76. package/authoring/doctypes/command/parse.mjs +1 -1
  77. package/authoring/doctypes/command/type.ts +2 -3
  78. package/authoring/doctypes/component/component.doc.mjs +3 -6
  79. package/authoring/doctypes/component/parse.d.mts +2 -2
  80. package/authoring/doctypes/component/parse.mjs +1 -1
  81. package/authoring/doctypes/component/type.ts +3 -4
  82. package/authoring/doctypes/enum/parse.d.mts +2 -2
  83. package/authoring/doctypes/enum/parse.mjs +1 -1
  84. package/authoring/doctypes/enum/type.ts +1 -3
  85. package/authoring/doctypes/function/function.doc.mjs +0 -4
  86. package/authoring/doctypes/function/parse.d.mts +2 -2
  87. package/authoring/doctypes/function/parse.mjs +1 -1
  88. package/authoring/doctypes/function/type.ts +2 -6
  89. package/authoring/doctypes/hook/hook.doc.mjs +0 -4
  90. package/authoring/doctypes/hook/parse.d.mts +2 -2
  91. package/authoring/doctypes/hook/parse.mjs +1 -1
  92. package/authoring/doctypes/hook/type.ts +2 -3
  93. package/authoring/doctypes/legacy.d.mts +6 -8
  94. package/authoring/doctypes/legacy.mjs +4 -5
  95. package/authoring/doctypes/parse.d.mts +18 -20
  96. package/authoring/doctypes/parse.mjs +10 -16
  97. package/authoring/doctypes/parse.test.mjs +3 -77
  98. package/authoring/doctypes/reference/parse.d.mts +2 -2
  99. package/authoring/doctypes/reference/parse.mjs +5 -8
  100. package/authoring/doctypes/reference/reference.doc.mjs +4 -17
  101. package/authoring/doctypes/reference/type.ts +5 -51
  102. package/authoring/doctypes/schema/parse.d.mts +2 -2
  103. package/authoring/doctypes/schema/parse.mjs +1 -1
  104. package/authoring/doctypes/schema/type.ts +2 -3
  105. package/authoring/doctypes/template/parse.d.mts +1 -92
  106. package/authoring/doctypes/template/parse.mjs +2 -36
  107. package/authoring/doctypes/template/parse.test.mjs +2 -8
  108. package/authoring/doctypes/template/template.doc.mjs +0 -4
  109. package/authoring/doctypes/template/type.ts +2 -5
  110. package/authoring/doctypes/types.ts +9 -10
  111. package/authoring/gap-report/parse.d.mts +10 -10
  112. package/authoring/gap-report/parse.mjs +6 -6
  113. package/authoring/gap-report/type.ts +1 -1
  114. package/authoring/index.d.mts +0 -1
  115. package/authoring/index.d.ts +17 -49
  116. package/authoring/index.mjs +0 -1
  117. package/authoring/integration/integration.doc.mjs +6 -13
  118. package/authoring/integration/parse.d.mts +2 -2
  119. package/authoring/integration/parse.mjs +1 -1
  120. package/authoring/integration/parse.test.mjs +1 -10
  121. package/authoring/integration/schema.d.mts +4 -6
  122. package/authoring/integration/schema.mjs +3 -9
  123. package/authoring/integration/type.ts +6 -23
  124. package/authoring/shadcn/receipt.d.mts +6 -6
  125. package/clients/cli/commands/docs.doc.mjs +3 -13
  126. package/clients/cli/commands/docs.mjs +21 -121
  127. package/clients/cli/commands/docs.test.mjs +0 -88
  128. package/clients/cli/commands/integration-authoring.test.mjs +9 -13
  129. package/clients/cli/commands/theme-palette-generate.doc.mjs +4 -8
  130. package/clients/cli/commands/upgrade.doc.mjs +2 -2
  131. package/clients/cli/formatters/index.mjs +1 -162
  132. package/clients/cli/formatters/index.test.mjs +0 -91
  133. package/clients/cli/lib/manifest.mjs +2 -7
  134. package/foundation/config/project.mjs +6 -21
  135. package/foundation/discovery/component-discovery.d.mts +1 -1
  136. package/foundation/discovery/component-discovery.mjs +1 -2
  137. package/foundation/discovery/docs-discovery.d.mts +4 -11
  138. package/foundation/discovery/docs-discovery.mjs +88 -208
  139. package/foundation/discovery/docs-discovery.test.mjs +13 -279
  140. package/foundation/discovery/template-adapter.mjs +1 -2
  141. package/foundation/integrations/autolink.mjs +5 -12
  142. package/foundation/integrations/integration-warnings.mjs +0 -6
  143. package/foundation/integrations/integrations.d.mts +2 -46
  144. package/foundation/integrations/integrations.mjs +8 -167
  145. package/foundation/integrations/integrations.test.mjs +1 -384
  146. package/foundation/integrations/validate-contributions.d.mts +0 -2
  147. package/foundation/integrations/validate-contributions.mjs +0 -10
  148. package/foundation/response/json-contract.test.mjs +17 -46
  149. package/foundation/response/response-types.doc.mjs +1 -6
  150. package/package.json +11 -9
  151. package/api/docs/compiled-topics.test.mjs +0 -78
  152. package/api/docs/index/index.d.mts +0 -18
  153. package/api/docs/index/index.mjs +0 -32
  154. package/api/docs/index/index.test.mjs +0 -62
  155. package/api/upgrade/project-context.test.mjs +0 -272
  156. package/assets/docs/authoring.doc.mjs +0 -14
  157. package/assets/templates/blocks/components/Timer/TimerFormats.doc.mjs +0 -14
  158. package/assets/templates/blocks/components/Timer/TimerFormats.tsx +0 -34
  159. package/assets/templates/blocks/components/Timer/TimerInline.doc.mjs +0 -14
  160. package/assets/templates/blocks/components/Timer/TimerInline.tsx +0 -14
  161. package/assets/templates/blocks/components/Timer/TimerShowcase.doc.mjs +0 -13
  162. package/assets/templates/blocks/components/Timer/TimerShowcase.tsx +0 -47
  163. package/assets/templates/blocks/components/Timer/TimerTypography.doc.mjs +0 -14
  164. package/assets/templates/blocks/components/Timer/TimerTypography.tsx +0 -31
  165. package/authoring/doctypes/base/graph-fields.doc.d.mts +0 -9
  166. package/authoring/doctypes/base/graph-fields.doc.mjs +0 -62
  167. package/authoring/doctypes/load-contract.test.mjs +0 -207
  168. package/authoring/doctypes/namespace/namespace.doc.d.mts +0 -9
  169. package/authoring/doctypes/namespace/namespace.doc.mjs +0 -132
  170. package/authoring/doctypes/namespace/parse.d.mts +0 -12
  171. package/authoring/doctypes/namespace/parse.mjs +0 -25
  172. package/authoring/doctypes/namespace/parse.test.mjs +0 -165
  173. package/authoring/doctypes/namespace/type.ts +0 -71
  174. package/authoring/identity/identity.doc.d.mts +0 -9
  175. package/authoring/identity/identity.doc.mjs +0 -61
  176. package/authoring/identity/type.ts +0 -132
  177. package/foundation/discovery/authoring-self-docs.d.mts +0 -69
  178. package/foundation/discovery/authoring-self-docs.mjs +0 -214
  179. package/foundation/discovery/authoring-self-docs.test.mjs +0 -154
  180. package/foundation/discovery/docs-output-budget.d.mts +0 -28
  181. package/foundation/discovery/docs-output-budget.mjs +0 -50
  182. package/foundation/discovery/docs-section-key.d.mts +0 -98
  183. package/foundation/discovery/docs-section-key.mjs +0 -221
  184. package/foundation/discovery/docs-section-key.test.mjs +0 -224
  185. package/foundation/doc-compiler/compile.d.mts +0 -162
  186. package/foundation/doc-compiler/compile.mjs +0 -262
  187. package/foundation/doc-compiler/doc-compiler.test.mjs +0 -687
  188. package/foundation/doc-compiler/ir.d.mts +0 -9
  189. package/foundation/doc-compiler/ir.mjs +0 -287
  190. package/foundation/doc-compiler/lenses.d.mts +0 -33
  191. package/foundation/doc-compiler/lenses.mjs +0 -127
  192. package/foundation/identity/provider-identity.d.mts +0 -90
  193. package/foundation/identity/provider-identity.mjs +0 -320
  194. package/foundation/identity/provider-identity.test.mjs +0 -254
  195. package/foundation/identity/providers.d.mts +0 -7
  196. package/foundation/identity/providers.mjs +0 -16
  197. package/foundation/integrations/provider-conflicts.test.mjs +0 -125
@@ -39,9 +39,6 @@ import {discoverIntegrationThemes} from '../discovery/theme-discovery.mjs';
39
39
  /** Stable issue code for an invalid optional agent-doc contribution. */
40
40
  export const INVALID_AGENT_DOCS = 'invalid_agent_docs';
41
41
 
42
- /** Stable issue code for a package whose provider ID is already claimed. */
43
- export const DUPLICATE_PROVIDER = 'duplicate_provider';
44
-
45
42
  /** @param {string} code @param {string} message @returns {Issue} */
46
43
  export function issueError(code, message) {
47
44
  return {code, severity: 'error', message};
@@ -292,13 +289,6 @@ export async function validateLoadedIntegration(loaded) {
292
289
  /** @type {Issue[]} */
293
290
  const issues = [];
294
291
  if (!loaded || typeof loaded !== 'object') return issues;
295
- // A package set aside for claiming another package's provider ID has no
296
- // contribution roots to check; the conflict itself is what to report.
297
- if (loaded.__providerConflict) {
298
- return [
299
- issueWarning(DUPLICATE_PROVIDER, loaded.__providerConflict.message),
300
- ];
301
- }
302
292
  // A manifest that threw on import (or failed the schema) carries a load-error
303
293
  // marker and no contribution roots, so every check below would find nothing
304
294
  // and report a clean integration — which is how a stale manifest used to go
@@ -13,8 +13,6 @@
13
13
 
14
14
  import {describe, it, expect, beforeEach, afterEach, vi} from 'vitest';
15
15
  import {spawnSync} from 'node:child_process';
16
- import * as fs from 'node:fs';
17
- import * as os from 'node:os';
18
16
  import * as path from 'node:path';
19
17
  import {fileURLToPath} from 'node:url';
20
18
  import {
@@ -29,20 +27,10 @@ import {
29
27
  } from './json.mjs';
30
28
 
31
29
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
32
- const CLI = path.resolve(
33
- __dirname,
34
- '..',
35
- '..',
36
- 'clients',
37
- 'cli',
38
- 'bin',
39
- 'astryx.mjs',
40
- );
41
-
42
- /** @param {string[]} args @param {{cwd?: string}} [options] */
43
- function runCli(args, {cwd = process.cwd()} = {}) {
30
+ const CLI = path.resolve(__dirname, '..', '..', 'clients', 'cli', 'bin', 'astryx.mjs');
31
+
32
+ function runCli(args) {
44
33
  return spawnSync(process.execPath, [CLI, ...args], {
45
- cwd,
46
34
  encoding: 'utf8',
47
35
  timeout: 20_000,
48
36
  stdio: ['ignore', 'pipe', 'pipe'],
@@ -54,9 +42,7 @@ describe('json envelope shape', () => {
54
42
  let logs;
55
43
  beforeEach(() => {
56
44
  logs = [];
57
- vi.spyOn(console, 'log').mockImplementation((...a) =>
58
- logs.push(a.join(' ')),
59
- );
45
+ vi.spyOn(console, 'log').mockImplementation((...a) => logs.push(a.join(' ')));
60
46
  setJsonMode(false);
61
47
  });
62
48
  afterEach(() => {
@@ -94,13 +80,11 @@ describe('json envelope shape', () => {
94
80
  });
95
81
 
96
82
  it('toErrorEnvelope honors an explicit code argument', () => {
97
- expect(toErrorEnvelope('boom', undefined, 'ERR_UNKNOWN_COMPONENT')).toEqual(
98
- {
99
- apiVersion: API_VERSION,
100
- error: 'boom',
101
- code: 'ERR_UNKNOWN_COMPONENT',
102
- },
103
- );
83
+ expect(toErrorEnvelope('boom', undefined, 'ERR_UNKNOWN_COMPONENT')).toEqual({
84
+ apiVersion: API_VERSION,
85
+ error: 'boom',
86
+ code: 'ERR_UNKNOWN_COMPONENT',
87
+ });
104
88
  });
105
89
 
106
90
  it('toErrorEnvelope reads a code carried on a thrown Error', () => {
@@ -125,12 +109,8 @@ describe('json envelope shape', () => {
125
109
  // The guard is `Array.isArray(...) && .length`, not a bare `?.length` — a
126
110
  // string ("hello".length === 5) or a `{length: n}` object must NOT slip
127
111
  // through as `suggestions`, which is contractually a Suggestion[].
128
- expect(
129
- 'suggestions' in toErrorEnvelope('x', /** @type {any} */ ('hello')),
130
- ).toBe(false);
131
- expect(
132
- 'suggestions' in toErrorEnvelope('x', /** @type {any} */ ({length: 3})),
133
- ).toBe(false);
112
+ expect('suggestions' in toErrorEnvelope('x', /** @type {any} */ ('hello'))).toBe(false);
113
+ expect('suggestions' in toErrorEnvelope('x', /** @type {any} */ ({length: 3}))).toBe(false);
134
114
  });
135
115
  });
136
116
 
@@ -139,12 +119,8 @@ describe('stdout discipline (humanLog / humanWarn)', () => {
139
119
  beforeEach(() => {
140
120
  logs = [];
141
121
  errs = [];
142
- vi.spyOn(console, 'log').mockImplementation((...a) =>
143
- logs.push(a.join(' ')),
144
- );
145
- vi.spyOn(console, 'error').mockImplementation((...a) =>
146
- errs.push(a.join(' ')),
147
- );
122
+ vi.spyOn(console, 'log').mockImplementation((...a) => logs.push(a.join(' ')));
123
+ vi.spyOn(console, 'error').mockImplementation((...a) => errs.push(a.join(' ')));
148
124
  });
149
125
  afterEach(() => {
150
126
  vi.restoreAllMocks();
@@ -198,15 +174,10 @@ describe('contract: every --json emission is valid JSON with apiVersion', () =>
198
174
  });
199
175
 
200
176
  it('init emits its install receipt', () => {
201
- const cwd = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-json-contract-'));
202
- try {
203
- const r = runCli(['init', '--json'], {cwd});
204
- const env = JSON.parse(r.stdout);
205
- expect(env.apiVersion).toBe(API_VERSION);
206
- expect(env.type).toBe('init.run');
207
- } finally {
208
- fs.rmSync(cwd, {recursive: true, force: true});
209
- }
177
+ const r = runCli(['init', '--json']);
178
+ const env = JSON.parse(r.stdout);
179
+ expect(env.apiVersion).toBe(API_VERSION);
180
+ expect(env.type).toBe('init.run');
210
181
  });
211
182
 
212
183
  it('supported command (discover) emits clean JSON, no human chatter leak', () => {
@@ -68,15 +68,10 @@ export const doc = {
68
68
  description:
69
69
  "One topic's full ReferenceDoc, with token-ref blocks inlined.",
70
70
  },
71
- {
72
- value: 'docs.index',
73
- description:
74
- "One topic's section index (--index): each section's key, title, and one-line summary.",
75
- },
76
71
  {
77
72
  value: 'docs.detail.section',
78
73
  description:
79
- 'One ReferenceSection of a topic, found by key or title, with token-ref blocks inlined.',
74
+ 'A single ReferenceSection of a topic: the first whose title contains the section query.',
80
75
  },
81
76
 
82
77
  // blog (read from the published RSS feed)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/cli",
3
- "version": "0.6.3-canary.f22695a",
3
+ "version": "0.6.3",
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,11 @@
100
100
  "zod": "^4.4.3"
101
101
  },
102
102
  "peerDependencies": {
103
- "@astryxdesign/charts": "0.6.3-canary.f22695a",
104
- "@astryxdesign/core": "0.6.3-canary.f22695a",
105
- "@astryxdesign/lab": "0.6.3-canary.f22695a",
106
- "@astryxdesign/theme-neutral": "0.6.3-canary.f22695a"
103
+ "@astryxdesign/charts": "*",
104
+ "@astryxdesign/core": "*",
105
+ "@astryxdesign/lab": "*",
106
+ "@astryxdesign/theme-neutral": "*",
107
+ "gpt-tokenizer": "^3.4.0"
107
108
  },
108
109
  "peerDependenciesMeta": {
109
110
  "@astryxdesign/charts": {
@@ -120,13 +121,14 @@
120
121
  }
121
122
  },
122
123
  "devDependencies": {
123
- "@astryxdesign/charts": "0.6.3-canary.f22695a",
124
- "@astryxdesign/core": "0.6.3-canary.f22695a",
125
- "@astryxdesign/lab": "0.6.3-canary.f22695a",
126
- "@astryxdesign/theme-neutral": "0.6.3-canary.f22695a",
124
+ "@astryxdesign/charts": "*",
125
+ "@astryxdesign/core": "*",
126
+ "@astryxdesign/lab": "*",
127
+ "@astryxdesign/theme-neutral": "*",
127
128
  "@heroicons/react": "^2.2.0",
128
129
  "@stylexjs/stylex": "^0.19.0",
129
130
  "@types/babel__core": "^7.20.5",
131
+ "gpt-tokenizer": "^3.4.0",
130
132
  "lucide-react": "^1.18.0",
131
133
  "recharts": "^3.9.2"
132
134
  },
@@ -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,18 +0,0 @@
1
- // @generated by scripts/sync-api-types.mjs from the JSDoc in api/**/*.mjs.
2
- // DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
3
-
4
- /**
5
- * @param {string} topic
6
- * @param {object} [options]
7
- * @param {string} [options.lang]
8
- * @param {boolean} [options.zh]
9
- * @param {boolean} [options.dense]
10
- * @param {string} [options.cwd]
11
- * @returns {Promise<import('../docs.type.mjs').DocsIndexResponse>}
12
- */
13
- export function index(topic: string, options?: {
14
- lang?: string | undefined;
15
- zh?: boolean | undefined;
16
- dense?: boolean | undefined;
17
- cwd?: string | undefined;
18
- }): Promise<import("../docs.type.mjs").DocsIndexResponse>;
@@ -1,32 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file docs.index leaf — the section index of one topic.
5
- *
6
- * @input A topic name plus optional {lang, zh, dense, cwd}. Resolves the topic
7
- * via the shared adapter and reads its lowered compiled node; nothing is
8
- * linked, since the index never inlines a token reference.
9
- * @output { type: 'docs.index', data: DocsIndex } — the topic's name, title and
10
- * description and, for each section, the key it is read by, its title, and a
11
- * one-line summary. Matches `astryx --json docs <topic> --index`.
12
- * @position Leaf under api/docs: a topic's opt-in progressive read. One section
13
- * is the section leaf (`docs <topic> <key>`); the whole topic, a plain topic
14
- * read, is the detail leaf.
15
- */
16
-
17
- import {indexView} from '../../../foundation/doc-compiler/lenses.mjs';
18
- import {resolveTopicDocs} from '../_adapter.mjs';
19
-
20
- /**
21
- * @param {string} topic
22
- * @param {object} [options]
23
- * @param {string} [options.lang]
24
- * @param {boolean} [options.zh]
25
- * @param {boolean} [options.dense]
26
- * @param {string} [options.cwd]
27
- * @returns {Promise<import('../docs.type.mjs').DocsIndexResponse>}
28
- */
29
- export async function index(topic, options = {}) {
30
- const {node} = await resolveTopicDocs(topic, options);
31
- return {type: 'docs.index', data: indexView(node)};
32
- }
@@ -1,62 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- import {describe, expect, it} from 'vitest';
4
- import {docs} from '../docs.mjs';
5
- import {index} from './index.mjs';
6
- import {loadDocsCatalog} from '../_adapter.mjs';
7
-
8
- const SLOW = 60_000;
9
-
10
- describe('docs.index leaf', () => {
11
- it('lists each section by key, title, and summary', async () => {
12
- const res = await index('theme');
13
- expect(res.type).toBe('docs.index');
14
- expect(res.data).toMatchObject({name: 'theme', title: expect.any(String)});
15
- const keys = res.data.sections.map(s => s.id);
16
- expect(new Set(keys).size).toBe(keys.length);
17
- for (const entry of res.data.sections) {
18
- expect(Object.keys(entry)).toEqual(['id', 'title', 'summary']);
19
- expect(entry.summary.length).toBeLessThanOrEqual(240);
20
- }
21
- }, SLOW);
22
-
23
- it('names the sections the full topic has, with the same keys', async () => {
24
- const full = await docs('theme');
25
- const {data} = await index('theme');
26
- expect(data.sections.map(s => [s.id, s.title])).toEqual(
27
- full.data.sections.map(s => [s.id, s.title]),
28
- );
29
- }, SLOW);
30
-
31
- it('keeps every key the same in every language', async () => {
32
- const english = (await index('theme')).data.sections.map(s => s.id);
33
- for (const lang of ['zh', 'dense']) {
34
- const localized = await index('theme', {lang});
35
- expect(localized.data.sections.map(s => s.id)).toEqual(english);
36
- }
37
- }, SLOW);
38
-
39
- it('lists keys every section can be read by', async () => {
40
- const catalog = await loadDocsCatalog();
41
- for (const entry of catalog.entries()) {
42
- const {data} = await index(entry.name);
43
- for (const {id, title} of data.sections) {
44
- const read = await docs(entry.name, id);
45
- expect(read.data.title).toBe(title);
46
- }
47
- }
48
- }, SLOW);
49
- });
50
-
51
- describe('docs() topic reads', () => {
52
- it('returns the whole topic by default, as before', async () => {
53
- const res = await docs('theme');
54
- expect(res.type).toBe('docs.detail');
55
- expect(res.data.sections[0].content.length).toBeGreaterThan(0);
56
- }, SLOW);
57
-
58
- it('returns the section index on request', async () => {
59
- const res = await docs('theme', undefined, {index: true});
60
- expect(res.type).toBe('docs.index');
61
- }, SLOW);
62
- });
@@ -1,272 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file `loadProjectContext` agrees with Project on provider identity, so
5
- * `astryx upgrade` never runs codemods from a package Project set aside.
6
- *
7
- * Fixtures live under a repo-local temp dir, not /tmp, because Vite refuses to
8
- * dynamically import a module from outside the project root.
9
- */
10
-
11
- import {afterEach, beforeEach, describe, expect, it} from 'vitest';
12
- import * as fs from 'node:fs';
13
- import * as path from 'node:path';
14
- import {loadProjectContext, selectIntegrationCodemodsFor} from './_adapter.mjs';
15
-
16
- let tmpDir;
17
- let originalCwd;
18
-
19
- beforeEach(() => {
20
- originalCwd = process.cwd();
21
- tmpDir = fs.mkdtempSync(path.join(process.cwd(), '.astryx-upgrade-context-'));
22
- });
23
-
24
- afterEach(() => {
25
- process.chdir(originalCwd);
26
- fs.rmSync(tmpDir, {recursive: true, force: true});
27
- });
28
-
29
- /**
30
- * Install an integration package that ships one 0.2.0 codemod.
31
- * @param {string} name
32
- * @param {string} version
33
- * @param {Record<string, unknown>} [manifest]
34
- */
35
- function installWithCodemod(name, version, manifest = {}) {
36
- const pkgDir = path.join(tmpDir, 'node_modules', ...name.split('/'));
37
- const codemodDir = path.join(pkgDir, 'codemods', '0.2.0');
38
- fs.mkdirSync(codemodDir, {recursive: true});
39
- fs.writeFileSync(path.join(pkgDir, 'package.json'), JSON.stringify({name, version}));
40
- fs.writeFileSync(
41
- path.join(pkgDir, 'astryx.integration.mjs'),
42
- `export default ${JSON.stringify({codemods: './codemods', ...manifest})};\n`,
43
- );
44
- fs.writeFileSync(
45
- path.join(codemodDir, 'rename.mjs'),
46
- "export default {type: 'code', title: 'Rename', transform: file => file.source};\n",
47
- );
48
- }
49
-
50
- /** @param {string[]} integrations */
51
- function configure(integrations) {
52
- fs.writeFileSync(
53
- path.join(tmpDir, 'astryx.config.mjs'),
54
- `export default ${JSON.stringify({integrations})};\n`,
55
- );
56
- }
57
-
58
- describe('loadProjectContext provider identity', () => {
59
- it('keeps codemods from a configured package the authored package sets aside', async () => {
60
- installWithCodemod('@acme/widgets', '1.0.0');
61
- configure(['@acme/widgets']);
62
- fs.writeFileSync(
63
- path.join(tmpDir, 'package.json'),
64
- JSON.stringify({name: '@acme/renamed', version: '2.0.0-dev'}),
65
- );
66
- fs.writeFileSync(
67
- path.join(tmpDir, 'astryx.integration.mjs'),
68
- "export default {providerId: '@acme/widgets'};\n",
69
- );
70
-
71
- const {integrations} = await loadProjectContext(tmpDir);
72
- expect(
73
- integrations.map(integration => [
74
- integration.name,
75
- Boolean(integration.__providerConflict),
76
- ]),
77
- ).toEqual([['@acme/widgets', true]]);
78
- expect(
79
- await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0'),
80
- ).toEqual([]);
81
- });
82
-
83
- it('still selects codemods from a configured package nothing else claims', async () => {
84
- installWithCodemod('@acme/widgets', '1.0.0');
85
- configure(['@acme/widgets']);
86
- fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({name: 'consumer'}));
87
-
88
- const {integrations} = await loadProjectContext(tmpDir);
89
- const selected = await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0');
90
- expect(selected.map(entry => entry.version)).toEqual(['0.2.0']);
91
- });
92
-
93
- it('sets aside an --integration extra that claims a configured provider ID', async () => {
94
- installWithCodemod('@acme/widgets', '1.0.0');
95
- installWithCodemod('@acme/other', '1.0.0', {providerId: '@acme/widgets'});
96
- configure(['@acme/widgets']);
97
- fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({name: 'consumer'}));
98
- // `--integration` specs resolve from the process cwd, as they always have.
99
- process.chdir(tmpDir);
100
-
101
- const {integrations} = await loadProjectContext(tmpDir, ['@acme/other']);
102
- expect(
103
- integrations.map(integration => [
104
- integration.name,
105
- integration.__providerConflict?.claimedBy ?? null,
106
- ]),
107
- ).toEqual([
108
- ['@acme/widgets', null],
109
- ['@acme/other', '@acme/widgets'],
110
- ]);
111
- });
112
-
113
- it('runs the installed copy of a package that lists itself, not its work in progress', async () => {
114
- installWithCodemod('@acme/widgets', '1.0.0');
115
- configure(['@acme/widgets']);
116
- fs.writeFileSync(
117
- path.join(tmpDir, 'package.json'),
118
- JSON.stringify({name: '@acme/widgets', version: '3.0.0-dev'}),
119
- );
120
- fs.writeFileSync(
121
- path.join(tmpDir, 'astryx.integration.mjs'),
122
- "export default {codemods: './codemods'};\n",
123
- );
124
- fs.mkdirSync(path.join(tmpDir, 'codemods', '0.2.0'), {recursive: true});
125
- fs.writeFileSync(
126
- path.join(tmpDir, 'codemods', '0.2.0', 'local-wip.mjs'),
127
- "export default {type: 'code', title: 'Local WIP', transform: file => file.source};\n",
128
- );
129
-
130
- const {integrations} = await loadProjectContext(tmpDir);
131
- expect(
132
- integrations.map(integration => [
133
- integration.name,
134
- integration.version,
135
- Boolean(integration.__local),
136
- Boolean(integration.__providerConflict),
137
- ]),
138
- ).toEqual([['@acme/widgets', '1.0.0', false, false]]);
139
- const selected = JSON.stringify(
140
- await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0'),
141
- );
142
- expect(selected).toContain('rename');
143
- expect(selected).not.toContain('local-wip');
144
- });
145
-
146
- it('runs the installed copy when the authored package is named with --integration', async () => {
147
- installWithCodemod('@acme/widgets', '1.0.0');
148
- configure([]);
149
- fs.writeFileSync(
150
- path.join(tmpDir, 'package.json'),
151
- JSON.stringify({name: '@acme/widgets', version: '3.0.0-dev'}),
152
- );
153
- fs.writeFileSync(
154
- path.join(tmpDir, 'astryx.integration.mjs'),
155
- "export default {codemods: './codemods'};\n",
156
- );
157
- fs.mkdirSync(path.join(tmpDir, 'codemods', '0.2.0'), {recursive: true});
158
- fs.writeFileSync(
159
- path.join(tmpDir, 'codemods', '0.2.0', 'local-wip.mjs'),
160
- "export default {type: 'code', title: 'Local WIP', transform: file => file.source};\n",
161
- );
162
- process.chdir(tmpDir);
163
-
164
- const {integrations} = await loadProjectContext(tmpDir, ['@acme/widgets']);
165
- expect(
166
- integrations.map(integration => [
167
- integration.name,
168
- integration.version,
169
- Boolean(integration.__local),
170
- integration.__providerConflict?.claimedBy ?? null,
171
- ]),
172
- ).toEqual([['@acme/widgets', '1.0.0', false, null]]);
173
- const selected = JSON.stringify(
174
- await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0'),
175
- );
176
- expect(selected).toContain('rename');
177
- expect(selected).not.toContain('local-wip');
178
- });
179
-
180
- it("sets aside an --integration extra that claims an autolinked package's ID", async () => {
181
- installWithCodemod('@acme/a', '1.0.0');
182
- installWithCodemod('@acme/b', '1.0.0', {providerId: '@acme/a'});
183
- configure([]);
184
- fs.writeFileSync(
185
- path.join(tmpDir, 'package.json'),
186
- JSON.stringify({name: 'consumer', dependencies: {'@acme/a': '1.0.0'}}),
187
- );
188
- process.chdir(tmpDir);
189
-
190
- const {integrations} = await loadProjectContext(tmpDir, ['@acme/b']);
191
- expect(
192
- integrations.map(integration => [
193
- integration.name,
194
- integration.__providerConflict?.claimedBy ?? null,
195
- ]),
196
- ).toEqual([['@acme/b', '@acme/a']]);
197
- expect(
198
- await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0'),
199
- ).toEqual([]);
200
- });
201
-
202
- it('runs an autolinked package the user names with --integration', async () => {
203
- installWithCodemod('@acme/a', '1.0.0');
204
- fs.writeFileSync(
205
- path.join(tmpDir, 'package.json'),
206
- JSON.stringify({name: 'consumer', dependencies: {'@acme/a': '1.0.0'}}),
207
- );
208
- process.chdir(tmpDir);
209
-
210
- const {integrations} = await loadProjectContext(tmpDir, ['@acme/a']);
211
- expect(
212
- integrations.map(integration => [
213
- integration.name,
214
- integration.__providerConflict?.claimedBy ?? null,
215
- ]),
216
- ).toEqual([['@acme/a', null]]);
217
- const selected = await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0');
218
- expect(selected.map(entry => entry.version)).toEqual(['0.2.0']);
219
- });
220
-
221
- it('never reports a claimant that every other command uses as set aside', async () => {
222
- installWithCodemod('@acme/widgets', '1.0.0');
223
- installWithCodemod('@acme/renamed', '2.0.0', {providerId: '@acme/widgets'});
224
- configure(['@acme/widgets']);
225
- fs.writeFileSync(
226
- path.join(tmpDir, 'package.json'),
227
- JSON.stringify({
228
- name: '@acme/widgets',
229
- version: '3.0.0-dev',
230
- dependencies: {'@acme/renamed': '2.0.0'},
231
- }),
232
- );
233
- fs.writeFileSync(
234
- path.join(tmpDir, 'astryx.integration.mjs'),
235
- "export default {providerId: '@acme/widgets-next'};\n",
236
- );
237
-
238
- const {integrations} = await loadProjectContext(tmpDir);
239
- expect(
240
- integrations.map(integration => [
241
- integration.name,
242
- integration.version,
243
- integration.__providerConflict?.claimedBy ?? null,
244
- ]),
245
- ).toEqual([['@acme/widgets', '1.0.0', null]]);
246
- });
247
-
248
- it("sets aside an --integration extra that claims the authored package's ID", async () => {
249
- installWithCodemod('@acme/widgets', '1.0.0');
250
- configure([]);
251
- fs.writeFileSync(
252
- path.join(tmpDir, 'package.json'),
253
- JSON.stringify({name: '@acme/renamed', version: '2.0.0-dev'}),
254
- );
255
- fs.writeFileSync(
256
- path.join(tmpDir, 'astryx.integration.mjs'),
257
- "export default {providerId: '@acme/widgets'};\n",
258
- );
259
- process.chdir(tmpDir);
260
-
261
- const {integrations} = await loadProjectContext(tmpDir, ['@acme/widgets']);
262
- expect(
263
- integrations.map(integration => [
264
- integration.name,
265
- integration.__providerConflict?.claimedBy ?? null,
266
- ]),
267
- ).toEqual([['@acme/widgets', '@acme/renamed']]);
268
- expect(
269
- await selectIntegrationCodemodsFor(integrations, '0.1.0', '0.3.0'),
270
- ).toEqual([]);
271
- });
272
- });
@@ -1,14 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file `astryx docs authoring`: every authoring schema, one section each.
5
- *
6
- * Built from the self-docs colocated under packages/cli/authoring, so it cannot
7
- * drift from the schemas it describes. `astryx doctor` names a self-doc this
8
- * topic cannot reach.
9
- */
10
-
11
- import {buildAuthoringTopic} from '../../foundation/discovery/authoring-self-docs.mjs';
12
-
13
- /** @type {import('@astryxdesign/cli/authoring').ReferenceDoc} */
14
- export const docs = await buildAuthoringTopic();