@orkestrel/scaffold 0.0.81 → 0.0.82
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/bin/main.js +167 -13
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +5 -3
- package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +2 -2
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +41 -38
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/decide.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/layer.md +5 -5
- 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/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/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/scaffold.md +475 -115
- package/dist/host/manifest.json +26 -26
- 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 +1261 -159
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +297 -35
- package/dist/src/core/index.d.ts +297 -35
- package/dist/src/core/index.js +1241 -160
- package/dist/src/core/index.js.map +1 -1
- package/package.json +1 -1
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.82",
|
|
8
8
|
description: "Scaffold workspaces with commands: new, audit, repair, catalog, and overwrite.",
|
|
9
9
|
keywords: [
|
|
10
10
|
"audit",
|
|
@@ -134,6 +134,44 @@ var ENVIRONMENTS = Object.freeze([
|
|
|
134
134
|
"browser",
|
|
135
135
|
"server"
|
|
136
136
|
]);
|
|
137
|
+
/** Lists the surfaces an extension may extend, frozen. */
|
|
138
|
+
var SURFACES = Object.freeze(["browser", "styles"]);
|
|
139
|
+
/** Lists the axes a browser extension may occupy, frozen. */
|
|
140
|
+
var AXES = Object.freeze(["src", "app"]);
|
|
141
|
+
/** Lists the supported browser frameworks, frozen. */
|
|
142
|
+
var FRAMEWORKS = Object.freeze(["vue"]);
|
|
143
|
+
/** Describes the tooling and package boundaries of each browser framework, frozen. */
|
|
144
|
+
var FRAMEWORK_MATRIX = Object.freeze({ vue: Object.freeze({
|
|
145
|
+
plugin: "@vitejs/plugin-vue",
|
|
146
|
+
checker: "vue-tsc",
|
|
147
|
+
suffixes: Object.freeze(["vue"]),
|
|
148
|
+
refused: Object.freeze(["vue", "@vue/"]),
|
|
149
|
+
dependencies: Object.freeze({
|
|
150
|
+
"@vitejs/plugin-vue": "^6.0.8",
|
|
151
|
+
vue: "^3.5.40",
|
|
152
|
+
"vue-tsc": "^3.3.7"
|
|
153
|
+
})
|
|
154
|
+
}) });
|
|
155
|
+
/** Names the base stylesheet marker. */
|
|
156
|
+
var STYLES_ENTRY_PATH = "src/styles/index.scss";
|
|
157
|
+
/** Names the themes build entry marker. */
|
|
158
|
+
var THEMES_ENTRY_PATH = "src/styles/themes/sheet.ts";
|
|
159
|
+
/** Names the themes stylesheet marker. */
|
|
160
|
+
var THEMES_BARREL_PATH = "src/styles/themes/index.scss";
|
|
161
|
+
/** Names the build entry beside each stylesheet marker. */
|
|
162
|
+
var SHEET_ENTRY_NAME = "sheet.ts";
|
|
163
|
+
/** Names the physical showcase output directory. */
|
|
164
|
+
var SHOWCASE_PAGES_PATH = "showcase";
|
|
165
|
+
/** Lists the development dependencies the styles surface adds, frozen. */
|
|
166
|
+
var STYLES_DEV_DEPENDENCIES = Object.freeze({ sass: "^1.105.1" });
|
|
167
|
+
/** Lists the names a styles extension cannot occupy, frozen. */
|
|
168
|
+
var RESERVED_SHEET_NAMES = Object.freeze([
|
|
169
|
+
...ENVIRONMENTS,
|
|
170
|
+
"bin",
|
|
171
|
+
"styles",
|
|
172
|
+
"themes",
|
|
173
|
+
...FRAMEWORKS
|
|
174
|
+
]);
|
|
137
175
|
/**
|
|
138
176
|
* Lists the `Group` values in plan order, frozen.
|
|
139
177
|
*
|
|
@@ -626,13 +664,10 @@ var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
|
626
664
|
});
|
|
627
665
|
/** Names the development dependency every private `app` environment adds. */
|
|
628
666
|
var APP_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/contract": package_default.dependencies["@orkestrel/contract"] });
|
|
629
|
-
/** Lists the development dependencies a private
|
|
667
|
+
/** Lists the development dependencies a private browser application adds. */
|
|
630
668
|
var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
631
669
|
...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"
|
|
670
|
+
"@orkestrel/html": package_default.devDependencies["@orkestrel/html"]
|
|
636
671
|
});
|
|
637
672
|
/**
|
|
638
673
|
* Names the development dependency used only by the optional single-file showcase build.
|
|
@@ -696,9 +731,7 @@ var CONFIG_TEMPLATES = Object.freeze({
|
|
|
696
731
|
"forceConsistentCasingInFileNames": true,
|
|
697
732
|
"skipLibCheck": true,
|
|
698
733
|
"noEmit": true,
|
|
699
|
-
"paths": {
|
|
700
734
|
{{paths}}
|
|
701
|
-
}
|
|
702
735
|
},
|
|
703
736
|
"exclude": ["node_modules", "dist", "tmp"]
|
|
704
737
|
}
|
|
@@ -815,6 +848,27 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
815
848
|
`
|
|
816
849
|
}),
|
|
817
850
|
factories: Object.freeze({
|
|
851
|
+
sheet: `export function sheetProject(name: string, override?: UserConfig): UserConfig {
|
|
852
|
+
const project: UserConfig = {
|
|
853
|
+
resolve,
|
|
854
|
+
optimizeDeps,
|
|
855
|
+
publicDir: false,
|
|
856
|
+
test: {
|
|
857
|
+
name: { label: name, color: 'magenta' },
|
|
858
|
+
root: resolveWorkspacePath('.'),
|
|
859
|
+
isolate: false,
|
|
860
|
+
setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts', './tests/setupStyles.ts'],
|
|
861
|
+
browser: {
|
|
862
|
+
enabled: true,
|
|
863
|
+
provider: playwright(browserOptions),
|
|
864
|
+
instances: [{ browser: 'chromium', headless: true }],
|
|
865
|
+
},
|
|
866
|
+
fileParallelism: false,
|
|
867
|
+
},
|
|
868
|
+
}
|
|
869
|
+
return mergeOverride(project, override)
|
|
870
|
+
}
|
|
871
|
+
`,
|
|
818
872
|
src: Object.freeze({
|
|
819
873
|
core: `export function srcCore(override?: UserConfig): UserConfig {
|
|
820
874
|
const project: UserConfig = {
|
|
@@ -837,9 +891,51 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
837
891
|
return mergeOverride(project, override)
|
|
838
892
|
}
|
|
839
893
|
`,
|
|
840
|
-
|
|
894
|
+
vue: `function resolveVueFilename(): string {
|
|
895
|
+
return 'index.js'
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
export function srcVue(override?: UserConfig): UserConfig {
|
|
899
|
+
const project: UserConfig = {
|
|
900
|
+
resolve,
|
|
901
|
+
optimizeDeps: { include: [...optimizeDeps.include, 'vue'] },
|
|
902
|
+
publicDir: false,
|
|
903
|
+
plugins: [outputBoundary('dist/src/vue'), environmentBoundary('src/vue'), vue()],
|
|
904
|
+
build: {
|
|
905
|
+
emptyOutDir: true,
|
|
906
|
+
sourcemap: true,
|
|
907
|
+
minify: false,
|
|
908
|
+
lib: {
|
|
909
|
+
entry: resolveWorkspacePath('src/vue/index.ts'),
|
|
910
|
+
formats: ['es'],
|
|
911
|
+
fileName: resolveVueFilename,
|
|
912
|
+
},
|
|
913
|
+
outDir: 'dist/src/vue',
|
|
914
|
+
rolldownOptions: { onLog: enforceBuildLog },
|
|
915
|
+
},
|
|
916
|
+
test: {
|
|
917
|
+
name: { label: 'src:vue', color: 'green' },
|
|
918
|
+
include: ['tests/src/vue/**/*.test.ts'],
|
|
919
|
+
setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],
|
|
920
|
+
browser: {
|
|
921
|
+
enabled: true,
|
|
922
|
+
provider: playwright(browserOptions),
|
|
923
|
+
instances: [{ browser: 'chromium', headless: true }],
|
|
924
|
+
},
|
|
925
|
+
fileParallelism: false,
|
|
926
|
+
},
|
|
927
|
+
}
|
|
928
|
+
return mergeOverride(project, override)
|
|
929
|
+
}
|
|
930
|
+
`,
|
|
931
|
+
browser: `function resolveBrowserFilename(): string {
|
|
932
|
+
return 'index.js'
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
export function srcBrowser(override?: UserConfig): UserConfig {
|
|
841
936
|
const project: UserConfig = {
|
|
842
937
|
resolve,
|
|
938
|
+
optimizeDeps,
|
|
843
939
|
publicDir: false,
|
|
844
940
|
plugins: [outputBoundary('dist/src/browser'), environmentBoundary('src/browser')],
|
|
845
941
|
build: {
|
|
@@ -849,7 +945,7 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
849
945
|
lib: {
|
|
850
946
|
entry: resolveWorkspacePath('src/browser/index.ts'),
|
|
851
947
|
formats: ['es'],
|
|
852
|
-
fileName:
|
|
948
|
+
fileName: resolveBrowserFilename,
|
|
853
949
|
},
|
|
854
950
|
outDir: 'dist/src/browser',
|
|
855
951
|
rolldownOptions: {
|
|
@@ -874,7 +970,11 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
874
970
|
return mergeOverride(project, override)
|
|
875
971
|
}
|
|
876
972
|
`,
|
|
877
|
-
server: `
|
|
973
|
+
server: `function resolveServerFilename(format: string): string {
|
|
974
|
+
return format === 'es' ? 'index.js' : 'index.cjs'
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
export function srcServer(override?: UserConfig): UserConfig {
|
|
878
978
|
const project: UserConfig = {
|
|
879
979
|
resolve,
|
|
880
980
|
publicDir: false,
|
|
@@ -886,7 +986,7 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
886
986
|
lib: {
|
|
887
987
|
entry: resolveWorkspacePath('src/server/index.ts'),
|
|
888
988
|
formats: ['es', 'cjs'],
|
|
889
|
-
fileName:
|
|
989
|
+
fileName: resolveServerFilename,
|
|
890
990
|
},
|
|
891
991
|
outDir: 'dist/src/server',
|
|
892
992
|
target: 'node22',
|
|
@@ -908,7 +1008,15 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
908
1008
|
return mergeOverride(project, override)
|
|
909
1009
|
}
|
|
910
1010
|
`,
|
|
911
|
-
bin: `
|
|
1011
|
+
bin: `function resolveBinFilename(): string {
|
|
1012
|
+
return 'main.js'
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
function resolveBinExternal(id: string): boolean {
|
|
1016
|
+
return id.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] })
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
export function srcBin(override?: UserConfig): UserConfig {
|
|
912
1020
|
const project: UserConfig = {
|
|
913
1021
|
resolve,
|
|
914
1022
|
publicDir: false,
|
|
@@ -920,17 +1028,13 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
920
1028
|
lib: {
|
|
921
1029
|
entry: resolveWorkspacePath('${BIN_ENTRY_PATH}'),
|
|
922
1030
|
formats: ['es'],
|
|
923
|
-
fileName:
|
|
1031
|
+
fileName: resolveBinFilename,
|
|
924
1032
|
},
|
|
925
1033
|
outDir: 'dist/bin',
|
|
926
1034
|
target: 'node22',
|
|
927
1035
|
rolldownOptions: {
|
|
928
1036
|
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 + '/')),
|
|
1037
|
+
external: resolveBinExternal,
|
|
934
1038
|
},
|
|
935
1039
|
},
|
|
936
1040
|
test: {
|
|
@@ -970,7 +1074,8 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
970
1074
|
const output = 'dist/app/browser'
|
|
971
1075
|
const project: UserConfig = {
|
|
972
1076
|
resolve,
|
|
973
|
-
|
|
1077
|
+
optimizeDeps,
|
|
1078
|
+
plugins: [outputBoundary(output), environmentBoundary('app/browser')],
|
|
974
1079
|
root: resolveWorkspacePath('app/browser'),
|
|
975
1080
|
publicDir: false,
|
|
976
1081
|
build: {
|
|
@@ -999,20 +1104,47 @@ function isNamedPlugin(plugin: PluginOption): plugin is { name: string } {
|
|
|
999
1104
|
return mergeOverride(project, override)
|
|
1000
1105
|
}
|
|
1001
1106
|
{{showcaseFactory}}{{journeyFactory}}`,
|
|
1107
|
+
vue: `export function appVue(override?: UserConfig): UserConfig {
|
|
1108
|
+
const output = 'dist/app/vue'
|
|
1109
|
+
const browser = appBrowser()
|
|
1110
|
+
const project: UserConfig = {
|
|
1111
|
+
...browser,
|
|
1112
|
+
optimizeDeps: { include: [...optimizeDeps.include, 'vue'] },
|
|
1113
|
+
plugins: [outputBoundary(output), environmentBoundary('app/vue'), vue()],
|
|
1114
|
+
root: resolveWorkspacePath('app/vue'),
|
|
1115
|
+
build: {
|
|
1116
|
+
...browser.build,
|
|
1117
|
+
outDir: resolveWorkspacePath(output),
|
|
1118
|
+
rolldownOptions: {
|
|
1119
|
+
...browser.build?.rolldownOptions,
|
|
1120
|
+
input: resolveWorkspacePath('app/vue/index.html'),
|
|
1121
|
+
},
|
|
1122
|
+
},
|
|
1123
|
+
test: {
|
|
1124
|
+
...browser.test,
|
|
1125
|
+
name: { label: 'app:vue', color: 'magenta' },
|
|
1126
|
+
include: ['tests/app/vue/**/*.test.ts'],
|
|
1127
|
+
{{journeyExclude}} },
|
|
1128
|
+
}
|
|
1129
|
+
return mergeOverride(project, override)
|
|
1130
|
+
}
|
|
1131
|
+
`,
|
|
1002
1132
|
journey: `
|
|
1003
1133
|
// Replace the journey fields directly: merging would concatenate the ordinary include
|
|
1004
1134
|
// and retain the exclusion of the journey suite.
|
|
1005
1135
|
export function appJourney(
|
|
1006
1136
|
variant: JourneyVariant,
|
|
1007
1137
|
variants: readonly JourneyVariant[],
|
|
1138
|
+
mode?: string,
|
|
1008
1139
|
): UserConfig {
|
|
1009
|
-
const
|
|
1140
|
+
const application = resolveApplication(mode, applications)
|
|
1141
|
+
const browser = applications[application]()
|
|
1010
1142
|
return {
|
|
1011
1143
|
...browser,
|
|
1012
1144
|
test: {
|
|
1013
1145
|
...browser.test,
|
|
1014
1146
|
name: { label: \`journey:\${variant.name}\`, color: 'green' },
|
|
1015
|
-
include: [
|
|
1147
|
+
include: [\`tests/app/\${application}/integration.test.ts\`],
|
|
1016
1148
|
exclude: [],
|
|
1017
1149
|
provide: { variant: variant.name, variants, capture },
|
|
1018
1150
|
browser: {
|
|
@@ -1025,8 +1157,39 @@ export function appJourney(
|
|
|
1025
1157
|
}
|
|
1026
1158
|
`,
|
|
1027
1159
|
showcase: `
|
|
1028
|
-
|
|
1029
|
-
|
|
1160
|
+
const showcaseStamp: PluginOption = {
|
|
1161
|
+
name: 'orkestrel-showcase-html',
|
|
1162
|
+
enforce: 'post',
|
|
1163
|
+
generateBundle(_, bundle) {
|
|
1164
|
+
for (const file of Object.values(bundle)) {
|
|
1165
|
+
if (
|
|
1166
|
+
file.type === 'asset' &&
|
|
1167
|
+
typeof file.source === 'string' &&
|
|
1168
|
+
file.fileName.endsWith('.html')
|
|
1169
|
+
) {
|
|
1170
|
+
file.source = stampPage(file.source)
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
function createShowcaseNaming(application: string): PluginOption {
|
|
1177
|
+
return {
|
|
1178
|
+
name: 'orkestrel-showcase-name',
|
|
1179
|
+
enforce: 'post',
|
|
1180
|
+
writeBundle(options) {
|
|
1181
|
+
if (options.dir === undefined) throw new Error('The showcase output is absent.')
|
|
1182
|
+
renameSync(
|
|
1183
|
+
resolvePath(options.dir, 'index.html'),
|
|
1184
|
+
resolvePath(options.dir, application + '.html'),
|
|
1185
|
+
)
|
|
1186
|
+
},
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
export function appShowcase(mode: string, override?: UserConfig): UserConfig {
|
|
1191
|
+
const application = resolveApplication(mode, applications)
|
|
1192
|
+
const output = 'showcase'
|
|
1030
1193
|
const showcase: UserConfig = {
|
|
1031
1194
|
plugins: [
|
|
1032
1195
|
outputBoundary(output),
|
|
@@ -1034,19 +1197,8 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1034
1197
|
removeViteModuleLoader: true,
|
|
1035
1198
|
useRecommendedBuildConfig: true,
|
|
1036
1199
|
}),
|
|
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
|
-
},
|
|
1200
|
+
showcaseStamp,
|
|
1201
|
+
createShowcaseNaming(application),
|
|
1050
1202
|
],
|
|
1051
1203
|
build: {
|
|
1052
1204
|
// The \`appBrowser\` factory sets \`assetsInlineLimit\` to 0, so every asset becomes
|
|
@@ -1055,6 +1207,7 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1055
1207
|
// true, so this line takes effect only in a workspace that turns that option off.
|
|
1056
1208
|
assetsInlineLimit: 4096,
|
|
1057
1209
|
cssMinify: 'lightningcss',
|
|
1210
|
+
emptyOutDir: false,
|
|
1058
1211
|
minify: 'oxc',
|
|
1059
1212
|
modulePreload: false,
|
|
1060
1213
|
outDir: resolveWorkspacePath(output),
|
|
@@ -1063,10 +1216,18 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1063
1216
|
target: 'esnext',
|
|
1064
1217
|
},
|
|
1065
1218
|
}
|
|
1066
|
-
return
|
|
1219
|
+
return applications[application](mergeOverride(showcase, override))
|
|
1067
1220
|
}
|
|
1068
1221
|
`,
|
|
1069
|
-
server: `
|
|
1222
|
+
server: `function resolveAppFilename(): string {
|
|
1223
|
+
return 'main.cjs'
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
function resolveAppExternal(id: string): boolean {
|
|
1227
|
+
return id.startsWith('node:')
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
export function appServer(override?: UserConfig): UserConfig {
|
|
1070
1231
|
const project: UserConfig = {
|
|
1071
1232
|
resolve,
|
|
1072
1233
|
publicDir: false,
|
|
@@ -1076,13 +1237,13 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1076
1237
|
lib: {
|
|
1077
1238
|
entry: resolveWorkspacePath('app/server/main.ts'),
|
|
1078
1239
|
formats: ['cjs'],
|
|
1079
|
-
fileName:
|
|
1240
|
+
fileName: resolveAppFilename,
|
|
1080
1241
|
},
|
|
1081
1242
|
outDir: resolveWorkspacePath('dist/app/server'),
|
|
1082
1243
|
target: 'node22',
|
|
1083
1244
|
rolldownOptions: {
|
|
1084
1245
|
onLog: enforceBuildLog,
|
|
1085
|
-
external:
|
|
1246
|
+
external: resolveAppExternal,
|
|
1086
1247
|
},
|
|
1087
1248
|
},
|
|
1088
1249
|
test: {
|
|
@@ -1135,8 +1296,10 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1135
1296
|
test: {
|
|
1136
1297
|
name: { label: 'setup', color: 'white' },
|
|
1137
1298
|
include: ['tests/setup*.test.ts'],
|
|
1138
|
-
exclude: ['tests/setupBrowser.test.ts'],
|
|
1299
|
+
exclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],
|
|
1139
1300
|
setupFiles: ['./tests/setup.ts'],
|
|
1301
|
+
pool: 'threads',
|
|
1302
|
+
isolate: false,
|
|
1140
1303
|
environment: 'node',
|
|
1141
1304
|
browser: { enabled: false },
|
|
1142
1305
|
},
|
|
@@ -1147,9 +1310,10 @@ export function appShowcase(override?: UserConfig): UserConfig {
|
|
|
1147
1310
|
browser: `export function setupBrowser(override?: UserConfig): UserConfig {
|
|
1148
1311
|
const project: UserConfig = {
|
|
1149
1312
|
resolve,
|
|
1313
|
+
{{optimization}},
|
|
1150
1314
|
{{plugins}} test: {
|
|
1151
1315
|
name: { label: 'setup:browser', color: 'blue' },
|
|
1152
|
-
include: ['tests/setupBrowser.test.ts'],
|
|
1316
|
+
include: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],
|
|
1153
1317
|
setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],
|
|
1154
1318
|
{{global}} browser: {
|
|
1155
1319
|
enabled: true,
|
|
@@ -1203,7 +1367,9 @@ export function conformance(override?: UserConfig): UserConfig {
|
|
|
1203
1367
|
test: {
|
|
1204
1368
|
name: { label: 'conformance', color: 'magenta' },
|
|
1205
1369
|
include: ['${CONFORMANCE_TEST_PATH}'],
|
|
1206
|
-
setupFiles: ['./tests/setup.ts'],
|
|
1370
|
+
setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
1371
|
+
pool: 'threads',
|
|
1372
|
+
isolate: false,
|
|
1207
1373
|
environment: 'node',
|
|
1208
1374
|
browser: { enabled: false },
|
|
1209
1375
|
},
|
|
@@ -1269,7 +1435,17 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1269
1435
|
return mergeOverride(project, override)
|
|
1270
1436
|
}
|
|
1271
1437
|
`,
|
|
1272
|
-
integration:
|
|
1438
|
+
integration: Object.freeze({
|
|
1439
|
+
sheet: `export function integration(override?: UserConfig): UserConfig {
|
|
1440
|
+
const project = sheetProject('integration', {
|
|
1441
|
+
test: {
|
|
1442
|
+
include: ['tests/integration.test.ts'],
|
|
1443
|
+
{{global}} },
|
|
1444
|
+
})
|
|
1445
|
+
return mergeOverride(project, override)
|
|
1446
|
+
}
|
|
1447
|
+
`,
|
|
1448
|
+
module: `export function integration(override?: UserConfig): UserConfig {
|
|
1273
1449
|
const project: UserConfig = {
|
|
1274
1450
|
resolve,
|
|
1275
1451
|
test: {
|
|
@@ -1282,8 +1458,51 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1282
1458
|
return mergeOverride(project, override)
|
|
1283
1459
|
}
|
|
1284
1460
|
`
|
|
1461
|
+
})
|
|
1285
1462
|
}),
|
|
1286
1463
|
tsconfigs: Object.freeze({
|
|
1464
|
+
vue: Object.freeze({
|
|
1465
|
+
src: `{
|
|
1466
|
+
"extends": "../../tsconfig.json",
|
|
1467
|
+
"compilerOptions": {
|
|
1468
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
1469
|
+
"types": ["vite/client"],
|
|
1470
|
+
"noEmit": false,
|
|
1471
|
+
"declaration": true,
|
|
1472
|
+
"emitDeclarationOnly": true,
|
|
1473
|
+
"rootDir": "../../src",
|
|
1474
|
+
"outDir": "../../dist/src"
|
|
1475
|
+
},
|
|
1476
|
+
"include": [
|
|
1477
|
+
"../../src/vue/**/*.cts",
|
|
1478
|
+
"../../src/vue/**/*.mts",
|
|
1479
|
+
"../../src/vue/**/*.ts",
|
|
1480
|
+
"../../src/vue/**/*.tsx"
|
|
1481
|
+
]
|
|
1482
|
+
}
|
|
1483
|
+
`,
|
|
1484
|
+
app: `{
|
|
1485
|
+
"extends": "../../tsconfig.json",
|
|
1486
|
+
"compilerOptions": {
|
|
1487
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
1488
|
+
"types": ["vite/client", "vue"]
|
|
1489
|
+
},
|
|
1490
|
+
"include": [
|
|
1491
|
+
{{include}}
|
|
1492
|
+
]
|
|
1493
|
+
}
|
|
1494
|
+
`
|
|
1495
|
+
}),
|
|
1496
|
+
sheet: `{
|
|
1497
|
+
"extends": "../../tsconfig.json",
|
|
1498
|
+
"compilerOptions": {
|
|
1499
|
+
"lib": ["ESNext"],
|
|
1500
|
+
"types": ["vite/client"],
|
|
1501
|
+
"noEmit": true
|
|
1502
|
+
},
|
|
1503
|
+
"include": ["../../src/{{name}}/**/*.ts"]
|
|
1504
|
+
}
|
|
1505
|
+
`,
|
|
1287
1506
|
src: Object.freeze({
|
|
1288
1507
|
core: `{
|
|
1289
1508
|
"extends": "../../tsconfig.json",
|
|
@@ -1367,7 +1586,7 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1367
1586
|
"extends": "../../tsconfig.json",
|
|
1368
1587
|
"compilerOptions": {
|
|
1369
1588
|
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
1370
|
-
"types": ["vite/client"
|
|
1589
|
+
"types": ["vite/client"]
|
|
1371
1590
|
},
|
|
1372
1591
|
"include": [
|
|
1373
1592
|
{{include}}
|
|
@@ -1417,9 +1636,38 @@ export function probe(override?: UserConfig): UserConfig {
|
|
|
1417
1636
|
`
|
|
1418
1637
|
}),
|
|
1419
1638
|
vites: Object.freeze({
|
|
1639
|
+
sheet: `import { defineConfig } from 'vitest/config'
|
|
1640
|
+
import { outputBoundary } from '../helpers.js'
|
|
1641
|
+
import { resolveWorkspacePath, sheetProject } from '../../vite.config.ts'
|
|
1642
|
+
|
|
1643
|
+
export default defineConfig((invocation) => {
|
|
1644
|
+
const project = sheetProject('src:{{label}}', {
|
|
1645
|
+
plugins: [outputBoundary('dist/src/{{name}}')],
|
|
1646
|
+
build: {
|
|
1647
|
+
outDir: 'dist/src/{{name}}',
|
|
1648
|
+
emptyOutDir: true,
|
|
1649
|
+
// Preserve the authored layer-order statement in the published sheet.
|
|
1650
|
+
cssMinify: false,
|
|
1651
|
+
lib: {
|
|
1652
|
+
entry: resolveWorkspacePath('src/{{name}}/sheet.ts'),
|
|
1653
|
+
formats: ['es'],
|
|
1654
|
+
fileName: 'index',
|
|
1655
|
+
cssFileName: 'index',
|
|
1656
|
+
},
|
|
1657
|
+
},
|
|
1658
|
+
test: { include: ['tests/src/{{name}}/**/*.test.ts'] },
|
|
1659
|
+
})
|
|
1660
|
+
return { ...project, mode: invocation.mode }
|
|
1661
|
+
})
|
|
1662
|
+
`,
|
|
1420
1663
|
src: Object.freeze({
|
|
1421
1664
|
core: `import { defineConfig } from 'vite'
|
|
1422
|
-
import {
|
|
1665
|
+
import {
|
|
1666
|
+
declarationRollup,
|
|
1667
|
+
environmentBoundary,
|
|
1668
|
+
outputBoundary,
|
|
1669
|
+
resolveExternal,
|
|
1670
|
+
} from '../helpers.js'
|
|
1423
1671
|
import { peers, srcCore, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1424
1672
|
|
|
1425
1673
|
export default defineConfig(
|
|
@@ -1440,11 +1688,43 @@ export default defineConfig(
|
|
|
1440
1688
|
fileName: (format: string) => (format === 'es' ? 'index.js' : 'index.cjs'),
|
|
1441
1689
|
},
|
|
1442
1690
|
outDir: 'dist/src/core',
|
|
1691
|
+
rolldownOptions: {
|
|
1692
|
+
external: (id: string) => resolveExternal(id, { peers, refused: [], siblings: [] }),
|
|
1693
|
+
},
|
|
1694
|
+
},
|
|
1695
|
+
}),
|
|
1696
|
+
)
|
|
1697
|
+
`,
|
|
1698
|
+
vue: `import { defineConfig } from 'vite'
|
|
1699
|
+
import {
|
|
1700
|
+
declarationRollup,
|
|
1701
|
+
resolveExternal,
|
|
1702
|
+
rewriteBrowserSpecifier,
|
|
1703
|
+
rewriteCoreSpecifier,
|
|
1704
|
+
} from '../helpers.js'
|
|
1705
|
+
import { peers, srcVue, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1706
|
+
|
|
1707
|
+
const siblings = {
|
|
1708
|
+
{{siblings}}
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
export default defineConfig(
|
|
1712
|
+
srcVue({
|
|
1713
|
+
plugins: [
|
|
1714
|
+
declarationRollup({
|
|
1715
|
+
project: resolveWorkspacePath('configs/src/tsconfig.vue.json'),
|
|
1716
|
+
rewrite: (content) => rewriteBrowserSpecifier(rewriteCoreSpecifier(content)),
|
|
1717
|
+
}),
|
|
1718
|
+
],
|
|
1719
|
+
build: {
|
|
1443
1720
|
rolldownOptions: {
|
|
1444
1721
|
external: (id: string) =>
|
|
1445
|
-
id
|
|
1446
|
-
|
|
1447
|
-
|
|
1722
|
+
resolveExternal(id, {
|
|
1723
|
+
peers,
|
|
1724
|
+
refused: {{refused}},
|
|
1725
|
+
siblings: Object.keys(siblings),
|
|
1726
|
+
}),
|
|
1727
|
+
output: { paths: siblings },
|
|
1448
1728
|
},
|
|
1449
1729
|
},
|
|
1450
1730
|
}),
|
|
@@ -1486,7 +1766,8 @@ export default defineConfig(
|
|
|
1486
1766
|
`
|
|
1487
1767
|
}),
|
|
1488
1768
|
bin: `import { defineConfig } from 'vite'
|
|
1489
|
-
import {
|
|
1769
|
+
import { resolveExternal } from '../helpers.js'
|
|
1770
|
+
import { peers, srcBin } from '../../vite.config.ts'
|
|
1490
1771
|
|
|
1491
1772
|
// The \`scaffold\` executable build — a single ESM lib file, no declarations (an
|
|
1492
1773
|
// executable ships no types), with the \`#!/usr/bin/env node\` shebang re-emitted through
|
|
@@ -1497,6 +1778,8 @@ export default defineConfig(
|
|
|
1497
1778
|
srcBin({
|
|
1498
1779
|
build: {
|
|
1499
1780
|
rolldownOptions: {
|
|
1781
|
+
external: (id: string) =>
|
|
1782
|
+
id.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] }),
|
|
1500
1783
|
output: {
|
|
1501
1784
|
banner: '#!/usr/bin/env node',
|
|
1502
1785
|
{{paths}}
|
|
@@ -1507,6 +1790,11 @@ export default defineConfig(
|
|
|
1507
1790
|
)
|
|
1508
1791
|
`,
|
|
1509
1792
|
app: Object.freeze({
|
|
1793
|
+
vue: `import { defineConfig } from 'vite'
|
|
1794
|
+
import { appVue } from '../../vite.config.ts'
|
|
1795
|
+
|
|
1796
|
+
export default defineConfig(appVue())
|
|
1797
|
+
`,
|
|
1510
1798
|
browser: `import { defineConfig } from 'vite'
|
|
1511
1799
|
import { appBrowser } from '../../vite.config.ts'
|
|
1512
1800
|
|
|
@@ -1520,7 +1808,7 @@ export default defineConfig(appServer())
|
|
|
1520
1808
|
showcase: `import { defineConfig } from 'vite'
|
|
1521
1809
|
import { appShowcase } from '../../vite.config.ts'
|
|
1522
1810
|
|
|
1523
|
-
export default defineConfig(appShowcase())
|
|
1811
|
+
export default defineConfig(({ mode }) => appShowcase(mode))
|
|
1524
1812
|
`,
|
|
1525
1813
|
journey: `import type { JourneyVariant } from '@orkestrel/test'
|
|
1526
1814
|
import { defineConfig } from 'vitest/config'
|
|
@@ -1532,11 +1820,11 @@ const VARIANTS: readonly JourneyVariant[] = Object.freeze([
|
|
|
1532
1820
|
{ name: 'compact', width: 390, height: 844 },
|
|
1533
1821
|
])
|
|
1534
1822
|
|
|
1535
|
-
export default defineConfig({
|
|
1823
|
+
export default defineConfig(({ mode }) => ({
|
|
1536
1824
|
test: {
|
|
1537
|
-
projects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS)),
|
|
1825
|
+
projects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS, mode)),
|
|
1538
1826
|
},
|
|
1539
|
-
})
|
|
1827
|
+
}))
|
|
1540
1828
|
`
|
|
1541
1829
|
})
|
|
1542
1830
|
}),
|
|
@@ -1879,7 +2167,38 @@ export function resolveBrowser(
|
|
|
1879
2167
|
*/
|
|
1880
2168
|
var ARTIFACT_TEMPLATES = Object.freeze({
|
|
1881
2169
|
source: Object.freeze({
|
|
2170
|
+
sheet: Object.freeze({
|
|
2171
|
+
"index.scss": "@use 'tokens';\n@use 'elements';\n@use 'components';\n@use 'utilities';\n",
|
|
2172
|
+
"_tokens.scss": "@layer theme, reset, base, elements, components, utilities;\n",
|
|
2173
|
+
"_mixins.scss": "",
|
|
2174
|
+
"elements/_index.scss": "",
|
|
2175
|
+
"components/_index.scss": "",
|
|
2176
|
+
"utilities/_index.scss": "",
|
|
2177
|
+
"sheet.ts": "import './index.scss'\n",
|
|
2178
|
+
"index.ts": "export * from './sheet.js'\n"
|
|
2179
|
+
}),
|
|
2180
|
+
themes: Object.freeze({
|
|
2181
|
+
"index.scss": "@use '../tokens';\n@use 'default';\n",
|
|
2182
|
+
"_default.scss": "",
|
|
2183
|
+
"sheet.ts": "import './index.scss'\n"
|
|
2184
|
+
}),
|
|
1882
2185
|
empty: "",
|
|
2186
|
+
barrel: "// TODO: [Feature] Export the browser extension API.\n",
|
|
2187
|
+
main: `document.body
|
|
2188
|
+
.appendChild(document.createElement('main'))
|
|
2189
|
+
.appendChild(document.createElement('h1')).textContent ={{heading}}
|
|
2190
|
+
`,
|
|
2191
|
+
vue: Object.freeze({
|
|
2192
|
+
"main.ts": `import { createApp } from 'vue'
|
|
2193
|
+
import App from './App.vue'
|
|
2194
|
+
|
|
2195
|
+
createApp(App).mount(document.body.appendChild(document.createElement('main')))
|
|
2196
|
+
`,
|
|
2197
|
+
"App.vue": `<template>
|
|
2198
|
+
<h1>{{heading}}</h1>
|
|
2199
|
+
</template>
|
|
2200
|
+
`
|
|
2201
|
+
}),
|
|
1883
2202
|
browser: `<!doctype html>
|
|
1884
2203
|
<html lang="en">
|
|
1885
2204
|
<head>
|
|
@@ -1894,9 +2213,263 @@ var ARTIFACT_TEMPLATES = Object.freeze({
|
|
|
1894
2213
|
`
|
|
1895
2214
|
}),
|
|
1896
2215
|
tests: Object.freeze({
|
|
2216
|
+
journey: `import {
|
|
2217
|
+
ACCESSIBLE_ROLES,
|
|
2218
|
+
createPortfolio,
|
|
2219
|
+
expandCaptures,
|
|
2220
|
+
isRendered,
|
|
2221
|
+
readRefusal,
|
|
2222
|
+
readStyle,
|
|
2223
|
+
} from '@orkestrel/test/browser'
|
|
2224
|
+
{{imports}}import { page } from 'vitest/browser'
|
|
2225
|
+
import { describe, expect, inject, it } from 'vitest'
|
|
2226
|
+
|
|
2227
|
+
const VARIANT = inject('variant')
|
|
2228
|
+
const VARIANTS = inject('variants')
|
|
2229
|
+
const CAPTURE = inject('capture')
|
|
2230
|
+
|
|
2231
|
+
describe('{{application}} arrival journey', () => {
|
|
2232
|
+
it('proves the declared arrival families', async () => {
|
|
2233
|
+
const families = new Set(['Journey', 'Refusal', 'Matrix', ...(CAPTURE ? ['Capture'] : [])])
|
|
2234
|
+
const proven = new Set<string>()
|
|
2235
|
+
const states = ['{{application}}-arrival']
|
|
2236
|
+
const placed = new Set<string>()
|
|
2237
|
+
const portfolio = createPortfolio({
|
|
2238
|
+
states,
|
|
2239
|
+
variants: VARIANTS,
|
|
2240
|
+
variant: VARIANT,
|
|
2241
|
+
directory: '../../../tmp/captures/states',
|
|
2242
|
+
enabled: CAPTURE,
|
|
2243
|
+
})
|
|
2244
|
+
{{mount}} try {
|
|
2245
|
+
{{arrival}} const heading = page
|
|
2246
|
+
.getByRole('heading', {
|
|
2247
|
+
name: {{heading}},
|
|
2248
|
+
exact: true,
|
|
2249
|
+
level: 1,
|
|
2250
|
+
})
|
|
2251
|
+
.element()
|
|
2252
|
+
expect(isRendered(heading)).toBe(true)
|
|
2253
|
+
proven.add('Journey')
|
|
2254
|
+
await portfolio.place('{{application}}-arrival')
|
|
2255
|
+
placed.add('{{application}}-arrival')
|
|
2256
|
+
|
|
2257
|
+
for (const role of ACCESSIBLE_ROLES) expect(page.getByRole(role).elements()).toEqual([])
|
|
2258
|
+
expect(readRefusal('Continue')).toBe(
|
|
2259
|
+
'No interactive element has the accessible name "Continue"',
|
|
2260
|
+
)
|
|
2261
|
+
proven.add('Refusal')
|
|
2262
|
+
|
|
2263
|
+
const measured = new Set<string>()
|
|
2264
|
+
for (const variant of VARIANTS) {
|
|
2265
|
+
await page.viewport(variant.width, variant.height)
|
|
2266
|
+
expect(readStyle(heading, 'display')).toBe('block')
|
|
2267
|
+
expect(window.innerWidth).toBe(variant.width)
|
|
2268
|
+
measured.add(variant.name)
|
|
2269
|
+
}
|
|
2270
|
+
expect(measured).toEqual(new Set(VARIANTS.map(({ name }) => name)))
|
|
2271
|
+
proven.add('Matrix')
|
|
2272
|
+
|
|
2273
|
+
const files = expandCaptures(states, VARIANTS)
|
|
2274
|
+
expect(portfolio.files).toEqual(files)
|
|
2275
|
+
expect(new Set(files).size).toBe(states.length * VARIANTS.length)
|
|
2276
|
+
expect(placed).toEqual(new Set(states))
|
|
2277
|
+
const expected = CAPTURE
|
|
2278
|
+
? expandCaptures(
|
|
2279
|
+
states,
|
|
2280
|
+
VARIANTS.filter(({ name }) => name === VARIANT),
|
|
2281
|
+
)
|
|
2282
|
+
: []
|
|
2283
|
+
expect(portfolio.paths.map((path) => path.replaceAll('\\\\', '/').split('/').at(-1))).toEqual(
|
|
2284
|
+
expected,
|
|
2285
|
+
)
|
|
2286
|
+
if (CAPTURE) proven.add('Capture')
|
|
2287
|
+
expect(proven).toEqual(families)
|
|
2288
|
+
} finally {
|
|
2289
|
+
{{cleanup}} const variant = VARIANTS.find(({ name }) => name === VARIANT)
|
|
2290
|
+
if (variant !== undefined) await page.viewport(variant.width, variant.height)
|
|
2291
|
+
}
|
|
2292
|
+
})
|
|
2293
|
+
})
|
|
2294
|
+
`,
|
|
2295
|
+
browser: `import type { JourneyVariant } from '@orkestrel/test'
|
|
2296
|
+
|
|
2297
|
+
declare module 'vitest' {
|
|
2298
|
+
export interface ProvidedContext {
|
|
2299
|
+
readonly variant: string
|
|
2300
|
+
readonly variants: readonly JourneyVariant[]
|
|
2301
|
+
readonly capture: boolean
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
`,
|
|
2305
|
+
sheet: `import sheet from '/dist/src/{{name}}/index.css?raw'
|
|
2306
|
+
import { describe, expect, it } from 'vitest'
|
|
2307
|
+
import { adoptSheet, readLayerNames } from '{{setup}}'
|
|
2308
|
+
|
|
2309
|
+
describe('{{name}} entry', () => {
|
|
2310
|
+
it('opens with the declared cascade order', () => {
|
|
2311
|
+
const adopted = adoptSheet(sheet)
|
|
2312
|
+
try {
|
|
2313
|
+
expect(adopted.sheet.cssRules[0]?.cssText).toBe(
|
|
2314
|
+
'@layer theme, reset, base, elements, components, utilities;',
|
|
2315
|
+
)
|
|
2316
|
+
expect(readLayerNames(adopted.sheet).slice(0, 6)).toEqual([
|
|
2317
|
+
'theme',
|
|
2318
|
+
'reset',
|
|
2319
|
+
'base',
|
|
2320
|
+
'elements',
|
|
2321
|
+
'components',
|
|
2322
|
+
'utilities',
|
|
2323
|
+
])
|
|
2324
|
+
} finally {
|
|
2325
|
+
adopted.release()
|
|
2326
|
+
}
|
|
2327
|
+
})
|
|
2328
|
+
})
|
|
2329
|
+
`,
|
|
2330
|
+
styles: Object.freeze({
|
|
2331
|
+
module: `/** Carries a CSSOM rule and its enclosing layer. */
|
|
2332
|
+
export interface SheetEntry {
|
|
2333
|
+
readonly rule: CSSRule
|
|
2334
|
+
readonly layer: string | undefined
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
/** Describes an adopted stylesheet and its idempotent release operation. */
|
|
2338
|
+
export interface SheetAdoption {
|
|
2339
|
+
readonly sheet: CSSStyleSheet
|
|
2340
|
+
release(): void
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
/**
|
|
2344
|
+
* Adopts CSS text into the document with an idempotent release operation.
|
|
2345
|
+
* @param text - The compiled sheet text.
|
|
2346
|
+
* @returns The adopted sheet and its release operation.
|
|
2347
|
+
* @example
|
|
2348
|
+
* \`\`\`ts
|
|
2349
|
+
* const adopted = adoptSheet('.sample { color: red }')
|
|
2350
|
+
* adopted.release()
|
|
2351
|
+
* \`\`\`
|
|
2352
|
+
*/
|
|
2353
|
+
export function adoptSheet(text: string): SheetAdoption {
|
|
2354
|
+
const sheet = new CSSStyleSheet()
|
|
2355
|
+
sheet.replaceSync(text)
|
|
2356
|
+
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]
|
|
2357
|
+
return {
|
|
2358
|
+
sheet,
|
|
2359
|
+
release: () => {
|
|
2360
|
+
document.adoptedStyleSheets = document.adoptedStyleSheets.filter(
|
|
2361
|
+
(candidate) => candidate !== sheet,
|
|
2362
|
+
)
|
|
2363
|
+
},
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
/**
|
|
2368
|
+
* Reads layer statements and blocks in declaration order, including repeated names.
|
|
2369
|
+
* @param sheet - The parsed sheet.
|
|
2370
|
+
* @returns Qualified layer names, with an empty name for an anonymous layer.
|
|
2371
|
+
* @example
|
|
2372
|
+
* \`\`\`ts
|
|
2373
|
+
* readLayerNames(new CSSStyleSheet()) // []
|
|
2374
|
+
* \`\`\`
|
|
2375
|
+
*/
|
|
2376
|
+
export function readLayerNames(sheet: CSSStyleSheet): readonly string[] {
|
|
2377
|
+
const pending: SheetEntry[] = Array.from(sheet.cssRules, (rule) => ({
|
|
2378
|
+
rule,
|
|
2379
|
+
layer: undefined,
|
|
2380
|
+
})).reverse()
|
|
2381
|
+
const names: string[] = []
|
|
2382
|
+
while (pending.length > 0) {
|
|
2383
|
+
const entry = pending.pop()
|
|
2384
|
+
if (entry === undefined) break
|
|
2385
|
+
const { rule, layer } = entry
|
|
2386
|
+
const declared =
|
|
2387
|
+
rule instanceof CSSLayerStatementRule
|
|
2388
|
+
? rule.nameList
|
|
2389
|
+
: rule instanceof CSSLayerBlockRule
|
|
2390
|
+
? [rule.name]
|
|
2391
|
+
: []
|
|
2392
|
+
for (const name of declared) names.push(layer === undefined ? name : layer + '.' + name)
|
|
2393
|
+
if (!(rule instanceof CSSGroupingRule)) continue
|
|
2394
|
+
const parent =
|
|
2395
|
+
rule instanceof CSSLayerBlockRule
|
|
2396
|
+
? layer === undefined
|
|
2397
|
+
? rule.name
|
|
2398
|
+
: layer + '.' + rule.name
|
|
2399
|
+
: layer
|
|
2400
|
+
for (const child of Array.from(rule.cssRules).reverse()) {
|
|
2401
|
+
pending.push({ rule: child, layer: parent })
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
return names
|
|
2405
|
+
}
|
|
2406
|
+
`,
|
|
2407
|
+
proof: `import type { SheetAdoption } from './setupStyles.js'
|
|
2408
|
+
import { describe, expect, it } from 'vitest'
|
|
2409
|
+
import { adoptSheet, readLayerNames } from './setupStyles.js'
|
|
2410
|
+
|
|
2411
|
+
describe('CSSOM instruments', () => {
|
|
2412
|
+
it('adopts and releases only its own sheet, including repeated release', () => {
|
|
2413
|
+
const previous = [...document.adoptedStyleSheets]
|
|
2414
|
+
const first: SheetAdoption = adoptSheet('.sample { color: red }')
|
|
2415
|
+
try {
|
|
2416
|
+
const second = adoptSheet('.other { display: block }')
|
|
2417
|
+
try {
|
|
2418
|
+
expect(document.adoptedStyleSheets).toEqual([...previous, first.sheet, second.sheet])
|
|
2419
|
+
expect(first.sheet.cssRules.length).toBe(1)
|
|
2420
|
+
first.release()
|
|
2421
|
+
first.release()
|
|
2422
|
+
expect(document.adoptedStyleSheets).toEqual([...previous, second.sheet])
|
|
2423
|
+
} finally {
|
|
2424
|
+
second.release()
|
|
2425
|
+
}
|
|
2426
|
+
} finally {
|
|
2427
|
+
first.release()
|
|
2428
|
+
}
|
|
2429
|
+
expect(document.adoptedStyleSheets).toEqual(previous)
|
|
2430
|
+
})
|
|
2431
|
+
|
|
2432
|
+
it('reads statements, blocks, nested conditions, and anonymous layers in order', () => {
|
|
2433
|
+
const adopted = adoptSheet(
|
|
2434
|
+
'@layer first, second; @layer first { @media all { @layer nested {} } } @layer {}',
|
|
2435
|
+
)
|
|
2436
|
+
try {
|
|
2437
|
+
expect(readLayerNames(adopted.sheet)).toEqual([
|
|
2438
|
+
'first',
|
|
2439
|
+
'second',
|
|
2440
|
+
'first',
|
|
2441
|
+
'first.nested',
|
|
2442
|
+
'',
|
|
2443
|
+
])
|
|
2444
|
+
} finally {
|
|
2445
|
+
adopted.release()
|
|
2446
|
+
}
|
|
2447
|
+
})
|
|
2448
|
+
|
|
2449
|
+
it('returns no layer names for an empty sheet or an unlayered rule', () => {
|
|
2450
|
+
const sheet = new CSSStyleSheet()
|
|
2451
|
+
expect(readLayerNames(sheet)).toEqual([])
|
|
2452
|
+
sheet.replaceSync('.sample { color: red }')
|
|
2453
|
+
expect(readLayerNames(sheet)).toEqual([])
|
|
2454
|
+
})
|
|
2455
|
+
})
|
|
2456
|
+
`
|
|
2457
|
+
}),
|
|
1897
2458
|
setup: "",
|
|
1898
|
-
global:
|
|
2459
|
+
global: Object.freeze({
|
|
2460
|
+
module: `export function setup(): void {}
|
|
1899
2461
|
`,
|
|
2462
|
+
proof: `import { describe, expect, it } from 'vitest'
|
|
2463
|
+
import { setup } from './setupGlobal.js'
|
|
2464
|
+
|
|
2465
|
+
describe('global setup', () => {
|
|
2466
|
+
it('runs without producing a teardown', () => {
|
|
2467
|
+
expect(setup()).toBeUndefined()
|
|
2468
|
+
expect(setup()).toBeUndefined()
|
|
2469
|
+
})
|
|
2470
|
+
})
|
|
2471
|
+
`
|
|
2472
|
+
}),
|
|
1900
2473
|
entry: `import * as entry from {{specifier}}
|
|
1901
2474
|
import { describe, expect, it } from 'vitest'
|
|
1902
2475
|
|
|
@@ -3256,6 +3829,80 @@ function isCollection(value) {
|
|
|
3256
3829
|
*/
|
|
3257
3830
|
var isEnvironment = (0, _orkestrel_contract.literalOf)(ENVIRONMENTS);
|
|
3258
3831
|
/**
|
|
3832
|
+
* Narrows a value to a surface an extension can extend.
|
|
3833
|
+
* @param value - The candidate surface.
|
|
3834
|
+
* @returns True if the value is a supported surface; false otherwise.
|
|
3835
|
+
* @example
|
|
3836
|
+
* ```ts
|
|
3837
|
+
* import { isSurface } from '@orkestrel/scaffold'
|
|
3838
|
+
*
|
|
3839
|
+
* isSurface('styles') // true
|
|
3840
|
+
* isSurface('themes') // false
|
|
3841
|
+
* ```
|
|
3842
|
+
*/
|
|
3843
|
+
var isSurface = (0, _orkestrel_contract.literalOf)(SURFACES);
|
|
3844
|
+
/**
|
|
3845
|
+
* Narrows a value to a non-reserved sheet face name.
|
|
3846
|
+
* @param value - The candidate name.
|
|
3847
|
+
* @returns True if the name matches the workspace pattern and is not reserved; false otherwise.
|
|
3848
|
+
* @example
|
|
3849
|
+
* ```ts
|
|
3850
|
+
* import { isSheetName } from '@orkestrel/scaffold'
|
|
3851
|
+
*
|
|
3852
|
+
* isSheetName('print') // true
|
|
3853
|
+
* isSheetName('styles') // false
|
|
3854
|
+
* ```
|
|
3855
|
+
*/
|
|
3856
|
+
function isSheetName(value) {
|
|
3857
|
+
return (0, _orkestrel_contract.isString)(value) && value.length <= 203 && NAME_PATTERN.test(value) && !RESERVED_SHEET_NAMES.includes(value);
|
|
3858
|
+
}
|
|
3859
|
+
/**
|
|
3860
|
+
* Narrows a value to a supported browser framework with distinct occupied axes.
|
|
3861
|
+
* @param value - The candidate extension.
|
|
3862
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
3863
|
+
* @example
|
|
3864
|
+
* ```ts
|
|
3865
|
+
* import { isBrowserExtension } from '@orkestrel/scaffold'
|
|
3866
|
+
*
|
|
3867
|
+
* isBrowserExtension({ surface: 'browser', name: 'vue', axes: ['app'] }) // true
|
|
3868
|
+
* isBrowserExtension(undefined) // false
|
|
3869
|
+
* ```
|
|
3870
|
+
*/
|
|
3871
|
+
var isBrowserExtension = (0, _orkestrel_contract.andOf)((0, _orkestrel_contract.recordOf)({
|
|
3872
|
+
surface: (0, _orkestrel_contract.literalOf)("browser"),
|
|
3873
|
+
name: (0, _orkestrel_contract.literalOf)(FRAMEWORKS),
|
|
3874
|
+
axes: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)((0, _orkestrel_contract.literalOf)(AXES)))
|
|
3875
|
+
}), (extension) => new Set(extension.axes).size === extension.axes.length);
|
|
3876
|
+
/**
|
|
3877
|
+
* Narrows a value to a named non-reserved stylesheet face.
|
|
3878
|
+
* @param value - The candidate extension.
|
|
3879
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
3880
|
+
* @example
|
|
3881
|
+
* ```ts
|
|
3882
|
+
* import { isStylesExtension } from '@orkestrel/scaffold'
|
|
3883
|
+
*
|
|
3884
|
+
* isStylesExtension({ surface: 'styles', name: 'print' }) // true
|
|
3885
|
+
* isStylesExtension(undefined) // false
|
|
3886
|
+
* ```
|
|
3887
|
+
*/
|
|
3888
|
+
var isStylesExtension = (0, _orkestrel_contract.recordOf)({
|
|
3889
|
+
surface: (0, _orkestrel_contract.literalOf)("styles"),
|
|
3890
|
+
name: isSheetName
|
|
3891
|
+
});
|
|
3892
|
+
/**
|
|
3893
|
+
* Narrows a value to an extension of a supported surface.
|
|
3894
|
+
* @param value - The candidate extension.
|
|
3895
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
3896
|
+
* @example
|
|
3897
|
+
* ```ts
|
|
3898
|
+
* import { isExtension } from '@orkestrel/scaffold'
|
|
3899
|
+
*
|
|
3900
|
+
* isExtension({ surface: 'styles', name: 'print' }) // true
|
|
3901
|
+
* isExtension(undefined) // false
|
|
3902
|
+
* ```
|
|
3903
|
+
*/
|
|
3904
|
+
var isExtension = (0, _orkestrel_contract.unionOf)(isBrowserExtension, isStylesExtension);
|
|
3905
|
+
/**
|
|
3259
3906
|
* Narrows a value to one {@link Group} a plan selects over.
|
|
3260
3907
|
*
|
|
3261
3908
|
* @example
|
|
@@ -3392,6 +4039,9 @@ var isBlueprint = (0, _orkestrel_contract.recordOf)({
|
|
|
3392
4039
|
keywords: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isString)),
|
|
3393
4040
|
src: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isEnvironment)),
|
|
3394
4041
|
app: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isEnvironment)),
|
|
4042
|
+
extensions: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isExtension)),
|
|
4043
|
+
styles: _orkestrel_contract.isBoolean,
|
|
4044
|
+
themes: _orkestrel_contract.isBoolean,
|
|
3395
4045
|
dependencies: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isDependency)),
|
|
3396
4046
|
peers: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isDependency)),
|
|
3397
4047
|
extras: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isDependency)),
|
|
@@ -3686,6 +4336,34 @@ function cloneValue(value) {
|
|
|
3686
4336
|
//#endregion
|
|
3687
4337
|
//#region src/core/parsers.ts
|
|
3688
4338
|
/**
|
|
4339
|
+
* Coerces an extension value or a `surface:name` selection into an extension.
|
|
4340
|
+
* @param value - An extension record or its selection text.
|
|
4341
|
+
* @returns The extension, or `undefined` for a malformed or unsupported selection.
|
|
4342
|
+
* @remarks Browser text has empty axes; the creating command supplies its selected browser axes.
|
|
4343
|
+
* @example
|
|
4344
|
+
* ```ts
|
|
4345
|
+
* import { parseExtension } from '@orkestrel/scaffold'
|
|
4346
|
+
*
|
|
4347
|
+
* parseExtension('browser:vue') // { surface: 'browser', name: 'vue', axes: [] }
|
|
4348
|
+
* parseExtension('styles:print') // { surface: 'styles', name: 'print' }
|
|
4349
|
+
* ```
|
|
4350
|
+
*/
|
|
4351
|
+
function parseExtension(value) {
|
|
4352
|
+
if (isExtension(value)) return value;
|
|
4353
|
+
if (!(0, _orkestrel_contract.isString)(value)) return void 0;
|
|
4354
|
+
const [surface, name, excess] = value.split(":");
|
|
4355
|
+
if (excess !== void 0 || !isSurface(surface)) return void 0;
|
|
4356
|
+
const candidate = surface === "browser" ? {
|
|
4357
|
+
surface,
|
|
4358
|
+
name,
|
|
4359
|
+
axes: []
|
|
4360
|
+
} : {
|
|
4361
|
+
surface,
|
|
4362
|
+
name
|
|
4363
|
+
};
|
|
4364
|
+
return isExtension(candidate) ? candidate : void 0;
|
|
4365
|
+
}
|
|
4366
|
+
/**
|
|
3689
4367
|
* Coerces an untrusted value to a {@link Blueprint}.
|
|
3690
4368
|
*
|
|
3691
4369
|
* @param value - The value to parse.
|
|
@@ -4771,6 +5449,67 @@ function renderSkillPointer(canonical, name) {
|
|
|
4771
5449
|
//#endregion
|
|
4772
5450
|
//#region src/core/compilers.ts
|
|
4773
5451
|
/**
|
|
5452
|
+
* Projects a blueprint into browser extensions restricted to occupied browser axes.
|
|
5453
|
+
* @param blueprint - The workspace specification.
|
|
5454
|
+
* @returns Browser extensions with their occupied axes, omitting unplaced extensions.
|
|
5455
|
+
* @example
|
|
5456
|
+
* ```ts
|
|
5457
|
+
* import { blueprintToFaces, createBlueprint } from '@orkestrel/scaffold'
|
|
5458
|
+
*
|
|
5459
|
+
* blueprintToFaces(createBlueprint('desk', { app: ['core'] })).length // 0
|
|
5460
|
+
* ```
|
|
5461
|
+
*/
|
|
5462
|
+
function blueprintToFaces(blueprint) {
|
|
5463
|
+
return blueprint.extensions.flatMap((extension) => {
|
|
5464
|
+
if (extension.surface !== "browser") return [];
|
|
5465
|
+
const axes = extension.axes.filter((axis) => blueprint[axis].includes("browser"));
|
|
5466
|
+
return axes.length === 0 ? [] : [{
|
|
5467
|
+
...extension,
|
|
5468
|
+
axes
|
|
5469
|
+
}];
|
|
5470
|
+
});
|
|
5471
|
+
}
|
|
5472
|
+
/**
|
|
5473
|
+
* Projects a blueprint into its validated sheet-face names in stable order.
|
|
5474
|
+
* @param blueprint - The workspace specification.
|
|
5475
|
+
* @returns The base face followed by named styles extensions; themes remain a separate target.
|
|
5476
|
+
* @example
|
|
5477
|
+
* ```ts
|
|
5478
|
+
* import { blueprintToSheets, createBlueprint } from '@orkestrel/scaffold'
|
|
5479
|
+
*
|
|
5480
|
+
* blueprintToSheets(createBlueprint('paper', { styles: true })) // ['styles']
|
|
5481
|
+
* ```
|
|
5482
|
+
*/
|
|
5483
|
+
function blueprintToSheets(blueprint) {
|
|
5484
|
+
return [...blueprint.styles ? ["styles"] : [], ...(0, _orkestrel_contract.sortValues)(blueprint.extensions.flatMap((extension) => extension.surface === "styles" && isSheetName(extension.name) ? [extension.name] : []))];
|
|
5485
|
+
}
|
|
5486
|
+
/**
|
|
5487
|
+
* Projects published environments and sheets into the manifest export map.
|
|
5488
|
+
* @param blueprint - The workspace specification.
|
|
5489
|
+
* @returns JavaScript conditions and CSS and SCSS subpaths, without an invented JavaScript root.
|
|
5490
|
+
* @example
|
|
5491
|
+
* ```ts
|
|
5492
|
+
* import { blueprintToExports, createBlueprint } from '@orkestrel/scaffold'
|
|
5493
|
+
*
|
|
5494
|
+
* blueprintToExports(createBlueprint('paper', { styles: true }))['./styles']
|
|
5495
|
+
* // './dist/src/styles/index.css'
|
|
5496
|
+
* ```
|
|
5497
|
+
*/
|
|
5498
|
+
function blueprintToExports(blueprint) {
|
|
5499
|
+
const exports = { ...srcToExports(blueprint.src) };
|
|
5500
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
5501
|
+
if (extension.surface !== "browser" || !extension.axes.includes("src")) continue;
|
|
5502
|
+
exports[`./${extension.name}`] = pathToCondition(`./dist/src/${extension.name}/index`, ["es"]);
|
|
5503
|
+
if (blueprint.src.includes("browser")) exports["./browser"] = pathToCondition("./dist/src/browser/index", ["es"]);
|
|
5504
|
+
}
|
|
5505
|
+
for (const name of [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []]) {
|
|
5506
|
+
exports[`./${name}`] = `./dist/src/${name}/index.css`;
|
|
5507
|
+
exports[`./${name}/scss`] = `./src/${name}/index.scss`;
|
|
5508
|
+
}
|
|
5509
|
+
if (Object.keys(exports).length > 0) exports["./package.json"] = "./package.json";
|
|
5510
|
+
return exports;
|
|
5511
|
+
}
|
|
5512
|
+
/**
|
|
4774
5513
|
* Builds one `exports` condition block for a built environment.
|
|
4775
5514
|
*
|
|
4776
5515
|
* @param path - The extensionless `dist` path both conditions point at.
|
|
@@ -4917,18 +5656,21 @@ function srcToExports(src) {
|
|
|
4917
5656
|
* ```
|
|
4918
5657
|
*/
|
|
4919
5658
|
function blueprintToDevDependencies(blueprint) {
|
|
5659
|
+
const sheets = blueprintToSheets(blueprint).length > 0 || blueprint.themes;
|
|
4920
5660
|
const merged = {
|
|
4921
5661
|
...BASE_DEV_DEPENDENCIES,
|
|
5662
|
+
...sheets ? STYLES_DEV_DEPENDENCIES : {},
|
|
4922
5663
|
...blueprint.src.length > 0 || blueprint.bin ? DECLARATION_DEV_DEPENDENCIES : {},
|
|
4923
|
-
...blueprint.src.includes("browser") || blueprint.setup.includes("browser") ? SOURCE_BROWSER_DEV_DEPENDENCIES : {},
|
|
5664
|
+
...blueprint.src.includes("browser") || blueprint.setup.includes("browser") || sheets ? SOURCE_BROWSER_DEV_DEPENDENCIES : {},
|
|
4924
5665
|
...blueprint.app.length > 0 ? APP_DEV_DEPENDENCIES : {},
|
|
4925
5666
|
...blueprint.app.includes("browser") ? APP_BROWSER_DEV_DEPENDENCIES : {},
|
|
4926
5667
|
...blueprint.showcase && blueprint.app.includes("browser") ? SHOWCASE_DEV_DEPENDENCIES : {},
|
|
4927
5668
|
...blueprint.app.includes("server") ? APP_SERVER_DEV_DEPENDENCIES : {}
|
|
4928
5669
|
};
|
|
5670
|
+
for (const framework of blueprintToMachinery(blueprint).frameworks) Object.assign(merged, FRAMEWORK_MATRIX[framework].dependencies);
|
|
4929
5671
|
for (const extra of blueprint.extras) merged[extra.name] = extra.range;
|
|
4930
5672
|
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;
|
|
5673
|
+
const own = blueprint.src.length > 0 || sheets ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
4932
5674
|
const runtime = new Set(blueprint.dependencies.map((dependency) => dependency.name));
|
|
4933
5675
|
return Object.fromEntries(Object.entries(merged).filter(([name]) => name !== own && !runtime.has(name)).sort(([left], [right]) => (0, _orkestrel_contract.compareValues)(left, right)));
|
|
4934
5676
|
}
|
|
@@ -4969,11 +5711,22 @@ function blueprintToDevDependencies(blueprint) {
|
|
|
4969
5711
|
* ```
|
|
4970
5712
|
*/
|
|
4971
5713
|
function blueprintToScripts(blueprint) {
|
|
4972
|
-
const
|
|
5714
|
+
const source = blueprintToFaces(blueprint).flatMap((extension) => extension.surface === "browser" && extension.axes.includes("src") ? [extension.name] : []);
|
|
5715
|
+
const application = blueprintToFaces(blueprint).flatMap((extension) => extension.surface === "browser" && extension.axes.includes("app") ? [extension.name] : []);
|
|
5716
|
+
const sheets = blueprintToSheets(blueprint);
|
|
5717
|
+
const targets = [...sheets, ...blueprint.themes && !blueprint.styles ? ["themes"] : []];
|
|
5718
|
+
const checker = application.includes("vue") ? FRAMEWORK_MATRIX.vue.checker : "tsc";
|
|
5719
|
+
const publishes = blueprint.src.length > 0 || targets.length > 0;
|
|
4973
5720
|
const integrates = blueprint.integration;
|
|
4974
5721
|
const compiles = publishes || blueprint.bin;
|
|
4975
5722
|
const runtime = blueprint.app.filter((environment) => environment !== "core");
|
|
4976
5723
|
const vitest = "vitest run --config vite.config.ts --no-cache --reporter=dot";
|
|
5724
|
+
const checks = [
|
|
5725
|
+
...blueprint.src,
|
|
5726
|
+
...source,
|
|
5727
|
+
...sheets,
|
|
5728
|
+
...blueprint.bin ? ["bin"] : []
|
|
5729
|
+
].map((name) => `npm run check:src:${name}`);
|
|
4977
5730
|
const scripts = {
|
|
4978
5731
|
clean: "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
4979
5732
|
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 +5735,32 @@ function blueprintToScripts(blueprint) {
|
|
|
4982
5735
|
lint: "oxlint --config .oxlintrc.json --fix .",
|
|
4983
5736
|
"lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
|
|
4984
5737
|
check: [
|
|
4985
|
-
|
|
4986
|
-
...
|
|
5738
|
+
`${checker} --noEmit --project tsconfig.json`,
|
|
5739
|
+
...checks.length > 0 ? ["npm run check:src"] : [],
|
|
4987
5740
|
...blueprint.app.length > 0 ? ["npm run check:app"] : [],
|
|
4988
5741
|
...blueprint.skills ? ["npm run check:skills"] : []
|
|
4989
5742
|
].join(" && ")
|
|
4990
5743
|
};
|
|
4991
|
-
if (
|
|
4992
|
-
scripts["check:src"] =
|
|
5744
|
+
if (checks.length > 0) {
|
|
5745
|
+
scripts["check:src"] = checks.join(" && ");
|
|
4993
5746
|
for (const environment of blueprint.src) scripts[`check:src:${environment}`] = `tsc --noEmit -p configs/src/tsconfig.${environment}.json`;
|
|
4994
5747
|
if (blueprint.bin) scripts["check:src:bin"] = "tsc --noEmit -p configs/src/tsconfig.bin.json";
|
|
5748
|
+
for (const name of [...sheets, ...source]) scripts[`check:src:${name}`] = `tsc --noEmit -p configs/src/tsconfig.${name}.json`;
|
|
4995
5749
|
}
|
|
4996
5750
|
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}`] =
|
|
5751
|
+
scripts["check:app"] = [...blueprint.app, ...application].map((environment) => `npm run check:app:${environment}`).join(" && ");
|
|
5752
|
+
for (const environment of blueprint.app) scripts[`check:app:${environment}`] = `tsc --noEmit -p configs/app/tsconfig.${environment}.json`;
|
|
5753
|
+
for (const name of application) scripts[`check:app:${name}`] = `${FRAMEWORK_MATRIX[name].checker} --noEmit -p configs/app/tsconfig.${name}.json`;
|
|
4999
5754
|
}
|
|
5000
5755
|
if (blueprint.skills) scripts["check:skills"] = `tsc --noEmit -p ${SKILLS_CONFIG_PATH}`;
|
|
5001
5756
|
scripts.test = [
|
|
5002
5757
|
...compiles ? ["npm run test:src"] : [],
|
|
5003
5758
|
...blueprint.app.length > 0 ? ["npm run test:app"] : [],
|
|
5004
|
-
...blueprint.journey && blueprint.app.includes("browser") ? ["npm run test:journey"] : [],
|
|
5759
|
+
...blueprint.journey && blueprint.app.includes("browser") ? ["npm run test:journey", ...application.map((name) => `npm run test:journey:${name}`)] : [],
|
|
5005
5760
|
"npm run test:policy",
|
|
5006
5761
|
"npm run test:config",
|
|
5007
|
-
...blueprint.setup.includes("node") ? ["npm run test:setup"] : [],
|
|
5008
|
-
...blueprint.setup.includes("browser") ? ["npm run test:setup:browser"] : [],
|
|
5762
|
+
...blueprint.setup.includes("node") || blueprint.global ? ["npm run test:setup"] : [],
|
|
5763
|
+
...blueprint.setup.includes("browser") || targets.length > 0 ? ["npm run test:setup:browser"] : [],
|
|
5009
5764
|
...blueprint.skills ? ["npm run test:skills"] : [],
|
|
5010
5765
|
...blueprint.guides ? ["npm run test:guides"] : [],
|
|
5011
5766
|
...blueprint.conformance ? ["npm run test:conformance"] : [],
|
|
@@ -5016,20 +5771,32 @@ function blueprintToScripts(blueprint) {
|
|
|
5016
5771
|
scripts["test:src"] = [
|
|
5017
5772
|
vitest,
|
|
5018
5773
|
...blueprint.src.map((environment) => `--project ${SRC_MATRIX[environment].project}`),
|
|
5774
|
+
...source.map((name) => `--project src:${name}`),
|
|
5019
5775
|
...blueprint.bin ? ["--project src:bin"] : []
|
|
5020
5776
|
].join(" ");
|
|
5021
5777
|
for (const environment of blueprint.src) scripts[`test:src:${environment}`] = `${vitest} --project ${SRC_MATRIX[environment].project}`;
|
|
5022
5778
|
if (blueprint.bin) scripts["test:src:bin"] = `${vitest} --project src:bin`;
|
|
5779
|
+
for (const name of source) scripts[`test:src:${name}`] = `${vitest} --project src:${name}`;
|
|
5780
|
+
scripts["test:src"] = [...blueprint.src.length > 0 || blueprint.bin ? [scripts["test:src"]] : [], ...targets.map((name) => `npm run test:src:${name}`)].join(" && ");
|
|
5781
|
+
for (const name of targets) scripts[`test:src:${name}`] = `npm run build:src:${name} && ${vitest} --project src:${name}`;
|
|
5023
5782
|
}
|
|
5024
5783
|
if (blueprint.app.length > 0) {
|
|
5025
|
-
scripts["test:app"] = [
|
|
5784
|
+
scripts["test:app"] = [
|
|
5785
|
+
vitest,
|
|
5786
|
+
...blueprint.app.map((environment) => `--project ${APP_MATRIX[environment].project}`),
|
|
5787
|
+
...application.map((name) => `--project app:${name}`)
|
|
5788
|
+
].join(" ");
|
|
5026
5789
|
for (const environment of blueprint.app) scripts[`test:app:${environment}`] = `${vitest} --project ${APP_MATRIX[environment].project}`;
|
|
5790
|
+
for (const name of application) scripts[`test:app:${name}`] = `${vitest} --project app:${name}`;
|
|
5027
5791
|
}
|
|
5028
5792
|
scripts["test:policy"] = `${vitest} --project policy`;
|
|
5029
5793
|
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"))
|
|
5794
|
+
if (blueprint.setup.includes("node") || blueprint.global) scripts["test:setup"] = `${vitest} --project setup`;
|
|
5795
|
+
if (blueprint.setup.includes("browser") || targets.length > 0) scripts["test:setup:browser"] = `${vitest} --project setup:browser`;
|
|
5796
|
+
if (blueprint.journey && blueprint.app.includes("browser")) {
|
|
5797
|
+
scripts["test:journey"] = `vitest run --config ${JOURNEY_CONFIG_PATH} --no-cache --reporter=dot`;
|
|
5798
|
+
for (const name of application) scripts[`test:journey:${name}`] = `${scripts["test:journey"]} --mode ${name}`;
|
|
5799
|
+
}
|
|
5033
5800
|
if (blueprint.skills) scripts["test:skills"] = `${vitest} --project skills`;
|
|
5034
5801
|
if (blueprint.guides) scripts["test:guides"] = `node --experimental-strip-types ${GUIDES_TEST_PATH}`;
|
|
5035
5802
|
if (blueprint.conformance) scripts["test:conformance"] = `${vitest} --project conformance`;
|
|
@@ -5044,23 +5811,34 @@ function blueprintToScripts(blueprint) {
|
|
|
5044
5811
|
...blueprint.app.length > 0 ? ["npm run build:app"] : []
|
|
5045
5812
|
].join(" && ");
|
|
5046
5813
|
if (compiles) {
|
|
5047
|
-
scripts["build:src"] = [
|
|
5814
|
+
scripts["build:src"] = [
|
|
5815
|
+
...blueprint.src.map((environment) => `npm run build:src:${environment}`),
|
|
5816
|
+
...source.map((name) => `npm run build:src:${name}`),
|
|
5817
|
+
...targets.map((name) => `npm run build:src:${name}`),
|
|
5818
|
+
...blueprint.bin ? ["npm run build:src:bin"] : []
|
|
5819
|
+
].join(" && ");
|
|
5048
5820
|
for (const environment of blueprint.src) {
|
|
5049
5821
|
const build = `vite build --config configs/src/vite.${environment}.config.ts`;
|
|
5050
5822
|
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
5823
|
}
|
|
5052
5824
|
if (blueprint.bin) scripts["build:src:bin"] = "vite build --config configs/src/vite.bin.config.ts";
|
|
5825
|
+
for (const name of source) scripts[`build:src:${name}`] = `vite build --config configs/src/vite.${name}.config.ts`;
|
|
5826
|
+
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
5827
|
}
|
|
5054
5828
|
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`;
|
|
5829
|
+
scripts["build:app"] = runtime.length > 0 ? [...runtime, ...application].map((environment) => `npm run build:app:${environment}`).join(" && ") : "npm run check:app:core";
|
|
5830
|
+
for (const environment of [...runtime, ...application]) scripts[`build:app:${environment}`] = `vite build --config configs/app/vite.${environment}.config.ts`;
|
|
5057
5831
|
}
|
|
5058
5832
|
if (blueprint.app.includes("browser")) {
|
|
5059
5833
|
scripts.dev = "vite --config configs/app/vite.browser.config.ts";
|
|
5834
|
+
for (const name of application) scripts[`dev:${name}`] = `vite --config configs/app/vite.${name}.config.ts`;
|
|
5060
5835
|
if (blueprint.showcase) {
|
|
5061
5836
|
scripts.showcase = `vite --config ${SHOWCASE_CONFIG_PATH}`;
|
|
5062
5837
|
scripts["build:showcase"] = `vite build --config ${SHOWCASE_CONFIG_PATH}`;
|
|
5063
|
-
|
|
5838
|
+
for (const name of application) {
|
|
5839
|
+
scripts[`showcase:${name}`] = `${scripts.showcase} --mode ${name}`;
|
|
5840
|
+
scripts[`build:showcase:${name}`] = `${scripts["build:showcase"]} --mode ${name}`;
|
|
5841
|
+
}
|
|
5064
5842
|
}
|
|
5065
5843
|
}
|
|
5066
5844
|
if (blueprint.app.includes("server")) {
|
|
@@ -5070,7 +5848,9 @@ function blueprintToScripts(blueprint) {
|
|
|
5070
5848
|
if (publishes) {
|
|
5071
5849
|
scripts.prepack = "npm run build";
|
|
5072
5850
|
scripts.prepublishOnly = [
|
|
5073
|
-
"npm run format:check && npm run lint:check && npm run check && npm run build
|
|
5851
|
+
"npm run format:check && npm run lint:check && npm run check && npm run build",
|
|
5852
|
+
...blueprint.showcase && blueprint.app.includes("browser") ? ["npm run build:showcase", ...application.map((name) => `npm run build:showcase:${name}`)] : [],
|
|
5853
|
+
"npm test",
|
|
5074
5854
|
RELEASE_PROOF_COMMAND,
|
|
5075
5855
|
...blueprint.service ? ["npm run test:service"] : []
|
|
5076
5856
|
].join(" && ");
|
|
@@ -5088,6 +5868,8 @@ function blueprintToScripts(blueprint) {
|
|
|
5088
5868
|
* benchmark workbench scripts. A workspace carrying guides adds `test:guides`,
|
|
5089
5869
|
* whose package-owned entry runs the guides project and handles explicit parity
|
|
5090
5870
|
* rewrites, and one carrying skills adds `test:skills`. Publishing adds the pack and publication lifecycle scripts.
|
|
5871
|
+
* Sheet and framework faces add their check and build scripts, application frameworks add dev scripts,
|
|
5872
|
+
* and selected showcases and journeys add their mode scripts.
|
|
5091
5873
|
* Aggregate test scripts and
|
|
5092
5874
|
* maintainer-owned gate chains stay outside the region.
|
|
5093
5875
|
*
|
|
@@ -5111,13 +5893,18 @@ function blueprintToScripts(blueprint) {
|
|
|
5111
5893
|
*/
|
|
5112
5894
|
function blueprintToWritableScripts(blueprint) {
|
|
5113
5895
|
const scripts = blueprintToScripts(blueprint);
|
|
5896
|
+
const sheets = [...blueprintToSheets(blueprint), ...blueprint.themes && !blueprint.styles ? ["themes"] : []];
|
|
5114
5897
|
const writable = [];
|
|
5115
5898
|
for (const [name, command] of Object.entries(scripts)) {
|
|
5116
|
-
|
|
5899
|
+
const direct = name.startsWith("test:") && name !== "test:src" && name !== "test:app";
|
|
5900
|
+
const sheet = sheets.some((face) => name === `build:src:${face}` || name === `check:src:${face}`);
|
|
5901
|
+
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}`));
|
|
5902
|
+
const showcase = name === "showcase" || name.startsWith("showcase:") || name === "build:showcase" || name.startsWith("build:showcase:");
|
|
5903
|
+
if (!direct && !sheet && !framework && !showcase) continue;
|
|
5117
5904
|
writable.push({
|
|
5118
5905
|
name,
|
|
5119
5906
|
command,
|
|
5120
|
-
accepted: name === "test:guides" ? ["vitest run --config vite.config.ts --no-cache --reporter=dot --project guides"] : []
|
|
5907
|
+
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
5908
|
});
|
|
5122
5909
|
}
|
|
5123
5910
|
const prepack = scripts.prepack;
|
|
@@ -5173,7 +5960,9 @@ function blueprintToWritableScripts(blueprint) {
|
|
|
5173
5960
|
* ```
|
|
5174
5961
|
*/
|
|
5175
5962
|
function blueprintToManifest(blueprint) {
|
|
5176
|
-
const
|
|
5963
|
+
const sheets = blueprintToSheets(blueprint);
|
|
5964
|
+
const targets = [...sheets, ...blueprint.themes ? ["styles/themes"] : []];
|
|
5965
|
+
const publishes = blueprint.src.length > 0 || targets.length > 0;
|
|
5177
5966
|
const name = publishes ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
5178
5967
|
const dependencies = {};
|
|
5179
5968
|
for (const dependency of [...blueprint.dependencies].sort((left, right) => (0, _orkestrel_contract.compareValues)(left.name, right.name))) dependencies[dependency.name] = dependency.range;
|
|
@@ -5200,18 +5989,19 @@ function blueprintToManifest(blueprint) {
|
|
|
5200
5989
|
url: `git+https://github.com/orkestrel/${blueprint.name}.git`
|
|
5201
5990
|
} } : {},
|
|
5202
5991
|
...blueprint.bin ? { bin: { [blueprint.name]: "./dist/bin/main.js" } } : {},
|
|
5203
|
-
files:
|
|
5204
|
-
"dist/src",
|
|
5205
|
-
"dist/bin",
|
|
5992
|
+
files: [
|
|
5993
|
+
blueprint.bin || publishes ? "dist/src" : "dist/app",
|
|
5994
|
+
...blueprint.bin ? ["dist/bin"] : [],
|
|
5995
|
+
...targets.map((face) => `!dist/src/${face}/index.js`),
|
|
5996
|
+
...sheets.map((face) => `src/${face}/**/*.scss`),
|
|
5997
|
+
...blueprint.themes && !blueprint.styles ? ["src/styles/themes/**/*.scss"] : [],
|
|
5206
5998
|
"README.md"
|
|
5207
|
-
]
|
|
5999
|
+
],
|
|
5208
6000
|
type: "module",
|
|
5209
6001
|
...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),
|
|
6002
|
+
sideEffects: targets.length > 0 || blueprint.bin ? [...targets.length > 0 ? ["**/*.css", "**/*.scss"] : [], ...blueprint.bin ? [`./${BIN_ENTRY_PATH}`, "./dist/bin/main.js"] : []] : false,
|
|
6003
|
+
...blueprint.src.length > 0 ? entry : {},
|
|
6004
|
+
exports: blueprintToExports(blueprint),
|
|
5215
6005
|
publishConfig: { access: "public" }
|
|
5216
6006
|
} : {},
|
|
5217
6007
|
scripts: blueprintToScripts(blueprint),
|
|
@@ -5248,15 +6038,16 @@ function blueprintToManifest(blueprint) {
|
|
|
5248
6038
|
*
|
|
5249
6039
|
* const blueprint = createBlueprint('router', { app: ['browser'] })
|
|
5250
6040
|
*
|
|
5251
|
-
* blueprintToMachinery(blueprint).
|
|
6041
|
+
* blueprintToMachinery(blueprint).frameworks // []
|
|
5252
6042
|
* ```
|
|
5253
6043
|
*/
|
|
5254
6044
|
function blueprintToMachinery(blueprint) {
|
|
5255
6045
|
const hosted = blueprint.app.some((environment) => environment !== "core");
|
|
6046
|
+
const frameworks = FRAMEWORKS.filter((framework) => blueprintToFaces(blueprint).some((extension) => extension.surface === "browser" && extension.name === framework && extension.axes.some((axis) => blueprint[axis].includes("browser"))));
|
|
5256
6047
|
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,
|
|
6048
|
+
browser: blueprint.src.includes("browser") || blueprint.app.includes("browser") || blueprint.setup.includes("browser") || blueprintToSheets(blueprint).length > 0 || blueprint.themes || frameworks.length > 0,
|
|
6049
|
+
frameworks,
|
|
6050
|
+
output: blueprint.src.length > 0 || blueprint.bin || hosted || blueprintToSheets(blueprint).length > 0 || blueprint.themes,
|
|
5260
6051
|
showcase: blueprint.showcase && blueprint.app.includes("browser")
|
|
5261
6052
|
};
|
|
5262
6053
|
}
|
|
@@ -5292,6 +6083,12 @@ function blueprintToMachinery(blueprint) {
|
|
|
5292
6083
|
*/
|
|
5293
6084
|
function blueprintToRootTsconfig(blueprint) {
|
|
5294
6085
|
const aliases = [];
|
|
6086
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6087
|
+
if (extension.surface !== "browser") continue;
|
|
6088
|
+
for (const axis of extension.axes) aliases.push([`@${axis}/${extension.name}`, `./${axis}/${extension.name}/index.ts`]);
|
|
6089
|
+
if (extension.axes.includes("src")) aliases.push([`@orkestrel/${blueprint.name}/${extension.name}`, `./src/${extension.name}/index.ts`]);
|
|
6090
|
+
}
|
|
6091
|
+
for (const name of blueprintToSheets(blueprint)) aliases.push([`@src/${name}`, `./src/${name}/index.ts`]);
|
|
5295
6092
|
for (const environment of ENVIRONMENTS) if (blueprint.src.includes(environment)) aliases.push([`@src/${environment}`, `./src/${environment}/index.ts`]);
|
|
5296
6093
|
for (const environment of ENVIRONMENTS) if (blueprint.app.includes(environment)) aliases.push([`@app/${environment}`, `./app/${environment}/index.ts`]);
|
|
5297
6094
|
const root = srcToRoot(blueprint.src);
|
|
@@ -5307,7 +6104,47 @@ function blueprintToRootTsconfig(blueprint) {
|
|
|
5307
6104
|
if (matchesPrintWidth(line)) return line;
|
|
5308
6105
|
return `\t\t\t"${specifier}": [\n\t\t\t\t"${target}"\n\t\t\t]${separator}`;
|
|
5309
6106
|
}).join("\n");
|
|
5310
|
-
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.tsconfig, { paths });
|
|
6107
|
+
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.tsconfig, { paths: aliases.length === 0 ? " \"paths\": {}" : `\t\t"paths": {\n${paths}\n\t\t}` });
|
|
6108
|
+
}
|
|
6109
|
+
/**
|
|
6110
|
+
* Projects a blueprint into the project labels its root Vitest configuration registers.
|
|
6111
|
+
*
|
|
6112
|
+
* @param blueprint - The workspace specification.
|
|
6113
|
+
* @returns Project labels in registration order, including wrapper-registered sheet faces.
|
|
6114
|
+
*
|
|
6115
|
+
* @example
|
|
6116
|
+
* ```ts
|
|
6117
|
+
* import { blueprintToProjects, createBlueprint } from '@orkestrel/scaffold'
|
|
6118
|
+
*
|
|
6119
|
+
* blueprintToProjects(createBlueprint('desk')).includes('policy') // true
|
|
6120
|
+
* ```
|
|
6121
|
+
*/
|
|
6122
|
+
function blueprintToProjects(blueprint) {
|
|
6123
|
+
const sheets = blueprintToSheets(blueprint);
|
|
6124
|
+
const styled = sheets.length > 0 || blueprint.themes;
|
|
6125
|
+
const faces = blueprintToFaces(blueprint);
|
|
6126
|
+
const projects = sheets.map((name) => `src:${name}`);
|
|
6127
|
+
if (blueprint.themes && !blueprint.styles) projects.push("src:themes");
|
|
6128
|
+
for (const axis of AXES) {
|
|
6129
|
+
for (const environment of ENVIRONMENTS) {
|
|
6130
|
+
if (axis === "app" && environment === "server") continue;
|
|
6131
|
+
if (blueprint[axis].includes(environment)) projects.push(`${axis}:${environment}`);
|
|
6132
|
+
}
|
|
6133
|
+
for (const face of faces) if (face.surface === "browser" && face.axes.includes(axis)) projects.push(`${axis}:${face.name}`);
|
|
6134
|
+
if (axis === "src" && blueprint.bin) projects.push("src:bin");
|
|
6135
|
+
if (axis === "app" && blueprint.app.includes("server")) projects.push("app:server");
|
|
6136
|
+
}
|
|
6137
|
+
projects.push("policy", "config");
|
|
6138
|
+
if (blueprint.setup.includes("node") || blueprint.global) projects.push("setup");
|
|
6139
|
+
if (blueprint.setup.includes("browser") || styled) projects.push("setup:browser");
|
|
6140
|
+
if (blueprint.guides) projects.push("guides");
|
|
6141
|
+
if (blueprint.skills) projects.push("skills");
|
|
6142
|
+
if (blueprint.conformance) projects.push("conformance");
|
|
6143
|
+
if (blueprint.service) projects.push("service");
|
|
6144
|
+
if (blueprint.src.length > 0 || styled) projects.push("distribution");
|
|
6145
|
+
if (blueprint.integration) projects.push("integration");
|
|
6146
|
+
projects.push("probe");
|
|
6147
|
+
return projects;
|
|
5311
6148
|
}
|
|
5312
6149
|
/**
|
|
5313
6150
|
* Compiles the root Vite and Vitest configuration for a blueprint.
|
|
@@ -5331,44 +6168,58 @@ function blueprintToRootTsconfig(blueprint) {
|
|
|
5331
6168
|
*/
|
|
5332
6169
|
function blueprintToRootVite(blueprint) {
|
|
5333
6170
|
const machinery = blueprintToMachinery(blueprint);
|
|
5334
|
-
const
|
|
6171
|
+
const planned = new Set(blueprintToProjects(blueprint));
|
|
6172
|
+
const sheets = blueprintToSheets(blueprint);
|
|
6173
|
+
const styled = sheets.length > 0 || blueprint.themes;
|
|
5335
6174
|
const global = blueprint.global ? " globalSetup: ['./tests/setupGlobal.ts'],\n" : "";
|
|
5336
6175
|
const imports = [];
|
|
5337
6176
|
if (machinery.browser) imports.push("import { playwright } from '@vitest/browser-playwright'");
|
|
5338
|
-
if (machinery.vue) imports.push("import vue from '@vitejs/plugin-vue'");
|
|
6177
|
+
if (machinery.frameworks.includes("vue")) imports.push("import vue from '@vitejs/plugin-vue'");
|
|
5339
6178
|
if (machinery.showcase) imports.push("import { viteSingleFile } from 'vite-plugin-singlefile'");
|
|
6179
|
+
if (machinery.showcase) {
|
|
6180
|
+
imports.push("import { renameSync } from 'node:fs'");
|
|
6181
|
+
imports.push("import { resolve as resolvePath } from 'node:path'");
|
|
6182
|
+
}
|
|
5340
6183
|
const factories = [];
|
|
5341
6184
|
const projects = [];
|
|
5342
|
-
|
|
6185
|
+
const external = "external: resolveSourceExternal,";
|
|
6186
|
+
if (blueprint.src.includes("browser") || blueprint.src.includes("server")) factories.push(blueprint.src.includes("core") ? `function resolveSourceExternal(id: string): boolean {
|
|
6187
|
+
return (
|
|
6188
|
+
id === '@src/core' ||
|
|
6189
|
+
resolveExternal(id, {
|
|
6190
|
+
peers,
|
|
6191
|
+
refused: [],
|
|
6192
|
+
siblings: [resolveWorkspacePath('src/core/index.ts')],
|
|
6193
|
+
})
|
|
6194
|
+
)
|
|
6195
|
+
}
|
|
6196
|
+
` : `function resolveSourceExternal(id: string): boolean {
|
|
6197
|
+
return resolveExternal(id, { peers, refused: [], siblings: [] })
|
|
6198
|
+
}
|
|
6199
|
+
`);
|
|
6200
|
+
if (styled) {
|
|
6201
|
+
factories.push(CONFIG_TEMPLATES.factories.sheet);
|
|
6202
|
+
for (const name of sheets) projects.push(`'./configs/src/vite.${name}.config.ts'`);
|
|
6203
|
+
if (planned.has("src:themes")) projects.push("'./configs/src/vite.themes.config.ts'");
|
|
6204
|
+
}
|
|
6205
|
+
if (planned.has("src:core")) {
|
|
5343
6206
|
factories.push(CONFIG_TEMPLATES.factories.src.core);
|
|
5344
6207
|
projects.push("srcCore");
|
|
5345
6208
|
}
|
|
5346
|
-
if (
|
|
6209
|
+
if (planned.has("src:browser")) {
|
|
5347
6210
|
const core = blueprint.src.includes("core");
|
|
5348
6211
|
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 + '/')),`,
|
|
6212
|
+
external,
|
|
5355
6213
|
output: core ? " output: { paths: { '@src/core': '../core/index.js' } }," : " output: {},",
|
|
5356
6214
|
exclude: core ? " exclude: ['tests/src/core/**/*.test.ts'],\n" : "",
|
|
5357
6215
|
global
|
|
5358
6216
|
}));
|
|
5359
6217
|
projects.push("srcBrowser");
|
|
5360
6218
|
}
|
|
5361
|
-
if (
|
|
6219
|
+
if (planned.has("src:server")) {
|
|
5362
6220
|
const core = blueprint.src.includes("core");
|
|
5363
6221
|
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 + '/')),`,
|
|
6222
|
+
external,
|
|
5372
6223
|
output: core ? `\t\t\t\toutput: [
|
|
5373
6224
|
{
|
|
5374
6225
|
format: 'es',
|
|
@@ -5385,15 +6236,19 @@ function blueprintToRootVite(blueprint) {
|
|
|
5385
6236
|
}));
|
|
5386
6237
|
projects.push("srcServer");
|
|
5387
6238
|
}
|
|
5388
|
-
if (
|
|
6239
|
+
if (planned.has("src:vue")) {
|
|
6240
|
+
factories.push(CONFIG_TEMPLATES.factories.src.vue);
|
|
6241
|
+
projects.push("srcVue");
|
|
6242
|
+
}
|
|
6243
|
+
if (planned.has("src:bin")) {
|
|
5389
6244
|
factories.push(CONFIG_TEMPLATES.factories.src.bin);
|
|
5390
6245
|
projects.push("srcBin");
|
|
5391
6246
|
}
|
|
5392
|
-
if (
|
|
6247
|
+
if (planned.has("app:core")) {
|
|
5393
6248
|
factories.push(CONFIG_TEMPLATES.factories.app.core);
|
|
5394
6249
|
projects.push("appCore");
|
|
5395
6250
|
}
|
|
5396
|
-
if (
|
|
6251
|
+
if (planned.has("app:browser")) {
|
|
5397
6252
|
const showcaseFactory = machinery.showcase ? CONFIG_TEMPLATES.factories.app.showcase : "";
|
|
5398
6253
|
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.app.browser, {
|
|
5399
6254
|
showcaseFactory,
|
|
@@ -5402,7 +6257,11 @@ function blueprintToRootVite(blueprint) {
|
|
|
5402
6257
|
}));
|
|
5403
6258
|
projects.push("appBrowser");
|
|
5404
6259
|
}
|
|
5405
|
-
if (
|
|
6260
|
+
if (planned.has("app:vue")) {
|
|
6261
|
+
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.app.vue, { journeyExclude: blueprint.journey ? " exclude: ['tests/app/vue/integration.test.ts'],\n" : " exclude: [],\n" }));
|
|
6262
|
+
projects.push("appVue");
|
|
6263
|
+
}
|
|
6264
|
+
if (planned.has("app:server")) {
|
|
5406
6265
|
factories.push(CONFIG_TEMPLATES.factories.app.server);
|
|
5407
6266
|
projects.push("appServer");
|
|
5408
6267
|
}
|
|
@@ -5410,39 +6269,40 @@ function blueprintToRootVite(blueprint) {
|
|
|
5410
6269
|
projects.push("policy");
|
|
5411
6270
|
factories.push(CONFIG_TEMPLATES.factories.config);
|
|
5412
6271
|
projects.push("config");
|
|
5413
|
-
if (
|
|
6272
|
+
if (planned.has("setup")) {
|
|
5414
6273
|
factories.push(CONFIG_TEMPLATES.factories.setup);
|
|
5415
6274
|
projects.push("setup");
|
|
5416
6275
|
}
|
|
5417
|
-
if (
|
|
6276
|
+
if (planned.has("setup:browser")) {
|
|
5418
6277
|
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.browser, {
|
|
5419
|
-
|
|
6278
|
+
optimization: machinery.frameworks.includes("vue") ? "optimizeDeps: { include: [...optimizeDeps.include, 'vue'] }" : "optimizeDeps",
|
|
6279
|
+
plugins: machinery.frameworks.includes("vue") ? " plugins: [vue()],\n" : "",
|
|
5420
6280
|
global
|
|
5421
6281
|
}));
|
|
5422
6282
|
projects.push("setupBrowser");
|
|
5423
6283
|
}
|
|
5424
|
-
if (
|
|
6284
|
+
if (planned.has("guides")) {
|
|
5425
6285
|
factories.push(CONFIG_TEMPLATES.factories.guides);
|
|
5426
6286
|
projects.push("guides");
|
|
5427
6287
|
}
|
|
5428
|
-
if (
|
|
6288
|
+
if (planned.has("skills")) {
|
|
5429
6289
|
factories.push(CONFIG_TEMPLATES.factories.skills);
|
|
5430
6290
|
projects.push("skills");
|
|
5431
6291
|
}
|
|
5432
|
-
if (
|
|
6292
|
+
if (planned.has("conformance")) {
|
|
5433
6293
|
factories.push(CONFIG_TEMPLATES.factories.conformance);
|
|
5434
6294
|
projects.push("conformance");
|
|
5435
6295
|
}
|
|
5436
|
-
if (
|
|
6296
|
+
if (planned.has("service")) {
|
|
5437
6297
|
factories.push(CONFIG_TEMPLATES.factories.service);
|
|
5438
6298
|
projects.push("service");
|
|
5439
6299
|
}
|
|
5440
|
-
if (
|
|
6300
|
+
if (planned.has("distribution")) {
|
|
5441
6301
|
factories.push(CONFIG_TEMPLATES.factories.distribution);
|
|
5442
6302
|
projects.push("distribution");
|
|
5443
6303
|
}
|
|
5444
|
-
if (
|
|
5445
|
-
factories.push((0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.factories.integration, { global }));
|
|
6304
|
+
if (planned.has("integration")) {
|
|
6305
|
+
factories.push((0, _orkestrel_template.fillTemplate)(styled ? CONFIG_TEMPLATES.factories.integration.sheet : CONFIG_TEMPLATES.factories.integration.module, { global }));
|
|
5446
6306
|
projects.push("integration");
|
|
5447
6307
|
}
|
|
5448
6308
|
factories.push(CONFIG_TEMPLATES.factories.probe);
|
|
@@ -5455,14 +6315,24 @@ ${projects.map((project) => `\t\t\t${project},`).join("\n")}
|
|
|
5455
6315
|
const helpers = [
|
|
5456
6316
|
"enforceBuildLog",
|
|
5457
6317
|
"environmentBoundary",
|
|
5458
|
-
"outputBoundary"
|
|
6318
|
+
"outputBoundary",
|
|
6319
|
+
"resolveApplication",
|
|
6320
|
+
"resolveExternal",
|
|
6321
|
+
"stampPage"
|
|
5459
6322
|
].filter((helper) => body.includes(helper));
|
|
6323
|
+
const helperImport = `import { ${helpers.join(", ")} } from './configs/helpers.js'\n`;
|
|
5460
6324
|
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.vite, {
|
|
5461
|
-
journey: blueprint.journey &&
|
|
6325
|
+
journey: blueprint.journey && blueprint.app.includes("browser") ? "import type { JourneyVariant } from '@orkestrel/test'\n" : "",
|
|
5462
6326
|
imports: imports.length === 0 ? "" : `${imports.join("\n")}\n`,
|
|
5463
|
-
helpers: helpers.length === 0 ? "" : `import {
|
|
6327
|
+
helpers: helpers.length === 0 ? "" : matchesPrintWidth(helperImport.trimEnd()) ? helperImport : `import {\n${helpers.map((helper) => `\t${helper},`).join("\n")}\n} from './configs/helpers.js'\n`,
|
|
5464
6328
|
browsers: machinery.browser ? "import { resolveBrowser, resolvePinnedBrowser } from './configs/browsers.js'\n" : "",
|
|
5465
|
-
options: (machinery.browser ?
|
|
6329
|
+
options: (machinery.browser ? `const browserOptions = resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)
|
|
6330
|
+
|
|
6331
|
+
const optimizeDeps = {\n\tinclude: ${JSON.stringify([
|
|
6332
|
+
"@orkestrel/test",
|
|
6333
|
+
"@orkestrel/test/browser",
|
|
6334
|
+
...Object.hasOwn(blueprintToDevDependencies(blueprint), "@orkestrel/contract") || blueprint.dependencies.some((dependency) => dependency.name === "@orkestrel/contract") || blueprint.peers.some((peer) => peer.name === "@orkestrel/contract") ? ["@orkestrel/contract"] : []
|
|
6335
|
+
]).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
6336
|
factories: body,
|
|
5467
6337
|
projects: projectRows
|
|
5468
6338
|
});
|
|
@@ -5503,6 +6373,26 @@ function blueprintToConfigArtifacts(blueprint) {
|
|
|
5503
6373
|
origin: "template",
|
|
5504
6374
|
content: CONFIG_TEMPLATES.browsers
|
|
5505
6375
|
});
|
|
6376
|
+
for (const name of [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []]) {
|
|
6377
|
+
const label = name === "styles/themes" ? "themes" : name;
|
|
6378
|
+
artifacts.push({
|
|
6379
|
+
path: `configs/src/vite.${label}.config.ts`,
|
|
6380
|
+
group: "configs",
|
|
6381
|
+
ownership: "content",
|
|
6382
|
+
origin: "template",
|
|
6383
|
+
content: (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.vites.sheet, {
|
|
6384
|
+
name,
|
|
6385
|
+
label
|
|
6386
|
+
})
|
|
6387
|
+
});
|
|
6388
|
+
if (name !== "styles/themes") artifacts.push({
|
|
6389
|
+
path: `configs/src/tsconfig.${name}.json`,
|
|
6390
|
+
group: "configs",
|
|
6391
|
+
ownership: "content",
|
|
6392
|
+
origin: "template",
|
|
6393
|
+
content: (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.tsconfigs.sheet, { name })
|
|
6394
|
+
});
|
|
6395
|
+
}
|
|
5506
6396
|
for (const environment of blueprint.src) for (const path of SRC_MATRIX[environment].configs) {
|
|
5507
6397
|
let content = CONFIG_TEMPLATES.vites.src.core;
|
|
5508
6398
|
if (path === "configs/src/tsconfig.core.json") content = CONFIG_TEMPLATES.tsconfigs.src.core;
|
|
@@ -5540,11 +6430,10 @@ ${paths.join("\n")}
|
|
|
5540
6430
|
"../../app/browser/**/*.cts",
|
|
5541
6431
|
"../../app/browser/**/*.mts",
|
|
5542
6432
|
"../../app/browser/**/*.ts",
|
|
5543
|
-
"../../app/browser/**/*.tsx"
|
|
5544
|
-
"../../app/browser/**/*.vue"
|
|
6433
|
+
"../../app/browser/**/*.tsx"
|
|
5545
6434
|
];
|
|
5546
6435
|
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/
|
|
6436
|
+
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
6437
|
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
6438
|
} else if (path === "configs/app/vite.server.config.ts") content = CONFIG_TEMPLATES.vites.app.server;
|
|
5550
6439
|
else if (path === "configs/app/tsconfig.server.json") {
|
|
@@ -5567,6 +6456,58 @@ ${paths.join("\n")}
|
|
|
5567
6456
|
content
|
|
5568
6457
|
});
|
|
5569
6458
|
}
|
|
6459
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6460
|
+
if (extension.surface !== "browser") continue;
|
|
6461
|
+
for (const axis of extension.axes) {
|
|
6462
|
+
const include = [
|
|
6463
|
+
...[
|
|
6464
|
+
"cts",
|
|
6465
|
+
"mts",
|
|
6466
|
+
"ts",
|
|
6467
|
+
"tsx",
|
|
6468
|
+
...FRAMEWORK_MATRIX[extension.name].suffixes
|
|
6469
|
+
].map((suffix) => `../../app/${extension.name}/**/*.${suffix}`),
|
|
6470
|
+
...blueprint.app.includes("core") ? [
|
|
6471
|
+
"cts",
|
|
6472
|
+
"mts",
|
|
6473
|
+
"ts",
|
|
6474
|
+
"tsx"
|
|
6475
|
+
].map((suffix) => `../../app/core/**/*.${suffix}`) : [],
|
|
6476
|
+
...[
|
|
6477
|
+
"cts",
|
|
6478
|
+
"mts",
|
|
6479
|
+
"ts",
|
|
6480
|
+
"tsx",
|
|
6481
|
+
...FRAMEWORK_MATRIX[extension.name].suffixes
|
|
6482
|
+
].map((suffix) => `../../tests/app/${extension.name}/**/*.${suffix}`),
|
|
6483
|
+
"../../tests/setup.ts",
|
|
6484
|
+
"../../tests/setupBrowser.ts"
|
|
6485
|
+
];
|
|
6486
|
+
const siblings = blueprint.src.filter((environment) => environment === "core" || environment === "browser").flatMap((environment) => ["ts", "js"].map((suffix) => {
|
|
6487
|
+
const key = `\t[resolveWorkspacePath('src/${environment}/index.${suffix}').replaceAll('\\\\', '/')]:`;
|
|
6488
|
+
const value = `'@orkestrel/${blueprint.name}${environment === "browser" ? "/browser" : ""}',`;
|
|
6489
|
+
return matchesPrintWidth(`${key} ${value}`) ? `${key} ${value}` : `${key}\n\t\t${value}`;
|
|
6490
|
+
})).join("\n");
|
|
6491
|
+
artifacts.push({
|
|
6492
|
+
path: `configs/${axis}/vite.${extension.name}.config.ts`,
|
|
6493
|
+
group: "configs",
|
|
6494
|
+
ownership: "content",
|
|
6495
|
+
origin: "template",
|
|
6496
|
+
environment: "browser",
|
|
6497
|
+
content: axis === "src" ? (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.vites.src.vue, {
|
|
6498
|
+
siblings,
|
|
6499
|
+
refused: `[${FRAMEWORK_MATRIX[extension.name].refused.map((name) => serializeTypeScriptString(name)).join(", ")}]`
|
|
6500
|
+
}) : CONFIG_TEMPLATES.vites.app.vue
|
|
6501
|
+
}, {
|
|
6502
|
+
path: `configs/${axis}/tsconfig.${extension.name}.json`,
|
|
6503
|
+
group: "configs",
|
|
6504
|
+
ownership: "content",
|
|
6505
|
+
origin: "template",
|
|
6506
|
+
environment: "browser",
|
|
6507
|
+
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") })
|
|
6508
|
+
});
|
|
6509
|
+
}
|
|
6510
|
+
}
|
|
5570
6511
|
if (blueprint.showcase && blueprint.app.includes("browser")) artifacts.push({
|
|
5571
6512
|
path: SHOWCASE_CONFIG_PATH,
|
|
5572
6513
|
group: "configs",
|
|
@@ -5596,15 +6537,11 @@ ${paths.join("\n")}
|
|
|
5596
6537
|
* Compiles every artifact in the `source` group.
|
|
5597
6538
|
*
|
|
5598
6539
|
* @param blueprint - The workspace specification.
|
|
5599
|
-
* @returns
|
|
6540
|
+
* @returns Published barrels, sheet seeds, selected application entries, and the optional bin entry.
|
|
5600
6541
|
*
|
|
5601
6542
|
* @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.
|
|
6543
|
+
* Barrels, server entries, and bin entries hold no starter implementation. Browser entries
|
|
6544
|
+
* render the workspace name as a level-one heading; the Vue face mounts its arrival component.
|
|
5608
6545
|
*
|
|
5609
6546
|
* @example
|
|
5610
6547
|
* ```ts
|
|
@@ -5617,6 +6554,20 @@ ${paths.join("\n")}
|
|
|
5617
6554
|
*/
|
|
5618
6555
|
function blueprintToSourceArtifacts(blueprint) {
|
|
5619
6556
|
const artifacts = [];
|
|
6557
|
+
if (blueprint.themes && !blueprint.styles) artifacts.push({
|
|
6558
|
+
path: "src/styles/_tokens.scss",
|
|
6559
|
+
group: "source",
|
|
6560
|
+
ownership: "birth",
|
|
6561
|
+
origin: "template",
|
|
6562
|
+
content: ARTIFACT_TEMPLATES.source.sheet["_tokens.scss"]
|
|
6563
|
+
});
|
|
6564
|
+
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({
|
|
6565
|
+
path: `src/${name}/${path}`,
|
|
6566
|
+
group: "source",
|
|
6567
|
+
ownership: "birth",
|
|
6568
|
+
origin: "template",
|
|
6569
|
+
content
|
|
6570
|
+
});
|
|
5620
6571
|
for (const environment of blueprint.src) artifacts.push({
|
|
5621
6572
|
path: `src/${environment}/index.ts`,
|
|
5622
6573
|
group: "source",
|
|
@@ -5640,7 +6591,7 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5640
6591
|
ownership: "birth",
|
|
5641
6592
|
origin: "template",
|
|
5642
6593
|
environment,
|
|
5643
|
-
content: ARTIFACT_TEMPLATES.source.
|
|
6594
|
+
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
6595
|
}, {
|
|
5645
6596
|
path: "app/browser/index.html",
|
|
5646
6597
|
group: "source",
|
|
@@ -5658,6 +6609,36 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5658
6609
|
content: ARTIFACT_TEMPLATES.source.empty
|
|
5659
6610
|
});
|
|
5660
6611
|
}
|
|
6612
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6613
|
+
if (extension.surface !== "browser") continue;
|
|
6614
|
+
for (const axis of extension.axes) {
|
|
6615
|
+
artifacts.push({
|
|
6616
|
+
path: `${axis}/${extension.name}/index.ts`,
|
|
6617
|
+
group: "source",
|
|
6618
|
+
ownership: "birth",
|
|
6619
|
+
origin: "template",
|
|
6620
|
+
environment: "browser",
|
|
6621
|
+
content: axis === "app" ? ARTIFACT_TEMPLATES.source.empty : ARTIFACT_TEMPLATES.source.barrel
|
|
6622
|
+
});
|
|
6623
|
+
if (axis !== "app") continue;
|
|
6624
|
+
artifacts.push({
|
|
6625
|
+
path: `app/${extension.name}/index.html`,
|
|
6626
|
+
group: "source",
|
|
6627
|
+
ownership: "birth",
|
|
6628
|
+
origin: "template",
|
|
6629
|
+
environment: "browser",
|
|
6630
|
+
content: ARTIFACT_TEMPLATES.source.browser
|
|
6631
|
+
});
|
|
6632
|
+
for (const [path, content] of Object.entries(ARTIFACT_TEMPLATES.source.vue)) artifacts.push({
|
|
6633
|
+
path: `app/${extension.name}/${path}`,
|
|
6634
|
+
group: "source",
|
|
6635
|
+
ownership: "birth",
|
|
6636
|
+
origin: "template",
|
|
6637
|
+
environment: "browser",
|
|
6638
|
+
content: (0, _orkestrel_template.fillTemplate)(content, { heading: matchesPrintWidth(`\t<h1>${blueprint.name}</h1>`) ? blueprint.name : `\n\t\t${blueprint.name}\n\t` })
|
|
6639
|
+
});
|
|
6640
|
+
}
|
|
6641
|
+
}
|
|
5661
6642
|
if (blueprint.bin) artifacts.push({
|
|
5662
6643
|
path: BIN_ENTRY_PATH,
|
|
5663
6644
|
group: "source",
|
|
@@ -5671,7 +6652,7 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5671
6652
|
* Compiles every artifact in the `tests` group that is not vendored from the host.
|
|
5672
6653
|
*
|
|
5673
6654
|
* @param blueprint - The workspace specification.
|
|
5674
|
-
* @returns Shared setup modules, axis tests, and the optional integration seed.
|
|
6655
|
+
* @returns Shared setup modules and proofs, axis and sheet tests, journey suites, and the optional integration seed.
|
|
5675
6656
|
*
|
|
5676
6657
|
* @remarks
|
|
5677
6658
|
* `tests/setupPolicy.ts`, `tests/policy.test.ts`, and `tests/config.test.ts` are
|
|
@@ -5710,15 +6691,53 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5710
6691
|
origin: "template",
|
|
5711
6692
|
content: ARTIFACT_TEMPLATES.tests.setup
|
|
5712
6693
|
}];
|
|
6694
|
+
const sheets = [...blueprintToSheets(blueprint), ...blueprint.themes ? ["styles/themes"] : []];
|
|
6695
|
+
for (const extension of blueprintToFaces(blueprint)) {
|
|
6696
|
+
if (extension.surface !== "browser") continue;
|
|
6697
|
+
for (const axis of extension.axes) artifacts.push({
|
|
6698
|
+
path: `tests/${axis}/${extension.name}/index.test.ts`,
|
|
6699
|
+
group: "tests",
|
|
6700
|
+
ownership: "birth",
|
|
6701
|
+
origin: "template",
|
|
6702
|
+
environment: "browser",
|
|
6703
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.tests.entry, {
|
|
6704
|
+
specifier: serializeTypeScriptString(`@${axis}/${extension.name}`),
|
|
6705
|
+
label: serializeTypeScriptString(`${axis} ${extension.name} entry`)
|
|
6706
|
+
})
|
|
6707
|
+
});
|
|
6708
|
+
}
|
|
6709
|
+
if (sheets.length > 0) artifacts.push({
|
|
6710
|
+
path: "tests/setupStyles.ts",
|
|
6711
|
+
group: "tests",
|
|
6712
|
+
ownership: "birth",
|
|
6713
|
+
origin: "template",
|
|
6714
|
+
content: ARTIFACT_TEMPLATES.tests.styles.module
|
|
6715
|
+
}, {
|
|
6716
|
+
path: "tests/setupStyles.test.ts",
|
|
6717
|
+
group: "tests",
|
|
6718
|
+
ownership: "birth",
|
|
6719
|
+
origin: "template",
|
|
6720
|
+
content: ARTIFACT_TEMPLATES.tests.styles.proof
|
|
6721
|
+
});
|
|
6722
|
+
for (const name of sheets) artifacts.push({
|
|
6723
|
+
path: `tests/src/${name}/index.test.ts`,
|
|
6724
|
+
group: "tests",
|
|
6725
|
+
ownership: "birth",
|
|
6726
|
+
origin: "template",
|
|
6727
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.tests.sheet, {
|
|
6728
|
+
name,
|
|
6729
|
+
setup: name === "styles/themes" ? "../../../setupStyles.js" : "../../setupStyles.js"
|
|
6730
|
+
})
|
|
6731
|
+
});
|
|
5713
6732
|
if (blueprintToMachinery(blueprint).browser) artifacts.push({
|
|
5714
6733
|
path: "tests/setupBrowser.ts",
|
|
5715
6734
|
group: "tests",
|
|
5716
6735
|
ownership: "birth",
|
|
5717
6736
|
origin: "template",
|
|
5718
6737
|
environment: "browser",
|
|
5719
|
-
content: ARTIFACT_TEMPLATES.tests.setup
|
|
6738
|
+
content: blueprint.journey ? ARTIFACT_TEMPLATES.tests.browser : ARTIFACT_TEMPLATES.tests.setup
|
|
5720
6739
|
});
|
|
5721
|
-
if (blueprint.src.includes("server") || blueprint.app.includes("server") || blueprint.bin) artifacts.push({
|
|
6740
|
+
if (blueprint.src.includes("server") || blueprint.app.includes("server") || blueprint.bin || blueprint.conformance) artifacts.push({
|
|
5722
6741
|
path: "tests/setupServer.ts",
|
|
5723
6742
|
group: "tests",
|
|
5724
6743
|
ownership: "birth",
|
|
@@ -5733,13 +6752,40 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5733
6752
|
origin: "template",
|
|
5734
6753
|
content: ARTIFACT_TEMPLATES.tests.setup
|
|
5735
6754
|
});
|
|
5736
|
-
if (blueprint.global)
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
6755
|
+
if (blueprint.global) {
|
|
6756
|
+
artifacts.push({
|
|
6757
|
+
path: GLOBAL_SETUP_PATH,
|
|
6758
|
+
group: "tests",
|
|
6759
|
+
ownership: "birth",
|
|
6760
|
+
origin: "template",
|
|
6761
|
+
content: ARTIFACT_TEMPLATES.tests.global.module
|
|
6762
|
+
});
|
|
6763
|
+
artifacts.push({
|
|
6764
|
+
path: "tests/setupGlobal.test.ts",
|
|
6765
|
+
group: "tests",
|
|
6766
|
+
ownership: "birth",
|
|
6767
|
+
origin: "template",
|
|
6768
|
+
content: ARTIFACT_TEMPLATES.tests.global.proof
|
|
6769
|
+
});
|
|
6770
|
+
}
|
|
6771
|
+
if (blueprint.journey && blueprint.app.includes("browser")) {
|
|
6772
|
+
const applications = ["browser", ...blueprintToFaces(blueprint).flatMap((extension) => extension.surface === "browser" && extension.axes.includes("app") ? [extension.name] : [])];
|
|
6773
|
+
for (const application of applications) artifacts.push({
|
|
6774
|
+
path: `tests/app/${application}/integration.test.ts`,
|
|
6775
|
+
group: "tests",
|
|
6776
|
+
ownership: "birth",
|
|
6777
|
+
origin: "template",
|
|
6778
|
+
environment: "browser",
|
|
6779
|
+
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.tests.journey, {
|
|
6780
|
+
application,
|
|
6781
|
+
heading: serializeTypeScriptString(blueprint.name),
|
|
6782
|
+
imports: application === "vue" ? "import { createApp } from 'vue'\nimport App from '../../../app/vue/App.vue'\n" : "",
|
|
6783
|
+
mount: application === "vue" ? " const container = document.body.appendChild(document.createElement('main'))\n const app = createApp(App)\n" : "",
|
|
6784
|
+
arrival: application === "vue" ? " app.mount(container)\n" : " await import('../../../app/browser/main.js')\n",
|
|
6785
|
+
cleanup: application === "vue" ? " app.unmount()\n container.remove()\n" : " for (const main of page.getByRole('main').elements()) main.remove()\n"
|
|
6786
|
+
})
|
|
6787
|
+
});
|
|
6788
|
+
}
|
|
5743
6789
|
for (const environment of blueprint.src) artifacts.push({
|
|
5744
6790
|
path: `tests/src/${environment}/index.test.ts`,
|
|
5745
6791
|
group: "tests",
|
|
@@ -5774,7 +6820,7 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5774
6820
|
label: serializeTypeScriptString(`app ${environment} entry`)
|
|
5775
6821
|
})
|
|
5776
6822
|
});
|
|
5777
|
-
if (blueprint.src.length > 0) {
|
|
6823
|
+
if (blueprint.src.length > 0 || blueprintToSheets(blueprint).length > 0 || blueprint.themes) {
|
|
5778
6824
|
const browser = blueprint.src.includes("browser");
|
|
5779
6825
|
const distribution = ARTIFACT_TEMPLATES.tests.distribution;
|
|
5780
6826
|
artifacts.push({
|
|
@@ -5843,7 +6889,12 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5843
6889
|
const tests = [];
|
|
5844
6890
|
const directories = [];
|
|
5845
6891
|
const guide = `guides/${blueprint.name}.md`;
|
|
5846
|
-
for (const environment of
|
|
6892
|
+
for (const environment of [
|
|
6893
|
+
...blueprint.src,
|
|
6894
|
+
...blueprintToFaces(blueprint).filter((extension) => extension.axes.includes("src")).map((extension) => extension.name),
|
|
6895
|
+
...blueprintToSheets(blueprint),
|
|
6896
|
+
...blueprint.themes ? ["styles/themes"] : []
|
|
6897
|
+
]) {
|
|
5847
6898
|
source.push(` - [\`src/${environment}\`](../src/${environment})`);
|
|
5848
6899
|
tests.push(` - [\`tests/src/${environment}\`](../tests/src/${environment})`);
|
|
5849
6900
|
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 +6904,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5853
6904
|
tests.push(" - [`tests/src/bin`](../tests/src/bin)");
|
|
5854
6905
|
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
6906
|
}
|
|
5856
|
-
for (const environment of blueprint.app) {
|
|
6907
|
+
for (const environment of [...blueprint.app, ...blueprintToFaces(blueprint).filter((extension) => extension.axes.includes("app")).map((extension) => extension.name)]) {
|
|
5857
6908
|
source.push(` - [\`app/${environment}\`](../app/${environment})`);
|
|
5858
6909
|
tests.push(` - [\`tests/app/${environment}\`](../tests/app/${environment})`);
|
|
5859
6910
|
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 +6916,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5865
6916
|
origin: "template",
|
|
5866
6917
|
content: (0, _orkestrel_template.fillTemplate)(ARTIFACT_TEMPLATES.guides.readme, {
|
|
5867
6918
|
source: source.join("\n"),
|
|
5868
|
-
tests: tests.join("\n"),
|
|
6919
|
+
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
6920
|
directories: directories.join("\n"),
|
|
5870
6921
|
guide: blueprint.name
|
|
5871
6922
|
})
|
|
@@ -5904,7 +6955,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5904
6955
|
* ```
|
|
5905
6956
|
*/
|
|
5906
6957
|
function blueprintToDocumentArtifacts(blueprint) {
|
|
5907
|
-
const publishes = blueprint.src.length > 0;
|
|
6958
|
+
const publishes = blueprint.src.length > 0 || blueprintToSheets(blueprint).length > 0 || blueprint.themes;
|
|
5908
6959
|
const name = publishes ? `@orkestrel/${blueprint.name}` : blueprint.name;
|
|
5909
6960
|
const description = blueprint.description ?? (publishes ? `The ${name} package.` : `The ${name} application.`);
|
|
5910
6961
|
return [{
|
|
@@ -6696,7 +7747,8 @@ function dependenciesToQuestions(dependencies, field, name, range) {
|
|
|
6696
7747
|
* These do not, because each describes a workspace it can describe honestly but
|
|
6697
7748
|
* will not create: a published axis of several environments without core,
|
|
6698
7749
|
* whose manifest names a core build the workspace never runs; a showcase flag
|
|
6699
|
-
* whose required browser axis is absent, which emits nothing;
|
|
7750
|
+
* or journey flag whose required browser axis is absent, which emits nothing; an unplaced browser
|
|
7751
|
+
* extension or a styles extension without the styles surface; and an
|
|
6700
7752
|
* integration flag over fewer than two environments, whose seed does emit and
|
|
6701
7753
|
* has nothing to compose across. Blocking any of them closed the gate for every
|
|
6702
7754
|
* verb. The verbs that read an existing workspace need the plan the gate
|
|
@@ -6737,7 +7789,7 @@ function blueprintToQuestions(blueprint) {
|
|
|
6737
7789
|
message: `${blueprint.engines} is not a supported minimum-Node floor.`,
|
|
6738
7790
|
blocking: true
|
|
6739
7791
|
});
|
|
6740
|
-
if (blueprint.src.length === 0 && blueprint.app.length === 0) questions.push({
|
|
7792
|
+
if (blueprint.src.length === 0 && blueprint.app.length === 0 && blueprintToSheets(blueprint).length === 0 && !blueprint.themes) questions.push({
|
|
6741
7793
|
field: "src",
|
|
6742
7794
|
message: "A workspace declares at least one environment on src or app.",
|
|
6743
7795
|
blocking: true,
|
|
@@ -6763,6 +7815,32 @@ function blueprintToQuestions(blueprint) {
|
|
|
6763
7815
|
candidates: ENVIRONMENTS
|
|
6764
7816
|
});
|
|
6765
7817
|
}
|
|
7818
|
+
const extensions = /* @__PURE__ */ new Set();
|
|
7819
|
+
for (const extension of blueprint.extensions) {
|
|
7820
|
+
const selection = `${extension.surface}:${extension.name}`;
|
|
7821
|
+
if (extensions.has(selection)) questions.push({
|
|
7822
|
+
field: "extensions",
|
|
7823
|
+
message: `${selection} is declared more than once on extensions.`,
|
|
7824
|
+
blocking: true
|
|
7825
|
+
});
|
|
7826
|
+
extensions.add(selection);
|
|
7827
|
+
if (extension.surface === "browser") {
|
|
7828
|
+
if (extension.axes.length === 0) questions.push({
|
|
7829
|
+
field: "extensions",
|
|
7830
|
+
message: `${selection} occupies no axis.`,
|
|
7831
|
+
blocking: false
|
|
7832
|
+
});
|
|
7833
|
+
for (const axis of extension.axes) if (!blueprint[axis].includes("browser")) questions.push({
|
|
7834
|
+
field: "extensions",
|
|
7835
|
+
message: `${selection} occupies ${axis}, whose selection lacks browser.`,
|
|
7836
|
+
blocking: false
|
|
7837
|
+
});
|
|
7838
|
+
} else if (!blueprint.styles) questions.push({
|
|
7839
|
+
field: "extensions",
|
|
7840
|
+
message: `${selection} extends a styles surface this workspace does not declare.`,
|
|
7841
|
+
blocking: false
|
|
7842
|
+
});
|
|
7843
|
+
}
|
|
6766
7844
|
if (blueprint.integration && blueprint.src.length + blueprint.app.length < 2) questions.push({
|
|
6767
7845
|
field: "integration",
|
|
6768
7846
|
message: "integration drives features across environments, and this workspace declares fewer than two, so its seed composes nothing.",
|
|
@@ -6992,6 +8070,9 @@ function createBlueprint(name, input) {
|
|
|
6992
8070
|
keywords: input?.keywords ?? [],
|
|
6993
8071
|
src: input?.src ?? [],
|
|
6994
8072
|
app: input?.app ?? [],
|
|
8073
|
+
extensions: input?.extensions ?? [],
|
|
8074
|
+
styles: input?.styles ?? false,
|
|
8075
|
+
themes: input?.themes ?? false,
|
|
6995
8076
|
dependencies: input?.dependencies ?? [],
|
|
6996
8077
|
peers: input?.peers ?? [],
|
|
6997
8078
|
extras: input?.extras ?? [],
|
|
@@ -7322,6 +8403,7 @@ exports.APP_DEV_DEPENDENCIES = APP_DEV_DEPENDENCIES;
|
|
|
7322
8403
|
exports.APP_MATRIX = APP_MATRIX;
|
|
7323
8404
|
exports.APP_SERVER_DEV_DEPENDENCIES = APP_SERVER_DEV_DEPENDENCIES;
|
|
7324
8405
|
exports.ARTIFACT_TEMPLATES = ARTIFACT_TEMPLATES;
|
|
8406
|
+
exports.AXES = AXES;
|
|
7325
8407
|
exports.BASE_DEV_DEPENDENCIES = BASE_DEV_DEPENDENCIES;
|
|
7326
8408
|
exports.BIN_CONFIGS = BIN_CONFIGS;
|
|
7327
8409
|
exports.BIN_ENTRY_PATH = BIN_ENTRY_PATH;
|
|
@@ -7344,6 +8426,8 @@ exports.EXECUTABLE_PATHS = EXECUTABLE_PATHS;
|
|
|
7344
8426
|
exports.EXTRA_RANGE_PATTERN = EXTRA_RANGE_PATTERN;
|
|
7345
8427
|
exports.FLOOR_RANGE_PATTERN = FLOOR_RANGE_PATTERN;
|
|
7346
8428
|
exports.FOREIGN_NAME_PATTERN = FOREIGN_NAME_PATTERN;
|
|
8429
|
+
exports.FRAMEWORKS = FRAMEWORKS;
|
|
8430
|
+
exports.FRAMEWORK_MATRIX = FRAMEWORK_MATRIX;
|
|
7347
8431
|
exports.GLOBAL_SETUP_PATH = GLOBAL_SETUP_PATH;
|
|
7348
8432
|
exports.GROUPS = GROUPS;
|
|
7349
8433
|
exports.GUIDES_TEST_PATH = GUIDES_TEST_PATH;
|
|
@@ -7376,18 +8460,26 @@ exports.ORKESTREL_RANGE_PATTERN = ORKESTREL_RANGE_PATTERN;
|
|
|
7376
8460
|
exports.PRINT_WIDTH = PRINT_WIDTH;
|
|
7377
8461
|
exports.REFERENCE_PATHS = REFERENCE_PATHS;
|
|
7378
8462
|
exports.RELEASE_PROOF_COMMAND = RELEASE_PROOF_COMMAND;
|
|
8463
|
+
exports.RESERVED_SHEET_NAMES = RESERVED_SHEET_NAMES;
|
|
7379
8464
|
exports.SEED_GUIDE_PATHS = SEED_GUIDE_PATHS;
|
|
7380
8465
|
exports.SERVICE_SCRIPT_PATH = SERVICE_SCRIPT_PATH;
|
|
7381
8466
|
exports.SERVICE_SETUP_PATH = SERVICE_SETUP_PATH;
|
|
7382
8467
|
exports.SERVICE_TEST_INCLUDE = SERVICE_TEST_INCLUDE;
|
|
8468
|
+
exports.SHEET_ENTRY_NAME = SHEET_ENTRY_NAME;
|
|
7383
8469
|
exports.SHOWCASE_CONFIG_PATH = SHOWCASE_CONFIG_PATH;
|
|
7384
8470
|
exports.SHOWCASE_DEV_DEPENDENCIES = SHOWCASE_DEV_DEPENDENCIES;
|
|
8471
|
+
exports.SHOWCASE_PAGES_PATH = SHOWCASE_PAGES_PATH;
|
|
7385
8472
|
exports.SKILLS_CONFIG_PATH = SKILLS_CONFIG_PATH;
|
|
7386
8473
|
exports.SOURCE_BROWSER_DEV_DEPENDENCIES = SOURCE_BROWSER_DEV_DEPENDENCIES;
|
|
7387
8474
|
exports.SRC_MATRIX = SRC_MATRIX;
|
|
8475
|
+
exports.STYLES_DEV_DEPENDENCIES = STYLES_DEV_DEPENDENCIES;
|
|
8476
|
+
exports.STYLES_ENTRY_PATH = STYLES_ENTRY_PATH;
|
|
8477
|
+
exports.SURFACES = SURFACES;
|
|
7388
8478
|
exports.ScaffoldError = ScaffoldError;
|
|
7389
8479
|
exports.TAB_WIDTH = TAB_WIDTH;
|
|
7390
8480
|
exports.TARGET_SKILL_NAMES = TARGET_SKILL_NAMES;
|
|
8481
|
+
exports.THEMES_BARREL_PATH = THEMES_BARREL_PATH;
|
|
8482
|
+
exports.THEMES_ENTRY_PATH = THEMES_ENTRY_PATH;
|
|
7391
8483
|
exports.VERSION_PATTERN = VERSION_PATTERN;
|
|
7392
8484
|
exports.WORKSPACE_DEV_ENGINES = WORKSPACE_DEV_ENGINES;
|
|
7393
8485
|
exports.WORKSPACE_OWNED_PATHS = WORKSPACE_OWNED_PATHS;
|
|
@@ -7398,15 +8490,19 @@ exports.artifactsToQuestions = artifactsToQuestions;
|
|
|
7398
8490
|
exports.blueprintToConfigArtifacts = blueprintToConfigArtifacts;
|
|
7399
8491
|
exports.blueprintToDevDependencies = blueprintToDevDependencies;
|
|
7400
8492
|
exports.blueprintToDocumentArtifacts = blueprintToDocumentArtifacts;
|
|
8493
|
+
exports.blueprintToExports = blueprintToExports;
|
|
8494
|
+
exports.blueprintToFaces = blueprintToFaces;
|
|
7401
8495
|
exports.blueprintToGuideArtifacts = blueprintToGuideArtifacts;
|
|
7402
8496
|
exports.blueprintToHostArtifacts = blueprintToHostArtifacts;
|
|
7403
8497
|
exports.blueprintToMachinery = blueprintToMachinery;
|
|
7404
8498
|
exports.blueprintToManifest = blueprintToManifest;
|
|
7405
8499
|
exports.blueprintToOrchestrationArtifacts = blueprintToOrchestrationArtifacts;
|
|
8500
|
+
exports.blueprintToProjects = blueprintToProjects;
|
|
7406
8501
|
exports.blueprintToQuestions = blueprintToQuestions;
|
|
7407
8502
|
exports.blueprintToRootTsconfig = blueprintToRootTsconfig;
|
|
7408
8503
|
exports.blueprintToRootVite = blueprintToRootVite;
|
|
7409
8504
|
exports.blueprintToScripts = blueprintToScripts;
|
|
8505
|
+
exports.blueprintToSheets = blueprintToSheets;
|
|
7410
8506
|
exports.blueprintToSourceArtifacts = blueprintToSourceArtifacts;
|
|
7411
8507
|
exports.blueprintToTestArtifacts = blueprintToTestArtifacts;
|
|
7412
8508
|
exports.blueprintToWritableScripts = blueprintToWritableScripts;
|
|
@@ -7426,6 +8522,7 @@ exports.inferGroup = inferGroup;
|
|
|
7426
8522
|
exports.isArtifact = isArtifact;
|
|
7427
8523
|
exports.isAudit = isAudit;
|
|
7428
8524
|
exports.isBlueprint = isBlueprint;
|
|
8525
|
+
exports.isBrowserExtension = isBrowserExtension;
|
|
7429
8526
|
exports.isCanonPath = isCanonPath;
|
|
7430
8527
|
exports.isCatalogEntry = isCatalogEntry;
|
|
7431
8528
|
exports.isCollection = isCollection;
|
|
@@ -7436,6 +8533,7 @@ exports.isDeferredPath = isDeferredPath;
|
|
|
7436
8533
|
exports.isDependency = isDependency;
|
|
7437
8534
|
exports.isDependencyName = isDependencyName;
|
|
7438
8535
|
exports.isEnvironment = isEnvironment;
|
|
8536
|
+
exports.isExtension = isExtension;
|
|
7439
8537
|
exports.isFinding = isFinding;
|
|
7440
8538
|
exports.isFloorPath = isFloorPath;
|
|
7441
8539
|
exports.isGroup = isGroup;
|
|
@@ -7449,7 +8547,10 @@ exports.isPlan = isPlan;
|
|
|
7449
8547
|
exports.isQuestion = isQuestion;
|
|
7450
8548
|
exports.isRetainedPath = isRetainedPath;
|
|
7451
8549
|
exports.isScaffoldError = isScaffoldError;
|
|
8550
|
+
exports.isSheetName = isSheetName;
|
|
7452
8551
|
exports.isSnapshot = isSnapshot;
|
|
8552
|
+
exports.isStylesExtension = isStylesExtension;
|
|
8553
|
+
exports.isSurface = isSurface;
|
|
7453
8554
|
exports.manifestToDependencies = manifestToDependencies;
|
|
7454
8555
|
exports.manifestToName = manifestToName;
|
|
7455
8556
|
exports.matchesDriftReachability = matchesDriftReachability;
|
|
@@ -7461,6 +8562,7 @@ exports.nameToGuide = nameToGuide;
|
|
|
7461
8562
|
exports.overridesToQuestions = overridesToQuestions;
|
|
7462
8563
|
exports.parseBlueprint = parseBlueprint;
|
|
7463
8564
|
exports.parseCompilerOptions = parseCompilerOptions;
|
|
8565
|
+
exports.parseExtension = parseExtension;
|
|
7464
8566
|
exports.parseGroups = parseGroups;
|
|
7465
8567
|
exports.parseSnapshot = parseSnapshot;
|
|
7466
8568
|
exports.pathToCondition = pathToCondition;
|