@bleedingdev/modern-js-create 3.2.0-ultramodern.1 → 3.2.0-ultramodern.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/index.js +330 -185
- package/package.json +5 -2
- package/template/.agents/skills-lock.json +34 -0
- package/template/AGENTS.md +20 -0
- package/template/api/effect/index.ts.handlebars +7 -45
- package/template/modern.config.ts.handlebars +20 -24
- package/template/oxfmt.config.ts +8 -0
- package/template/oxlint.config.ts +12 -0
- package/template/package.json.handlebars +41 -26
- package/template/scripts/bootstrap-agent-skills.mjs +95 -0
- package/template/scripts/validate-ultramodern.mjs.handlebars +81 -17
- package/template/shared/effect/api.ts.handlebars +1 -2
- package/template/src/modern.runtime.ts.handlebars +2 -4
- package/template/src/routes/index.css.handlebars +14 -3
- package/template/src/routes/page.tsx.handlebars +28 -11
- package/template/tsconfig.json +106 -2
- package/template-workspace/.agents/rstackjs-agent-skills-LICENSE +21 -0
- package/template-workspace/.agents/skills/rsbuild-best-practices/SKILL.md +57 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/SKILL.md +96 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/command-map.md +113 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/common-analysis-patterns.md +190 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-common.md +88 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-rspack.md +138 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor-webpack.md +71 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/install-rsdoctor.md +39 -0
- package/template-workspace/.agents/skills/rsdoctor-analysis/references/rsdoctor-data-types.md +103 -0
- package/template-workspace/.agents/skills/rslib-best-practices/SKILL.md +58 -0
- package/template-workspace/.agents/skills/rslib-modern-package/SKILL.md +173 -0
- package/template-workspace/.agents/skills/rspack-best-practices/SKILL.md +70 -0
- package/template-workspace/.agents/skills/rspack-tracing/SKILL.md +75 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/bottlenecks.md +47 -0
- package/template-workspace/.agents/skills/rspack-tracing/references/tracing-guide.md +38 -0
- package/template-workspace/.agents/skills/rspack-tracing/scripts/analyze_trace.js +184 -0
- package/template-workspace/.agents/skills/rstest-best-practices/SKILL.md +133 -0
- package/template-workspace/.agents/skills-lock.json +95 -0
- package/template-workspace/AGENTS.md +45 -0
- package/template-workspace/oxfmt.config.ts +16 -0
- package/template-workspace/oxlint.config.ts +19 -0
- package/template-workspace/pnpm-workspace.yaml +12 -0
- package/template-workspace/scripts/bootstrap-agent-skills.mjs +95 -0
- package/template-workspace/scripts/validate-ultramodern-workspace.mjs.handlebars +188 -59
- package/template/biome.json +0 -41
package/dist/index.js
CHANGED
|
@@ -485,7 +485,7 @@ const EN_LOCALE = {
|
|
|
485
485
|
example7: ' create my-app --bff',
|
|
486
486
|
example8: ' create my-app --router tanstack --bff-runtime effect',
|
|
487
487
|
example9: ' create my-app --router tanstack --bff-runtime effect --workspace',
|
|
488
|
-
example10: ' create my-super-app
|
|
488
|
+
example10: ' pnpm dlx @bleedingdev/modern-js-create my-super-app',
|
|
489
489
|
moreInfo: '📚 Learn more: https://modernjs.dev'
|
|
490
490
|
},
|
|
491
491
|
version: {
|
|
@@ -556,10 +556,32 @@ const ultramodern_workspace_dirname = node_path.dirname(fileURLToPath(import.met
|
|
|
556
556
|
const workspaceTemplateDir = node_path.resolve(ultramodern_workspace_dirname, '..', 'template-workspace');
|
|
557
557
|
const TANSTACK_ROUTER_VERSION = '1.170.1';
|
|
558
558
|
const MODULE_FEDERATION_VERSION = '2.4.0';
|
|
559
|
-
const
|
|
559
|
+
const EFFECT_TSGO_VERSION = '0.7.3';
|
|
560
|
+
const TYPESCRIPT_NATIVE_PREVIEW_VERSION = '7.0.0-dev.20260518.1';
|
|
561
|
+
const OXLINT_VERSION = '1.65.0';
|
|
562
|
+
const OXFMT_VERSION = '0.50.0';
|
|
563
|
+
const ULTRACITE_VERSION = '7.7.0';
|
|
560
564
|
const REACT_VERSION = '^19.2.6';
|
|
561
565
|
const REACT_DOM_VERSION = '^19.2.6';
|
|
562
566
|
const WORKSPACE_PACKAGE_VERSION = 'workspace:*';
|
|
567
|
+
const RSTACK_AGENT_SKILLS_COMMIT = '61c948b42512e223bad44b83af4080eba48b2677';
|
|
568
|
+
const baselineAgentSkills = [
|
|
569
|
+
'rsbuild-best-practices',
|
|
570
|
+
'rspack-best-practices',
|
|
571
|
+
'rspack-tracing',
|
|
572
|
+
'rsdoctor-analysis',
|
|
573
|
+
'rslib-best-practices',
|
|
574
|
+
'rslib-modern-package',
|
|
575
|
+
'rstest-best-practices'
|
|
576
|
+
];
|
|
577
|
+
const privateAgentSkills = [
|
|
578
|
+
'plan-graph',
|
|
579
|
+
'dag',
|
|
580
|
+
'subagent-graph',
|
|
581
|
+
'helm',
|
|
582
|
+
'debugger-mode'
|
|
583
|
+
];
|
|
584
|
+
const effectTsgoTypecheckCommand = "node -e \"const fs = require('node:fs'); const { execFileSync, spawnSync } = require('node:child_process'); const bin = execFileSync('effect-tsgo', ['get-exe-path'], { encoding: 'utf8' }).trim(); if (process.platform !== 'win32') fs.chmodSync(bin, 0o755); const result = spawnSync(bin, ['--noEmit', '-p', 'tsconfig.json'], { stdio: 'inherit' }); process.exit(result.status ?? 1);\"";
|
|
563
585
|
const modernPackageNames = [
|
|
564
586
|
'@modern-js/app-tools',
|
|
565
587
|
'@modern-js/plugin-bff',
|
|
@@ -609,7 +631,7 @@ const remoteApps = [
|
|
|
609
631
|
mfName: 'remoteCommerce',
|
|
610
632
|
exposes: {
|
|
611
633
|
'./Route': './src/remote-entry.tsx',
|
|
612
|
-
'./Widget': './src/components/
|
|
634
|
+
'./Widget': './src/components/commerce-widget.tsx'
|
|
613
635
|
},
|
|
614
636
|
ownership: {
|
|
615
637
|
team: 'commerce-experience',
|
|
@@ -638,7 +660,7 @@ const remoteApps = [
|
|
|
638
660
|
mfName: 'remoteIdentity',
|
|
639
661
|
exposes: {
|
|
640
662
|
'./Route': './src/remote-entry.tsx',
|
|
641
|
-
'./Widget': './src/components/
|
|
663
|
+
'./Widget': './src/components/identity-widget.tsx'
|
|
642
664
|
},
|
|
643
665
|
ownership: {
|
|
644
666
|
team: 'identity-platform',
|
|
@@ -666,7 +688,7 @@ const remoteApps = [
|
|
|
666
688
|
port: 3023,
|
|
667
689
|
mfName: 'remoteDesignSystem',
|
|
668
690
|
exposes: {
|
|
669
|
-
'./Button': './src/components/
|
|
691
|
+
'./Button': './src/components/button.tsx',
|
|
670
692
|
'./tokens': './src/tokens.ts'
|
|
671
693
|
},
|
|
672
694
|
ownership: {
|
|
@@ -706,6 +728,81 @@ const effectService = {
|
|
|
706
728
|
}
|
|
707
729
|
}
|
|
708
730
|
};
|
|
731
|
+
const effectDiagnostics = [
|
|
732
|
+
'anyUnknownInErrorContext',
|
|
733
|
+
'classSelfMismatch',
|
|
734
|
+
'duplicatePackage',
|
|
735
|
+
'effectFnImplicitAny',
|
|
736
|
+
'floatingEffect',
|
|
737
|
+
'genericEffectServices',
|
|
738
|
+
'missingEffectContext',
|
|
739
|
+
'missingEffectError',
|
|
740
|
+
'missingLayerContext',
|
|
741
|
+
'missingReturnYieldStar',
|
|
742
|
+
'missingStarInYieldEffectGen',
|
|
743
|
+
'nonObjectEffectServiceType',
|
|
744
|
+
'outdatedApi',
|
|
745
|
+
'overriddenSchemaConstructor',
|
|
746
|
+
'catchUnfailableEffect',
|
|
747
|
+
'effectFnIife',
|
|
748
|
+
'effectGenUsesAdapter',
|
|
749
|
+
'effectInFailure',
|
|
750
|
+
'effectInVoidSuccess',
|
|
751
|
+
'globalErrorInEffectCatch',
|
|
752
|
+
'globalErrorInEffectFailure',
|
|
753
|
+
'layerMergeAllWithDependencies',
|
|
754
|
+
'lazyPromiseInEffectSync',
|
|
755
|
+
'leakingRequirements',
|
|
756
|
+
'multipleEffectProvide',
|
|
757
|
+
'returnEffectInGen',
|
|
758
|
+
'runEffectInsideEffect',
|
|
759
|
+
'schemaSyncInEffect',
|
|
760
|
+
'scopeInLayerEffect',
|
|
761
|
+
'strictEffectProvide',
|
|
762
|
+
'tryCatchInEffectGen',
|
|
763
|
+
'unknownInEffectCatch',
|
|
764
|
+
'asyncFunction',
|
|
765
|
+
'cryptoRandomUUID',
|
|
766
|
+
'cryptoRandomUUIDInEffect',
|
|
767
|
+
'extendsNativeError',
|
|
768
|
+
'globalConsole',
|
|
769
|
+
'globalConsoleInEffect',
|
|
770
|
+
'globalDate',
|
|
771
|
+
'globalDateInEffect',
|
|
772
|
+
'globalFetch',
|
|
773
|
+
'globalFetchInEffect',
|
|
774
|
+
'globalRandom',
|
|
775
|
+
'globalRandomInEffect',
|
|
776
|
+
'globalTimers',
|
|
777
|
+
'globalTimersInEffect',
|
|
778
|
+
'instanceOfSchema',
|
|
779
|
+
'newPromise',
|
|
780
|
+
'nodeBuiltinImport',
|
|
781
|
+
'preferSchemaOverJson',
|
|
782
|
+
'processEnv',
|
|
783
|
+
'processEnvInEffect',
|
|
784
|
+
'unsafeEffectTypeAssertion',
|
|
785
|
+
'catchAllToMapError',
|
|
786
|
+
'deterministicKeys',
|
|
787
|
+
'effectDoNotation',
|
|
788
|
+
'effectFnOpportunity',
|
|
789
|
+
'effectMapFlatten',
|
|
790
|
+
'effectMapVoid',
|
|
791
|
+
'effectSucceedWithVoid',
|
|
792
|
+
'missedPipeableOpportunity',
|
|
793
|
+
'missingEffectServiceDependency',
|
|
794
|
+
'nestedEffectGenYield',
|
|
795
|
+
'redundantSchemaTagIdentifier',
|
|
796
|
+
'schemaStructWithTag',
|
|
797
|
+
'schemaUnionOfLiterals',
|
|
798
|
+
'serviceNotAsClass',
|
|
799
|
+
'strictBooleanExpressions',
|
|
800
|
+
'unnecessaryArrowBlock',
|
|
801
|
+
'unnecessaryEffectGen',
|
|
802
|
+
'unnecessaryFailYieldableError',
|
|
803
|
+
'unnecessaryPipe',
|
|
804
|
+
'unnecessaryPipeChain'
|
|
805
|
+
];
|
|
709
806
|
const sharedPackages = [
|
|
710
807
|
{
|
|
711
808
|
id: 'shared-contracts',
|
|
@@ -834,10 +931,11 @@ function appDependencies(scope, packageSource) {
|
|
|
834
931
|
function appDevDependencies(packageSource) {
|
|
835
932
|
return {
|
|
836
933
|
'@modern-js/app-tools': modernPackageSpecifier('@modern-js/app-tools', packageSource),
|
|
934
|
+
'@effect/tsgo': EFFECT_TSGO_VERSION,
|
|
935
|
+
"@typescript/native-preview": TYPESCRIPT_NATIVE_PREVIEW_VERSION,
|
|
837
936
|
'@types/node': '^20',
|
|
838
937
|
'@types/react': '^19.1.8',
|
|
839
|
-
'@types/react-dom': '^19.1.6'
|
|
840
|
-
typescript: TYPESCRIPT_VERSION
|
|
938
|
+
'@types/react-dom': '^19.1.6'
|
|
841
939
|
};
|
|
842
940
|
}
|
|
843
941
|
function createRootPackageJson(scope, packageSource) {
|
|
@@ -845,6 +943,8 @@ function createRootPackageJson(scope, packageSource) {
|
|
|
845
943
|
private: true,
|
|
846
944
|
name: scope,
|
|
847
945
|
version: '0.1.0',
|
|
946
|
+
type: 'module',
|
|
947
|
+
packageManager: 'pnpm@11.1.2',
|
|
848
948
|
scripts: {
|
|
849
949
|
dev: `pnpm --parallel --filter ${ultramodern_workspace_packageName(scope, shellApp.packageSuffix)} --filter ${ultramodern_workspace_packageName(scope, 'remote-commerce')} --filter ${ultramodern_workspace_packageName(scope, 'remote-identity')} --filter ${ultramodern_workspace_packageName(scope, 'remote-design-system')} dev`,
|
|
850
950
|
'dev:shell': `pnpm --filter ${ultramodern_workspace_packageName(scope, shellApp.packageSuffix)} dev`,
|
|
@@ -853,13 +953,19 @@ function createRootPackageJson(scope, packageSource) {
|
|
|
853
953
|
'dev:design-system': `pnpm --filter ${ultramodern_workspace_packageName(scope, 'remote-design-system')} dev`,
|
|
854
954
|
'dev:recommendations': `pnpm --filter ${ultramodern_workspace_packageName(scope, effectService.packageSuffix)} dev`,
|
|
855
955
|
build: 'pnpm -r --filter ./apps/** --filter ./services/** build',
|
|
856
|
-
|
|
956
|
+
format: 'oxfmt .',
|
|
957
|
+
'format:check': 'oxfmt --check .',
|
|
958
|
+
lint: 'oxlint .',
|
|
959
|
+
'lint:fix': 'oxlint . --fix',
|
|
960
|
+
typecheck: `pnpm -r --filter "@${scope}/*" typecheck`,
|
|
961
|
+
'skills:install': "node ./scripts/bootstrap-agent-skills.mjs",
|
|
962
|
+
'skills:check': "node ./scripts/bootstrap-agent-skills.mjs --check",
|
|
857
963
|
'ultramodern:check': "node ./scripts/validate-ultramodern-workspace.mjs",
|
|
858
|
-
check: 'pnpm ultramodern:check'
|
|
964
|
+
check: 'pnpm format:check && pnpm lint && pnpm typecheck && pnpm skills:check && pnpm ultramodern:check'
|
|
859
965
|
},
|
|
860
966
|
engines: {
|
|
861
967
|
node: '>=20',
|
|
862
|
-
pnpm: '>=
|
|
968
|
+
pnpm: '>=11.0.0'
|
|
863
969
|
},
|
|
864
970
|
workspaces: [
|
|
865
971
|
'apps/*',
|
|
@@ -867,15 +973,6 @@ function createRootPackageJson(scope, packageSource) {
|
|
|
867
973
|
'services/*',
|
|
868
974
|
'packages/*'
|
|
869
975
|
],
|
|
870
|
-
pnpm: {
|
|
871
|
-
onlyBuiltDependencies: [
|
|
872
|
-
'@biomejs/biome',
|
|
873
|
-
'@swc/core',
|
|
874
|
-
'core-js',
|
|
875
|
-
'esbuild',
|
|
876
|
-
'msgpackr-extract'
|
|
877
|
-
]
|
|
878
|
-
},
|
|
879
976
|
modernjs: {
|
|
880
977
|
preset: 'presetUltramodern',
|
|
881
978
|
workspace: 'ultramodern-superapp',
|
|
@@ -887,35 +984,56 @@ function createRootPackageJson(scope, packageSource) {
|
|
|
887
984
|
}
|
|
888
985
|
},
|
|
889
986
|
devDependencies: {
|
|
890
|
-
'@
|
|
891
|
-
typescript:
|
|
987
|
+
'@effect/tsgo': EFFECT_TSGO_VERSION,
|
|
988
|
+
"@typescript/native-preview": TYPESCRIPT_NATIVE_PREVIEW_VERSION,
|
|
989
|
+
oxlint: OXLINT_VERSION,
|
|
990
|
+
oxfmt: OXFMT_VERSION,
|
|
991
|
+
ultracite: ULTRACITE_VERSION
|
|
892
992
|
}
|
|
893
993
|
};
|
|
894
994
|
}
|
|
895
|
-
function createTsConfigBase(
|
|
995
|
+
function createTsConfigBase() {
|
|
896
996
|
return {
|
|
897
997
|
compilerOptions: {
|
|
898
|
-
target: '
|
|
998
|
+
target: 'ESNext',
|
|
899
999
|
lib: [
|
|
1000
|
+
'ESNext',
|
|
900
1001
|
'DOM',
|
|
901
|
-
'DOM.Iterable'
|
|
902
|
-
'ES2022'
|
|
1002
|
+
'DOM.Iterable'
|
|
903
1003
|
],
|
|
904
|
-
module: '
|
|
1004
|
+
module: 'preserve',
|
|
905
1005
|
moduleResolution: 'Bundler',
|
|
1006
|
+
moduleDetection: 'force',
|
|
906
1007
|
jsx: 'preserve',
|
|
1008
|
+
isolatedModules: true,
|
|
1009
|
+
verbatimModuleSyntax: true,
|
|
907
1010
|
strict: true,
|
|
908
1011
|
noEmit: true,
|
|
1012
|
+
allowJs: true,
|
|
909
1013
|
esModuleInterop: true,
|
|
1014
|
+
noUncheckedIndexedAccess: true,
|
|
1015
|
+
exactOptionalPropertyTypes: true,
|
|
1016
|
+
noImplicitOverride: true,
|
|
1017
|
+
noFallthroughCasesInSwitch: true,
|
|
1018
|
+
noPropertyAccessFromIndexSignature: true,
|
|
1019
|
+
noImplicitReturns: true,
|
|
910
1020
|
skipLibCheck: true,
|
|
911
1021
|
resolveJsonModule: true,
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1022
|
+
plugins: [
|
|
1023
|
+
{
|
|
1024
|
+
name: '@effect/language-service',
|
|
1025
|
+
diagnostics: true,
|
|
1026
|
+
includeSuggestionsInTsc: true,
|
|
1027
|
+
ignoreEffectSuggestionsInTscExitCode: false,
|
|
1028
|
+
ignoreEffectWarningsInTscExitCode: false,
|
|
1029
|
+
ignoreEffectErrorsInTscExitCode: false,
|
|
1030
|
+
skipDisabledOptimization: true,
|
|
1031
|
+
diagnosticSeverity: Object.fromEntries(effectDiagnostics.map((name)=>[
|
|
1032
|
+
name,
|
|
1033
|
+
'error'
|
|
1034
|
+
]))
|
|
1035
|
+
}
|
|
1036
|
+
]
|
|
919
1037
|
}
|
|
920
1038
|
};
|
|
921
1039
|
}
|
|
@@ -928,20 +1046,6 @@ function createPackageTsConfig(packageDir, includeApi = false) {
|
|
|
928
1046
|
if (includeApi) include.push('api', 'shared');
|
|
929
1047
|
return {
|
|
930
1048
|
extends: `${relativeRootFor(packageDir)}/tsconfig.base.json`,
|
|
931
|
-
compilerOptions: {
|
|
932
|
-
baseUrl: '.',
|
|
933
|
-
paths: {
|
|
934
|
-
'@/*': [
|
|
935
|
-
'./src/*'
|
|
936
|
-
],
|
|
937
|
-
'@api/*': [
|
|
938
|
-
'./api/*'
|
|
939
|
-
],
|
|
940
|
-
'@shared/*': [
|
|
941
|
-
'./shared/*'
|
|
942
|
-
]
|
|
943
|
-
}
|
|
944
|
-
},
|
|
945
1049
|
include
|
|
946
1050
|
};
|
|
947
1051
|
}
|
|
@@ -954,7 +1058,7 @@ function createAppPackage(scope, app, packageSource) {
|
|
|
954
1058
|
dev: 'modern dev',
|
|
955
1059
|
build: 'modern build',
|
|
956
1060
|
serve: 'modern serve',
|
|
957
|
-
typecheck:
|
|
1061
|
+
typecheck: effectTsgoTypecheckCommand
|
|
958
1062
|
},
|
|
959
1063
|
modernjs: {
|
|
960
1064
|
preset: 'presetUltramodern',
|
|
@@ -975,7 +1079,7 @@ function createServicePackage(scope, packageSource) {
|
|
|
975
1079
|
dev: 'modern dev',
|
|
976
1080
|
build: 'modern build',
|
|
977
1081
|
serve: 'modern serve',
|
|
978
|
-
typecheck:
|
|
1082
|
+
typecheck: effectTsgoTypecheckCommand
|
|
979
1083
|
},
|
|
980
1084
|
modernjs: {
|
|
981
1085
|
preset: 'presetUltramodern',
|
|
@@ -992,10 +1096,11 @@ function createServicePackage(scope, packageSource) {
|
|
|
992
1096
|
devDependencies: {
|
|
993
1097
|
'@modern-js/app-tools': modernPackageSpecifier('@modern-js/app-tools', packageSource),
|
|
994
1098
|
'@modern-js/plugin-bff': modernPackageSpecifier('@modern-js/plugin-bff', packageSource),
|
|
1099
|
+
'@effect/tsgo': EFFECT_TSGO_VERSION,
|
|
1100
|
+
"@typescript/native-preview": TYPESCRIPT_NATIVE_PREVIEW_VERSION,
|
|
995
1101
|
'@types/node': '^20',
|
|
996
1102
|
'@types/react': '^19.1.8',
|
|
997
|
-
'@types/react-dom': '^19.1.6'
|
|
998
|
-
typescript: TYPESCRIPT_VERSION
|
|
1103
|
+
'@types/react-dom': '^19.1.6'
|
|
999
1104
|
}
|
|
1000
1105
|
};
|
|
1001
1106
|
}
|
|
@@ -1010,24 +1115,32 @@ function createSharedPackage(scope, id, description) {
|
|
|
1010
1115
|
'.': './src/index.ts'
|
|
1011
1116
|
},
|
|
1012
1117
|
scripts: {
|
|
1013
|
-
typecheck:
|
|
1118
|
+
typecheck: effectTsgoTypecheckCommand
|
|
1014
1119
|
},
|
|
1015
1120
|
devDependencies: {
|
|
1016
|
-
|
|
1121
|
+
'@effect/tsgo': EFFECT_TSGO_VERSION,
|
|
1122
|
+
"@typescript/native-preview": TYPESCRIPT_NATIVE_PREVIEW_VERSION
|
|
1017
1123
|
}
|
|
1018
1124
|
};
|
|
1019
1125
|
}
|
|
1020
1126
|
function createAppModernConfig(app) {
|
|
1021
|
-
return
|
|
1127
|
+
return `// @effect-diagnostics processEnv:off
|
|
1128
|
+
import { appTools, defineConfig, presetUltramodern } from '@modern-js/app-tools';
|
|
1022
1129
|
import { tanstackRouterPlugin } from '@modern-js/plugin-tanstack';
|
|
1023
1130
|
import { moduleFederationPlugin } from '@module-federation/modern-js-v3';
|
|
1024
1131
|
|
|
1025
1132
|
const appId = '${app.id}';
|
|
1026
|
-
const port = Number(process.env
|
|
1133
|
+
const port = Number(process.env['${app.portEnv}'] ?? ${app.port});
|
|
1027
1134
|
|
|
1028
1135
|
export default defineConfig(
|
|
1029
1136
|
presetUltramodern(
|
|
1030
1137
|
{
|
|
1138
|
+
output: {
|
|
1139
|
+
disableTsChecker: true,
|
|
1140
|
+
polyfill: 'off',
|
|
1141
|
+
splitRouteChunks: false,
|
|
1142
|
+
},
|
|
1143
|
+
plugins: [appTools(), tanstackRouterPlugin(), moduleFederationPlugin()],
|
|
1031
1144
|
server: {
|
|
1032
1145
|
port,
|
|
1033
1146
|
ssr: {
|
|
@@ -1035,21 +1148,11 @@ export default defineConfig(
|
|
|
1035
1148
|
moduleFederationAppSSR: true,
|
|
1036
1149
|
},
|
|
1037
1150
|
},
|
|
1038
|
-
output: {
|
|
1039
|
-
polyfill: 'off',
|
|
1040
|
-
disableTsChecker: true,
|
|
1041
|
-
splitRouteChunks: false,
|
|
1042
|
-
},
|
|
1043
|
-
plugins: [
|
|
1044
|
-
appTools(),
|
|
1045
|
-
tanstackRouterPlugin(),
|
|
1046
|
-
moduleFederationPlugin(),
|
|
1047
|
-
],
|
|
1048
1151
|
},
|
|
1049
1152
|
{
|
|
1050
1153
|
appId,
|
|
1051
|
-
enableModuleFederationSSR: true,
|
|
1052
1154
|
enableBffRequestId: true,
|
|
1155
|
+
enableModuleFederationSSR: true,
|
|
1053
1156
|
enableTelemetryExporters: true,
|
|
1054
1157
|
telemetryFailLoudStartup: false,
|
|
1055
1158
|
},
|
|
@@ -1057,129 +1160,112 @@ export default defineConfig(
|
|
|
1057
1160
|
);
|
|
1058
1161
|
`;
|
|
1059
1162
|
}
|
|
1163
|
+
function createSharedModuleFederationConfig() {
|
|
1164
|
+
return ` shared: {
|
|
1165
|
+
'@modern-js/runtime': {
|
|
1166
|
+
requiredVersion: runtimeVersion,
|
|
1167
|
+
singleton: true,
|
|
1168
|
+
treeShaking: false,
|
|
1169
|
+
},
|
|
1170
|
+
'@tanstack/react-router': {
|
|
1171
|
+
requiredVersion: dependencies['@tanstack/react-router'],
|
|
1172
|
+
singleton: true,
|
|
1173
|
+
treeShaking: false,
|
|
1174
|
+
},
|
|
1175
|
+
react: {
|
|
1176
|
+
requiredVersion: reactVersion,
|
|
1177
|
+
singleton: true,
|
|
1178
|
+
treeShaking: false,
|
|
1179
|
+
},
|
|
1180
|
+
'react-dom': {
|
|
1181
|
+
requiredVersion: reactDomVersion,
|
|
1182
|
+
singleton: true,
|
|
1183
|
+
treeShaking: false,
|
|
1184
|
+
},
|
|
1185
|
+
}`;
|
|
1186
|
+
}
|
|
1187
|
+
function formatTsObjectLiteral(value) {
|
|
1188
|
+
const entries = Object.entries(value).sort(([left], [right])=>left.localeCompare(right));
|
|
1189
|
+
if (0 === entries.length) return '{}';
|
|
1190
|
+
return `{
|
|
1191
|
+
${entries.map(([key, entryValue])=>` '${key}': '${entryValue}',`).join('\n')}
|
|
1192
|
+
}`;
|
|
1193
|
+
}
|
|
1060
1194
|
function createShellModuleFederationConfig() {
|
|
1061
|
-
return
|
|
1195
|
+
return `// @effect-diagnostics nodeBuiltinImport:off processEnv:off
|
|
1196
|
+
import { createRequire } from 'node:module';
|
|
1062
1197
|
import { createModuleFederationConfig } from '@module-federation/modern-js-v3';
|
|
1063
1198
|
import { dependencies } from './package.json';
|
|
1064
1199
|
|
|
1065
1200
|
const require = createRequire(import.meta.url);
|
|
1066
|
-
const runtimeVersion = (
|
|
1067
|
-
|
|
1068
|
-
).version;
|
|
1069
|
-
const reactVersion = (require('react/package.json') as { version: string })
|
|
1070
|
-
.version;
|
|
1071
|
-
const reactDomVersion = (
|
|
1072
|
-
require('react-dom/package.json') as { version: string }
|
|
1073
|
-
).version;
|
|
1201
|
+
const runtimeVersion = (require('@modern-js/runtime/package.json') as { version: string }).version;
|
|
1202
|
+
const reactVersion = (require('react/package.json') as { version: string }).version;
|
|
1203
|
+
const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
|
|
1074
1204
|
|
|
1075
1205
|
export default createModuleFederationConfig({
|
|
1076
|
-
name: '${shellApp.mfName}',
|
|
1077
1206
|
dts: false,
|
|
1207
|
+
filename: 'remoteEntry.js',
|
|
1208
|
+
name: '${shellApp.mfName}',
|
|
1078
1209
|
remotes: {
|
|
1079
1210
|
commerce:
|
|
1080
|
-
process.env
|
|
1211
|
+
process.env['REMOTE_COMMERCE_MF_MANIFEST'] ??
|
|
1081
1212
|
'remoteCommerce@http://localhost:3021/mf-manifest.json',
|
|
1082
|
-
identity:
|
|
1083
|
-
process.env.REMOTE_IDENTITY_MF_MANIFEST ??
|
|
1084
|
-
'remoteIdentity@http://localhost:3022/mf-manifest.json',
|
|
1085
1213
|
designSystem:
|
|
1086
|
-
process.env
|
|
1214
|
+
process.env['REMOTE_DESIGN_SYSTEM_MF_MANIFEST'] ??
|
|
1087
1215
|
'remoteDesignSystem@http://localhost:3023/mf-manifest.json',
|
|
1216
|
+
identity:
|
|
1217
|
+
process.env['REMOTE_IDENTITY_MF_MANIFEST'] ??
|
|
1218
|
+
'remoteIdentity@http://localhost:3022/mf-manifest.json',
|
|
1088
1219
|
},
|
|
1089
|
-
|
|
1090
|
-
react: {
|
|
1091
|
-
singleton: true,
|
|
1092
|
-
requiredVersion: reactVersion,
|
|
1093
|
-
treeShaking: false,
|
|
1094
|
-
},
|
|
1095
|
-
'react-dom': {
|
|
1096
|
-
singleton: true,
|
|
1097
|
-
requiredVersion: reactDomVersion,
|
|
1098
|
-
treeShaking: false,
|
|
1099
|
-
},
|
|
1100
|
-
'@tanstack/react-router': {
|
|
1101
|
-
singleton: true,
|
|
1102
|
-
requiredVersion: dependencies['@tanstack/react-router'],
|
|
1103
|
-
treeShaking: false,
|
|
1104
|
-
},
|
|
1105
|
-
'@modern-js/runtime': {
|
|
1106
|
-
singleton: true,
|
|
1107
|
-
requiredVersion: runtimeVersion,
|
|
1108
|
-
treeShaking: false,
|
|
1109
|
-
},
|
|
1110
|
-
},
|
|
1220
|
+
${createSharedModuleFederationConfig()},
|
|
1111
1221
|
});
|
|
1112
1222
|
`;
|
|
1113
1223
|
}
|
|
1114
1224
|
function createRemoteModuleFederationConfig(app) {
|
|
1115
|
-
const exposes =
|
|
1116
|
-
return
|
|
1225
|
+
const exposes = formatTsObjectLiteral(app.exposes ?? {});
|
|
1226
|
+
return `// @effect-diagnostics nodeBuiltinImport:off
|
|
1227
|
+
import { createRequire } from 'node:module';
|
|
1117
1228
|
import { createModuleFederationConfig } from '@module-federation/modern-js-v3';
|
|
1118
1229
|
import { dependencies } from './package.json';
|
|
1119
1230
|
|
|
1120
1231
|
const require = createRequire(import.meta.url);
|
|
1121
|
-
const runtimeVersion = (
|
|
1122
|
-
|
|
1123
|
-
).version;
|
|
1124
|
-
const reactVersion = (require('react/package.json') as { version: string })
|
|
1125
|
-
.version;
|
|
1126
|
-
const reactDomVersion = (
|
|
1127
|
-
require('react-dom/package.json') as { version: string }
|
|
1128
|
-
).version;
|
|
1232
|
+
const runtimeVersion = (require('@modern-js/runtime/package.json') as { version: string }).version;
|
|
1233
|
+
const reactVersion = (require('react/package.json') as { version: string }).version;
|
|
1234
|
+
const reactDomVersion = (require('react-dom/package.json') as { version: string }).version;
|
|
1129
1235
|
|
|
1130
1236
|
export default createModuleFederationConfig({
|
|
1131
|
-
name: '${app.mfName}',
|
|
1132
1237
|
dts: false,
|
|
1133
|
-
filename: 'remoteEntry.js',
|
|
1134
1238
|
exposes: ${exposes},
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
requiredVersion: reactVersion,
|
|
1139
|
-
treeShaking: false,
|
|
1140
|
-
},
|
|
1141
|
-
'react-dom': {
|
|
1142
|
-
singleton: true,
|
|
1143
|
-
requiredVersion: reactDomVersion,
|
|
1144
|
-
treeShaking: false,
|
|
1145
|
-
},
|
|
1146
|
-
'@tanstack/react-router': {
|
|
1147
|
-
singleton: true,
|
|
1148
|
-
requiredVersion: dependencies['@tanstack/react-router'],
|
|
1149
|
-
treeShaking: false,
|
|
1150
|
-
},
|
|
1151
|
-
'@modern-js/runtime': {
|
|
1152
|
-
singleton: true,
|
|
1153
|
-
requiredVersion: runtimeVersion,
|
|
1154
|
-
treeShaking: false,
|
|
1155
|
-
},
|
|
1156
|
-
},
|
|
1239
|
+
filename: 'remoteEntry.js',
|
|
1240
|
+
name: '${app.mfName}',
|
|
1241
|
+
${createSharedModuleFederationConfig()},
|
|
1157
1242
|
});
|
|
1158
1243
|
`;
|
|
1159
1244
|
}
|
|
1160
1245
|
function createServiceModernConfig() {
|
|
1161
|
-
return
|
|
1246
|
+
return `// @effect-diagnostics processEnv:off
|
|
1247
|
+
import { appTools, defineConfig, presetUltramodern } from '@modern-js/app-tools';
|
|
1162
1248
|
import { bffPlugin } from '@modern-js/plugin-bff';
|
|
1163
1249
|
|
|
1164
1250
|
const appId = '${effectService.id}';
|
|
1165
|
-
const port = Number(process.env
|
|
1251
|
+
const port = Number(process.env['${effectService.portEnv}'] ?? ${effectService.port});
|
|
1166
1252
|
|
|
1167
1253
|
export default defineConfig(
|
|
1168
1254
|
presetUltramodern(
|
|
1169
1255
|
{
|
|
1170
|
-
server: {
|
|
1171
|
-
port,
|
|
1172
|
-
},
|
|
1173
1256
|
bff: {
|
|
1174
|
-
prefix: '/recommendations-api',
|
|
1175
|
-
runtimeFramework: 'effect',
|
|
1176
1257
|
effect: {
|
|
1177
1258
|
openapi: {
|
|
1178
1259
|
path: '/openapi.json',
|
|
1179
1260
|
},
|
|
1180
1261
|
},
|
|
1262
|
+
prefix: '/recommendations-api',
|
|
1263
|
+
runtimeFramework: 'effect',
|
|
1181
1264
|
},
|
|
1182
1265
|
plugins: [appTools(), bffPlugin()],
|
|
1266
|
+
server: {
|
|
1267
|
+
port,
|
|
1268
|
+
},
|
|
1183
1269
|
},
|
|
1184
1270
|
{
|
|
1185
1271
|
appId,
|
|
@@ -1192,11 +1278,7 @@ export default defineConfig(
|
|
|
1192
1278
|
`;
|
|
1193
1279
|
}
|
|
1194
1280
|
function createShellPage() {
|
|
1195
|
-
return `const remotes = [
|
|
1196
|
-
'remote-commerce',
|
|
1197
|
-
'remote-identity',
|
|
1198
|
-
'remote-design-system',
|
|
1199
|
-
];
|
|
1281
|
+
return `const remotes = ['remote-commerce', 'remote-identity', 'remote-design-system'];
|
|
1200
1282
|
|
|
1201
1283
|
export default function ShellHome() {
|
|
1202
1284
|
return (
|
|
@@ -1204,7 +1286,7 @@ export default function ShellHome() {
|
|
|
1204
1286
|
<h1>UltraModern SuperApp Shell</h1>
|
|
1205
1287
|
<p data-testid="ultramodern-preset">presetUltramodern workspace</p>
|
|
1206
1288
|
<ul>
|
|
1207
|
-
{remotes.map(remote => (
|
|
1289
|
+
{remotes.map((remote) => (
|
|
1208
1290
|
<li key={remote}>{remote}</li>
|
|
1209
1291
|
))}
|
|
1210
1292
|
</ul>
|
|
@@ -1233,8 +1315,8 @@ export default function Layout({ children }: { children: ReactNode }) {
|
|
|
1233
1315
|
`;
|
|
1234
1316
|
}
|
|
1235
1317
|
function createRemoteEntry(app) {
|
|
1236
|
-
const
|
|
1237
|
-
return `export { default } from './components/${
|
|
1318
|
+
const componentFile = 'remote-identity' === app.id ? 'identity-widget' : 'commerce-widget';
|
|
1319
|
+
return `export { default } from './components/${componentFile}';
|
|
1238
1320
|
`;
|
|
1239
1321
|
}
|
|
1240
1322
|
function createRemoteWidget(app) {
|
|
@@ -1270,8 +1352,8 @@ export default function Button({ label = 'Design System Button' }: { label?: str
|
|
|
1270
1352
|
function createDesignTokens() {
|
|
1271
1353
|
return `export const designTokens = {
|
|
1272
1354
|
color: {
|
|
1273
|
-
foreground: '#133225',
|
|
1274
1355
|
accent: '#2f8f68',
|
|
1356
|
+
foreground: '#133225',
|
|
1275
1357
|
},
|
|
1276
1358
|
radius: {
|
|
1277
1359
|
control: '999px',
|
|
@@ -1292,9 +1374,7 @@ const recommendationSchema = Schema.Struct({
|
|
|
1292
1374
|
title: Schema.String,
|
|
1293
1375
|
});
|
|
1294
1376
|
|
|
1295
|
-
export const recommendationsEffectApi = HttpApi.make(
|
|
1296
|
-
'RecommendationsEffectApi',
|
|
1297
|
-
).add(
|
|
1377
|
+
export const recommendationsEffectApi = HttpApi.make('RecommendationsEffectApi').add(
|
|
1298
1378
|
HttpApiGroup.make('recommendations').add(
|
|
1299
1379
|
HttpApiEndpoint.get('list', '/effect/recommendations', {
|
|
1300
1380
|
success: Schema.Struct({
|
|
@@ -1317,7 +1397,7 @@ import { recommendationsEffectApi } from '../../shared/effect/api';
|
|
|
1317
1397
|
const recommendationsLayer = HttpApiBuilder.group(
|
|
1318
1398
|
recommendationsEffectApi,
|
|
1319
1399
|
'recommendations',
|
|
1320
|
-
(handlers
|
|
1400
|
+
(handlers) =>
|
|
1321
1401
|
handlers.handle('list', () =>
|
|
1322
1402
|
Effect.succeed({
|
|
1323
1403
|
items: [
|
|
@@ -1541,11 +1621,15 @@ function createTemplateManifest(modernVersion, packageSource) {
|
|
|
1541
1621
|
materialization: {
|
|
1542
1622
|
targetRoot: 'generated-project-root',
|
|
1543
1623
|
allowedPaths: [
|
|
1624
|
+
'.agents/**',
|
|
1544
1625
|
'.modernjs/**',
|
|
1626
|
+
'AGENTS.md',
|
|
1545
1627
|
'README.md',
|
|
1546
1628
|
'apps/**',
|
|
1547
1629
|
'packages/**',
|
|
1548
1630
|
'package.json',
|
|
1631
|
+
'oxfmt.config.ts',
|
|
1632
|
+
'oxlint.config.ts',
|
|
1549
1633
|
'pnpm-workspace.yaml',
|
|
1550
1634
|
"scripts/**",
|
|
1551
1635
|
'services/**',
|
|
@@ -1570,6 +1654,22 @@ function createTemplateManifest(modernVersion, packageSource) {
|
|
|
1570
1654
|
modernPackageSpecifier: modernPackageVersion(packageSource),
|
|
1571
1655
|
generatedWorkspacePackageSpecifier: WORKSPACE_PACKAGE_VERSION
|
|
1572
1656
|
},
|
|
1657
|
+
agentSkills: {
|
|
1658
|
+
installDir: '.agents/skills',
|
|
1659
|
+
source: {
|
|
1660
|
+
repository: 'https://github.com/rstackjs/agent-skills',
|
|
1661
|
+
commit: RSTACK_AGENT_SKILLS_COMMIT,
|
|
1662
|
+
license: 'MIT',
|
|
1663
|
+
licensePath: '.agents/rstackjs-agent-skills-LICENSE'
|
|
1664
|
+
},
|
|
1665
|
+
baseline: baselineAgentSkills,
|
|
1666
|
+
privateSource: {
|
|
1667
|
+
repository: 'https://github.com/TechsioCZ/skills',
|
|
1668
|
+
install: 'clone-if-authorized',
|
|
1669
|
+
baseline: privateAgentSkills
|
|
1670
|
+
},
|
|
1671
|
+
lockFile: '.agents/skills-lock.json'
|
|
1672
|
+
},
|
|
1573
1673
|
validation: {
|
|
1574
1674
|
schemaValidation: true,
|
|
1575
1675
|
sourceValidation: [
|
|
@@ -1589,7 +1689,7 @@ function createTemplateManifest(modernVersion, packageSource) {
|
|
|
1589
1689
|
'template-manifest-retained'
|
|
1590
1690
|
],
|
|
1591
1691
|
expectedCommands: [
|
|
1592
|
-
|
|
1692
|
+
'pnpm install',
|
|
1593
1693
|
'pnpm run ultramodern:check'
|
|
1594
1694
|
]
|
|
1595
1695
|
}
|
|
@@ -1605,11 +1705,11 @@ function writeApp(targetDir, scope, app, packageSource) {
|
|
|
1605
1705
|
writeFile(targetDir, `${app.directory}/src/routes/page.tsx`, 'shell' === app.kind ? createShellPage() : createRemotePage(app));
|
|
1606
1706
|
if ('vertical' === app.kind) {
|
|
1607
1707
|
writeFile(targetDir, `${app.directory}/src/remote-entry.tsx`, createRemoteEntry(app));
|
|
1608
|
-
const widgetFile = 'remote-identity' === app.id ? '
|
|
1708
|
+
const widgetFile = 'remote-identity' === app.id ? 'identity-widget.tsx' : 'commerce-widget.tsx';
|
|
1609
1709
|
writeFile(targetDir, `${app.directory}/src/components/${widgetFile}`, createRemoteWidget(app));
|
|
1610
1710
|
}
|
|
1611
1711
|
if ('horizontal-design-system' === app.kind) {
|
|
1612
|
-
writeFile(targetDir, `${app.directory}/src/components/
|
|
1712
|
+
writeFile(targetDir, `${app.directory}/src/components/button.tsx`, createDesignButton());
|
|
1613
1713
|
writeFile(targetDir, `${app.directory}/src/tokens.ts`, createDesignTokens());
|
|
1614
1714
|
}
|
|
1615
1715
|
}
|
|
@@ -1636,27 +1736,27 @@ function writeSharedPackages(targetDir, scope) {
|
|
|
1636
1736
|
});
|
|
1637
1737
|
}
|
|
1638
1738
|
writeFile(targetDir, 'packages/shared-contracts/src/index.ts', `export const ultramodernWorkspaceContract = {
|
|
1739
|
+
ownership: 'topology/ownership.json',
|
|
1639
1740
|
preset: 'presetUltramodern',
|
|
1640
1741
|
topology: 'topology/reference-topology.json',
|
|
1641
|
-
ownership: 'topology/ownership.json',
|
|
1642
1742
|
} as const;
|
|
1643
1743
|
`);
|
|
1644
1744
|
writeFile(targetDir, 'packages/shared-design-tokens/src/index.ts', `export const sharedDesignTokens = {
|
|
1645
1745
|
color: {
|
|
1646
|
-
surface: '#f6fbf7',
|
|
1647
|
-
foreground: '#133225',
|
|
1648
1746
|
accent: '#2f8f68',
|
|
1747
|
+
foreground: '#133225',
|
|
1748
|
+
surface: '#f6fbf7',
|
|
1649
1749
|
},
|
|
1650
1750
|
} as const;
|
|
1651
1751
|
`);
|
|
1652
|
-
writeFile(targetDir, 'packages/shared-effect-api/src/index.ts', `export
|
|
1752
|
+
writeFile(targetDir, 'packages/shared-effect-api/src/index.ts', `export interface Recommendation {
|
|
1653
1753
|
id: string;
|
|
1654
1754
|
title: string;
|
|
1655
|
-
}
|
|
1755
|
+
}
|
|
1656
1756
|
|
|
1657
1757
|
export const recommendationsApiContract = {
|
|
1658
|
-
serviceId: '${effectService.id}',
|
|
1659
1758
|
basePath: '/recommendations-api/effect/recommendations',
|
|
1759
|
+
serviceId: '${effectService.id}',
|
|
1660
1760
|
} as const;
|
|
1661
1761
|
`);
|
|
1662
1762
|
}
|
|
@@ -1671,7 +1771,7 @@ function generateUltramodernWorkspace(options) {
|
|
|
1671
1771
|
packageScope: scope
|
|
1672
1772
|
});
|
|
1673
1773
|
writeJson(options.targetDir, 'package.json', createRootPackageJson(scope, packageSource));
|
|
1674
|
-
writeJson(options.targetDir, 'tsconfig.base.json', createTsConfigBase(
|
|
1774
|
+
writeJson(options.targetDir, 'tsconfig.base.json', createTsConfigBase());
|
|
1675
1775
|
writeJson(options.targetDir, 'topology/reference-topology.json', createTopology(scope));
|
|
1676
1776
|
writeJson(options.targetDir, 'topology/ownership.json', createOwnership(scope));
|
|
1677
1777
|
writeJson(options.targetDir, 'topology/local-overlays/development.json', createDevelopmentOverlay());
|
|
@@ -1866,14 +1966,17 @@ function createBuiltinTemplateManifest(version) {
|
|
|
1866
1966
|
materialization: {
|
|
1867
1967
|
targetRoot: 'generated-project-root',
|
|
1868
1968
|
allowedPaths: [
|
|
1969
|
+
'.agents/**',
|
|
1869
1970
|
'.browserslistrc',
|
|
1870
1971
|
'.gitignore',
|
|
1871
1972
|
'.modernjs/**',
|
|
1872
1973
|
'.nvmrc',
|
|
1974
|
+
'AGENTS.md',
|
|
1873
1975
|
'README.md',
|
|
1874
1976
|
'api/**',
|
|
1875
|
-
'biome.json',
|
|
1876
1977
|
'modern.config.ts',
|
|
1978
|
+
'oxfmt.config.ts',
|
|
1979
|
+
'oxlint.config.ts',
|
|
1877
1980
|
'package.json',
|
|
1878
1981
|
'postcss.config.mjs',
|
|
1879
1982
|
"scripts/**",
|
|
@@ -2017,9 +2120,19 @@ function writeTemplateManifestEvidence(targetDir, manifest) {
|
|
|
2017
2120
|
});
|
|
2018
2121
|
node_fs.writeFileSync(evidencePath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
2019
2122
|
}
|
|
2020
|
-
function
|
|
2123
|
+
function readCreatePackageJson() {
|
|
2021
2124
|
const createPackageJson = node_path.resolve(src_dirname, '..', 'package.json');
|
|
2022
|
-
|
|
2125
|
+
return JSON.parse(node_fs.readFileSync(createPackageJson, 'utf-8'));
|
|
2126
|
+
}
|
|
2127
|
+
function isBleedingDevCreatePackage(createPackage) {
|
|
2128
|
+
return '@bleedingdev/modern-js-create' === createPackage.name;
|
|
2129
|
+
}
|
|
2130
|
+
function getBleedingDevFrameworkVersion(createPackage, fallbackVersion) {
|
|
2131
|
+
const frameworkVersion = createPackage.ultramodern?.frameworkVersion;
|
|
2132
|
+
return 'string' == typeof frameworkVersion && frameworkVersion.length > 0 ? frameworkVersion : fallbackVersion;
|
|
2133
|
+
}
|
|
2134
|
+
function showVersion() {
|
|
2135
|
+
const createPackage = readCreatePackageJson();
|
|
2023
2136
|
const version = createPackage.version || 'unknown';
|
|
2024
2137
|
console.log(i18n.t(localeKeys.version.message, {
|
|
2025
2138
|
version
|
|
@@ -2090,14 +2203,15 @@ function detectWorkspaceProtocolFlag() {
|
|
|
2090
2203
|
const args = process.argv.slice(2);
|
|
2091
2204
|
return args.includes('--workspace');
|
|
2092
2205
|
}
|
|
2093
|
-
function detectUltramodernWorkspaceFlag() {
|
|
2206
|
+
function detectUltramodernWorkspaceFlag(createPackage) {
|
|
2094
2207
|
const args = process.argv.slice(2);
|
|
2095
|
-
return args.includes(ULTRAMODERN_WORKSPACE_FLAG);
|
|
2208
|
+
return args.includes(ULTRAMODERN_WORKSPACE_FLAG) || isBleedingDevCreatePackage(createPackage);
|
|
2096
2209
|
}
|
|
2097
|
-
function detectUltramodernPackageSource(args,
|
|
2210
|
+
function detectUltramodernPackageSource(args, defaultPackageVersion, createPackage) {
|
|
2211
|
+
const bleedingDevDefaults = isBleedingDevCreatePackage(createPackage);
|
|
2098
2212
|
const strategy = getOptionValue(args, [
|
|
2099
2213
|
'--ultramodern-package-source'
|
|
2100
|
-
]) ?? 'workspace';
|
|
2214
|
+
]) ?? (bleedingDevDefaults ? 'install' : 'workspace');
|
|
2101
2215
|
if ('workspace' !== strategy && 'install' !== strategy) {
|
|
2102
2216
|
console.error('--ultramodern-package-source must be "workspace" or "install"');
|
|
2103
2217
|
process.exit(1);
|
|
@@ -2106,18 +2220,29 @@ function detectUltramodernPackageSource(args, modernVersion) {
|
|
|
2106
2220
|
strategy,
|
|
2107
2221
|
modernPackageVersion: getOptionValue(args, [
|
|
2108
2222
|
'--ultramodern-package-version'
|
|
2109
|
-
]) ??
|
|
2223
|
+
]) ?? defaultPackageVersion,
|
|
2110
2224
|
registry: getOptionValue(args, [
|
|
2111
2225
|
'--ultramodern-package-registry'
|
|
2112
2226
|
]),
|
|
2113
2227
|
aliasScope: getOptionValue(args, [
|
|
2114
2228
|
'--ultramodern-package-scope'
|
|
2115
|
-
]),
|
|
2229
|
+
]) ?? (bleedingDevDefaults && 'install' === strategy ? 'bleedingdev' : void 0),
|
|
2116
2230
|
aliasPackageNamePrefix: getOptionValue(args, [
|
|
2117
2231
|
'--ultramodern-package-name-prefix'
|
|
2118
2232
|
]) ?? 'modern-js-'
|
|
2119
2233
|
};
|
|
2120
2234
|
}
|
|
2235
|
+
function src_modernAliasPackageName(packageName, packageSource) {
|
|
2236
|
+
if (!packageSource.aliasScope) return packageName;
|
|
2237
|
+
const scope = packageSource.aliasScope.replace(/^@/, '');
|
|
2238
|
+
const unscopedName = packageName.split('/').at(-1);
|
|
2239
|
+
return `@${scope}/${packageSource.aliasPackageNamePrefix ?? ''}${unscopedName}`;
|
|
2240
|
+
}
|
|
2241
|
+
function singleAppModernPackageSpecifier(packageName, packageSource, useWorkspaceProtocol) {
|
|
2242
|
+
if (useWorkspaceProtocol) return 'workspace:*';
|
|
2243
|
+
if ('install' !== packageSource.strategy || !packageSource.aliasScope) return packageSource.modernPackageVersion;
|
|
2244
|
+
return `npm:${src_modernAliasPackageName(packageName, packageSource)}@${packageSource.modernPackageVersion}`;
|
|
2245
|
+
}
|
|
2121
2246
|
function isDirectoryEmpty(dirPath) {
|
|
2122
2247
|
if (!node_fs.existsSync(dirPath)) return false;
|
|
2123
2248
|
try {
|
|
@@ -2203,16 +2328,16 @@ async function main() {
|
|
|
2203
2328
|
process.exit(1);
|
|
2204
2329
|
}
|
|
2205
2330
|
}
|
|
2206
|
-
const
|
|
2207
|
-
const createPackage = JSON.parse(node_fs.readFileSync(createPackageJson, 'utf-8'));
|
|
2331
|
+
const createPackage = readCreatePackageJson();
|
|
2208
2332
|
const version = createPackage.version || 'latest';
|
|
2209
|
-
const
|
|
2333
|
+
const ultramodernPackageVersion = isBleedingDevCreatePackage(createPackage) ? getBleedingDevFrameworkVersion(createPackage, version) : version;
|
|
2334
|
+
const generateWorkspace = detectUltramodernWorkspaceFlag(createPackage);
|
|
2210
2335
|
if (generateWorkspace) {
|
|
2211
2336
|
generateUltramodernWorkspace({
|
|
2212
2337
|
targetDir,
|
|
2213
2338
|
packageName: generatedPackageName,
|
|
2214
2339
|
modernVersion: version,
|
|
2215
|
-
packageSource: detectUltramodernPackageSource(args,
|
|
2340
|
+
packageSource: detectUltramodernPackageSource(args, ultramodernPackageVersion, createPackage)
|
|
2216
2341
|
});
|
|
2217
2342
|
const dim = '\x1b[2m\x1b[3m';
|
|
2218
2343
|
const reset = '\x1b[0m';
|
|
@@ -2232,12 +2357,17 @@ async function main() {
|
|
|
2232
2357
|
const bffRuntime = detectBffRuntime();
|
|
2233
2358
|
const enableTailwind = detectTailwindFlag();
|
|
2234
2359
|
const useWorkspaceProtocol = detectWorkspaceProtocolFlag();
|
|
2235
|
-
const
|
|
2360
|
+
const packageSource = detectUltramodernPackageSource(args, ultramodernPackageVersion, createPackage);
|
|
2236
2361
|
const templateManifest = createBuiltinTemplateManifest(version);
|
|
2237
2362
|
validateTemplateManifest(templateManifest);
|
|
2238
2363
|
copyTemplate(templateDir, targetDir, {
|
|
2239
2364
|
packageName: generatedPackageName,
|
|
2240
|
-
version:
|
|
2365
|
+
version: useWorkspaceProtocol ? 'workspace:*' : packageSource.modernPackageVersion,
|
|
2366
|
+
runtimeVersion: singleAppModernPackageSpecifier('@modern-js/runtime', packageSource, useWorkspaceProtocol),
|
|
2367
|
+
appToolsVersion: singleAppModernPackageSpecifier('@modern-js/app-tools', packageSource, useWorkspaceProtocol),
|
|
2368
|
+
tsconfigVersion: singleAppModernPackageSpecifier('@modern-js/tsconfig', packageSource, useWorkspaceProtocol),
|
|
2369
|
+
pluginTanstackVersion: singleAppModernPackageSpecifier('@modern-js/plugin-tanstack', packageSource, useWorkspaceProtocol),
|
|
2370
|
+
pluginBffVersion: singleAppModernPackageSpecifier('@modern-js/plugin-bff', packageSource, useWorkspaceProtocol),
|
|
2241
2371
|
isSubproject,
|
|
2242
2372
|
routerFramework,
|
|
2243
2373
|
bffRuntime,
|
|
@@ -2252,12 +2382,19 @@ async function main() {
|
|
|
2252
2382
|
delete packageJson['simple-git-hooks'];
|
|
2253
2383
|
if (packageJson.scripts) {
|
|
2254
2384
|
delete packageJson.scripts.prepare;
|
|
2385
|
+
delete packageJson.scripts.format;
|
|
2386
|
+
delete packageJson.scripts['format:check'];
|
|
2255
2387
|
delete packageJson.scripts.lint;
|
|
2388
|
+
delete packageJson.scripts['lint:fix'];
|
|
2389
|
+
delete packageJson.scripts['skills:install'];
|
|
2390
|
+
delete packageJson.scripts['skills:check'];
|
|
2256
2391
|
}
|
|
2257
2392
|
if (packageJson.devDependencies) {
|
|
2258
2393
|
delete packageJson.devDependencies['lint-staged'];
|
|
2259
2394
|
delete packageJson.devDependencies['simple-git-hooks'];
|
|
2260
|
-
delete packageJson.devDependencies
|
|
2395
|
+
delete packageJson.devDependencies.oxlint;
|
|
2396
|
+
delete packageJson.devDependencies.oxfmt;
|
|
2397
|
+
delete packageJson.devDependencies.ultracite;
|
|
2261
2398
|
}
|
|
2262
2399
|
}
|
|
2263
2400
|
node_fs.writeFileSync(targetPackageJson, `${JSON.stringify(packageJson, null, 2)}\n`);
|
|
@@ -2277,10 +2414,13 @@ function copyTemplate(src, dest, options) {
|
|
|
2277
2414
|
recursive: true
|
|
2278
2415
|
});
|
|
2279
2416
|
const excludeInSubproject = [
|
|
2417
|
+
'.agents',
|
|
2280
2418
|
'.gitignore.handlebars',
|
|
2281
|
-
'
|
|
2419
|
+
'AGENTS.md',
|
|
2282
2420
|
'.npmrc',
|
|
2283
|
-
'.nvmrc'
|
|
2421
|
+
'.nvmrc',
|
|
2422
|
+
'oxfmt.config.ts',
|
|
2423
|
+
'oxlint.config.ts'
|
|
2284
2424
|
];
|
|
2285
2425
|
function copyRecursive(srcDir, destDir) {
|
|
2286
2426
|
const entries = node_fs.readdirSync(srcDir, {
|
|
@@ -2302,6 +2442,11 @@ function copyTemplate(src, dest, options) {
|
|
|
2302
2442
|
const rendered = src_renderTemplate(templateContent, {
|
|
2303
2443
|
packageName: options.packageName,
|
|
2304
2444
|
version: options.version,
|
|
2445
|
+
runtimeVersion: options.runtimeVersion,
|
|
2446
|
+
appToolsVersion: options.appToolsVersion,
|
|
2447
|
+
tsconfigVersion: options.tsconfigVersion,
|
|
2448
|
+
pluginTanstackVersion: options.pluginTanstackVersion,
|
|
2449
|
+
pluginBffVersion: options.pluginBffVersion,
|
|
2305
2450
|
isSubproject: options.isSubproject,
|
|
2306
2451
|
isTanstackRouter: 'tanstack' === options.routerFramework,
|
|
2307
2452
|
enableBff: 'none' !== options.bffRuntime,
|