@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.3 → 3.9.0-ultramodern.4

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.
@@ -40,18 +40,51 @@ const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = 'module';
40
40
  const CLOUDFLARE_WORKER_PACKAGE_TYPE = 'commonjs';
41
41
  const CLOUDFLARE_WORKER_BUNDLE_FORMAT = 'commonjs';
42
42
  const CLOUDFLARE_WORKER_NODE_BUILTINS = [
43
+ 'assert',
44
+ 'assert/strict',
43
45
  'async_hooks',
44
46
  'buffer',
47
+ 'child_process',
45
48
  'crypto',
49
+ 'dgram',
50
+ 'dns',
51
+ 'domain',
46
52
  'events',
53
+ 'fs',
47
54
  'fs/promises',
55
+ 'http',
56
+ 'http2',
57
+ 'inspector',
48
58
  'module',
59
+ 'net',
60
+ 'os',
49
61
  'path',
50
62
  'process',
63
+ 'readline',
64
+ 'readline/promises',
65
+ 'repl',
66
+ 'sqlite',
51
67
  'stream',
68
+ 'stream/consumers',
69
+ 'stream/promises',
70
+ 'stream/web',
52
71
  'string_decoder',
72
+ 'timers',
73
+ 'timers/promises',
74
+ 'tls',
75
+ 'trace_events',
76
+ 'tty',
53
77
  'url',
54
- 'util'
78
+ 'util',
79
+ 'util/types',
80
+ 'v8',
81
+ 'vm',
82
+ 'wasi',
83
+ 'worker_threads',
84
+ 'zlib'
85
+ ];
86
+ const CLOUDFLARE_WORKER_PLATFORM_MODULES = [
87
+ 'cloudflare:sockets'
55
88
  ];
56
89
  const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS = [
57
90
  'nodejs_compat',
@@ -71,6 +104,7 @@ __webpack_require__.d(__webpack_exports__, {}, {
71
104
  CLOUDFLARE_WORKER_NODE_BUILTINS: CLOUDFLARE_WORKER_NODE_BUILTINS,
72
105
  CLOUDFLARE_WORKER_PACKAGE_FILE: CLOUDFLARE_WORKER_PACKAGE_FILE,
73
106
  CLOUDFLARE_WORKER_PACKAGE_TYPE: CLOUDFLARE_WORKER_PACKAGE_TYPE,
107
+ CLOUDFLARE_WORKER_PLATFORM_MODULES: CLOUDFLARE_WORKER_PLATFORM_MODULES,
74
108
  CLOUDFLARE_WRANGLER_CONFIG_FILE: CLOUDFLARE_WRANGLER_CONFIG_FILE
75
109
  });
76
110
  exports.CLOUDFLARE_ASSETS_BINDING = __webpack_exports__.CLOUDFLARE_ASSETS_BINDING;
@@ -86,6 +120,7 @@ exports.CLOUDFLARE_WORKER_MANIFEST = __webpack_exports__.CLOUDFLARE_WORKER_MANIF
86
120
  exports.CLOUDFLARE_WORKER_NODE_BUILTINS = __webpack_exports__.CLOUDFLARE_WORKER_NODE_BUILTINS;
87
121
  exports.CLOUDFLARE_WORKER_PACKAGE_FILE = __webpack_exports__.CLOUDFLARE_WORKER_PACKAGE_FILE;
88
122
  exports.CLOUDFLARE_WORKER_PACKAGE_TYPE = __webpack_exports__.CLOUDFLARE_WORKER_PACKAGE_TYPE;
123
+ exports.CLOUDFLARE_WORKER_PLATFORM_MODULES = __webpack_exports__.CLOUDFLARE_WORKER_PLATFORM_MODULES;
89
124
  exports.CLOUDFLARE_WRANGLER_CONFIG_FILE = __webpack_exports__.CLOUDFLARE_WRANGLER_CONFIG_FILE;
90
125
  for(var __rspack_i in __webpack_exports__)if (-1 === [
91
126
  "CLOUDFLARE_ASSETS_BINDING",
@@ -101,6 +136,7 @@ for(var __rspack_i in __webpack_exports__)if (-1 === [
101
136
  "CLOUDFLARE_WORKER_NODE_BUILTINS",
102
137
  "CLOUDFLARE_WORKER_PACKAGE_FILE",
103
138
  "CLOUDFLARE_WORKER_PACKAGE_TYPE",
139
+ "CLOUDFLARE_WORKER_PLATFORM_MODULES",
104
140
  "CLOUDFLARE_WRANGLER_CONFIG_FILE"
105
141
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
106
142
  Object.defineProperty(exports, '__esModule', {
@@ -223,7 +223,10 @@ const analyzeWorkerModule = (source)=>{
223
223
  };
224
224
  };
225
225
  const getPackageName = (specifier)=>specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
226
- const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set(external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_WORKER_NODE_BUILTINS.map((builtin)=>`node:${builtin}`));
226
+ const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set([
227
+ ...external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_WORKER_NODE_BUILTINS.map((builtin)=>`node:${builtin}`),
228
+ ...external_cloudflare_output_contract_js_namespaceObject.CLOUDFLARE_WORKER_PLATFORM_MODULES
229
+ ]);
227
230
  const isInsideDirectory = (directory, filePath)=>{
228
231
  const relative = external_node_path_default().relative(directory, filePath);
229
232
  return 0 === relative.length || !relative.startsWith('..') && !external_node_path_default().isAbsolute(relative);
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
22
+ };
23
+ })();
24
+ (()=>{
25
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
26
+ })();
27
+ (()=>{
28
+ __webpack_require__.r = (exports1)=>{
29
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
30
+ value: 'Module'
31
+ });
32
+ Object.defineProperty(exports1, '__esModule', {
33
+ value: true
34
+ });
35
+ };
36
+ })();
37
+ var __webpack_exports__ = {};
38
+ __webpack_require__.r(__webpack_exports__);
39
+ __webpack_require__.d(__webpack_exports__, {
40
+ UltramodernNativeTypeChecker: ()=>UltramodernNativeTypeChecker,
41
+ configureUltramodernTypeChecker: ()=>configureUltramodernTypeChecker
42
+ });
43
+ const external_node_child_process_namespaceObject = require("node:child_process");
44
+ const external_node_path_namespaceObject = require("node:path");
45
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
46
+ const external_node_util_namespaceObject = require("node:util");
47
+ const execute = (0, external_node_util_namespaceObject.promisify)(external_node_child_process_namespaceObject.execFile);
48
+ const native_type_checker_name = 'UltramodernNativeTypeChecker';
49
+ class UltramodernNativeTypeChecker {
50
+ async check() {
51
+ const { configFile, build } = this.options;
52
+ const args = build ? [
53
+ '--build',
54
+ configFile,
55
+ '--stopBuildOnErrors'
56
+ ] : [
57
+ '--project',
58
+ configFile,
59
+ '--noEmit'
60
+ ];
61
+ await this.run([
62
+ ...args,
63
+ '--pretty',
64
+ 'false'
65
+ ]);
66
+ }
67
+ async run(args) {
68
+ try {
69
+ const result = await execute(this.options.compiler(), args, {
70
+ cwd: external_node_path_default().dirname(this.options.configFile),
71
+ maxBuffer: 16777216
72
+ });
73
+ return result.stdout;
74
+ } catch (cause) {
75
+ const output = cause;
76
+ throw new Error(`${native_type_checker_name} failed:\n${output.stdout ?? ''}${output.stderr ?? ''}`, {
77
+ cause
78
+ });
79
+ }
80
+ }
81
+ async watchInputs() {
82
+ const inputs = new Set();
83
+ const projects = [
84
+ this.options.configFile
85
+ ];
86
+ const visited = new Set();
87
+ for (const configFile of projects){
88
+ if (visited.has(configFile)) continue;
89
+ visited.add(configFile);
90
+ inputs.add(configFile);
91
+ const config = JSON.parse(await this.run([
92
+ '--showConfig',
93
+ '--project',
94
+ configFile
95
+ ]));
96
+ const directory = external_node_path_default().dirname(configFile);
97
+ for (const file of config.files ?? [])inputs.add(external_node_path_default().resolve(directory, file));
98
+ for (const reference of config.references ?? []){
99
+ const target = external_node_path_default().resolve(directory, reference.path);
100
+ projects.push('.json' === external_node_path_default().extname(target) ? target : external_node_path_default().join(target, 'tsconfig.json'));
101
+ }
102
+ }
103
+ return inputs;
104
+ }
105
+ apply(compiler) {
106
+ compiler.hooks.thisCompilation.tap(native_type_checker_name, (compilation)=>{
107
+ compilation.fileDependencies.add(this.options.configFile);
108
+ compilation.hooks.processAssets.tapPromise(native_type_checker_name, async ()=>{
109
+ try {
110
+ for (const file of (await this.watchInputs()))compilation.fileDependencies.add(file);
111
+ await this.check();
112
+ } catch (cause) {
113
+ compilation.errors.push(new Error(cause instanceof Error ? cause.message : String(cause), {
114
+ cause
115
+ }));
116
+ }
117
+ });
118
+ });
119
+ }
120
+ constructor(options){
121
+ this.options = options;
122
+ }
123
+ }
124
+ function configureUltramodernTypeChecker(chain, pluginId, resolveCompiler) {
125
+ if (!chain.plugins.has(pluginId)) return;
126
+ const options = chain.plugin(pluginId).get('args')?.[0];
127
+ const typescript = options?.typescript;
128
+ if (typescript?.tsgo === false) return;
129
+ if (!typescript?.configFile) throw new Error(`${native_type_checker_name} requires the configured TypeScript project.`);
130
+ const configFile = external_node_path_default().resolve(typescript.configFile);
131
+ chain.plugin(pluginId).use(UltramodernNativeTypeChecker, [
132
+ {
133
+ build: true === typescript.build,
134
+ compiler: ()=>resolveCompiler(configFile),
135
+ configFile
136
+ }
137
+ ]);
138
+ }
139
+ exports.UltramodernNativeTypeChecker = __webpack_exports__.UltramodernNativeTypeChecker;
140
+ exports.configureUltramodernTypeChecker = __webpack_exports__.configureUltramodernTypeChecker;
141
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
142
+ "UltramodernNativeTypeChecker",
143
+ "configureUltramodernTypeChecker"
144
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
145
+ Object.defineProperty(exports, '__esModule', {
146
+ value: true
147
+ });
@@ -38,11 +38,8 @@ const BUILD_MARKER_NAMESPACE = 'ultramodern-delivery-unit-release-build-marker:v
38
38
  const PROMOTABLE_SOURCE_REVISION_PATTERN = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u;
39
39
  const gitOutput = (workspaceRoot, args)=>{
40
40
  try {
41
- return (0, external_node_child_process_namespaceObject.execFileSync)('git', [
42
- '-C',
43
- workspaceRoot,
44
- ...args
45
- ], {
41
+ return (0, external_node_child_process_namespaceObject.execFileSync)('git', args, {
42
+ cwd: workspaceRoot,
46
43
  encoding: 'utf8',
47
44
  stdio: [
48
45
  'ignore',
@@ -77,7 +74,7 @@ const resolveUltramodernSourceRevision = (workspaceRoot = process.cwd(), configu
77
74
  ]);
78
75
  const status = gitOutput(gitRoot, [
79
76
  'status',
80
- '--porcelain=v1',
77
+ '--porcelain',
81
78
  '--untracked-files=all'
82
79
  ]);
83
80
  if (!revision || void 0 === status || status.length > 0) return 'workspace';
@@ -11,21 +11,54 @@ const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = 'module';
11
11
  const CLOUDFLARE_WORKER_PACKAGE_TYPE = 'commonjs';
12
12
  const CLOUDFLARE_WORKER_BUNDLE_FORMAT = 'commonjs';
13
13
  const CLOUDFLARE_WORKER_NODE_BUILTINS = [
14
+ 'assert',
15
+ 'assert/strict',
14
16
  'async_hooks',
15
17
  'buffer',
18
+ 'child_process',
16
19
  'crypto',
20
+ 'dgram',
21
+ 'dns',
22
+ 'domain',
17
23
  'events',
24
+ 'fs',
18
25
  'fs/promises',
26
+ 'http',
27
+ 'http2',
28
+ 'inspector',
19
29
  'module',
30
+ 'net',
31
+ 'os',
20
32
  'path',
21
33
  'process',
34
+ 'readline',
35
+ 'readline/promises',
36
+ 'repl',
37
+ 'sqlite',
22
38
  'stream',
39
+ 'stream/consumers',
40
+ 'stream/promises',
41
+ 'stream/web',
23
42
  'string_decoder',
43
+ 'timers',
44
+ 'timers/promises',
45
+ 'tls',
46
+ 'trace_events',
47
+ 'tty',
24
48
  'url',
25
- 'util'
49
+ 'util',
50
+ 'util/types',
51
+ 'v8',
52
+ 'vm',
53
+ 'wasi',
54
+ 'worker_threads',
55
+ 'zlib'
56
+ ];
57
+ const CLOUDFLARE_WORKER_PLATFORM_MODULES = [
58
+ 'cloudflare:sockets'
26
59
  ];
27
60
  const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS = [
28
61
  'nodejs_compat',
29
62
  'global_fetch_strictly_public'
30
63
  ];
31
- export { CLOUDFLARE_ASSETS_BINDING, CLOUDFLARE_OUTPUT_PACKAGE_FILE, CLOUDFLARE_OUTPUT_PACKAGE_TYPE, CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY, CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS, CLOUDFLARE_RUNTIME_TYPE, CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_BUNDLE_FORMAT, CLOUDFLARE_WORKER_ENTRY, CLOUDFLARE_WORKER_MANIFEST, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PACKAGE_FILE, CLOUDFLARE_WORKER_PACKAGE_TYPE, CLOUDFLARE_WRANGLER_CONFIG_FILE };
64
+ export { CLOUDFLARE_ASSETS_BINDING, CLOUDFLARE_OUTPUT_PACKAGE_FILE, CLOUDFLARE_OUTPUT_PACKAGE_TYPE, CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY, CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS, CLOUDFLARE_RUNTIME_TYPE, CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_BUNDLE_FORMAT, CLOUDFLARE_WORKER_ENTRY, CLOUDFLARE_WORKER_MANIFEST, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PACKAGE_FILE, CLOUDFLARE_WORKER_PACKAGE_TYPE, CLOUDFLARE_WORKER_PLATFORM_MODULES, CLOUDFLARE_WRANGLER_CONFIG_FILE };
@@ -4,7 +4,7 @@ import { pathToFileURL } from "node:url";
4
4
  import { isDeepStrictEqual } from "node:util";
5
5
  import { parse } from "@babel/parser";
6
6
  import traverse from "@babel/traverse";
7
- import { CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_NODE_BUILTINS } from "../cloudflare-output-contract.mjs";
7
+ import { CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PLATFORM_MODULES } from "../cloudflare-output-contract.mjs";
8
8
  import { addIssue } from "./issues.mjs";
9
9
  const getReferencedRouteWorkers = (manifest)=>Array.isArray(manifest?.routeSpec?.routes) ? manifest.routeSpec.routes.map((route)=>'string' == typeof route?.worker && route.worker.length > 0 ? route.worker : void 0).filter((worker)=>'string' == typeof worker) : [];
10
10
  const getEffectBffWorker = (manifest)=>manifest?.bff?.runtimeFramework === 'effect' && 'string' == typeof manifest.bff.worker ? manifest.bff.worker : void 0;
@@ -174,7 +174,10 @@ const analyzeWorkerModule = (source)=>{
174
174
  };
175
175
  };
176
176
  const getPackageName = (specifier)=>specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
177
- const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set(CLOUDFLARE_WORKER_NODE_BUILTINS.map((builtin)=>`node:${builtin}`));
177
+ const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set([
178
+ ...CLOUDFLARE_WORKER_NODE_BUILTINS.map((builtin)=>`node:${builtin}`),
179
+ ...CLOUDFLARE_WORKER_PLATFORM_MODULES
180
+ ]);
178
181
  const isInsideDirectory = (directory, filePath)=>{
179
182
  const relative = node_path.relative(directory, filePath);
180
183
  return 0 === relative.length || !relative.startsWith('..') && !node_path.isAbsolute(relative);
@@ -0,0 +1,96 @@
1
+ import { execFile } from "node:child_process";
2
+ import node_path from "node:path";
3
+ import { promisify } from "node:util";
4
+ const execute = promisify(execFile);
5
+ const native_type_checker_name = 'UltramodernNativeTypeChecker';
6
+ class UltramodernNativeTypeChecker {
7
+ async check() {
8
+ const { configFile, build } = this.options;
9
+ const args = build ? [
10
+ '--build',
11
+ configFile,
12
+ '--stopBuildOnErrors'
13
+ ] : [
14
+ '--project',
15
+ configFile,
16
+ '--noEmit'
17
+ ];
18
+ await this.run([
19
+ ...args,
20
+ '--pretty',
21
+ 'false'
22
+ ]);
23
+ }
24
+ async run(args) {
25
+ try {
26
+ const result = await execute(this.options.compiler(), args, {
27
+ cwd: node_path.dirname(this.options.configFile),
28
+ maxBuffer: 16777216
29
+ });
30
+ return result.stdout;
31
+ } catch (cause) {
32
+ const output = cause;
33
+ throw new Error(`${native_type_checker_name} failed:\n${output.stdout ?? ''}${output.stderr ?? ''}`, {
34
+ cause
35
+ });
36
+ }
37
+ }
38
+ async watchInputs() {
39
+ const inputs = new Set();
40
+ const projects = [
41
+ this.options.configFile
42
+ ];
43
+ const visited = new Set();
44
+ for (const configFile of projects){
45
+ if (visited.has(configFile)) continue;
46
+ visited.add(configFile);
47
+ inputs.add(configFile);
48
+ const config = JSON.parse(await this.run([
49
+ '--showConfig',
50
+ '--project',
51
+ configFile
52
+ ]));
53
+ const directory = node_path.dirname(configFile);
54
+ for (const file of config.files ?? [])inputs.add(node_path.resolve(directory, file));
55
+ for (const reference of config.references ?? []){
56
+ const target = node_path.resolve(directory, reference.path);
57
+ projects.push('.json' === node_path.extname(target) ? target : node_path.join(target, 'tsconfig.json'));
58
+ }
59
+ }
60
+ return inputs;
61
+ }
62
+ apply(compiler) {
63
+ compiler.hooks.thisCompilation.tap(native_type_checker_name, (compilation)=>{
64
+ compilation.fileDependencies.add(this.options.configFile);
65
+ compilation.hooks.processAssets.tapPromise(native_type_checker_name, async ()=>{
66
+ try {
67
+ for (const file of (await this.watchInputs()))compilation.fileDependencies.add(file);
68
+ await this.check();
69
+ } catch (cause) {
70
+ compilation.errors.push(new Error(cause instanceof Error ? cause.message : String(cause), {
71
+ cause
72
+ }));
73
+ }
74
+ });
75
+ });
76
+ }
77
+ constructor(options){
78
+ this.options = options;
79
+ }
80
+ }
81
+ function configureUltramodernTypeChecker(chain, pluginId, resolveCompiler) {
82
+ if (!chain.plugins.has(pluginId)) return;
83
+ const options = chain.plugin(pluginId).get('args')?.[0];
84
+ const typescript = options?.typescript;
85
+ if (typescript?.tsgo === false) return;
86
+ if (!typescript?.configFile) throw new Error(`${native_type_checker_name} requires the configured TypeScript project.`);
87
+ const configFile = node_path.resolve(typescript.configFile);
88
+ chain.plugin(pluginId).use(UltramodernNativeTypeChecker, [
89
+ {
90
+ build: true === typescript.build,
91
+ compiler: ()=>resolveCompiler(configFile),
92
+ configFile
93
+ }
94
+ ]);
95
+ }
96
+ export { UltramodernNativeTypeChecker, configureUltramodernTypeChecker };
@@ -4,11 +4,8 @@ const BUILD_MARKER_NAMESPACE = 'ultramodern-delivery-unit-release-build-marker:v
4
4
  const PROMOTABLE_SOURCE_REVISION_PATTERN = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u;
5
5
  const gitOutput = (workspaceRoot, args)=>{
6
6
  try {
7
- return execFileSync('git', [
8
- '-C',
9
- workspaceRoot,
10
- ...args
11
- ], {
7
+ return execFileSync('git', args, {
8
+ cwd: workspaceRoot,
12
9
  encoding: 'utf8',
13
10
  stdio: [
14
11
  'ignore',
@@ -43,7 +40,7 @@ const resolveUltramodernSourceRevision = (workspaceRoot = process.cwd(), configu
43
40
  ]);
44
41
  const status = gitOutput(gitRoot, [
45
42
  'status',
46
- '--porcelain=v1',
43
+ '--porcelain',
47
44
  '--untracked-files=all'
48
45
  ]);
49
46
  if (!revision || void 0 === status || status.length > 0) return 'workspace';
@@ -12,21 +12,54 @@ const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = 'module';
12
12
  const CLOUDFLARE_WORKER_PACKAGE_TYPE = 'commonjs';
13
13
  const CLOUDFLARE_WORKER_BUNDLE_FORMAT = 'commonjs';
14
14
  const CLOUDFLARE_WORKER_NODE_BUILTINS = [
15
+ 'assert',
16
+ 'assert/strict',
15
17
  'async_hooks',
16
18
  'buffer',
19
+ 'child_process',
17
20
  'crypto',
21
+ 'dgram',
22
+ 'dns',
23
+ 'domain',
18
24
  'events',
25
+ 'fs',
19
26
  'fs/promises',
27
+ 'http',
28
+ 'http2',
29
+ 'inspector',
20
30
  'module',
31
+ 'net',
32
+ 'os',
21
33
  'path',
22
34
  'process',
35
+ 'readline',
36
+ 'readline/promises',
37
+ 'repl',
38
+ 'sqlite',
23
39
  'stream',
40
+ 'stream/consumers',
41
+ 'stream/promises',
42
+ 'stream/web',
24
43
  'string_decoder',
44
+ 'timers',
45
+ 'timers/promises',
46
+ 'tls',
47
+ 'trace_events',
48
+ 'tty',
25
49
  'url',
26
- 'util'
50
+ 'util',
51
+ 'util/types',
52
+ 'v8',
53
+ 'vm',
54
+ 'wasi',
55
+ 'worker_threads',
56
+ 'zlib'
57
+ ];
58
+ const CLOUDFLARE_WORKER_PLATFORM_MODULES = [
59
+ 'cloudflare:sockets'
27
60
  ];
28
61
  const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS = [
29
62
  'nodejs_compat',
30
63
  'global_fetch_strictly_public'
31
64
  ];
32
- export { CLOUDFLARE_ASSETS_BINDING, CLOUDFLARE_OUTPUT_PACKAGE_FILE, CLOUDFLARE_OUTPUT_PACKAGE_TYPE, CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY, CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS, CLOUDFLARE_RUNTIME_TYPE, CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_BUNDLE_FORMAT, CLOUDFLARE_WORKER_ENTRY, CLOUDFLARE_WORKER_MANIFEST, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PACKAGE_FILE, CLOUDFLARE_WORKER_PACKAGE_TYPE, CLOUDFLARE_WRANGLER_CONFIG_FILE };
65
+ export { CLOUDFLARE_ASSETS_BINDING, CLOUDFLARE_OUTPUT_PACKAGE_FILE, CLOUDFLARE_OUTPUT_PACKAGE_TYPE, CLOUDFLARE_PUBLIC_ASSETS_DIRECTORY, CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS, CLOUDFLARE_RUNTIME_TYPE, CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_BUNDLE_FORMAT, CLOUDFLARE_WORKER_ENTRY, CLOUDFLARE_WORKER_MANIFEST, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PACKAGE_FILE, CLOUDFLARE_WORKER_PACKAGE_TYPE, CLOUDFLARE_WORKER_PLATFORM_MODULES, CLOUDFLARE_WRANGLER_CONFIG_FILE };
@@ -5,7 +5,7 @@ import { pathToFileURL } from "node:url";
5
5
  import { isDeepStrictEqual } from "node:util";
6
6
  import { parse } from "@babel/parser";
7
7
  import traverse from "@babel/traverse";
8
- import { CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_NODE_BUILTINS } from "../cloudflare-output-contract.mjs";
8
+ import { CLOUDFLARE_WORKER_BUNDLE_DIRECTORY, CLOUDFLARE_WORKER_NODE_BUILTINS, CLOUDFLARE_WORKER_PLATFORM_MODULES } from "../cloudflare-output-contract.mjs";
9
9
  import { addIssue } from "./issues.mjs";
10
10
  const getReferencedRouteWorkers = (manifest)=>Array.isArray(manifest?.routeSpec?.routes) ? manifest.routeSpec.routes.map((route)=>'string' == typeof route?.worker && route.worker.length > 0 ? route.worker : void 0).filter((worker)=>'string' == typeof worker) : [];
11
11
  const getEffectBffWorker = (manifest)=>manifest?.bff?.runtimeFramework === 'effect' && 'string' == typeof manifest.bff.worker ? manifest.bff.worker : void 0;
@@ -175,7 +175,10 @@ const analyzeWorkerModule = (source)=>{
175
175
  };
176
176
  };
177
177
  const getPackageName = (specifier)=>specifier.startsWith('@') ? specifier.split('/').slice(0, 2).join('/') : specifier.split('/')[0];
178
- const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set(CLOUDFLARE_WORKER_NODE_BUILTINS.map((builtin)=>`node:${builtin}`));
178
+ const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set([
179
+ ...CLOUDFLARE_WORKER_NODE_BUILTINS.map((builtin)=>`node:${builtin}`),
180
+ ...CLOUDFLARE_WORKER_PLATFORM_MODULES
181
+ ]);
179
182
  const isInsideDirectory = (directory, filePath)=>{
180
183
  const relative = node_path.relative(directory, filePath);
181
184
  return 0 === relative.length || !relative.startsWith('..') && !node_path.isAbsolute(relative);
@@ -0,0 +1,97 @@
1
+ import "node:module";
2
+ import { execFile } from "node:child_process";
3
+ import node_path from "node:path";
4
+ import { promisify } from "node:util";
5
+ const execute = promisify(execFile);
6
+ const native_type_checker_name = 'UltramodernNativeTypeChecker';
7
+ class UltramodernNativeTypeChecker {
8
+ async check() {
9
+ const { configFile, build } = this.options;
10
+ const args = build ? [
11
+ '--build',
12
+ configFile,
13
+ '--stopBuildOnErrors'
14
+ ] : [
15
+ '--project',
16
+ configFile,
17
+ '--noEmit'
18
+ ];
19
+ await this.run([
20
+ ...args,
21
+ '--pretty',
22
+ 'false'
23
+ ]);
24
+ }
25
+ async run(args) {
26
+ try {
27
+ const result = await execute(this.options.compiler(), args, {
28
+ cwd: node_path.dirname(this.options.configFile),
29
+ maxBuffer: 16777216
30
+ });
31
+ return result.stdout;
32
+ } catch (cause) {
33
+ const output = cause;
34
+ throw new Error(`${native_type_checker_name} failed:\n${output.stdout ?? ''}${output.stderr ?? ''}`, {
35
+ cause
36
+ });
37
+ }
38
+ }
39
+ async watchInputs() {
40
+ const inputs = new Set();
41
+ const projects = [
42
+ this.options.configFile
43
+ ];
44
+ const visited = new Set();
45
+ for (const configFile of projects){
46
+ if (visited.has(configFile)) continue;
47
+ visited.add(configFile);
48
+ inputs.add(configFile);
49
+ const config = JSON.parse(await this.run([
50
+ '--showConfig',
51
+ '--project',
52
+ configFile
53
+ ]));
54
+ const directory = node_path.dirname(configFile);
55
+ for (const file of config.files ?? [])inputs.add(node_path.resolve(directory, file));
56
+ for (const reference of config.references ?? []){
57
+ const target = node_path.resolve(directory, reference.path);
58
+ projects.push('.json' === node_path.extname(target) ? target : node_path.join(target, 'tsconfig.json'));
59
+ }
60
+ }
61
+ return inputs;
62
+ }
63
+ apply(compiler) {
64
+ compiler.hooks.thisCompilation.tap(native_type_checker_name, (compilation)=>{
65
+ compilation.fileDependencies.add(this.options.configFile);
66
+ compilation.hooks.processAssets.tapPromise(native_type_checker_name, async ()=>{
67
+ try {
68
+ for (const file of (await this.watchInputs()))compilation.fileDependencies.add(file);
69
+ await this.check();
70
+ } catch (cause) {
71
+ compilation.errors.push(new Error(cause instanceof Error ? cause.message : String(cause), {
72
+ cause
73
+ }));
74
+ }
75
+ });
76
+ });
77
+ }
78
+ constructor(options){
79
+ this.options = options;
80
+ }
81
+ }
82
+ function configureUltramodernTypeChecker(chain, pluginId, resolveCompiler) {
83
+ if (!chain.plugins.has(pluginId)) return;
84
+ const options = chain.plugin(pluginId).get('args')?.[0];
85
+ const typescript = options?.typescript;
86
+ if (typescript?.tsgo === false) return;
87
+ if (!typescript?.configFile) throw new Error(`${native_type_checker_name} requires the configured TypeScript project.`);
88
+ const configFile = node_path.resolve(typescript.configFile);
89
+ chain.plugin(pluginId).use(UltramodernNativeTypeChecker, [
90
+ {
91
+ build: true === typescript.build,
92
+ compiler: ()=>resolveCompiler(configFile),
93
+ configFile
94
+ }
95
+ ]);
96
+ }
97
+ export { UltramodernNativeTypeChecker, configureUltramodernTypeChecker };
@@ -5,11 +5,8 @@ const BUILD_MARKER_NAMESPACE = 'ultramodern-delivery-unit-release-build-marker:v
5
5
  const PROMOTABLE_SOURCE_REVISION_PATTERN = /^(?:[a-f0-9]{40}|[a-f0-9]{64})$/u;
6
6
  const gitOutput = (workspaceRoot, args)=>{
7
7
  try {
8
- return execFileSync('git', [
9
- '-C',
10
- workspaceRoot,
11
- ...args
12
- ], {
8
+ return execFileSync('git', args, {
9
+ cwd: workspaceRoot,
13
10
  encoding: 'utf8',
14
11
  stdio: [
15
12
  'ignore',
@@ -44,7 +41,7 @@ const resolveUltramodernSourceRevision = (workspaceRoot = process.cwd(), configu
44
41
  ]);
45
42
  const status = gitOutput(gitRoot, [
46
43
  'status',
47
- '--porcelain=v1',
44
+ '--porcelain',
48
45
  '--untracked-files=all'
49
46
  ]);
50
47
  if (!revision || void 0 === status || status.length > 0) return 'workspace';
@@ -10,5 +10,6 @@ export declare const CLOUDFLARE_RUNTIME_TYPE = "cloudflare-module-worker";
10
10
  export declare const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = "module";
11
11
  export declare const CLOUDFLARE_WORKER_PACKAGE_TYPE = "commonjs";
12
12
  export declare const CLOUDFLARE_WORKER_BUNDLE_FORMAT = "commonjs";
13
- export declare const CLOUDFLARE_WORKER_NODE_BUILTINS: readonly ['async_hooks', 'buffer', 'crypto', 'events', 'fs/promises', 'module', 'path', 'process', 'stream', 'string_decoder', 'url', 'util'];
13
+ export declare const CLOUDFLARE_WORKER_NODE_BUILTINS: readonly ['assert', 'assert/strict', 'async_hooks', 'buffer', 'child_process', 'crypto', 'dgram', 'dns', 'domain', 'events', 'fs', 'fs/promises', 'http', 'http2', 'inspector', 'module', 'net', 'os', 'path', 'process', 'readline', 'readline/promises', 'repl', 'sqlite', 'stream', 'stream/consumers', 'stream/promises', 'stream/web', 'string_decoder', 'timers', 'timers/promises', 'tls', 'trace_events', 'tty', 'url', 'util', 'util/types', 'v8', 'vm', 'wasi', 'worker_threads', 'zlib'];
14
+ export declare const CLOUDFLARE_WORKER_PLATFORM_MODULES: readonly ['cloudflare:sockets'];
14
15
  export declare const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS: readonly ['nodejs_compat', 'global_fetch_strictly_public'];
@@ -0,0 +1,15 @@
1
+ import type { Rspack, RspackChain } from '@rsbuild/core';
2
+ export declare class UltramodernNativeTypeChecker {
3
+ private readonly options;
4
+ constructor(options: {
5
+ compiler: () => string;
6
+ configFile: string;
7
+ build: boolean;
8
+ });
9
+ check(): Promise<void>;
10
+ private run;
11
+ private watchInputs;
12
+ apply(compiler: Rspack.Compiler): void;
13
+ }
14
+ /** Preserve project-reference emit contracts in the native Effect compiler. */
15
+ export declare function configureUltramodernTypeChecker(chain: RspackChain, pluginId: string, resolveCompiler: (configFile: string) => string): void;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/solutions/app-tools-extensions"
12
12
  },
13
13
  "license": "MIT",
14
- "version": "3.9.0-ultramodern.3",
14
+ "version": "3.9.0-ultramodern.4",
15
15
  "files": [
16
16
  "dist",
17
17
  "src"
@@ -81,6 +81,11 @@
81
81
  "types": "./dist/types/release-identity.d.ts",
82
82
  "import": "./dist/esm-node/release-identity.mjs",
83
83
  "require": "./dist/cjs/release-identity.js"
84
+ },
85
+ "./native-type-checker": {
86
+ "types": "./dist/types/native-type-checker.d.ts",
87
+ "import": "./dist/esm-node/native-type-checker.mjs",
88
+ "require": "./dist/cjs/native-type-checker.js"
84
89
  }
85
90
  },
86
91
  "typesVersions": {
@@ -98,10 +103,10 @@
98
103
  "@babel/parser": "^8.0.4",
99
104
  "@babel/traverse": "^8.0.4",
100
105
  "@loadable/component": "5.16.7",
101
- "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.3",
102
- "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.3",
103
- "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.3",
104
- "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.3",
106
+ "@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.4",
107
+ "@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.4",
108
+ "@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.4",
109
+ "@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.4",
105
110
  "@swc/helpers": "^0.5.23",
106
111
  "std-env": "4.2.0"
107
112
  },
@@ -10,19 +10,56 @@ export const CLOUDFLARE_RUNTIME_TYPE = 'cloudflare-module-worker';
10
10
  export const CLOUDFLARE_OUTPUT_PACKAGE_TYPE = 'module';
11
11
  export const CLOUDFLARE_WORKER_PACKAGE_TYPE = 'commonjs';
12
12
  export const CLOUDFLARE_WORKER_BUNDLE_FORMAT = 'commonjs';
13
+ // Import availability for the default 2026-06-02 nodejs_compat target.
14
+ // Some modules are runtime-provided stubs whose unsupported operations throw.
13
15
  export const CLOUDFLARE_WORKER_NODE_BUILTINS = [
16
+ 'assert',
17
+ 'assert/strict',
14
18
  'async_hooks',
15
19
  'buffer',
20
+ 'child_process',
16
21
  'crypto',
22
+ 'dgram',
23
+ 'dns',
24
+ 'domain',
17
25
  'events',
26
+ 'fs',
18
27
  'fs/promises',
28
+ 'http',
29
+ 'http2',
30
+ 'inspector',
19
31
  'module',
32
+ 'net',
33
+ 'os',
20
34
  'path',
21
35
  'process',
36
+ 'readline',
37
+ 'readline/promises',
38
+ 'repl',
39
+ 'sqlite',
22
40
  'stream',
41
+ 'stream/consumers',
42
+ 'stream/promises',
43
+ 'stream/web',
23
44
  'string_decoder',
45
+ 'timers',
46
+ 'timers/promises',
47
+ 'tls',
48
+ 'trace_events',
49
+ 'tty',
24
50
  'url',
25
51
  'util',
52
+ 'util/types',
53
+ 'v8',
54
+ 'vm',
55
+ 'wasi',
56
+ 'worker_threads',
57
+ 'zlib',
58
+ ] as const;
59
+ // Platform imports available with the default 2026-06-02 nodejs_compat target.
60
+ // Import availability does not imply support for every Node API operation.
61
+ export const CLOUDFLARE_WORKER_PLATFORM_MODULES = [
62
+ 'cloudflare:sockets',
26
63
  ] as const;
27
64
  export const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS = [
28
65
  'nodejs_compat',
@@ -7,6 +7,7 @@ import traverse, { type NodePath } from '@babel/traverse';
7
7
  import {
8
8
  CLOUDFLARE_WORKER_BUNDLE_DIRECTORY,
9
9
  CLOUDFLARE_WORKER_NODE_BUILTINS,
10
+ CLOUDFLARE_WORKER_PLATFORM_MODULES,
10
11
  } from '../cloudflare-output-contract';
11
12
  import type { CloudflareOutputVerifierIssue, JsonObject } from './issues';
12
13
  import { addIssue } from './issues';
@@ -436,9 +437,10 @@ const getPackageName = (specifier: string) =>
436
437
  ? specifier.split('/').slice(0, 2).join('/')
437
438
  : specifier.split('/')[0];
438
439
 
439
- const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set(
440
- CLOUDFLARE_WORKER_NODE_BUILTINS.map(builtin => `node:${builtin}`),
441
- );
440
+ const CLOUDFLARE_WORKER_NODE_BUILTIN_SPECIFIERS = new Set([
441
+ ...CLOUDFLARE_WORKER_NODE_BUILTINS.map(builtin => `node:${builtin}`),
442
+ ...CLOUDFLARE_WORKER_PLATFORM_MODULES,
443
+ ]);
442
444
 
443
445
  const isInsideDirectory = (directory: string, filePath: string) => {
444
446
  const relative = path.relative(directory, filePath);
@@ -0,0 +1,114 @@
1
+ import { execFile } from 'node:child_process';
2
+ import path from 'node:path';
3
+ import { promisify } from 'node:util';
4
+ import type { Rspack, RspackChain } from '@rsbuild/core';
5
+
6
+ const execute = promisify(execFile);
7
+ const name = 'UltramodernNativeTypeChecker';
8
+
9
+ export class UltramodernNativeTypeChecker {
10
+ constructor(
11
+ private readonly options: {
12
+ compiler: () => string;
13
+ configFile: string;
14
+ build: boolean;
15
+ },
16
+ ) {}
17
+
18
+ async check(): Promise<void> {
19
+ const { configFile, build } = this.options;
20
+ const args = build
21
+ ? ['--build', configFile, '--stopBuildOnErrors']
22
+ : ['--project', configFile, '--noEmit'];
23
+ await this.run([...args, '--pretty', 'false']);
24
+ }
25
+
26
+ private async run(args: string[]): Promise<string> {
27
+ try {
28
+ const result = await execute(this.options.compiler(), args, {
29
+ cwd: path.dirname(this.options.configFile),
30
+ maxBuffer: 16 * 1024 * 1024,
31
+ });
32
+ return result.stdout;
33
+ } catch (cause) {
34
+ const output = cause as { stdout?: string; stderr?: string };
35
+ throw new Error(
36
+ `${name} failed:\n${output.stdout ?? ''}${output.stderr ?? ''}`,
37
+ { cause },
38
+ );
39
+ }
40
+ }
41
+
42
+ private async watchInputs(): Promise<Set<string>> {
43
+ const inputs = new Set<string>();
44
+ const projects = [this.options.configFile];
45
+ const visited = new Set<string>();
46
+ for (const configFile of projects) {
47
+ if (visited.has(configFile)) continue;
48
+ visited.add(configFile);
49
+ inputs.add(configFile);
50
+ const config = JSON.parse(
51
+ await this.run(['--showConfig', '--project', configFile]),
52
+ ) as {
53
+ files?: string[];
54
+ references?: { path: string }[];
55
+ };
56
+ const directory = path.dirname(configFile);
57
+ for (const file of config.files ?? [])
58
+ inputs.add(path.resolve(directory, file));
59
+ for (const reference of config.references ?? []) {
60
+ const target = path.resolve(directory, reference.path);
61
+ projects.push(
62
+ path.extname(target) === '.json'
63
+ ? target
64
+ : path.join(target, 'tsconfig.json'),
65
+ );
66
+ }
67
+ }
68
+ return inputs;
69
+ }
70
+
71
+ apply(compiler: Rspack.Compiler): void {
72
+ compiler.hooks.thisCompilation.tap(name, compilation => {
73
+ compilation.fileDependencies.add(this.options.configFile);
74
+ compilation.hooks.processAssets.tapPromise(name, async () => {
75
+ try {
76
+ for (const file of await this.watchInputs())
77
+ compilation.fileDependencies.add(file);
78
+ await this.check();
79
+ } catch (cause) {
80
+ compilation.errors.push(
81
+ new Error(cause instanceof Error ? cause.message : String(cause), {
82
+ cause,
83
+ }),
84
+ );
85
+ }
86
+ });
87
+ });
88
+ }
89
+ }
90
+
91
+ /** Preserve project-reference emit contracts in the native Effect compiler. */
92
+ export function configureUltramodernTypeChecker(
93
+ chain: RspackChain,
94
+ pluginId: string,
95
+ resolveCompiler: (configFile: string) => string,
96
+ ): void {
97
+ if (!chain.plugins.has(pluginId)) return;
98
+ const options = chain.plugin(pluginId).get('args')?.[0] as
99
+ | { typescript?: { configFile?: string; build?: boolean; tsgo?: boolean } }
100
+ | undefined;
101
+ const typescript = options?.typescript;
102
+ if (typescript?.tsgo === false) return;
103
+ if (!typescript?.configFile) {
104
+ throw new Error(`${name} requires the configured TypeScript project.`);
105
+ }
106
+ const configFile = path.resolve(typescript.configFile);
107
+ chain.plugin(pluginId).use(UltramodernNativeTypeChecker, [
108
+ {
109
+ build: typescript.build === true,
110
+ compiler: () => resolveCompiler(configFile),
111
+ configFile,
112
+ },
113
+ ]);
114
+ }
@@ -15,7 +15,8 @@ const gitOutput = (
15
15
  args: string[],
16
16
  ): string | undefined => {
17
17
  try {
18
- return execFileSync('git', ['-C', workspaceRoot, ...args], {
18
+ return execFileSync('git', args, {
19
+ cwd: workspaceRoot,
19
20
  encoding: 'utf8',
20
21
  stdio: ['ignore', 'pipe', 'ignore'],
21
22
  }).trim();
@@ -84,7 +85,7 @@ export const resolveUltramodernSourceRevision = (
84
85
  const revision = gitOutput(gitRoot, ['rev-parse', 'HEAD']);
85
86
  const status = gitOutput(gitRoot, [
86
87
  'status',
87
- '--porcelain=v1',
88
+ '--porcelain',
88
89
  '--untracked-files=all',
89
90
  ]);
90
91
  if (!revision || status === undefined || status.length > 0) {