@plumeria/utils 19.2.2 → 19.2.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.
@@ -119,14 +119,20 @@ const cssUnits = [
119
119
  'svh',
120
120
  'svmin',
121
121
  'svmax',
122
+ 'svb',
123
+ 'svi',
122
124
  'lvw',
123
125
  'lvh',
124
126
  'lvmin',
125
127
  'lvmax',
128
+ 'lvb',
129
+ 'lvi',
126
130
  'dvw',
127
131
  'dvh',
128
132
  'dvmin',
129
133
  'dvmax',
134
+ 'dvb',
135
+ 'dvi',
130
136
  'cqw',
131
137
  'cqh',
132
138
  'cqi',
package/dist/resolver.js CHANGED
@@ -37,41 +37,240 @@ exports.resetImportResolutionCache = resetImportResolutionCache;
37
37
  exports.resolveImportPath = resolveImportPath;
38
38
  const fs = __importStar(require("fs"));
39
39
  const path = __importStar(require("path"));
40
- let cachedTsConfig = undefined;
41
- function resetImportResolutionCache(cwd = process.cwd()) {
42
- const configPath = path.join(cwd, 'tsconfig.json');
40
+ const CONFIG_DIR = '${configDir}';
41
+ let cachedPathsMatcher = undefined;
42
+ function stripComments(text) {
43
+ let out = '';
44
+ let inString = false;
45
+ for (let i = 0; i < text.length; i++) {
46
+ const char = text[i];
47
+ if (inString) {
48
+ if (char === '\\') {
49
+ out += char + (text[i + 1] ?? '');
50
+ i++;
51
+ continue;
52
+ }
53
+ if (char === '"')
54
+ inString = false;
55
+ out += char;
56
+ continue;
57
+ }
58
+ if (char === '"') {
59
+ inString = true;
60
+ out += char;
61
+ continue;
62
+ }
63
+ if (char === '/' && text[i + 1] === '/') {
64
+ while (i < text.length && text[i] !== '\n')
65
+ i++;
66
+ out += '\n';
67
+ continue;
68
+ }
69
+ if (char === '/' && text[i + 1] === '*') {
70
+ i += 2;
71
+ while (i < text.length && !(text[i] === '*' && text[i + 1] === '/'))
72
+ i++;
73
+ i++;
74
+ out += ' ';
75
+ continue;
76
+ }
77
+ out += char;
78
+ }
79
+ return out;
80
+ }
81
+ function stripTrailingCommas(text) {
82
+ let out = '';
83
+ let inString = false;
84
+ for (let i = 0; i < text.length; i++) {
85
+ const char = text[i];
86
+ if (inString) {
87
+ if (char === '\\') {
88
+ out += char + (text[i + 1] ?? '');
89
+ i++;
90
+ continue;
91
+ }
92
+ if (char === '"')
93
+ inString = false;
94
+ out += char;
95
+ continue;
96
+ }
97
+ if (char === '"') {
98
+ inString = true;
99
+ out += char;
100
+ continue;
101
+ }
102
+ if (char === ',') {
103
+ let next = i + 1;
104
+ while (next < text.length && /\s/.test(text[next]))
105
+ next++;
106
+ if (text[next] === '}' || text[next] === ']')
107
+ continue;
108
+ }
109
+ out += char;
110
+ }
111
+ return out;
112
+ }
113
+ function readConfig(configPath) {
114
+ let text;
43
115
  try {
44
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
45
- cachedTsConfig = {
46
- config: config.compilerOptions || null,
47
- basePath: path.dirname(configPath),
48
- };
116
+ text = fs.readFileSync(configPath, 'utf8');
49
117
  }
50
118
  catch {
51
- cachedTsConfig = null;
119
+ return null;
120
+ }
121
+ try {
122
+ const config = JSON.parse(stripTrailingCommas(stripComments(text.replace(/^\uFEFF/, ''))));
123
+ return config && typeof config === 'object' ? config : null;
124
+ }
125
+ catch {
126
+ return null;
52
127
  }
53
128
  }
54
- function getTsConfig() {
55
- if (cachedTsConfig !== undefined) {
56
- return cachedTsConfig;
129
+ function configFileAt(candidate) {
130
+ return fs.statSync(candidate, { throwIfNoEntry: false })?.isDirectory()
131
+ ? path.join(candidate, 'tsconfig.json')
132
+ : candidate;
133
+ }
134
+ function packageNameOf(specifier) {
135
+ const segments = specifier.split('/');
136
+ return specifier.startsWith('@')
137
+ ? segments.slice(0, 2).join('/')
138
+ : segments[0];
139
+ }
140
+ function resolveQuietly(specifier, basePath) {
141
+ try {
142
+ return require.resolve(specifier, { paths: [basePath] });
57
143
  }
58
- const tsConfigPath = path.join(process.cwd(), 'tsconfig.json');
59
- if (fs.existsSync(tsConfigPath)) {
60
- try {
61
- const config = require(tsConfigPath);
62
- cachedTsConfig = {
63
- config: config.compilerOptions || null,
64
- basePath: path.dirname(tsConfigPath),
65
- };
66
- }
67
- catch {
68
- cachedTsConfig = null;
69
- }
144
+ catch {
145
+ return null;
146
+ }
147
+ }
148
+ function resolveExtendsPath(specifier, basePath) {
149
+ if (specifier.startsWith('.') || path.isAbsolute(specifier)) {
150
+ const resolved = configFileAt(path.resolve(basePath, specifier));
151
+ if (isFile(resolved))
152
+ return resolved;
153
+ const withExtension = resolved + '.json';
154
+ return isFile(withExtension) ? withExtension : null;
155
+ }
156
+ const packageName = packageNameOf(specifier);
157
+ const exported = () => {
158
+ const resolved = resolveQuietly(specifier, basePath);
159
+ return resolved?.endsWith('.json') ? resolved : null;
160
+ };
161
+ if (specifier !== packageName)
162
+ return exported();
163
+ const manifestPath = resolveQuietly(`${packageName}/package.json`, basePath);
164
+ if (!manifestPath)
165
+ return exported();
166
+ const manifest = readConfig(manifestPath);
167
+ if (manifest?.exports !== undefined) {
168
+ const resolved = exported();
169
+ if (resolved)
170
+ return resolved;
171
+ }
172
+ const packageDir = path.dirname(manifestPath);
173
+ if (typeof manifest?.tsconfig === 'string') {
174
+ const declared = configFileAt(path.resolve(packageDir, manifest.tsconfig));
175
+ if (isFile(declared))
176
+ return declared;
70
177
  }
71
- else {
72
- cachedTsConfig = null;
178
+ const fallback = path.join(packageDir, 'tsconfig.json');
179
+ return isFile(fallback) ? fallback : null;
180
+ }
181
+ function patternsOf(paths, basePath, entryPath) {
182
+ if (!paths || typeof paths !== 'object')
183
+ return null;
184
+ const patterns = [];
185
+ for (const [alias, targets] of Object.entries(paths)) {
186
+ if (!Array.isArray(targets) || targets.length === 0)
187
+ continue;
188
+ const written = targets.filter((target) => typeof target === 'string');
189
+ if (written.length === 0)
190
+ continue;
191
+ const star = alias.indexOf('*');
192
+ patterns.push({
193
+ prefix: star < 0 ? alias : alias.slice(0, star),
194
+ suffix: star < 0 ? '' : alias.slice(star + 1),
195
+ wildcard: star >= 0,
196
+ basePath,
197
+ targets: written.map((target) => target.startsWith(CONFIG_DIR)
198
+ ? path.join(entryPath, target.slice(CONFIG_DIR.length))
199
+ : target),
200
+ });
73
201
  }
74
- return cachedTsConfig;
202
+ return patterns;
203
+ }
204
+ function collectPatterns(configPath, seen, entryPath = path.dirname(configPath)) {
205
+ if (seen.has(configPath))
206
+ return null;
207
+ seen.add(configPath);
208
+ const config = readConfig(configPath);
209
+ if (!config)
210
+ return null;
211
+ const basePath = path.dirname(configPath);
212
+ const own = patternsOf(config.compilerOptions?.paths, basePath, entryPath);
213
+ if (own)
214
+ return own;
215
+ const inherited = Array.isArray(config.extends)
216
+ ? config.extends.slice().reverse()
217
+ : config.extends
218
+ ? [config.extends]
219
+ : [];
220
+ for (const specifier of inherited) {
221
+ const resolved = resolveExtendsPath(specifier, basePath);
222
+ if (!resolved)
223
+ continue;
224
+ const patterns = collectPatterns(resolved, seen, entryPath);
225
+ if (patterns)
226
+ return patterns;
227
+ }
228
+ for (const reference of config.references ?? []) {
229
+ if (!reference?.path)
230
+ continue;
231
+ const patterns = collectPatterns(configFileAt(path.resolve(basePath, reference.path)), seen);
232
+ if (patterns)
233
+ return patterns;
234
+ }
235
+ return null;
236
+ }
237
+ function buildMatcher(patterns) {
238
+ const exact = patterns.filter((pattern) => !pattern.wildcard);
239
+ const wildcard = patterns
240
+ .filter((pattern) => pattern.wildcard)
241
+ .sort((a, b) => b.prefix.length - a.prefix.length);
242
+ return (specifier) => {
243
+ for (const pattern of exact) {
244
+ if (pattern.prefix === specifier) {
245
+ return pattern.targets.map((target) => path.resolve(pattern.basePath, target));
246
+ }
247
+ }
248
+ for (const pattern of wildcard) {
249
+ if (specifier.length >= pattern.prefix.length + pattern.suffix.length &&
250
+ specifier.startsWith(pattern.prefix) &&
251
+ specifier.endsWith(pattern.suffix)) {
252
+ const matched = specifier.slice(pattern.prefix.length, specifier.length - pattern.suffix.length);
253
+ return pattern.targets.map((target) => path.resolve(pattern.basePath, target.replace('*', matched)));
254
+ }
255
+ }
256
+ return [];
257
+ };
258
+ }
259
+ function loadPathsMatcher(configPath) {
260
+ const patterns = collectPatterns(configPath, new Set());
261
+ return patterns ? buildMatcher(patterns) : null;
262
+ }
263
+ function resetImportResolutionCache(cwd = process.cwd()) {
264
+ cachedPathsMatcher = loadPathsMatcher(path.join(cwd, 'tsconfig.json'));
265
+ }
266
+ function getPathsMatcher() {
267
+ if (cachedPathsMatcher !== undefined)
268
+ return cachedPathsMatcher;
269
+ const tsConfigPath = path.join(process.cwd(), 'tsconfig.json');
270
+ cachedPathsMatcher = fs.existsSync(tsConfigPath)
271
+ ? loadPathsMatcher(tsConfigPath)
272
+ : null;
273
+ return cachedPathsMatcher;
75
274
  }
76
275
  const extensions = [
77
276
  '.ts',
@@ -102,21 +301,12 @@ function resolveImportPath(importPath, importerPath) {
102
301
  if (importPath.startsWith('.')) {
103
302
  return resolveWithExtension(path.resolve(path.dirname(importerPath), importPath));
104
303
  }
105
- const tsConfig = getTsConfig();
106
- const config = tsConfig?.config;
107
- if (config?.paths) {
108
- const root = tsConfig.basePath;
109
- for (const [alias, targets] of Object.entries(config.paths)) {
110
- const prefix = alias.replace(/\*$/, '');
111
- if (importPath.startsWith(prefix)) {
112
- for (const target of targets) {
113
- const resolvedTarget = target.replace(/\*$/, '');
114
- const candidate = path.resolve(root, resolvedTarget + importPath.slice(prefix.length));
115
- const result = resolveWithExtension(candidate);
116
- if (result)
117
- return result;
118
- }
119
- }
304
+ const matchPaths = getPathsMatcher();
305
+ if (matchPaths) {
306
+ for (const candidate of matchPaths(importPath)) {
307
+ const result = resolveWithExtension(candidate);
308
+ if (result)
309
+ return result;
120
310
  }
121
311
  }
122
312
  let currentDir = path.dirname(importerPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plumeria/utils",
3
- "version": "19.2.2",
3
+ "version": "19.2.4",
4
4
  "description": "Plumeria Utils",
5
5
  "author": "Refirst 11",
6
6
  "license": "MIT",