@astryxdesign/cli 0.6.4-canary.f0355e3 → 0.6.4
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 +96 -99
- package/api/build/build.doc.mjs +1 -6
- package/api/build/build.test.mjs +0 -22
- package/api/build/kit/kit.mjs +5 -44
- package/api/component/_adapter.d.mts +0 -25
- package/api/component/_adapter.mjs +5 -59
- package/api/component/component.d.mts +3 -6
- package/api/component/component.doc.mjs +17 -37
- package/api/component/component.mjs +9 -249
- package/api/component/component.type.d.mts +0 -25
- package/api/component/component.type.mjs +0 -44
- package/api/discover/_adapter.d.mts +6 -114
- package/api/discover/_adapter.mjs +17 -372
- package/api/discover/detail/detail.d.mts +6 -18
- package/api/discover/detail/detail.mjs +13 -67
- package/api/discover/detail/detail.test.mjs +0 -85
- package/api/discover/discover.d.mts +9 -3
- package/api/discover/discover.doc.mjs +18 -61
- package/api/discover/discover.mjs +36 -220
- package/api/discover/discover.test.mjs +2 -11
- package/api/discover/discover.type.d.mts +8 -147
- package/api/discover/discover.type.mjs +12 -102
- package/api/discover/list/list.d.mts +6 -20
- package/api/discover/list/list.mjs +12 -45
- package/api/discover/list/list.test.mjs +0 -46
- package/api/discover/search/search.d.mts +16 -18
- package/api/discover/search/search.mjs +56 -102
- package/api/discover/search/search.test.mjs +10 -144
- package/api/docs/_adapter.d.mts +3 -8
- package/api/docs/_adapter.mjs +6 -14
- package/api/docs/docOverlays.test.mjs +1 -27
- package/api/docs/docs.doc.mjs +2 -2
- package/api/docs/docs.test.mjs +243 -0
- package/api/docs/integration-tree.test.mjs +555 -0
- package/api/docs/integrationDocs.test.mjs +314 -0
- package/api/doctor/doctor.d.mts +3 -8
- package/api/doctor/doctor.doc.mjs +8 -17
- package/api/doctor/doctor.mjs +9 -90
- package/api/doctor/doctor.test.mjs +10 -122
- package/api/doctor/doctor.type.d.mts +1 -1
- package/api/doctor/doctor.type.mjs +1 -1
- package/api/gap-report/gap-report.doc.mjs +10 -19
- package/api/hook/hook.doc.mjs +3 -6
- package/api/index.d.mts +2 -1
- package/api/index.mjs +5 -5
- package/api/init/init.doc.mjs +12 -17
- package/api/integration/add-helpers.d.mts +2 -5
- package/api/integration/add-helpers.mjs +9 -36
- package/api/integration/add-theme.mjs +1 -22
- package/api/integration/add-theme.test.mjs +0 -34
- package/api/integration/authoring-checks.mjs +2 -2
- package/api/integration/integrationPackCheck.doc.mjs +3 -3
- package/api/integration/pack-check.mjs +9 -82
- package/api/integration/pack-check.test.mjs +0 -90
- package/api/integration/pack-check.type.mjs +1 -1
- package/api/json/assertResponse.doc.mjs +1 -1
- package/api/json/index.ts +1 -0
- package/api/json/isError.doc.mjs +1 -1
- package/api/layout/_adapter.d.mts +34 -0
- package/api/layout/_adapter.mjs +148 -0
- package/api/layout/check/check.d.mts +16 -0
- package/api/layout/check/check.mjs +40 -0
- package/api/layout/expand/expand.d.mts +22 -0
- package/api/layout/expand/expand.mjs +155 -0
- package/api/layout/expand/expand.path-safety.test.mjs +53 -0
- package/api/layout/grammar/grammar.d.mts +13 -0
- package/api/layout/grammar/grammar.mjs +87 -0
- package/api/layout/layout.d.mts +6 -0
- package/api/layout/layout.mjs +17 -0
- package/api/layout/layout.test.mjs +297 -0
- package/api/layout/layout.type.d.mts +89 -0
- package/api/layout/layout.type.mjs +103 -0
- package/api/layout/layoutCheck.doc.d.mts +11 -0
- package/api/layout/layoutCheck.doc.mjs +85 -0
- package/api/layout/layoutExpand.doc.d.mts +11 -0
- package/api/layout/layoutExpand.doc.mjs +107 -0
- package/api/layout/layoutGrammar.doc.d.mts +11 -0
- package/api/layout/layoutGrammar.doc.mjs +57 -0
- package/api/search/search.d.mts +1 -27
- package/api/search/search.doc.mjs +2 -2
- package/api/search/search.mjs +16 -228
- package/api/search/search.test.mjs +512 -0
- package/api/swizzle/swizzle.doc.mjs +5 -7
- package/api/template/copy/copy.mjs +1 -1
- package/api/template/copy/copy.test.mjs +0 -9
- package/api/template/template-integration.test.mjs +65 -1
- package/api/template/template.doc.mjs +1 -2
- package/api/template/template.mjs +1 -1
- package/api/theme/add/add.mjs +25 -17
- package/api/theme/add/add.staging.test.mjs +23 -40
- package/api/theme/build/build.family.test.mjs +12 -7
- package/api/theme/build/build.mjs +18 -8
- package/api/theme/generateTonalPalette.doc.mjs +2 -1
- package/api/theme/listThemes.doc.mjs +1 -1
- package/api/theme/themeAdd.doc.mjs +10 -9
- package/api/theme/themeBuild.doc.mjs +13 -13
- package/api/theme/themeList.doc.mjs +1 -1
- package/api/theme/themeListAvailable.doc.mjs +1 -2
- package/api/theme/themePaletteGenerate.doc.mjs +8 -15
- package/api/theme/themeTargets.doc.mjs +2 -3
- package/api/theme/themeTemplate.doc.mjs +1 -2
- package/api/upgrade/run/run.mjs +4 -6
- package/api/upgrade/upgrade.doc.mjs +22 -24
- package/api/upgrade/upgrade.type.mjs +2 -2
- package/assets/codemods/__tests__/runner.test.mjs +1 -3
- package/assets/codemods/integration-runner.mjs +3 -3
- package/assets/codemods/runner.mjs +4 -5
- package/assets/docs/README.md +2 -4
- package/assets/docs/browser-support.doc.mjs +11 -11
- package/assets/docs/color.doc.mjs +2 -8
- package/assets/docs/elevation.doc.mjs +4 -6
- package/assets/docs/getting-started.doc.mjs +16 -5
- package/assets/docs/icons.doc.mjs +21 -2
- package/assets/docs/illustrations.doc.mjs +15 -7
- package/assets/docs/internationalization.doc.mjs +5 -7
- package/assets/docs/layout.doc.dense.mjs +82 -130
- package/assets/docs/layout.doc.mjs +77 -133
- package/assets/docs/migration.doc.mjs +21 -19
- package/assets/docs/motion.doc.mjs +3 -16
- package/assets/docs/principles.doc.dense.mjs +5 -5
- package/assets/docs/principles.doc.mjs +0 -8
- package/assets/docs/principles.doc.zh.mjs +6 -6
- package/assets/docs/shape.doc.mjs +3 -8
- package/assets/docs/spacing.doc.mjs +2 -7
- package/assets/docs/styling-libraries.doc.mjs +2 -6
- package/assets/docs/styling.doc.mjs +23 -19
- package/assets/docs/theme.doc.dense.mjs +18 -58
- package/assets/docs/theme.doc.mjs +46 -56
- package/assets/docs/theme.doc.zh.mjs +8 -9
- package/assets/docs/tokens.doc.dense.mjs +2 -2
- package/assets/docs/tokens.doc.mjs +8 -389
- package/assets/docs/tokens.doc.zh.mjs +2 -2
- package/assets/docs/tree/integrations.doc.mjs +451 -25
- package/assets/docs/tree/integrations.test.mjs +62 -0
- package/assets/docs/tree/writing-docs.doc.mjs +286 -0
- package/assets/docs/typography.doc.mjs +4 -24
- package/assets/docs/working-with-ai.doc.mjs +22 -30
- package/assets/templates/blocks/components/InternationalizationProvider/InternationalizationProvider01ShippedLocale.tsx +1 -1
- package/authoring/config/config.doc.mjs +2 -10
- package/authoring/config/parse.d.mts +0 -2
- package/authoring/config/parse.mjs +0 -19
- package/authoring/config/parse.test.mjs +0 -8
- package/authoring/config/type.ts +2 -13
- package/authoring/doctypes/_schema.d.mts +2 -3
- package/authoring/doctypes/_schema.mjs +0 -6
- package/authoring/doctypes/base/graph-fields.doc.mjs +3 -3
- package/authoring/doctypes/base/type.ts +2 -4
- package/authoring/doctypes/command/command.doc.mjs +1 -1
- package/authoring/doctypes/command/type.ts +1 -1
- package/authoring/doctypes/component/component.doc.mjs +0 -6
- package/authoring/doctypes/component/type.ts +0 -8
- package/authoring/doctypes/reference/reference.doc.mjs +0 -7
- package/authoring/doctypes/reference/type.ts +0 -5
- package/authoring/doctypes/schema/schema.doc.mjs +2 -2
- package/authoring/doctypes/template/template.doc.mjs +1 -1
- package/authoring/doctypes/template/type.ts +2 -2
- package/authoring/index.d.mts +0 -1
- package/authoring/index.d.ts +0 -10
- package/authoring/index.mjs +0 -1
- package/authoring/integration/integration.doc.mjs +10 -12
- package/clients/cli/command-result-coverage.test.mjs +7 -7
- package/clients/cli/commands/component/index.mjs +55 -152
- package/clients/cli/commands/component-ownership.test.mjs +0 -89
- package/clients/cli/commands/component.doc.mjs +9 -27
- package/clients/cli/commands/debug-result-summary.test.mjs +2 -2
- package/clients/cli/commands/discover.doc.mjs +9 -53
- package/clients/cli/commands/discover.mjs +118 -393
- package/clients/cli/commands/docs.doc.mjs +1 -1
- package/clients/cli/commands/docs.mjs +17 -60
- package/clients/cli/commands/docs.test.mjs +294 -0
- package/clients/cli/commands/doctor-integration-docs.doc.mjs +2 -3
- package/clients/cli/commands/doctor-integration.test.mjs +0 -53
- package/clients/cli/commands/doctor.doc.mjs +1 -3
- package/clients/cli/commands/doctor.mjs +5 -49
- package/clients/cli/commands/gap-report.doc.mjs +9 -10
- package/clients/cli/commands/init.doc.mjs +6 -9
- package/clients/cli/commands/integration-add.doc.mjs +9 -9
- package/clients/cli/commands/integration-authoring.test.mjs +10 -61
- package/clients/cli/commands/integration-pack.doc.mjs +9 -5
- package/clients/cli/commands/integration-real-world.test.mjs +1 -1
- package/clients/cli/commands/integration.doc.mjs +4 -4
- package/clients/cli/commands/integration.mjs +43 -74
- package/clients/cli/commands/layout-check.doc.mjs +65 -0
- package/clients/cli/commands/layout-expand.doc.mjs +83 -0
- package/clients/cli/commands/layout-grammar.doc.mjs +30 -0
- package/clients/cli/commands/layout.doc.mjs +34 -0
- package/clients/cli/commands/layout.error-codes.test.mjs +66 -0
- package/clients/cli/commands/layout.exit-parity.test.mjs +41 -0
- package/clients/cli/commands/layout.mjs +275 -0
- package/clients/cli/commands/layout.path-help.test.mjs +33 -0
- package/clients/cli/commands/layout.stdin-cap.test.mjs +47 -0
- package/clients/cli/commands/layout.text-fields.test.mjs +39 -0
- package/clients/cli/commands/manifest.doc.mjs +1 -1
- package/clients/cli/commands/search.doc.mjs +3 -10
- package/clients/cli/commands/search.mjs +2 -21
- package/clients/cli/commands/search.test.mjs +4 -21
- package/clients/cli/commands/swizzle.doc.mjs +1 -1
- package/clients/cli/commands/template.doc.mjs +1 -1
- package/clients/cli/commands/text-json-parity.test.mjs +16 -5
- package/clients/cli/commands/theme-add.doc.mjs +1 -1
- package/clients/cli/commands/theme-palette-generate.doc.mjs +2 -3
- package/clients/cli/commands/theme-palette.doc.mjs +2 -1
- package/clients/cli/commands/theme-targets.doc.mjs +2 -2
- package/clients/cli/commands/theme.doc.mjs +1 -2
- package/clients/cli/commands/upgrade.doc.mjs +3 -62
- package/clients/cli/index.mjs +10 -28
- package/clients/cli/lib/define-command.mjs +4 -28
- package/clients/cli/lib/define-command.test.mjs +0 -54
- package/clients/cli/lib/exit-codes.test.mjs +9 -18
- package/clients/cli/lib/json-shim.mjs +14 -24
- package/clients/cli/lib/json-shim.test.mjs +20 -6
- package/clients/cli/lib/manifest.mjs +13 -18
- package/clients/cli/lib/manifest.test.mjs +2 -5
- package/foundation/agent-docs/agent-docs.mjs +1 -1
- package/foundation/agent-docs/agent-docs.test.mjs +1159 -0
- package/foundation/discovery/authoring-self-docs.mjs +0 -1
- package/foundation/discovery/authoring-self-docs.test.mjs +2 -6
- package/foundation/discovery/cli-self-docs.mjs +2 -16
- package/foundation/discovery/cli-self-docs.test.mjs +0 -20
- package/foundation/discovery/docs-discovery.mjs +1 -5
- package/foundation/discovery/docs-discovery.test.mjs +0 -21
- package/foundation/discovery/docs-section-key.d.mts +1 -1
- package/foundation/discovery/docs-section-key.mjs +1 -1
- package/foundation/discovery/template-adapter.mjs +1 -1
- package/foundation/doc-compiler/doc-loads.test.mjs +14 -3
- package/foundation/doc-compiler/tree.d.mts +0 -4
- package/foundation/doc-compiler/tree.mjs +1 -6
- package/foundation/doc-compiler/tree.test.mjs +598 -0
- package/foundation/integrations/cli-requirement.d.mts +6 -26
- package/foundation/integrations/cli-requirement.mjs +11 -46
- package/foundation/integrations/cli-requirement.test.mjs +2 -7
- package/foundation/integrations/contribution-inventory.mjs +1 -1
- package/foundation/integrations/integrations.d.mts +1 -14
- package/foundation/integrations/integrations.mjs +1 -41
- package/foundation/integrations/integrations.test.mjs +0 -31
- package/foundation/response/error-codes.doc.mjs +8 -6
- package/foundation/response/error-codes.test.mjs +5 -30
- package/foundation/response/response-types.doc.d.mts +3 -4
- package/foundation/response/response-types.doc.mjs +27 -40
- package/foundation/response/response-types.doc.test.mjs +0 -23
- package/foundation/response/response.doc.mjs +10 -11
- package/foundation/xle/browser.d.mts +3 -3
- package/foundation/xle/browser.mjs +3 -3
- package/foundation/xle/expand.mjs +2 -2
- package/foundation/xle/parse.mjs +1 -1
- package/foundation/xle/print.mjs +2 -2
- package/foundation/xle/splice.mjs +1 -1
- package/package.json +9 -9
- package/api/discover/_adapter.test.mjs +0 -215
- package/api/discover/_catalog-view.d.mts +0 -115
- package/api/discover/_catalog-view.mjs +0 -203
- package/api/discover/_catalog-view.test.mjs +0 -128
- package/api/discover/detail/item/item.d.mts +0 -26
- package/api/discover/detail/item/item.mjs +0 -78
- package/api/discover/detail/item/item.test.mjs +0 -73
- package/api/integration/pack-check.lifecycle-output.test.mjs +0 -107
- package/api/theme/add/add.rollback.test.mjs +0 -158
- package/api/theme/build/build.rollback.test.mjs +0 -148
- package/api/upgrade/run/files-changed.test.mjs +0 -111
- package/assets/codemods/file-count.test.mjs +0 -163
- package/assets/docs/tree/add-a-component.doc.mjs +0 -75
- package/assets/docs/tree/add-a-theme.doc.mjs +0 -85
- package/assets/docs/tree/add-a-topic.doc.mjs +0 -144
- package/assets/docs/tree/agent-guidance.doc.mjs +0 -138
- package/assets/docs/tree/block-template.doc.mjs +0 -130
- package/assets/docs/tree/build-the-template.doc.mjs +0 -28
- package/assets/docs/tree/building-blocks.doc.mjs +0 -46
- package/assets/docs/tree/check-your-docs.doc.mjs +0 -137
- package/assets/docs/tree/checks.doc.mjs +0 -119
- package/assets/docs/tree/codemods.doc.mjs +0 -147
- package/assets/docs/tree/component-family.doc.mjs +0 -113
- package/assets/docs/tree/component-imports.doc.mjs +0 -69
- package/assets/docs/tree/component-lookups.doc.mjs +0 -149
- package/assets/docs/tree/components.doc.mjs +0 -23
- package/assets/docs/tree/configuration.doc.mjs +0 -23
- package/assets/docs/tree/debug-and-gap-reports.doc.mjs +0 -182
- package/assets/docs/tree/define-the-theme.doc.mjs +0 -118
- package/assets/docs/tree/describe-the-component.doc.mjs +0 -57
- package/assets/docs/tree/docs.doc.mjs +0 -21
- package/assets/docs/tree/document-the-template.doc.mjs +0 -28
- package/assets/docs/tree/document-the-theme.doc.mjs +0 -68
- package/assets/docs/tree/export-template-assets.doc.mjs +0 -147
- package/assets/docs/tree/extend-or-replace.doc.mjs +0 -103
- package/assets/docs/tree/fonts-and-assets.doc.mjs +0 -106
- package/assets/docs/tree/generate-a-palette.doc.mjs +0 -66
- package/assets/docs/tree/grade-template-with-agent.doc.mjs +0 -105
- package/assets/docs/tree/help.doc.mjs +0 -16
- package/assets/docs/tree/links.doc.mjs +0 -98
- package/assets/docs/tree/package-and-test.doc.mjs +0 -32
- package/assets/docs/tree/page-template.doc.mjs +0 -71
- package/assets/docs/tree/publishing.doc.mjs +0 -111
- package/assets/docs/tree/quick-start.doc.mjs +0 -272
- package/assets/docs/tree/replace-a-core-component.doc.mjs +0 -104
- package/assets/docs/tree/replace-a-core-template.doc.mjs +0 -172
- package/assets/docs/tree/sections-and-placement.doc.mjs +0 -108
- package/assets/docs/tree/see-it-in-an-app.doc.mjs +0 -59
- package/assets/docs/tree/ship.doc.mjs +0 -16
- package/assets/docs/tree/short-and-findable.doc.mjs +0 -108
- package/assets/docs/tree/single-component.doc.mjs +0 -165
- package/assets/docs/tree/start-a-template.doc.mjs +0 -143
- package/assets/docs/tree/subcomponent.doc.mjs +0 -115
- package/assets/docs/tree/template-assets.doc.mjs +0 -64
- package/assets/docs/tree/template-doc-overview.doc.mjs +0 -109
- package/assets/docs/tree/template-fonts.doc.mjs +0 -102
- package/assets/docs/tree/template-grading-rubric.doc.mjs +0 -452
- package/assets/docs/tree/template-icons.doc.mjs +0 -97
- package/assets/docs/tree/template-images-media.doc.mjs +0 -127
- package/assets/docs/tree/template-styles.doc.mjs +0 -93
- package/assets/docs/tree/templates.doc.mjs +0 -34
- package/assets/docs/tree/test-in-an-app.doc.mjs +0 -115
- package/assets/docs/tree/test-template-in-app.doc.mjs +0 -128
- package/assets/docs/tree/themes.doc.mjs +0 -39
- package/assets/docs/tree/troubleshooting.doc.mjs +0 -149
- package/assets/docs/tree/upgrading.doc.mjs +0 -103
- package/assets/docs/tree/use-a-theme-in-an-app.doc.mjs +0 -51
- package/assets/docs/tree/verify-packed-template.doc.mjs +0 -77
- package/assets/docs/tree/versioning.doc.mjs +0 -161
- package/assets/docs/tree/write-good-templates.doc.mjs +0 -64
- package/assets/docs/tree/write-the-template-file.doc.mjs +0 -154
- package/authoring/discover/discover.doc.d.mts +0 -13
- package/authoring/discover/discover.doc.mjs +0 -138
- package/authoring/discover/parse.d.mts +0 -24
- package/authoring/discover/parse.mjs +0 -128
- package/authoring/discover/parse.test.mjs +0 -124
- package/authoring/discover/type.ts +0 -87
- package/clients/cli/commands/component-batch.test.mjs +0 -341
- package/clients/cli/commands/discover.sources.test.mjs +0 -267
- package/clients/cli/commands/integration-verify.doc.mjs +0 -22
- package/clients/cli/lib/parse-error-format.test.mjs +0 -81
- package/foundation/response/batch.type.d.mts +0 -33
- package/foundation/response/batch.type.mjs +0 -34
|
@@ -102,7 +102,6 @@ export const doc = {
|
|
|
102
102
|
type: 'string',
|
|
103
103
|
description:
|
|
104
104
|
'Directory to discover templates and resolve the target path from.',
|
|
105
|
-
default: 'process.cwd()',
|
|
106
105
|
},
|
|
107
106
|
],
|
|
108
107
|
returns: [
|
|
@@ -135,7 +134,7 @@ export const doc = {
|
|
|
135
134
|
throws: [
|
|
136
135
|
{
|
|
137
136
|
code: 'ERR_UNKNOWN_TEMPLATE',
|
|
138
|
-
when: 'the named template does not exist, or
|
|
137
|
+
when: 'the named template does not exist, or --skeleton is run without a name',
|
|
139
138
|
},
|
|
140
139
|
{
|
|
141
140
|
code: 'ERR_AMBIGUOUS_TEMPLATE',
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* the requested one, and routes to a leaf (list/show/skeleton/copy/cdn). The shared
|
|
9
9
|
* discovery/IO + cross-command helpers live in `foundation/discovery/template-adapter.mjs` and are
|
|
10
10
|
* RE-EXPORTED here so external import paths (`api/template/template.mjs`) —
|
|
11
|
-
* used by component, search, init, discover, Doctor integration, and
|
|
11
|
+
* used by component, layout, search, init, discover, Doctor integration, and
|
|
12
12
|
* lib/project — keep resolving unchanged.
|
|
13
13
|
*
|
|
14
14
|
* @position api/template — the template dispatcher + barrel; leaves live under
|
package/api/theme/add/add.mjs
CHANGED
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
import {AstryxError} from '../../error.mjs';
|
|
16
16
|
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
17
17
|
import {listAvailableThemes, findTheme} from '../_adapter.mjs';
|
|
18
|
-
import {applyWrites} from '../../integration/add-helpers.mjs';
|
|
19
18
|
// Scaffolded files must not carry our repo boilerplate into a consumer's tree.
|
|
20
19
|
import {stripCopyrightHeader} from '../../../foundation/text/copyright-header.mjs';
|
|
21
20
|
|
|
@@ -137,28 +136,37 @@ export async function themeAdd(slug, options = {}) {
|
|
|
137
136
|
}
|
|
138
137
|
}
|
|
139
138
|
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
139
|
+
// Stage to temp files then rename, rolling back partials on failure so a
|
|
140
|
+
// failed write never leaves a half-written theme. mkdir is inside the try so
|
|
141
|
+
// a failure (e.g. an ancestor is a file → EEXIST/ENOTDIR) surfaces as a
|
|
142
|
+
// stable ERR_WRITE_FAILED rather than leaking a raw fs errno + absolute path.
|
|
143
|
+
const staged = [];
|
|
144
144
|
try {
|
|
145
145
|
fs.mkdirSync(resolvedDir, {recursive: true});
|
|
146
|
-
const
|
|
147
|
-
fs.mkdirSync(path.dirname(w.dest), {recursive: true});
|
|
148
|
-
// Confine again once the directories exist: one may have been swapped
|
|
149
|
-
// for a link since the destination was first checked.
|
|
146
|
+
for (const w of writes) {
|
|
150
147
|
const dest = assertWithin(w.name, resolvedDir, {
|
|
151
148
|
label: `theme destination for ${w.name}`,
|
|
152
149
|
});
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
fs.mkdirSync(path.dirname(dest), {recursive: true});
|
|
151
|
+
// The staging file is an output path too: confine it, and never write
|
|
152
|
+
// through an entry that already exists under its name.
|
|
153
|
+
const tmp = assertWithin(`${w.name}.${process.pid}.tmp`, resolvedDir, {
|
|
154
|
+
label: `theme staging file for ${w.name}`,
|
|
155
|
+
});
|
|
156
|
+
fs.writeFileSync(tmp, scaffoldContents(fs.readFileSync(w.src)), {flag: 'wx'});
|
|
157
|
+
staged.push({tmp, dest});
|
|
158
|
+
}
|
|
159
|
+
for (const s of staged) {
|
|
160
|
+
fs.renameSync(s.tmp, s.dest);
|
|
161
|
+
}
|
|
160
162
|
} catch (err) {
|
|
161
|
-
|
|
163
|
+
for (const s of staged) {
|
|
164
|
+
try {
|
|
165
|
+
fs.rmSync(s.tmp, {force: true});
|
|
166
|
+
} catch {
|
|
167
|
+
/* best-effort */
|
|
168
|
+
}
|
|
169
|
+
}
|
|
162
170
|
if (err instanceof PathSafetyError) {
|
|
163
171
|
throw new AstryxError(
|
|
164
172
|
err.message,
|
|
@@ -6,15 +6,14 @@ import * as os from 'node:os';
|
|
|
6
6
|
import * as path from 'node:path';
|
|
7
7
|
import {themeAdd} from './add.mjs';
|
|
8
8
|
import {listThemes} from '../_adapter.mjs';
|
|
9
|
+
import {isErrorCode} from '../../../foundation/response/error-codes.mjs';
|
|
9
10
|
|
|
10
11
|
let tmpDir;
|
|
11
12
|
let outsideDir;
|
|
12
13
|
|
|
13
14
|
beforeEach(() => {
|
|
14
15
|
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-themeadd-staging-'));
|
|
15
|
-
outsideDir = fs.mkdtempSync(
|
|
16
|
-
path.join(os.tmpdir(), 'astryx-themeadd-outside-'),
|
|
17
|
-
);
|
|
16
|
+
outsideDir = fs.mkdtempSync(path.join(os.tmpdir(), 'astryx-themeadd-outside-'));
|
|
18
17
|
});
|
|
19
18
|
|
|
20
19
|
afterEach(() => {
|
|
@@ -23,61 +22,45 @@ afterEach(() => {
|
|
|
23
22
|
});
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
25
|
+
* Put a symlink where `theme add` stages the first file of `slug`.
|
|
27
26
|
* @param {string} slug
|
|
27
|
+
* @param {string} target
|
|
28
28
|
*/
|
|
29
|
-
function
|
|
29
|
+
function plantStagingLink(slug, target) {
|
|
30
30
|
const theme = listThemes().find(entry => entry.slug === slug);
|
|
31
31
|
if (!theme) throw new Error(`missing bundled theme ${slug}`);
|
|
32
|
-
const
|
|
32
|
+
const first = theme.files[0];
|
|
33
|
+
const dest = path.join(tmpDir, 'src', 'themes', slug, first);
|
|
33
34
|
fs.mkdirSync(path.dirname(dest), {recursive: true});
|
|
35
|
+
fs.symlinkSync(target, `${dest}.${process.pid}.tmp`);
|
|
34
36
|
return dest;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
// Staging names are unpredictable and created exclusively, so an entry planted
|
|
38
|
-
// at a predictable name beside the destination is never written through.
|
|
39
39
|
describe('themeAdd staging writes stay inside the project', () => {
|
|
40
|
-
it('
|
|
40
|
+
it('refuses a staging path that links outside the project', async () => {
|
|
41
41
|
const victim = path.join(outsideDir, 'victim.txt');
|
|
42
42
|
fs.writeFileSync(victim, 'outside\n');
|
|
43
|
-
const dest =
|
|
44
|
-
fs.symlinkSync(victim, `${dest}.${process.pid}.tmp`);
|
|
45
|
-
|
|
46
|
-
await themeAdd('stone', {cwd: tmpDir});
|
|
43
|
+
const dest = plantStagingLink('stone', victim);
|
|
47
44
|
|
|
45
|
+
await expect(themeAdd('stone', {cwd: tmpDir})).rejects.toMatchObject({
|
|
46
|
+
code: 'ERR_PATH_TRAVERSAL',
|
|
47
|
+
});
|
|
48
48
|
expect(fs.readFileSync(victim, 'utf-8')).toBe('outside\n');
|
|
49
|
-
expect(fs.
|
|
49
|
+
expect(fs.existsSync(dest)).toBe(false);
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
-
it('never creates a file through a dangling
|
|
52
|
+
it('never creates a file through a dangling staging link', async () => {
|
|
53
53
|
const victim = path.join(outsideDir, 'created.txt');
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
await themeAdd('stone', {cwd: tmpDir});
|
|
57
|
-
|
|
58
|
-
expect(fs.existsSync(victim)).toBe(false);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('refuses to replace a destination that links outside the project', async () => {
|
|
62
|
-
const victim = path.join(outsideDir, 'victim.txt');
|
|
63
|
-
fs.writeFileSync(victim, 'outside\n');
|
|
64
|
-
const dest = firstDestination('stone');
|
|
65
|
-
fs.symlinkSync(victim, dest);
|
|
54
|
+
plantStagingLink('stone', victim);
|
|
66
55
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
56
|
+
let error;
|
|
57
|
+
try {
|
|
58
|
+
await themeAdd('stone', {cwd: tmpDir});
|
|
59
|
+
} catch (caught) {
|
|
60
|
+
error = caught;
|
|
61
|
+
}
|
|
73
62
|
|
|
74
|
-
|
|
75
|
-
const victim = path.join(outsideDir, 'created.txt');
|
|
76
|
-
fs.symlinkSync(victim, firstDestination('stone'));
|
|
77
|
-
|
|
78
|
-
await expect(themeAdd('stone', {cwd: tmpDir})).rejects.toMatchObject({
|
|
79
|
-
code: 'ERR_PATH_TRAVERSAL',
|
|
80
|
-
});
|
|
63
|
+
expect(isErrorCode(error?.code)).toBe(true);
|
|
81
64
|
expect(fs.existsSync(victim)).toBe(false);
|
|
82
65
|
});
|
|
83
66
|
});
|
|
@@ -251,18 +251,23 @@ describe('themeBuildFamily()', () => {
|
|
|
251
251
|
const dir = makeDir();
|
|
252
252
|
const files = writeFamily(dir);
|
|
253
253
|
const outputDir = path.join(dir, 'themes');
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
const blockedTmp = path.join(
|
|
255
|
+
outputDir,
|
|
256
|
+
`${FAMILY_KEY}.js.${process.pid}.tmp`,
|
|
257
|
+
);
|
|
258
|
+
fs.mkdirSync(blockedTmp);
|
|
257
259
|
|
|
258
260
|
await expect(build(dir, files)).rejects.toThrow(
|
|
259
261
|
/Failed to write theme outputs/,
|
|
260
262
|
);
|
|
261
|
-
|
|
262
|
-
|
|
263
|
+
for (const output of OUTPUTS) {
|
|
264
|
+
expect(fs.existsSync(path.join(outputDir, output))).toBe(false);
|
|
265
|
+
}
|
|
263
266
|
expect(
|
|
264
|
-
fs.
|
|
265
|
-
|
|
267
|
+
fs.existsSync(
|
|
268
|
+
path.join(outputDir, `${FAMILY_KEY}.css.${process.pid}.tmp`),
|
|
269
|
+
),
|
|
270
|
+
).toBe(false);
|
|
266
271
|
});
|
|
267
272
|
|
|
268
273
|
it('rejects invalid graphs and keys before touching an existing trio', async () => {
|
|
@@ -53,7 +53,6 @@ import {
|
|
|
53
53
|
} from '../../../foundation/fs/path-safety.mjs';
|
|
54
54
|
import {ERROR_CODES} from '../../../foundation/response/error-codes.mjs';
|
|
55
55
|
import {AstryxError} from '../../error.mjs';
|
|
56
|
-
import {applyWrites} from '../../integration/add-helpers.mjs';
|
|
57
56
|
import {logger} from '../../logger.mjs';
|
|
58
57
|
import {loadComponentDoc} from '../../../foundation/discovery/component-loader.mjs';
|
|
59
58
|
import {
|
|
@@ -225,15 +224,26 @@ function staleBuildOutputs(writes, cwd) {
|
|
|
225
224
|
/** @param {Array<{dest: string, content: string}>} writes */
|
|
226
225
|
function writeBuildOutputs(writes) {
|
|
227
226
|
if (writes.length === 0) return;
|
|
227
|
+
/** @type {Array<{tmp: string, dest: string}>} */
|
|
228
|
+
const staged = [];
|
|
228
229
|
try {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)
|
|
230
|
+
fs.mkdirSync(path.dirname(writes[0].dest), {recursive: true});
|
|
231
|
+
for (const write of writes) {
|
|
232
|
+
const tmp = `${write.dest}.${process.pid}.tmp`;
|
|
233
|
+
fs.writeFileSync(tmp, write.content);
|
|
234
|
+
staged.push({tmp, dest: write.dest});
|
|
235
|
+
}
|
|
236
|
+
for (const stagedWrite of staged) {
|
|
237
|
+
fs.renameSync(stagedWrite.tmp, stagedWrite.dest);
|
|
238
|
+
}
|
|
236
239
|
} catch (error) {
|
|
240
|
+
for (const stagedWrite of staged) {
|
|
241
|
+
try {
|
|
242
|
+
fs.rmSync(stagedWrite.tmp, {force: true});
|
|
243
|
+
} catch {
|
|
244
|
+
// Best effort: the command still fails and never reports success.
|
|
245
|
+
}
|
|
246
|
+
}
|
|
237
247
|
const message = `Failed to write theme outputs: ${/** @type {Error} */ (error).message}`;
|
|
238
248
|
throw new AstryxError(message, undefined, ERROR_CODES.ERR_WRITE_FAILED);
|
|
239
249
|
}
|
|
@@ -29,7 +29,7 @@ export const doc = {
|
|
|
29
29
|
name: 'input',
|
|
30
30
|
type: 'TonalPaletteGenerationInput',
|
|
31
31
|
description:
|
|
32
|
-
'Families and seeds plus optional modes, shared stops, anchors, vibrancy from 0 to 100 (default 50), and neutral profile.',
|
|
32
|
+
'Families and seeds plus optional modes, shared stops, anchors, vibrancy from 0 to 100 (default 50), and neutral profile. Only generate an accent family when one is explicitly requested; clarify whether an ambiguous accent means one theme value or a tonal family.',
|
|
33
33
|
required: true,
|
|
34
34
|
},
|
|
35
35
|
],
|
|
@@ -72,5 +72,6 @@ export const doc = {
|
|
|
72
72
|
code: "generateTonalPalette({stops: [12.5, 50], families: [{id: 'blue', seed: '#0074e2'}]});",
|
|
73
73
|
},
|
|
74
74
|
],
|
|
75
|
+
command: 'theme palette generate',
|
|
75
76
|
related: ['themePaletteGenerate'],
|
|
76
77
|
};
|
|
@@ -13,7 +13,7 @@ export const doc = {
|
|
|
13
13
|
displayName: 'listThemes()',
|
|
14
14
|
summary: 'Read the CLI bundled-theme descriptors.',
|
|
15
15
|
description:
|
|
16
|
-
|
|
16
|
+
'Reads the typed same-stem descriptors under templates/themes and returns normalized entries synchronously. This low-level helper keeps its historical bundled-only contract; project-aware themeList() and themeAdd() also discover source themes from installed integrations.',
|
|
17
17
|
importPath: '@astryxdesign/cli/api',
|
|
18
18
|
signature: 'listThemes(): BundledTheme[]',
|
|
19
19
|
keywords: ['theme', 'themes', 'descriptor', 'bundled', 'adapter', 'list'],
|
|
@@ -44,7 +44,6 @@ export const doc = {
|
|
|
44
44
|
type: 'string',
|
|
45
45
|
description:
|
|
46
46
|
'Project directory used for integration discovery and target paths.',
|
|
47
|
-
default: 'process.cwd()',
|
|
48
47
|
},
|
|
49
48
|
{
|
|
50
49
|
name: 'options.package',
|
|
@@ -58,6 +57,11 @@ export const doc = {
|
|
|
58
57
|
description:
|
|
59
58
|
'Copy receipt with slug, displayName, maintained flag, owner package, outputDir, entry, exportName, and files.',
|
|
60
59
|
},
|
|
60
|
+
{
|
|
61
|
+
type: 'theme.list',
|
|
62
|
+
description:
|
|
63
|
+
'The CLI list affordance routes a bare `astryx theme add` or `--list` to themeListAvailable() and returns every available theme with its owner.',
|
|
64
|
+
},
|
|
61
65
|
],
|
|
62
66
|
throws: [
|
|
63
67
|
{
|
|
@@ -70,10 +74,7 @@ export const doc = {
|
|
|
70
74
|
when: 'the selected installed package has a blocking integration or theme-descriptor error',
|
|
71
75
|
},
|
|
72
76
|
{code: 'ERR_PATH_TRAVERSAL', when: 'the target path escapes cwd'},
|
|
73
|
-
{
|
|
74
|
-
code: 'ERR_NO_SOURCE',
|
|
75
|
-
when: 'the bundled theme descriptors cannot be read, or a theme file to copy is missing',
|
|
76
|
-
},
|
|
77
|
+
{code: 'ERR_NO_SOURCE', when: 'a theme file to copy is missing'},
|
|
77
78
|
{
|
|
78
79
|
code: 'ERR_FILE_EXISTS',
|
|
79
80
|
when: 'a destination exists and overwrite is not set',
|
|
@@ -81,12 +82,12 @@ export const doc = {
|
|
|
81
82
|
{code: 'ERR_WRITE_FAILED', when: 'writing files fails'},
|
|
82
83
|
],
|
|
83
84
|
examples: [
|
|
84
|
-
{label: 'Copy a bundled theme', code: "await themeAdd('
|
|
85
|
+
{label: 'Copy a bundled theme', code: "await themeAdd('ocean');"},
|
|
85
86
|
{
|
|
86
|
-
label: '
|
|
87
|
-
code: "await themeAdd('
|
|
87
|
+
label: 'Copy an integration theme',
|
|
88
|
+
code: "await themeAdd('ocean', {package: '@acme/themes'});",
|
|
88
89
|
},
|
|
89
90
|
],
|
|
90
91
|
command: 'theme add',
|
|
91
|
-
related: ['
|
|
92
|
+
related: ['themeList', 'listThemes'],
|
|
92
93
|
};
|
|
@@ -14,13 +14,14 @@ export const doc = {
|
|
|
14
14
|
name: 'themeBuild',
|
|
15
15
|
namespace: 'cli/api',
|
|
16
16
|
displayName: 'themeBuild()',
|
|
17
|
-
summary:
|
|
18
|
-
'Compile a defineTheme() file to scoped CSS, a JS module, and type declarations, or check committed outputs for drift in CI.',
|
|
17
|
+
summary: 'Compile a defineTheme file to CSS + JS + type declarations.',
|
|
19
18
|
description:
|
|
20
|
-
'The compiler behind `astryx theme build`. Reads a file that calls defineTheme() and ' +
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
|
|
19
|
+
'The compiler behind `astryx theme build`. Reads a file that calls defineTheme() and, ' +
|
|
20
|
+
"via @astryxdesign/core's shared generator (the single source of truth, so the build " +
|
|
21
|
+
'emits the exact CSS the <Theme> runtime does), writes a scoped CSS file, a JS module ' +
|
|
22
|
+
'that re-exports the built theme, and a .d.ts (plus an optional .variants.d.ts when the ' +
|
|
23
|
+
'theme adds custom prop values). When another build step emits the icon registry, ' +
|
|
24
|
+
'{iconsSpecifier} declares the fully specified module path for the generated JS import. ' +
|
|
24
25
|
'With {check: true} it writes nothing and instead compares ' +
|
|
25
26
|
'each output against disk, returning the drift: the CI guard for committed, generated theme CSS.',
|
|
26
27
|
importPath: '@astryxdesign/cli/api',
|
|
@@ -47,7 +48,7 @@ export const doc = {
|
|
|
47
48
|
name: 'options.out',
|
|
48
49
|
type: 'string',
|
|
49
50
|
description:
|
|
50
|
-
'Override the output CSS path
|
|
51
|
+
'Override the output CSS path; the sibling .js and .d.ts derive from it. A relative path must stay within cwd.',
|
|
51
52
|
},
|
|
52
53
|
{
|
|
53
54
|
name: 'options.check',
|
|
@@ -60,14 +61,13 @@ export const doc = {
|
|
|
60
61
|
name: 'options.iconsSpecifier',
|
|
61
62
|
type: 'string',
|
|
62
63
|
description:
|
|
63
|
-
'Override the import specifier
|
|
64
|
+
'Override the icon-registry import specifier in the generated JS module, for example ./icons.mjs. When omitted, the source specifier is preserved.',
|
|
64
65
|
},
|
|
65
66
|
{
|
|
66
67
|
name: 'ctx.cwd',
|
|
67
68
|
type: 'string',
|
|
68
69
|
description:
|
|
69
|
-
'Directory the theme file
|
|
70
|
-
default: 'process.cwd()',
|
|
70
|
+
'Directory the theme file and @astryxdesign/core resolve against.',
|
|
71
71
|
},
|
|
72
72
|
],
|
|
73
73
|
returns: [
|
|
@@ -79,7 +79,7 @@ export const doc = {
|
|
|
79
79
|
{
|
|
80
80
|
type: 'theme.build.check',
|
|
81
81
|
description:
|
|
82
|
-
'The {check: true} receipt: theme name, an upToDate flag, the stale outputs (each {path, reason: "missing" | "outdated"}), and the full list of checked paths. Writes nothing.
|
|
82
|
+
'The {check: true} receipt: theme name, an upToDate flag, the stale outputs (each {path, reason: "missing" | "outdated"}), and the full list of checked paths. Writes nothing.',
|
|
83
83
|
},
|
|
84
84
|
],
|
|
85
85
|
throws: [
|
|
@@ -102,7 +102,7 @@ export const doc = {
|
|
|
102
102
|
},
|
|
103
103
|
{
|
|
104
104
|
code: 'ERR_CORE_INCOMPATIBLE',
|
|
105
|
-
when: 'the
|
|
105
|
+
when: 'the selected theme carries ordered-adaptation intent but the installed @astryxdesign/core does not export generateAdaptationCSS (upgrade core)',
|
|
106
106
|
},
|
|
107
107
|
{
|
|
108
108
|
code: 'ERR_WRITE_FAILED',
|
|
@@ -124,5 +124,5 @@ export const doc = {
|
|
|
124
124
|
},
|
|
125
125
|
],
|
|
126
126
|
command: 'theme build',
|
|
127
|
-
related: ['
|
|
127
|
+
related: ['themeAdd', 'themeList', 'listThemes'],
|
|
128
128
|
};
|
|
@@ -13,7 +13,7 @@ export const doc = {
|
|
|
13
13
|
displayName: 'themeList()',
|
|
14
14
|
summary: 'List themes bundled with this CLI build.',
|
|
15
15
|
description:
|
|
16
|
-
'
|
|
16
|
+
'Projects the bundled typed theme descriptors into a synchronous theme.list envelope. This preserves the original programmatic API contract. The CLI command uses themeListAvailable() so installed integrations also appear.',
|
|
17
17
|
importPath: '@astryxdesign/cli/api',
|
|
18
18
|
signature: 'themeList(): ThemeListResponse',
|
|
19
19
|
keywords: ['theme', 'list', 'themes', 'bundled', 'available'],
|
|
@@ -13,7 +13,7 @@ export const doc = {
|
|
|
13
13
|
displayName: 'themeListAvailable()',
|
|
14
14
|
summary: 'List bundled and installed integration themes.',
|
|
15
15
|
description:
|
|
16
|
-
'
|
|
16
|
+
'Loads Project for the requested directory, combines the CLI bundle with source themes from installed integrations, and projects each entry with its owner package. An unreadable project configuration degrades to the bundled descriptors.',
|
|
17
17
|
importPath: '@astryxdesign/cli/api',
|
|
18
18
|
signature:
|
|
19
19
|
'themeListAvailable(options?: {cwd?: string, package?: string}): Promise<ThemeListResponse>',
|
|
@@ -24,7 +24,6 @@ export const doc = {
|
|
|
24
24
|
type: 'string',
|
|
25
25
|
description:
|
|
26
26
|
'Project directory whose installed integrations contribute themes.',
|
|
27
|
-
default: 'process.cwd()',
|
|
28
27
|
},
|
|
29
28
|
{
|
|
30
29
|
name: 'options.package',
|
|
@@ -27,34 +27,30 @@ export const doc = {
|
|
|
27
27
|
{
|
|
28
28
|
name: 'configPath',
|
|
29
29
|
type: 'string',
|
|
30
|
-
description:
|
|
31
|
-
'Path to a JSON file holding a TonalPaletteGenerationInput (the object generateTonalPalette() takes), resolved within cwd.',
|
|
30
|
+
description: 'JSON generation request, resolved within cwd.',
|
|
32
31
|
required: true,
|
|
33
32
|
},
|
|
34
33
|
{
|
|
35
34
|
name: 'options.out',
|
|
36
35
|
type: 'string',
|
|
37
36
|
description:
|
|
38
|
-
'
|
|
37
|
+
'Optional candidate JSON destination. A sibling .receipt.json path is derived from it.',
|
|
39
38
|
},
|
|
40
39
|
{
|
|
41
40
|
name: 'options.preview',
|
|
42
41
|
type: 'string',
|
|
43
|
-
description:
|
|
44
|
-
'Optional path, ending in .html, for a self-contained HTML review page.',
|
|
42
|
+
description: 'Optional path for a self-contained HTML review artifact.',
|
|
45
43
|
},
|
|
46
44
|
{
|
|
47
45
|
name: 'options.overwrite',
|
|
48
46
|
type: 'boolean',
|
|
49
|
-
description:
|
|
50
|
-
"Replace existing candidate, receipt and preview files. Without it, if any target exists, nothing is written and the result has written: false, reason: 'exists'.",
|
|
47
|
+
description: 'Replace existing candidate and receipt files.',
|
|
51
48
|
default: 'false',
|
|
52
49
|
},
|
|
53
50
|
{
|
|
54
51
|
name: 'ctx.cwd',
|
|
55
52
|
type: 'string',
|
|
56
53
|
description: 'Directory used to resolve the input and output paths.',
|
|
57
|
-
default: 'process.cwd()',
|
|
58
54
|
},
|
|
59
55
|
],
|
|
60
56
|
returns: [
|
|
@@ -68,20 +64,17 @@ export const doc = {
|
|
|
68
64
|
{code: 'ERR_FILE_NOT_FOUND', when: 'the config file does not exist'},
|
|
69
65
|
{
|
|
70
66
|
code: 'ERR_PALETTE_GENERATION',
|
|
71
|
-
when: 'the
|
|
67
|
+
when: 'the request, seed, stop layout, mode, or anchor constraint is invalid',
|
|
72
68
|
},
|
|
73
69
|
{
|
|
74
70
|
code: 'ERR_PATH_TRAVERSAL',
|
|
75
71
|
when: 'an input or output path escapes cwd, or output would replace input',
|
|
76
72
|
},
|
|
77
|
-
{
|
|
78
|
-
code: 'ERR_WRITE_FAILED',
|
|
79
|
-
when: 'the candidate, receipt or preview file cannot be written',
|
|
80
|
-
},
|
|
73
|
+
{code: 'ERR_WRITE_FAILED', when: 'the candidate pair cannot be written'},
|
|
81
74
|
],
|
|
82
75
|
examples: [
|
|
83
76
|
{
|
|
84
|
-
label: '
|
|
77
|
+
label: 'Preview a candidate',
|
|
85
78
|
code: "themePaletteGenerate('palette.config.json');",
|
|
86
79
|
},
|
|
87
80
|
{
|
|
@@ -90,5 +83,5 @@ export const doc = {
|
|
|
90
83
|
},
|
|
91
84
|
],
|
|
92
85
|
command: 'theme palette generate',
|
|
93
|
-
related: ['
|
|
86
|
+
related: ['themeBuild', 'themeTemplate'],
|
|
94
87
|
};
|
|
@@ -22,7 +22,7 @@ export const doc = {
|
|
|
22
22
|
'Same source as the Theming table `astryx component <Name>` prints ' +
|
|
23
23
|
'(the component docs), so the list cannot drift from the components, and `theme build` ' +
|
|
24
24
|
'validates overrides against this exact set. A filter naming a component gives that ' +
|
|
25
|
-
"component's set; anything else is a
|
|
25
|
+
"component's set; anything else is a substring search over the keys.",
|
|
26
26
|
importPath: '@astryxdesign/cli/api',
|
|
27
27
|
signature:
|
|
28
28
|
'themeTargets(filter?: string, ctx?: {cwd?: string}): Promise<ThemeTargetsResponse>',
|
|
@@ -41,14 +41,13 @@ export const doc = {
|
|
|
41
41
|
name: 'filter',
|
|
42
42
|
type: 'string',
|
|
43
43
|
description:
|
|
44
|
-
'A component name (exact, case-insensitive)
|
|
44
|
+
'A component name (exact, case-insensitive) or a substring of a target key. Omit for the whole surface.',
|
|
45
45
|
},
|
|
46
46
|
{
|
|
47
47
|
name: 'ctx.cwd',
|
|
48
48
|
type: 'string',
|
|
49
49
|
description:
|
|
50
50
|
"Directory the project's @astryxdesign/core is resolved from.",
|
|
51
|
-
default: 'process.cwd()',
|
|
52
51
|
},
|
|
53
52
|
],
|
|
54
53
|
returns: [
|
|
@@ -43,7 +43,6 @@ export const doc = {
|
|
|
43
43
|
name: 'options.cwd',
|
|
44
44
|
type: 'string',
|
|
45
45
|
description: 'Directory the target path resolves against.',
|
|
46
|
-
default: 'process.cwd()',
|
|
47
46
|
},
|
|
48
47
|
],
|
|
49
48
|
returns: [
|
|
@@ -65,5 +64,5 @@ export const doc = {
|
|
|
65
64
|
},
|
|
66
65
|
],
|
|
67
66
|
command: 'theme template',
|
|
68
|
-
related: ['themeAdd', 'themeBuild', '
|
|
67
|
+
related: ['themeAdd', 'themeBuild', 'themeList'],
|
|
69
68
|
};
|
package/api/upgrade/run/run.mjs
CHANGED
|
@@ -114,7 +114,7 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
114
114
|
// Resolve the source dir against the API's cwd (not process.cwd()) so a
|
|
115
115
|
// programmatic caller in another directory scans the right tree. Confine it to
|
|
116
116
|
// cwd: --apply rewrites files in place, so a `..`-escaping or out-of-tree
|
|
117
|
-
// absolute --path must be rejected (parity with template/theme/swizzle,
|
|
117
|
+
// absolute --path must be rejected (parity with template/theme/swizzle/layout,
|
|
118
118
|
// and this is the most destructive command). allowAbsolute permits an absolute
|
|
119
119
|
// path that still resolves inside cwd.
|
|
120
120
|
let path_;
|
|
@@ -437,11 +437,9 @@ export async function run(options = {}, {cwd = process.cwd()} = {}) {
|
|
|
437
437
|
|
|
438
438
|
const registryResult = await reconcileCompositions();
|
|
439
439
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
...(integrationResult?.changedFiles ?? []),
|
|
444
|
-
]).size;
|
|
440
|
+
const mergedFilesChanged =
|
|
441
|
+
(coreResult?.totalFilesChanged ?? 0) +
|
|
442
|
+
(integrationResult?.totalFilesChanged ?? 0);
|
|
445
443
|
const mergedTransformsApplied =
|
|
446
444
|
(coreResult?.totalTransformsApplied ?? 0) +
|
|
447
445
|
(integrationResult?.totalTransformsApplied ?? 0);
|