@astryxdesign/cli 0.7.2 → 0.7.3-canary.06872b4
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 +99 -66
- package/api/build/_adapter.d.mts +58 -0
- package/api/build/_adapter.mjs +115 -3
- package/api/build/blocks/blocks.d.mts +42 -0
- package/api/build/blocks/blocks.mjs +169 -0
- package/api/build/blocks/blocks.test.mjs +108 -0
- package/api/build/blocks/blocks.weights.json +1 -0
- package/api/build/build.mjs +25 -6
- package/api/build/kit/answer.d.mts +14 -0
- package/api/build/kit/answer.mjs +85 -0
- package/api/build/kit/answer.test.mjs +38 -0
- package/api/build/kit/kind.d.mts +25 -0
- package/api/build/kit/kind.mjs +170 -0
- package/api/build/kit/kit.d.mts +2 -4
- package/api/build/kit/kit.mjs +8 -398
- package/api/build/kit/rank.d.mts +3 -32
- package/api/build/kit/rank.mjs +25 -342
- package/api/build/kit/rank.test.mjs +2 -1
- package/api/build/kit/signals.d.mts +60 -0
- package/api/build/kit/signals.mjs +284 -0
- package/api/build/kit/start.d.mts +32 -0
- package/api/build/kit/start.mjs +163 -0
- package/api/build/kit/words.d.mts +72 -0
- package/api/build/kit/words.mjs +202 -0
- package/api/build/tree.d.mts +20 -0
- package/api/build/tree.mjs +52 -0
- package/api/build/tree.test.mjs +177 -0
- package/api/build/tree.weights.json +1 -0
- package/api/component/component.mjs +16 -2
- package/api/component/component.test.mjs +15 -0
- package/api/discover/_adapter.mjs +36 -9
- package/api/discover/_adapter.test.mjs +42 -0
- package/api/docs/_adapter.mjs +17 -5
- package/api/docs/docs.test.mjs +7 -1
- package/api/doctor/doctor.mjs +86 -12
- package/api/doctor/doctor.test.mjs +28 -3
- package/api/init/init.doc.mjs +20 -6
- package/api/init/init.test.mjs +18 -2
- package/api/init/init.type.d.mts +3 -3
- package/api/init/init.type.mjs +3 -3
- package/api/init/remove/remove.mjs +17 -4
- package/api/init/remove/remove.test.mjs +114 -2
- package/api/init/run/run.mjs +69 -6
- package/api/integration/authoring-checks.mjs +83 -9
- package/api/integration/pack-check.mjs +123 -4
- package/api/integration/pack-check.test.mjs +87 -0
- package/api/integration/validate-integration-case-disk.test.mjs +111 -0
- package/api/integration/validate-integration-gaps.test.mjs +1964 -0
- package/api/integration/validate-integration.d.mts +11 -2
- package/api/integration/validate-integration.mjs +226 -32
- package/api/integration/validate-integration.type.d.mts +58 -1
- package/api/integration/validate-integration.type.mjs +45 -2
- package/api/integration/validateIntegration.doc.mjs +1 -1
- package/api/search/ORDERING.md +28 -0
- package/api/search/_adapter.d.mts +66 -2
- package/api/search/_adapter.mjs +118 -10
- package/api/search/_candidate-score.d.mts +40 -0
- package/api/search/_candidate-score.mjs +238 -0
- package/api/search/_cards.json +6098 -0
- package/api/search/_compound.d.mts +50 -0
- package/api/search/_compound.mjs +170 -0
- package/api/search/_doc-searcher.d.mts +4 -0
- package/api/search/_doc-searcher.mjs +23 -0
- package/api/search/_doc-searcher.test.mjs +36 -0
- package/api/search/_doc-searcher.weights.json +1 -0
- package/api/search/_doc-text.d.mts +30 -0
- package/api/search/_doc-text.mjs +87 -0
- package/api/search/_entries.d.mts +52 -0
- package/api/search/_entries.mjs +158 -0
- package/api/search/_features.d.mts +35 -0
- package/api/search/_features.mjs +155 -0
- package/api/search/_gather-components.d.mts +26 -0
- package/api/search/_gather-components.mjs +284 -0
- package/api/search/_gather-docs.d.mts +20 -0
- package/api/search/_gather-docs.mjs +254 -0
- package/api/search/_gather-hooks.d.mts +12 -0
- package/api/search/_gather-hooks.mjs +52 -0
- package/api/search/_gather-templates.d.mts +25 -0
- package/api/search/_gather-templates.mjs +107 -0
- package/api/search/_lexical.d.mts +135 -0
- package/api/search/_lexical.mjs +351 -0
- package/api/search/_main-searcher.d.mts +19 -0
- package/api/search/_main-searcher.mjs +115 -0
- package/api/search/_main-searcher.test.mjs +106 -0
- package/api/search/_main-searcher.weights.json +1 -0
- package/api/search/_module-doc.d.mts +32 -0
- package/api/search/_module-doc.mjs +78 -0
- package/api/search/_order.d.mts +32 -0
- package/api/search/_order.mjs +162 -0
- package/api/search/_order.test.mjs +72 -0
- package/api/search/_priority.d.mts +50 -0
- package/api/search/_priority.mjs +139 -0
- package/api/search/_query-words.d.mts +25 -0
- package/api/search/_query-words.mjs +92 -0
- package/api/search/_query.d.mts +65 -0
- package/api/search/_query.mjs +176 -0
- package/api/search/_result.d.mts +97 -0
- package/api/search/_result.mjs +150 -0
- package/api/search/_score.d.mts +60 -0
- package/api/search/_score.mjs +283 -0
- package/api/search/_synonyms.d.mts +21 -0
- package/api/search/_synonyms.mjs +67 -0
- package/api/search/_template-searcher.d.mts +4 -0
- package/api/search/_template-searcher.mjs +23 -0
- package/api/search/_template-searcher.test.mjs +40 -0
- package/api/search/_template-searcher.weights.json +1 -0
- package/api/search/_titles.d.mts +33 -0
- package/api/search/_titles.mjs +65 -0
- package/api/search/_words.d.mts +64 -0
- package/api/search/_words.mjs +157 -0
- package/api/search/search.d.mts +22 -305
- package/api/search/search.doc.mjs +7 -5
- package/api/search/search.mjs +53 -2483
- package/api/search/search.type.d.mts +6 -1
- package/api/search/search.type.mjs +6 -1
- package/api/search/tree.d.mts +15 -0
- package/api/search/tree.mjs +40 -0
- package/api/search/tree.test.mjs +66 -0
- package/api/search/tree.weights.json +1 -0
- package/api/theme/build/build.packed-old-core.test.mjs +1 -0
- package/api/upgrade/_adapter.d.mts +57 -9
- package/api/upgrade/_adapter.mjs +198 -28
- package/api/upgrade/registry/registry.d.mts +10 -4
- package/api/upgrade/registry/registry.mjs +33 -16
- package/api/upgrade/registry/registry.test.mjs +85 -0
- package/api/upgrade/run/run.d.mts +4 -2
- package/api/upgrade/run/run.mjs +13 -2
- package/api/upgrade/run/run.test.mjs +417 -3
- package/api/upgrade/upgrade.doc.mjs +10 -5
- package/api/upgrade/upgrade.mjs +13 -2
- package/api/upgrade/upgrade.test.mjs +194 -0
- package/api/upgrade/upgrade.type.d.mts +5 -3
- package/api/upgrade/upgrade.type.mjs +8 -6
- package/assets/codemods/transforms/v0.7.0/__tests__/validate-data-token-ownership.test.mjs +11 -0
- package/assets/codemods/transforms/v0.7.0/validate-data-token-ownership.mjs +3 -3
- package/assets/docs/is-my-code-good.doc.mjs +287 -0
- package/assets/docs/tree/api.doc.mjs +6 -0
- package/assets/docs/tree/host-entry.doc.mjs +128 -0
- package/assets/docs/tree/template-grading-rubric.doc.mjs +16 -37
- package/assets/docs/tree/tokens-data.doc.mjs +2 -2
- package/assets/docs/working-with-ai.doc.mjs +6 -2
- package/assets/templates/themes/butter/butterTheme.ts +4 -2
- package/assets/templates/themes/stone/stoneTheme.ts +4 -2
- package/assets/templates/themes/y2k/y2kTheme.ts +4 -2
- package/authoring/debug/parse.d.mts +1 -1
- package/clients/cli/bin/astryx.mjs +7 -78
- package/clients/cli/commands/doctor.mjs +30 -0
- package/clients/cli/commands/doctor.test.mjs +65 -0
- package/clients/cli/commands/init.behavior.test.mjs +230 -1
- package/clients/cli/commands/init.doc.mjs +28 -9
- package/clients/cli/commands/init.flag-help.test.mjs +1 -0
- package/clients/cli/commands/init.mjs +2 -2
- package/clients/cli/commands/outside-project.test.mjs +2 -1
- package/clients/cli/commands/setup-nudge.test.mjs +61 -0
- package/clients/cli/commands/upgrade.doc.mjs +4 -2
- package/clients/cli/commands/upgrade.mjs +9 -2
- package/clients/cli/commands/upgrade.subfolder-path.test.mjs +97 -0
- package/clients/cli/index.mjs +19 -1
- package/clients/cli/run.mjs +108 -0
- package/foundation/agent-docs/agent-doc-state.d.mts +20 -7
- package/foundation/agent-docs/agent-doc-state.mjs +35 -8
- package/foundation/agent-docs/agent-docs.d.mts +100 -12
- package/foundation/agent-docs/agent-docs.mjs +1010 -99
- package/foundation/agent-docs/agent-docs.path-safety.test.mjs +1239 -17
- package/foundation/agent-docs/agent-docs.test.mjs +678 -35
- package/foundation/config/project.mjs +20 -22
- package/foundation/config/project.test.mjs +56 -0
- package/foundation/discovery/component-discovery.d.mts +37 -0
- package/foundation/discovery/component-discovery.mjs +80 -5
- package/foundation/discovery/component-loader.d.mts +1 -1
- package/foundation/discovery/docs-discovery.mjs +14 -1
- package/foundation/discovery/module-exports.d.mts +41 -0
- package/foundation/discovery/module-exports.mjs +253 -0
- package/foundation/discovery/template-adapter.mjs +18 -1
- package/foundation/discovery/template-needs.mjs +1 -44
- package/foundation/discovery/theme-discovery.mjs +147 -3
- package/foundation/doc-compiler/doc-loads.test.mjs +8 -0
- package/foundation/doc-compiler/read.mjs +59 -1
- package/foundation/doc-compiler/read.test.mjs +11 -2
- package/foundation/fs/paths.d.mts +70 -8
- package/foundation/fs/paths.mjs +556 -38
- package/foundation/fs/paths.test.mjs +430 -54
- package/foundation/integrations/autolink.d.mts +2 -1
- package/foundation/integrations/autolink.mjs +4 -13
- package/foundation/integrations/computer-integrations.d.mts +6 -3
- package/foundation/integrations/computer-integrations.mjs +38 -9
- package/foundation/integrations/contribution-inventory.d.mts +15 -20
- package/foundation/integrations/contribution-inventory.mjs +41 -5
- package/foundation/integrations/integrations.d.mts +27 -1
- package/foundation/integrations/integrations.mjs +61 -2
- package/foundation/integrations/validate-contributions.d.mts +115 -0
- package/foundation/integrations/validate-contributions.mjs +1168 -13
- package/foundation/release/handoff.d.mts +23 -4
- package/foundation/release/handoff.mjs +175 -8
- package/foundation/release/run-context.mjs +14 -0
- package/foundation/response/response-types.doc.mjs +1 -1
- package/foundation/route/route.d.mts +285 -0
- package/foundation/route/route.mjs +324 -0
- package/foundation/route/route.test.mjs +153 -0
- package/foundation/runtime/hosted-runtime.test.mjs +403 -0
- package/foundation/runtime/locked-versions.d.mts +32 -0
- package/foundation/runtime/locked-versions.mjs +65 -0
- package/foundation/runtime/package-root.d.mts +91 -0
- package/foundation/runtime/package-root.mjs +174 -0
- package/foundation/runtime/package-set.d.mts +62 -0
- package/foundation/runtime/package-set.mjs +130 -0
- package/foundation/runtime/package-set.test.mjs +432 -0
- package/host/door-conformance.test.mjs +274 -0
- package/host/index.d.ts +116 -0
- package/host/index.mjs +295 -0
- package/host/index.test.mjs +302 -0
- package/package.json +14 -9
|
@@ -225,12 +225,19 @@ export function peerProblem(pkg, release) {
|
|
|
225
225
|
|
|
226
226
|
/**
|
|
227
227
|
* The computer-level integrations installed beside the CLI at `cliRoot`, in
|
|
228
|
-
* name order (declaration order when the root declares them)
|
|
228
|
+
* name order (declaration order when the root declares them), then each
|
|
229
|
+
* integration a host approves (`approved`, architecture:cli-surface INV30),
|
|
230
|
+
* resolved by name from the package set that holds that CLI alone. Reads
|
|
229
231
|
* package.json files only.
|
|
230
|
-
* @param {{cliRoot: string, release: string, cacheDir?: string}} options
|
|
232
|
+
* @param {{cliRoot: string, release: string, cacheDir?: string, approved?: readonly string[]}} options
|
|
231
233
|
* @returns {ComputerIntegrationCandidate[]}
|
|
232
234
|
*/
|
|
233
|
-
export function scanComputerIntegrations({
|
|
235
|
+
export function scanComputerIntegrations({
|
|
236
|
+
cliRoot,
|
|
237
|
+
release,
|
|
238
|
+
cacheDir,
|
|
239
|
+
approved = [],
|
|
240
|
+
}) {
|
|
234
241
|
const self = real(cliRoot);
|
|
235
242
|
/** @type {ComputerIntegrationCandidate[]} */
|
|
236
243
|
const found = [];
|
|
@@ -238,21 +245,43 @@ export function scanComputerIntegrations({cliRoot, release, cacheDir}) {
|
|
|
238
245
|
for (const root of computerInstallRoots(cliRoot, {cacheDir})) {
|
|
239
246
|
scanRoot(root, {self, release, found, seen});
|
|
240
247
|
}
|
|
248
|
+
const owner = approved.length > 0 ? installPlaceOf(self).owner : null;
|
|
249
|
+
if (owner) scanRoot(owner, {self, release, found, seen}, approved);
|
|
241
250
|
return found;
|
|
242
251
|
}
|
|
243
252
|
|
|
244
253
|
/**
|
|
245
|
-
*
|
|
254
|
+
* `name` as installed in `root`'s own `node_modules`, never in a folder above.
|
|
255
|
+
* @param {string} name
|
|
256
|
+
* @param {string} root
|
|
257
|
+
* @returns {{packageDir: string, hostDir: string} | null}
|
|
258
|
+
*/
|
|
259
|
+
function ownPackageDir(name, root) {
|
|
260
|
+
const packageDir = path.join(root, 'node_modules', ...name.split('/'));
|
|
261
|
+
return fs.existsSync(path.join(packageDir, 'package.json'))
|
|
262
|
+
? {packageDir, hostDir: root}
|
|
263
|
+
: null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Add the integrations installed in one install root: those it declares or
|
|
268
|
+
* installs, or, given `approved`, those names installed in its own
|
|
269
|
+
* `node_modules`.
|
|
246
270
|
* @param {string} root
|
|
247
271
|
* @param {{self: string, release: string, found: ComputerIntegrationCandidate[], seen: Set<string>}} into
|
|
272
|
+
* @param {readonly string[] | null} [approved]
|
|
248
273
|
*/
|
|
249
|
-
function scanRoot(root, {self, release, found, seen}) {
|
|
250
|
-
const declared =
|
|
251
|
-
|
|
252
|
-
|
|
274
|
+
function scanRoot(root, {self, release, found, seen}, approved = null) {
|
|
275
|
+
const declared =
|
|
276
|
+
approved ??
|
|
277
|
+
(readPackage(root)
|
|
278
|
+
? readDeclaredDependencies(root).map(d => d.name)
|
|
279
|
+
: installedNames(root));
|
|
253
280
|
for (const name of declared) {
|
|
254
281
|
if (NOT_INTEGRATIONS.has(name)) continue;
|
|
255
|
-
const resolved =
|
|
282
|
+
const resolved = approved
|
|
283
|
+
? ownPackageDir(name, root)
|
|
284
|
+
: resolveInstalledPackageDir(name, root);
|
|
256
285
|
if (!resolved) continue;
|
|
257
286
|
const identity = real(resolved.packageDir);
|
|
258
287
|
if (identity === self || seen.has(identity)) continue;
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
// @generated by scripts/sync-api-types.mjs from the JSDoc in foundation/**/*.mjs.
|
|
2
2
|
// DO NOT EDIT — run `pnpm sync:api-types` to regenerate.
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* The contribution files readers read under each declared root that is a
|
|
6
|
+
* readable folder, package-relative, without importing anything. A folder
|
|
7
|
+
* inside a root that cannot be listed is skipped.
|
|
8
|
+
* @param {{components?: string, templates?: string, codemods?: string, docs?: string, themes?: string}} loaded
|
|
9
|
+
* @param {string} pkgDir
|
|
10
|
+
* @returns {string[]}
|
|
11
|
+
*/
|
|
12
|
+
export function contributionFiles(loaded: {
|
|
13
|
+
components?: string;
|
|
14
|
+
templates?: string;
|
|
15
|
+
codemods?: string;
|
|
16
|
+
docs?: string;
|
|
17
|
+
themes?: string;
|
|
18
|
+
}, pkgDir: string): string[];
|
|
4
19
|
/**
|
|
5
20
|
* @typedef {object} FileInventoryRoot
|
|
6
21
|
* @property {'themes'|'components'|'templates'|'codemods'|'docs'} kind
|
|
@@ -22,26 +37,6 @@
|
|
|
22
37
|
* @returns {FileInventory}
|
|
23
38
|
*/
|
|
24
39
|
export function computeRequiredFiles(loaded: import("./integrations.mjs").LoadedIntegration): FileInventory;
|
|
25
|
-
/**
|
|
26
|
-
* @typedef {object} ContributionIdentities
|
|
27
|
-
* @property {{slug: string, exportName: string}[]} themes
|
|
28
|
-
* @property {string[]} components
|
|
29
|
-
* @property {{id: string, type: string, name: string, replaces?: string}[]} templates
|
|
30
|
-
* @property {{version: string, id: string}[]} codemods
|
|
31
|
-
* @property {string[]} docs
|
|
32
|
-
* @property {string[]} agentDocsAppend
|
|
33
|
-
*/
|
|
34
|
-
/**
|
|
35
|
-
* The resolved fields needed to discover contribution identities.
|
|
36
|
-
* @typedef {object} IdentitySource
|
|
37
|
-
* @property {string} name
|
|
38
|
-
* @property {string} [themes]
|
|
39
|
-
* @property {string} [components]
|
|
40
|
-
* @property {string} [templates]
|
|
41
|
-
* @property {string} [codemods]
|
|
42
|
-
* @property {string} [docs]
|
|
43
|
-
* @property {{append?: readonly string[]}} [agentDocs]
|
|
44
|
-
*/
|
|
45
40
|
/**
|
|
46
41
|
* Run the same discovery functions a consumer uses to collect every
|
|
47
42
|
* contribution identity from a loaded integration.
|
|
@@ -137,6 +137,29 @@ const ROOT_KINDS = /** @type {const} */ ([
|
|
|
137
137
|
'docs',
|
|
138
138
|
]);
|
|
139
139
|
|
|
140
|
+
/**
|
|
141
|
+
* The contribution files readers read under each declared root that is a
|
|
142
|
+
* readable folder, package-relative, without importing anything. A folder
|
|
143
|
+
* inside a root that cannot be listed is skipped.
|
|
144
|
+
* @param {{components?: string, templates?: string, codemods?: string, docs?: string, themes?: string}} loaded
|
|
145
|
+
* @param {string} pkgDir
|
|
146
|
+
* @returns {string[]}
|
|
147
|
+
*/
|
|
148
|
+
export function contributionFiles(loaded, pkgDir) {
|
|
149
|
+
/** @type {Set<string>} */
|
|
150
|
+
const files = new Set();
|
|
151
|
+
for (const kind of ROOT_KINDS) {
|
|
152
|
+
const root = loaded[kind];
|
|
153
|
+
if (!root || !isFolder(root)) continue;
|
|
154
|
+
try {
|
|
155
|
+
for (const file of ENUMERATORS[kind](root, pkgDir)) files.add(file);
|
|
156
|
+
} catch {
|
|
157
|
+
// An unreadable folder inside the root.
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return [...files].sort();
|
|
161
|
+
}
|
|
162
|
+
|
|
140
163
|
// ── Public: static file inventory ────────────────────────────────
|
|
141
164
|
|
|
142
165
|
/**
|
|
@@ -207,6 +230,19 @@ export function computeRequiredFiles(loaded) {
|
|
|
207
230
|
* @property {{append?: readonly string[]}} [agentDocs]
|
|
208
231
|
*/
|
|
209
232
|
|
|
233
|
+
/**
|
|
234
|
+
* Whether `dir` is a folder to list. A declared root that is a file is
|
|
235
|
+
* reported by the root check; discovery finds nothing in it.
|
|
236
|
+
* @param {string} dir
|
|
237
|
+
*/
|
|
238
|
+
function isFolder(dir) {
|
|
239
|
+
try {
|
|
240
|
+
return fs.statSync(dir).isDirectory();
|
|
241
|
+
} catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
210
246
|
/**
|
|
211
247
|
* Run the same discovery functions a consumer uses to collect every
|
|
212
248
|
* contribution identity from a loaded integration.
|
|
@@ -229,7 +265,7 @@ export async function collectIdentities(loaded) {
|
|
|
229
265
|
/** @type {Array<{kind: string, message: string}>} */
|
|
230
266
|
const errors = [];
|
|
231
267
|
|
|
232
|
-
if (loaded.themes &&
|
|
268
|
+
if (loaded.themes && isFolder(loaded.themes)) {
|
|
233
269
|
try {
|
|
234
270
|
const themes = await discoverIntegrationThemes(
|
|
235
271
|
/** @type {import('./integrations.mjs').LoadedIntegration} */ (loaded),
|
|
@@ -245,7 +281,7 @@ export async function collectIdentities(loaded) {
|
|
|
245
281
|
}
|
|
246
282
|
}
|
|
247
283
|
|
|
248
|
-
if (loaded.components &&
|
|
284
|
+
if (loaded.components && isFolder(loaded.components)) {
|
|
249
285
|
try {
|
|
250
286
|
const records = discoverIntegrationComponents(loaded) ?? [];
|
|
251
287
|
// A family doc backs several records: load it, and report it, once.
|
|
@@ -275,7 +311,7 @@ export async function collectIdentities(loaded) {
|
|
|
275
311
|
}
|
|
276
312
|
}
|
|
277
313
|
|
|
278
|
-
if (loaded.templates &&
|
|
314
|
+
if (loaded.templates && isFolder(loaded.templates)) {
|
|
279
315
|
try {
|
|
280
316
|
const {templates, errors: templateErrors} =
|
|
281
317
|
await discoverIntegrationTemplatesForOne(loaded);
|
|
@@ -298,7 +334,7 @@ export async function collectIdentities(loaded) {
|
|
|
298
334
|
}
|
|
299
335
|
}
|
|
300
336
|
|
|
301
|
-
if (loaded.codemods &&
|
|
337
|
+
if (loaded.codemods && isFolder(loaded.codemods)) {
|
|
302
338
|
try {
|
|
303
339
|
const byVersion = await discoverIntegrationCodemods([loaded]);
|
|
304
340
|
/** @type {{version: string, id: string}[]} */
|
|
@@ -317,7 +353,7 @@ export async function collectIdentities(loaded) {
|
|
|
317
353
|
}
|
|
318
354
|
}
|
|
319
355
|
|
|
320
|
-
if (loaded.docs &&
|
|
356
|
+
if (loaded.docs && isFolder(loaded.docs)) {
|
|
321
357
|
try {
|
|
322
358
|
const {
|
|
323
359
|
records,
|
|
@@ -45,13 +45,14 @@ export function findManifestPaths(dir: string): string[];
|
|
|
45
45
|
* @param {string} file absolute manifest path
|
|
46
46
|
* @param {string} [label] used in error messages
|
|
47
47
|
* @param {{fresh?: boolean}} [options]
|
|
48
|
-
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string, cliCommandError?: string}>}
|
|
48
|
+
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], declaredKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string, cliCommandError?: string}>}
|
|
49
49
|
*/
|
|
50
50
|
export function loadManifest(file: string, label?: string, { fresh }?: {
|
|
51
51
|
fresh?: boolean;
|
|
52
52
|
}): Promise<{
|
|
53
53
|
manifest: import("../../authoring/integration/type").AstryxIntegration;
|
|
54
54
|
unknownKeys: string[];
|
|
55
|
+
declaredKeys: string[];
|
|
55
56
|
debug?: import("../../authoring/debug/type").DebugEventHandler;
|
|
56
57
|
gapReport?: import("../../authoring/gap-report/type").GapReportHandler;
|
|
57
58
|
gapReportError?: string;
|
|
@@ -79,6 +80,17 @@ export function loadManifestObject(file: string, label?: string, options?: {
|
|
|
79
80
|
* @param {string} [cwd]
|
|
80
81
|
*/
|
|
81
82
|
export function resolvePackageDir(packageName: string, cwd?: string): string;
|
|
83
|
+
/**
|
|
84
|
+
* Where an integration named in astryx.config is installed: the nearest
|
|
85
|
+
* `node_modules/<name>` at or above `cwd`, found the way an autolinked
|
|
86
|
+
* dependency is, so a package a workspace hoists to its root loads in every
|
|
87
|
+
* member. When it is installed nowhere, `cwd`'s own `node_modules/<name>`,
|
|
88
|
+
* which the caller reports as not installed.
|
|
89
|
+
* @param {string} packageName
|
|
90
|
+
* @param {string} [cwd]
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
93
|
+
export function resolveInstalledIntegrationDir(packageName: string, cwd?: string): string;
|
|
82
94
|
/**
|
|
83
95
|
* Load the integration package rooted at `packageDir` directly, without first
|
|
84
96
|
* installing or publishing it. This is the self-resolution seam: an author in
|
|
@@ -134,6 +146,8 @@ export function loadIntegrations(specs?: string[], { cwd, fresh, resolveProvider
|
|
|
134
146
|
* @property {string} [__agentDocsError] contribution-specific validation
|
|
135
147
|
* failure; other manifest contributions remain available
|
|
136
148
|
* @property {string} __spec
|
|
149
|
+
* @property {string} [__declaredProviderId] the manifest's `providerId` as
|
|
150
|
+
* written, kept by validation so it can tell whether the package has one
|
|
137
151
|
* @property {string} __packageDir
|
|
138
152
|
* @property {Record<string, unknown>|null} [__packageExports] the owning
|
|
139
153
|
* package's `exports` map, kept from the package.json this loader already
|
|
@@ -145,6 +159,8 @@ export function loadIntegrations(specs?: string[], { cwd, fresh, resolveProvider
|
|
|
145
159
|
* set on a package whose provider ID an earlier-loaded package already
|
|
146
160
|
* claims; it contributes nothing and is reported as a `duplicate_provider`
|
|
147
161
|
* warning
|
|
162
|
+
* @property {string[]} [__declaredKeys] the keys the manifest object itself
|
|
163
|
+
* declares, before any is filled in (providerId from the package name)
|
|
148
164
|
* @property {string[]} [__unknownKeys] manifest keys this CLI does not know —
|
|
149
165
|
* surfaced as a warning; the rest of the manifest still contributes
|
|
150
166
|
* @property {boolean} [__autolinked] loaded because the project declares the
|
|
@@ -210,6 +226,11 @@ export type LoadedIntegration = {
|
|
|
210
226
|
*/
|
|
211
227
|
__agentDocsError?: string | undefined;
|
|
212
228
|
__spec: string;
|
|
229
|
+
/**
|
|
230
|
+
* the manifest's `providerId` as
|
|
231
|
+
* written, kept by validation so it can tell whether the package has one
|
|
232
|
+
*/
|
|
233
|
+
__declaredProviderId?: string | undefined;
|
|
213
234
|
__packageDir: string;
|
|
214
235
|
/**
|
|
215
236
|
* the owning
|
|
@@ -233,6 +254,11 @@ export type LoadedIntegration = {
|
|
|
233
254
|
claimedBy: string;
|
|
234
255
|
message: string;
|
|
235
256
|
} | undefined;
|
|
257
|
+
/**
|
|
258
|
+
* the keys the manifest object itself
|
|
259
|
+
* declares, before any is filled in (providerId from the package name)
|
|
260
|
+
*/
|
|
261
|
+
__declaredKeys?: string[] | undefined;
|
|
236
262
|
/**
|
|
237
263
|
* manifest keys this CLI does not know —
|
|
238
264
|
* surfaced as a warning; the rest of the manifest still contributes
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
import * as fs from 'node:fs';
|
|
20
20
|
import * as path from 'node:path';
|
|
21
21
|
import {assertWithin} from '../fs/path-safety.mjs';
|
|
22
|
+
import {findNodeModulesPackage} from '../fs/paths.mjs';
|
|
22
23
|
import {normalizeProviderId} from '../identity/provider-identity.mjs';
|
|
23
24
|
// The key census and contribution parsers are internal to the schema module on
|
|
24
25
|
// purpose: the public parser still validates the complete authored type, while
|
|
@@ -60,6 +61,8 @@ import {resolveProviders} from './provider-resolution.mjs';
|
|
|
60
61
|
* @property {string} [__agentDocsError] contribution-specific validation
|
|
61
62
|
* failure; other manifest contributions remain available
|
|
62
63
|
* @property {string} __spec
|
|
64
|
+
* @property {string} [__declaredProviderId] the manifest's `providerId` as
|
|
65
|
+
* written, kept by validation so it can tell whether the package has one
|
|
63
66
|
* @property {string} __packageDir
|
|
64
67
|
* @property {Record<string, unknown>|null} [__packageExports] the owning
|
|
65
68
|
* package's `exports` map, kept from the package.json this loader already
|
|
@@ -71,6 +74,8 @@ import {resolveProviders} from './provider-resolution.mjs';
|
|
|
71
74
|
* set on a package whose provider ID an earlier-loaded package already
|
|
72
75
|
* claims; it contributes nothing and is reported as a `duplicate_provider`
|
|
73
76
|
* warning
|
|
77
|
+
* @property {string[]} [__declaredKeys] the keys the manifest object itself
|
|
78
|
+
* declares, before any is filled in (providerId from the package name)
|
|
74
79
|
* @property {string[]} [__unknownKeys] manifest keys this CLI does not know —
|
|
75
80
|
* surfaced as a warning; the rest of the manifest still contributes
|
|
76
81
|
* @property {boolean} [__autolinked] loaded because the project declares the
|
|
@@ -213,7 +218,7 @@ function parseDiscoverSourceExport(value, label) {
|
|
|
213
218
|
* @param {string} file absolute manifest path
|
|
214
219
|
* @param {string} [label] used in error messages
|
|
215
220
|
* @param {{fresh?: boolean}} [options]
|
|
216
|
-
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string, cliCommandError?: string}>}
|
|
221
|
+
* @returns {Promise<{manifest: import('../../authoring/integration/type').AstryxIntegration, unknownKeys: string[], declaredKeys: string[], debug?: import('../../authoring/debug/type').DebugEventHandler, gapReport?: import('../../authoring/gap-report/type').GapReportHandler, gapReportError?: string, discover?: import('../../authoring/discover/type').DiscoverSource, discoverError?: string, agentDocsError?: string, cliCommandError?: string}>}
|
|
217
222
|
*/
|
|
218
223
|
export async function loadManifest(
|
|
219
224
|
file,
|
|
@@ -222,6 +227,7 @@ export async function loadManifest(
|
|
|
222
227
|
) {
|
|
223
228
|
const mod = await importUserModule(file, {fresh});
|
|
224
229
|
const raw = mod?.default;
|
|
230
|
+
if (raw === undefined) throw new Error(noDefaultExportMessage(file, label, mod));
|
|
225
231
|
const baseManifest = parseIntegrationBase(raw, label);
|
|
226
232
|
const gapReport = parseGapReportHandlerExport(mod?.gapReport, label);
|
|
227
233
|
const discover = parseDiscoverSourceExport(mod?.discover, label);
|
|
@@ -274,6 +280,8 @@ export async function loadManifest(
|
|
|
274
280
|
...(cliCommand == null ? {} : {cliCommand}),
|
|
275
281
|
},
|
|
276
282
|
unknownKeys: unknownIntegrationKeys(raw),
|
|
283
|
+
declaredKeys:
|
|
284
|
+
raw != null && typeof raw === 'object' ? Object.keys(raw) : [],
|
|
277
285
|
debug:
|
|
278
286
|
typeof mod?.debug === 'function'
|
|
279
287
|
? /** @type {import('../../authoring/debug/type').DebugEventHandler} */ (
|
|
@@ -289,6 +297,30 @@ export async function loadManifest(
|
|
|
289
297
|
};
|
|
290
298
|
}
|
|
291
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Why a manifest has no default export, said plainly instead of as a schema
|
|
302
|
+
* failure on `undefined`: the file is empty, or it exports other names.
|
|
303
|
+
* @param {string} file
|
|
304
|
+
* @param {string} label
|
|
305
|
+
* @param {Record<string, unknown> | undefined} mod
|
|
306
|
+
*/
|
|
307
|
+
function noDefaultExportMessage(file, label, mod) {
|
|
308
|
+
const fix = `Fix: export the manifest object as the default export: \`export default {components: './components'}\`, naming the roots the package has.`;
|
|
309
|
+
let text = '';
|
|
310
|
+
try {
|
|
311
|
+
text = fs.readFileSync(file, 'utf8');
|
|
312
|
+
} catch {
|
|
313
|
+
// Unreadable now: say only what is missing.
|
|
314
|
+
}
|
|
315
|
+
const names = Object.keys(mod ?? {}).filter(name => name !== 'default');
|
|
316
|
+
if (text.trim() === '') return `${label} is empty. ${fix}`;
|
|
317
|
+
const found =
|
|
318
|
+
names.length > 0
|
|
319
|
+
? ` (it exports ${names.map(name => `\`${name}\``).join(', ')})`
|
|
320
|
+
: '';
|
|
321
|
+
return `${label} has no default export${found}. ${fix}`;
|
|
322
|
+
}
|
|
323
|
+
|
|
292
324
|
/**
|
|
293
325
|
* Load and validate a manifest module's default export against the integration
|
|
294
326
|
* schema. Throws if the default export is missing or invalid. Exposed for
|
|
@@ -337,6 +369,25 @@ export function resolvePackageDir(packageName, cwd = process.cwd()) {
|
|
|
337
369
|
return dir;
|
|
338
370
|
}
|
|
339
371
|
|
|
372
|
+
/**
|
|
373
|
+
* Where an integration named in astryx.config is installed: the nearest
|
|
374
|
+
* `node_modules/<name>` at or above `cwd`, found the way an autolinked
|
|
375
|
+
* dependency is, so a package a workspace hoists to its root loads in every
|
|
376
|
+
* member. When it is installed nowhere, `cwd`'s own `node_modules/<name>`,
|
|
377
|
+
* which the caller reports as not installed.
|
|
378
|
+
* @param {string} packageName
|
|
379
|
+
* @param {string} [cwd]
|
|
380
|
+
* @returns {string}
|
|
381
|
+
*/
|
|
382
|
+
export function resolveInstalledIntegrationDir(
|
|
383
|
+
packageName,
|
|
384
|
+
cwd = process.cwd(),
|
|
385
|
+
) {
|
|
386
|
+
// Validates the name first: it throws on a spec with path segments.
|
|
387
|
+
const ownDir = resolvePackageDir(packageName, cwd);
|
|
388
|
+
return findNodeModulesPackage(cwd, packageName)?.packageDir ?? ownDir;
|
|
389
|
+
}
|
|
390
|
+
|
|
340
391
|
/**
|
|
341
392
|
* Find the single conventional root manifest sibling of the package's
|
|
342
393
|
* package.json. Multiple present is a hard error; missing is a hard error.
|
|
@@ -396,6 +447,8 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
396
447
|
let manifest;
|
|
397
448
|
/** @type {string[]} */
|
|
398
449
|
let unknownKeys;
|
|
450
|
+
/** @type {string[]} */
|
|
451
|
+
let declaredKeys;
|
|
399
452
|
/** @type {import('../../authoring/debug/type').DebugEventHandler | undefined} */
|
|
400
453
|
let debugHandler;
|
|
401
454
|
/** @type {import('../../authoring/gap-report/type').GapReportHandler | undefined} */
|
|
@@ -414,6 +467,7 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
414
467
|
({
|
|
415
468
|
manifest,
|
|
416
469
|
unknownKeys,
|
|
470
|
+
declaredKeys,
|
|
417
471
|
debug: debugHandler,
|
|
418
472
|
gapReport: gapReportHandler,
|
|
419
473
|
gapReportError,
|
|
@@ -462,6 +516,7 @@ export async function loadLocalIntegration(packageDir, {fresh = false} = {}) {
|
|
|
462
516
|
__cliCommandError: cliCommandError,
|
|
463
517
|
__agentDocsError: agentDocsError,
|
|
464
518
|
__unknownKeys: unknownKeys,
|
|
519
|
+
__declaredKeys: declaredKeys,
|
|
465
520
|
__debug: debugHandler,
|
|
466
521
|
__gapReport: gapReportHandler,
|
|
467
522
|
__gapReportError: gapReportError,
|
|
@@ -496,7 +551,7 @@ export async function loadIntegrations(
|
|
|
496
551
|
if (!spec || seenSpecs.has(spec)) continue;
|
|
497
552
|
seenSpecs.add(spec);
|
|
498
553
|
|
|
499
|
-
const packageDir =
|
|
554
|
+
const packageDir = resolveInstalledIntegrationDir(spec, cwd);
|
|
500
555
|
const pkgPath = path.join(packageDir, 'package.json');
|
|
501
556
|
let pkg;
|
|
502
557
|
try {
|
|
@@ -512,6 +567,8 @@ export async function loadIntegrations(
|
|
|
512
567
|
let manifest;
|
|
513
568
|
/** @type {string[]} */
|
|
514
569
|
let unknownKeys;
|
|
570
|
+
/** @type {string[]} */
|
|
571
|
+
let declaredKeys;
|
|
515
572
|
/** @type {import('../../authoring/debug/type').DebugEventHandler | undefined} */
|
|
516
573
|
let debugHandler;
|
|
517
574
|
/** @type {import('../../authoring/gap-report/type').GapReportHandler | undefined} */
|
|
@@ -530,6 +587,7 @@ export async function loadIntegrations(
|
|
|
530
587
|
({
|
|
531
588
|
manifest,
|
|
532
589
|
unknownKeys,
|
|
590
|
+
declaredKeys,
|
|
533
591
|
debug: debugHandler,
|
|
534
592
|
gapReport: gapReportHandler,
|
|
535
593
|
gapReportError,
|
|
@@ -585,6 +643,7 @@ export async function loadIntegrations(
|
|
|
585
643
|
__cliCommandError: cliCommandError,
|
|
586
644
|
__agentDocsError: agentDocsError,
|
|
587
645
|
__unknownKeys: unknownKeys,
|
|
646
|
+
__declaredKeys: declaredKeys,
|
|
588
647
|
__debug: debugHandler,
|
|
589
648
|
__gapReport: gapReportHandler,
|
|
590
649
|
__gapReportError: gapReportError,
|
|
@@ -5,6 +5,29 @@
|
|
|
5
5
|
export function issueError(code: string, message: string): Issue;
|
|
6
6
|
/** @param {string} code @param {string} message @returns {Issue} */
|
|
7
7
|
export function issueWarning(code: string, message: string): Issue;
|
|
8
|
+
/**
|
|
9
|
+
* A layout finding added after the last minor release: validate lists it, in
|
|
10
|
+
* its `layout` report, but it is never an issue, so nothing counts it and
|
|
11
|
+
* `integration check --strict` does not fail on it. A new failing finding
|
|
12
|
+
* joins only in a minor release (architecture:cli-surface INV35).
|
|
13
|
+
* @param {string} code
|
|
14
|
+
* @param {string} message
|
|
15
|
+
* @returns {Issue}
|
|
16
|
+
*/
|
|
17
|
+
export function issueListed(code: string, message: string): Issue;
|
|
18
|
+
/**
|
|
19
|
+
* Whether `issueListed` made this issue.
|
|
20
|
+
* @param {Issue} issue
|
|
21
|
+
*/
|
|
22
|
+
export function isListedIssue(issue: Issue): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The known manifest key `key` is a near miss of: a different letter case, or
|
|
25
|
+
* at most two letters added, dropped or changed (`component`, `doc`,
|
|
26
|
+
* `tempaltes`). Null when no known key is that close, or two are.
|
|
27
|
+
* @param {string} key
|
|
28
|
+
* @returns {string | null}
|
|
29
|
+
*/
|
|
30
|
+
export function nearestKnownKey(key: string): string | null;
|
|
8
31
|
/**
|
|
9
32
|
* Why a declared root cannot be read as a folder, or null when it can.
|
|
10
33
|
* A missing root keeps its own issue; a root that is a file or that the
|
|
@@ -21,6 +44,79 @@ export function rootProblem(root: string): {
|
|
|
21
44
|
kind: "unreadable";
|
|
22
45
|
code: string;
|
|
23
46
|
} | null;
|
|
47
|
+
/**
|
|
48
|
+
* The first folder on the way from the package to `root` (the root itself
|
|
49
|
+
* included) that is a symlink, with where it points, or null.
|
|
50
|
+
* @param {string} root absolute
|
|
51
|
+
* @param {string} packageDir absolute
|
|
52
|
+
* @returns {{path: string, target: string} | null}
|
|
53
|
+
*/
|
|
54
|
+
export function symlinkedFolder(root: string, packageDir: string): {
|
|
55
|
+
path: string;
|
|
56
|
+
target: string;
|
|
57
|
+
} | null;
|
|
58
|
+
/**
|
|
59
|
+
* The block component names this check could not judge, shaped like the
|
|
60
|
+
* doc type report so `integration check` counts them as not compared: each
|
|
61
|
+
* name a template gives in `exampleFor` or `componentsUsed` that neither the
|
|
62
|
+
* package nor Core has, when the template reaches components through
|
|
63
|
+
* anything but named imports and re-exports from the package, Core, or
|
|
64
|
+
* helpers read in full (see importedNames), or when Core is not installed to
|
|
65
|
+
* look it up in; its findings are always empty. A name judged unknown is an
|
|
66
|
+
* `unknown_block_component` note, with its fix in the message: validate
|
|
67
|
+
* lists notes beside its issues, and nothing counts them, so `--strict` does
|
|
68
|
+
* not fail on it until the next minor release (architecture:cli-surface
|
|
69
|
+
* INV35).
|
|
70
|
+
* @param {LoadedIntegration} integration
|
|
71
|
+
* @returns {Promise<{report: {status: 'checked', findings: [], unchecked: Array<{file: string, name: string, reason: string}>}, notes: Note[]}>}
|
|
72
|
+
*/
|
|
73
|
+
export function blockComponentsCheck(integration: LoadedIntegration): Promise<{
|
|
74
|
+
report: {
|
|
75
|
+
status: "checked";
|
|
76
|
+
findings: [];
|
|
77
|
+
unchecked: Array<{
|
|
78
|
+
file: string;
|
|
79
|
+
name: string;
|
|
80
|
+
reason: string;
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
notes: Note[];
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* The component doc names the check could not judge, shaped like the doc type
|
|
87
|
+
* report so `integration check` counts them as not compared: each doc whose
|
|
88
|
+
* `name` differs from the name it is listed under and whose source's exports
|
|
89
|
+
* cannot all be read without running it; its findings are always empty. A
|
|
90
|
+
* name the module its printed import names provably lacks is a
|
|
91
|
+
* `doc_name_mismatch` note, with its fix in the message: validate lists
|
|
92
|
+
* notes beside its issues, and nothing counts them, so `--strict` does not
|
|
93
|
+
* fail on it until the next minor release (architecture:cli-surface INV35).
|
|
94
|
+
* @param {LoadedIntegration} integration
|
|
95
|
+
* @returns {Promise<{report: {status: 'checked', findings: [], unchecked: Array<{file: string, name: string, reason: string}>}, notes: Note[]}>}
|
|
96
|
+
*/
|
|
97
|
+
export function componentDocNamesCheck(integration: LoadedIntegration): Promise<{
|
|
98
|
+
report: {
|
|
99
|
+
status: "checked";
|
|
100
|
+
findings: [];
|
|
101
|
+
unchecked: Array<{
|
|
102
|
+
file: string;
|
|
103
|
+
name: string;
|
|
104
|
+
reason: string;
|
|
105
|
+
}>;
|
|
106
|
+
};
|
|
107
|
+
notes: Note[];
|
|
108
|
+
}>;
|
|
109
|
+
/**
|
|
110
|
+
* The `name` a theme source passes to defineTheme for its exported theme,
|
|
111
|
+
* when the file says it as a string literal: `export const oceanTheme =
|
|
112
|
+
* defineTheme({name: 'ocean', ...})`. Null whenever only running the module
|
|
113
|
+
* could tell (a variable, a factory, a spread after the name, `extends`
|
|
114
|
+
* alone), so nothing is judged that a build would decide.
|
|
115
|
+
* @param {string} file
|
|
116
|
+
* @param {string} exportName
|
|
117
|
+
* @returns {string | null}
|
|
118
|
+
*/
|
|
119
|
+
export function literalThemeName(file: string, exportName: string): string | null;
|
|
24
120
|
/**
|
|
25
121
|
* Validate an already-LOADED integration (as produced by `loadIntegrations` —
|
|
26
122
|
* absolute contribution roots plus identity) and return its issues. This is the
|
|
@@ -32,6 +128,17 @@ export function rootProblem(root: string): {
|
|
|
32
128
|
* @returns {Promise<Issue[]>}
|
|
33
129
|
*/
|
|
34
130
|
export function validateLoadedIntegration(loaded: LoadedIntegration): Promise<Issue[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Every contribution check, split: `issues` as validateLoadedIntegration
|
|
133
|
+
* returns them, and `listed`, the layout findings validate lists in its
|
|
134
|
+
* `layout` report without counting them.
|
|
135
|
+
* @param {LoadedIntegration} loaded
|
|
136
|
+
* @returns {Promise<{issues: Issue[], listed: Issue[]}>}
|
|
137
|
+
*/
|
|
138
|
+
export function validateLoadedIntegrationListed(loaded: LoadedIntegration): Promise<{
|
|
139
|
+
issues: Issue[];
|
|
140
|
+
listed: Issue[];
|
|
141
|
+
}>;
|
|
35
142
|
/**
|
|
36
143
|
* @typedef {import('./issue').AstryxIntegrationIssue} Issue
|
|
37
144
|
* @typedef {import('./integrations.mjs').LoadedIntegration} LoadedIntegration
|
|
@@ -42,5 +149,13 @@ export const INVALID_AGENT_DOCS: "invalid_agent_docs";
|
|
|
42
149
|
export const INVALID_CLI_COMMAND: "invalid_cli_command";
|
|
43
150
|
/** Stable issue code for a package whose provider ID is already claimed. */
|
|
44
151
|
export const DUPLICATE_PROVIDER: "duplicate_provider";
|
|
152
|
+
/**
|
|
153
|
+
* A note: information beside validate's issues that fails nothing, with the
|
|
154
|
+
* fix in its message.
|
|
155
|
+
*/
|
|
156
|
+
export type Note = {
|
|
157
|
+
code: string;
|
|
158
|
+
message: string;
|
|
159
|
+
};
|
|
45
160
|
export type Issue = import("./issue").AstryxIntegrationIssue;
|
|
46
161
|
export type LoadedIntegration = import("./integrations.mjs").LoadedIntegration;
|