@orkestrel/scaffold 0.0.81 → 0.0.83
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/dist/agents/skills/orkestrel-publish/scripts/wave.js +14 -3
- package/dist/bin/main.js +295 -13
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +5 -3
- package/dist/host/agents/orchestration.md +1 -0
- package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +2 -2
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +43 -39
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/decide.md +10 -9
- package/dist/host/agents/skills/orkestrel-journey/references/layer.md +5 -5
- package/dist/host/agents/skills/orkestrel-journey/references/recorded.md +77 -0
- package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/styles.md +9 -9
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +4 -0
- package/dist/host/agents/skills/orkestrel-publish/scripts/wave.ts +22 -4
- package/dist/host/claude/agents/orkestrel.md +10 -10
- package/dist/host/claude/rules/application.md +20 -6
- package/dist/host/claude/rules/architecture.md +2 -2
- package/dist/host/claude/rules/browser.md +9 -0
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/quality.md +5 -0
- package/dist/host/claude/rules/styles.md +35 -12
- package/dist/host/claude/rules/tests.md +15 -10
- package/dist/host/claude/rules/workspace.md +128 -98
- package/dist/host/claude/skills/orkestrel-journey/SKILL.md +1 -1
- package/dist/host/configs/helpers.ts +157 -9
- package/dist/host/configs/policy.ts +64 -61
- package/dist/host/dotfiles/oxlintrc.json +132 -16
- package/dist/host/dotfiles/prettierignore +1 -1
- package/dist/host/guides/README.md +9 -5
- package/dist/host/guides/guide.md +4 -1
- package/dist/host/guides/scaffold.md +482 -115
- package/dist/host/manifest.json +38 -32
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +0 -0
- package/dist/host/tests/config.test.ts +996 -39
- package/dist/host/tests/policy.test.ts +11 -0
- package/dist/host/tests/setupPolicy.ts +396 -22
- package/dist/src/core/index.cjs +1289 -164
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +313 -35
- package/dist/src/core/index.d.ts +313 -35
- package/dist/src/core/index.js +1268 -165
- package/dist/src/core/index.js.map +1 -1
- package/package.json +7 -6
package/dist/src/core/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ let _orkestrel_template = require("@orkestrel/template");
|
|
|
4
4
|
let _orkestrel_emitter = require("@orkestrel/emitter");
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@orkestrel/scaffold",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.83",
|
|
8
8
|
description: "Scaffold workspaces with commands: new, audit, repair, catalog, and overwrite.",
|
|
9
9
|
keywords: [
|
|
10
10
|
"audit",
|
|
@@ -95,16 +95,17 @@ var package_default = {
|
|
|
95
95
|
},
|
|
96
96
|
dependencies: {
|
|
97
97
|
"@orkestrel/console": "^0.0.15",
|
|
98
|
-
"@orkestrel/contract": "^0.0.
|
|
98
|
+
"@orkestrel/contract": "^0.0.19",
|
|
99
99
|
"@orkestrel/emitter": "^0.0.11",
|
|
100
|
-
"@orkestrel/markdown": "^0.0.
|
|
100
|
+
"@orkestrel/markdown": "^0.0.17",
|
|
101
101
|
"@orkestrel/process": "^0.0.14",
|
|
102
102
|
"@orkestrel/template": "^0.0.9"
|
|
103
103
|
},
|
|
104
104
|
devDependencies: {
|
|
105
105
|
"@microsoft/api-extractor": "^7.59.3",
|
|
106
|
-
"@orkestrel/
|
|
107
|
-
"@orkestrel/
|
|
106
|
+
"@orkestrel/browser": "^0.0.20",
|
|
107
|
+
"@orkestrel/guide": "^0.0.22",
|
|
108
|
+
"@orkestrel/html": "^0.0.12",
|
|
108
109
|
"@orkestrel/probe": "^0.0.19",
|
|
109
110
|
"@orkestrel/test": "^0.0.24",
|
|
110
111
|
"@types/node": "^26.6.3",
|
|
@@ -113,7 +114,7 @@ var package_default = {
|
|
|
113
114
|
"oxlint": "^1.86.0",
|
|
114
115
|
"playwright": "^1.63.0",
|
|
115
116
|
"typescript": "^6.0.3",
|
|
116
|
-
"vite": "^8.3.
|
|
117
|
+
"vite": "^8.3.2",
|
|
117
118
|
"vitest": "^4.1.11"
|
|
118
119
|
},
|
|
119
120
|
engines: { "node": ">=22.18.0" }
|
|
@@ -134,6 +135,44 @@ var ENVIRONMENTS = Object.freeze([
|
|
|
134
135
|
"browser",
|
|
135
136
|
"server"
|
|
136
137
|
]);
|
|
138
|
+
/** Lists the surfaces an extension may extend, frozen. */
|
|
139
|
+
var SURFACES = Object.freeze(["browser", "styles"]);
|
|
140
|
+
/** Lists the axes a browser extension may occupy, frozen. */
|
|
141
|
+
var AXES = Object.freeze(["src", "app"]);
|
|
142
|
+
/** Lists the supported browser frameworks, frozen. */
|
|
143
|
+
var FRAMEWORKS = Object.freeze(["vue"]);
|
|
144
|
+
/** Describes the tooling and package boundaries of each browser framework, frozen. */
|
|
145
|
+
var FRAMEWORK_MATRIX = Object.freeze({ vue: Object.freeze({
|
|
146
|
+
plugin: "@vitejs/plugin-vue",
|
|
147
|
+
checker: "vue-tsc",
|
|
148
|
+
suffixes: Object.freeze(["vue"]),
|
|
149
|
+
refused: Object.freeze(["vue", "@vue/"]),
|
|
150
|
+
dependencies: Object.freeze({
|
|
151
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
152
|
+
vue: "^3.5.40",
|
|
153
|
+
"vue-tsc": "^3.3.7"
|
|
154
|
+
})
|
|
155
|
+
}) });
|
|
156
|
+
/** Names the base stylesheet marker. */
|
|
157
|
+
var STYLES_ENTRY_PATH = "src/styles/index.scss";
|
|
158
|
+
/** Names the themes build entry marker. */
|
|
159
|
+
var THEMES_ENTRY_PATH = "src/styles/themes/sheet.ts";
|
|
160
|
+
/** Names the themes stylesheet marker. */
|
|
161
|
+
var THEMES_BARREL_PATH = "src/styles/themes/index.scss";
|
|
162
|
+
/** Names the build entry beside each stylesheet marker. */
|
|
163
|
+
var SHEET_ENTRY_NAME = "sheet.ts";
|
|
164
|
+
/** Names the physical showcase output directory. */
|
|
165
|
+
var SHOWCASE_PAGES_PATH = "showcase";
|
|
166
|
+
/** Lists the development dependencies the styles surface adds, frozen. */
|
|
167
|
+
var STYLES_DEV_DEPENDENCIES = Object.freeze({ sass: "^1.105.1" });
|
|
168
|
+
/** Lists the names a styles extension cannot occupy, frozen. */
|
|
169
|
+
var RESERVED_SHEET_NAMES = Object.freeze([
|
|
170
|
+
...ENVIRONMENTS,
|
|
171
|
+
"bin",
|
|
172
|
+
"styles",
|
|
173
|
+
"themes",
|
|
174
|
+
...FRAMEWORKS
|
|
175
|
+
]);
|
|
137
176
|
/**
|
|
138
177
|
* Lists the `Group` values in plan order, frozen.
|
|
139
178
|
*
|
|
@@ -624,15 +663,21 @@ var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
|
624
663
|
"@vitest/browser-playwright": package_default.devDependencies["@vitest/browser-playwright"],
|
|
625
664
|
playwright: package_default.devDependencies.playwright
|
|
626
665
|
});
|
|
666
|
+
/**
|
|
667
|
+
* Names the development dependency a browser or styles surface adds.
|
|
668
|
+
*
|
|
669
|
+
* @remarks
|
|
670
|
+
* The package ships the `browse` binary, an MCP server that drives a rendered page and records
|
|
671
|
+
* journeys, and `.claude/rules/quality.md` § Instruments names its registration.
|
|
672
|
+
* `blueprintToDevDependencies` names the blueprints that receive it.
|
|
673
|
+
*/
|
|
674
|
+
var BROWSE_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/browser": package_default.devDependencies["@orkestrel/browser"] });
|
|
627
675
|
/** Names the development dependency every private `app` environment adds. */
|
|
628
676
|
var APP_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/contract": package_default.dependencies["@orkestrel/contract"] });
|
|
629
|
-
/** Lists the development dependencies a private
|
|
677
|
+
/** Lists the development dependencies a private browser application adds. */
|
|
630
678
|
var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
631
679
|
...SOURCE_BROWSER_DEV_DEPENDENCIES,
|
|
632
|
-
"@orkestrel/html": package_default.devDependencies["@orkestrel/html"]
|
|
633
|
-
"@vitejs/plugin-vue": "^6.0.8",
|
|
634
|
-
vue: "^3.5.40",
|
|
635
|
-
"vue-tsc": "^3.3.7"
|
|
680
|
+
"@orkestrel/html": package_default.devDependencies["@orkestrel/html"]
|
|
636
681
|
});
|
|
637
682
|
/**
|
|
638
683
|
* Names the development dependency used only by the optional single-file showcase build.
|
|
@@ -696,9 +741,7 @@ var CONFIG_TEMPLATES = Object.freeze({
|
|
|
696
741
|
"forceConsistentCasingInFileNames": true,
|
|
697
742
|
"skipLibCheck": true,
|
|
698
743
|
"noEmit": true,
|
|
699
|
-
"paths": {
|
|
700
744
|
{{paths}}
|
|
701
|
-
}
|
|
702
745
|
},
|
|
703
746
|
"exclude": ["node_modules", "dist", "tmp"]
|
|
704
747
|
}
|
|
@@ -815,6 +858,27 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
815
858
|
`
|
|
816
859
|
}),
|
|
817
860
|
factories: Object.freeze({
|
|
861
|
+
sheet: `export function sheetProject(name: string, override?: UserConfig): UserConfig {
|
|
862
|
+
const project: UserConfig = {
|
|
863
|
+
resolve,
|
|
864
|
+
optimizeDeps,
|
|
865
|
+
publicDir: false,
|
|
866
|
+
test: {
|
|
867
|
+
name: { label: name, color: 'magenta' },
|
|
868
|
+
root: resolveWorkspacePath('.'),
|
|
869
|
+
isolate: false,
|
|
870
|
+
setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts', './tests/setupStyles.ts'],
|
|
871
|
+
browser: {
|
|
872
|
+
enabled: true,
|
|
873
|
+
provider: playwright(browserOptions),
|
|
874
|
+
instances: [{ browser: 'chromium', headless: true }],
|
|
875
|
+
},
|
|
876
|
+
fileParallelism: false,
|
|
877
|
+
},
|
|
878
|
+
}
|
|
879
|
+
return mergeOverride(project, override)
|
|
880
|
+
}
|
|
881
|
+
`,
|
|
818
882
|
src: Object.freeze({
|
|
819
883
|
core: `export function srcCore(override?: UserConfig): UserConfig {
|
|
820
884
|
const project: UserConfig = {
|
|
@@ -837,9 +901,51 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
837
901
|
return mergeOverride(project, override)
|
|
838
902
|
}
|
|
839
903
|
`,
|
|
840
|
-
|
|
904
|
+
vue: `function resolveVueFilename(): string {
|
|
905
|
+
return 'index.js'
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
export function srcVue(override?: UserConfig): UserConfig {
|
|
841
909
|
const project: UserConfig = {
|
|
842
910
|
resolve,
|
|
911
|
+
optimizeDeps: { include: [...optimizeDeps.include, 'vue'] },
|
|
912
|
+
publicDir: false,
|
|
913
|
+
plugins: [outputBoundary('dist/src/vue'), environmentBoundary('src/vue'), vue()],
|
|
914
|
+
build: {
|
|
915
|
+
emptyOutDir: true,
|
|
916
|
+
sourcemap: true,
|
|
917
|
+
minify: false,
|
|
918
|
+
lib: {
|
|
919
|
+
entry: resolveWorkspacePath('src/vue/index.ts'),
|
|
920
|
+
formats: ['es'],
|
|
921
|
+
fileName: resolveVueFilename,
|
|
922
|
+
},
|
|
923
|
+
outDir: 'dist/src/vue',
|
|
924
|
+
rolldownOptions: { onLog: enforceBuildLog },
|
|
925
|
+
},
|
|
926
|
+
test: {
|
|
927
|
+
name: { label: 'src:vue', color: 'green' },
|
|
928
|
+
include: ['tests/src/vue/**/*.test.ts'],
|
|
929
|
+
setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],
|
|
930
|
+
browser: {
|
|
931
|
+
enabled: true,
|
|
932
|
+
provider: playwright(browserOptions),
|
|
933
|
+
instances: [{ browser: 'chromium', headless: true }],
|
|
934
|
+
},
|
|
935
|
+
fileParallelism: false,
|
|
936
|
+
},
|
|
937
|
+
}
|
|
938
|
+
return mergeOverride(project, override)
|
|
939
|
+
}
|
|
940
|
+
`,
|
|
941
|
+
browser: `function resolveBrowserFilename(): string {
|
|
942
|
+
return 'index.js'
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
export function srcBrowser(override?: UserConfig): UserConfig {
|
|
946
|
+
const project: UserConfig = {
|
|
947
|
+
resolve,
|
|
948
|
+
optimizeDeps,
|
|
843
949
|
publicDir: false,
|
|
844
950
|
plugins: [outputBoundary('dist/src/browser'), environmentBoundary('src/browser')],
|
|
845
951
|
build: {
|
|
@@ -849,7 +955,7 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
849
955
|
lib: {
|
|
850
956
|
entry: resolveWorkspacePath('src/browser/index.ts'),
|
|
851
957
|
formats: ['es'],
|
|
852
|
-
fileName:
|
|
958
|
+
fileName: resolveBrowserFilename,
|
|
853
959
|
},
|
|
854
960
|
outDir: 'dist/src/browser',
|
|
855
961
|
rolldownOptions: {
|
|
@@ -874,7 +980,11 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
874
980
|
return mergeOverride(project, override)
|
|
875
981
|
}
|
|
876
982
|
`,
|
|
877
|
-
server: `
|
|
983
|
+
server: `function resolveServerFilename(format: string): string {
|
|
984
|
+
return format === 'es' ? 'index.js' : 'index.cjs'
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
export function srcServer(override?: UserConfig): UserConfig {
|
|
878
988
|
const project: UserConfig = {
|
|
879
989
|
resolve,
|
|
880
990
|
publicDir: false,
|
|
@@ -886,7 +996,7 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
886
996
|
lib: {
|
|
887
997
|
entry: resolveWorkspacePath('src/server/index.ts'),
|
|
888
998
|
formats: ['es', 'cjs'],
|
|
889
|
-
fileName:
|
|
999
|
+
fileName: resolveServerFilename,
|
|
890
1000
|
},
|
|
891
1001
|
outDir: 'dist/src/server',
|
|
892
1002
|
target: 'node22',
|
|
@@ -908,7 +1018,15 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
908
1018
|
return mergeOverride(project, override)
|
|
909
1019
|
}
|
|
910
1020
|
`,
|
|
911
|
-
bin: `
|
|
1021
|
+
bin: `function resolveBinFilename(): string {
|
|
1022
|
+
return 'main.js'
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
function resolveBinExternal(id: string): boolean {
|
|
1026
|
+
return id.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] })
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
export function srcBin(override?: UserConfig): UserConfig {
|
|
912
1030
|
const project: UserConfig = {
|
|
913
1031
|
resolve,
|
|
914
1032
|
publicDir: false,
|
|
@@ -920,17 +1038,13 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
920
1038
|
lib: {
|
|
921
1039
|
entry: resolveWorkspacePath('${BIN_ENTRY_PATH}'),
|
|
922
1040
|
formats: ['es'],
|
|
923
|
-
fileName:
|
|
1041
|
+
fileName: resolveBinFilename,
|
|
924
1042
|
},
|
|
925
1043
|
outDir: 'dist/bin',
|
|
926
1044
|
target: 'node22',
|
|
927
1045
|
rolldownOptions: {
|
|
928
1046
|
onLog: enforceBuildLog,
|
|
929
|
-
external:
|
|
930
|
-
id.startsWith('node:') ||
|
|
931
|
-
id.startsWith('@orkestrel/') ||
|
|
932
|
-
id.startsWith('@src/') ||
|
|
933
|
-
peers.some((peer) => id === peer || id.startsWith(peer + '/')),
|
|
1047
|
+
external: resolveBinExternal,
|
|
934
1048
|
},
|
|
935
1049
|
},
|
|
936
1050
|
test: {
|
|
@@ -970,7 +1084,8 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
970
1084
|
const output = 'dist/app/browser'
|
|
971
1085
|
const project: UserConfig = {
|
|
972
1086
|
resolve,
|
|
973
|
-
|
|
1087
|
+
optimizeDeps,
|
|
1088
|
+
plugins: [outputBoundary(output), environmentBoundary('app/browser')],
|
|
974
1089
|
root: resolveWorkspacePath('app/browser'),
|
|
975
1090
|
publicDir: false,
|
|
976
1091
|
build: {
|
|
@@ -999,20 +1114,47 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
999
1114
|
return mergeOverride(project, override)
|
|
1000
1115
|
}
|
|
1001
1116
|
{{showcaseFactory}}{{journeyFactory}}`,
|
|
1117
|
+
vue: `export function appVue(override?: UserConfig): UserConfig {
|
|
1118
|
+
const output = 'dist/app/vue'
|
|
1119
|
+
const browser = appBrowser()
|
|
1120
|
+
const project: UserConfig = {
|
|
1121
|
+
...browser,
|
|
1122
|
+
optimizeDeps: { include: [...optimizeDeps.include, 'vue'] },
|
|
1123
|
+
plugins: [outputBoundary(output), environmentBoundary('app/vue'), vue()],
|
|
1124
|
+
root: resolveWorkspacePath('app/vue'),
|
|
1125
|
+
build: {
|
|
1126
|
+
...browser.build,
|
|
1127
|
+
outDir: resolveWorkspacePath(output),
|
|
1128
|
+
rolldownOptions: {
|
|
1129
|
+
...browser.build?.rolldownOptions,
|
|
1130
|
+
input: resolveWorkspacePath('app/vue/index.html'),
|
|
1131
|
+
},
|
|
1132
|
+
},
|
|
1133
|
+
test: {
|
|
1134
|
+
...browser.test,
|
|
1135
|
+
name: { label: 'app:vue', color: 'magenta' },
|
|
1136
|
+
include: ['tests/app/vue/**/*.test.ts'],
|
|
1137
|
+
{{journeyExclude}} },
|
|
1138
|
+
}
|
|
1139
|
+
return mergeOverride(project, override)
|
|
1140
|
+
}
|
|
1141
|
+
`,
|
|
1002
1142
|
journey: `
|
|
1003
1143
|
// Replace the journey fields directly: merging would concatenate the ordinary include
|
|
1004
1144
|
// and retain the exclusion of the journey suite.
|
|
1005
1145
|
export function appJourney(
|
|
1006
1146
|
variant: JourneyVariant,
|
|
1007
1147
|
variants: readonly JourneyVariant[],
|
|
1148
|
+
mode?: string,
|
|
1008
1149
|
): UserConfig {
|
|
1009
|
-
const
|
|
1150
|
+
const application = resolveApplication(mode, applications)
|
|
1151
|
+
const browser = applications[application]()
|
|
1010
1152
|
return {
|
|
1011
1153
|
...browser,
|
|
1012
1154
|
test: {
|
|
1013
1155
|
...browser.test,
|
|
1014
1156
|
name: { label: \`journey:\${variant.name}\`, color: 'green' },
|
|
1015
|
-
include: [
|
|
1157
|
+
include: [\`tests/app/\${application}/integration.test.ts\`],
|
|
1016
1158
|
exclude: [],
|
|
1017
1159
|
provide: { variant: variant.name, variants, capture },
|
|
1018
1160
|
browser: {
|
|
@@ -1025,8 +1167,39 @@ export function appJourney(
|
|
|
1025
1167
|
}
|
|
1026
1168
|
`,
|
|
1027
1169
|
showcase: `
|
|
1028
|
-
|
|
1029
|
-
|
|
1170
|
+
const showcaseStamp: PluginOption = {
|
|
1171
|
+
name: 'orkestrel-showcase-html',
|
|
1172
|
+
enforce: 'post',
|
|
1173
|
+
generateBundle(_, bundle) {
|
|
1174
|
+
for (const file of Object.values(bundle)) {
|
|
1175
|
+
if (
|
|
1176
|
+
file.type === 'asset' &&
|
|
1177
|
+
typeof file.source === 'string' &&
|
|
1178
|
+
file.fileName.endsWith('.html')
|
|
1179
|
+
) {
|
|
1180
|
+
file.source = stampPage(file.source)
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
function createShowcaseNaming(application: string): PluginOption {
|
|
1187
|
+
return {
|
|
1188
|
+
name: 'orkestrel-showcase-name',
|
|
1189
|
+
enforce: 'post',
|
|
1190
|
+
writeBundle(options) {
|
|
1191
|
+
if (options.dir === undefined) throw new Error('The showcase output is absent.')
|
|
1192
|
+
renameSync(
|
|
1193
|
+
resolvePath(options.dir, 'index.html'),
|
|
1194
|
+
resolvePath(options.dir, application + '.html'),
|
|
1195
|
+
)
|
|
1196
|
+
},
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
export function appShowcase(mode: string, override?: UserConfig): UserConfig {
|
|
1201
|
+
const application = resolveApplication(mode, applications)
|
|
1202
|
+
const output = 'showcase'
|
|
1030
1203
|
const showcase: UserConfig = {
|
|
1031
1204
|
plugins: [
|
|
1032
1205
|
outputBoundary(output),
|
|
@@ -1034,19 +1207,8 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1034
1207
|
removeViteModuleLoader: true,
|
|
1035
1208
|
useRecommendedBuildConfig: true,
|
|
1036
1209
|
}),
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
transformIndexHtml: {
|
|
1040
|
-
order: 'post',
|
|
1041
|
-
handler(html) {
|
|
1042
|
-
const stamp = new Date().toISOString()
|
|
1043
|
-
return html.replace(
|
|
1044
|
-
'</head>',
|
|
1045
|
-
'\t\t<meta name="build-id" content="' + stamp + '" />\\n\t</head>',
|
|
1046
|
-
)
|
|
1047
|
-
},
|
|
1048
|
-
},
|
|
1049
|
-
},
|
|
1210
|
+
showcaseStamp,
|
|
1211
|
+
createShowcaseNaming(application),
|
|
1050
1212
|
],
|
|
1051
1213
|
build: {
|
|
1052
1214
|
// The \`appBrowser\` factory sets \`assetsInlineLimit\` to 0, so every asset becomes
|
|
@@ -1055,6 +1217,7 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1055
1217
|
// true, so this line takes effect only in a workspace that turns that option off.
|
|
1056
1218
|
assetsInlineLimit: 4096,
|
|
1057
1219
|
cssMinify: 'lightningcss',
|
|
1220
|
+
emptyOutDir: false,
|
|
1058
1221
|
minify: 'oxc',
|
|
1059
1222
|
modulePreload: false,
|
|
1060
1223
|
outDir: resolveWorkspacePath(output),
|
|
@@ -1063,10 +1226,18 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1063
1226
|
target: 'esnext',
|
|
1064
1227
|
},
|
|
1065
1228
|
}
|
|
1066
|
-
return
|
|
1229
|
+
return applications[application](mergeOverride(showcase, override))
|
|
1067
1230
|
}
|
|
1068
1231
|
`,
|
|
1069
|
-
server: `
|
|
1232
|
+
server: `function resolveAppFilename(): string {
|
|
1233
|
+
return 'main.cjs'
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
function resolveAppExternal(id: string): boolean {
|
|
1237
|
+
return id.startsWith('node:')
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
export function appServer(override?: UserConfig): UserConfig {
|
|
1070
1241
|
const project: UserConfig = {
|
|
1071
1242
|
resolve,
|
|
1072
1243
|
publicDir: false,
|
|
@@ -1076,13 +1247,13 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1076
1247
|
lib: {
|
|
1077
1248
|
entry: resolveWorkspacePath('app/server/main.ts'),
|
|
1078
1249
|
formats: ['cjs'],
|
|
1079
|
-
fileName:
|
|
1250
|
+
fileName: resolveAppFilename,
|
|
1080
1251
|
},
|
|
1081
1252
|
outDir: resolveWorkspacePath('dist/app/server'),
|
|
1082
1253
|
target: 'node22',
|
|
1083
1254
|
rolldownOptions: {
|
|
1084
1255
|
onLog: enforceBuildLog,
|
|
1085
|
-
external:
|
|
1256
|
+
external: resolveAppExternal,
|
|
1086
1257
|
},
|
|
1087
1258
|
},
|
|
1088
1259
|
test: {
|
|
@@ -1135,8 +1306,10 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1135
1306
|
test: {
|
|
1136
1307
|
name: { label: 'setup', color: 'white' },
|
|
1137
1308
|
include: ['tests/setup*.test.ts'],
|
|
1138
|
-
exclude: ['tests/setupBrowser.test.ts'],
|
|
1309
|
+
exclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],
|
|
1139
1310
|
setupFiles: ['./tests/setup.ts'],
|
|
1311
|
+
pool: 'threads',
|
|
1312
|
+
isolate: false,
|
|
1140
1313
|
environment: 'node',
|
|
1141
1314
|
browser: { enabled: false },
|
|
1142
1315
|
},
|
|
@@ -1147,9 +1320,10 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1147
1320
|
browser: `export function setupBrowser(override?: UserConfig): UserConfig {
|
|
1148
1321
|
const project: UserConfig = {
|
|
1149
1322
|
resolve,
|
|
1323
|
+
{{optimization}},
|
|
1150
1324
|
{{plugins}} test: {
|
|
1151
1325
|
name: { label: 'setup:browser', color: 'blue' },
|
|
1152
|
-
include: ['tests/setupBrowser.test.ts'],
|
|
1326
|
+
include: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],
|
|
1153
1327
|
setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],
|
|
1154
1328
|
{{global}} browser: {
|
|
1155
1329
|
enabled: true,
|
|
@@ -1203,7 +1377,9 @@ export function conformance(override?: UserConfig): UserConfig {
|
|
|
1203
1377
|
test: {
|
|
1204
1378
|
name: { label: 'conformance', color: 'magenta' },
|
|
1205
1379
|
include: ['${CONFORMANCE_TEST_PATH}'],
|
|
1206
|
-
setupFiles: ['./tests/setup.ts'],
|
|
1380
|
+
setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
1381
|
+
pool: 'threads',
|
|
1382
|
+
isolate: false,
|
|
1207
1383
|
environment: 'node',
|
|
1208
1384
|
browser: { enabled: false },
|
|
1209
1385
|
},
|
|
@@ -1269,7 +1445,17 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1269
1445
|
return mergeOverride(project, override)
|
|
1270
1446
|
}
|
|
1271
1447
|
`,
|
|
1272
|
-
integration:
|
|
1448
|
+
integration: Object.freeze({
|
|
1449
|
+
sheet: `export function integration(override?: UserConfig): UserConfig {
|
|
1450
|
+
const project = sheetProject('integration', {
|
|
1451
|
+
test: {
|
|
1452
|
+
include: ['tests/integration.test.ts'],
|
|
1453
|
+
{{global}} },
|
|
1454
|
+
})
|
|
1455
|
+
return mergeOverride(project, override)
|
|
1456
|
+
}
|
|
1457
|
+
`,
|
|
1458
|
+
module: `export function integration(override?: UserConfig): UserConfig {
|
|
1273
1459
|
const project: UserConfig = {
|
|
1274
1460
|
resolve,
|
|
1275
1461
|
test: {
|
|
@@ -1282,8 +1468,51 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1282
1468
|
return mergeOverride(project, override)
|
|
1283
1469
|
}
|
|
1284
1470
|
`
|
|
1471
|
+
})
|
|
1285
1472
|
}),
|
|
1286
1473
|
tsconfigs: Object.freeze({
|
|
1474
|
+
vue: Object.freeze({
|
|
1475
|
+
src: `{
|
|
1476
|
+
"extends": "../../tsconfig.json",
|
|
1477
|
+
"compilerOptions": {
|
|
1478
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
1479
|
+
"types": ["vite/client"],
|
|
1480
|
+
"noEmit": false,
|
|
1481
|
+
"declaration": true,
|
|
1482
|
+
"emitDeclarationOnly": true,
|
|
1483
|
+
"rootDir": "../../src",
|
|
1484
|
+
"outDir": "../../dist/src"
|
|
1485
|
+
},
|
|
1486
|
+
"include": [
|
|
1487
|
+
"../../src/vue/**/*.cts",
|
|
1488
|
+
"../../src/vue/**/*.mts",
|
|
1489
|
+
"../../src/vue/**/*.ts",
|
|
1490
|
+
"../../src/vue/**/*.tsx"
|
|
1491
|
+
]
|
|
1492
|
+
}
|
|
1493
|
+
`,
|
|
1494
|
+
app: `{
|
|
1495
|
+
"extends": "../../tsconfig.json",
|
|
1496
|
+
"compilerOptions": {
|
|
1497
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
1498
|
+
"types": ["vite/client", "vue"]
|
|
1499
|
+
},
|
|
1500
|
+
"include": [
|
|
1501
|
+
{{include}}
|
|
1502
|
+
]
|
|
1503
|
+
}
|
|
1504
|
+
`
|
|
1505
|
+
}),
|
|
1506
|
+
sheet: `{
|
|
1507
|
+
"extends": "../../tsconfig.json",
|
|
1508
|
+
"compilerOptions": {
|
|
1509
|
+
"lib": ["ESNext"],
|
|
1510
|
+
"types": ["vite/client"],
|
|
1511
|
+
"noEmit": true
|
|
1512
|
+
},
|
|
1513
|
+
"include": ["../../src/{{name}}/**/*.ts"]
|
|
1514
|
+
}
|
|
1515
|
+
`,
|
|
1287
1516
|
src: Object.freeze({
|
|
1288
1517
|
core: `{
|
|
1289
1518
|
"extends": "../../tsconfig.json",
|
|
@@ -1367,7 +1596,7 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1367
1596
|
"extends": "../../tsconfig.json",
|
|
1368
1597
|
"compilerOptions": {
|
|
1369
1598
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
1370
|
-
"types": ["vite/client"
|
|
1599
|
+
"types": ["vite/client"]
|
|
1371
1600
|
},
|
|
1372
1601
|
"include": [
|
|
1373
1602
|
{{include}}
|
|
@@ -1417,9 +1646,38 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1417
1646
|
`
|
|
1418
1647
|
}),
|
|
1419
1648
|
vites: Object.freeze({
|
|
1649
|
+
sheet: `import { defineConfig } from 'vitest/config'
|
|
1650
|
+
import { outputBoundary } from '../helpers.js'
|
|
1651
|
+
import { resolveWorkspacePath, sheetProject } from '../../vite.config.ts'
|
|
1652
|
+
|
|
1653
|
+
export default defineConfig((invocation) => {
|
|
1654
|
+
const project = sheetProject('src:{{label}}', {
|
|
1655
|
+
plugins: [outputBoundary('dist/src/{{name}}')],
|
|
1656
|
+
build: {
|
|
1657
|
+
outDir: 'dist/src/{{name}}',
|
|
1658
|
+
emptyOutDir: true,
|
|
1659
|
+
// Preserve the authored layer-order statement in the published sheet.
|
|
1660
|
+
cssMinify: false,
|
|
1661
|
+
lib: {
|
|
1662
|
+
entry: resolveWorkspacePath('src/{{name}}/sheet.ts'),
|
|
1663
|
+
formats: ['es'],
|
|
1664
|
+
fileName: 'index',
|
|
1665
|
+
cssFileName: 'index',
|
|
1666
|
+
},
|
|
1667
|
+
},
|
|
1668
|
+
test: { include: ['tests/src/{{name}}/**/*.test.ts'] },
|
|
1669
|
+
})
|
|
1670
|
+
return { ...project, mode: invocation.mode }
|
|
1671
|
+
})
|
|
1672
|
+
`,
|
|
1420
1673
|
src: Object.freeze({
|
|
1421
1674
|
core: `import { defineConfig } from 'vite'
|
|
1422
|
-
import {
|
|
1675
|
+
import {
|
|
1676
|
+
declarationRollup,
|
|
1677
|
+
environmentBoundary,
|
|
1678
|
+
outputBoundary,
|
|
1679
|
+
resolveExternal,
|
|
1680
|
+
} from '../helpers.js'
|
|
1423
1681
|
import { peers, srcCore, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1424
1682
|
|
|
1425
1683
|
export default defineConfig(
|
|
@@ -1440,11 +1698,43 @@ export default defineConfig(
|
|
|
1440
1698
|
fileName: (format: string) => (format === 'es' ? 'index.js' : 'index.cjs'),
|
|
1441
1699
|
},
|
|
1442
1700
|
outDir: 'dist/src/core',
|
|
1701
|
+
rolldownOptions: {
|
|
1702
|
+
external: (id: string) => resolveExternal(id, { peers, refused: [], siblings: [] }),
|
|
1703
|
+
},
|
|
1704
|
+
},
|
|
1705
|
+
}),
|
|
1706
|
+
)
|
|
1707
|
+
`,
|
|
1708
|
+
vue: `import { defineConfig } from 'vite'
|
|
1709
|
+
import {
|
|
1710
|
+
declarationRollup,
|
|
1711
|
+
resolveExternal,
|
|
1712
|
+
rewriteBrowserSpecifier,
|
|
1713
|
+
rewriteCoreSpecifier,
|
|
1714
|
+
} from '../helpers.js'
|
|
1715
|
+
import { peers, srcVue, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1716
|
+
|
|
1717
|
+
const siblings = {
|
|
1718
|
+
{{siblings}}
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
export default defineConfig(
|
|
1722
|
+
srcVue({
|
|
1723
|
+
plugins: [
|
|
1724
|
+
declarationRollup({
|
|
1725
|
+
project: resolveWorkspacePath('configs/src/tsconfig.vue.json'),
|
|
1726
|
+
rewrite: (content) => rewriteBrowserSpecifier(rewriteCoreSpecifier(content)),
|
|
1727
|
+
}),
|
|
1728
|
+
],
|
|
1729
|
+
build: {
|
|
1443
1730
|
rolldownOptions: {
|
|
1444
1731
|
external: (id: string) =>
|
|
1445
|
-
id
|
|
1446
|
-
|
|
1447
|
-
|
|
1732
|
+
resolveExternal(id, {
|
|
1733
|
+
peers,
|
|
1734
|
+
refused: {{refused}},
|
|
1735
|
+
siblings: Object.keys(siblings),
|
|
1736
|
+
}),
|
|
1737
|
+
output: { paths: siblings },
|
|
1448
1738
|
},
|
|
1449
1739
|
},
|
|
1450
1740
|
}),
|
|
@@ -1486,7 +1776,8 @@ export default defineConfig(
|
|
|
1486
1776
|
`
|
|
1487
1777
|
}),
|
|
1488
1778
|
bin: `import { defineConfig } from 'vite'
|
|
1489
|
-
import {
|
|
1779
|
+
import { resolveExternal } from '../helpers.js'
|
|
1780
|
+
import { peers, srcBin } from '../../vite.config.ts'
|
|
1490
1781
|
|
|
1491
1782
|
// The \`scaffold\` executable build — a single ESM lib file, no declarations (an
|
|
1492
1783
|
// executable ships no types), with the \`#!/usr/bin/env node\` shebang re-emitted through
|
|
@@ -1497,6 +1788,8 @@ export default defineConfig(
|
|
|
1497
1788
|
srcBin({
|
|
1498
1789
|
build: {
|
|
1499
1790
|
rolldownOptions: {
|
|
1791
|
+
external: (id: string) =>
|
|
1792
|
+
id.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] }),
|
|
1500
1793
|
output: {
|
|
1501
1794
|
banner: '#!/usr/bin/env node',
|
|
1502
1795
|
{{paths}}
|
|
@@ -1507,6 +1800,11 @@ export default defineConfig(
|
|
|
1507
1800
|
)
|
|
1508
1801
|
`,
|
|
1509
1802
|
app: Object.freeze({
|
|
1803
|
+
vue: `import { defineConfig } from 'vite'
|
|
1804
|
+
import { appVue } from '../../vite.config.ts'
|
|
1805
|
+
|
|
1806
|
+
export default defineConfig(appVue())
|
|
1807
|
+
`,
|
|
1510
1808
|
browser: `import { defineConfig } from 'vite'
|
|
1511
1809
|
import { appBrowser } from '../../vite.config.ts'
|
|
1512
1810
|
|
|
@@ -1520,7 +1818,7 @@ export default defineConfig(appServer())
|
|
|
1520
1818
|
showcase: `import { defineConfig } from 'vite'
|
|
1521
1819
|
import { appShowcase } from '../../vite.config.ts'
|
|
1522
1820
|
|
|
1523
|
-
export default defineConfig(appShowcase())
|
|
1821
|
+
export default defineConfig(({ mode }) => appShowcase(mode))
|
|
1524
1822
|
`,
|
|
1525
1823
|
journey: `import type { JourneyVariant } from '@orkestrel/test'
|
|
1526
1824
|
import { defineConfig } from 'vitest/config'
|
|
@@ -1532,11 +1830,11 @@ const VARIANTS: readonly JourneyVariant[] = Object.freeze([
|
|
|
1532
1830
|
{ name: 'compact', width: 390, height: 844 },
|
|
1533
1831
|
])
|
|
1534
1832
|
|
|
1535
|
-
export default defineConfig({
|
|
1833
|
+
export default defineConfig(({ mode }) => ({
|
|
1536
1834
|
test: {
|
|
1537
|
-
projects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS)),
|
|
1835
|
+
projects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS, mode)),
|
|
1538
1836
|
},
|
|
1539
|
-
})
|
|
1837
|
+
}))
|
|
1540
1838
|
`
|
|
1541
1839
|
})
|
|
1542
1840
|
}),
|
|
@@ -1879,7 +2177,38 @@ export function resolveBrowser(
|
|
|
1879
2177
|
*/
|
|
1880
2178
|
var ARTIFACT_TEMPLATES = Object.freeze({
|
|
1881
2179
|
source: Object.freeze({
|
|
2180
|
+
sheet: Object.freeze({
|
|
2181
|
+
"index.scss": "@use 'tokens';\n@use 'elements';\n@use 'components';\n@use 'utilities';\n",
|
|
2182
|
+
"_tokens.scss": "@layer theme, reset, base, elements, components, utilities;\n",
|
|
2183
|
+
"_mixins.scss": "",
|
|
2184
|
+
"elements/_index.scss": "",
|
|
2185
|
+
"components/_index.scss": "",
|
|
2186
|
+
"utilities/_index.scss": "",
|
|
2187
|
+
"sheet.ts": "import './index.scss'\n",
|
|
2188
|
+
"index.ts": "export * from './sheet.js'\n"
|
|
2189
|
+
}),
|
|
2190
|
+
themes: Object.freeze({
|
|
2191
|
+
"index.scss": "@use '../tokens';\n@use 'default';\n",
|
|
2192
|
+
"_default.scss": "",
|
|
2193
|
+
"sheet.ts": "import './index.scss'\n"
|
|
2194
|
+
}),
|
|
1882
2195
|
empty: "",
|
|
2196
|
+
barrel: "// TODO: [Feature] Export the browser extension API.\n",
|
|
2197
|
+
main: `document.body
|
|
2198
|
+
.appendChild(document.createElement('main'))
|
|
2199
|
+
.appendChild(document.createElement('h1')).textContent ={{heading}}
|
|
2200
|
+
`,
|
|
2201
|
+
vue: Object.freeze({
|
|
2202
|
+
"main.ts": `import { createApp } from 'vue'
|
|
2203
|
+
import App from './App.vue'
|
|
2204
|
+
|
|
2205
|
+
createApp(App).mount(document.body.appendChild(document.createElement('main')))
|
|
2206
|
+
`,
|
|
2207
|
+
"App.vue": `<template>
|
|
2208
|
+
<h1>{{heading}}</h1>
|
|
2209
|
+
</template>
|
|
2210
|
+
`
|
|
2211
|
+
}),
|
|
1883
2212
|
browser: `<!doctype html>
|
|
1884
2213
|
<html lang="en">
|
|
1885
2214
|
<head>
|
|
@@ -1894,9 +2223,263 @@ var ARTIFACT_TEMPLATES = Object.freeze({
|
|
|
1894
2223
|
`
|
|
1895
2224
|
}),
|
|
1896
2225
|
tests: Object.freeze({
|
|
2226
|
+
journey: `import {
|
|
2227
|
+
ACCESSIBLE_ROLES,
|
|
2228
|
+
createPortfolio,
|
|
2229
|
+
expandCaptures,
|
|
2230
|
+
isRendered,
|
|
2231
|
+
readRefusal,
|
|
2232
|
+
readStyle,
|
|
2233
|
+
} from '@orkestrel/test/browser'
|
|
2234
|
+
{{imports}}import { page } from 'vitest/browser'
|
|
2235
|
+
import { describe, expect, inject, it } from 'vitest'
|
|
2236
|
+
|
|
2237
|
+
const VARIANT = inject('variant')
|
|
2238
|
+
const VARIANTS = inject('variants')
|
|
2239
|
+
const CAPTURE = inject('capture')
|
|
2240
|
+
|
|
2241
|
+
describe('{{application}} arrival journey', () => {
|
|
2242
|
+
it('proves the declared arrival families', async () => {
|
|
2243
|
+
const families = new Set(['Journey', 'Refusal', 'Matrix', ...(CAPTURE ? ['Capture'] : [])])
|
|
2244
|
+
const proven = new Set<string>()
|
|
2245
|
+
const states = ['{{application}}-arrival']
|
|
2246
|
+
const placed = new Set<string>()
|
|
2247
|
+
const portfolio = createPortfolio({
|
|
2248
|
+
states,
|
|
2249
|
+
variants: VARIANTS,
|
|
2250
|
+
variant: VARIANT,
|
|
2251
|
+
directory: '../../../tmp/captures/states',
|
|
2252
|
+
enabled: CAPTURE,
|
|
2253
|
+
})
|
|
2254
|
+
{{mount}} try {
|
|
2255
|
+
{{arrival}} const heading = page
|
|
2256
|
+
.getByRole('heading', {
|
|
2257
|
+
name: {{heading}},
|
|
2258
|
+
exact: true,
|
|
2259
|
+
level: 1,
|
|
2260
|
+
})
|
|
2261
|
+
.element()
|
|
2262
|
+
expect(isRendered(heading)).toBe(true)
|
|
2263
|
+
proven.add('Journey')
|
|
2264
|
+
await portfolio.place('{{application}}-arrival')
|
|
2265
|
+
placed.add('{{application}}-arrival')
|
|
2266
|
+
|
|
2267
|
+
for (const role of ACCESSIBLE_ROLES) expect(page.getByRole(role).elements()).toEqual([])
|
|
2268
|
+
expect(readRefusal('Continue')).toBe(
|
|
2269
|
+
'No interactive element has the accessible name "Continue"',
|
|
2270
|
+
)
|
|
2271
|
+
proven.add('Refusal')
|
|
2272
|
+
|
|
2273
|
+
const measured = new Set<string>()
|
|
2274
|
+
for (const variant of VARIANTS) {
|
|
2275
|
+
await page.viewport(variant.width, variant.height)
|
|
2276
|
+
expect(readStyle(heading, 'display')).toBe('block')
|
|
2277
|
+
expect(window.innerWidth).toBe(variant.width)
|
|
2278
|
+
measured.add(variant.name)
|
|
2279
|
+
}
|
|
2280
|
+
expect(measured).toEqual(new Set(VARIANTS.map(({ name }) => name)))
|
|
2281
|
+
proven.add('Matrix')
|
|
2282
|
+
|
|
2283
|
+
const files = expandCaptures(states, VARIANTS)
|
|
2284
|
+
expect(portfolio.files).toEqual(files)
|
|
2285
|
+
expect(new Set(files).size).toBe(states.length * VARIANTS.length)
|
|
2286
|
+
expect(placed).toEqual(new Set(states))
|
|
2287
|
+
const expected = CAPTURE
|
|
2288
|
+
? expandCaptures(
|
|
2289
|
+
states,
|
|
2290
|
+
VARIANTS.filter(({ name }) => name === VARIANT),
|
|
2291
|
+
)
|
|
2292
|
+
: []
|
|
2293
|
+
expect(portfolio.paths.map((path) => path.replaceAll('\\\\', '/').split('/').at(-1))).toEqual(
|
|
2294
|
+
expected,
|
|
2295
|
+
)
|
|
2296
|
+
if (CAPTURE) proven.add('Capture')
|
|
2297
|
+
expect(proven).toEqual(families)
|
|
2298
|
+
} finally {
|
|
2299
|
+
{{cleanup}} const variant = VARIANTS.find(({ name }) => name === VARIANT)
|
|
2300
|
+
if (variant !== undefined) await page.viewport(variant.width, variant.height)
|
|
2301
|
+
}
|
|
2302
|
+
})
|
|
2303
|
+
})
|
|
2304
|
+
`,
|
|
2305
|
+
browser: `import type { JourneyVariant } from '@orkestrel/test'
|
|
2306
|
+
|
|
2307
|
+
declare module 'vitest' {
|
|
2308
|
+
export interface ProvidedContext {
|
|
2309
|
+
readonly variant: string
|
|
2310
|
+
readonly variants: readonly JourneyVariant[]
|
|
2311
|
+
readonly capture: boolean
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
`,
|
|
2315
|
+
sheet: `import sheet from '{{root}}dist/src/{{name}}/index.css?raw'
|
|
2316
|
+
import { describe, expect, it } from 'vitest'
|
|
2317
|
+
import { adoptSheet, readLayerNames } from '{{setup}}'
|
|
2318
|
+
|
|
2319
|
+
describe('{{name}} entry', () => {
|
|
2320
|
+
it('opens with the declared cascade order', () => {
|
|
2321
|
+
const adopted = adoptSheet(sheet)
|
|
2322
|
+
try {
|
|
2323
|
+
expect(adopted.sheet.cssRules[0]?.cssText).toBe(
|
|
2324
|
+
'@layer theme, reset, base, elements, components, utilities;',
|
|
2325
|
+
)
|
|
2326
|
+
expect(readLayerNames(adopted.sheet).slice(0, 6)).toEqual([
|
|
2327
|
+
'theme',
|
|
2328
|
+
'reset',
|
|
2329
|
+
'base',
|
|
2330
|
+
'elements',
|
|
2331
|
+
'components',
|
|
2332
|
+
'utilities',
|
|
2333
|
+
])
|
|
2334
|
+
} finally {
|
|
2335
|
+
adopted.release()
|
|
2336
|
+
}
|
|
2337
|
+
})
|
|
2338
|
+
})
|
|
2339
|
+
`,
|
|
2340
|
+
styles: Object.freeze({
|
|
2341
|
+
module: `/** Carries a CSSOM rule and its enclosing layer. */
|
|
2342
|
+
export interface SheetEntry {
|
|
2343
|
+
readonly rule: CSSRule
|
|
2344
|
+
readonly layer: string | undefined
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2347
|
+
/** Describes an adopted stylesheet and its idempotent release operation. */
|
|
2348
|
+
export interface SheetAdoption {
|
|
2349
|
+
readonly sheet: CSSStyleSheet
|
|
2350
|
+
release(): void
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
/**
|
|
2354
|
+
* Adopts CSS text into the document with an idempotent release operation.
|
|
2355
|
+
* @param text - The compiled sheet text.
|
|
2356
|
+
* @returns The adopted sheet and its release operation.
|
|
2357
|
+
* @example
|
|
2358
|
+
* \`\`\`ts
|
|
2359
|
+
* const adopted = adoptSheet('.sample { color: red }')
|
|
2360
|
+
* adopted.release()
|
|
2361
|
+
* \`\`\`
|
|
2362
|
+
*/
|
|
2363
|
+
export function adoptSheet(text: string): SheetAdoption {
|
|
2364
|
+
const sheet = new CSSStyleSheet()
|
|
2365
|
+
sheet.replaceSync(text)
|
|
2366
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]
|
|
2367
|
+
return {
|
|
2368
|
+
sheet,
|
|
2369
|
+
release: () => {
|
|
2370
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
|
|
2371
|
+
(candidate) => candidate !== sheet,
|
|
2372
|
+
)
|
|
2373
|
+
},
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
/**
|
|
2378
|
+
* Reads layer statements and blocks in declaration order, including repeated names.
|
|
2379
|
+
* @param sheet - The parsed sheet.
|
|
2380
|
+
* @returns Qualified layer names, with an empty name for an anonymous layer.
|
|
2381
|
+
* @example
|
|
2382
|
+
* \`\`\`ts
|
|
2383
|
+
* readLayerNames(new CSSStyleSheet()) // []
|
|
2384
|
+
* \`\`\`
|
|
2385
|
+
*/
|
|
2386
|
+
export function readLayerNames(sheet: CSSStyleSheet): readonly string[] {
|
|
2387
|
+
const pending: SheetEntry[] = Array.from(sheet.cssRules, (rule) => ({
|
|
2388
|
+
rule,
|
|
2389
|
+
layer: undefined,
|
|
2390
|
+
})).reverse()
|
|
2391
|
+
const names: string[] = []
|
|
2392
|
+
while (pending.length > 0) {
|
|
2393
|
+
const entry = pending.pop()
|
|
2394
|
+
if (entry === undefined) break
|
|
2395
|
+
const { rule, layer } = entry
|
|
2396
|
+
const declared =
|
|
2397
|
+
rule instanceof CSSLayerStatementRule
|
|
2398
|
+
? rule.nameList
|
|
2399
|
+
: rule instanceof CSSLayerBlockRule
|
|
2400
|
+
? [rule.name]
|
|
2401
|
+
: []
|
|
2402
|
+
for (const name of declared) names.push(layer === undefined ? name : layer + '.' + name)
|
|
2403
|
+
if (!(rule instanceof CSSGroupingRule)) continue
|
|
2404
|
+
const parent =
|
|
2405
|
+
rule instanceof CSSLayerBlockRule
|
|
2406
|
+
? layer === undefined
|
|
2407
|
+
? rule.name
|
|
2408
|
+
: layer + '.' + rule.name
|
|
2409
|
+
: layer
|
|
2410
|
+
for (const child of Array.from(rule.cssRules).reverse()) {
|
|
2411
|
+
pending.push({ rule: child, layer: parent })
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
return names
|
|
2415
|
+
}
|
|
2416
|
+
`,
|
|
2417
|
+
proof: `import type { SheetAdoption } from './setupStyles.js'
|
|
2418
|
+
import { describe, expect, it } from 'vitest'
|
|
2419
|
+
import { adoptSheet, readLayerNames } from './setupStyles.js'
|
|
2420
|
+
|
|
2421
|
+
describe('CSSOM instruments', () => {
|
|
2422
|
+
it('adopts and releases only its own sheet, including repeated release', () => {
|
|
2423
|
+
const previous = [...document.adoptedStyleSheets]
|
|
2424
|
+
const first: SheetAdoption = adoptSheet('.sample { color: red }')
|
|
2425
|
+
try {
|
|
2426
|
+
const second = adoptSheet('.other { display: block }')
|
|
2427
|
+
try {
|
|
2428
|
+
expect(document.adoptedStyleSheets).toEqual([...previous, first.sheet, second.sheet])
|
|
2429
|
+
expect(first.sheet.cssRules.length).toBe(1)
|
|
2430
|
+
first.release()
|
|
2431
|
+
first.release()
|
|
2432
|
+
expect(document.adoptedStyleSheets).toEqual([...previous, second.sheet])
|
|
2433
|
+
} finally {
|
|
2434
|
+
second.release()
|
|
2435
|
+
}
|
|
2436
|
+
} finally {
|
|
2437
|
+
first.release()
|
|
2438
|
+
}
|
|
2439
|
+
expect(document.adoptedStyleSheets).toEqual(previous)
|
|
2440
|
+
})
|
|
2441
|
+
|
|
2442
|
+
it('reads statements, blocks, nested conditions, and anonymous layers in order', () => {
|
|
2443
|
+
const adopted = adoptSheet(
|
|
2444
|
+
'@layer first, second; @layer first { @media all { @layer nested {} } } @layer {}',
|
|
2445
|
+
)
|
|
2446
|
+
try {
|
|
2447
|
+
expect(readLayerNames(adopted.sheet)).toEqual([
|
|
2448
|
+
'first',
|
|
2449
|
+
'second',
|
|
2450
|
+
'first',
|
|
2451
|
+
'first.nested',
|
|
2452
|
+
'',
|
|
2453
|
+
])
|
|
2454
|
+
} finally {
|
|
2455
|
+
adopted.release()
|
|
2456
|
+
}
|
|
2457
|
+
})
|
|
2458
|
+
|
|
2459
|
+
it('returns no layer names for an empty sheet or an unlayered rule', () => {
|
|
2460
|
+
const sheet = new CSSStyleSheet()
|
|
2461
|
+
expect(readLayerNames(sheet)).toEqual([])
|
|
2462
|
+
sheet.replaceSync('.sample { color: red }')
|
|
2463
|
+
expect(readLayerNames(sheet)).toEqual([])
|
|
2464
|
+
})
|
|
2465
|
+
})
|
|
2466
|
+
`
|
|
2467
|
+
}),
|
|
1897
2468
|
setup: "",
|
|
1898
|
-
global:
|
|
2469
|
+
global: Object.freeze({
|
|
2470
|
+
module: `export function setup(): void {}
|
|
1899
2471
|
`,
|
|
2472
|
+
proof: `import { describe, expect, it } from 'vitest'
|
|
2473
|
+
import { setup } from './setupGlobal.js'
|
|
2474
|
+
|
|
2475
|
+
describe('global setup', () => {
|
|
2476
|
+
it('runs without producing a teardown', () => {
|
|
2477
|
+
expect(setup()).toBeUndefined()
|
|
2478
|
+
expect(setup()).toBeUndefined()
|
|
2479
|
+
})
|
|
2480
|
+
})
|
|
2481
|
+
`
|
|
2482
|
+
}),
|
|
1900
2483
|
entry: `import * as entry from {{specifier}}
|
|
1901
2484
|
import { describe, expect, it } from 'vitest'
|
|
1902
2485
|
|
|
@@ -3256,6 +3839,80 @@ function isCollection(value) {
|
|
|
3256
3839
|
*/
|
|
3257
3840
|
var isEnvironment = (0, _orkestrel_contract.literalOf)(ENVIRONMENTS);
|
|
3258
3841
|
/**
|
|
3842
|
+
* Narrows a value to a surface an extension can extend.
|
|
3843
|
+
* @param value - The candidate surface.
|
|
3844
|
+
* @returns True if the value is a supported surface; false otherwise.
|
|
3845
|
+
* @example
|
|
3846
|
+
* ```ts
|
|
3847
|
+
* import { isSurface } from '@orkestrel/scaffold'
|
|
3848
|
+
*
|
|
3849
|
+
* isSurface('styles') // true
|
|
3850
|
+
* isSurface('themes') // false
|
|
3851
|
+
* ```
|
|
3852
|
+
*/
|
|
3853
|
+
var isSurface = (0, _orkestrel_contract.literalOf)(SURFACES);
|
|
3854
|
+
/**
|
|
3855
|
+
* Narrows a value to a non-reserved sheet face name.
|
|
3856
|
+
* @param value - The candidate name.
|
|
3857
|
+
* @returns True if the name matches the workspace pattern and is not reserved; false otherwise.
|
|
3858
|
+
* @example
|
|
3859
|
+
* ```ts
|
|
3860
|
+
* import { isSheetName } from '@orkestrel/scaffold'
|
|
3861
|
+
*
|
|
3862
|
+
* isSheetName('print') // true
|
|
3863
|
+
* isSheetName('styles') // false
|
|
3864
|
+
* ```
|
|
3865
|
+
*/
|
|
3866
|
+
function isSheetName(value) {
|
|
3867
|
+
return (0, _orkestrel_contract.isString)(value) && value.length <= 203 && NAME_PATTERN.test(value) && !RESERVED_SHEET_NAMES.includes(value);
|
|
3868
|
+
}
|
|
3869
|
+
/**
|
|
3870
|
+
* Narrows a value to a supported browser framework with distinct occupied axes.
|
|
3871
|
+
* @param value - The candidate extension.
|
|
3872
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
3873
|
+
* @example
|
|
3874
|
+
* ```ts
|
|
3875
|
+
* import { isBrowserExtension } from '@orkestrel/scaffold'
|
|
3876
|
+
*
|
|
3877
|
+
* isBrowserExtension({ surface: 'browser', name: 'vue', axes: ['app'] }) // true
|
|
3878
|
+
* isBrowserExtension(undefined) // false
|
|
3879
|
+
* ```
|
|
3880
|
+
*/
|
|
3881
|
+
var isBrowserExtension = (0, _orkestrel_contract.andOf)((0, _orkestrel_contract.recordOf)({
|
|
3882
|
+
surface: (0, _orkestrel_contract.literalOf)("browser"),
|
|
3883
|
+
name: (0, _orkestrel_contract.literalOf)(FRAMEWORKS),
|
|
3884
|
+
axes: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)((0, _orkestrel_contract.literalOf)(AXES)))
|
|
3885
|
+
}), (extension) => new Set(extension.axes).size === extension.axes.length);
|
|
3886
|
+
/**
|
|
3887
|
+
* Narrows a value to a named non-reserved stylesheet face.
|
|
3888
|
+
* @param value - The candidate extension.
|
|
3889
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
3890
|
+
* @example
|
|
3891
|
+
* ```ts
|
|
3892
|
+
* import { isStylesExtension } from '@orkestrel/scaffold'
|
|
3893
|
+
*
|
|
3894
|
+
* isStylesExtension({ surface: 'styles', name: 'print' }) // true
|
|
3895
|
+
* isStylesExtension(undefined) // false
|
|
3896
|
+
* ```
|
|
3897
|
+
*/
|
|
3898
|
+
var isStylesExtension = (0, _orkestrel_contract.recordOf)({
|
|
3899
|
+
surface: (0, _orkestrel_contract.literalOf)("styles"),
|
|
3900
|
+
name: isSheetName
|
|
3901
|
+
});
|
|
3902
|
+
/**
|
|
3903
|
+
* Narrows a value to an extension of a supported surface.
|
|
3904
|
+
* @param value - The candidate extension.
|
|
3905
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
3906
|
+
* @example
|
|
3907
|
+
* ```ts
|
|
3908
|
+
* import { isExtension } from '@orkestrel/scaffold'
|
|
3909
|
+
*
|
|
3910
|
+
* isExtension({ surface: 'styles', name: 'print' }) // true
|
|
3911
|
+
* isExtension(undefined) // false
|
|
3912
|
+
* ```
|
|
3913
|
+
*/
|
|
3914
|
+
var isExtension = (0, _orkestrel_contract.unionOf)(isBrowserExtension, isStylesExtension);
|
|
3915
|
+
/**
|
|
3259
3916
|
* Narrows a value to one {@link Group} a plan selects over.
|
|
3260
3917
|
*
|
|
3261
3918
|
* @example
|
|
@@ -3392,6 +4049,9 @@ var isBlueprint = (0, _orkestrel_contract.recordOf)({
|
|
|
3392
4049
|
keywords: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isString)),
|
|
3393
4050
|
src: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isEnvironment)),
|
|
3394
4051
|
app: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isEnvironment)),
|
|
4052
|
+
extensions: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isExtension)),
|
|
4053
|
+
styles: _orkestrel_contract.isBoolean,
|
|
4054
|
+
themes: _orkestrel_contract.isBoolean,
|
|
3395
4055
|
dependencies: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isDependency)),
|
|
3396
4056
|
peers: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isDependency)),
|
|
3397
4057
|
extras: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isDependency)),
|
|
@@ -3686,6 +4346,34 @@ function cloneValue(value) {
|
|
|
3686
4346
|
//#endregion
|
|
3687
4347
|
//#region src/core/parsers.ts
|
|
3688
4348
|
/**
|
|
4349
|
+
* Coerces an extension value or a `surface:name` selection into an extension.
|
|
4350
|
+
* @param value - An extension record or its selection text.
|
|
4351
|
+
* @returns The extension, or `undefined` for a malformed or unsupported selection.
|
|
4352
|
+
* @remarks Browser text has empty axes; the creating command supplies its selected browser axes.
|
|
4353
|
+
* @example
|
|
4354
|
+
* ```ts
|
|
4355
|
+
* import { parseExtension } from '@orkestrel/scaffold'
|
|
4356
|
+
*
|
|
4357
|
+
* parseExtension('browser:vue') // { surface: 'browser', name: 'vue', axes: [] }
|
|
4358
|
+
* parseExtension('styles:print') // { surface: 'styles', name: 'print' }
|
|
4359
|
+
* ```
|
|
4360
|
+
*/
|
|
4361
|
+
function parseExtension(value) {
|
|
4362
|
+
if (isExtension(value)) return value;
|
|
4363
|
+
if (!(0, _orkestrel_contract.isString)(value)) return void 0;
|
|
4364
|
+
const [surface, name, excess] = value.split(":");
|
|
4365
|
+
if (excess !== void 0 || !isSurface(surface)) return void 0;
|
|
4366
|
+
const candidate = surface === "browser" ? {
|
|
4367
|
+
surface,
|
|
4368
|
+
name,
|
|
4369
|
+
axes: []
|
|
4370
|
+
} : {
|
|
4371
|
+
surface,
|
|
4372
|
+
name
|
|
4373
|
+
};
|
|
4374
|
+
return isExtension(candidate) ? candidate : void 0;
|
|
4375
|
+
}
|
|
4376
|
+
/**
|
|
3689
4377
|
* Coerces an untrusted value to a {@link Blueprint}.
|
|
3690
4378
|
*
|
|
3691
4379
|
* @param value - The value to parse.
|
|
@@ -4771,6 +5459,67 @@ function renderSkillPointer(canonical, name) {
|
|
|
4771
5459
|
//#endregion
|
|
4772
5460
|
//#region src/core/compilers.ts
|
|
4773
5461
|
/**
|
|
5462
|
+
* Projects a blueprint into browser extensions restricted to occupied browser axes.
|
|
5463
|
+
* @param blueprint - The workspace specification.
|
|
5464
|
+
* @returns Browser extensions with their occupied axes, omitting unplaced extensions.
|
|
5465
|
+
* @example
|
|
5466
|
+
* ```ts
|
|
5467
|
+
* import { blueprintToFaces, createBlueprint } from '@orkestrel/scaffold'
|
|
5468
|
+
*
|
|
5469
|
+
* blueprintToFaces(createBlueprint('desk', { app: ['core'] })).length // 0
|
|
5470
|
+
* ```
|
|
5471
|
+
*/
|
|
5472
|
+
function blueprintToFaces(blueprint) {
|
|
5473
|
+
return blueprint.extensions.flatMap((extension) => {
|
|
5474
|
+
if (extension.surface !== "browser") return [];
|
|
5475
|
+
const axes = extension.axes.filter((axis) => blueprint[axis].includes("browser"));
|
|
5476
|
+
return axes.length === 0 ? [] : [{
|
|
5477
|
+
...extension,
|
|
5478
|
+
axes
|
|
5479
|
+
}];
|
|
5480
|
+
});
|
|
5481
|
+
}
|
|
5482
|
+
/**
|
|
5483
|
+
* Projects a blueprint into its validated sheet-face names in stable order.
|
|
5484
|
+
* @param blueprint - The workspace specification.
|
|
5485
|
+
* @returns The base face followed by named styles extensions; themes remain a separate target.
|
|
5486
|
+
* @example
|
|
5487
|
+
* ```ts
|
|
5488
|
+
* import { blueprintToSheets, createBlueprint } from '@orkestrel/scaffold'
|
|
5489
|
+
*
|
|
5490
|
+
* blueprintToSheets(createBlueprint('paper', { styles: true })) // ['styles']
|
|
5491
|
+
* ```
|
|
5492
|
+
*/
|
|
5493
|
+
function blueprintToSheets(blueprint) {
|
|
5494
|
+
return [...blueprint.styles ? ["styles"] : [], ...(0, _orkestrel_contract.sortValues)(blueprint.extensions.flatMap((extension) => extension.surface === "styles" && isSheetName(extension.name) ? [extension.name] : []))];
|
|
5495
|
+
}
|
|
5496
|
+
/**
|
|
5497
|
+
* Projects published environments and sheets into the manifest export map.
|
|
5498
|
+
* @param blueprint - The workspace specification.
|
|
5499
|
+
* @returns JavaScript conditions and CSS and SCSS subpaths, without an invented JavaScript root.
|
|
5500
|
+
* @example
|
|
5501
|
+
* ```ts
|
|
5502
|
+
* import { blueprintToExports, createBlueprint } from '@orkestrel/scaffold'
|
|
5503
|
+
*
|
|
5504
|
+
* blueprintToExports(createBlueprint('paper', { styles: true }))['./styles']
|
|
5505
|
+
* // './dist/src/styles/index.css'
|
|
5506
|
+
* ```
|
|
5507
|
+
*/
|
|
5508
|
+
function blueprintToExports(blueprint) {
|
|
5509
|
+
const exports = { ...srcToExports(blueprint.src) };
|
|
5510
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
5511
|
+
if (extension.surface !== "browser" || !extension.axes.includes("src")) continue;
|
|
5512
|
+
exports[`./${extension.name}`] = pathToCondition(`./dist/src/${extension.name}/index`, ["es"]);
|
|
5513
|
+
if (blueprint.src.includes("browser")) exports["./browser"] = pathToCondition("./dist/src/browser/index", ["es"]);
|
|
5514
|
+
}
|
|
5515
|
+
for (const name of [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []]) {
|
|
5516
|
+
exports[`./${name}`] = `./dist/src/${name}/index.css`;
|
|
5517
|
+
exports[`./${name}/scss`] = `./src/${name}/index.scss`;
|
|
5518
|
+
}
|
|
5519
|
+
if (Object.keys(exports).length > 0) exports["./package.json"] = "./package.json";
|
|
5520
|
+
return exports;
|
|
5521
|
+
}
|
|
5522
|
+
/**
|
|
4774
5523
|
* Builds one `exports` condition block for a built environment.
|
|
4775
5524
|
*
|
|
4776
5525
|
* @param path - The extensionless `dist` path both conditions point at.
|
|
@@ -4896,6 +5645,12 @@ function srcToExports(src) {
|
|
|
4896
5645
|
* the peer's floor states what consumers may supply rather than what this workspace
|
|
4897
5646
|
* develops against.
|
|
4898
5647
|
*
|
|
5648
|
+
* A workspace that renders a surface receives {@link BROWSE_DEV_DEPENDENCIES}: a browser
|
|
5649
|
+
* environment on either axis, a sheet, or themes. A framework face counts without a clause of
|
|
5650
|
+
* its own, because a face is selected only on an axis that carries a browser environment.
|
|
5651
|
+
* A browser setup runtime alone receives nothing, because it renders no surface for `browse`
|
|
5652
|
+
* to drive.
|
|
5653
|
+
*
|
|
4899
5654
|
* A peer is declared here as well as under `peerDependencies`, because a peer is
|
|
4900
5655
|
* not installed by the workspace that declares it and developing against one
|
|
4901
5656
|
* requires it present. A runtime dependency is the opposite case and is removed:
|
|
@@ -4917,18 +5672,23 @@ function srcToExports(src) {
|
|
|
4917
5672
|
* ```
|
|
4918
5673
|
*/
|
|
4919
5674
|
function blueprintToDevDependencies(blueprint) {
|
|
5675
|
+
const sheets = blueprintToSheets(blueprint).length > 0 || blueprint.themes;
|
|
5676
|
+
const rendered = blueprint.src.includes("browser") || blueprint.app.includes("browser") || sheets;
|
|
4920
5677
|
const merged = {
|
|
4921
5678
|
...BASE_DEV_DEPENDENCIES,
|
|
5679
|
+
...rendered ? BROWSE_DEV_DEPENDENCIES : {},
|
|
5680
|
+
...sheets ? STYLES_DEV_DEPENDENCIES : {},
|
|
4922
5681
|
...blueprint.src.length > 0 || blueprint.bin ? DECLARATION_DEV_DEPENDENCIES : {},
|
|
4923
|
-
...blueprint.src.includes("browser") || blueprint.setup.includes("browser") ? SOURCE_BROWSER_DEV_DEPENDENCIES : {},
|
|
5682
|
+
...blueprint.src.includes("browser") || blueprint.setup.includes("browser") || sheets ? SOURCE_BROWSER_DEV_DEPENDENCIES : {},
|
|
4924
5683
|
...blueprint.app.length > 0 ? APP_DEV_DEPENDENCIES : {},
|
|
4925
5684
|
...blueprint.app.includes("browser") ? APP_BROWSER_DEV_DEPENDENCIES : {},
|
|
4926
5685
|
...blueprint.showcase && blueprint.app.includes("browser") ? SHOWCASE_DEV_DEPENDENCIES : {},
|
|
4927
5686
|
...blueprint.app.includes("server") ? APP_SERVER_DEV_DEPENDENCIES : {}
|
|
4928
5687
|
};
|
|
5688
|
+
for (const framework of blueprintToMachinery(blueprint).frameworks) Object.assign(merged, FRAMEWORK_MATRIX[framework].dependencies);
|
|
4929
5689
|
for (const extra of blueprint.extras) merged[extra.name] = extra.range;
|
|
4930
5690
|
for (const peer of blueprint.peers) if (!Object.hasOwn(merged, peer.name)) merged[peer.name] = peer.range;
|
|
4931
|
-
const own = blueprint.src.length > 0 ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
5691
|
+
const own = blueprint.src.length > 0 || sheets ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
4932
5692
|
const runtime = new Set(blueprint.dependencies.map((dependency) => dependency.name));
|
|
4933
5693
|
return Object.fromEntries(Object.entries(merged).filter(([name]) => name !== own && !runtime.has(name)).sort(([left], [right]) => (0, _orkestrel_contract.compareValues)(left, right)));
|
|
4934
5694
|
}
|
|
@@ -4969,11 +5729,22 @@ function blueprintToDevDependencies(blueprint) {
|
|
|
4969
5729
|
* ```
|
|
4970
5730
|
*/
|
|
4971
5731
|
function blueprintToScripts(blueprint) {
|
|
4972
|
-
const
|
|
5732
|
+
const source = blueprintToFaces(blueprint).flatMap((extension) => extension.surface === "browser" && extension.axes.includes("src") ? [extension.name] : []);
|
|
5733
|
+
const application = blueprintToFaces(blueprint).flatMap((extension) => extension.surface === "browser" && extension.axes.includes("app") ? [extension.name] : []);
|
|
5734
|
+
const sheets = blueprintToSheets(blueprint);
|
|
5735
|
+
const targets = [...sheets, ...blueprint.themes && !blueprint.styles ? ["themes"] : []];
|
|
5736
|
+
const checker = application.includes("vue") ? FRAMEWORK_MATRIX.vue.checker : "tsc";
|
|
5737
|
+
const publishes = blueprint.src.length > 0 || targets.length > 0;
|
|
4973
5738
|
const integrates = blueprint.integration;
|
|
4974
5739
|
const compiles = publishes || blueprint.bin;
|
|
4975
5740
|
const runtime = blueprint.app.filter((environment) => environment !== "core");
|
|
4976
5741
|
const vitest = "vitest run --config vite.config.ts --no-cache --reporter=dot";
|
|
5742
|
+
const checks = [
|
|
5743
|
+
...blueprint.src,
|
|
5744
|
+
...source,
|
|
5745
|
+
...sheets,
|
|
5746
|
+
...blueprint.bin ? ["bin"] : []
|
|
5747
|
+
].map((name) => `npm run check:src:${name}`);
|
|
4977
5748
|
const scripts = {
|
|
4978
5749
|
clean: "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
4979
5750
|
copy: "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
|
|
@@ -4982,30 +5753,32 @@ function blueprintToScripts(blueprint) {
|
|
|
4982
5753
|
lint: "oxlint --config .oxlintrc.json --fix .",
|
|
4983
5754
|
"lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
|
|
4984
5755
|
check: [
|
|
4985
|
-
|
|
4986
|
-
...
|
|
5756
|
+
`${checker} --noEmit --project tsconfig.json`,
|
|
5757
|
+
...checks.length > 0 ? ["npm run check:src"] : [],
|
|
4987
5758
|
...blueprint.app.length > 0 ? ["npm run check:app"] : [],
|
|
4988
5759
|
...blueprint.skills ? ["npm run check:skills"] : []
|
|
4989
5760
|
].join(" && ")
|
|
4990
5761
|
};
|
|
4991
|
-
if (
|
|
4992
|
-
scripts["check:src"] =
|
|
5762
|
+
if (checks.length > 0) {
|
|
5763
|
+
scripts["check:src"] = checks.join(" && ");
|
|
4993
5764
|
for (const environment of blueprint.src) scripts[`check:src:${environment}`] = `tsc --noEmit -p configs/src/tsconfig.${environment}.json`;
|
|
4994
5765
|
if (blueprint.bin) scripts["check:src:bin"] = "tsc --noEmit -p configs/src/tsconfig.bin.json";
|
|
5766
|
+
for (const name of [...sheets, ...source]) scripts[`check:src:${name}`] = `tsc --noEmit -p configs/src/tsconfig.${name}.json`;
|
|
4995
5767
|
}
|
|
4996
5768
|
if (blueprint.app.length > 0) {
|
|
4997
|
-
scripts["check:app"] = blueprint.app.map((environment) => `npm run check:app:${environment}`).join(" && ");
|
|
4998
|
-
for (const environment of blueprint.app) scripts[`check:app:${environment}`] =
|
|
5769
|
+
scripts["check:app"] = [...blueprint.app, ...application].map((environment) => `npm run check:app:${environment}`).join(" && ");
|
|
5770
|
+
for (const environment of blueprint.app) scripts[`check:app:${environment}`] = `tsc --noEmit -p configs/app/tsconfig.${environment}.json`;
|
|
5771
|
+
for (const name of application) scripts[`check:app:${name}`] = `${FRAMEWORK_MATRIX[name].checker} --noEmit -p configs/app/tsconfig.${name}.json`;
|
|
4999
5772
|
}
|
|
5000
5773
|
if (blueprint.skills) scripts["check:skills"] = `tsc --noEmit -p ${SKILLS_CONFIG_PATH}`;
|
|
5001
5774
|
scripts.test = [
|
|
5002
5775
|
...compiles ? ["npm run test:src"] : [],
|
|
5003
5776
|
...blueprint.app.length > 0 ? ["npm run test:app"] : [],
|
|
5004
|
-
...blueprint.journey && blueprint.app.includes("browser") ? ["npm run test:journey"] : [],
|
|
5777
|
+
...blueprint.journey && blueprint.app.includes("browser") ? ["npm run test:journey", ...application.map((name) => `npm run test:journey:${name}`)] : [],
|
|
5005
5778
|
"npm run test:policy",
|
|
5006
5779
|
"npm run test:config",
|
|
5007
|
-
...blueprint.setup.includes("node") ? ["npm run test:setup"] : [],
|
|
5008
|
-
...blueprint.setup.includes("browser") ? ["npm run test:setup:browser"] : [],
|
|
5780
|
+
...blueprint.setup.includes("node") || blueprint.global ? ["npm run test:setup"] : [],
|
|
5781
|
+
...blueprint.setup.includes("browser") || targets.length > 0 ? ["npm run test:setup:browser"] : [],
|
|
5009
5782
|
...blueprint.skills ? ["npm run test:skills"] : [],
|
|
5010
5783
|
...blueprint.guides ? ["npm run test:guides"] : [],
|
|
5011
5784
|
...blueprint.conformance ? ["npm run test:conformance"] : [],
|
|
@@ -5016,20 +5789,32 @@ function blueprintToScripts(blueprint) {
|
|
|
5016
5789
|
scripts["test:src"] = [
|
|
5017
5790
|
vitest,
|
|
5018
5791
|
...blueprint.src.map((environment) => `--project ${SRC_MATRIX[environment].project}`),
|
|
5792
|
+
...source.map((name) => `--project src:${name}`),
|
|
5019
5793
|
...blueprint.bin ? ["--project src:bin"] : []
|
|
5020
5794
|
].join(" ");
|
|
5021
5795
|
for (const environment of blueprint.src) scripts[`test:src:${environment}`] = `${vitest} --project ${SRC_MATRIX[environment].project}`;
|
|
5022
5796
|
if (blueprint.bin) scripts["test:src:bin"] = `${vitest} --project src:bin`;
|
|
5797
|
+
for (const name of source) scripts[`test:src:${name}`] = `${vitest} --project src:${name}`;
|
|
5798
|
+
scripts["test:src"] = [...blueprint.src.length > 0 || blueprint.bin ? [scripts["test:src"]] : [], ...targets.map((name) => `npm run test:src:${name}`)].join(" && ");
|
|
5799
|
+
for (const name of targets) scripts[`test:src:${name}`] = `npm run build:src:${name} && ${vitest} --project src:${name}`;
|
|
5023
5800
|
}
|
|
5024
5801
|
if (blueprint.app.length > 0) {
|
|
5025
|
-
scripts["test:app"] = [
|
|
5802
|
+
scripts["test:app"] = [
|
|
5803
|
+
vitest,
|
|
5804
|
+
...blueprint.app.map((environment) => `--project ${APP_MATRIX[environment].project}`),
|
|
5805
|
+
...application.map((name) => `--project app:${name}`)
|
|
5806
|
+
].join(" ");
|
|
5026
5807
|
for (const environment of blueprint.app) scripts[`test:app:${environment}`] = `${vitest} --project ${APP_MATRIX[environment].project}`;
|
|
5808
|
+
for (const name of application) scripts[`test:app:${name}`] = `${vitest} --project app:${name}`;
|
|
5027
5809
|
}
|
|
5028
5810
|
scripts["test:policy"] = `${vitest} --project policy`;
|
|
5029
5811
|
scripts["test:config"] = `${vitest} --project config`;
|
|
5030
|
-
if (blueprint.setup.includes("node")) scripts["test:setup"] = `${vitest} --project setup`;
|
|
5031
|
-
if (blueprint.setup.includes("browser")) scripts["test:setup:browser"] = `${vitest} --project setup:browser`;
|
|
5032
|
-
if (blueprint.journey && blueprint.app.includes("browser"))
|
|
5812
|
+
if (blueprint.setup.includes("node") || blueprint.global) scripts["test:setup"] = `${vitest} --project setup`;
|
|
5813
|
+
if (blueprint.setup.includes("browser") || targets.length > 0) scripts["test:setup:browser"] = `${vitest} --project setup:browser`;
|
|
5814
|
+
if (blueprint.journey && blueprint.app.includes("browser")) {
|
|
5815
|
+
scripts["test:journey"] = `vitest run --config ${JOURNEY_CONFIG_PATH} --no-cache --reporter=dot`;
|
|
5816
|
+
for (const name of application) scripts[`test:journey:${name}`] = `${scripts["test:journey"]} --mode ${name}`;
|
|
5817
|
+
}
|
|
5033
5818
|
if (blueprint.skills) scripts["test:skills"] = `${vitest} --project skills`;
|
|
5034
5819
|
if (blueprint.guides) scripts["test:guides"] = `node --experimental-strip-types ${GUIDES_TEST_PATH}`;
|
|
5035
5820
|
if (blueprint.conformance) scripts["test:conformance"] = `${vitest} --project conformance`;
|
|
@@ -5044,23 +5829,34 @@ function blueprintToScripts(blueprint) {
|
|
|
5044
5829
|
...blueprint.app.length > 0 ? ["npm run build:app"] : []
|
|
5045
5830
|
].join(" && ");
|
|
5046
5831
|
if (compiles) {
|
|
5047
|
-
scripts["build:src"] = [
|
|
5832
|
+
scripts["build:src"] = [
|
|
5833
|
+
...blueprint.src.map((environment) => `npm run build:src:${environment}`),
|
|
5834
|
+
...source.map((name) => `npm run build:src:${name}`),
|
|
5835
|
+
...targets.map((name) => `npm run build:src:${name}`),
|
|
5836
|
+
...blueprint.bin ? ["npm run build:src:bin"] : []
|
|
5837
|
+
].join(" && ");
|
|
5048
5838
|
for (const environment of blueprint.src) {
|
|
5049
5839
|
const build = `vite build --config configs/src/vite.${environment}.config.ts`;
|
|
5050
5840
|
scripts[`build:src:${environment}`] = SRC_MATRIX[environment].formats.includes("cjs") ? `${build} && npm run copy dist/src/${environment}/index.d.ts dist/src/${environment}/index.d.cts` : build;
|
|
5051
5841
|
}
|
|
5052
5842
|
if (blueprint.bin) scripts["build:src:bin"] = "vite build --config configs/src/vite.bin.config.ts";
|
|
5843
|
+
for (const name of source) scripts[`build:src:${name}`] = `vite build --config configs/src/vite.${name}.config.ts`;
|
|
5844
|
+
for (const name of targets) scripts[`build:src:${name}`] = [`vite build --config configs/src/vite.${name}.config.ts`, ...name === "styles" && blueprint.themes ? ["vite build --config configs/src/vite.themes.config.ts"] : []].join(" && ");
|
|
5053
5845
|
}
|
|
5054
5846
|
if (blueprint.app.length > 0) {
|
|
5055
|
-
scripts["build:app"] = runtime.length > 0 ? runtime.map((environment) => `npm run build:app:${environment}`).join(" && ") : "npm run check:app:core";
|
|
5056
|
-
for (const environment of runtime) scripts[`build:app:${environment}`] = `vite build --config configs/app/vite.${environment}.config.ts`;
|
|
5847
|
+
scripts["build:app"] = runtime.length > 0 ? [...runtime, ...application].map((environment) => `npm run build:app:${environment}`).join(" && ") : "npm run check:app:core";
|
|
5848
|
+
for (const environment of [...runtime, ...application]) scripts[`build:app:${environment}`] = `vite build --config configs/app/vite.${environment}.config.ts`;
|
|
5057
5849
|
}
|
|
5058
5850
|
if (blueprint.app.includes("browser")) {
|
|
5059
5851
|
scripts.dev = "vite --config configs/app/vite.browser.config.ts";
|
|
5852
|
+
for (const name of application) scripts[`dev:${name}`] = `vite --config configs/app/vite.${name}.config.ts`;
|
|
5060
5853
|
if (blueprint.showcase) {
|
|
5061
5854
|
scripts.showcase = `vite --config ${SHOWCASE_CONFIG_PATH}`;
|
|
5062
5855
|
scripts["build:showcase"] = `vite build --config ${SHOWCASE_CONFIG_PATH}`;
|
|
5063
|
-
|
|
5856
|
+
for (const name of application) {
|
|
5857
|
+
scripts[`showcase:${name}`] = `${scripts.showcase} --mode ${name}`;
|
|
5858
|
+
scripts[`build:showcase:${name}`] = `${scripts["build:showcase"]} --mode ${name}`;
|
|
5859
|
+
}
|
|
5064
5860
|
}
|
|
5065
5861
|
}
|
|
5066
5862
|
if (blueprint.app.includes("server")) {
|
|
@@ -5070,7 +5866,9 @@ function blueprintToScripts(blueprint) {
|
|
|
5070
5866
|
if (publishes) {
|
|
5071
5867
|
scripts.prepack = "npm run build";
|
|
5072
5868
|
scripts.prepublishOnly = [
|
|
5073
|
-
"npm run format:check && npm run lint:check && npm run check && npm run build
|
|
5869
|
+
"npm run format:check && npm run lint:check && npm run check && npm run build",
|
|
5870
|
+
...blueprint.showcase && blueprint.app.includes("browser") ? ["npm run build:showcase", ...application.map((name) => `npm run build:showcase:${name}`)] : [],
|
|
5871
|
+
"npm test",
|
|
5074
5872
|
RELEASE_PROOF_COMMAND,
|
|
5075
5873
|
...blueprint.service ? ["npm run test:service"] : []
|
|
5076
5874
|
].join(" && ");
|
|
@@ -5088,6 +5886,8 @@ function blueprintToScripts(blueprint) {
|
|
|
5088
5886
|
* benchmark workbench scripts. A workspace carrying guides adds `test:guides`,
|
|
5089
5887
|
* whose package-owned entry runs the guides project and handles explicit parity
|
|
5090
5888
|
* rewrites, and one carrying skills adds `test:skills`. Publishing adds the pack and publication lifecycle scripts.
|
|
5889
|
+
* Sheet and framework faces add their check and build scripts, application frameworks add dev scripts,
|
|
5890
|
+
* and selected showcases and journeys add their mode scripts.
|
|
5091
5891
|
* Aggregate test scripts and
|
|
5092
5892
|
* maintainer-owned gate chains stay outside the region.
|
|
5093
5893
|
*
|
|
@@ -5111,13 +5911,18 @@ function blueprintToScripts(blueprint) {
|
|
|
5111
5911
|
*/
|
|
5112
5912
|
function blueprintToWritableScripts(blueprint) {
|
|
5113
5913
|
const scripts = blueprintToScripts(blueprint);
|
|
5914
|
+
const sheets = [...blueprintToSheets(blueprint), ...blueprint.themes && !blueprint.styles ? ["themes"] : []];
|
|
5114
5915
|
const writable = [];
|
|
5115
5916
|
for (const [name, command] of Object.entries(scripts)) {
|
|
5116
|
-
|
|
5917
|
+
const direct = name.startsWith("test:") && name !== "test:src" && name !== "test:app";
|
|
5918
|
+
const sheet = sheets.some((face) => name === `build:src:${face}` || name === `check:src:${face}`);
|
|
5919
|
+
const framework = blueprintToFaces(blueprint).some((extension) => extension.surface === "browser" && extension.axes.some((axis) => name === `check:${axis}:${extension.name}` || name === `build:${axis}:${extension.name}` || axis === "app" && name === `dev:${extension.name}`));
|
|
5920
|
+
const showcase = name === "showcase" || name.startsWith("showcase:") || name === "build:showcase" || name.startsWith("build:showcase:");
|
|
5921
|
+
if (!direct && !sheet && !framework && !showcase) continue;
|
|
5117
5922
|
writable.push({
|
|
5118
5923
|
name,
|
|
5119
5924
|
command,
|
|
5120
|
-
accepted: name === "test:guides" ? ["vitest run --config vite.config.ts --no-cache --reporter=dot --project guides"] : []
|
|
5925
|
+
accepted: name === "test:guides" ? ["vitest run --config vite.config.ts --no-cache --reporter=dot --project guides"] : name === "build:src:styles" && blueprint.themes ? ["vite build --config configs/src/vite.styles.config.ts"] : sheets.some((face) => name === `test:src:${face}`) ? [command.slice(command.indexOf(" && ") + 4)] : []
|
|
5121
5926
|
});
|
|
5122
5927
|
}
|
|
5123
5928
|
const prepack = scripts.prepack;
|
|
@@ -5173,7 +5978,9 @@ function blueprintToWritableScripts(blueprint) {
|
|
|
5173
5978
|
* ```
|
|
5174
5979
|
*/
|
|
5175
5980
|
function blueprintToManifest(blueprint) {
|
|
5176
|
-
const
|
|
5981
|
+
const sheets = blueprintToSheets(blueprint);
|
|
5982
|
+
const targets = [...sheets, ...blueprint.themes ? ["styles/themes"] : []];
|
|
5983
|
+
const publishes = blueprint.src.length > 0 || targets.length > 0;
|
|
5177
5984
|
const name = publishes ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
5178
5985
|
const dependencies = {};
|
|
5179
5986
|
for (const dependency of [...blueprint.dependencies].sort((left, right) => (0, _orkestrel_contract.compareValues)(left.name, right.name))) dependencies[dependency.name] = dependency.range;
|
|
@@ -5200,18 +6007,19 @@ function blueprintToManifest(blueprint) {
|
|
|
5200
6007
|
url: `git+https://github.com/orkestrel/${blueprint.name}.git`
|
|
5201
6008
|
} } : {},
|
|
5202
6009
|
...blueprint.bin ? { bin: { [blueprint.name]: "./dist/bin/main.js" } } : {},
|
|
5203
|
-
files:
|
|
5204
|
-
"dist/src",
|
|
5205
|
-
"dist/bin",
|
|
6010
|
+
files: [
|
|
6011
|
+
blueprint.bin || publishes ? "dist/src" : "dist/app",
|
|
6012
|
+
...blueprint.bin ? ["dist/bin"] : [],
|
|
6013
|
+
...targets.map((face) => `!dist/src/${face}/index.js`),
|
|
6014
|
+
...sheets.map((face) => `src/${face}/**/*.scss`),
|
|
6015
|
+
...blueprint.themes && !blueprint.styles ? ["src/styles/themes/**/*.scss"] : [],
|
|
5206
6016
|
"README.md"
|
|
5207
|
-
]
|
|
6017
|
+
],
|
|
5208
6018
|
type: "module",
|
|
5209
6019
|
...publishes ? {
|
|
5210
|
-
sideEffects: blueprint.bin ? [`./${BIN_ENTRY_PATH}`, "./dist/bin/main.js"] : false,
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
...entry.types === void 0 ? {} : { types: entry.types },
|
|
5214
|
-
exports: srcToExports(blueprint.src),
|
|
6020
|
+
sideEffects: targets.length > 0 || blueprint.bin ? [...targets.length > 0 ? ["**/*.css", "**/*.scss"] : [], ...blueprint.bin ? [`./${BIN_ENTRY_PATH}`, "./dist/bin/main.js"] : []] : false,
|
|
6021
|
+
...blueprint.src.length > 0 ? entry : {},
|
|
6022
|
+
exports: blueprintToExports(blueprint),
|
|
5215
6023
|
publishConfig: { access: "public" }
|
|
5216
6024
|
} : {},
|
|
5217
6025
|
scripts: blueprintToScripts(blueprint),
|
|
@@ -5248,15 +6056,16 @@ function blueprintToManifest(blueprint) {
|
|
|
5248
6056
|
*
|
|
5249
6057
|
* const blueprint = createBlueprint('router', { app: ['browser'] })
|
|
5250
6058
|
*
|
|
5251
|
-
* blueprintToMachinery(blueprint).
|
|
6059
|
+
* blueprintToMachinery(blueprint).frameworks // []
|
|
5252
6060
|
* ```
|
|
5253
6061
|
*/
|
|
5254
6062
|
function blueprintToMachinery(blueprint) {
|
|
5255
6063
|
const hosted = blueprint.app.some((environment) => environment !== "core");
|
|
6064
|
+
const frameworks = FRAMEWORKS.filter((framework) => blueprintToFaces(blueprint).some((extension) => extension.surface === "browser" && extension.name === framework && extension.axes.some((axis) => blueprint[axis].includes("browser"))));
|
|
5256
6065
|
return {
|
|
5257
|
-
browser: blueprint.src.includes("browser") || blueprint.app.includes("browser") || blueprint.setup.includes("browser"),
|
|
5258
|
-
|
|
5259
|
-
output: blueprint.src.length > 0 || blueprint.bin || hosted,
|
|
6066
|
+
browser: blueprint.src.includes("browser") || blueprint.app.includes("browser") || blueprint.setup.includes("browser") || blueprintToSheets(blueprint).length > 0 || blueprint.themes || frameworks.length > 0,
|
|
6067
|
+
frameworks,
|
|
6068
|
+
output: blueprint.src.length > 0 || blueprint.bin || hosted || blueprintToSheets(blueprint).length > 0 || blueprint.themes,
|
|
5260
6069
|
showcase: blueprint.showcase && blueprint.app.includes("browser")
|
|
5261
6070
|
};
|
|
5262
6071
|
}
|
|
@@ -5292,6 +6101,12 @@ function blueprintToMachinery(blueprint) {
|
|
|
5292
6101
|
*/
|
|
5293
6102
|
function blueprintToRootTsconfig(blueprint) {
|
|
5294
6103
|
const aliases = [];
|
|
6104
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6105
|
+
if (extension.surface !== "browser") continue;
|
|
6106
|
+
for (const axis of extension.axes) aliases.push([`@${axis}/${extension.name}`, `./${axis}/${extension.name}/index.ts`]);
|
|
6107
|
+
if (extension.axes.includes("src")) aliases.push([`@orkestrel/${blueprint.name}/${extension.name}`, `./src/${extension.name}/index.ts`]);
|
|
6108
|
+
}
|
|
6109
|
+
for (const name of blueprintToSheets(blueprint)) aliases.push([`@src/${name}`, `./src/${name}/index.ts`]);
|
|
5295
6110
|
for (const environment of ENVIRONMENTS) if (blueprint.src.includes(environment)) aliases.push([`@src/${environment}`, `./src/${environment}/index.ts`]);
|
|
5296
6111
|
for (const environment of ENVIRONMENTS) if (blueprint.app.includes(environment)) aliases.push([`@app/${environment}`, `./app/${environment}/index.ts`]);
|
|
5297
6112
|
const root = srcToRoot(blueprint.src);
|
|
@@ -5307,7 +6122,47 @@ function blueprintToRootTsconfig(blueprint) {
|
|
|
5307
6122
|
if (matchesPrintWidth(line)) return line;
|
|
5308
6123
|
return `\t\t\t"${specifier}": [\n\t\t\t\t"${target}"\n\t\t\t]${separator}`;
|
|
5309
6124
|
}).join("\n");
|
|
5310
|
-
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.tsconfig, { paths });
|
|
6125
|
+
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.tsconfig, { paths: aliases.length === 0 ? " \"paths\": {}" : `\t\t"paths": {\n${paths}\n\t\t}` });
|
|
6126
|
+
}
|
|
6127
|
+
/**
|
|
6128
|
+
* Projects a blueprint into the project labels its root Vitest configuration registers.
|
|
6129
|
+
*
|
|
6130
|
+
* @param blueprint - The workspace specification.
|
|
6131
|
+
* @returns Project labels in registration order, including wrapper-registered sheet faces.
|
|
6132
|
+
*
|
|
6133
|
+
* @example
|
|
6134
|
+
* ```ts
|
|
6135
|
+
* import { blueprintToProjects, createBlueprint } from '@orkestrel/scaffold'
|
|
6136
|
+
*
|
|
6137
|
+
* blueprintToProjects(createBlueprint('desk')).includes('policy') // true
|
|
6138
|
+
* ```
|
|
6139
|
+
*/
|
|
6140
|
+
function blueprintToProjects(blueprint) {
|
|
6141
|
+
const sheets = blueprintToSheets(blueprint);
|
|
6142
|
+
const styled = sheets.length > 0 || blueprint.themes;
|
|
6143
|
+
const faces = blueprintToFaces(blueprint);
|
|
6144
|
+
const projects = sheets.map((name) => `src:${name}`);
|
|
6145
|
+
if (blueprint.themes && !blueprint.styles) projects.push("src:themes");
|
|
6146
|
+
for (const axis of AXES) {
|
|
6147
|
+
for (const environment of ENVIRONMENTS) {
|
|
6148
|
+
if (axis === "app" && environment === "server") continue;
|
|
6149
|
+
if (blueprint[axis].includes(environment)) projects.push(`${axis}:${environment}`);
|
|
6150
|
+
}
|
|
6151
|
+
for (const face of faces) if (face.surface === "browser" && face.axes.includes(axis)) projects.push(`${axis}:${face.name}`);
|
|
6152
|
+
if (axis === "src" && blueprint.bin) projects.push("src:bin");
|
|
6153
|
+
if (axis === "app" && blueprint.app.includes("server")) projects.push("app:server");
|
|
6154
|
+
}
|
|
6155
|
+
projects.push("policy", "config");
|
|
6156
|
+
if (blueprint.setup.includes("node") || blueprint.global) projects.push("setup");
|
|
6157
|
+
if (blueprint.setup.includes("browser") || styled) projects.push("setup:browser");
|
|
6158
|
+
if (blueprint.guides) projects.push("guides");
|
|
6159
|
+
if (blueprint.skills) projects.push("skills");
|
|
6160
|
+
if (blueprint.conformance) projects.push("conformance");
|
|
6161
|
+
if (blueprint.service) projects.push("service");
|
|
6162
|
+
if (blueprint.src.length > 0 || styled) projects.push("distribution");
|
|
6163
|
+
if (blueprint.integration) projects.push("integration");
|
|
6164
|
+
projects.push("probe");
|
|
6165
|
+
return projects;
|
|
5311
6166
|
}
|
|
5312
6167
|
/**
|
|
5313
6168
|
* Compiles the root Vite and Vitest configuration for a blueprint.
|
|
@@ -5331,44 +6186,58 @@ function blueprintToRootTsconfig(blueprint) {
|
|
|
5331
6186
|
*/
|
|
5332
6187
|
function blueprintToRootVite(blueprint) {
|
|
5333
6188
|
const machinery = blueprintToMachinery(blueprint);
|
|
5334
|
-
const
|
|
6189
|
+
const planned = new Set(blueprintToProjects(blueprint));
|
|
6190
|
+
const sheets = blueprintToSheets(blueprint);
|
|
6191
|
+
const styled = sheets.length > 0 || blueprint.themes;
|
|
5335
6192
|
const global = blueprint.global ? " globalSetup: ['./tests/setupGlobal.ts'],\n" : "";
|
|
5336
6193
|
const imports = [];
|
|
5337
6194
|
if (machinery.browser) imports.push("import { playwright } from '@vitest/browser-playwright'");
|
|
5338
|
-
if (machinery.vue) imports.push("import vue from '@vitejs/plugin-vue'");
|
|
6195
|
+
if (machinery.frameworks.includes("vue")) imports.push("import vue from '@vitejs/plugin-vue'");
|
|
5339
6196
|
if (machinery.showcase) imports.push("import { viteSingleFile } from 'vite-plugin-singlefile'");
|
|
6197
|
+
if (machinery.showcase) {
|
|
6198
|
+
imports.push("import { renameSync } from 'node:fs'");
|
|
6199
|
+
imports.push("import { resolve as resolvePath } from 'node:path'");
|
|
6200
|
+
}
|
|
5340
6201
|
const factories = [];
|
|
5341
6202
|
const projects = [];
|
|
5342
|
-
|
|
6203
|
+
const external = "external: resolveSourceExternal,";
|
|
6204
|
+
if (blueprint.src.includes("browser") || blueprint.src.includes("server")) factories.push(blueprint.src.includes("core") ? `function resolveSourceExternal(id: string): boolean {
|
|
6205
|
+
return (
|
|
6206
|
+
id === '@src/core' ||
|
|
6207
|
+
resolveExternal(id, {
|
|
6208
|
+
peers,
|
|
6209
|
+
refused: [],
|
|
6210
|
+
siblings: [resolveWorkspacePath('src/core/index.ts')],
|
|
6211
|
+
})
|
|
6212
|
+
)
|
|
6213
|
+
}
|
|
6214
|
+
` : `function resolveSourceExternal(id: string): boolean {
|
|
6215
|
+
return resolveExternal(id, { peers, refused: [], siblings: [] })
|
|
6216
|
+
}
|
|
6217
|
+
`);
|
|
6218
|
+
if (styled) {
|
|
6219
|
+
factories.push(CONFIG_TEMPLATES.factories.sheet);
|
|
6220
|
+
for (const name of sheets) projects.push(`'./configs/src/vite.${name}.config.ts'`);
|
|
6221
|
+
if (planned.has("src:themes")) projects.push("'./configs/src/vite.themes.config.ts'");
|
|
6222
|
+
}
|
|
6223
|
+
if (planned.has("src:core")) {
|
|
5343
6224
|
factories.push(CONFIG_TEMPLATES.factories.src.core);
|
|
5344
6225
|
projects.push("srcCore");
|
|
5345
6226
|
}
|
|
5346
|
-
if (
|
|
6227
|
+
if (planned.has("src:browser")) {
|
|
5347
6228
|
const core = blueprint.src.includes("core");
|
|
5348
6229
|
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.src.browser, {
|
|
5349
|
-
external
|
|
5350
|
-
id === '@src/core' ||
|
|
5351
|
-
id.startsWith('@orkestrel/') ||
|
|
5352
|
-
peers.some((peer) => id === peer || id.startsWith(peer + '/')),` : `external: (id: string) =>
|
|
5353
|
-
id.startsWith('@orkestrel/') ||
|
|
5354
|
-
peers.some((peer) => id === peer || id.startsWith(peer + '/')),`,
|
|
6230
|
+
external,
|
|
5355
6231
|
output: core ? " output: { paths: { '@src/core': '../core/index.js' } }," : " output: {},",
|
|
5356
6232
|
exclude: core ? " exclude: ['tests/src/core/**/*.test.ts'],\n" : "",
|
|
5357
6233
|
global
|
|
5358
6234
|
}));
|
|
5359
6235
|
projects.push("srcBrowser");
|
|
5360
6236
|
}
|
|
5361
|
-
if (
|
|
6237
|
+
if (planned.has("src:server")) {
|
|
5362
6238
|
const core = blueprint.src.includes("core");
|
|
5363
6239
|
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.src.server, {
|
|
5364
|
-
external
|
|
5365
|
-
id === '@src/core' ||
|
|
5366
|
-
id.startsWith('node:') ||
|
|
5367
|
-
id.startsWith('@orkestrel/') ||
|
|
5368
|
-
peers.some((peer) => id === peer || id.startsWith(peer + '/')),` : `external: (id: string) =>
|
|
5369
|
-
id.startsWith('node:') ||
|
|
5370
|
-
id.startsWith('@orkestrel/') ||
|
|
5371
|
-
peers.some((peer) => id === peer || id.startsWith(peer + '/')),`,
|
|
6240
|
+
external,
|
|
5372
6241
|
output: core ? `\t\t\t\toutput: [
|
|
5373
6242
|
{
|
|
5374
6243
|
format: 'es',
|
|
@@ -5385,15 +6254,19 @@ function blueprintToRootVite(blueprint) {
|
|
|
5385
6254
|
}));
|
|
5386
6255
|
projects.push("srcServer");
|
|
5387
6256
|
}
|
|
5388
|
-
if (
|
|
6257
|
+
if (planned.has("src:vue")) {
|
|
6258
|
+
factories.push(CONFIG_TEMPLATES.factories.src.vue);
|
|
6259
|
+
projects.push("srcVue");
|
|
6260
|
+
}
|
|
6261
|
+
if (planned.has("src:bin")) {
|
|
5389
6262
|
factories.push(CONFIG_TEMPLATES.factories.src.bin);
|
|
5390
6263
|
projects.push("srcBin");
|
|
5391
6264
|
}
|
|
5392
|
-
if (
|
|
6265
|
+
if (planned.has("app:core")) {
|
|
5393
6266
|
factories.push(CONFIG_TEMPLATES.factories.app.core);
|
|
5394
6267
|
projects.push("appCore");
|
|
5395
6268
|
}
|
|
5396
|
-
if (
|
|
6269
|
+
if (planned.has("app:browser")) {
|
|
5397
6270
|
const showcaseFactory = machinery.showcase ? CONFIG_TEMPLATES.factories.app.showcase : "";
|
|
5398
6271
|
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.app.browser, {
|
|
5399
6272
|
showcaseFactory,
|
|
@@ -5402,7 +6275,11 @@ function blueprintToRootVite(blueprint) {
|
|
|
5402
6275
|
}));
|
|
5403
6276
|
projects.push("appBrowser");
|
|
5404
6277
|
}
|
|
5405
|
-
if (
|
|
6278
|
+
if (planned.has("app:vue")) {
|
|
6279
|
+
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.app.vue, { journeyExclude: blueprint.journey ? " exclude: ['tests/app/vue/integration.test.ts'],\n" : " exclude: [],\n" }));
|
|
6280
|
+
projects.push("appVue");
|
|
6281
|
+
}
|
|
6282
|
+
if (planned.has("app:server")) {
|
|
5406
6283
|
factories.push(CONFIG_TEMPLATES.factories.app.server);
|
|
5407
6284
|
projects.push("appServer");
|
|
5408
6285
|
}
|
|
@@ -5410,39 +6287,40 @@ function blueprintToRootVite(blueprint) {
|
|
|
5410
6287
|
projects.push("policy");
|
|
5411
6288
|
factories.push(CONFIG_TEMPLATES.factories.config);
|
|
5412
6289
|
projects.push("config");
|
|
5413
|
-
if (
|
|
6290
|
+
if (planned.has("setup")) {
|
|
5414
6291
|
factories.push(CONFIG_TEMPLATES.factories.setup);
|
|
5415
6292
|
projects.push("setup");
|
|
5416
6293
|
}
|
|
5417
|
-
if (
|
|
6294
|
+
if (planned.has("setup:browser")) {
|
|
5418
6295
|
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.browser, {
|
|
5419
|
-
|
|
6296
|
+
optimization: machinery.frameworks.includes("vue") ? "optimizeDeps: { include: [...optimizeDeps.include, 'vue'] }" : "optimizeDeps",
|
|
6297
|
+
plugins: machinery.frameworks.includes("vue") ? " plugins: [vue()],\n" : "",
|
|
5420
6298
|
global
|
|
5421
6299
|
}));
|
|
5422
6300
|
projects.push("setupBrowser");
|
|
5423
6301
|
}
|
|
5424
|
-
if (
|
|
6302
|
+
if (planned.has("guides")) {
|
|
5425
6303
|
factories.push(CONFIG_TEMPLATES.factories.guides);
|
|
5426
6304
|
projects.push("guides");
|
|
5427
6305
|
}
|
|
5428
|
-
if (
|
|
6306
|
+
if (planned.has("skills")) {
|
|
5429
6307
|
factories.push(CONFIG_TEMPLATES.factories.skills);
|
|
5430
6308
|
projects.push("skills");
|
|
5431
6309
|
}
|
|
5432
|
-
if (
|
|
6310
|
+
if (planned.has("conformance")) {
|
|
5433
6311
|
factories.push(CONFIG_TEMPLATES.factories.conformance);
|
|
5434
6312
|
projects.push("conformance");
|
|
5435
6313
|
}
|
|
5436
|
-
if (
|
|
6314
|
+
if (planned.has("service")) {
|
|
5437
6315
|
factories.push(CONFIG_TEMPLATES.factories.service);
|
|
5438
6316
|
projects.push("service");
|
|
5439
6317
|
}
|
|
5440
|
-
if (
|
|
6318
|
+
if (planned.has("distribution")) {
|
|
5441
6319
|
factories.push(CONFIG_TEMPLATES.factories.distribution);
|
|
5442
6320
|
projects.push("distribution");
|
|
5443
6321
|
}
|
|
5444
|
-
if (
|
|
5445
|
-
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.integration, { global }));
|
|
6322
|
+
if (planned.has("integration")) {
|
|
6323
|
+
factories.push((0, _orkestrel_template.fillTemplate)(styled ? CONFIG_TEMPLATES.factories.integration.sheet : CONFIG_TEMPLATES.factories.integration.module, { global }));
|
|
5446
6324
|
projects.push("integration");
|
|
5447
6325
|
}
|
|
5448
6326
|
factories.push(CONFIG_TEMPLATES.factories.probe);
|
|
@@ -5455,14 +6333,24 @@ ${projects.map((project) => `\t\t\t${project},`).join("\n")}
|
|
|
5455
6333
|
const helpers = [
|
|
5456
6334
|
"enforceBuildLog",
|
|
5457
6335
|
"environmentBoundary",
|
|
5458
|
-
"outputBoundary"
|
|
6336
|
+
"outputBoundary",
|
|
6337
|
+
"resolveApplication",
|
|
6338
|
+
"resolveExternal",
|
|
6339
|
+
"stampPage"
|
|
5459
6340
|
].filter((helper) => body.includes(helper));
|
|
6341
|
+
const helperImport = `import { ${helpers.join(", ")} } from './configs/helpers.js'\n`;
|
|
5460
6342
|
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.vite, {
|
|
5461
|
-
journey: blueprint.journey &&
|
|
6343
|
+
journey: blueprint.journey && blueprint.app.includes("browser") ? "import type { JourneyVariant } from '@orkestrel/test'\n" : "",
|
|
5462
6344
|
imports: imports.length === 0 ? "" : `${imports.join("\n")}\n`,
|
|
5463
|
-
helpers: helpers.length === 0 ? "" : `import {
|
|
6345
|
+
helpers: helpers.length === 0 ? "" : matchesPrintWidth(helperImport.trimEnd()) ? helperImport : `import {\n${helpers.map((helper) => `\t${helper},`).join("\n")}\n} from './configs/helpers.js'\n`,
|
|
5464
6346
|
browsers: machinery.browser ? "import { resolveBrowser, resolvePinnedBrowser } from './configs/browsers.js'\n" : "",
|
|
5465
|
-
options: (machinery.browser ?
|
|
6347
|
+
options: (machinery.browser ? `const browserOptions = resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)
|
|
6348
|
+
|
|
6349
|
+
const optimizeDeps = {\n\tinclude: ${JSON.stringify([
|
|
6350
|
+
"@orkestrel/test",
|
|
6351
|
+
"@orkestrel/test/browser",
|
|
6352
|
+
...Object.hasOwn(blueprintToDevDependencies(blueprint), "@orkestrel/contract") || blueprint.dependencies.some((dependency) => dependency.name === "@orkestrel/contract") || blueprint.peers.some((peer) => peer.name === "@orkestrel/contract") ? ["@orkestrel/contract"] : []
|
|
6353
|
+
]).replaceAll("\"", "'").replaceAll(",", ", ")},\n}\n\n` : "") + (blueprint.journey && blueprint.app.includes("browser") ? "const capture = process.env.CAPTURE === '1'\n\n" : "") + ((blueprint.journey || blueprint.showcase) && blueprint.app.includes("browser") ? `const applications = {\n\tbrowser: appBrowser,\n${blueprintToFaces(blueprint).filter((extension) => extension.surface === "browser" && extension.axes.includes("app")).map((extension) => `\t${extension.name}: app${extension.name[0]?.toUpperCase()}${extension.name.slice(1)},\n`).join("")}}\n\n` : ""),
|
|
5466
6354
|
factories: body,
|
|
5467
6355
|
projects: projectRows
|
|
5468
6356
|
});
|
|
@@ -5503,6 +6391,26 @@ function blueprintToConfigArtifacts(blueprint) {
|
|
|
5503
6391
|
origin: "template",
|
|
5504
6392
|
content: CONFIG_TEMPLATES.browsers
|
|
5505
6393
|
});
|
|
6394
|
+
for (const name of [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []]) {
|
|
6395
|
+
const label = name === "styles/themes" ? "themes" : name;
|
|
6396
|
+
artifacts.push({
|
|
6397
|
+
path: `configs/src/vite.${label}.config.ts`,
|
|
6398
|
+
group: "configs",
|
|
6399
|
+
ownership: "content",
|
|
6400
|
+
origin: "template",
|
|
6401
|
+
content: (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.vites.sheet, {
|
|
6402
|
+
name,
|
|
6403
|
+
label
|
|
6404
|
+
})
|
|
6405
|
+
});
|
|
6406
|
+
if (name !== "styles/themes") artifacts.push({
|
|
6407
|
+
path: `configs/src/tsconfig.${name}.json`,
|
|
6408
|
+
group: "configs",
|
|
6409
|
+
ownership: "content",
|
|
6410
|
+
origin: "template",
|
|
6411
|
+
content: (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.tsconfigs.sheet, { name })
|
|
6412
|
+
});
|
|
6413
|
+
}
|
|
5506
6414
|
for (const environment of blueprint.src) for (const path of SRC_MATRIX[environment].configs) {
|
|
5507
6415
|
let content = CONFIG_TEMPLATES.vites.src.core;
|
|
5508
6416
|
if (path === "configs/src/tsconfig.core.json") content = CONFIG_TEMPLATES.tsconfigs.src.core;
|
|
@@ -5540,11 +6448,10 @@ ${paths.join("\n")}
|
|
|
5540
6448
|
"../../app/browser/**/*.cts",
|
|
5541
6449
|
"../../app/browser/**/*.mts",
|
|
5542
6450
|
"../../app/browser/**/*.ts",
|
|
5543
|
-
"../../app/browser/**/*.tsx"
|
|
5544
|
-
"../../app/browser/**/*.vue"
|
|
6451
|
+
"../../app/browser/**/*.tsx"
|
|
5545
6452
|
];
|
|
5546
6453
|
if (blueprint.app.includes("core")) include.push("../../app/core/**/*.cts", "../../app/core/**/*.mts", "../../app/core/**/*.ts", "../../app/core/**/*.tsx");
|
|
5547
|
-
include.push("../../tests/app/browser/**/*.cts", "../../tests/app/browser/**/*.mts", "../../tests/app/browser/**/*.ts", "../../tests/app/browser/**/*.tsx", "../../tests/
|
|
6454
|
+
include.push("../../tests/app/browser/**/*.cts", "../../tests/app/browser/**/*.mts", "../../tests/app/browser/**/*.ts", "../../tests/app/browser/**/*.tsx", "../../tests/setup.ts", "../../tests/setupBrowser.ts");
|
|
5548
6455
|
content = (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.tsconfigs.app.browser, { include: include.map((entry, index) => `\t\t${JSON.stringify(entry)}${index === include.length - 1 ? "" : ","}`).join("\n") });
|
|
5549
6456
|
} else if (path === "configs/app/vite.server.config.ts") content = CONFIG_TEMPLATES.vites.app.server;
|
|
5550
6457
|
else if (path === "configs/app/tsconfig.server.json") {
|
|
@@ -5567,6 +6474,58 @@ ${paths.join("\n")}
|
|
|
5567
6474
|
content
|
|
5568
6475
|
});
|
|
5569
6476
|
}
|
|
6477
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6478
|
+
if (extension.surface !== "browser") continue;
|
|
6479
|
+
for (const axis of extension.axes) {
|
|
6480
|
+
const include = [
|
|
6481
|
+
...[
|
|
6482
|
+
"cts",
|
|
6483
|
+
"mts",
|
|
6484
|
+
"ts",
|
|
6485
|
+
"tsx",
|
|
6486
|
+
...FRAMEWORK_MATRIX[extension.name].suffixes
|
|
6487
|
+
].map((suffix) => `../../app/${extension.name}/**/*.${suffix}`),
|
|
6488
|
+
...blueprint.app.includes("core") ? [
|
|
6489
|
+
"cts",
|
|
6490
|
+
"mts",
|
|
6491
|
+
"ts",
|
|
6492
|
+
"tsx"
|
|
6493
|
+
].map((suffix) => `../../app/core/**/*.${suffix}`) : [],
|
|
6494
|
+
...[
|
|
6495
|
+
"cts",
|
|
6496
|
+
"mts",
|
|
6497
|
+
"ts",
|
|
6498
|
+
"tsx",
|
|
6499
|
+
...FRAMEWORK_MATRIX[extension.name].suffixes
|
|
6500
|
+
].map((suffix) => `../../tests/app/${extension.name}/**/*.${suffix}`),
|
|
6501
|
+
"../../tests/setup.ts",
|
|
6502
|
+
"../../tests/setupBrowser.ts"
|
|
6503
|
+
];
|
|
6504
|
+
const siblings = blueprint.src.filter((environment) => environment === "core" || environment === "browser").flatMap((environment) => ["ts", "js"].map((suffix) => {
|
|
6505
|
+
const key = `\t[resolveWorkspacePath('src/${environment}/index.${suffix}').replaceAll('\\\\', '/')]:`;
|
|
6506
|
+
const value = `'@orkestrel/${blueprint.name}${environment === "browser" ? "/browser" : ""}',`;
|
|
6507
|
+
return matchesPrintWidth(`${key} ${value}`) ? `${key} ${value}` : `${key}\n\t\t${value}`;
|
|
6508
|
+
})).join("\n");
|
|
6509
|
+
artifacts.push({
|
|
6510
|
+
path: `configs/${axis}/vite.${extension.name}.config.ts`,
|
|
6511
|
+
group: "configs",
|
|
6512
|
+
ownership: "content",
|
|
6513
|
+
origin: "template",
|
|
6514
|
+
environment: "browser",
|
|
6515
|
+
content: axis === "src" ? (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.vites.src.vue, {
|
|
6516
|
+
siblings,
|
|
6517
|
+
refused: `[${FRAMEWORK_MATRIX[extension.name].refused.map((name) => serializeTypeScriptString(name)).join(", ")}]`
|
|
6518
|
+
}) : CONFIG_TEMPLATES.vites.app.vue
|
|
6519
|
+
}, {
|
|
6520
|
+
path: `configs/${axis}/tsconfig.${extension.name}.json`,
|
|
6521
|
+
group: "configs",
|
|
6522
|
+
ownership: "content",
|
|
6523
|
+
origin: "template",
|
|
6524
|
+
environment: "browser",
|
|
6525
|
+
content: axis === "src" ? CONFIG_TEMPLATES.tsconfigs.vue.src : (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.tsconfigs.vue.app, { include: include.map((entry, index) => `\t\t${JSON.stringify(entry)}${index === include.length - 1 ? "" : ","}`).join("\n") })
|
|
6526
|
+
});
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
5570
6529
|
if (blueprint.showcase && blueprint.app.includes("browser")) artifacts.push({
|
|
5571
6530
|
path: SHOWCASE_CONFIG_PATH,
|
|
5572
6531
|
group: "configs",
|
|
@@ -5596,15 +6555,11 @@ ${paths.join("\n")}
|
|
|
5596
6555
|
* Compiles every artifact in the `source` group.
|
|
5597
6556
|
*
|
|
5598
6557
|
* @param blueprint - The workspace specification.
|
|
5599
|
-
* @returns
|
|
6558
|
+
* @returns Published barrels, sheet seeds, selected application entries, and the optional bin entry.
|
|
5600
6559
|
*
|
|
5601
6560
|
* @remarks
|
|
5602
|
-
*
|
|
5603
|
-
*
|
|
5604
|
-
* scaffold establishes only the selected environment boundaries. An application
|
|
5605
|
-
* entry is empty for the same reason the bin entry is, and because the vendored
|
|
5606
|
-
* lint config refuses an unassigned import outside a stylesheet, so the entry
|
|
5607
|
-
* cannot start by importing its barrel for effect either.
|
|
6561
|
+
* Barrels, server entries, and bin entries hold no starter implementation. Browser entries
|
|
6562
|
+
* render the workspace name as a level-one heading; the Vue face mounts its arrival component.
|
|
5608
6563
|
*
|
|
5609
6564
|
* @example
|
|
5610
6565
|
* ```ts
|
|
@@ -5617,6 +6572,20 @@ ${paths.join("\n")}
|
|
|
5617
6572
|
*/
|
|
5618
6573
|
function blueprintToSourceArtifacts(blueprint) {
|
|
5619
6574
|
const artifacts = [];
|
|
6575
|
+
if (blueprint.themes && !blueprint.styles) artifacts.push({
|
|
6576
|
+
path: "src/styles/_tokens.scss",
|
|
6577
|
+
group: "source",
|
|
6578
|
+
ownership: "birth",
|
|
6579
|
+
origin: "template",
|
|
6580
|
+
content: ARTIFACT_TEMPLATES.source.sheet["_tokens.scss"]
|
|
6581
|
+
});
|
|
6582
|
+
for (const name of [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []]) for (const [path, content] of Object.entries(name === "styles/themes" ? ARTIFACT_TEMPLATES.source.themes : ARTIFACT_TEMPLATES.source.sheet)) artifacts.push({
|
|
6583
|
+
path: `src/${name}/${path}`,
|
|
6584
|
+
group: "source",
|
|
6585
|
+
ownership: "birth",
|
|
6586
|
+
origin: "template",
|
|
6587
|
+
content
|
|
6588
|
+
});
|
|
5620
6589
|
for (const environment of blueprint.src) artifacts.push({
|
|
5621
6590
|
path: `src/${environment}/index.ts`,
|
|
5622
6591
|
group: "source",
|
|
@@ -5640,7 +6609,7 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5640
6609
|
ownership: "birth",
|
|
5641
6610
|
origin: "template",
|
|
5642
6611
|
environment,
|
|
5643
|
-
content: ARTIFACT_TEMPLATES.source.
|
|
6612
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.source.main, { heading: `${matchesPrintWidth(`\t.appendChild(document.createElement('h1')).textContent = ${serializeTypeScriptString(blueprint.name)}`) ? " " : "\n "}${serializeTypeScriptString(blueprint.name)}` })
|
|
5644
6613
|
}, {
|
|
5645
6614
|
path: "app/browser/index.html",
|
|
5646
6615
|
group: "source",
|
|
@@ -5658,6 +6627,36 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5658
6627
|
content: ARTIFACT_TEMPLATES.source.empty
|
|
5659
6628
|
});
|
|
5660
6629
|
}
|
|
6630
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6631
|
+
if (extension.surface !== "browser") continue;
|
|
6632
|
+
for (const axis of extension.axes) {
|
|
6633
|
+
artifacts.push({
|
|
6634
|
+
path: `${axis}/${extension.name}/index.ts`,
|
|
6635
|
+
group: "source",
|
|
6636
|
+
ownership: "birth",
|
|
6637
|
+
origin: "template",
|
|
6638
|
+
environment: "browser",
|
|
6639
|
+
content: axis === "app" ? ARTIFACT_TEMPLATES.source.empty : ARTIFACT_TEMPLATES.source.barrel
|
|
6640
|
+
});
|
|
6641
|
+
if (axis !== "app") continue;
|
|
6642
|
+
artifacts.push({
|
|
6643
|
+
path: `app/${extension.name}/index.html`,
|
|
6644
|
+
group: "source",
|
|
6645
|
+
ownership: "birth",
|
|
6646
|
+
origin: "template",
|
|
6647
|
+
environment: "browser",
|
|
6648
|
+
content: ARTIFACT_TEMPLATES.source.browser
|
|
6649
|
+
});
|
|
6650
|
+
for (const [path, content] of Object.entries(ARTIFACT_TEMPLATES.source.vue)) artifacts.push({
|
|
6651
|
+
path: `app/${extension.name}/${path}`,
|
|
6652
|
+
group: "source",
|
|
6653
|
+
ownership: "birth",
|
|
6654
|
+
origin: "template",
|
|
6655
|
+
environment: "browser",
|
|
6656
|
+
content: (0, _orkestrel_template.fillTemplate)(content, { heading: matchesPrintWidth(`\t<h1>${blueprint.name}</h1>`) ? blueprint.name : `\n\t\t${blueprint.name}\n\t` })
|
|
6657
|
+
});
|
|
6658
|
+
}
|
|
6659
|
+
}
|
|
5661
6660
|
if (blueprint.bin) artifacts.push({
|
|
5662
6661
|
path: BIN_ENTRY_PATH,
|
|
5663
6662
|
group: "source",
|
|
@@ -5671,7 +6670,7 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5671
6670
|
* Compiles every artifact in the `tests` group that is not vendored from the host.
|
|
5672
6671
|
*
|
|
5673
6672
|
* @param blueprint - The workspace specification.
|
|
5674
|
-
* @returns Shared setup modules, axis tests, and the optional integration seed.
|
|
6673
|
+
* @returns Shared setup modules and proofs, axis and sheet tests, journey suites, and the optional integration seed.
|
|
5675
6674
|
*
|
|
5676
6675
|
* @remarks
|
|
5677
6676
|
* `tests/setupPolicy.ts`, `tests/policy.test.ts`, and `tests/config.test.ts` are
|
|
@@ -5710,15 +6709,57 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5710
6709
|
origin: "template",
|
|
5711
6710
|
content: ARTIFACT_TEMPLATES.tests.setup
|
|
5712
6711
|
}];
|
|
6712
|
+
const sheets = [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []];
|
|
6713
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6714
|
+
if (extension.surface !== "browser") continue;
|
|
6715
|
+
for (const axis of extension.axes) artifacts.push({
|
|
6716
|
+
path: `tests/${axis}/${extension.name}/index.test.ts`,
|
|
6717
|
+
group: "tests",
|
|
6718
|
+
ownership: "birth",
|
|
6719
|
+
origin: "template",
|
|
6720
|
+
environment: "browser",
|
|
6721
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.tests.entry, {
|
|
6722
|
+
specifier: serializeTypeScriptString(`@${axis}/${extension.name}`),
|
|
6723
|
+
label: serializeTypeScriptString(`${axis} ${extension.name} entry`)
|
|
6724
|
+
})
|
|
6725
|
+
});
|
|
6726
|
+
}
|
|
6727
|
+
if (sheets.length > 0) artifacts.push({
|
|
6728
|
+
path: "tests/setupStyles.ts",
|
|
6729
|
+
group: "tests",
|
|
6730
|
+
ownership: "birth",
|
|
6731
|
+
origin: "template",
|
|
6732
|
+
content: ARTIFACT_TEMPLATES.tests.styles.module
|
|
6733
|
+
}, {
|
|
6734
|
+
path: "tests/setupStyles.test.ts",
|
|
6735
|
+
group: "tests",
|
|
6736
|
+
ownership: "birth",
|
|
6737
|
+
origin: "template",
|
|
6738
|
+
content: ARTIFACT_TEMPLATES.tests.styles.proof
|
|
6739
|
+
});
|
|
6740
|
+
for (const name of sheets) {
|
|
6741
|
+
const tests = "../".repeat(name.split("/").length + 1);
|
|
6742
|
+
artifacts.push({
|
|
6743
|
+
path: `tests/src/${name}/index.test.ts`,
|
|
6744
|
+
group: "tests",
|
|
6745
|
+
ownership: "birth",
|
|
6746
|
+
origin: "template",
|
|
6747
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.tests.sheet, {
|
|
6748
|
+
name,
|
|
6749
|
+
root: `${tests}../`,
|
|
6750
|
+
setup: `${tests}setupStyles.js`
|
|
6751
|
+
})
|
|
6752
|
+
});
|
|
6753
|
+
}
|
|
5713
6754
|
if (blueprintToMachinery(blueprint).browser) artifacts.push({
|
|
5714
6755
|
path: "tests/setupBrowser.ts",
|
|
5715
6756
|
group: "tests",
|
|
5716
6757
|
ownership: "birth",
|
|
5717
6758
|
origin: "template",
|
|
5718
6759
|
environment: "browser",
|
|
5719
|
-
content: ARTIFACT_TEMPLATES.tests.setup
|
|
6760
|
+
content: blueprint.journey ? ARTIFACT_TEMPLATES.tests.browser : ARTIFACT_TEMPLATES.tests.setup
|
|
5720
6761
|
});
|
|
5721
|
-
if (blueprint.src.includes("server") || blueprint.app.includes("server") || blueprint.bin) artifacts.push({
|
|
6762
|
+
if (blueprint.src.includes("server") || blueprint.app.includes("server") || blueprint.bin || blueprint.conformance) artifacts.push({
|
|
5722
6763
|
path: "tests/setupServer.ts",
|
|
5723
6764
|
group: "tests",
|
|
5724
6765
|
ownership: "birth",
|
|
@@ -5733,13 +6774,40 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5733
6774
|
origin: "template",
|
|
5734
6775
|
content: ARTIFACT_TEMPLATES.tests.setup
|
|
5735
6776
|
});
|
|
5736
|
-
if (blueprint.global)
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
6777
|
+
if (blueprint.global) {
|
|
6778
|
+
artifacts.push({
|
|
6779
|
+
path: GLOBAL_SETUP_PATH,
|
|
6780
|
+
group: "tests",
|
|
6781
|
+
ownership: "birth",
|
|
6782
|
+
origin: "template",
|
|
6783
|
+
content: ARTIFACT_TEMPLATES.tests.global.module
|
|
6784
|
+
});
|
|
6785
|
+
artifacts.push({
|
|
6786
|
+
path: "tests/setupGlobal.test.ts",
|
|
6787
|
+
group: "tests",
|
|
6788
|
+
ownership: "birth",
|
|
6789
|
+
origin: "template",
|
|
6790
|
+
content: ARTIFACT_TEMPLATES.tests.global.proof
|
|
6791
|
+
});
|
|
6792
|
+
}
|
|
6793
|
+
if (blueprint.journey && blueprint.app.includes("browser")) {
|
|
6794
|
+
const applications = ["browser", ...blueprintToFaces(blueprint).flatMap((extension) => extension.surface === "browser" && extension.axes.includes("app") ? [extension.name] : [])];
|
|
6795
|
+
for (const application of applications) artifacts.push({
|
|
6796
|
+
path: `tests/app/${application}/integration.test.ts`,
|
|
6797
|
+
group: "tests",
|
|
6798
|
+
ownership: "birth",
|
|
6799
|
+
origin: "template",
|
|
6800
|
+
environment: "browser",
|
|
6801
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.tests.journey, {
|
|
6802
|
+
application,
|
|
6803
|
+
heading: serializeTypeScriptString(blueprint.name),
|
|
6804
|
+
imports: application === "vue" ? "import { createApp } from 'vue'\nimport App from '../../../app/vue/App.vue'\n" : "",
|
|
6805
|
+
mount: application === "vue" ? " const container = document.body.appendChild(document.createElement('main'))\n const app = createApp(App)\n" : "",
|
|
6806
|
+
arrival: application === "vue" ? " app.mount(container)\n" : " await import('../../../app/browser/main.js')\n",
|
|
6807
|
+
cleanup: application === "vue" ? " app.unmount()\n container.remove()\n" : " for (const main of page.getByRole('main').elements()) main.remove()\n"
|
|
6808
|
+
})
|
|
6809
|
+
});
|
|
6810
|
+
}
|
|
5743
6811
|
for (const environment of blueprint.src) artifacts.push({
|
|
5744
6812
|
path: `tests/src/${environment}/index.test.ts`,
|
|
5745
6813
|
group: "tests",
|
|
@@ -5774,7 +6842,7 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5774
6842
|
label: serializeTypeScriptString(`app ${environment} entry`)
|
|
5775
6843
|
})
|
|
5776
6844
|
});
|
|
5777
|
-
if (blueprint.src.length > 0) {
|
|
6845
|
+
if (blueprint.src.length > 0 || blueprintToSheets(blueprint).length > 0 || blueprint.themes) {
|
|
5778
6846
|
const browser = blueprint.src.includes("browser");
|
|
5779
6847
|
const distribution = ARTIFACT_TEMPLATES.tests.distribution;
|
|
5780
6848
|
artifacts.push({
|
|
@@ -5843,7 +6911,12 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5843
6911
|
const tests = [];
|
|
5844
6912
|
const directories = [];
|
|
5845
6913
|
const guide = `guides/${blueprint.name}.md`;
|
|
5846
|
-
for (const environment of
|
|
6914
|
+
for (const environment of [
|
|
6915
|
+
...blueprint.src,
|
|
6916
|
+
...blueprintToFaces(blueprint).filter((extension) => extension.axes.includes("src")).map((extension) => extension.name),
|
|
6917
|
+
...blueprintToSheets(blueprint),
|
|
6918
|
+
...blueprint.themes ? ["styles/themes"] : []
|
|
6919
|
+
]) {
|
|
5847
6920
|
source.push(` - [\`src/${environment}\`](../src/${environment})`);
|
|
5848
6921
|
tests.push(` - [\`tests/src/${environment}\`](../tests/src/${environment})`);
|
|
5849
6922
|
directories.push(`- [\`src/${environment}\`](../src/${environment})\n - Guide: Not created. Create this file when the workspace has a public surface:\n \`${guide}\`\n - Tests: [\`tests/src/${environment}\`](../tests/src/${environment})`);
|
|
@@ -5853,7 +6926,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5853
6926
|
tests.push(" - [`tests/src/bin`](../tests/src/bin)");
|
|
5854
6927
|
directories.push(`- [\`src/bin\`](../src/bin)\n - Guide: Not created. Create this file when the workspace has a public surface:\n \`${guide}\`\n - Tests: [\`tests/src/bin\`](../tests/src/bin)`);
|
|
5855
6928
|
}
|
|
5856
|
-
for (const environment of blueprint.app) {
|
|
6929
|
+
for (const environment of [...blueprint.app, ...blueprintToFaces(blueprint).filter((extension) => extension.axes.includes("app")).map((extension) => extension.name)]) {
|
|
5857
6930
|
source.push(` - [\`app/${environment}\`](../app/${environment})`);
|
|
5858
6931
|
tests.push(` - [\`tests/app/${environment}\`](../tests/app/${environment})`);
|
|
5859
6932
|
directories.push(`- [\`app/${environment}\`](../app/${environment})\n - Guide: Not created. Create this file when the workspace has a public surface:\n \`${guide}\`\n - Tests: [\`tests/app/${environment}\`](../tests/app/${environment})`);
|
|
@@ -5865,7 +6938,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5865
6938
|
origin: "template",
|
|
5866
6939
|
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.guides.readme, {
|
|
5867
6940
|
source: source.join("\n"),
|
|
5868
|
-
tests: tests.join("\n"),
|
|
6941
|
+
tests: tests.join("\n") + (blueprint.showcase && blueprint.app.includes("browser") ? "\n - Showcase:\n" + ["browser", ...blueprintToFaces(blueprint).filter((extension) => extension.axes.includes("app")).map((extension) => extension.name)].map((application) => ` - [\`showcase/${application}.html\`](../showcase/${application}.html)`).join("\n") : ""),
|
|
5869
6942
|
directories: directories.join("\n"),
|
|
5870
6943
|
guide: blueprint.name
|
|
5871
6944
|
})
|
|
@@ -5904,7 +6977,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5904
6977
|
* ```
|
|
5905
6978
|
*/
|
|
5906
6979
|
function blueprintToDocumentArtifacts(blueprint) {
|
|
5907
|
-
const publishes = blueprint.src.length > 0;
|
|
6980
|
+
const publishes = blueprint.src.length > 0 || blueprintToSheets(blueprint).length > 0 || blueprint.themes;
|
|
5908
6981
|
const name = publishes ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
5909
6982
|
const description = blueprint.description ?? (publishes ? `The ${name} package.` : `The ${name} application.`);
|
|
5910
6983
|
return [{
|
|
@@ -6696,7 +7769,8 @@ function dependenciesToQuestions(dependencies, field, name, range) {
|
|
|
6696
7769
|
* These do not, because each describes a workspace it can describe honestly but
|
|
6697
7770
|
* will not create: a published axis of several environments without core,
|
|
6698
7771
|
* whose manifest names a core build the workspace never runs; a showcase flag
|
|
6699
|
-
* whose required browser axis is absent, which emits nothing;
|
|
7772
|
+
* or journey flag whose required browser axis is absent, which emits nothing; an unplaced browser
|
|
7773
|
+
* extension or a styles extension without the styles surface; and an
|
|
6700
7774
|
* integration flag over fewer than two environments, whose seed does emit and
|
|
6701
7775
|
* has nothing to compose across. Blocking any of them closed the gate for every
|
|
6702
7776
|
* verb. The verbs that read an existing workspace need the plan the gate
|
|
@@ -6737,7 +7811,7 @@ function blueprintToQuestions(blueprint) {
|
|
|
6737
7811
|
message: `${blueprint.engines} is not a supported minimum-Node floor.`,
|
|
6738
7812
|
blocking: true
|
|
6739
7813
|
});
|
|
6740
|
-
if (blueprint.src.length === 0 && blueprint.app.length === 0) questions.push({
|
|
7814
|
+
if (blueprint.src.length === 0 && blueprint.app.length === 0 && blueprintToSheets(blueprint).length === 0 && !blueprint.themes) questions.push({
|
|
6741
7815
|
field: "src",
|
|
6742
7816
|
message: "A workspace declares at least one environment on src or app.",
|
|
6743
7817
|
blocking: true,
|
|
@@ -6763,6 +7837,32 @@ function blueprintToQuestions(blueprint) {
|
|
|
6763
7837
|
candidates: ENVIRONMENTS
|
|
6764
7838
|
});
|
|
6765
7839
|
}
|
|
7840
|
+
const extensions = /* @__PURE__ */ new Set();
|
|
7841
|
+
for (const extension of blueprint.extensions) {
|
|
7842
|
+
const selection = `${extension.surface}:${extension.name}`;
|
|
7843
|
+
if (extensions.has(selection)) questions.push({
|
|
7844
|
+
field: "extensions",
|
|
7845
|
+
message: `${selection} is declared more than once on extensions.`,
|
|
7846
|
+
blocking: true
|
|
7847
|
+
});
|
|
7848
|
+
extensions.add(selection);
|
|
7849
|
+
if (extension.surface === "browser") {
|
|
7850
|
+
if (extension.axes.length === 0) questions.push({
|
|
7851
|
+
field: "extensions",
|
|
7852
|
+
message: `${selection} occupies no axis.`,
|
|
7853
|
+
blocking: false
|
|
7854
|
+
});
|
|
7855
|
+
for (const axis of extension.axes) if (!blueprint[axis].includes("browser")) questions.push({
|
|
7856
|
+
field: "extensions",
|
|
7857
|
+
message: `${selection} occupies ${axis}, whose selection lacks browser.`,
|
|
7858
|
+
blocking: false
|
|
7859
|
+
});
|
|
7860
|
+
} else if (!blueprint.styles) questions.push({
|
|
7861
|
+
field: "extensions",
|
|
7862
|
+
message: `${selection} extends a styles surface this workspace does not declare.`,
|
|
7863
|
+
blocking: false
|
|
7864
|
+
});
|
|
7865
|
+
}
|
|
6766
7866
|
if (blueprint.integration && blueprint.src.length + blueprint.app.length < 2) questions.push({
|
|
6767
7867
|
field: "integration",
|
|
6768
7868
|
message: "integration drives features across environments, and this workspace declares fewer than two, so its seed composes nothing.",
|
|
@@ -6992,6 +8092,9 @@ function createBlueprint(name, input) {
|
|
|
6992
8092
|
keywords: input?.keywords ?? [],
|
|
6993
8093
|
src: input?.src ?? [],
|
|
6994
8094
|
app: input?.app ?? [],
|
|
8095
|
+
extensions: input?.extensions ?? [],
|
|
8096
|
+
styles: input?.styles ?? false,
|
|
8097
|
+
themes: input?.themes ?? false,
|
|
6995
8098
|
dependencies: input?.dependencies ?? [],
|
|
6996
8099
|
peers: input?.peers ?? [],
|
|
6997
8100
|
extras: input?.extras ?? [],
|
|
@@ -7322,9 +8425,11 @@ exports.APP_DEV_DEPENDENCIES = APP_DEV_DEPENDENCIES;
|
|
|
7322
8425
|
exports.APP_MATRIX = APP_MATRIX;
|
|
7323
8426
|
exports.APP_SERVER_DEV_DEPENDENCIES = APP_SERVER_DEV_DEPENDENCIES;
|
|
7324
8427
|
exports.ARTIFACT_TEMPLATES = ARTIFACT_TEMPLATES;
|
|
8428
|
+
exports.AXES = AXES;
|
|
7325
8429
|
exports.BASE_DEV_DEPENDENCIES = BASE_DEV_DEPENDENCIES;
|
|
7326
8430
|
exports.BIN_CONFIGS = BIN_CONFIGS;
|
|
7327
8431
|
exports.BIN_ENTRY_PATH = BIN_ENTRY_PATH;
|
|
8432
|
+
exports.BROWSE_DEV_DEPENDENCIES = BROWSE_DEV_DEPENDENCIES;
|
|
7328
8433
|
exports.CANON_PATHS = CANON_PATHS;
|
|
7329
8434
|
exports.CATALOG_AGENT_PATH = CATALOG_AGENT_PATH;
|
|
7330
8435
|
exports.CATALOG_CLOSING_MARKER = CATALOG_CLOSING_MARKER;
|
|
@@ -7344,6 +8449,8 @@ exports.EXECUTABLE_PATHS = EXECUTABLE_PATHS;
|
|
|
7344
8449
|
exports.EXTRA_RANGE_PATTERN = EXTRA_RANGE_PATTERN;
|
|
7345
8450
|
exports.FLOOR_RANGE_PATTERN = FLOOR_RANGE_PATTERN;
|
|
7346
8451
|
exports.FOREIGN_NAME_PATTERN = FOREIGN_NAME_PATTERN;
|
|
8452
|
+
exports.FRAMEWORKS = FRAMEWORKS;
|
|
8453
|
+
exports.FRAMEWORK_MATRIX = FRAMEWORK_MATRIX;
|
|
7347
8454
|
exports.GLOBAL_SETUP_PATH = GLOBAL_SETUP_PATH;
|
|
7348
8455
|
exports.GROUPS = GROUPS;
|
|
7349
8456
|
exports.GUIDES_TEST_PATH = GUIDES_TEST_PATH;
|
|
@@ -7376,18 +8483,26 @@ exports.ORKESTREL_RANGE_PATTERN = ORKESTREL_RANGE_PATTERN;
|
|
|
7376
8483
|
exports.PRINT_WIDTH = PRINT_WIDTH;
|
|
7377
8484
|
exports.REFERENCE_PATHS = REFERENCE_PATHS;
|
|
7378
8485
|
exports.RELEASE_PROOF_COMMAND = RELEASE_PROOF_COMMAND;
|
|
8486
|
+
exports.RESERVED_SHEET_NAMES = RESERVED_SHEET_NAMES;
|
|
7379
8487
|
exports.SEED_GUIDE_PATHS = SEED_GUIDE_PATHS;
|
|
7380
8488
|
exports.SERVICE_SCRIPT_PATH = SERVICE_SCRIPT_PATH;
|
|
7381
8489
|
exports.SERVICE_SETUP_PATH = SERVICE_SETUP_PATH;
|
|
7382
8490
|
exports.SERVICE_TEST_INCLUDE = SERVICE_TEST_INCLUDE;
|
|
8491
|
+
exports.SHEET_ENTRY_NAME = SHEET_ENTRY_NAME;
|
|
7383
8492
|
exports.SHOWCASE_CONFIG_PATH = SHOWCASE_CONFIG_PATH;
|
|
7384
8493
|
exports.SHOWCASE_DEV_DEPENDENCIES = SHOWCASE_DEV_DEPENDENCIES;
|
|
8494
|
+
exports.SHOWCASE_PAGES_PATH = SHOWCASE_PAGES_PATH;
|
|
7385
8495
|
exports.SKILLS_CONFIG_PATH = SKILLS_CONFIG_PATH;
|
|
7386
8496
|
exports.SOURCE_BROWSER_DEV_DEPENDENCIES = SOURCE_BROWSER_DEV_DEPENDENCIES;
|
|
7387
8497
|
exports.SRC_MATRIX = SRC_MATRIX;
|
|
8498
|
+
exports.STYLES_DEV_DEPENDENCIES = STYLES_DEV_DEPENDENCIES;
|
|
8499
|
+
exports.STYLES_ENTRY_PATH = STYLES_ENTRY_PATH;
|
|
8500
|
+
exports.SURFACES = SURFACES;
|
|
7388
8501
|
exports.ScaffoldError = ScaffoldError;
|
|
7389
8502
|
exports.TAB_WIDTH = TAB_WIDTH;
|
|
7390
8503
|
exports.TARGET_SKILL_NAMES = TARGET_SKILL_NAMES;
|
|
8504
|
+
exports.THEMES_BARREL_PATH = THEMES_BARREL_PATH;
|
|
8505
|
+
exports.THEMES_ENTRY_PATH = THEMES_ENTRY_PATH;
|
|
7391
8506
|
exports.VERSION_PATTERN = VERSION_PATTERN;
|
|
7392
8507
|
exports.WORKSPACE_DEV_ENGINES = WORKSPACE_DEV_ENGINES;
|
|
7393
8508
|
exports.WORKSPACE_OWNED_PATHS = WORKSPACE_OWNED_PATHS;
|
|
@@ -7398,15 +8513,19 @@ exports.artifactsToQuestions = artifactsToQuestions;
|
|
|
7398
8513
|
exports.blueprintToConfigArtifacts = blueprintToConfigArtifacts;
|
|
7399
8514
|
exports.blueprintToDevDependencies = blueprintToDevDependencies;
|
|
7400
8515
|
exports.blueprintToDocumentArtifacts = blueprintToDocumentArtifacts;
|
|
8516
|
+
exports.blueprintToExports = blueprintToExports;
|
|
8517
|
+
exports.blueprintToFaces = blueprintToFaces;
|
|
7401
8518
|
exports.blueprintToGuideArtifacts = blueprintToGuideArtifacts;
|
|
7402
8519
|
exports.blueprintToHostArtifacts = blueprintToHostArtifacts;
|
|
7403
8520
|
exports.blueprintToMachinery = blueprintToMachinery;
|
|
7404
8521
|
exports.blueprintToManifest = blueprintToManifest;
|
|
7405
8522
|
exports.blueprintToOrchestrationArtifacts = blueprintToOrchestrationArtifacts;
|
|
8523
|
+
exports.blueprintToProjects = blueprintToProjects;
|
|
7406
8524
|
exports.blueprintToQuestions = blueprintToQuestions;
|
|
7407
8525
|
exports.blueprintToRootTsconfig = blueprintToRootTsconfig;
|
|
7408
8526
|
exports.blueprintToRootVite = blueprintToRootVite;
|
|
7409
8527
|
exports.blueprintToScripts = blueprintToScripts;
|
|
8528
|
+
exports.blueprintToSheets = blueprintToSheets;
|
|
7410
8529
|
exports.blueprintToSourceArtifacts = blueprintToSourceArtifacts;
|
|
7411
8530
|
exports.blueprintToTestArtifacts = blueprintToTestArtifacts;
|
|
7412
8531
|
exports.blueprintToWritableScripts = blueprintToWritableScripts;
|
|
@@ -7426,6 +8545,7 @@ exports.inferGroup = inferGroup;
|
|
|
7426
8545
|
exports.isArtifact = isArtifact;
|
|
7427
8546
|
exports.isAudit = isAudit;
|
|
7428
8547
|
exports.isBlueprint = isBlueprint;
|
|
8548
|
+
exports.isBrowserExtension = isBrowserExtension;
|
|
7429
8549
|
exports.isCanonPath = isCanonPath;
|
|
7430
8550
|
exports.isCatalogEntry = isCatalogEntry;
|
|
7431
8551
|
exports.isCollection = isCollection;
|
|
@@ -7436,6 +8556,7 @@ exports.isDeferredPath = isDeferredPath;
|
|
|
7436
8556
|
exports.isDependency = isDependency;
|
|
7437
8557
|
exports.isDependencyName = isDependencyName;
|
|
7438
8558
|
exports.isEnvironment = isEnvironment;
|
|
8559
|
+
exports.isExtension = isExtension;
|
|
7439
8560
|
exports.isFinding = isFinding;
|
|
7440
8561
|
exports.isFloorPath = isFloorPath;
|
|
7441
8562
|
exports.isGroup = isGroup;
|
|
@@ -7449,7 +8570,10 @@ exports.isPlan = isPlan;
|
|
|
7449
8570
|
exports.isQuestion = isQuestion;
|
|
7450
8571
|
exports.isRetainedPath = isRetainedPath;
|
|
7451
8572
|
exports.isScaffoldError = isScaffoldError;
|
|
8573
|
+
exports.isSheetName = isSheetName;
|
|
7452
8574
|
exports.isSnapshot = isSnapshot;
|
|
8575
|
+
exports.isStylesExtension = isStylesExtension;
|
|
8576
|
+
exports.isSurface = isSurface;
|
|
7453
8577
|
exports.manifestToDependencies = manifestToDependencies;
|
|
7454
8578
|
exports.manifestToName = manifestToName;
|
|
7455
8579
|
exports.matchesDriftReachability = matchesDriftReachability;
|
|
@@ -7461,6 +8585,7 @@ exports.nameToGuide = nameToGuide;
|
|
|
7461
8585
|
exports.overridesToQuestions = overridesToQuestions;
|
|
7462
8586
|
exports.parseBlueprint = parseBlueprint;
|
|
7463
8587
|
exports.parseCompilerOptions = parseCompilerOptions;
|
|
8588
|
+
exports.parseExtension = parseExtension;
|
|
7464
8589
|
exports.parseGroups = parseGroups;
|
|
7465
8590
|
exports.parseSnapshot = parseSnapshot;
|
|
7466
8591
|
exports.pathToCondition = pathToCondition;
|