@soda-gql/common 0.11.10 → 0.11.12
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.
- package/dist/{canonical-id-BJahCcrS.mjs → canonical-id-9alor9gv.mjs} +66 -7
- package/dist/canonical-id-9alor9gv.mjs.map +1 -0
- package/dist/{canonical-id-CgMNOZyn.cjs → canonical-id-DHdeYIsT.cjs} +76 -5
- package/dist/canonical-id-DHdeYIsT.cjs.map +1 -0
- package/dist/canonical-id.cjs +5 -3
- package/dist/canonical-id.d.cts +2 -2
- package/dist/canonical-id.d.mts +2 -2
- package/dist/canonical-id.mjs +3 -3
- package/dist/{index-Cm2Zwk9m.d.cts → index-AqkJhrm3.d.mts} +53 -3
- package/dist/index-AqkJhrm3.d.mts.map +1 -0
- package/dist/index-BCu9PNbZ.d.mts +139 -0
- package/dist/index-BCu9PNbZ.d.mts.map +1 -0
- package/dist/{index-D1tzB3W5.d.cts → index-BMa2_rDb.d.mts} +6 -35
- package/dist/index-BMa2_rDb.d.mts.map +1 -0
- package/dist/index-BMl8pzFY.d.cts +139 -0
- package/dist/index-BMl8pzFY.d.cts.map +1 -0
- package/dist/{index-B424kKYS.d.mts → index-CbQyueYV.d.cts} +6 -35
- package/dist/index-CbQyueYV.d.cts.map +1 -0
- package/dist/{index-CPpVc8Id.d.mts → index-DZSebwar.d.cts} +53 -3
- package/dist/index-DZSebwar.d.cts.map +1 -0
- package/dist/index-Dit86qkX.d.mts.map +1 -1
- package/dist/index.cjs +9 -7
- package/dist/index.d.cts +4 -4
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +4 -4
- package/dist/portable-B3K3IE7E.cjs +239 -0
- package/dist/portable-B3K3IE7E.cjs.map +1 -0
- package/dist/portable-BFrcBOaX.mjs +196 -0
- package/dist/portable-BFrcBOaX.mjs.map +1 -0
- package/dist/portable.cjs +2 -5
- package/dist/portable.d.cts +2 -2
- package/dist/portable.d.mts +2 -2
- package/dist/portable.mjs +2 -2
- package/dist/utils-Rs7YbafF.cjs +431 -0
- package/dist/utils-Rs7YbafF.cjs.map +1 -0
- package/dist/utils-ZCE_eqCf.mjs +371 -0
- package/dist/utils-ZCE_eqCf.mjs.map +1 -0
- package/dist/utils.cjs +4 -1
- package/dist/utils.d.cts +2 -2
- package/dist/utils.d.mts +2 -2
- package/dist/utils.mjs +2 -2
- package/dist/{zod-C_6JfuYV.cjs → zod-DjI3IUH3.cjs} +2 -2
- package/dist/{zod-C_6JfuYV.cjs.map → zod-DjI3IUH3.cjs.map} +1 -1
- package/dist/zod.cjs +1 -1
- package/package.json +1 -1
- package/dist/canonical-id-BJahCcrS.mjs.map +0 -1
- package/dist/canonical-id-CgMNOZyn.cjs.map +0 -1
- package/dist/index-B424kKYS.d.mts.map +0 -1
- package/dist/index-CPpVc8Id.d.mts.map +0 -1
- package/dist/index-Cm2Zwk9m.d.cts.map +0 -1
- package/dist/index-D1tzB3W5.d.cts.map +0 -1
- package/dist/index-Dv8spPt0.d.mts +0 -61
- package/dist/index-Dv8spPt0.d.mts.map +0 -1
- package/dist/index-LaXfl_e_.d.cts +0 -61
- package/dist/index-LaXfl_e_.d.cts.map +0 -1
- package/dist/portable-BT3ahkQN.mjs +0 -391
- package/dist/portable-BT3ahkQN.mjs.map +0 -1
- package/dist/portable-cJqkfeHw.cjs +0 -451
- package/dist/portable-cJqkfeHw.cjs.map +0 -1
- package/dist/utils-CsTwS1dw.cjs +0 -148
- package/dist/utils-CsTwS1dw.cjs.map +0 -1
- package/dist/utils-DLEgAn7q.mjs +0 -106
- package/dist/utils-DLEgAn7q.mjs.map +0 -1
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
const require_canonical_id = require('./canonical-id-DHdeYIsT.cjs');
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
|
+
let neverthrow = require("neverthrow");
|
|
5
|
+
|
|
6
|
+
//#region packages/common/src/utils/path.ts
|
|
7
|
+
/**
|
|
8
|
+
* File extensions to try when resolving module specifiers.
|
|
9
|
+
* Ordered to match TypeScript's module resolution order.
|
|
10
|
+
* @see https://www.typescriptlang.org/docs/handbook/module-resolution.html
|
|
11
|
+
*/
|
|
12
|
+
const MODULE_EXTENSION_CANDIDATES = [
|
|
13
|
+
".ts",
|
|
14
|
+
".tsx",
|
|
15
|
+
".mts",
|
|
16
|
+
".cts",
|
|
17
|
+
".js",
|
|
18
|
+
".mjs",
|
|
19
|
+
".cjs",
|
|
20
|
+
".jsx"
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Mapping from JS extensions to their corresponding TS extensions.
|
|
24
|
+
* Used for ESM-style imports where .js is written but .ts is the actual source.
|
|
25
|
+
*/
|
|
26
|
+
const JS_TO_TS_EXTENSION_MAP = {
|
|
27
|
+
".js": [".ts", ".tsx"],
|
|
28
|
+
".mjs": [".mts"],
|
|
29
|
+
".cjs": [".cts"],
|
|
30
|
+
".jsx": [".tsx"]
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Parse a JS extension from a specifier for ESM-style import resolution.
|
|
34
|
+
* Returns the base path (without extension), the JS extension, and corresponding TS extensions.
|
|
35
|
+
*
|
|
36
|
+
* @param specifier - The import specifier to parse
|
|
37
|
+
* @returns Object with base, jsExtension, and tsExtensions, or null if no JS extension found
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* parseJsExtension("./foo.js") // { base: "./foo", jsExtension: ".js", tsExtensions: [".ts", ".tsx"] }
|
|
41
|
+
* parseJsExtension("./foo.mjs") // { base: "./foo", jsExtension: ".mjs", tsExtensions: [".mts"] }
|
|
42
|
+
* parseJsExtension("./foo") // null
|
|
43
|
+
* parseJsExtension("./foo.ts") // null
|
|
44
|
+
*/
|
|
45
|
+
const parseJsExtension = (specifier) => {
|
|
46
|
+
for (const [ext, tsExts] of Object.entries(JS_TO_TS_EXTENSION_MAP)) {
|
|
47
|
+
if (specifier.endsWith(ext)) {
|
|
48
|
+
return {
|
|
49
|
+
base: specifier.slice(0, -ext.length),
|
|
50
|
+
jsExtension: ext,
|
|
51
|
+
tsExtensions: tsExts
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Normalize path to use forward slashes (cross-platform).
|
|
59
|
+
* Ensures consistent path handling across platforms.
|
|
60
|
+
*/
|
|
61
|
+
const normalizePath = (value) => (0, node_path.normalize)(value).replace(/\\/g, "/");
|
|
62
|
+
/**
|
|
63
|
+
* Resolve a relative import specifier to an absolute file path.
|
|
64
|
+
* Tries the specifier as-is, with extensions, and as a directory with index files.
|
|
65
|
+
*
|
|
66
|
+
* @param from - Absolute path to the importing file
|
|
67
|
+
* @param specifier - Relative module specifier (must start with '.')
|
|
68
|
+
* @returns Absolute POSIX path to the resolved file, or null if not found
|
|
69
|
+
*/
|
|
70
|
+
const resolveRelativeImportWithExistenceCheck = ({ filePath, specifier }) => {
|
|
71
|
+
const jsExtInfo = parseJsExtension(specifier);
|
|
72
|
+
if (jsExtInfo) {
|
|
73
|
+
const baseWithoutExt = (0, node_path.resolve)((0, node_path.dirname)(filePath), jsExtInfo.base);
|
|
74
|
+
for (const ext of jsExtInfo.tsExtensions) {
|
|
75
|
+
const candidate = `${baseWithoutExt}${ext}`;
|
|
76
|
+
if ((0, node_fs.existsSync)(candidate)) {
|
|
77
|
+
return normalizePath(candidate);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const jsCandidate = `${baseWithoutExt}${jsExtInfo.jsExtension}`;
|
|
81
|
+
if ((0, node_fs.existsSync)(jsCandidate)) {
|
|
82
|
+
try {
|
|
83
|
+
const stat = (0, node_fs.statSync)(jsCandidate);
|
|
84
|
+
if (stat.isFile()) {
|
|
85
|
+
return normalizePath(jsCandidate);
|
|
86
|
+
}
|
|
87
|
+
} catch {}
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const base = (0, node_path.resolve)((0, node_path.dirname)(filePath), specifier);
|
|
92
|
+
for (const ext of MODULE_EXTENSION_CANDIDATES) {
|
|
93
|
+
const candidate = `${base}${ext}`;
|
|
94
|
+
if ((0, node_fs.existsSync)(candidate)) {
|
|
95
|
+
return normalizePath(candidate);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const ext of MODULE_EXTENSION_CANDIDATES) {
|
|
99
|
+
const candidate = (0, node_path.join)(base, `index${ext}`);
|
|
100
|
+
if ((0, node_fs.existsSync)(candidate)) {
|
|
101
|
+
return normalizePath(candidate);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if ((0, node_fs.existsSync)(base)) {
|
|
105
|
+
try {
|
|
106
|
+
const stat = (0, node_fs.statSync)(base);
|
|
107
|
+
if (stat.isFile()) {
|
|
108
|
+
return normalizePath(base);
|
|
109
|
+
}
|
|
110
|
+
} catch {}
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Resolve a relative import specifier to an absolute file path.
|
|
116
|
+
* Tries the specifier as-is, with extensions, and as a directory with index files.
|
|
117
|
+
*
|
|
118
|
+
* @param from - Absolute path to the importing file
|
|
119
|
+
* @param specifier - Relative module specifier (must start with '.')
|
|
120
|
+
* @returns Absolute POSIX path to the resolved file, or null if not found
|
|
121
|
+
*/
|
|
122
|
+
const resolveRelativeImportWithReferences = ({ filePath, specifier, references }) => {
|
|
123
|
+
const jsExtInfo = parseJsExtension(specifier);
|
|
124
|
+
if (jsExtInfo) {
|
|
125
|
+
const baseWithoutExt = (0, node_path.resolve)((0, node_path.dirname)(filePath), jsExtInfo.base);
|
|
126
|
+
for (const ext of jsExtInfo.tsExtensions) {
|
|
127
|
+
const candidate = `${baseWithoutExt}${ext}`;
|
|
128
|
+
if (references.has(candidate)) {
|
|
129
|
+
return normalizePath(candidate);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const jsCandidate = `${baseWithoutExt}${jsExtInfo.jsExtension}`;
|
|
133
|
+
if (references.has(jsCandidate)) {
|
|
134
|
+
return normalizePath(jsCandidate);
|
|
135
|
+
}
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const base = (0, node_path.resolve)((0, node_path.dirname)(filePath), specifier);
|
|
139
|
+
if (references.has(base)) {
|
|
140
|
+
return normalizePath(base);
|
|
141
|
+
}
|
|
142
|
+
for (const ext of MODULE_EXTENSION_CANDIDATES) {
|
|
143
|
+
const candidate = `${base}${ext}`;
|
|
144
|
+
if (references.has(candidate)) {
|
|
145
|
+
return normalizePath(candidate);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
for (const ext of MODULE_EXTENSION_CANDIDATES) {
|
|
149
|
+
const candidate = (0, node_path.join)(base, `index${ext}`);
|
|
150
|
+
if (references.has(candidate)) {
|
|
151
|
+
return normalizePath(candidate);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Check if a module specifier is relative (starts with '.' or '..')
|
|
158
|
+
*/
|
|
159
|
+
const isRelativeSpecifier = (specifier) => specifier.startsWith("./") || specifier.startsWith("../");
|
|
160
|
+
/**
|
|
161
|
+
* Check if a module specifier is external (package name, not relative)
|
|
162
|
+
*/
|
|
163
|
+
const isExternalSpecifier = (specifier) => !isRelativeSpecifier(specifier);
|
|
164
|
+
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region packages/common/src/utils/alias-resolver.ts
|
|
167
|
+
/**
|
|
168
|
+
* Match a specifier against a tsconfig path pattern.
|
|
169
|
+
* Returns the captured wildcard portion or null if no match.
|
|
170
|
+
*
|
|
171
|
+
* Pattern rules:
|
|
172
|
+
* - Exact match: "@/utils" matches "@/utils" exactly, captures ""
|
|
173
|
+
* - Wildcard: "@/*" matches "@/foo", captures "foo"
|
|
174
|
+
* - Wildcard with suffix: "*.js" matches "foo.js", captures "foo"
|
|
175
|
+
*/
|
|
176
|
+
const matchPattern = (specifier, pattern) => {
|
|
177
|
+
const starIndex = pattern.indexOf("*");
|
|
178
|
+
if (starIndex === -1) {
|
|
179
|
+
return specifier === pattern ? "" : null;
|
|
180
|
+
}
|
|
181
|
+
const prefix = pattern.slice(0, starIndex);
|
|
182
|
+
const suffix = pattern.slice(starIndex + 1);
|
|
183
|
+
if (!specifier.startsWith(prefix)) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
if (suffix && !specifier.endsWith(suffix)) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const captured = specifier.slice(prefix.length, suffix ? specifier.length - suffix.length : undefined);
|
|
190
|
+
return captured;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Apply a captured wildcard to a target path.
|
|
194
|
+
*/
|
|
195
|
+
const applyCapture = (target, captured) => {
|
|
196
|
+
const starIndex = target.indexOf("*");
|
|
197
|
+
if (starIndex === -1) {
|
|
198
|
+
return target;
|
|
199
|
+
}
|
|
200
|
+
return target.slice(0, starIndex) + captured + target.slice(starIndex + 1);
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Try to resolve a path to an actual file, applying extension resolution.
|
|
204
|
+
* Handles ESM-style imports with JS extensions.
|
|
205
|
+
*/
|
|
206
|
+
const resolveToFile = (basePath) => {
|
|
207
|
+
const jsExtInfo = parseJsExtension(basePath);
|
|
208
|
+
if (jsExtInfo) {
|
|
209
|
+
const baseWithoutExt = basePath.slice(0, -jsExtInfo.jsExtension.length);
|
|
210
|
+
for (const ext of jsExtInfo.tsExtensions) {
|
|
211
|
+
const candidate = `${baseWithoutExt}${ext}`;
|
|
212
|
+
if ((0, node_fs.existsSync)(candidate)) {
|
|
213
|
+
try {
|
|
214
|
+
const stat = (0, node_fs.statSync)(candidate);
|
|
215
|
+
if (stat.isFile()) {
|
|
216
|
+
return normalizePath(candidate);
|
|
217
|
+
}
|
|
218
|
+
} catch {}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if ((0, node_fs.existsSync)(basePath)) {
|
|
222
|
+
try {
|
|
223
|
+
const stat = (0, node_fs.statSync)(basePath);
|
|
224
|
+
if (stat.isFile()) {
|
|
225
|
+
return normalizePath(basePath);
|
|
226
|
+
}
|
|
227
|
+
} catch {}
|
|
228
|
+
}
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
if ((0, node_fs.existsSync)(basePath)) {
|
|
232
|
+
try {
|
|
233
|
+
const stat = (0, node_fs.statSync)(basePath);
|
|
234
|
+
if (stat.isFile()) {
|
|
235
|
+
return normalizePath(basePath);
|
|
236
|
+
}
|
|
237
|
+
} catch {}
|
|
238
|
+
}
|
|
239
|
+
for (const ext of MODULE_EXTENSION_CANDIDATES) {
|
|
240
|
+
const candidate = `${basePath}${ext}`;
|
|
241
|
+
if ((0, node_fs.existsSync)(candidate)) {
|
|
242
|
+
try {
|
|
243
|
+
const stat = (0, node_fs.statSync)(candidate);
|
|
244
|
+
if (stat.isFile()) {
|
|
245
|
+
return normalizePath(candidate);
|
|
246
|
+
}
|
|
247
|
+
} catch {}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
for (const ext of MODULE_EXTENSION_CANDIDATES) {
|
|
251
|
+
const candidate = (0, node_path.join)(basePath, `index${ext}`);
|
|
252
|
+
if ((0, node_fs.existsSync)(candidate)) {
|
|
253
|
+
try {
|
|
254
|
+
const stat = (0, node_fs.statSync)(candidate);
|
|
255
|
+
if (stat.isFile()) {
|
|
256
|
+
return normalizePath(candidate);
|
|
257
|
+
}
|
|
258
|
+
} catch {}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Create an alias resolver from tsconfig paths configuration.
|
|
265
|
+
*
|
|
266
|
+
* Resolution behavior:
|
|
267
|
+
* 1. Try each pattern in order (first match wins per TS spec)
|
|
268
|
+
* 2. For each matched pattern, try all target paths in order
|
|
269
|
+
* 3. For each target, apply extension resolution
|
|
270
|
+
* 4. Return first found file, or null if none found
|
|
271
|
+
*/
|
|
272
|
+
const createAliasResolver = (config) => {
|
|
273
|
+
const { paths } = config;
|
|
274
|
+
const patterns = Object.keys(paths);
|
|
275
|
+
return { resolve: (specifier) => {
|
|
276
|
+
for (const pattern of patterns) {
|
|
277
|
+
const captured = matchPattern(specifier, pattern);
|
|
278
|
+
if (captured === null) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const targets = paths[pattern];
|
|
282
|
+
if (!targets) {
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
for (const target of targets) {
|
|
286
|
+
const resolvedTarget = applyCapture(target, captured);
|
|
287
|
+
const result = resolveToFile(resolvedTarget);
|
|
288
|
+
if (result) {
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
} };
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region packages/common/src/utils/cached-fn.ts
|
|
299
|
+
const cachedFn = (fn) => {
|
|
300
|
+
let cached = null;
|
|
301
|
+
const ensure = () => (cached ??= { value: fn() }).value;
|
|
302
|
+
ensure.clear = () => {
|
|
303
|
+
cached = null;
|
|
304
|
+
};
|
|
305
|
+
return ensure;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region packages/common/src/utils/tsconfig.ts
|
|
310
|
+
/**
|
|
311
|
+
* Strip JSON comments and trailing commas for parsing.
|
|
312
|
+
* Handles both line comments (//) and block comments.
|
|
313
|
+
*/
|
|
314
|
+
const stripJsonComments = (json) => {
|
|
315
|
+
return json.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*/g, "").replace(/,(\s*[}\]])/g, "$1");
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* Read and parse tsconfig.json to extract paths configuration.
|
|
319
|
+
* Currently does not support `extends` - reads only the specified file.
|
|
320
|
+
*
|
|
321
|
+
* @param tsconfigPath - Absolute path to tsconfig.json
|
|
322
|
+
* @returns Parsed paths configuration or null if no paths defined
|
|
323
|
+
*/
|
|
324
|
+
const readTsconfigPaths = (tsconfigPath) => {
|
|
325
|
+
let content;
|
|
326
|
+
try {
|
|
327
|
+
content = (0, node_fs.readFileSync)(tsconfigPath, "utf-8");
|
|
328
|
+
} catch (error) {
|
|
329
|
+
return (0, neverthrow.err)({
|
|
330
|
+
code: "TSCONFIG_READ_FAILED",
|
|
331
|
+
message: `Failed to read tsconfig.json: ${error instanceof Error ? error.message : String(error)}`
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
let parsed;
|
|
335
|
+
try {
|
|
336
|
+
const cleaned = stripJsonComments(content);
|
|
337
|
+
parsed = JSON.parse(cleaned);
|
|
338
|
+
} catch (error) {
|
|
339
|
+
return (0, neverthrow.err)({
|
|
340
|
+
code: "TSCONFIG_PARSE_FAILED",
|
|
341
|
+
message: `Failed to parse tsconfig.json: ${error instanceof Error ? error.message : String(error)}`
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
if (typeof parsed !== "object" || parsed === null) {
|
|
345
|
+
return (0, neverthrow.err)({
|
|
346
|
+
code: "TSCONFIG_INVALID",
|
|
347
|
+
message: "tsconfig.json must be an object"
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
const config = parsed;
|
|
351
|
+
const compilerOptions = config.compilerOptions;
|
|
352
|
+
if (!compilerOptions?.paths) {
|
|
353
|
+
return (0, neverthrow.ok)(null);
|
|
354
|
+
}
|
|
355
|
+
const tsconfigDir = (0, node_path.dirname)(tsconfigPath);
|
|
356
|
+
const baseUrl = typeof compilerOptions.baseUrl === "string" ? (0, node_path.resolve)(tsconfigDir, compilerOptions.baseUrl) : tsconfigDir;
|
|
357
|
+
const rawPaths = compilerOptions.paths;
|
|
358
|
+
const resolvedPaths = {};
|
|
359
|
+
for (const [pattern, targets] of Object.entries(rawPaths)) {
|
|
360
|
+
if (Array.isArray(targets)) {
|
|
361
|
+
resolvedPaths[pattern] = targets.map((target) => (0, node_path.resolve)(baseUrl, target));
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return (0, neverthrow.ok)({
|
|
365
|
+
baseUrl,
|
|
366
|
+
paths: resolvedPaths
|
|
367
|
+
});
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
//#endregion
|
|
371
|
+
Object.defineProperty(exports, 'MODULE_EXTENSION_CANDIDATES', {
|
|
372
|
+
enumerable: true,
|
|
373
|
+
get: function () {
|
|
374
|
+
return MODULE_EXTENSION_CANDIDATES;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
Object.defineProperty(exports, 'cachedFn', {
|
|
378
|
+
enumerable: true,
|
|
379
|
+
get: function () {
|
|
380
|
+
return cachedFn;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
Object.defineProperty(exports, 'createAliasResolver', {
|
|
384
|
+
enumerable: true,
|
|
385
|
+
get: function () {
|
|
386
|
+
return createAliasResolver;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
Object.defineProperty(exports, 'isExternalSpecifier', {
|
|
390
|
+
enumerable: true,
|
|
391
|
+
get: function () {
|
|
392
|
+
return isExternalSpecifier;
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
Object.defineProperty(exports, 'isRelativeSpecifier', {
|
|
396
|
+
enumerable: true,
|
|
397
|
+
get: function () {
|
|
398
|
+
return isRelativeSpecifier;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
Object.defineProperty(exports, 'normalizePath', {
|
|
402
|
+
enumerable: true,
|
|
403
|
+
get: function () {
|
|
404
|
+
return normalizePath;
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
Object.defineProperty(exports, 'parseJsExtension', {
|
|
408
|
+
enumerable: true,
|
|
409
|
+
get: function () {
|
|
410
|
+
return parseJsExtension;
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
Object.defineProperty(exports, 'readTsconfigPaths', {
|
|
414
|
+
enumerable: true,
|
|
415
|
+
get: function () {
|
|
416
|
+
return readTsconfigPaths;
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
Object.defineProperty(exports, 'resolveRelativeImportWithExistenceCheck', {
|
|
420
|
+
enumerable: true,
|
|
421
|
+
get: function () {
|
|
422
|
+
return resolveRelativeImportWithExistenceCheck;
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
Object.defineProperty(exports, 'resolveRelativeImportWithReferences', {
|
|
426
|
+
enumerable: true,
|
|
427
|
+
get: function () {
|
|
428
|
+
return resolveRelativeImportWithReferences;
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
//# sourceMappingURL=utils-Rs7YbafF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-Rs7YbafF.cjs","names":["JS_TO_TS_EXTENSION_MAP: Readonly<Record<string, readonly string[]>>","cached: { value: T } | null","content: string","parsed: unknown","resolvedPaths: Record<string, readonly string[]>"],"sources":["../src/utils/path.ts","../src/utils/alias-resolver.ts","../src/utils/cached-fn.ts","../src/utils/tsconfig.ts"],"sourcesContent":["import { existsSync, statSync } from \"node:fs\";\nimport { dirname, join, normalize, resolve } from \"node:path\";\n\n/**\n * File extensions to try when resolving module specifiers.\n * Ordered to match TypeScript's module resolution order.\n * @see https://www.typescriptlang.org/docs/handbook/module-resolution.html\n */\nexport const MODULE_EXTENSION_CANDIDATES = [\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".mjs\", \".cjs\", \".jsx\"] as const;\n\n/**\n * Mapping from JS extensions to their corresponding TS extensions.\n * Used for ESM-style imports where .js is written but .ts is the actual source.\n */\nconst JS_TO_TS_EXTENSION_MAP: Readonly<Record<string, readonly string[]>> = {\n \".js\": [\".ts\", \".tsx\"],\n \".mjs\": [\".mts\"],\n \".cjs\": [\".cts\"],\n \".jsx\": [\".tsx\"],\n};\n\n/**\n * Result of parsing a JS extension from a specifier.\n */\nexport type JsExtensionInfo = {\n /** The specifier without the JS extension */\n readonly base: string;\n /** The JS extension found (e.g., \".js\", \".mjs\") */\n readonly jsExtension: string;\n /** The corresponding TS extensions to try (e.g., [\".ts\", \".tsx\"] for \".js\") */\n readonly tsExtensions: readonly string[];\n};\n\n/**\n * Parse a JS extension from a specifier for ESM-style import resolution.\n * Returns the base path (without extension), the JS extension, and corresponding TS extensions.\n *\n * @param specifier - The import specifier to parse\n * @returns Object with base, jsExtension, and tsExtensions, or null if no JS extension found\n *\n * @example\n * parseJsExtension(\"./foo.js\") // { base: \"./foo\", jsExtension: \".js\", tsExtensions: [\".ts\", \".tsx\"] }\n * parseJsExtension(\"./foo.mjs\") // { base: \"./foo\", jsExtension: \".mjs\", tsExtensions: [\".mts\"] }\n * parseJsExtension(\"./foo\") // null\n * parseJsExtension(\"./foo.ts\") // null\n */\nexport const parseJsExtension = (specifier: string): JsExtensionInfo | null => {\n for (const [ext, tsExts] of Object.entries(JS_TO_TS_EXTENSION_MAP)) {\n if (specifier.endsWith(ext)) {\n return {\n base: specifier.slice(0, -ext.length),\n jsExtension: ext,\n tsExtensions: tsExts,\n };\n }\n }\n return null;\n};\n\n/**\n * Normalize path to use forward slashes (cross-platform).\n * Ensures consistent path handling across platforms.\n */\nexport const normalizePath = (value: string): string => normalize(value).replace(/\\\\/g, \"/\");\n\n/**\n * Resolve a relative import specifier to an absolute file path.\n * Tries the specifier as-is, with extensions, and as a directory with index files.\n *\n * @param from - Absolute path to the importing file\n * @param specifier - Relative module specifier (must start with '.')\n * @returns Absolute POSIX path to the resolved file, or null if not found\n */\nexport const resolveRelativeImportWithExistenceCheck = ({\n filePath,\n specifier,\n}: {\n filePath: string;\n specifier: string;\n}): string | null => {\n // Handle ESM-style imports with JS extensions (e.g., \"./foo.js\" -> \"./foo.ts\")\n const jsExtInfo = parseJsExtension(specifier);\n if (jsExtInfo) {\n const baseWithoutExt = resolve(dirname(filePath), jsExtInfo.base);\n\n // Try corresponding TS extensions first\n for (const ext of jsExtInfo.tsExtensions) {\n const candidate = `${baseWithoutExt}${ext}`;\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Fall back to actual JS file if it exists\n const jsCandidate = `${baseWithoutExt}${jsExtInfo.jsExtension}`;\n if (existsSync(jsCandidate)) {\n try {\n const stat = statSync(jsCandidate);\n if (stat.isFile()) {\n return normalizePath(jsCandidate);\n }\n } catch {\n // Ignore stat errors\n }\n }\n\n return null;\n }\n\n const base = resolve(dirname(filePath), specifier);\n\n // Try with extensions first (most common case)\n // This handles cases like \"./constants\" resolving to \"./constants.ts\"\n // even when a \"./constants\" directory exists\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${base}${ext}`;\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(base, `index${ext}`);\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try exact path last (only if it's a file, not directory)\n if (existsSync(base)) {\n try {\n const stat = statSync(base);\n if (stat.isFile()) {\n return normalizePath(base);\n }\n } catch {\n // Ignore stat errors\n }\n }\n\n return null;\n};\n\n/**\n * Resolve a relative import specifier to an absolute file path.\n * Tries the specifier as-is, with extensions, and as a directory with index files.\n *\n * @param from - Absolute path to the importing file\n * @param specifier - Relative module specifier (must start with '.')\n * @returns Absolute POSIX path to the resolved file, or null if not found\n */\nexport const resolveRelativeImportWithReferences = <_>({\n filePath,\n specifier,\n references,\n}: {\n filePath: string;\n specifier: string;\n references: Map<string, _> | Set<string>;\n}): string | null => {\n // Handle ESM-style imports with JS extensions (e.g., \"./foo.js\" -> \"./foo.ts\")\n const jsExtInfo = parseJsExtension(specifier);\n if (jsExtInfo) {\n const baseWithoutExt = resolve(dirname(filePath), jsExtInfo.base);\n\n // Try corresponding TS extensions first\n for (const ext of jsExtInfo.tsExtensions) {\n const candidate = `${baseWithoutExt}${ext}`;\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Fall back to actual JS file if it exists in references\n const jsCandidate = `${baseWithoutExt}${jsExtInfo.jsExtension}`;\n if (references.has(jsCandidate)) {\n return normalizePath(jsCandidate);\n }\n\n return null;\n }\n\n const base = resolve(dirname(filePath), specifier);\n\n // Try exact path first\n if (references.has(base)) {\n return normalizePath(base);\n }\n\n // Try with extensions\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${base}${ext}`;\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(base, `index${ext}`);\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n return null;\n};\n\n/**\n * Check if a module specifier is relative (starts with '.' or '..')\n */\nexport const isRelativeSpecifier = (specifier: string): boolean => specifier.startsWith(\"./\") || specifier.startsWith(\"../\");\n\n/**\n * Check if a module specifier is external (package name, not relative)\n */\nexport const isExternalSpecifier = (specifier: string): boolean => !isRelativeSpecifier(specifier);\n","import { existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { MODULE_EXTENSION_CANDIDATES, normalizePath, parseJsExtension } from \"./path\";\nimport type { TsconfigPathsConfig } from \"./tsconfig\";\n\n/**\n * Alias resolver interface for resolving path aliases to file paths.\n */\nexport type AliasResolver = {\n /**\n * Resolve an alias specifier to an absolute file path.\n * Returns null if the specifier doesn't match any alias pattern\n * or if the resolved file doesn't exist.\n */\n readonly resolve: (specifier: string) => string | null;\n};\n\n/**\n * Match a specifier against a tsconfig path pattern.\n * Returns the captured wildcard portion or null if no match.\n *\n * Pattern rules:\n * - Exact match: \"@/utils\" matches \"@/utils\" exactly, captures \"\"\n * - Wildcard: \"@/*\" matches \"@/foo\", captures \"foo\"\n * - Wildcard with suffix: \"*.js\" matches \"foo.js\", captures \"foo\"\n */\nconst matchPattern = (specifier: string, pattern: string): string | null => {\n const starIndex = pattern.indexOf(\"*\");\n\n if (starIndex === -1) {\n // Exact match - no wildcard\n return specifier === pattern ? \"\" : null;\n }\n\n const prefix = pattern.slice(0, starIndex);\n const suffix = pattern.slice(starIndex + 1);\n\n if (!specifier.startsWith(prefix)) {\n return null;\n }\n\n if (suffix && !specifier.endsWith(suffix)) {\n return null;\n }\n\n // Extract the wildcard capture\n const captured = specifier.slice(prefix.length, suffix ? specifier.length - suffix.length : undefined);\n\n return captured;\n};\n\n/**\n * Apply a captured wildcard to a target path.\n */\nconst applyCapture = (target: string, captured: string): string => {\n const starIndex = target.indexOf(\"*\");\n if (starIndex === -1) {\n return target;\n }\n return target.slice(0, starIndex) + captured + target.slice(starIndex + 1);\n};\n\n/**\n * Try to resolve a path to an actual file, applying extension resolution.\n * Handles ESM-style imports with JS extensions.\n */\nconst resolveToFile = (basePath: string): string | null => {\n // Handle ESM-style JS extension imports\n const jsExtInfo = parseJsExtension(basePath);\n if (jsExtInfo) {\n const baseWithoutExt = basePath.slice(0, -jsExtInfo.jsExtension.length);\n\n // Try corresponding TS extensions first\n for (const ext of jsExtInfo.tsExtensions) {\n const candidate = `${baseWithoutExt}${ext}`;\n if (existsSync(candidate)) {\n try {\n const stat = statSync(candidate);\n if (stat.isFile()) {\n return normalizePath(candidate);\n }\n } catch {\n // Ignore stat errors\n }\n }\n }\n\n // Fall back to actual JS file\n if (existsSync(basePath)) {\n try {\n const stat = statSync(basePath);\n if (stat.isFile()) {\n return normalizePath(basePath);\n }\n } catch {\n // Ignore stat errors\n }\n }\n\n return null;\n }\n\n // Try exact path first (for paths with explicit extension)\n if (existsSync(basePath)) {\n try {\n const stat = statSync(basePath);\n if (stat.isFile()) {\n return normalizePath(basePath);\n }\n } catch {\n // Ignore stat errors\n }\n }\n\n // Try with extensions\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${basePath}${ext}`;\n if (existsSync(candidate)) {\n try {\n const stat = statSync(candidate);\n if (stat.isFile()) {\n return normalizePath(candidate);\n }\n } catch {\n // Ignore stat errors\n }\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(basePath, `index${ext}`);\n if (existsSync(candidate)) {\n try {\n const stat = statSync(candidate);\n if (stat.isFile()) {\n return normalizePath(candidate);\n }\n } catch {\n // Ignore stat errors\n }\n }\n }\n\n return null;\n};\n\n/**\n * Create an alias resolver from tsconfig paths configuration.\n *\n * Resolution behavior:\n * 1. Try each pattern in order (first match wins per TS spec)\n * 2. For each matched pattern, try all target paths in order\n * 3. For each target, apply extension resolution\n * 4. Return first found file, or null if none found\n */\nexport const createAliasResolver = (config: TsconfigPathsConfig): AliasResolver => {\n const { paths } = config;\n const patterns = Object.keys(paths);\n\n return {\n resolve: (specifier: string): string | null => {\n // Try each pattern in order (first match wins per TS spec)\n for (const pattern of patterns) {\n const captured = matchPattern(specifier, pattern);\n if (captured === null) {\n continue;\n }\n\n const targets = paths[pattern];\n if (!targets) {\n continue;\n }\n\n // Try each target path in order\n for (const target of targets) {\n const resolvedTarget = applyCapture(target, captured);\n const result = resolveToFile(resolvedTarget);\n if (result) {\n return result;\n }\n }\n }\n\n return null;\n },\n };\n};\n","export const cachedFn = <T>(fn: () => T) => {\n let cached: { value: T } | null = null;\n\n const ensure = () => (cached ??= { value: fn() }).value;\n ensure.clear = () => {\n cached = null;\n };\n\n return ensure;\n};\n","import { readFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { err, ok, type Result } from \"neverthrow\";\n\n/**\n * Parsed tsconfig.json paths configuration.\n * All paths are resolved to absolute paths.\n */\nexport type TsconfigPathsConfig = {\n /** Absolute base URL for path resolution */\n readonly baseUrl: string;\n /** Path mappings with absolute paths */\n readonly paths: Readonly<Record<string, readonly string[]>>;\n};\n\n/**\n * Error types for tsconfig reading.\n */\nexport type TsconfigReadError = {\n readonly code: \"TSCONFIG_READ_FAILED\" | \"TSCONFIG_PARSE_FAILED\" | \"TSCONFIG_INVALID\";\n readonly message: string;\n};\n\n/**\n * Strip JSON comments and trailing commas for parsing.\n * Handles both line comments (//) and block comments.\n */\nconst stripJsonComments = (json: string): string => {\n return (\n json\n // Remove block comments\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\")\n // Remove line comments\n .replace(/\\/\\/.*/g, \"\")\n // Remove trailing commas before } or ]\n .replace(/,(\\s*[}\\]])/g, \"$1\")\n );\n};\n\n/**\n * Read and parse tsconfig.json to extract paths configuration.\n * Currently does not support `extends` - reads only the specified file.\n *\n * @param tsconfigPath - Absolute path to tsconfig.json\n * @returns Parsed paths configuration or null if no paths defined\n */\nexport const readTsconfigPaths = (tsconfigPath: string): Result<TsconfigPathsConfig | null, TsconfigReadError> => {\n // Read file\n let content: string;\n try {\n content = readFileSync(tsconfigPath, \"utf-8\");\n } catch (error) {\n return err({\n code: \"TSCONFIG_READ_FAILED\",\n message: `Failed to read tsconfig.json: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n\n // Parse JSON (with comment stripping)\n let parsed: unknown;\n try {\n const cleaned = stripJsonComments(content);\n parsed = JSON.parse(cleaned);\n } catch (error) {\n return err({\n code: \"TSCONFIG_PARSE_FAILED\",\n message: `Failed to parse tsconfig.json: ${error instanceof Error ? error.message : String(error)}`,\n });\n }\n\n // Validate structure\n if (typeof parsed !== \"object\" || parsed === null) {\n return err({\n code: \"TSCONFIG_INVALID\",\n message: \"tsconfig.json must be an object\",\n });\n }\n\n const config = parsed as Record<string, unknown>;\n const compilerOptions = config.compilerOptions as Record<string, unknown> | undefined;\n\n // Return null if no paths defined\n if (!compilerOptions?.paths) {\n return ok(null);\n }\n\n // Resolve baseUrl\n const tsconfigDir = dirname(tsconfigPath);\n const baseUrl = typeof compilerOptions.baseUrl === \"string\" ? resolve(tsconfigDir, compilerOptions.baseUrl) : tsconfigDir;\n\n // Resolve paths to absolute paths\n const rawPaths = compilerOptions.paths as Record<string, string[]>;\n const resolvedPaths: Record<string, readonly string[]> = {};\n\n for (const [pattern, targets] of Object.entries(rawPaths)) {\n if (Array.isArray(targets)) {\n resolvedPaths[pattern] = targets.map((target) => resolve(baseUrl, target));\n }\n }\n\n return ok({\n baseUrl,\n paths: resolvedPaths,\n });\n};\n"],"mappings":"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"}
|