@bleedingdev/modern-js-code-tools 3.5.0-ultramodern.0 → 3.5.0-ultramodern.2
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.
|
@@ -88,9 +88,9 @@ const DEFAULT_IGNORE_COMMENT_PATTERN = 'i18n-ignore';
|
|
|
88
88
|
const LETTER_PATTERN = /\p{L}/u;
|
|
89
89
|
const SPLIT_TRANSLATION_KEY_PATTERN = /\.(?:prefix|suffix|before|after)$/u;
|
|
90
90
|
const API_SOURCE_FILE_PATTERN = /(?:^|\/)(?:api\/|shared\/api\.[cm]?[jt]sx?$)/u;
|
|
91
|
-
const FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN = /(?:^|\/)(?:apps
|
|
92
|
-
const
|
|
93
|
-
const SHARED_API_CONTRACT_PATTERN = /(?:^|\/)verticals\/[^/]+\/shared\/api\.[cm]?[jt]sx?$/u;
|
|
91
|
+
const FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN = /(?:^|\/)(?:(?:apps|verticals)\/[^/]+\/(?:api\/(?:effect|lambda)|shared\/effect|src\/effect))(?:\/|$)/u;
|
|
92
|
+
const API_ENTRY_PATTERN = /(?:^|\/)(?:apps|verticals)\/[^/]+\/api\/index\.[cm]?[jt]sx?$/u;
|
|
93
|
+
const SHARED_API_CONTRACT_PATTERN = /(?:^|\/)(?:apps|verticals)\/[^/]+\/shared\/api\.[cm]?[jt]sx?$/u;
|
|
94
94
|
const isRecord = (value)=>Boolean(value) && 'object' == typeof value && !Array.isArray(value);
|
|
95
95
|
const asStringArray = (value, fallback)=>Array.isArray(value) && value.every((item)=>'string' == typeof item) ? value : fallback;
|
|
96
96
|
const getCommonRuleOption = (context, defaults)=>{
|
|
@@ -245,7 +245,7 @@ const getSourceText = (context, node)=>context.getSourceCode?.().getText?.(node)
|
|
|
245
245
|
const normalizeFilename = (filePath)=>(filePath ?? '').replaceAll('\\', '/');
|
|
246
246
|
const isApiSourceFile = (filePath)=>API_SOURCE_FILE_PATTERN.test(normalizeFilename(filePath));
|
|
247
247
|
const isForbiddenGeneratedEffectPath = (filePath)=>FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN.test(normalizeFilename(filePath));
|
|
248
|
-
const
|
|
248
|
+
const isApiEntryFile = (filePath)=>API_ENTRY_PATTERN.test(normalizeFilename(filePath));
|
|
249
249
|
const isSharedApiContractFile = (filePath)=>SHARED_API_CONTRACT_PATTERN.test(normalizeFilename(filePath));
|
|
250
250
|
const looksLikeLocaleTest = (context, node)=>{
|
|
251
251
|
const text = getSourceText(context, node);
|
|
@@ -372,7 +372,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
|
|
|
372
372
|
reportProgramPattern(context, node, source, /\bruntimeFramework\s*(?::|=)\s*['"]hono['"]/u, 'UltraModern API apps must use bff.runtimeFramework: "effect".');
|
|
373
373
|
reportProgramPattern(context, node, source, /(?:from|import)\s*['"][^'"]*(?:api\/effect|shared\/effect)[^'"]*['"]|shared-effect-api/u, 'Import API code from direct api/index.ts, shared/api.ts or src/api/* paths, not api/effect, shared/effect or shared Effect API packages.');
|
|
374
374
|
reportProgramPattern(context, node, source, /\bstrictEffectApproach\s*(?::|=)\s*false\b/u, 'UltraModern API apps must keep strictEffectApproach enabled.');
|
|
375
|
-
if (
|
|
375
|
+
if (isApiEntryFile(filename)) {
|
|
376
376
|
reportMissingProgramPattern(context, node, source, /\bdefineEffectBff\b/u, 'Generated API entries must export defineEffectBff(...).');
|
|
377
377
|
reportMissingProgramPattern(context, node, source, /\bHttpApiBuilder\b/u, 'Generated API entries must implement handlers through HttpApiBuilder.');
|
|
378
378
|
reportMissingProgramPattern(context, node, source, /\bLayer\b/u, 'Generated API entries must compose dependencies with Effect Layer.');
|
|
@@ -389,6 +389,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
|
|
|
389
389
|
reportProgramPattern(context, node, source, /\b(?:request|req)\.(?:json|text|formData|arrayBuffer)\s*\(/u, 'API modules must not manually parse request bodies; use HttpApiEndpoint payload/query/params schemas.');
|
|
390
390
|
reportProgramPattern(context, node, source, /\bexport\s+const\s+handler\b|\bexport\s+default\s+async\b/u, 'API modules must not export raw request handlers; export defineEffectBff(...) from api/index.ts.');
|
|
391
391
|
reportProgramPattern(context, node, source, /\bcreateHandler\s*[:=]\s*(?!defineEffectBff\b)/u, 'API modules must not define unbranded handler factories; use defineEffectBff(...).');
|
|
392
|
+
reportProgramPattern(context, node, source, /\bSchema\.(?:UnknownFromJsonString|Unknown|Any)\b/u, 'API modules must use concrete request, response and error schemas; Schema.UnknownFromJsonString, Schema.Unknown and Schema.Any are forbidden in UltraModern API code.');
|
|
392
393
|
}
|
|
393
394
|
};
|
|
394
395
|
}
|
|
@@ -59,9 +59,9 @@ const DEFAULT_IGNORE_COMMENT_PATTERN = 'i18n-ignore';
|
|
|
59
59
|
const LETTER_PATTERN = /\p{L}/u;
|
|
60
60
|
const SPLIT_TRANSLATION_KEY_PATTERN = /\.(?:prefix|suffix|before|after)$/u;
|
|
61
61
|
const API_SOURCE_FILE_PATTERN = /(?:^|\/)(?:api\/|shared\/api\.[cm]?[jt]sx?$)/u;
|
|
62
|
-
const FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN = /(?:^|\/)(?:apps
|
|
63
|
-
const
|
|
64
|
-
const SHARED_API_CONTRACT_PATTERN = /(?:^|\/)verticals\/[^/]+\/shared\/api\.[cm]?[jt]sx?$/u;
|
|
62
|
+
const FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN = /(?:^|\/)(?:(?:apps|verticals)\/[^/]+\/(?:api\/(?:effect|lambda)|shared\/effect|src\/effect))(?:\/|$)/u;
|
|
63
|
+
const API_ENTRY_PATTERN = /(?:^|\/)(?:apps|verticals)\/[^/]+\/api\/index\.[cm]?[jt]sx?$/u;
|
|
64
|
+
const SHARED_API_CONTRACT_PATTERN = /(?:^|\/)(?:apps|verticals)\/[^/]+\/shared\/api\.[cm]?[jt]sx?$/u;
|
|
65
65
|
const isRecord = (value)=>Boolean(value) && 'object' == typeof value && !Array.isArray(value);
|
|
66
66
|
const asStringArray = (value, fallback)=>Array.isArray(value) && value.every((item)=>'string' == typeof item) ? value : fallback;
|
|
67
67
|
const getCommonRuleOption = (context, defaults)=>{
|
|
@@ -216,7 +216,7 @@ const getSourceText = (context, node)=>context.getSourceCode?.().getText?.(node)
|
|
|
216
216
|
const normalizeFilename = (filePath)=>(filePath ?? '').replaceAll('\\', '/');
|
|
217
217
|
const isApiSourceFile = (filePath)=>API_SOURCE_FILE_PATTERN.test(normalizeFilename(filePath));
|
|
218
218
|
const isForbiddenGeneratedEffectPath = (filePath)=>FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN.test(normalizeFilename(filePath));
|
|
219
|
-
const
|
|
219
|
+
const isApiEntryFile = (filePath)=>API_ENTRY_PATTERN.test(normalizeFilename(filePath));
|
|
220
220
|
const isSharedApiContractFile = (filePath)=>SHARED_API_CONTRACT_PATTERN.test(normalizeFilename(filePath));
|
|
221
221
|
const looksLikeLocaleTest = (context, node)=>{
|
|
222
222
|
const text = getSourceText(context, node);
|
|
@@ -343,7 +343,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
|
|
|
343
343
|
reportProgramPattern(context, node, source, /\bruntimeFramework\s*(?::|=)\s*['"]hono['"]/u, 'UltraModern API apps must use bff.runtimeFramework: "effect".');
|
|
344
344
|
reportProgramPattern(context, node, source, /(?:from|import)\s*['"][^'"]*(?:api\/effect|shared\/effect)[^'"]*['"]|shared-effect-api/u, 'Import API code from direct api/index.ts, shared/api.ts or src/api/* paths, not api/effect, shared/effect or shared Effect API packages.');
|
|
345
345
|
reportProgramPattern(context, node, source, /\bstrictEffectApproach\s*(?::|=)\s*false\b/u, 'UltraModern API apps must keep strictEffectApproach enabled.');
|
|
346
|
-
if (
|
|
346
|
+
if (isApiEntryFile(filename)) {
|
|
347
347
|
reportMissingProgramPattern(context, node, source, /\bdefineEffectBff\b/u, 'Generated API entries must export defineEffectBff(...).');
|
|
348
348
|
reportMissingProgramPattern(context, node, source, /\bHttpApiBuilder\b/u, 'Generated API entries must implement handlers through HttpApiBuilder.');
|
|
349
349
|
reportMissingProgramPattern(context, node, source, /\bLayer\b/u, 'Generated API entries must compose dependencies with Effect Layer.');
|
|
@@ -360,6 +360,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
|
|
|
360
360
|
reportProgramPattern(context, node, source, /\b(?:request|req)\.(?:json|text|formData|arrayBuffer)\s*\(/u, 'API modules must not manually parse request bodies; use HttpApiEndpoint payload/query/params schemas.');
|
|
361
361
|
reportProgramPattern(context, node, source, /\bexport\s+const\s+handler\b|\bexport\s+default\s+async\b/u, 'API modules must not export raw request handlers; export defineEffectBff(...) from api/index.ts.');
|
|
362
362
|
reportProgramPattern(context, node, source, /\bcreateHandler\s*[:=]\s*(?!defineEffectBff\b)/u, 'API modules must not define unbranded handler factories; use defineEffectBff(...).');
|
|
363
|
+
reportProgramPattern(context, node, source, /\bSchema\.(?:UnknownFromJsonString|Unknown|Any)\b/u, 'API modules must use concrete request, response and error schemas; Schema.UnknownFromJsonString, Schema.Unknown and Schema.Any are forbidden in UltraModern API code.');
|
|
363
364
|
}
|
|
364
365
|
};
|
|
365
366
|
}
|
|
@@ -60,9 +60,9 @@ const DEFAULT_IGNORE_COMMENT_PATTERN = 'i18n-ignore';
|
|
|
60
60
|
const LETTER_PATTERN = /\p{L}/u;
|
|
61
61
|
const SPLIT_TRANSLATION_KEY_PATTERN = /\.(?:prefix|suffix|before|after)$/u;
|
|
62
62
|
const API_SOURCE_FILE_PATTERN = /(?:^|\/)(?:api\/|shared\/api\.[cm]?[jt]sx?$)/u;
|
|
63
|
-
const FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN = /(?:^|\/)(?:apps
|
|
64
|
-
const
|
|
65
|
-
const SHARED_API_CONTRACT_PATTERN = /(?:^|\/)verticals\/[^/]+\/shared\/api\.[cm]?[jt]sx?$/u;
|
|
63
|
+
const FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN = /(?:^|\/)(?:(?:apps|verticals)\/[^/]+\/(?:api\/(?:effect|lambda)|shared\/effect|src\/effect))(?:\/|$)/u;
|
|
64
|
+
const API_ENTRY_PATTERN = /(?:^|\/)(?:apps|verticals)\/[^/]+\/api\/index\.[cm]?[jt]sx?$/u;
|
|
65
|
+
const SHARED_API_CONTRACT_PATTERN = /(?:^|\/)(?:apps|verticals)\/[^/]+\/shared\/api\.[cm]?[jt]sx?$/u;
|
|
66
66
|
const isRecord = (value)=>Boolean(value) && 'object' == typeof value && !Array.isArray(value);
|
|
67
67
|
const asStringArray = (value, fallback)=>Array.isArray(value) && value.every((item)=>'string' == typeof item) ? value : fallback;
|
|
68
68
|
const getCommonRuleOption = (context, defaults)=>{
|
|
@@ -217,7 +217,7 @@ const getSourceText = (context, node)=>context.getSourceCode?.().getText?.(node)
|
|
|
217
217
|
const normalizeFilename = (filePath)=>(filePath ?? '').replaceAll('\\', '/');
|
|
218
218
|
const isApiSourceFile = (filePath)=>API_SOURCE_FILE_PATTERN.test(normalizeFilename(filePath));
|
|
219
219
|
const isForbiddenGeneratedEffectPath = (filePath)=>FORBIDDEN_GENERATED_EFFECT_PATH_PATTERN.test(normalizeFilename(filePath));
|
|
220
|
-
const
|
|
220
|
+
const isApiEntryFile = (filePath)=>API_ENTRY_PATTERN.test(normalizeFilename(filePath));
|
|
221
221
|
const isSharedApiContractFile = (filePath)=>SHARED_API_CONTRACT_PATTERN.test(normalizeFilename(filePath));
|
|
222
222
|
const looksLikeLocaleTest = (context, node)=>{
|
|
223
223
|
const text = getSourceText(context, node);
|
|
@@ -344,7 +344,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
|
|
|
344
344
|
reportProgramPattern(context, node, source, /\bruntimeFramework\s*(?::|=)\s*['"]hono['"]/u, 'UltraModern API apps must use bff.runtimeFramework: "effect".');
|
|
345
345
|
reportProgramPattern(context, node, source, /(?:from|import)\s*['"][^'"]*(?:api\/effect|shared\/effect)[^'"]*['"]|shared-effect-api/u, 'Import API code from direct api/index.ts, shared/api.ts or src/api/* paths, not api/effect, shared/effect or shared Effect API packages.');
|
|
346
346
|
reportProgramPattern(context, node, source, /\bstrictEffectApproach\s*(?::|=)\s*false\b/u, 'UltraModern API apps must keep strictEffectApproach enabled.');
|
|
347
|
-
if (
|
|
347
|
+
if (isApiEntryFile(filename)) {
|
|
348
348
|
reportMissingProgramPattern(context, node, source, /\bdefineEffectBff\b/u, 'Generated API entries must export defineEffectBff(...).');
|
|
349
349
|
reportMissingProgramPattern(context, node, source, /\bHttpApiBuilder\b/u, 'Generated API entries must implement handlers through HttpApiBuilder.');
|
|
350
350
|
reportMissingProgramPattern(context, node, source, /\bLayer\b/u, 'Generated API entries must compose dependencies with Effect Layer.');
|
|
@@ -361,6 +361,7 @@ const createStrictEffectApiBoundariesRule = ()=>({
|
|
|
361
361
|
reportProgramPattern(context, node, source, /\b(?:request|req)\.(?:json|text|formData|arrayBuffer)\s*\(/u, 'API modules must not manually parse request bodies; use HttpApiEndpoint payload/query/params schemas.');
|
|
362
362
|
reportProgramPattern(context, node, source, /\bexport\s+const\s+handler\b|\bexport\s+default\s+async\b/u, 'API modules must not export raw request handlers; export defineEffectBff(...) from api/index.ts.');
|
|
363
363
|
reportProgramPattern(context, node, source, /\bcreateHandler\s*[:=]\s*(?!defineEffectBff\b)/u, 'API modules must not define unbranded handler factories; use defineEffectBff(...).');
|
|
364
|
+
reportProgramPattern(context, node, source, /\bSchema\.(?:UnknownFromJsonString|Unknown|Any)\b/u, 'API modules must use concrete request, response and error schemas; Schema.UnknownFromJsonString, Schema.Unknown and Schema.Any are forbidden in UltraModern API code.');
|
|
364
365
|
}
|
|
365
366
|
};
|
|
366
367
|
}
|
package/package.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=20"
|
|
25
25
|
},
|
|
26
|
-
"version": "3.5.0-ultramodern.
|
|
26
|
+
"version": "3.5.0-ultramodern.2",
|
|
27
27
|
"types": "./dist/types/index.d.ts",
|
|
28
28
|
"main": "./dist/esm-node/index.js",
|
|
29
29
|
"typesVersions": {
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"oxlint": "1.71.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@rslib/core": "0.23.
|
|
64
|
+
"@rslib/core": "0.23.1",
|
|
65
65
|
"@types/node": "^26.0.1",
|
|
66
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
66
|
+
"@typescript/native-preview": "7.0.0-dev.20260628.1",
|
|
67
67
|
"@scripts/rstest-config": "2.66.0"
|
|
68
68
|
},
|
|
69
69
|
"sideEffects": false,
|