@orkestrel/scaffold 0.0.50 → 0.0.52
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 +46 -17
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +2 -2
- package/dist/host/CLAUDE.md +3 -1
- package/dist/host/agents/orchestration.md +109 -274
- package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +12 -8
- package/dist/host/agents/skills/orkestrel-align-packages/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +15 -11
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +38 -12
- package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +107 -0
- package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/SKILL.md +1 -1
- package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/agents/openai.yaml +1 -1
- package/dist/host/agents/skills/orkestrel-publish/SKILL.md +77 -0
- package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +4 -0
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +97 -0
- package/dist/host/agents/skills/orkestrel-publish/references/window.md +95 -0
- package/dist/host/agents/templates/brief.md +157 -0
- package/dist/host/{codex/agents/claude.toml → agents/transports/claude.md} +16 -10
- package/dist/host/{claude/agents → agents/transports}/codex.md +13 -12
- package/dist/host/claude/agents/analyst.md +11 -10
- package/dist/host/claude/agents/application.md +6 -3
- package/dist/host/claude/agents/builder.md +11 -10
- package/dist/host/claude/agents/checker.md +20 -10
- package/dist/host/claude/agents/grok.md +8 -7
- package/dist/host/claude/agents/implementer.md +7 -4
- package/dist/host/claude/agents/orkestrel.md +27 -21
- package/dist/host/claude/agents/planner.md +13 -5
- package/dist/host/claude/agents/researcher.md +8 -7
- package/dist/host/claude/agents/reviewer.md +6 -4
- package/dist/host/claude/agents/scout.md +6 -7
- package/dist/host/claude/agents/sol.md +9 -8
- package/dist/host/claude/agents/verifier.md +6 -3
- package/dist/host/claude/rules/architecture.md +6 -6
- package/dist/host/claude/rules/documentation.md +2 -0
- package/dist/host/claude/rules/tests.md +4 -2
- package/dist/host/claude/rules/workspace.md +1 -1
- package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +12 -8
- package/dist/host/claude/skills/orkestrel-debrief/SKILL.md +1 -1
- package/dist/host/claude/skills/{orkestrel-human-journey → orkestrel-prove-journey}/SKILL.md +2 -2
- package/dist/host/claude/skills/orkestrel-publish/SKILL.md +12 -0
- package/dist/host/codex/agents/analyst.toml +3 -0
- package/dist/host/codex/agents/application.toml +3 -0
- package/dist/host/codex/agents/builder.toml +10 -7
- package/dist/host/codex/agents/checker.toml +14 -3
- package/dist/host/codex/agents/grok.toml +5 -2
- package/dist/host/codex/agents/implementer.toml +3 -2
- package/dist/host/codex/agents/opus.toml +4 -3
- package/dist/host/codex/agents/orkestrel.toml +14 -9
- package/dist/host/codex/agents/planner.toml +7 -5
- package/dist/host/codex/agents/researcher.toml +6 -4
- package/dist/host/codex/agents/reviewer.toml +4 -3
- package/dist/host/codex/agents/scout.toml +4 -1
- package/dist/host/codex/agents/verifier.toml +3 -2
- package/dist/host/codex/config.toml +1 -1
- package/dist/host/guides/scaffold.md +48 -44
- package/dist/host/manifest.json +132 -84
- package/dist/host/tests/config.test.ts +57 -0
- package/dist/src/core/index.cjs +455 -406
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +51 -48
- package/dist/src/core/index.d.ts +51 -48
- package/dist/src/core/index.js +455 -406
- package/dist/src/core/index.js.map +1 -1
- package/package.json +2 -2
- /package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/references/captures.md +0 -0
- /package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/references/layer.md +0 -0
package/dist/src/core/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { fillTemplate } from "@orkestrel/template";
|
|
|
3
3
|
import { Emitter } from "@orkestrel/emitter";
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@orkestrel/scaffold",
|
|
6
|
-
version: "0.0.
|
|
6
|
+
version: "0.0.52",
|
|
7
7
|
description: "Scaffold workspaces with five commands: new, audit, repair, catalog, and overwrite.",
|
|
8
8
|
keywords: [
|
|
9
9
|
"audit",
|
|
@@ -99,7 +99,7 @@ var package_default = {
|
|
|
99
99
|
"@microsoft/api-extractor": "^7.59.0",
|
|
100
100
|
"@orkestrel/guide": "^0.0.13",
|
|
101
101
|
"@orkestrel/html": "^0.0.5",
|
|
102
|
-
"@orkestrel/probe": "^0.0.
|
|
102
|
+
"@orkestrel/probe": "^0.0.4",
|
|
103
103
|
"@orkestrel/test": "^0.0.11",
|
|
104
104
|
"@types/node": "^26.2.0",
|
|
105
105
|
"@vitest/browser-playwright": "^4.1.11",
|
|
@@ -224,6 +224,8 @@ var HOST_PATHS = Object.freeze([
|
|
|
224
224
|
"LICENSE",
|
|
225
225
|
".agents/orchestration.md",
|
|
226
226
|
".agents/skills",
|
|
227
|
+
".agents/templates",
|
|
228
|
+
".agents/transports",
|
|
227
229
|
".claude/agents",
|
|
228
230
|
".claude/rules",
|
|
229
231
|
".claude/skills",
|
|
@@ -560,7 +562,7 @@ var CONFIG_TEMPLATES = Object.freeze({
|
|
|
560
562
|
}
|
|
561
563
|
`,
|
|
562
564
|
vite: `import type { {{viteTypes}} } from 'vite'
|
|
563
|
-
{{imports}}import { defineConfig
|
|
565
|
+
{{imports}}import { defineConfig } from 'vitest/config'
|
|
564
566
|
import manifest from './package.json' with { type: 'json' }
|
|
565
567
|
import tsconfig from './tsconfig.json' with { type: 'json' }
|
|
566
568
|
{{helpers}}{{browsers}}import { fileURLToPath, URL } from 'node:url'
|
|
@@ -599,160 +601,140 @@ const resolve = {
|
|
|
599
601
|
}),
|
|
600
602
|
factories: Object.freeze({
|
|
601
603
|
src: Object.freeze({
|
|
602
|
-
core: `export const srcCore = (
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
},
|
|
620
|
-
},
|
|
621
|
-
options ?? {},
|
|
622
|
-
)
|
|
604
|
+
core: `export const srcCore = (): UserConfig => ({
|
|
605
|
+
resolve,
|
|
606
|
+
publicDir: false,
|
|
607
|
+
build: {
|
|
608
|
+
emptyOutDir: true,
|
|
609
|
+
sourcemap: true,
|
|
610
|
+
minify: false,
|
|
611
|
+
rolldownOptions: { onLog: enforceBuildLog },
|
|
612
|
+
},
|
|
613
|
+
test: {
|
|
614
|
+
name: { label: 'src:core', color: 'magenta' },
|
|
615
|
+
include: ['tests/src/core/**/*.test.ts'],
|
|
616
|
+
setupFiles: ['./tests/setup.ts'],
|
|
617
|
+
environment: 'node',
|
|
618
|
+
browser: { enabled: false },
|
|
619
|
+
},
|
|
620
|
+
})
|
|
623
621
|
`,
|
|
624
|
-
browser: `export const srcBrowser = (
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
onLog: enforceBuildLog,
|
|
642
|
-
{{external}}
|
|
622
|
+
browser: `export const srcBrowser = (): UserConfig => ({
|
|
623
|
+
resolve,
|
|
624
|
+
publicDir: false,
|
|
625
|
+
plugins: [outputBoundary('dist/src/browser'), environmentBoundary('src/browser')],
|
|
626
|
+
build: {
|
|
627
|
+
emptyOutDir: true,
|
|
628
|
+
sourcemap: true,
|
|
629
|
+
minify: false,
|
|
630
|
+
lib: {
|
|
631
|
+
entry: resolveWorkspacePath('src/browser/index.ts'),
|
|
632
|
+
formats: ['es'],
|
|
633
|
+
fileName: () => 'index.js',
|
|
634
|
+
},
|
|
635
|
+
outDir: 'dist/src/browser',
|
|
636
|
+
rolldownOptions: {
|
|
637
|
+
onLog: enforceBuildLog,
|
|
638
|
+
{{external}}
|
|
643
639
|
{{output}}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
{{exclude}}
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
test: {
|
|
643
|
+
name: { label: 'src:browser', color: 'yellow' },
|
|
644
|
+
include: ['tests/src/browser/**/*.test.ts'],
|
|
645
|
+
{{exclude}} setupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],
|
|
650
646
|
{{global}}
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
},
|
|
656
|
-
fileParallelism: false,
|
|
657
|
-
},
|
|
647
|
+
browser: {
|
|
648
|
+
enabled: true,
|
|
649
|
+
provider: playwright(browserOptions),
|
|
650
|
+
instances: [{ browser: 'chromium', headless: true }],
|
|
658
651
|
},
|
|
659
|
-
|
|
660
|
-
|
|
652
|
+
fileParallelism: false,
|
|
653
|
+
},
|
|
654
|
+
})
|
|
661
655
|
`,
|
|
662
|
-
server: `export const srcServer = (
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
platform: 'node',
|
|
682
|
-
{{external}}
|
|
656
|
+
server: `export const srcServer = (): UserConfig => ({
|
|
657
|
+
resolve,
|
|
658
|
+
publicDir: false,
|
|
659
|
+
plugins: [outputBoundary('dist/src/server'), environmentBoundary('src/server')],
|
|
660
|
+
build: {
|
|
661
|
+
emptyOutDir: true,
|
|
662
|
+
sourcemap: true,
|
|
663
|
+
minify: false,
|
|
664
|
+
lib: {
|
|
665
|
+
entry: resolveWorkspacePath('src/server/index.ts'),
|
|
666
|
+
formats: ['es', 'cjs'],
|
|
667
|
+
fileName: (format: string) => (format === 'es' ? 'index.js' : 'index.cjs'),
|
|
668
|
+
},
|
|
669
|
+
outDir: 'dist/src/server',
|
|
670
|
+
target: 'node22',
|
|
671
|
+
rolldownOptions: {
|
|
672
|
+
onLog: enforceBuildLog,
|
|
673
|
+
platform: 'node',
|
|
674
|
+
{{external}}
|
|
683
675
|
{{output}}
|
|
684
|
-
},
|
|
685
|
-
},
|
|
686
|
-
test: {
|
|
687
|
-
name: { label: 'src:server', color: 'red' },
|
|
688
|
-
include: ['tests/src/server/**/*.test.ts'],
|
|
689
|
-
{{exclude}} setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
690
|
-
environment: 'node',
|
|
691
|
-
browser: { enabled: false },
|
|
692
|
-
},
|
|
693
676
|
},
|
|
694
|
-
|
|
695
|
-
|
|
677
|
+
},
|
|
678
|
+
test: {
|
|
679
|
+
name: { label: 'src:server', color: 'red' },
|
|
680
|
+
include: ['tests/src/server/**/*.test.ts'],
|
|
681
|
+
{{exclude}} setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
682
|
+
environment: 'node',
|
|
683
|
+
browser: { enabled: false },
|
|
684
|
+
},
|
|
685
|
+
})
|
|
696
686
|
`,
|
|
697
|
-
bin: `export const srcBin = (
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
formats: ['es'],
|
|
710
|
-
fileName: () => 'main.js',
|
|
711
|
-
},
|
|
712
|
-
outDir: 'dist/bin',
|
|
713
|
-
target: 'node22',
|
|
714
|
-
rolldownOptions: {
|
|
715
|
-
onLog: enforceBuildLog,
|
|
716
|
-
external: (id: string) =>
|
|
717
|
-
id.startsWith('node:') ||
|
|
718
|
-
id.startsWith('@orkestrel/') ||
|
|
719
|
-
id.startsWith('@src/') ||
|
|
720
|
-
peers.some((peer) => id === peer || id.startsWith(peer + '/')),
|
|
721
|
-
},
|
|
722
|
-
},
|
|
723
|
-
test: {
|
|
724
|
-
name: { label: 'src:bin', color: 'yellow' },
|
|
725
|
-
include: ['tests/src/bin/**/*.test.ts'],
|
|
726
|
-
setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
727
|
-
environment: 'node',
|
|
728
|
-
browser: { enabled: false },
|
|
729
|
-
// A bin test drives the real executable over a real temporary repository, so it
|
|
730
|
-
// spends seconds in process startup and filesystem work rather than milliseconds.
|
|
731
|
-
// Vitest's five-second default clears one alone and times out under a full suite.
|
|
732
|
-
testTimeout: 15_000,
|
|
733
|
-
},
|
|
687
|
+
bin: `export const srcBin = (): UserConfig => ({
|
|
688
|
+
resolve,
|
|
689
|
+
publicDir: false,
|
|
690
|
+
plugins: [outputBoundary('dist/bin')],
|
|
691
|
+
build: {
|
|
692
|
+
emptyOutDir: true,
|
|
693
|
+
sourcemap: true,
|
|
694
|
+
minify: false,
|
|
695
|
+
lib: {
|
|
696
|
+
entry: resolveWorkspacePath('${BIN_ENTRY_PATH}'),
|
|
697
|
+
formats: ['es'],
|
|
698
|
+
fileName: () => 'main.js',
|
|
734
699
|
},
|
|
735
|
-
|
|
736
|
-
|
|
700
|
+
outDir: 'dist/bin',
|
|
701
|
+
target: 'node22',
|
|
702
|
+
rolldownOptions: {
|
|
703
|
+
onLog: enforceBuildLog,
|
|
704
|
+
external: (id: string) =>
|
|
705
|
+
id.startsWith('node:') ||
|
|
706
|
+
id.startsWith('@orkestrel/') ||
|
|
707
|
+
id.startsWith('@src/') ||
|
|
708
|
+
peers.some((peer) => id === peer || id.startsWith(peer + '/')),
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
test: {
|
|
712
|
+
name: { label: 'src:bin', color: 'yellow' },
|
|
713
|
+
include: ['tests/src/bin/**/*.test.ts'],
|
|
714
|
+
setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
715
|
+
environment: 'node',
|
|
716
|
+
browser: { enabled: false },
|
|
717
|
+
// A bin test drives the real executable over a real temporary repository, so it
|
|
718
|
+
// spends seconds in process startup and filesystem work rather than milliseconds.
|
|
719
|
+
// Vitest's five-second default clears one alone and times out under a full suite.
|
|
720
|
+
testTimeout: 15_000,
|
|
721
|
+
},
|
|
722
|
+
})
|
|
737
723
|
`
|
|
738
724
|
}),
|
|
739
725
|
app: Object.freeze({
|
|
740
|
-
core: `export const appCore = (
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
},
|
|
753
|
-
},
|
|
754
|
-
options ?? {},
|
|
755
|
-
)
|
|
726
|
+
core: `export const appCore = (): UserConfig => ({
|
|
727
|
+
resolve,
|
|
728
|
+
publicDir: false,
|
|
729
|
+
plugins: [environmentBoundary('app/core')],
|
|
730
|
+
test: {
|
|
731
|
+
name: { label: 'app:core', color: 'cyan' },
|
|
732
|
+
include: ['tests/app/core/**/*.test.ts'],
|
|
733
|
+
setupFiles: ['./tests/setup.ts'],
|
|
734
|
+
environment: 'node',
|
|
735
|
+
browser: { enabled: false },
|
|
736
|
+
},
|
|
737
|
+
})
|
|
756
738
|
`,
|
|
757
739
|
browser: `function applicationBrowser(showcase: boolean): UserConfig {
|
|
758
740
|
const output = showcase ? 'dist/showcase' : 'dist/app/browser'
|
|
@@ -784,197 +766,157 @@ const resolve = {
|
|
|
784
766
|
}
|
|
785
767
|
}
|
|
786
768
|
|
|
787
|
-
export function appBrowser(
|
|
788
|
-
return
|
|
769
|
+
export function appBrowser(): UserConfig {
|
|
770
|
+
return applicationBrowser(false)
|
|
789
771
|
}
|
|
790
772
|
{{showcaseFactory}}`,
|
|
791
|
-
server: `export const appServer = (
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
formats: ['cjs'],
|
|
802
|
-
fileName: () => 'main.cjs',
|
|
803
|
-
},
|
|
804
|
-
outDir: resolveWorkspacePath('dist/app/server'),
|
|
805
|
-
target: 'node22',
|
|
806
|
-
rolldownOptions: {
|
|
807
|
-
onLog: enforceBuildLog,
|
|
808
|
-
external: (id: string) => id.startsWith('node:'),
|
|
809
|
-
},
|
|
810
|
-
},
|
|
811
|
-
test: {
|
|
812
|
-
name: { label: 'app:server', color: 'green' },
|
|
813
|
-
include: ['tests/app/server/**/*.test.ts'],
|
|
814
|
-
setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
815
|
-
environment: 'node',
|
|
816
|
-
browser: { enabled: false },
|
|
817
|
-
},
|
|
773
|
+
server: `export const appServer = (): UserConfig => ({
|
|
774
|
+
resolve,
|
|
775
|
+
publicDir: false,
|
|
776
|
+
plugins: [outputBoundary('dist/app/server'), environmentBoundary('app/server')],
|
|
777
|
+
build: {
|
|
778
|
+
emptyOutDir: true,
|
|
779
|
+
lib: {
|
|
780
|
+
entry: resolveWorkspacePath('app/server/main.ts'),
|
|
781
|
+
formats: ['cjs'],
|
|
782
|
+
fileName: () => 'main.cjs',
|
|
818
783
|
},
|
|
819
|
-
|
|
820
|
-
|
|
784
|
+
outDir: resolveWorkspacePath('dist/app/server'),
|
|
785
|
+
target: 'node22',
|
|
786
|
+
rolldownOptions: {
|
|
787
|
+
onLog: enforceBuildLog,
|
|
788
|
+
external: (id: string) => id.startsWith('node:'),
|
|
789
|
+
},
|
|
790
|
+
},
|
|
791
|
+
test: {
|
|
792
|
+
name: { label: 'app:server', color: 'green' },
|
|
793
|
+
include: ['tests/app/server/**/*.test.ts'],
|
|
794
|
+
setupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],
|
|
795
|
+
environment: 'node',
|
|
796
|
+
browser: { enabled: false },
|
|
797
|
+
},
|
|
798
|
+
})
|
|
821
799
|
`
|
|
822
800
|
}),
|
|
823
|
-
policy: `export const policy = (
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
},
|
|
834
|
-
},
|
|
835
|
-
options ?? {},
|
|
836
|
-
)
|
|
801
|
+
policy: `export const policy = (): UserConfig => ({
|
|
802
|
+
resolve,
|
|
803
|
+
test: {
|
|
804
|
+
name: { label: 'policy', color: 'white' },
|
|
805
|
+
include: ['tests/policy.test.ts'],
|
|
806
|
+
setupFiles: ['./tests/setup.ts'],
|
|
807
|
+
environment: 'node',
|
|
808
|
+
browser: { enabled: false },
|
|
809
|
+
},
|
|
810
|
+
})
|
|
837
811
|
`,
|
|
838
|
-
config: `export const config = (
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
},
|
|
852
|
-
},
|
|
853
|
-
options ?? {},
|
|
854
|
-
)
|
|
812
|
+
config: `export const config = (): UserConfig => ({
|
|
813
|
+
resolve,
|
|
814
|
+
test: {
|
|
815
|
+
name: { label: 'config', color: 'yellow' },
|
|
816
|
+
include: ['tests/config.test.ts'],
|
|
817
|
+
setupFiles: ['./tests/setup.ts'],
|
|
818
|
+
environment: 'node',
|
|
819
|
+
browser: { enabled: false },
|
|
820
|
+
// A config test validates every target wrapper and runs the real linter twice with
|
|
821
|
+
// 15-second child caps, so this budget clears both caps and reports their diagnostics.
|
|
822
|
+
testTimeout: 45_000,
|
|
823
|
+
},
|
|
824
|
+
})
|
|
855
825
|
`,
|
|
856
|
-
setup: `export const setup = (
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
},
|
|
867
|
-
},
|
|
868
|
-
options ?? {},
|
|
869
|
-
)
|
|
826
|
+
setup: `export const setup = (): UserConfig => ({
|
|
827
|
+
resolve,
|
|
828
|
+
test: {
|
|
829
|
+
name: { label: 'setup', color: 'white' },
|
|
830
|
+
include: ['tests/setup*.test.ts'],
|
|
831
|
+
setupFiles: ['./tests/setup.ts'],
|
|
832
|
+
environment: 'node',
|
|
833
|
+
browser: { enabled: false },
|
|
834
|
+
},
|
|
835
|
+
})
|
|
870
836
|
`,
|
|
871
|
-
guides: `export const guides = (
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
},
|
|
883
|
-
},
|
|
884
|
-
options ?? {},
|
|
885
|
-
)
|
|
837
|
+
guides: `export const guides = (): UserConfig => ({
|
|
838
|
+
resolve,
|
|
839
|
+
test: {
|
|
840
|
+
name: { label: 'guides', color: 'green' },
|
|
841
|
+
include: ['${GUIDES_TEST_PATH}'],
|
|
842
|
+
exclude: ['tests/src/**/*.test.ts', 'tests/app/**/*.test.ts', 'tests/setup.test.ts'],
|
|
843
|
+
setupFiles: ['./tests/setup.ts'],
|
|
844
|
+
environment: 'node',
|
|
845
|
+
browser: { enabled: false },
|
|
846
|
+
},
|
|
847
|
+
})
|
|
886
848
|
`,
|
|
887
849
|
conformance: `// Where this package drifts from the official tooling it stays compatible with.
|
|
888
850
|
// The subject is this package, so the proof is hermetic and stays in \`npm test\`.
|
|
889
|
-
export const conformance = (
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
},
|
|
900
|
-
},
|
|
901
|
-
options ?? {},
|
|
902
|
-
)
|
|
851
|
+
export const conformance = (): UserConfig => ({
|
|
852
|
+
resolve,
|
|
853
|
+
test: {
|
|
854
|
+
name: { label: 'conformance', color: 'magenta' },
|
|
855
|
+
include: ['${CONFORMANCE_TEST_PATH}'],
|
|
856
|
+
setupFiles: ['./tests/setup.ts'],
|
|
857
|
+
environment: 'node',
|
|
858
|
+
browser: { enabled: false },
|
|
859
|
+
},
|
|
860
|
+
})
|
|
903
861
|
`,
|
|
904
862
|
service: `// The live external services this package drives. It starts nothing itself:
|
|
905
863
|
// \`scripts/service.sh\` provisions, \`tests/setupService.ts\` proves readiness, and
|
|
906
864
|
// the project stays out of \`npm test\` because a real service answers it.
|
|
907
|
-
export const service = (
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
},
|
|
921
|
-
},
|
|
922
|
-
options ?? {},
|
|
923
|
-
)
|
|
865
|
+
export const service = (): UserConfig => ({
|
|
866
|
+
resolve,
|
|
867
|
+
test: {
|
|
868
|
+
name: { label: 'service', color: 'red' },
|
|
869
|
+
include: ['${SERVICE_TEST_INCLUDE}'],
|
|
870
|
+
setupFiles: ['./tests/setup.ts', './tests/setupService.ts'],
|
|
871
|
+
environment: 'node',
|
|
872
|
+
browser: { enabled: false },
|
|
873
|
+
testTimeout: 120_000,
|
|
874
|
+
hookTimeout: 120_000,
|
|
875
|
+
fileParallelism: false,
|
|
876
|
+
},
|
|
877
|
+
})
|
|
924
878
|
`,
|
|
925
|
-
distribution: `export const distribution = (
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
},
|
|
938
|
-
},
|
|
939
|
-
options ?? {},
|
|
940
|
-
)
|
|
879
|
+
distribution: `export const distribution = (): UserConfig => ({
|
|
880
|
+
resolve,
|
|
881
|
+
test: {
|
|
882
|
+
name: { label: 'distribution', color: 'cyan' },
|
|
883
|
+
include: ['${DISTRIBUTION_TEST_PATH}'],
|
|
884
|
+
setupFiles: ['./tests/setup.ts'],
|
|
885
|
+
environment: 'node',
|
|
886
|
+
testTimeout: 120_000,
|
|
887
|
+
hookTimeout: 120_000,
|
|
888
|
+
fileParallelism: false,
|
|
889
|
+
},
|
|
890
|
+
})
|
|
941
891
|
`,
|
|
942
892
|
probe: `// A workbench, not a proof. No gate selects this project. Run in test mode by the
|
|
943
893
|
// \`test:probe\` script, it collects \`tmp/probe/**/*.test.ts\`. Run in benchmark mode by the
|
|
944
894
|
// \`test:bench\` script, the same workbench also collects \`tests/**/*.test.ts\` for a \`bench\` block,
|
|
945
895
|
// so a suite may carry a bench beside its ordinary tests without a second project. The mode
|
|
946
896
|
// guard around each \`bench\` call keeps it out of test mode, so it never executes there.
|
|
947
|
-
export const probe = (
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
},
|
|
961
|
-
},
|
|
962
|
-
options ?? {},
|
|
963
|
-
)
|
|
897
|
+
export const probe = (): UserConfig => ({
|
|
898
|
+
resolve,
|
|
899
|
+
test: {
|
|
900
|
+
name: { label: 'probe', color: 'black' },
|
|
901
|
+
include: ['tmp/probe/**/*.test.ts'],
|
|
902
|
+
setupFiles: ['./tests/setup.ts'],
|
|
903
|
+
environment: 'node',
|
|
904
|
+
browser: { enabled: false },
|
|
905
|
+
fileParallelism: false,
|
|
906
|
+
pool: 'threads',
|
|
907
|
+
benchmark: { include: ['tmp/probe/**/*.test.ts', 'tests/**/*.test.ts'] },
|
|
908
|
+
},
|
|
909
|
+
})
|
|
964
910
|
`,
|
|
965
|
-
integration: `export const integration = (
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
},
|
|
975
|
-
},
|
|
976
|
-
options ?? {},
|
|
977
|
-
)
|
|
911
|
+
integration: `export const integration = (): UserConfig => ({
|
|
912
|
+
resolve,
|
|
913
|
+
test: {
|
|
914
|
+
name: { label: 'integration', color: 'blue' },
|
|
915
|
+
include: ['${INTEGRATION_TEST_PATH}'],
|
|
916
|
+
setupFiles: ['./tests/setup.ts'],
|
|
917
|
+
{{global}} environment: 'node',
|
|
918
|
+
},
|
|
919
|
+
})
|
|
978
920
|
`
|
|
979
921
|
}),
|
|
980
922
|
tsconfigs: Object.freeze({
|
|
@@ -1102,13 +1044,13 @@ export const probe = (options?: UserConfig): UserConfig =>
|
|
|
1102
1044
|
}),
|
|
1103
1045
|
vites: Object.freeze({
|
|
1104
1046
|
src: Object.freeze({
|
|
1105
|
-
core: `import { defineConfig } from 'vite'
|
|
1047
|
+
core: `import { defineConfig, mergeConfig } from 'vite'
|
|
1106
1048
|
import dts from 'vite-plugin-dts'
|
|
1107
1049
|
import { environmentBoundary, outputBoundary } from '../helpers.js'
|
|
1108
1050
|
import { peers, srcCore, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1109
1051
|
|
|
1110
1052
|
export default defineConfig(
|
|
1111
|
-
srcCore({
|
|
1053
|
+
mergeConfig(srcCore(), {
|
|
1112
1054
|
publicDir: false,
|
|
1113
1055
|
plugins: [
|
|
1114
1056
|
outputBoundary('dist/src/core'),
|
|
@@ -1130,7 +1072,7 @@ export default defineConfig(
|
|
|
1130
1072
|
lib: {
|
|
1131
1073
|
entry: resolveWorkspacePath('src/core/index.ts'),
|
|
1132
1074
|
formats: ['es', 'cjs'],
|
|
1133
|
-
fileName: (format) => (format === 'es' ? 'index.js' : 'index.cjs'),
|
|
1075
|
+
fileName: (format: string) => (format === 'es' ? 'index.js' : 'index.cjs'),
|
|
1134
1076
|
},
|
|
1135
1077
|
outDir: 'dist/src/core',
|
|
1136
1078
|
rolldownOptions: {
|
|
@@ -1143,17 +1085,17 @@ export default defineConfig(
|
|
|
1143
1085
|
}),
|
|
1144
1086
|
)
|
|
1145
1087
|
`,
|
|
1146
|
-
browser: `import { defineConfig } from 'vite'
|
|
1088
|
+
browser: `import { defineConfig, mergeConfig } from 'vite'
|
|
1147
1089
|
import dts from 'vite-plugin-dts'
|
|
1148
1090
|
import { srcBrowser, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1149
1091
|
|
|
1150
1092
|
// vite-plugin-dts rolls this face into one declaration, and the roll-up reaches
|
|
1151
1093
|
// src/core through a relative source path the tarball does not carry. The path
|
|
1152
1094
|
// keeps each source module's own depth, so a module in a browser subfolder emits
|
|
1153
|
-
// one that leaves dist/src entirely. The rewrite
|
|
1154
|
-
// the package's own published root export, on the final roll-up only.
|
|
1095
|
+
// one that leaves dist/src entirely. The following rewrite externalizes core
|
|
1096
|
+
// through the package's own published root export, on the final roll-up only.
|
|
1155
1097
|
export default defineConfig(
|
|
1156
|
-
srcBrowser({
|
|
1098
|
+
mergeConfig(srcBrowser(), {
|
|
1157
1099
|
plugins: [
|
|
1158
1100
|
dts({
|
|
1159
1101
|
tsconfigPath: resolveWorkspacePath('configs/src/tsconfig.browser.json'),
|
|
@@ -1168,16 +1110,16 @@ export default defineConfig(
|
|
|
1168
1110
|
}),
|
|
1169
1111
|
)
|
|
1170
1112
|
`,
|
|
1171
|
-
server: `import { defineConfig } from 'vite'
|
|
1113
|
+
server: `import { defineConfig, mergeConfig } from 'vite'
|
|
1172
1114
|
import dts from 'vite-plugin-dts'
|
|
1173
1115
|
import { srcServer, resolveWorkspacePath } from '../../vite.config.ts'
|
|
1174
1116
|
|
|
1175
1117
|
// vite-plugin-dts rolls this face into one declaration, and the roll-up reaches
|
|
1176
|
-
// src/core through a relative source path the tarball does not carry. The
|
|
1177
|
-
//
|
|
1178
|
-
// final roll-up only.
|
|
1118
|
+
// src/core through a relative source path the tarball does not carry. The
|
|
1119
|
+
// following rewrite externalizes core through the package's own published root
|
|
1120
|
+
// export, on the final roll-up only.
|
|
1179
1121
|
export default defineConfig(
|
|
1180
|
-
srcServer({
|
|
1122
|
+
mergeConfig(srcServer(), {
|
|
1181
1123
|
plugins: [
|
|
1182
1124
|
dts({
|
|
1183
1125
|
tsconfigPath: resolveWorkspacePath('configs/src/tsconfig.server.json'),
|
|
@@ -1193,7 +1135,7 @@ export default defineConfig(
|
|
|
1193
1135
|
)
|
|
1194
1136
|
`
|
|
1195
1137
|
}),
|
|
1196
|
-
bin: `import { defineConfig } from 'vite'
|
|
1138
|
+
bin: `import { defineConfig, mergeConfig } from 'vite'
|
|
1197
1139
|
import { srcBin } from '../../vite.config.ts'
|
|
1198
1140
|
|
|
1199
1141
|
// The \`scaffold\` executable build — a single ESM lib file, no declarations (an
|
|
@@ -1202,7 +1144,7 @@ import { srcBin } from '../../vite.config.ts'
|
|
|
1202
1144
|
// \`output.paths\` rewriting the externalized \`@src/*\` specifiers to the built sibling
|
|
1203
1145
|
// src environments (relative to \`dist/bin/\`), so the emitted bin resolves at runtime.
|
|
1204
1146
|
export default defineConfig(
|
|
1205
|
-
srcBin({
|
|
1147
|
+
mergeConfig(srcBin(), {
|
|
1206
1148
|
build: {
|
|
1207
1149
|
rolldownOptions: {
|
|
1208
1150
|
output: {
|
|
@@ -1640,8 +1582,8 @@ const SHELL = process.platform === 'win32'
|
|
|
1640
1582
|
// Release is the publish gate, so evidence it cannot obtain fails there and skips
|
|
1641
1583
|
// everywhere else: a gate that passes on missing evidence proves nothing.
|
|
1642
1584
|
const RELEASE = import.meta.env.MODE === 'release'
|
|
1643
|
-
// The built output directory a browser face
|
|
1644
|
-
// reads this prefix off the export
|
|
1585
|
+
// The built output directory convention a browser face may publish from. Every
|
|
1586
|
+
// selection reads this prefix off the export target and never off the subpath name. A
|
|
1645
1587
|
// workspace whose only published face is the browser one publishes that face at the
|
|
1646
1588
|
// root subpath, so a rule keyed on the subpath name drives a browser bundle through
|
|
1647
1589
|
// Node and the miss is silent.
|
|
@@ -1929,11 +1871,33 @@ function readPackageType(installed: string, target: string): unknown {
|
|
|
1929
1871
|
}
|
|
1930
1872
|
}
|
|
1931
1873
|
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1874
|
+
function resolvesBrowser(entry: unknown): boolean {
|
|
1875
|
+
const module = resolveTarget(entry, RUNTIME_CONDITIONS.browser)
|
|
1876
|
+
if (module !== undefined && module.startsWith(BROWSER_OUTPUT)) return true
|
|
1877
|
+
if (module === undefined) return false
|
|
1878
|
+
const imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)
|
|
1879
|
+
const required = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)
|
|
1880
|
+
return module !== imported && module !== required
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1883
|
+
// Whether the target selected by Node's CommonJS conditions is a module require can
|
|
1884
|
+
// load. A JavaScript target takes its own nearest package scope. Native addons and
|
|
1885
|
+
// extensionless targets have their own CommonJS handlers.
|
|
1936
1886
|
function resolvesCommonJS(entry: unknown, installed: string): boolean {
|
|
1887
|
+
const target = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)
|
|
1888
|
+
if (target === undefined) return false
|
|
1889
|
+
const name = target.slice(target.lastIndexOf('/') + 1)
|
|
1890
|
+
if (name.endsWith('.cjs')) return true
|
|
1891
|
+
if (name.endsWith('.mjs')) return false
|
|
1892
|
+
if (name.endsWith('.node')) return true
|
|
1893
|
+
if (!name.includes('.')) return true
|
|
1894
|
+
return name.endsWith('.js') && readPackageType(installed, target) !== 'module'
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
// Whether the declaration selected by a typed CommonJS consumer admits that entry.
|
|
1898
|
+
// A \`.d.cts\` declaration admits and a \`.d.mts\` declaration refuses. A \`.d.ts\`
|
|
1899
|
+
// declaration takes its own nearest package scope.
|
|
1900
|
+
function declaresCommonJS(entry: unknown, installed: string): boolean {
|
|
1937
1901
|
const declaration = resolveDeclaration(entry, DECLARATION_CONDITIONS.commonjs, installed)
|
|
1938
1902
|
if (declaration === undefined) return false
|
|
1939
1903
|
if (declaration.endsWith('.d.cts')) return true
|
|
@@ -1996,13 +1960,13 @@ function selectEntries(entries: readonly Entry[], conditions: readonly string[])
|
|
|
1996
1960
|
// Require-loadable entries that declare CommonJS support but a typed CommonJS
|
|
1997
1961
|
// consumer cannot compile against. A default branch resolving under the require
|
|
1998
1962
|
// condition set makes no CommonJS claim.
|
|
1999
|
-
function selectUntypable(entries: readonly Entry[]): readonly Entry[] {
|
|
1963
|
+
function selectUntypable(entries: readonly Entry[], installed: string): readonly Entry[] {
|
|
2000
1964
|
return entries.filter(
|
|
2001
1965
|
(entry) =>
|
|
2002
1966
|
entry.required &&
|
|
2003
1967
|
isRecord(entry.mapping) &&
|
|
2004
1968
|
Object.hasOwn(entry.mapping, 'require') &&
|
|
2005
|
-
!entry.
|
|
1969
|
+
!declaresCommonJS(entry.mapping, installed),
|
|
2006
1970
|
)
|
|
2007
1971
|
}
|
|
2008
1972
|
|
|
@@ -2135,9 +2099,11 @@ function buildStage(): Stage {
|
|
|
2135
2099
|
continue
|
|
2136
2100
|
}
|
|
2137
2101
|
const imported = resolveTarget(entry, RUNTIME_CONDITIONS.module)
|
|
2138
|
-
const
|
|
2139
|
-
const
|
|
2140
|
-
const
|
|
2102
|
+
const requiredTarget = resolveTarget(entry, RUNTIME_CONDITIONS.commonjs)
|
|
2103
|
+
const browserTarget = resolveTarget(entry, RUNTIME_CONDITIONS.browser)
|
|
2104
|
+
const browser = resolvesBrowser(entry)
|
|
2105
|
+
const required = requiredTarget !== undefined && !(browser && requiredTarget === browserTarget)
|
|
2106
|
+
const commonjs = required && resolvesCommonJS(entry, installed)
|
|
2141
2107
|
entries.push({
|
|
2142
2108
|
subpath,
|
|
2143
2109
|
specifier: subpath === '.' ? name : \`\${name}\${subpath.slice(1)}\`,
|
|
@@ -2149,8 +2115,8 @@ function buildStage(): Stage {
|
|
|
2149
2115
|
browser:
|
|
2150
2116
|
declaration.browser === undefined ? undefined : join(installed, declaration.browser),
|
|
2151
2117
|
},
|
|
2152
|
-
browser
|
|
2153
|
-
module: imported !== undefined,
|
|
2118
|
+
browser,
|
|
2119
|
+
module: imported !== undefined && !(browser && imported === browserTarget),
|
|
2154
2120
|
commonjs,
|
|
2155
2121
|
required,
|
|
2156
2122
|
})
|
|
@@ -2191,6 +2157,74 @@ function openStage(): Stage | undefined {
|
|
|
2191
2157
|
const STAGE = openStage()
|
|
2192
2158
|
const STAGED = STAGE !== undefined
|
|
2193
2159
|
|
|
2160
|
+
describe('distribution classifiers', () => {
|
|
2161
|
+
it('classifies synthetic export mappings without a registry stage', () => {
|
|
2162
|
+
const root = join(SCRATCH, 'classifiers')
|
|
2163
|
+
writeFile(
|
|
2164
|
+
join(root, 'package.json'),
|
|
2165
|
+
JSON.stringify({
|
|
2166
|
+
type: 'commonjs',
|
|
2167
|
+
exports: {
|
|
2168
|
+
condition: { browser: './b.js', default: './n.js' },
|
|
2169
|
+
convention: { default: './dist/src/browser/index.js' },
|
|
2170
|
+
universal: { default: './shared.js' },
|
|
2171
|
+
'import-shared': {
|
|
2172
|
+
browser: './shared.mjs',
|
|
2173
|
+
import: './shared.mjs',
|
|
2174
|
+
default: './node.js',
|
|
2175
|
+
},
|
|
2176
|
+
'require-shared': {
|
|
2177
|
+
browser: './shared.cjs',
|
|
2178
|
+
require: './shared.cjs',
|
|
2179
|
+
default: './node.js',
|
|
2180
|
+
},
|
|
2181
|
+
node: { node: './node.js', default: './node.js' },
|
|
2182
|
+
silent: { 'module-sync': './x.cjs', import: './x.mjs' },
|
|
2183
|
+
module: { require: './x.mjs' },
|
|
2184
|
+
'nested-module': { require: './module/x.js' },
|
|
2185
|
+
'nested-commonjs': { require: './commonjs/x.js' },
|
|
2186
|
+
esm: { import: './x.mjs' },
|
|
2187
|
+
},
|
|
2188
|
+
}),
|
|
2189
|
+
)
|
|
2190
|
+
writeFile(join(root, 'module/package.json'), '{ "type": "module" }\\n')
|
|
2191
|
+
writeFile(join(root, 'commonjs/package.json'), '{ "type": "commonjs" }\\n')
|
|
2192
|
+
const manifest = readJson(join(root, 'package.json'))
|
|
2193
|
+
if (!isRecord(manifest) || !isRecord(manifest.exports)) {
|
|
2194
|
+
throw new Error('The classifier fixture declares no exports map')
|
|
2195
|
+
}
|
|
2196
|
+
const mappings = manifest.exports
|
|
2197
|
+
expect({
|
|
2198
|
+
condition: resolvesBrowser(mappings.condition),
|
|
2199
|
+
convention: resolvesBrowser(mappings.convention),
|
|
2200
|
+
universal: resolvesBrowser(mappings.universal),
|
|
2201
|
+
import: resolvesBrowser(mappings['import-shared']),
|
|
2202
|
+
require: resolvesBrowser(mappings['require-shared']),
|
|
2203
|
+
node: resolvesBrowser(mappings.node),
|
|
2204
|
+
}).toStrictEqual({
|
|
2205
|
+
condition: true,
|
|
2206
|
+
convention: true,
|
|
2207
|
+
universal: false,
|
|
2208
|
+
import: false,
|
|
2209
|
+
require: false,
|
|
2210
|
+
node: false,
|
|
2211
|
+
})
|
|
2212
|
+
expect({
|
|
2213
|
+
silent: resolvesCommonJS(mappings.silent, root),
|
|
2214
|
+
module: resolvesCommonJS(mappings.module, root),
|
|
2215
|
+
nestedModule: resolvesCommonJS(mappings['nested-module'], root),
|
|
2216
|
+
nestedCommonJS: resolvesCommonJS(mappings['nested-commonjs'], root),
|
|
2217
|
+
esm: resolvesCommonJS(mappings.esm, root),
|
|
2218
|
+
}).toStrictEqual({
|
|
2219
|
+
silent: true,
|
|
2220
|
+
module: false,
|
|
2221
|
+
nestedModule: false,
|
|
2222
|
+
nestedCommonJS: true,
|
|
2223
|
+
esm: false,
|
|
2224
|
+
})
|
|
2225
|
+
})
|
|
2226
|
+
})
|
|
2227
|
+
|
|
2194
2228
|
// The staged consumer, or a skip naming what the run could not reach. \`it.skipIf\`
|
|
2195
2229
|
// carries no reason, so the gate sits here where the test context can state one.
|
|
2196
2230
|
function requireStage(context: TestContext): Stage {
|
|
@@ -2238,7 +2272,7 @@ describe('installed package consumer', () => {
|
|
|
2238
2272
|
(entry) => !entry.module && !entry.required && !entry.browser,
|
|
2239
2273
|
)
|
|
2240
2274
|
expect(unreachable.map((entry) => entry.subpath)).toStrictEqual([])
|
|
2241
|
-
const untypable = selectUntypable(stage.entries)
|
|
2275
|
+
const untypable = selectUntypable(stage.entries, stage.installed)
|
|
2242
2276
|
expect(untypable.map((entry) => entry.subpath)).toStrictEqual([])
|
|
2243
2277
|
})
|
|
2244
2278
|
|
|
@@ -2283,7 +2317,7 @@ describe('installed package consumer', () => {
|
|
|
2283
2317
|
|
|
2284
2318
|
for (const entry of STAGE?.entries ?? []) {
|
|
2285
2319
|
describe(\`installed entry \${entry.subpath}\`, () => {
|
|
2286
|
-
it.runIf(entry.module
|
|
2320
|
+
it.runIf(entry.module)(
|
|
2287
2321
|
'publishes what it declares to a Node import, and no more',
|
|
2288
2322
|
(context) => {
|
|
2289
2323
|
const declaration = entry.declaration.module
|
|
@@ -2295,7 +2329,7 @@ for (const entry of STAGE?.entries ?? []) {
|
|
|
2295
2329
|
},
|
|
2296
2330
|
)
|
|
2297
2331
|
|
|
2298
|
-
it.runIf(
|
|
2332
|
+
it.runIf(entry.required)(
|
|
2299
2333
|
'publishes what it declares to a Node require, and no more',
|
|
2300
2334
|
(context) => {
|
|
2301
2335
|
const declaration = entry.declaration.commonjs
|
|
@@ -4317,7 +4351,7 @@ function blueprintToScripts(blueprint) {
|
|
|
4317
4351
|
scripts["serve:build"] = "npm run build:app:server && npm run serve";
|
|
4318
4352
|
}
|
|
4319
4353
|
if (publishes) {
|
|
4320
|
-
scripts.prepack =
|
|
4354
|
+
scripts.prepack = "npm run build";
|
|
4321
4355
|
scripts.prepublishOnly = [
|
|
4322
4356
|
"npm run format:check && npm run lint:check && npm run check && npm run build && npm test",
|
|
4323
4357
|
RELEASE_PROOF_COMMAND,
|
|
@@ -4330,19 +4364,21 @@ function blueprintToScripts(blueprint) {
|
|
|
4330
4364
|
* Project a blueprint into the manifest scripts a region write may replace.
|
|
4331
4365
|
*
|
|
4332
4366
|
* @param blueprint - The workspace specification.
|
|
4333
|
-
* @returns One entry per writable script
|
|
4334
|
-
* nothing and therefore declares neither script.
|
|
4367
|
+
* @returns One entry per writable script.
|
|
4335
4368
|
*
|
|
4336
4369
|
* @remarks
|
|
4337
|
-
*
|
|
4338
|
-
*
|
|
4339
|
-
*
|
|
4340
|
-
*
|
|
4341
|
-
*
|
|
4370
|
+
* Every direct `test:<project>` script is writable, together with the probe and
|
|
4371
|
+
* benchmark workbench scripts. Publishing adds the pack and publication
|
|
4372
|
+
* lifecycle scripts. Aggregate test scripts and maintainer-owned gate chains
|
|
4373
|
+
* stay outside the region.
|
|
4374
|
+
*
|
|
4375
|
+
* `accepted` carries each generated predecessor the region can replace. The
|
|
4376
|
+
* pack hook accepts the build chain emitted before it delegated to `build`. The
|
|
4377
|
+
* publication hook accepts the same gate chain without
|
|
4342
4378
|
* {@link RELEASE_PROOF_COMMAND}. The value being written is always writable, so
|
|
4343
|
-
* it is not repeated there. Any other value is a
|
|
4344
|
-
* customized, and {@link replaceManifestScripts}
|
|
4345
|
-
*
|
|
4379
|
+
* it is not repeated there. Any other value is a script the workspace author
|
|
4380
|
+
* customized, and {@link replaceManifestScripts} retains it while writing the
|
|
4381
|
+
* other named scripts independently.
|
|
4346
4382
|
*
|
|
4347
4383
|
* @example
|
|
4348
4384
|
* ```ts
|
|
@@ -4350,23 +4386,36 @@ function blueprintToScripts(blueprint) {
|
|
|
4350
4386
|
*
|
|
4351
4387
|
* const blueprint = createBlueprint('router', { src: ['core'] })
|
|
4352
4388
|
*
|
|
4353
|
-
* blueprintToWritableScripts(blueprint)[0]?.name // 'test:
|
|
4389
|
+
* blueprintToWritableScripts(blueprint)[0]?.name // 'test:src:core'
|
|
4354
4390
|
* ```
|
|
4355
4391
|
*/
|
|
4356
4392
|
function blueprintToWritableScripts(blueprint) {
|
|
4357
4393
|
const scripts = blueprintToScripts(blueprint);
|
|
4358
|
-
const
|
|
4394
|
+
const writable = [];
|
|
4395
|
+
for (const [name, command] of Object.entries(scripts)) {
|
|
4396
|
+
if (!name.startsWith("test:") || name === "test:src" || name === "test:app") continue;
|
|
4397
|
+
writable.push({
|
|
4398
|
+
name,
|
|
4399
|
+
command,
|
|
4400
|
+
accepted: []
|
|
4401
|
+
});
|
|
4402
|
+
}
|
|
4403
|
+
const prepack = scripts.prepack;
|
|
4404
|
+
if (prepack !== void 0) {
|
|
4405
|
+
const predecessor = scripts.build;
|
|
4406
|
+
writable.push({
|
|
4407
|
+
name: "prepack",
|
|
4408
|
+
command: prepack,
|
|
4409
|
+
accepted: predecessor === void 0 ? [] : [predecessor]
|
|
4410
|
+
});
|
|
4411
|
+
}
|
|
4359
4412
|
const prepublish = scripts.prepublishOnly;
|
|
4360
|
-
if (
|
|
4361
|
-
return [{
|
|
4362
|
-
name: "test:distribution",
|
|
4363
|
-
command: distribution,
|
|
4364
|
-
accepted: []
|
|
4365
|
-
}, {
|
|
4413
|
+
if (prepublish !== void 0) writable.push({
|
|
4366
4414
|
name: "prepublishOnly",
|
|
4367
4415
|
command: prepublish,
|
|
4368
4416
|
accepted: [prepublish.replace(` && ${RELEASE_PROOF_COMMAND}`, "")]
|
|
4369
|
-
}
|
|
4417
|
+
});
|
|
4418
|
+
return writable;
|
|
4370
4419
|
}
|
|
4371
4420
|
/**
|
|
4372
4421
|
* Compile a blueprint into its `package.json` content.
|
|
@@ -4549,14 +4598,14 @@ function blueprintToRootVite(blueprint) {
|
|
|
4549
4598
|
const core = blueprint.src.includes("core");
|
|
4550
4599
|
factories.push(fillTemplate(CONFIG_TEMPLATES.factories.src.browser, {
|
|
4551
4600
|
external: core ? `external: (id: string) =>
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
output: core ? "
|
|
4558
|
-
exclude: core ? "
|
|
4559
|
-
global: blueprint.global ? "
|
|
4601
|
+
id === '@src/core' ||
|
|
4602
|
+
id.startsWith('@orkestrel/') ||
|
|
4603
|
+
peers.some((peer) => id === peer || id.startsWith(peer + '/')),` : `external: (id: string) =>
|
|
4604
|
+
id.startsWith('@orkestrel/') ||
|
|
4605
|
+
peers.some((peer) => id === peer || id.startsWith(peer + '/')),`,
|
|
4606
|
+
output: core ? " output: { paths: { '@src/core': '../core/index.js' } }," : " output: {},",
|
|
4607
|
+
exclude: core ? " exclude: ['tests/src/core/**/*.test.ts'],\n" : "",
|
|
4608
|
+
global: blueprint.global ? " globalSetup: ['./tests/setupGlobal.ts'],\n" : ""
|
|
4560
4609
|
}));
|
|
4561
4610
|
projects.push("srcBrowser");
|
|
4562
4611
|
}
|
|
@@ -4564,26 +4613,26 @@ function blueprintToRootVite(blueprint) {
|
|
|
4564
4613
|
const core = blueprint.src.includes("core");
|
|
4565
4614
|
factories.push(fillTemplate(CONFIG_TEMPLATES.factories.src.server, {
|
|
4566
4615
|
external: core ? `external: (id: string) =>
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
output: core ? `\t\t\
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
exclude: core ? "
|
|
4616
|
+
id === '@src/core' ||
|
|
4617
|
+
id.startsWith('node:') ||
|
|
4618
|
+
id.startsWith('@orkestrel/') ||
|
|
4619
|
+
peers.some((peer) => id === peer || id.startsWith(peer + '/')),` : `external: (id: string) =>
|
|
4620
|
+
id.startsWith('node:') ||
|
|
4621
|
+
id.startsWith('@orkestrel/') ||
|
|
4622
|
+
peers.some((peer) => id === peer || id.startsWith(peer + '/')),`,
|
|
4623
|
+
output: core ? `\t\t\toutput: [
|
|
4624
|
+
{
|
|
4625
|
+
format: 'es',
|
|
4626
|
+
entryFileNames: 'index.js',
|
|
4627
|
+
paths: { '@src/core': '../core/index.js' },
|
|
4628
|
+
},
|
|
4629
|
+
{
|
|
4630
|
+
format: 'cjs',
|
|
4631
|
+
entryFileNames: 'index.cjs',
|
|
4632
|
+
paths: { '@src/core': '../core/index.cjs' },
|
|
4633
|
+
},
|
|
4634
|
+
],` : " output: {},",
|
|
4635
|
+
exclude: core ? " exclude: ['tests/src/core/**/*.test.ts'],\n" : ""
|
|
4587
4636
|
}));
|
|
4588
4637
|
projects.push("srcServer");
|
|
4589
4638
|
}
|
|
@@ -4678,7 +4727,7 @@ export function appShowcase(): UserConfig {
|
|
|
4678
4727
|
projects.push("distribution");
|
|
4679
4728
|
}
|
|
4680
4729
|
if (blueprint.integration) {
|
|
4681
|
-
factories.push(fillTemplate(CONFIG_TEMPLATES.factories.integration, { global: blueprint.global ? "
|
|
4730
|
+
factories.push(fillTemplate(CONFIG_TEMPLATES.factories.integration, { global: blueprint.global ? " globalSetup: ['./tests/setupGlobal.ts'],\n" : "" }));
|
|
4682
4731
|
projects.push("integration");
|
|
4683
4732
|
}
|
|
4684
4733
|
factories.push(CONFIG_TEMPLATES.factories.probe);
|
|
@@ -5381,24 +5430,23 @@ function replaceManifestRanges(manifest, pins) {
|
|
|
5381
5430
|
*
|
|
5382
5431
|
* @param manifest - The manifest text to compile.
|
|
5383
5432
|
* @param scripts - The scripts to write, each with the predecessors it accepts.
|
|
5384
|
-
* @returns The manifest carrying every
|
|
5385
|
-
*
|
|
5386
|
-
* no readable `scripts` object to
|
|
5433
|
+
* @returns The manifest carrying every absent or accepted named script and
|
|
5434
|
+
* retaining every differing string value, or `undefined` when a planned key
|
|
5435
|
+
* holds a non-string value or the text carries no readable `scripts` object to
|
|
5436
|
+
* write into.
|
|
5387
5437
|
*
|
|
5388
5438
|
* @remarks
|
|
5389
5439
|
* The compiler replaces values in place instead of serializing the manifest, so
|
|
5390
5440
|
* description, keywords, dependencies, key order, indentation, and every byte
|
|
5391
5441
|
* outside the replaced ranges survive. A named script the manifest already
|
|
5392
|
-
* declares is overwritten only when its value is
|
|
5393
|
-
*
|
|
5394
|
-
*
|
|
5395
|
-
* byte
|
|
5396
|
-
* the
|
|
5397
|
-
*
|
|
5398
|
-
*
|
|
5399
|
-
*
|
|
5400
|
-
* The refusal is whole rather than per script, so a manifest never ends up
|
|
5401
|
-
* holding one written script beside one refused one.
|
|
5442
|
+
* declares is overwritten only when its value is one of its
|
|
5443
|
+
* {@link ManifestScript.accepted} predecessors. The planned value stands. Any
|
|
5444
|
+
* other string is a chain the workspace author customized, so it stays
|
|
5445
|
+
* byte-identical while the other named scripts are written independently. A
|
|
5446
|
+
* named script the manifest does not declare is appended after the last
|
|
5447
|
+
* declared script, copying that section's indentation. A region declaring
|
|
5448
|
+
* nothing takes every named script as its first entries, indented from the line
|
|
5449
|
+
* its own opening brace sits on.
|
|
5402
5450
|
*
|
|
5403
5451
|
* @example
|
|
5404
5452
|
* ```ts
|
|
@@ -5420,7 +5468,6 @@ function replaceManifestScripts(manifest, scripts) {
|
|
|
5420
5468
|
if (!Object.hasOwn(declared, script.name)) continue;
|
|
5421
5469
|
const value = declared[script.name];
|
|
5422
5470
|
if (!isString(value)) return void 0;
|
|
5423
|
-
if (value !== script.command && !script.accepted.includes(value)) return void 0;
|
|
5424
5471
|
}
|
|
5425
5472
|
let depth = 0;
|
|
5426
5473
|
let cursor = 0;
|
|
@@ -5548,6 +5595,8 @@ function replaceManifestScripts(manifest, scripts) {
|
|
|
5548
5595
|
const script = scripts.find((entry) => entry.name === key);
|
|
5549
5596
|
if (script === void 0) continue;
|
|
5550
5597
|
written.add(script.name);
|
|
5598
|
+
const value = declared[script.name];
|
|
5599
|
+
if (value === script.command || !isString(value) || !script.accepted.includes(value)) continue;
|
|
5551
5600
|
edits.push({
|
|
5552
5601
|
start: valueStart,
|
|
5553
5602
|
end: valueEnd + 1,
|