@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.
Files changed (27) hide show
  1. package/README.md +10 -6
  2. package/dist/cjs/ultramodern-tooling/commands.cjs +271 -3
  3. package/dist/cjs/ultramodern-workspace/app-files.cjs +8 -11
  4. package/dist/cjs/ultramodern-workspace/package-json.cjs +15 -7
  5. package/dist/cjs/ultramodern-workspace/versions.cjs +9 -4
  6. package/dist/cjs/ultramodern-workspace/workspace-scripts.cjs +1 -0
  7. package/dist/cjs/ultramodern-workspace/write-workspace.cjs +1 -0
  8. package/dist/esm/ultramodern-tooling/commands.js +271 -3
  9. package/dist/esm/ultramodern-workspace/app-files.js +8 -11
  10. package/dist/esm/ultramodern-workspace/package-json.js +5 -7
  11. package/dist/esm/ultramodern-workspace/versions.js +7 -5
  12. package/dist/esm/ultramodern-workspace/workspace-scripts.js +2 -1
  13. package/dist/esm/ultramodern-workspace/write-workspace.js +2 -1
  14. package/dist/esm-node/ultramodern-tooling/commands.js +271 -3
  15. package/dist/esm-node/ultramodern-workspace/app-files.js +8 -11
  16. package/dist/esm-node/ultramodern-workspace/package-json.js +5 -7
  17. package/dist/esm-node/ultramodern-workspace/versions.js +7 -5
  18. package/dist/esm-node/ultramodern-workspace/workspace-scripts.js +2 -1
  19. package/dist/esm-node/ultramodern-workspace/write-workspace.js +2 -1
  20. package/dist/types/ultramodern-workspace/versions.d.ts +6 -4
  21. package/package.json +6 -6
  22. package/template-workspace/.gitignore.handlebars +2 -0
  23. package/template-workspace/README.md.handlebars +8 -4
  24. package/template-workspace/patches/drizzle-orm-ts7-strict-declarations.patch +452 -0
  25. package/template-workspace/patches/effect-schema-error-type-id.patch +18 -0
  26. package/template-workspace/pnpm-workspace.yaml.handlebars +7 -0
  27. 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, and the pnpm lockfile for strict Effect
301
- workspaces. Source code still has to pass pnpm api:check and pnpm contract:check.
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
- if (updateModernDependencies(packageJson, packageSource)) writeJsonFile(packageFile, packageJson);
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 reactTypeReference = remoteModuleDeclarations ? "/// <reference types='react' />\n" : '';
31
- const siteUrlDeclaration = 'declare const ULTRAMODERN_SITE_URL: string;';
32
- return `${reactTypeReference}/// <reference types='@modern-js/app-tools/types' />
33
-
34
- ${siteUrlDeclaration}
35
- declare module '*.svg' {
36
- const url: string;
37
- export default url;
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: `${relativeRootFor(packageDir)}/${reference}`
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.values(app.exposes ?? {}).map((exposePath)=>exposePath.replace(/^\.\//u, ''));
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: './tsconfig.json',
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.89';
12
- const EFFECT_VITEST_VERSION = '4.0.0-beta.89';
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.20260624.1';
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.55.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,