@bleedingdev/modern-js-server-utils 3.8.3-ultramodern.1 → 3.8.3-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.
@@ -27,206 +27,115 @@ var __webpack_require__ = {};
27
27
  })();
28
28
  var __webpack_exports__ = {};
29
29
  __webpack_require__.r(__webpack_exports__);
30
- const IDENTIFIER_CHAR = /[A-Za-z0-9_$]/;
31
- const WHITESPACE = /\s/;
32
- const KEYWORDS_BEFORE_REGEX = new Set([
33
- 'return',
34
- 'typeof',
35
- 'instanceof',
36
- 'in',
37
- 'of',
38
- 'new',
39
- 'delete',
40
- 'void',
41
- 'throw',
42
- 'case',
43
- 'do',
44
- 'else',
45
- 'yield',
46
- 'await'
47
- ]);
48
- const PUNCTUATORS_BEFORE_REGEX = new Set('{}(,;[=:?!&|+-*%^~<>/');
49
- const isRegexAllowed = (lastToken)=>{
50
- if (!lastToken) return true;
51
- if (KEYWORDS_BEFORE_REGEX.has(lastToken)) return true;
52
- return 1 === lastToken.length && PUNCTUATORS_BEFORE_REGEX.has(lastToken);
30
+ __webpack_require__.d(__webpack_exports__, {
31
+ assertNoNativeModuleOutputCollision: ()=>assertNoNativeModuleOutputCollision,
32
+ rewriteImportSpecifiers: ()=>rewriteImportSpecifiers
33
+ });
34
+ const core_namespaceObject = require("@swc/core");
35
+ const assertNoNativeModuleOutputCollision = (sourceFile, fileExists)=>{
36
+ const rawModuleFile = sourceFile.endsWith('.mts') ? `${sourceFile.slice(0, -4)}.mjs` : sourceFile.endsWith('.cts') ? `${sourceFile.slice(0, -4)}.cjs` : void 0;
37
+ if (rawModuleFile && fileExists(rawModuleFile)) throw new Error(`Native module sources collide: "${sourceFile}" and "${rawModuleFile}" publish the same output.`);
53
38
  };
54
- const isSpecifierContext = (prev1, prev2, prev3)=>{
55
- if (('from' === prev1 || 'import' === prev1) && '.' !== prev2) return true;
56
- return '(' === prev1 && ('import' === prev2 || 'require' === prev2) && '.' !== prev3;
39
+ const isObjectRecord = (value)=>'object' == typeof value && null !== value;
40
+ const isAstNode = (value)=>isObjectRecord(value) && 'string' == typeof value.type;
41
+ const isStringLiteral = (value)=>isAstNode(value) && 'StringLiteral' === value.type && 'string' == typeof value.value && 'object' == typeof value.span && null !== value.span && 'number' == typeof value.span.start && 'number' == typeof value.span.end;
42
+ const getCallSpecifier = (node)=>{
43
+ if ('CallExpression' !== node.type || !Array.isArray(node.arguments)) return;
44
+ const callee = node.callee;
45
+ const isDynamicImport = isAstNode(callee) && 'Import' === callee.type;
46
+ const isCommonJsRequire = isAstNode(callee) && 'Identifier' === callee.type && 'require' === callee.value;
47
+ if (!isDynamicImport && !isCommonJsRequire) return;
48
+ const firstArgument = node.arguments[0];
49
+ if (!isObjectRecord(firstArgument)) return;
50
+ return isStringLiteral(firstArgument.expression) ? firstArgument.expression : void 0;
57
51
  };
58
- const isCallSpecifierContext = (prev1, prev2, prev3)=>'(' === prev1 && ('import' === prev2 || 'require' === prev2) && '.' !== prev3;
59
- const nextNonTriviaChar = (content, start)=>{
60
- let i = start;
61
- while(i < content.length){
62
- if (WHITESPACE.test(content[i])) {
63
- i++;
64
- continue;
65
- }
66
- if ('/' === content[i] && '/' === content[i + 1]) {
67
- const newline = content.indexOf('\n', i + 2);
68
- i = -1 === newline ? content.length : newline + 1;
69
- continue;
70
- }
71
- if ('/' === content[i] && '*' === content[i + 1]) {
72
- const end = content.indexOf('*/', i + 2);
73
- i = -1 === end ? content.length : end + 2;
74
- continue;
52
+ const collectSpecifierLiterals = (content)=>{
53
+ const parserOptions = {
54
+ decorators: true,
55
+ syntax: "typescript",
56
+ target: 'esnext'
57
+ };
58
+ let program;
59
+ try {
60
+ program = (0, core_namespaceObject.parseSync)(content, parserOptions);
61
+ } catch (typescriptError) {
62
+ try {
63
+ program = (0, core_namespaceObject.parseSync)(content, {
64
+ ...parserOptions,
65
+ tsx: true
66
+ });
67
+ } catch {
68
+ throw typescriptError;
75
69
  }
76
- return content[i];
77
70
  }
78
- return '';
79
- };
80
- const skipRegexLiteral = (content, start)=>{
81
- let i = start + 1;
82
- let inClass = false;
83
- while(i < content.length){
84
- const ch = content[i];
85
- if ('\\' === ch) {
86
- i += 2;
87
- continue;
71
+ const literals = [];
72
+ const seenSpans = new Set();
73
+ const add = (value)=>{
74
+ if (!isStringLiteral(value)) return;
75
+ const spanKey = `${value.span.start}:${value.span.end}`;
76
+ if (!seenSpans.has(spanKey)) {
77
+ seenSpans.add(spanKey);
78
+ literals.push(value);
88
79
  }
89
- if ('\n' === ch) break;
90
- if ('[' === ch) inClass = true;
91
- else if (']' === ch) inClass = false;
92
- else if ('/' === ch && !inClass) {
93
- i++;
94
- while(i < content.length && IDENTIFIER_CHAR.test(content[i]))i++;
95
- break;
80
+ };
81
+ const visit = (value)=>{
82
+ if (Array.isArray(value)) return void value.forEach(visit);
83
+ if (!isObjectRecord(value)) return;
84
+ if (isAstNode(value)) switch(value.type){
85
+ case 'ImportDeclaration':
86
+ case 'ExportAllDeclaration':
87
+ case 'ExportNamedDeclaration':
88
+ add(value.source);
89
+ break;
90
+ case 'TsImportType':
91
+ add(value.argument);
92
+ break;
93
+ case 'TsExternalModuleReference':
94
+ add(value.expression);
95
+ break;
96
+ case 'CallExpression':
97
+ add(getCallSpecifier(value));
98
+ break;
96
99
  }
97
- i++;
100
+ for (const [key, child] of Object.entries(value))if ('span' !== key) visit(child);
101
+ };
102
+ visit(program);
103
+ return literals.sort((left, right)=>left.span.start - right.span.start);
104
+ };
105
+ const mapUtf8ByteOffsets = (content, byteOffsets)=>{
106
+ const pending = new Set(byteOffsets);
107
+ const result = new Map();
108
+ let byteOffset = 0;
109
+ let stringOffset = 0;
110
+ while(stringOffset <= content.length && pending.size > 0){
111
+ if (pending.delete(byteOffset)) result.set(byteOffset, stringOffset);
112
+ if (stringOffset === content.length) break;
113
+ const codePoint = content.codePointAt(stringOffset);
114
+ if (void 0 === codePoint) break;
115
+ const character = String.fromCodePoint(codePoint);
116
+ byteOffset += Buffer.byteLength(character);
117
+ stringOffset += character.length;
98
118
  }
99
- return i;
119
+ if (pending.size > 0) throw new Error('SWC returned an import specifier span outside its source');
120
+ return result;
100
121
  };
101
122
  const scanSpecifiers = (content)=>{
102
- const specifiers = [];
103
- const length = content.length;
104
- const templateExpressionDepths = [];
105
- let prev1 = '';
106
- let prev2 = '';
107
- let prev3 = '';
108
- const pushToken = (token)=>{
109
- prev3 = prev2;
110
- prev2 = prev1;
111
- prev1 = token;
112
- };
113
- let mode = 'code';
114
- let i = 0;
115
- while(i < length){
116
- const ch = content[i];
117
- if ('template' === mode) {
118
- if ('\\' === ch) {
119
- i += 2;
120
- continue;
121
- }
122
- if ('`' === ch) {
123
- mode = 'code';
124
- pushToken('`');
125
- i++;
126
- continue;
127
- }
128
- if ('$' === ch && '{' === content[i + 1]) {
129
- templateExpressionDepths.push(0);
130
- mode = 'code';
131
- pushToken('{');
132
- i += 2;
133
- continue;
134
- }
135
- i++;
136
- continue;
137
- }
138
- if (WHITESPACE.test(ch)) {
139
- i++;
140
- continue;
141
- }
142
- if ('/' === ch) {
143
- const next = content[i + 1];
144
- if ('/' === next) {
145
- const newline = content.indexOf('\n', i + 2);
146
- i = -1 === newline ? length : newline + 1;
147
- continue;
148
- }
149
- if ('*' === next) {
150
- const end = content.indexOf('*/', i + 2);
151
- i = -1 === end ? length : end + 2;
152
- continue;
153
- }
154
- if (isRegexAllowed(prev1)) {
155
- i = skipRegexLiteral(content, i);
156
- pushToken('/regex/');
157
- continue;
158
- }
159
- pushToken('/');
160
- i++;
161
- continue;
162
- }
163
- if ('`' === ch) {
164
- mode = 'template';
165
- i++;
166
- continue;
167
- }
168
- if ('{' === ch) {
169
- if (templateExpressionDepths.length > 0) templateExpressionDepths[templateExpressionDepths.length - 1]++;
170
- pushToken('{');
171
- i++;
172
- continue;
173
- }
174
- if ('}' === ch) {
175
- if (templateExpressionDepths.length > 0) {
176
- const top = templateExpressionDepths.length - 1;
177
- if (0 === templateExpressionDepths[top]) {
178
- templateExpressionDepths.pop();
179
- mode = 'template';
180
- i++;
181
- continue;
182
- }
183
- templateExpressionDepths[top]--;
184
- }
185
- pushToken('}');
186
- i++;
187
- continue;
188
- }
189
- if ('"' === ch || "'" === ch) {
190
- const start = i;
191
- let j = i + 1;
192
- let terminated = false;
193
- while(j < length){
194
- const sch = content[j];
195
- if ('\\' === sch) {
196
- j += 2;
197
- continue;
198
- }
199
- if (sch === ch) {
200
- terminated = true;
201
- j++;
202
- break;
203
- }
204
- if ('\n' === sch) break;
205
- j++;
206
- }
207
- const callSpecifier = isCallSpecifierContext(prev1, prev2, prev3);
208
- const nextChar = callSpecifier ? nextNonTriviaChar(content, j) : '';
209
- const isCompleteCallSpecifier = !callSpecifier || ')' === nextChar || ',' === nextChar;
210
- if (terminated && isSpecifierContext(prev1, prev2, prev3) && isCompleteCallSpecifier) specifiers.push({
211
- start: start + 1,
212
- end: j - 1,
213
- value: content.slice(start + 1, j - 1)
214
- });
215
- pushToken('"string"');
216
- i = j;
217
- continue;
218
- }
219
- if (IDENTIFIER_CHAR.test(ch)) {
220
- let j = i + 1;
221
- while(j < length && IDENTIFIER_CHAR.test(content[j]))j++;
222
- pushToken(content.slice(i, j));
223
- i = j;
224
- continue;
225
- }
226
- pushToken(ch);
227
- i++;
228
- }
229
- return specifiers;
123
+ const literals = collectSpecifierLiterals(content);
124
+ const byteOffsets = literals.flatMap((literal)=>[
125
+ literal.span.start,
126
+ literal.span.end - 2
127
+ ]);
128
+ const stringOffsets = mapUtf8ByteOffsets(content, byteOffsets);
129
+ return literals.map((literal)=>{
130
+ const start = stringOffsets.get(literal.span.start);
131
+ const end = stringOffsets.get(literal.span.end - 2);
132
+ if (void 0 === start || void 0 === end) throw new Error('Could not locate an SWC import specifier in its source');
133
+ return {
134
+ start,
135
+ end,
136
+ value: content.slice(start, end)
137
+ };
138
+ });
230
139
  };
231
140
  const rewriteImportSpecifiers = (content, rewrite)=>{
232
141
  const specifiers = scanSpecifiers(content);
@@ -255,11 +164,10 @@ const rewriteImportSpecifiers = (content, rewrite)=>{
255
164
  changed: true
256
165
  };
257
166
  };
258
- __webpack_require__.d(__webpack_exports__, {}, {
259
- rewriteImportSpecifiers: rewriteImportSpecifiers
260
- });
167
+ exports.assertNoNativeModuleOutputCollision = __webpack_exports__.assertNoNativeModuleOutputCollision;
261
168
  exports.rewriteImportSpecifiers = __webpack_exports__.rewriteImportSpecifiers;
262
169
  for(var __rspack_i in __webpack_exports__)if (-1 === [
170
+ "assertNoNativeModuleOutputCollision",
263
171
  "rewriteImportSpecifiers"
264
172
  ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
265
173
  Object.defineProperty(exports, '__esModule', {
@@ -53,12 +53,7 @@ const copyFiles = async (from, to, appDirectory)=>{
53
53
  const relativePath = external_path_default().relative(appDirectory, from);
54
54
  const targetDir = external_path_default().join(to, relativePath);
55
55
  await utils_namespaceObject.fs.copy(from, targetDir, {
56
- filter: (src)=>![
57
- '.ts',
58
- '.tsx',
59
- '.js',
60
- '.jsx'
61
- ].includes(external_path_default().extname(src)) && !src.endsWith('tsconfig.json')
56
+ filter: (src)=>!/\.(?:[cm]?ts|tsx|jsx?)$/u.test(src) && !src.endsWith('tsconfig.json')
62
57
  });
63
58
  }
64
59
  };
@@ -155,7 +150,7 @@ const runTsgo = (tsgoBinPath, args, options)=>new Promise((resolve, reject)=>{
155
150
  });
156
151
  const getTsgoBinEntry = (pkg)=>{
157
152
  if ('string' == typeof pkg.bin) return pkg.bin;
158
- return pkg.bin?.tsgo;
153
+ return pkg.bin?.tsc ?? pkg.bin?.tsgo;
159
154
  };
160
155
  const resolveTsgoBinPath = (pkgPath)=>{
161
156
  const pkgDir = external_path_default().dirname(pkgPath);
@@ -172,12 +167,19 @@ const getTsgoBinPath = (appDirectory, resolvePaths = [
172
167
  __dirname
173
168
  ])=>{
174
169
  try {
175
- const pkgPath = require.resolve("@typescript/native-preview/package.json", {
176
- paths: resolvePaths
177
- });
170
+ let pkgPath;
171
+ try {
172
+ pkgPath = require.resolve("@typescript/native/package.json", {
173
+ paths: resolvePaths
174
+ });
175
+ } catch {
176
+ pkgPath = require.resolve("@typescript/native-preview/package.json", {
177
+ paths: resolvePaths
178
+ });
179
+ }
178
180
  return resolveTsgoBinPath(pkgPath);
179
181
  } catch {
180
- throw new Error('tsgo could not be found! Please install "@typescript/native-preview" in your project to compile BFF/server code.');
182
+ throw new Error('tsgo could not be found! Please install "@typescript/native" (or legacy "@typescript/native-preview") in your project to compile BFF/server code.');
181
183
  }
182
184
  };
183
185
  const OUTPUT_SOURCE_EXTENSIONS = {
@@ -237,6 +239,7 @@ const rewriteOutputSpecifiers = async (appDirectory, distDir, baseUrl, paths, mo
237
239
  await Promise.all(files.map(async (file)=>{
238
240
  const sourceFile = getSourceFileForOutput(appDirectory, distDir, file);
239
241
  if (!sourceFile) return;
242
+ (0, external_importRewriter_js_namespaceObject.assertNoNativeModuleOutputCollision)(sourceFile, utils_namespaceObject.fs.existsSync);
240
243
  const content = await utils_namespaceObject.fs.readFile(file, 'utf8');
241
244
  const { content: rewritten, changed } = (0, external_importRewriter_js_namespaceObject.rewriteImportSpecifiers)(content, (specifier)=>(0, external_tsconfigPathsPlugin_js_namespaceObject.getNotAliasedPath)(sourceFile, matcher, specifier, moduleType));
242
245
  if (changed) await utils_namespaceObject.fs.writeFile(file, await dropStaleSourceMap(file, rewritten));
@@ -293,6 +296,7 @@ const compileByTs = async (appDirectory, config, compileOptions)=>{
293
296
  } else process.exit(1);
294
297
  }
295
298
  for (const source of sourceDirs)await copyFiles(source, distDir, appDirectory);
299
+ await rewriteOutputSpecifiers(appDirectory, distDir, absoluteBaseUrl, paths, compileOptions.moduleType);
296
300
  utils_namespaceObject.logger.info("TS-Go compile succeed");
297
301
  };
298
302
  exports.compileByTs = __webpack_exports__.compileByTs;
@@ -52,18 +52,47 @@ const toImportSpecifier = (sourceFile, resolvedPath)=>{
52
52
  const relativePath = pathApi.relative(pathApi.dirname(sourceFile), resolvedPath).split(pathApi.sep).join(external_path_default().posix.sep);
53
53
  return '.' === relativePath[0] ? relativePath : `./${relativePath}`;
54
54
  };
55
- const COMPILED_TO_JS_EXTENSIONS = new Set([
56
- '.ts',
57
- '.tsx',
58
- '.js',
59
- '.jsx'
55
+ const SOURCE_TO_OUTPUT_EXTENSION = new Map([
56
+ [
57
+ '.ts',
58
+ '.js'
59
+ ],
60
+ [
61
+ '.tsx',
62
+ '.js'
63
+ ],
64
+ [
65
+ '.js',
66
+ '.js'
67
+ ],
68
+ [
69
+ '.jsx',
70
+ '.js'
71
+ ],
72
+ [
73
+ '.mts',
74
+ '.mjs'
75
+ ],
76
+ [
77
+ '.mjs',
78
+ '.mjs'
79
+ ],
80
+ [
81
+ '.cts',
82
+ '.cjs'
83
+ ],
84
+ [
85
+ '.cjs',
86
+ '.cjs'
87
+ ]
60
88
  ]);
61
89
  const toEsmOutputPath = (resolvedPath)=>{
62
90
  const sourcePath = ((0, utils_namespaceObject.findSourceEntry)(resolvedPath) || resolvedPath).replace(/\\/g, '/');
63
91
  const ext = external_path_default().extname(sourcePath);
64
92
  if (!ext) return `${sourcePath}.js`;
65
- if (!COMPILED_TO_JS_EXTENSIONS.has(ext)) return sourcePath;
66
- return `${sourcePath.slice(0, -ext.length)}.js`;
93
+ const outputExtension = SOURCE_TO_OUTPUT_EXTENSION.get(ext);
94
+ if (!outputExtension) return sourcePath;
95
+ return `${sourcePath.slice(0, -ext.length)}${outputExtension}`;
67
96
  };
68
97
  const resolveRelativeEsmSpecifier = (sourceFile, text)=>{
69
98
  if (!text.startsWith('./') && !text.startsWith('../')) return;
@@ -151,7 +180,7 @@ function getNotAliasedPath(sourceFile, matcher, text, moduleType) {
151
180
  if (packagePath) return text;
152
181
  } catch {}
153
182
  }
154
- if ('module' === moduleType) result = toEsmOutputPath(result);
183
+ if ('module' === moduleType || /\.[cm]ts$/iu.test(result)) result = toEsmOutputPath(result);
155
184
  return toImportSpecifier(sourceFile, result) || './';
156
185
  }
157
186
  exports.createTsconfigPathsMatcher = __webpack_exports__.createTsconfigPathsMatcher;