@bleedingdev/modern-js-create 3.2.0-ultramodern.72 → 3.2.0-ultramodern.74

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 (2) hide show
  1. package/dist/index.js +45 -39
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -983,8 +983,8 @@ function createRootPackageJson(scope, packageSource, remotes = []) {
983
983
  build: `${remoteBuildPrefix}pnpm --filter "./apps/shell-super-app" run build && pnpm ultramodern:assert-mf-types`,
984
984
  format: "oxfmt . '!repos/**'",
985
985
  'format:check': "oxfmt --check . '!repos/**'",
986
- lint: 'oxlint apps/*/src verticals/*/src packages/*/src --ignore-pattern "**/modern-tanstack/**"',
987
- 'lint:fix': 'oxlint apps/*/src verticals/*/src packages/*/src --ignore-pattern "**/modern-tanstack/**" --fix',
986
+ lint: 'oxlint .',
987
+ 'lint:fix': 'oxlint . --fix',
988
988
  typecheck: `pnpm -r --filter "@${scope}/*" typecheck`,
989
989
  'cloudflare:build': `${remoteCloudflareBuildPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:build && pnpm ultramodern:assert-mf-types`,
990
990
  'cloudflare:deploy': `${remoteCloudflareDeployPrefix}pnpm --filter "./apps/shell-super-app" run cloudflare:deploy`,
@@ -1151,10 +1151,7 @@ function createPackageTsConfig(packageDir, includeApi = false) {
1151
1151
  if (includeApi) include.push('api', 'shared');
1152
1152
  return {
1153
1153
  extends: `${relativeRootFor(packageDir)}/tsconfig.base.json`,
1154
- include,
1155
- exclude: [
1156
- 'src/modern-tanstack'
1157
- ]
1154
+ include
1158
1155
  };
1159
1156
  }
1160
1157
  function createAppPackage(scope, app, packageSource, enableTailwind, remotes = []) {
@@ -4510,9 +4507,8 @@ function createWorkspaceI18nBoundaryValidationScript() {
4510
4507
  return `#!/usr/bin/env node
4511
4508
  import fs from 'node:fs';
4512
4509
  import path from 'node:path';
4513
- import { fileURLToPath } from 'node:url';
4514
4510
 
4515
- const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
4511
+ const root = path.resolve(import.meta.dirname, '..');
4516
4512
  const sourceRoots = ['apps', 'verticals'];
4517
4513
  const languageConditionalPattern =
4518
4514
  /\\b(language|locale|lng|currentLanguage)\\s*={0,2}={1,2}\\s*['"][a-z-]+['"]\\s*\\?\\s*([^:;\\n]+)\\s*:\\s*([^;\\n})]+)/gu;
@@ -4532,11 +4528,11 @@ const visibleCopyAttributes = new Set([
4532
4528
  'title',
4533
4529
  ]);
4534
4530
 
4535
- function fail(message) {
4531
+ const fail = (message) => {
4536
4532
  throw new Error(message);
4537
- }
4533
+ };
4538
4534
 
4539
- function walk(directory, files = []) {
4535
+ const walk = (directory, files = []) => {
4540
4536
  if (!fs.existsSync(directory)) {
4541
4537
  return files;
4542
4538
  }
@@ -4552,43 +4548,37 @@ function walk(directory, files = []) {
4552
4548
  }
4553
4549
  }
4554
4550
  return files;
4555
- }
4551
+ };
4556
4552
 
4557
- function relative(filePath) {
4558
- return path.relative(root, filePath).replace(/\\\\/gu, '/');
4559
- }
4553
+ const relative = (filePath) => path.relative(root, filePath).replaceAll('\\\\', '/');
4560
4554
 
4561
- function isSourceFile(filePath) {
4562
- return /\\.(?:ts|tsx|js|jsx)$/u.test(filePath);
4563
- }
4555
+ const isSourceFile = (filePath) => /\\.(?:ts|tsx|js|jsx)$/u.test(filePath);
4564
4556
 
4565
- function isLocaleJson(filePath) {
4557
+ const isLocaleJson = (filePath) => {
4566
4558
  const normalized = relative(filePath);
4567
4559
  return /\\/locales\\/(en|cs)\\/[^/]+\\.json$/u.test(normalized);
4568
- }
4560
+ };
4569
4561
 
4570
- function readText(filePath) {
4571
- return fs.readFileSync(filePath, 'utf8');
4572
- }
4562
+ const readText = (filePath) => fs.readFileSync(filePath, 'utf-8');
4573
4563
 
4574
- function branchIsUserCopy(branch) {
4564
+ const branchIsUserCopy = (branch) => {
4575
4565
  const value = branch.trim().replace(/,$/u, '');
4576
4566
  if (allowedLanguageConditionalBranches.has(value)) {
4577
4567
  return false;
4578
4568
  }
4579
4569
  return /^['"][^'"]{2,}['"]$/u.test(value);
4580
- }
4570
+ };
4581
4571
 
4582
- function checkRuntimeResources(filePath, text) {
4572
+ const checkRuntimeResources = (filePath, text) => {
4583
4573
  if (!relative(filePath).endsWith('/src/modern.runtime.ts')) {
4584
4574
  return;
4585
4575
  }
4586
4576
  if (/initOptions\\s*:\\s*\\{[\\s\\S]*?\\bresources\\s*:/u.test(text)) {
4587
4577
  fail(\`\${relative(filePath)} must not inline i18n resources in modern.runtime.ts; use locale JSON files.\`);
4588
4578
  }
4589
- }
4579
+ };
4590
4580
 
4591
- function checkLanguageConditionals(filePath, text) {
4581
+ const checkLanguageConditionals = (filePath, text) => {
4592
4582
  for (const match of text.matchAll(languageConditionalPattern)) {
4593
4583
  const [, name, whenTrue = '', whenFalse = ''] = match;
4594
4584
  if (branchIsUserCopy(whenTrue) || branchIsUserCopy(whenFalse)) {
@@ -4597,9 +4587,9 @@ function checkLanguageConditionals(filePath, text) {
4597
4587
  );
4598
4588
  }
4599
4589
  }
4600
- }
4590
+ };
4601
4591
 
4602
- function checkLiteralVisibleAttributes(filePath, text) {
4592
+ const checkLiteralVisibleAttributes = (filePath, text) => {
4603
4593
  if (!filePath.endsWith('.tsx') && !filePath.endsWith('.jsx')) {
4604
4594
  return;
4605
4595
  }
@@ -4611,17 +4601,17 @@ function checkLiteralVisibleAttributes(filePath, text) {
4611
4601
  );
4612
4602
  }
4613
4603
  }
4614
- }
4604
+ };
4615
4605
 
4616
- function checkSplitPhraseKeys(filePath, text) {
4606
+ const checkSplitPhraseKeys = (filePath, text) => {
4617
4607
  if (/t\\(\\s*['"][^'"]+\\.(?:prefix|suffix|before|after)['"]\\s*\\)/u.test(text)) {
4618
4608
  fail(
4619
4609
  \`\${relative(filePath)} uses split phrase translation keys. Keep translator-owned phrases whole.\`,
4620
4610
  );
4621
4611
  }
4622
- }
4612
+ };
4623
4613
 
4624
- function checkBoundaryAttributes(filePath, text) {
4614
+ const checkBoundaryAttributes = (filePath, text) => {
4625
4615
  if (!filePath.endsWith('.tsx') && !filePath.endsWith('.jsx')) {
4626
4616
  return;
4627
4617
  }
@@ -4630,9 +4620,9 @@ function checkBoundaryAttributes(filePath, text) {
4630
4620
  \`\${relative(filePath)} uses legacy data-mf-* boundary attributes. Use data-modern-boundary-id and data-modern-mf-expose.\`,
4631
4621
  );
4632
4622
  }
4633
- }
4623
+ };
4634
4624
 
4635
- function visitLocaleKeys(value, visitor, pathParts = []) {
4625
+ const visitLocaleKeys = (value, visitor, pathParts = []) => {
4636
4626
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
4637
4627
  return;
4638
4628
  }
@@ -4641,9 +4631,9 @@ function visitLocaleKeys(value, visitor, pathParts = []) {
4641
4631
  visitor(key, child, nextPath);
4642
4632
  visitLocaleKeys(child, visitor, nextPath);
4643
4633
  }
4644
- }
4634
+ };
4645
4635
 
4646
- function checkPluralResources(filePath, json) {
4636
+ const checkPluralResources = (filePath, json) => {
4647
4637
  const language = relative(filePath).split('/locales/')[1]?.split('/')[0];
4648
4638
  const requiredSuffixes =
4649
4639
  language === 'cs' ? ['one', 'few', 'many', 'other'] : ['one', 'other'];
@@ -4673,7 +4663,7 @@ function checkPluralResources(filePath, json) {
4673
4663
  }
4674
4664
  }
4675
4665
  }
4676
- }
4666
+ };
4677
4667
 
4678
4668
  const sourceFiles = sourceRoots.flatMap(sourceRoot =>
4679
4669
  walk(path.join(root, sourceRoot)).filter(filePath => isSourceFile(filePath)),
@@ -5085,6 +5075,7 @@ async function fetchText(url) {
5085
5075
  status: response.status,
5086
5076
  accessControlAllowOrigin: response.headers.get('access-control-allow-origin'),
5087
5077
  contentType: response.headers.get('content-type'),
5078
+ link: response.headers.get('link'),
5088
5079
  body: await response.text(),
5089
5080
  };
5090
5081
  }
@@ -5179,6 +5170,21 @@ async function validateApp(app, publicUrl) {
5179
5170
  expectedAppId && ssr.body.includes(\`data-app-id="\${expectedAppId}"\`),
5180
5171
  \`\${app.id} SSR response is missing CSS root marker \${cssRootSelector}\`,
5181
5172
  );
5173
+ const cssPreloadLinkHeader = ssr.link ?? '';
5174
+ evidence.assertions.push({
5175
+ type: 'css-preload-link-header',
5176
+ actual: cssPreloadLinkHeader,
5177
+ status:
5178
+ cssPreloadLinkHeader.includes('rel=preload') &&
5179
+ cssPreloadLinkHeader.includes('as=style')
5180
+ ? 'pass'
5181
+ : 'fail',
5182
+ });
5183
+ assert(
5184
+ cssPreloadLinkHeader.includes('rel=preload') &&
5185
+ cssPreloadLinkHeader.includes('as=style'),
5186
+ \`\${app.id} SSR response is missing CSS preload Link headers\`,
5187
+ );
5182
5188
 
5183
5189
  const manifestRoute = routes.mfManifest ?? '/mf-manifest.json';
5184
5190
  const manifest = await fetchText(joinUrl(publicUrl, manifestRoute));
package/package.json CHANGED
@@ -21,7 +21,7 @@
21
21
  "engines": {
22
22
  "node": ">=20"
23
23
  },
24
- "version": "3.2.0-ultramodern.72",
24
+ "version": "3.2.0-ultramodern.74",
25
25
  "types": "./dist/types/index.d.ts",
26
26
  "main": "./dist/index.js",
27
27
  "bin": {
@@ -41,7 +41,7 @@
41
41
  "@types/node": "^25.9.1",
42
42
  "@typescript/native-preview": "7.0.0-dev.20260527.2",
43
43
  "tsx": "^4.22.3",
44
- "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.72"
44
+ "@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.74"
45
45
  },
46
46
  "publishConfig": {
47
47
  "registry": "https://registry.npmjs.org/",
@@ -54,6 +54,6 @@
54
54
  "start": "node ./dist/index.js"
55
55
  },
56
56
  "ultramodern": {
57
- "frameworkVersion": "3.2.0-ultramodern.72"
57
+ "frameworkVersion": "3.2.0-ultramodern.74"
58
58
  }
59
59
  }