@bleedingdev/modern-js-create 3.5.0-ultramodern.1 → 3.5.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 +10 -6
- package/dist/cjs/ultramodern-tooling/commands.cjs +271 -3
- package/dist/cjs/ultramodern-workspace/app-files.cjs +8 -11
- package/dist/cjs/ultramodern-workspace/package-json.cjs +15 -7
- package/dist/cjs/ultramodern-workspace/versions.cjs +9 -4
- package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +1 -0
- package/dist/cjs/ultramodern-workspace/write-workspace.cjs +1 -0
- package/dist/esm/ultramodern-tooling/commands.js +271 -3
- package/dist/esm/ultramodern-workspace/app-files.js +8 -11
- package/dist/esm/ultramodern-workspace/package-json.js +5 -7
- package/dist/esm/ultramodern-workspace/versions.js +7 -5
- package/dist/esm/ultramodern-workspace/workspace-scripts.js +2 -1
- package/dist/esm/ultramodern-workspace/write-workspace.js +2 -1
- package/dist/esm-node/ultramodern-tooling/commands.js +271 -3
- package/dist/esm-node/ultramodern-workspace/app-files.js +8 -11
- package/dist/esm-node/ultramodern-workspace/package-json.js +5 -7
- package/dist/esm-node/ultramodern-workspace/versions.js +7 -5
- package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +2 -1
- package/dist/esm-node/ultramodern-workspace/write-workspace.js +2 -1
- package/dist/types/ultramodern-workspace/versions.d.ts +6 -4
- package/package.json +6 -6
- package/template-workspace/.gitignore.handlebars +2 -0
- package/template-workspace/README.md.handlebars +8 -4
- package/template-workspace/patches/drizzle-orm-ts7-strict-declarations.patch +452 -0
- package/template-workspace/patches/effect-schema-error-type-id.patch +18 -0
- package/template-workspace/pnpm-workspace.yaml.handlebars +7 -0
- package/templates/workspace-scripts/validate-ultramodern-workspace.mjs.handlebars +58 -2
|
@@ -5,7 +5,10 @@ import node_path from "node:path";
|
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { resolveCreatePackageRoot } from "../create-package-root.js";
|
|
7
7
|
import { BLEEDINGDEV_PACKAGE_NAME_PREFIX, BLEEDINGDEV_PACKAGE_SCOPE, ULTRAMODERN_SINGLE_APP_MODERN_PACKAGES, ULTRAMODERN_WORKSPACE_MODERN_PACKAGES, WORKSPACE_PACKAGE_VERSION, modernPackageSpecifier } from "../ultramodern-package-source.js";
|
|
8
|
+
import { createAppEnvDts } from "../ultramodern-workspace/app-files.js";
|
|
8
9
|
import { validateModuleFederationTypes } from "../ultramodern-workspace/mf-validation.js";
|
|
10
|
+
import { createAppMfTypesTsConfig, createAppTsConfig, createSharedPackageTsConfig, createTsConfigBase } from "../ultramodern-workspace/package-json.js";
|
|
11
|
+
import { DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, OXFMT_VERSION, OXLINT_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION } from "../ultramodern-workspace/versions.js";
|
|
9
12
|
import { createWorkspaceValidationScript } from "../ultramodern-workspace/workspace-scripts.js";
|
|
10
13
|
import { readUltramodernConfig, workspaceAppsFromToolingConfig } from "./config.js";
|
|
11
14
|
const commands_dirname = node_path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -151,6 +154,82 @@ function updateModernDependencies(packageJson, packageSource) {
|
|
|
151
154
|
}
|
|
152
155
|
return changed;
|
|
153
156
|
}
|
|
157
|
+
const generatedToolingDependencyPins = new Map([
|
|
158
|
+
[
|
|
159
|
+
'@effect/tsgo',
|
|
160
|
+
EFFECT_TSGO_VERSION
|
|
161
|
+
],
|
|
162
|
+
[
|
|
163
|
+
"@typescript/native-preview",
|
|
164
|
+
TYPESCRIPT_NATIVE_PREVIEW_VERSION
|
|
165
|
+
],
|
|
166
|
+
[
|
|
167
|
+
'oxfmt',
|
|
168
|
+
OXFMT_VERSION
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
'oxlint',
|
|
172
|
+
OXLINT_VERSION
|
|
173
|
+
],
|
|
174
|
+
[
|
|
175
|
+
'wrangler',
|
|
176
|
+
WRANGLER_VERSION
|
|
177
|
+
],
|
|
178
|
+
[
|
|
179
|
+
'zephyr-agent',
|
|
180
|
+
ZEPHYR_AGENT_VERSION
|
|
181
|
+
],
|
|
182
|
+
[
|
|
183
|
+
'zephyr-rspack-plugin',
|
|
184
|
+
ZEPHYR_RSPACK_PLUGIN_VERSION
|
|
185
|
+
]
|
|
186
|
+
]);
|
|
187
|
+
const strictEffectPackageVersionPolicyExclusions = [
|
|
188
|
+
`effect@${EFFECT_VERSION}`,
|
|
189
|
+
`@effect/opentelemetry@${EFFECT_VERSION}`
|
|
190
|
+
];
|
|
191
|
+
const effectDeclarationPatchPath = 'patches/effect-schema-error-type-id.patch';
|
|
192
|
+
const effectDeclarationPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', effectDeclarationPatchPath);
|
|
193
|
+
const drizzleOrmDeclarationPatchPath = 'patches/drizzle-orm-ts7-strict-declarations.patch';
|
|
194
|
+
const drizzleOrmDeclarationPatchSourcePath = node_path.join(createPackageRoot, 'template-workspace', drizzleOrmDeclarationPatchPath);
|
|
195
|
+
function updateGeneratedToolingDependencies(packageJson) {
|
|
196
|
+
let changed = false;
|
|
197
|
+
for (const section of [
|
|
198
|
+
'dependencies',
|
|
199
|
+
'devDependencies',
|
|
200
|
+
'peerDependencies',
|
|
201
|
+
'optionalDependencies'
|
|
202
|
+
]){
|
|
203
|
+
const dependencies = packageJson[section];
|
|
204
|
+
if (!(!dependencies || 'object' != typeof dependencies || Array.isArray(dependencies))) {
|
|
205
|
+
for (const [packageName, version] of generatedToolingDependencyPins)if (Object.prototype.hasOwnProperty.call(dependencies, packageName) && dependencies[packageName] !== version) {
|
|
206
|
+
dependencies[packageName] = version;
|
|
207
|
+
changed = true;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return changed;
|
|
212
|
+
}
|
|
213
|
+
const cloudflareModernDeployCommand = 'ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy';
|
|
214
|
+
const cloudflareModernDeploySkipBuildCommand = `${cloudflareModernDeployCommand} --skip-build`;
|
|
215
|
+
const cloudflareWranglerDeployCommand = 'wrangler deploy --config .output/wrangler.json';
|
|
216
|
+
const cloudflareWranglerDeployInvalidSkipBuildCommand = `${cloudflareWranglerDeployCommand} --skip-build`;
|
|
217
|
+
function updateGeneratedPackageScripts(packageJson) {
|
|
218
|
+
const scripts = packageJson.scripts;
|
|
219
|
+
if (!scripts || 'object' != typeof scripts || Array.isArray(scripts)) return false;
|
|
220
|
+
let changed = false;
|
|
221
|
+
const cloudflareBuild = scripts['cloudflare:build'];
|
|
222
|
+
if ('string' == typeof cloudflareBuild && cloudflareBuild.includes(cloudflareModernDeployCommand) && !cloudflareBuild.includes(cloudflareModernDeploySkipBuildCommand)) {
|
|
223
|
+
scripts['cloudflare:build'] = cloudflareBuild.replace(cloudflareModernDeployCommand, cloudflareModernDeploySkipBuildCommand);
|
|
224
|
+
changed = true;
|
|
225
|
+
}
|
|
226
|
+
const cloudflareDeploy = scripts['cloudflare:deploy'];
|
|
227
|
+
if ('string' == typeof cloudflareDeploy && cloudflareDeploy.includes(cloudflareWranglerDeployInvalidSkipBuildCommand)) {
|
|
228
|
+
scripts['cloudflare:deploy'] = cloudflareDeploy.replace(cloudflareWranglerDeployInvalidSkipBuildCommand, cloudflareWranglerDeployCommand);
|
|
229
|
+
changed = true;
|
|
230
|
+
}
|
|
231
|
+
return changed;
|
|
232
|
+
}
|
|
154
233
|
function normalizeStrictEffectApiMetadata(value) {
|
|
155
234
|
const api = value.api;
|
|
156
235
|
if (!api || 'object' != typeof api || Array.isArray(api)) return false;
|
|
@@ -216,6 +295,135 @@ function normalizeStrictEffectApiMetadata(value) {
|
|
|
216
295
|
}
|
|
217
296
|
return changed;
|
|
218
297
|
}
|
|
298
|
+
function replaceYamlLine(source, pattern, replacement) {
|
|
299
|
+
const updated = source.replace(pattern, replacement);
|
|
300
|
+
return {
|
|
301
|
+
source: updated,
|
|
302
|
+
changed: updated !== source
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
function ensureYamlListItem(source, key, item) {
|
|
306
|
+
const itemLine = ` - '${item}'`;
|
|
307
|
+
const headerPattern = new RegExp(`^${key}:\\n(?:(?: - .+\\n)*)`, 'mu');
|
|
308
|
+
const header = source.match(headerPattern);
|
|
309
|
+
if (header) {
|
|
310
|
+
if (header[0].split('\n').includes(itemLine)) return {
|
|
311
|
+
source,
|
|
312
|
+
changed: false
|
|
313
|
+
};
|
|
314
|
+
return {
|
|
315
|
+
source: source.replace(headerPattern, `${header[0]}${itemLine}\n`),
|
|
316
|
+
changed: true
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
const block = `${key}:\n${itemLine}\n`;
|
|
320
|
+
const afterTrustPolicyIgnore = source.replace(/^(trustPolicyIgnoreAfter: .+\n)/mu, `$1${block}`);
|
|
321
|
+
if (afterTrustPolicyIgnore !== source) return {
|
|
322
|
+
source: afterTrustPolicyIgnore,
|
|
323
|
+
changed: true
|
|
324
|
+
};
|
|
325
|
+
return {
|
|
326
|
+
source: `${source.trimEnd()}\n${block}`,
|
|
327
|
+
changed: true
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
function ensureYamlMapEntry(source, key, entryKey, value) {
|
|
331
|
+
const entryLine = ` '${entryKey}': ${value}`;
|
|
332
|
+
const packageName = entryKey.includes('@') ? entryKey.slice(0, entryKey.lastIndexOf('@')) : entryKey;
|
|
333
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
334
|
+
const currentEntryPattern = new RegExp(`^ {2}'${escapedPackageName}@[^']+': .+$`, 'mu');
|
|
335
|
+
const currentEntry = source.match(currentEntryPattern);
|
|
336
|
+
if (currentEntry) {
|
|
337
|
+
if (currentEntry[0] === entryLine) return {
|
|
338
|
+
source,
|
|
339
|
+
changed: false
|
|
340
|
+
};
|
|
341
|
+
return {
|
|
342
|
+
source: source.replace(currentEntryPattern, entryLine),
|
|
343
|
+
changed: true
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
const headerPattern = new RegExp(`^${key}:\\n(?:(?: .+\\n)*)`, 'mu');
|
|
347
|
+
const header = source.match(headerPattern);
|
|
348
|
+
if (header) {
|
|
349
|
+
if (header[0].split('\n').includes(entryLine)) return {
|
|
350
|
+
source,
|
|
351
|
+
changed: false
|
|
352
|
+
};
|
|
353
|
+
return {
|
|
354
|
+
source: source.replace(headerPattern, `${header[0]}${entryLine}\n`),
|
|
355
|
+
changed: true
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
source: `${source.trimEnd()}\n${key}:\n${entryLine}\n`,
|
|
360
|
+
changed: true
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
function ensureGeneratedPatchFile(workspaceRoot, relativePatchPath, sourcePatchPath) {
|
|
364
|
+
const targetPath = node_path.join(workspaceRoot, relativePatchPath);
|
|
365
|
+
const patch = node_fs.readFileSync(sourcePatchPath, 'utf-8');
|
|
366
|
+
if (node_fs.existsSync(targetPath) && node_fs.readFileSync(targetPath, 'utf-8') === patch) return false;
|
|
367
|
+
node_fs.mkdirSync(node_path.dirname(targetPath), {
|
|
368
|
+
recursive: true
|
|
369
|
+
});
|
|
370
|
+
node_fs.writeFileSync(targetPath, patch, 'utf-8');
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
function ensureGeneratedDeclarationPatches(workspaceRoot) {
|
|
374
|
+
let changed = false;
|
|
375
|
+
changed = ensureGeneratedPatchFile(workspaceRoot, effectDeclarationPatchPath, effectDeclarationPatchSourcePath) || changed;
|
|
376
|
+
changed = ensureGeneratedPatchFile(workspaceRoot, drizzleOrmDeclarationPatchPath, drizzleOrmDeclarationPatchSourcePath) || changed;
|
|
377
|
+
return changed;
|
|
378
|
+
}
|
|
379
|
+
function updateGeneratedPnpmWorkspacePolicy(workspaceRoot) {
|
|
380
|
+
const workspaceFile = node_path.join(workspaceRoot, 'pnpm-workspace.yaml');
|
|
381
|
+
if (!node_fs.existsSync(workspaceFile)) return false;
|
|
382
|
+
let source = node_fs.readFileSync(workspaceFile, 'utf-8');
|
|
383
|
+
let changed = false;
|
|
384
|
+
const replacements = [
|
|
385
|
+
[
|
|
386
|
+
/^ {4}'@effect\/vitest>effect': .+$/mu,
|
|
387
|
+
` '@effect/vitest>effect': '${EFFECT_VERSION}'`
|
|
388
|
+
],
|
|
389
|
+
[
|
|
390
|
+
/^ {2}'@effect\/vitest': .+$/mu,
|
|
391
|
+
` '@effect/vitest': ${EFFECT_VITEST_VERSION}`
|
|
392
|
+
],
|
|
393
|
+
[
|
|
394
|
+
/^ {2}effect: .+$/mu,
|
|
395
|
+
` effect: ${EFFECT_VERSION}`
|
|
396
|
+
]
|
|
397
|
+
];
|
|
398
|
+
for (const [pattern, replacement] of replacements){
|
|
399
|
+
const result = replaceYamlLine(source, pattern, replacement);
|
|
400
|
+
source = result.source;
|
|
401
|
+
changed = result.changed || changed;
|
|
402
|
+
}
|
|
403
|
+
for (const item of strictEffectPackageVersionPolicyExclusions){
|
|
404
|
+
const packageName = item.slice(0, item.lastIndexOf('@'));
|
|
405
|
+
const escapedPackageName = packageName.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
406
|
+
const currentVersion = replaceYamlLine(source, new RegExp(`^ {2}- '${escapedPackageName}@[^']+'$`, 'gmu'), ` - '${item}'`);
|
|
407
|
+
source = currentVersion.source;
|
|
408
|
+
changed = currentVersion.changed || changed;
|
|
409
|
+
for (const policyKey of [
|
|
410
|
+
'minimumReleaseAgeExclude',
|
|
411
|
+
'trustPolicyExclude'
|
|
412
|
+
]){
|
|
413
|
+
const policyExclude = ensureYamlListItem(source, policyKey, item);
|
|
414
|
+
source = policyExclude.source;
|
|
415
|
+
changed = policyExclude.changed || changed;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
const effectPatch = ensureYamlMapEntry(source, 'patchedDependencies', `effect@${EFFECT_VERSION}`, effectDeclarationPatchPath);
|
|
419
|
+
source = effectPatch.source;
|
|
420
|
+
changed = effectPatch.changed || changed;
|
|
421
|
+
const drizzleOrmPatch = ensureYamlMapEntry(source, 'patchedDependencies', `drizzle-orm@${DRIZZLE_ORM_VERSION}`, drizzleOrmDeclarationPatchPath);
|
|
422
|
+
source = drizzleOrmPatch.source;
|
|
423
|
+
changed = drizzleOrmPatch.changed || changed;
|
|
424
|
+
if (changed) node_fs.writeFileSync(workspaceFile, source, 'utf-8');
|
|
425
|
+
return changed;
|
|
426
|
+
}
|
|
219
427
|
function updateUltramodernConfig(workspaceRoot, packageSource) {
|
|
220
428
|
const configPath = node_path.join(workspaceRoot, '.modernjs/ultramodern.json');
|
|
221
429
|
const config = readJsonFile(configPath);
|
|
@@ -235,6 +443,57 @@ function updateUltramodernConfig(workspaceRoot, packageSource) {
|
|
|
235
443
|
for (const app of config.topology?.apps ?? [])if (app && 'object' == typeof app && !Array.isArray(app)) normalizeStrictEffectApiMetadata(app);
|
|
236
444
|
writeJsonFile(configPath, config);
|
|
237
445
|
}
|
|
446
|
+
function writeJsonIfChanged(filePath, value) {
|
|
447
|
+
const next = `${JSON.stringify(value, null, 2)}\n`;
|
|
448
|
+
if (node_fs.existsSync(filePath) && node_fs.readFileSync(filePath, 'utf-8') === next) return false;
|
|
449
|
+
node_fs.mkdirSync(node_path.dirname(filePath), {
|
|
450
|
+
recursive: true
|
|
451
|
+
});
|
|
452
|
+
node_fs.writeFileSync(filePath, next, 'utf-8');
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
function writeTextIfChanged(filePath, value) {
|
|
456
|
+
if (node_fs.existsSync(filePath) && node_fs.readFileSync(filePath, 'utf-8') === value) return false;
|
|
457
|
+
node_fs.mkdirSync(node_path.dirname(filePath), {
|
|
458
|
+
recursive: true
|
|
459
|
+
});
|
|
460
|
+
node_fs.writeFileSync(filePath, value, 'utf-8');
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
function ensureGeneratedIgnoreRules(workspaceRoot) {
|
|
464
|
+
const gitignorePath = node_path.join(workspaceRoot, '.gitignore');
|
|
465
|
+
const existing = node_fs.existsSync(gitignorePath) ? node_fs.readFileSync(gitignorePath, 'utf-8') : '';
|
|
466
|
+
const lines = 0 === existing.trimEnd().length ? [] : existing.trimEnd().split(/\r?\n/u);
|
|
467
|
+
let changed = false;
|
|
468
|
+
for (const rule of [
|
|
469
|
+
'.mf/',
|
|
470
|
+
'**/.mf/'
|
|
471
|
+
])if (!lines.includes(rule)) {
|
|
472
|
+
lines.push(rule);
|
|
473
|
+
changed = true;
|
|
474
|
+
}
|
|
475
|
+
if (!changed) return false;
|
|
476
|
+
const next = `${lines.join('\n')}\n`;
|
|
477
|
+
node_fs.writeFileSync(gitignorePath, next, 'utf-8');
|
|
478
|
+
return true;
|
|
479
|
+
}
|
|
480
|
+
function updateGeneratedTypeScriptSurfaces(workspaceRoot, config) {
|
|
481
|
+
let changed = false;
|
|
482
|
+
const apps = workspaceAppsFromToolingConfig(config);
|
|
483
|
+
const remotes = apps.filter((app)=>'shell' !== app.kind);
|
|
484
|
+
changed = writeJsonIfChanged(node_path.join(workspaceRoot, 'tsconfig.base.json'), createTsConfigBase()) || changed;
|
|
485
|
+
changed = ensureGeneratedIgnoreRules(workspaceRoot) || changed;
|
|
486
|
+
for (const sharedPackage of [
|
|
487
|
+
'packages/shared-contracts',
|
|
488
|
+
'packages/shared-design-tokens'
|
|
489
|
+
])changed = writeJsonIfChanged(node_path.join(workspaceRoot, sharedPackage, 'tsconfig.json'), createSharedPackageTsConfig(sharedPackage)) || changed;
|
|
490
|
+
for (const app of apps){
|
|
491
|
+
changed = writeJsonIfChanged(node_path.join(workspaceRoot, app.directory, 'tsconfig.json'), createAppTsConfig(app, remotes)) || changed;
|
|
492
|
+
changed = writeJsonIfChanged(node_path.join(workspaceRoot, app.directory, 'tsconfig.mf-types.json'), createAppMfTypesTsConfig(app)) || changed;
|
|
493
|
+
changed = writeTextIfChanged(node_path.join(workspaceRoot, app.directory, 'src/modern-app-env.d.ts'), createAppEnvDts(app, remotes)) || changed;
|
|
494
|
+
}
|
|
495
|
+
return changed;
|
|
496
|
+
}
|
|
238
497
|
function updateReferenceTopology(workspaceRoot) {
|
|
239
498
|
const topologyPath = node_path.join(workspaceRoot, 'topology/reference-topology.json');
|
|
240
499
|
if (!node_fs.existsSync(topologyPath)) return false;
|
|
@@ -297,8 +556,10 @@ function runMigrateStrictEffect(args, context) {
|
|
|
297
556
|
modern-js-create ultramodern migrate-strict-effect --version <version> [--skip-install]
|
|
298
557
|
|
|
299
558
|
Updates generated UltraModern package-source metadata, Modern package aliases,
|
|
300
|
-
direct Effect API topology metadata,
|
|
301
|
-
|
|
559
|
+
framework-owned toolchain pins, direct Effect API topology metadata, strict
|
|
560
|
+
Effect pnpm overrides/trust policy, framework-owned TypeScript config
|
|
561
|
+
surfaces, and the pnpm lockfile. Source code still has to pass pnpm api:check
|
|
562
|
+
and pnpm contract:check.
|
|
302
563
|
`);
|
|
303
564
|
return 0;
|
|
304
565
|
}
|
|
@@ -306,6 +567,7 @@ workspaces. Source code still has to pass pnpm api:check and pnpm contract:check
|
|
|
306
567
|
const packageSource = createMigrationPackageSource(args, current);
|
|
307
568
|
updateUltramodernConfig(context.workspaceRoot, packageSource);
|
|
308
569
|
updateReferenceTopology(context.workspaceRoot);
|
|
570
|
+
updateGeneratedTypeScriptSurfaces(context.workspaceRoot, current);
|
|
309
571
|
for (const relativePackageFile of listWorkspacePackageFiles(context.workspaceRoot)){
|
|
310
572
|
const packageFile = node_path.join(context.workspaceRoot, relativePackageFile);
|
|
311
573
|
const packageJson = readJsonFile(packageFile);
|
|
@@ -316,9 +578,15 @@ workspaces. Source code still has to pass pnpm api:check and pnpm contract:check
|
|
|
316
578
|
config: './.modernjs/ultramodern.json'
|
|
317
579
|
};
|
|
318
580
|
}
|
|
319
|
-
|
|
581
|
+
const modernDependenciesChanged = updateModernDependencies(packageJson, packageSource);
|
|
582
|
+
const toolingDependenciesChanged = updateGeneratedToolingDependencies(packageJson);
|
|
583
|
+
const generatedScriptsChanged = updateGeneratedPackageScripts(packageJson);
|
|
584
|
+
const changed = modernDependenciesChanged || toolingDependenciesChanged || generatedScriptsChanged;
|
|
585
|
+
if (changed) writeJsonFile(packageFile, packageJson);
|
|
320
586
|
else if ('package.json' === relativePackageFile) writeJsonFile(packageFile, packageJson);
|
|
321
587
|
}
|
|
588
|
+
updateGeneratedPnpmWorkspacePolicy(context.workspaceRoot);
|
|
589
|
+
ensureGeneratedDeclarationPatches(context.workspaceRoot);
|
|
322
590
|
if (!hasFlag(args, '--skip-install')) {
|
|
323
591
|
const status = runPnpmLockfileRefresh(context);
|
|
324
592
|
if (0 !== status) return status;
|
|
@@ -27,17 +27,14 @@ function createAppEnvDts(app, remotes = []) {
|
|
|
27
27
|
}
|
|
28
28
|
`;
|
|
29
29
|
})).join('\n');
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
declare module '*.css';
|
|
40
|
-
${remoteModuleDeclarations ? `\n${remoteModuleDeclarations}` : ''}`;
|
|
30
|
+
const reactTypeImport = remoteModuleDeclarations ? "import type React from 'react';\n" : '';
|
|
31
|
+
return [
|
|
32
|
+
`import '@modern-js/app-tools/types';\n${reactTypeImport}`.trimEnd(),
|
|
33
|
+
`declare global {
|
|
34
|
+
const ULTRAMODERN_SITE_URL: string;
|
|
35
|
+
}`,
|
|
36
|
+
remoteModuleDeclarations.trimEnd()
|
|
37
|
+
].filter((section)=>section.length > 0).join('\n\n').concat('\n');
|
|
41
38
|
}
|
|
42
39
|
function createAppRuntimeConfig(app, scope, remotes = []) {
|
|
43
40
|
const pluginsConfig = 'shell' === app.kind ? ` plugins: [
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import node_path from "node:path";
|
|
1
2
|
import { WORKSPACE_PACKAGE_VERSION, modernPackageSpecifier } from "../ultramodern-package-source.js";
|
|
2
3
|
import { appHasApi, remoteDependencyAlias, resolveRemoteRefs, sharedPackages, shellApp, verticalApiApps, zephyrRemoteDependency } from "./descriptors.js";
|
|
3
4
|
import { readFileTemplate } from "./fs-io.js";
|
|
@@ -248,7 +249,6 @@ function createTsConfigBase() {
|
|
|
248
249
|
noFallthroughCasesInSwitch: true,
|
|
249
250
|
noPropertyAccessFromIndexSignature: true,
|
|
250
251
|
noImplicitReturns: true,
|
|
251
|
-
skipLibCheck: true,
|
|
252
252
|
resolveJsonModule: true,
|
|
253
253
|
plugins: [
|
|
254
254
|
{
|
|
@@ -280,7 +280,7 @@ function createReferences(packageDir, references) {
|
|
|
280
280
|
return [
|
|
281
281
|
...new Set(references)
|
|
282
282
|
].filter((reference)=>reference !== packageDir).map((reference)=>({
|
|
283
|
-
path:
|
|
283
|
+
path: node_path.relative(packageDir, reference).split(node_path.sep).join('/')
|
|
284
284
|
}));
|
|
285
285
|
}
|
|
286
286
|
function createPackageTsConfig(packageDir, options = {}) {
|
|
@@ -290,8 +290,6 @@ function createPackageTsConfig(packageDir, options = {}) {
|
|
|
290
290
|
const include = resolvedOptions.include ?? [
|
|
291
291
|
'src',
|
|
292
292
|
'locales/**/*.json',
|
|
293
|
-
'modern.config.ts',
|
|
294
|
-
'module-federation.config.ts',
|
|
295
293
|
'package.json',
|
|
296
294
|
'shared'
|
|
297
295
|
];
|
|
@@ -325,9 +323,9 @@ function createAppTsConfig(app, remotes = []) {
|
|
|
325
323
|
});
|
|
326
324
|
}
|
|
327
325
|
function createAppMfTypesTsConfig(app) {
|
|
328
|
-
const exposedFiles = Object.
|
|
326
|
+
const exposedFiles = Object.entries(app.exposes ?? {}).sort(([left], [right])=>'./Route' === left ? -1 : './Route' === right ? 1 : 0).map(([, exposePath])=>exposePath.replace(/^\.\//u, ''));
|
|
329
327
|
return {
|
|
330
|
-
extends:
|
|
328
|
+
extends: `${relativeRootFor(app.directory)}/tsconfig.base.json`,
|
|
331
329
|
include: [
|
|
332
330
|
...new Set([
|
|
333
331
|
...exposedFiles,
|
|
@@ -371,7 +369,7 @@ function createAppPackage(scope, app, packageSource, enableTailwind, remotes = [
|
|
|
371
369
|
scripts: {
|
|
372
370
|
dev: 'modern dev',
|
|
373
371
|
build: app.exposes ? `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand} && node ${relativeRootFor(app.directory)}/scripts/assert-mf-types.mts` : `ULTRAMODERN_ZEPHYR=false modern build && ${publicSurfaceBuildCommand}`,
|
|
374
|
-
'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ${publicSurfaceCloudflareBuildCommand} && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy && ${publicSurfaceCloudflareOutputCommand}`,
|
|
372
|
+
'cloudflare:build': `ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern build && ${publicSurfaceCloudflareBuildCommand} && ULTRAMODERN_ZEPHYR=false MODERNJS_DEPLOY=cloudflare modern deploy --skip-build && ${publicSurfaceCloudflareOutputCommand}`,
|
|
375
373
|
'cloudflare:deploy': 'ULTRAMODERN_CLOUDFLARE_REQUIRE_PUBLIC_URLS=true pnpm run cloudflare:build && wrangler deploy --config .output/wrangler.json',
|
|
376
374
|
'cloudflare:preview': 'pnpm run cloudflare:build && wrangler dev --config .output/wrangler.json',
|
|
377
375
|
'cloudflare:proof': `node ${relativeRootFor(app.directory)}/scripts/proof-cloudflare-version.mts --app ${app.id}`,
|
|
@@ -8,14 +8,15 @@ const CLOUDFLARE_COMPATIBILITY_DATE = '2026-06-02';
|
|
|
8
8
|
const TAILWIND_VERSION = '4.3.1';
|
|
9
9
|
const TAILWIND_POSTCSS_VERSION = '4.3.1';
|
|
10
10
|
const POSTCSS_VERSION = '8.5.15';
|
|
11
|
-
const EFFECT_VERSION = '4.0.0-beta.
|
|
12
|
-
const EFFECT_VITEST_VERSION = '4.0.0-beta.
|
|
11
|
+
const EFFECT_VERSION = '4.0.0-beta.91';
|
|
12
|
+
const EFFECT_VITEST_VERSION = '4.0.0-beta.91';
|
|
13
13
|
const EFFECT_TSGO_VERSION = '0.14.6';
|
|
14
|
+
const DRIZZLE_ORM_VERSION = '1.0.0-rc.4';
|
|
14
15
|
const TYPESCRIPT_STABLE_VERSION = '6.0.3';
|
|
15
|
-
const TYPESCRIPT_NATIVE_PREVIEW_VERSION = '7.0.0-dev.
|
|
16
|
+
const TYPESCRIPT_NATIVE_PREVIEW_VERSION = '7.0.0-dev.20260628.1';
|
|
16
17
|
const TYPESCRIPT_VERSION = TYPESCRIPT_STABLE_VERSION;
|
|
17
18
|
const OXLINT_VERSION = '1.71.0';
|
|
18
|
-
const OXFMT_VERSION = '0.
|
|
19
|
+
const OXFMT_VERSION = '0.56.0';
|
|
19
20
|
const ULTRACITE_VERSION = '7.8.3';
|
|
20
21
|
const LEFTHOOK_VERSION = '^2.1.9';
|
|
21
22
|
const I18NEXT_VERSION = '26.3.1';
|
|
@@ -35,7 +36,8 @@ const ultramodernWorkspaceVersions = {
|
|
|
35
36
|
moduleFederation: MODULE_FEDERATION_VERSION,
|
|
36
37
|
effect: EFFECT_VERSION,
|
|
37
38
|
effectVitest: EFFECT_VITEST_VERSION,
|
|
39
|
+
drizzleOrm: DRIZZLE_ORM_VERSION,
|
|
38
40
|
tailwind: TAILWIND_VERSION,
|
|
39
41
|
tailwindPostcss: TAILWIND_POSTCSS_VERSION
|
|
40
42
|
};
|
|
41
|
-
export { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, I18NEXT_VERSION, LEFTHOOK_VERSION, MODULE_FEDERATION_AGENT_SKILLS_COMMIT, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, OXFMT_VERSION, OXLINT_VERSION, PNPM_VERSION, POSTCSS_VERSION, REACT_DOM_VERSION, REACT_ROUTER_VERSION, REACT_VERSION, RSTACK_AGENT_SKILLS_COMMIT, TAILWIND_POSTCSS_VERSION, TAILWIND_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, TYPESCRIPT_STABLE_VERSION, TYPESCRIPT_VERSION, TYPES_REACT_DOM_VERSION, TYPES_REACT_VERSION, ULTRACITE_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION, ultramodernWorkspaceVersions };
|
|
43
|
+
export { CLOUDFLARE_COMPATIBILITY_DATE, DRIZZLE_ORM_VERSION, EFFECT_TSGO_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, I18NEXT_VERSION, LEFTHOOK_VERSION, MODULE_FEDERATION_AGENT_SKILLS_COMMIT, MODULE_FEDERATION_VERSION, NODE_FETCH_VERSION, NODE_VERSION, OXFMT_VERSION, OXLINT_VERSION, PNPM_VERSION, POSTCSS_VERSION, REACT_DOM_VERSION, REACT_ROUTER_VERSION, REACT_VERSION, RSTACK_AGENT_SKILLS_COMMIT, TAILWIND_POSTCSS_VERSION, TAILWIND_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_NATIVE_PREVIEW_VERSION, TYPESCRIPT_STABLE_VERSION, TYPESCRIPT_VERSION, TYPES_REACT_DOM_VERSION, TYPES_REACT_VERSION, ULTRACITE_VERSION, WRANGLER_VERSION, ZEPHYR_AGENT_VERSION, ZEPHYR_RSPACK_PLUGIN_VERSION, ultramodernWorkspaceVersions };
|
|
@@ -8,7 +8,7 @@ import { packageName, tailwindPrefixForApp } from "./naming.js";
|
|
|
8
8
|
import { createCloudflareSecurityContract } from "./policy.js";
|
|
9
9
|
import { publicSurfaceManagedSourceAssetPaths } from "./public-surface.js";
|
|
10
10
|
import { createLocalisedUrlsMap, createRouteMetaFilePath, createRouteOwnedI18nPaths, createRoutePageFilePath } from "./routes.js";
|
|
11
|
-
import { CLOUDFLARE_COMPATIBILITY_DATE, NODE_VERSION, PNPM_VERSION } from "./versions.js";
|
|
11
|
+
import { CLOUDFLARE_COMPATIBILITY_DATE, EFFECT_VERSION, NODE_VERSION, PNPM_VERSION } from "./versions.js";
|
|
12
12
|
function createToolWrapperScript(command, extraArgs = []) {
|
|
13
13
|
const commandJson = JSON.stringify(command);
|
|
14
14
|
const extraArgsJson = JSON.stringify(extraArgs);
|
|
@@ -127,6 +127,7 @@ function createWorkspaceValidationScript(scope, enableTailwind, remotes = []) {
|
|
|
127
127
|
const expectedCloudflareSecurity = createCloudflareSecurityContract();
|
|
128
128
|
return renderFileTemplate("workspace-scripts/validate-ultramodern-workspace.mjs", {
|
|
129
129
|
packageScope: scope,
|
|
130
|
+
effectVersion: EFFECT_VERSION,
|
|
130
131
|
nodeVersion: NODE_VERSION,
|
|
131
132
|
pnpmVersion: PNPM_VERSION,
|
|
132
133
|
tailwindEnabledJson: JSON.stringify(enableTailwind),
|
|
@@ -14,7 +14,7 @@ import { runCodeSmithOverlays } from "./overlays.js";
|
|
|
14
14
|
import { createAppMfTypesTsConfig, createAppPackage, createAppTsConfig, createRootPackageJson, createRootTsConfig, createSharedContractsIndex, createSharedPackage, createSharedPackageTsConfig, createTsConfigBase } from "./package-json.js";
|
|
15
15
|
import { resolvePackageSource } from "./package-source.js";
|
|
16
16
|
import { createPublicWebAppArtifacts } from "./public-surface.js";
|
|
17
|
-
import { EFFECT_VERSION, EFFECT_VITEST_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
|
|
17
|
+
import { DRIZZLE_ORM_VERSION, EFFECT_VERSION, EFFECT_VITEST_VERSION, NODE_FETCH_VERSION, NODE_VERSION, PNPM_VERSION, TANSTACK_ROUTER_CORE_VERSION, TANSTACK_ROUTER_VERSION, TYPESCRIPT_VERSION } from "./versions.js";
|
|
18
18
|
import { writeGeneratedWorkspaceScripts } from "./workspace-scripts.js";
|
|
19
19
|
function writeApp(targetDir, scope, app, packageSource, enableTailwind, remotes = [], bridge) {
|
|
20
20
|
const resolvedApp = 'shell' === app.kind ? createShellHost(remotes) : app;
|
|
@@ -130,6 +130,7 @@ function generateUltramodernWorkspace(options) {
|
|
|
130
130
|
nodeVersion: NODE_VERSION,
|
|
131
131
|
pnpmVersion: PNPM_VERSION,
|
|
132
132
|
nodeFetchVersion: NODE_FETCH_VERSION,
|
|
133
|
+
drizzleOrmVersion: DRIZZLE_ORM_VERSION,
|
|
133
134
|
effectVersion: EFFECT_VERSION,
|
|
134
135
|
effectVitestVersion: EFFECT_VITEST_VERSION,
|
|
135
136
|
tanstackRouterCoreVersion: TANSTACK_ROUTER_CORE_VERSION,
|