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