@plumeria/codemod 18.2.17 → 18.2.19

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/README.md CHANGED
@@ -5,6 +5,7 @@ No install needed — run it with `npx`.
5
5
 
6
6
  ```sh
7
7
  npx @plumeria/codemod migrate --from css-modules
8
+ npx @plumeria/codemod migrate --from plumeria
8
9
  npx @plumeria/codemod rename-prop classStyle sx
9
10
  ```
10
11
 
@@ -93,6 +94,127 @@ Any rules that cannot be converted are reported in the same run, and the exit
93
94
  code remains 1 while such rules are present. Remove `--dry-run` to write the
94
95
  generated modules and consumer changes.
95
96
 
97
+ ## `migrate --from plumeria`
98
+
99
+ The reverse of the forward migration. Every `css.create` definition under the
100
+ paths becomes a `*.module.css` beside it, and the files that use it are rewritten
101
+ — the import, the `classStyle` prop, and the style composition:
102
+
103
+ ```sh
104
+ npx @plumeria/codemod migrate --from plumeria [paths...]
105
+ ```
106
+
107
+ ```tsx
108
+ /* Card.tsx — before */
109
+ import * as css from '@plumeria/core';
110
+
111
+ export const styles = css.create({
112
+ base: { fontSize: 12 },
113
+ card: {
114
+ padding: 16,
115
+ ':hover': { background: 'teal' },
116
+ },
117
+ size: (width: number) => ({ width }),
118
+ });
119
+
120
+ export function Card({ width }: { width: number }) {
121
+ return <div classStyle={[styles.base, styles.card, styles.size(width)]} />;
122
+ }
123
+ ```
124
+
125
+ ```css
126
+ /* Card.module.css — generated */
127
+ .base { font-size: 12px }
128
+ .card { padding: 16px }
129
+ .card:hover { background: teal }
130
+ .size { width: var(--styles-size-width) }
131
+ ```
132
+
133
+ ```diff
134
+ /* Card.tsx — after */
135
+ - import * as css from '@plumeria/core';
136
+ + import styles from './Card.module.css';
137
+
138
+ - export const styles = css.create({
139
+ - base: { fontSize: 12 },
140
+ - card: {
141
+ - padding: 16,
142
+ - ':hover': { background: 'teal' },
143
+ - },
144
+ - size: (width: number) => ({ width }),
145
+ - });
146
+ + export { styles };
147
+
148
+ export function Card({ width }: { width: number }) {
149
+ - return <div classStyle={[styles.base, styles.card, styles.size(width)]} />;
150
+ + return (
151
+ + <div
152
+ + className={`${styles.base} ${styles.card} ${styles.size}`}
153
+ + style={{ '--styles-size-width': width }}
154
+ + />
155
+ + );
156
+ }
157
+ ```
158
+
159
+ A function style key such as `(width) => ({ width })` has no CSS Modules
160
+ equivalent, so each parameter becomes a CSS custom property named
161
+ `--<binding>-<key>-<param>`. The class name stays in `className`; the argument
162
+ values move to the inline `style` prop. If a `style` prop already exists, the
163
+ custom properties are merged into it.
164
+
165
+ An array on the styling prop is joined into a template literal. When the array
166
+ contains a conditional expression, it uses `.filter(Boolean).join(' ')` instead,
167
+ so the falsy branch drops out at runtime:
168
+
169
+ ```diff
170
+ - <div classStyle={[styles.base, active && styles.active]} />
171
+ + <div className={[styles.base, active && styles.active].filter(Boolean).join(' ')} />
172
+ ```
173
+
174
+ ### Global styles
175
+
176
+ `css.createTheme`, `css.keyframes`, and `css.viewTransition` produce rules that
177
+ belong in a global stylesheet, not in a CSS Module. The codemod extracts them and
178
+ appends them to `src/styles/global.css` (or `styles/global.css` when `src` does
179
+ not exist). Theme tokens become CSS custom properties under `:where(:root)` and
180
+ the theme selector; keyframes become `@keyframes kf-<hash>`; view transitions
181
+ become `::view-transition-*` pseudo-element rules. References in style objects
182
+ are replaced by their generated names.
183
+
184
+ `css.createStatic` values are statically evaluated and inlined directly into the
185
+ generated CSS rules — no separate output file is needed.
186
+
187
+ ### What it reports instead of converting
188
+
189
+ ```
190
+ src/Card.tsx
191
+ 8:5 dynamic-value
192
+ The value of `color` cannot be represented statically.
193
+ 12:3 spread-create
194
+ Top-level spreads cannot name a CSS Module class.
195
+ ```
196
+
197
+ Constructs that cannot be resolved statically — dynamic values, computed keys,
198
+ runtime function calls, object spreads, and multiple `css.create` calls in one
199
+ file — are reported and left in place. A target `*.module.css` that already
200
+ exists is reported as `target-exists` and will not be overwritten.
201
+
202
+ The exit code is 1 while anything remains, so the command composes with a script.
203
+
204
+ Start with `-d, --dry-run` to preview the export without writing files:
205
+
206
+ ```sh
207
+ npx @plumeria/codemod migrate --from plumeria --dry-run [paths...]
208
+ ```
209
+
210
+ ```
211
+ src/Card.tsx -> src/Card.module.css
212
+ global styles -> src/styles/global.css
213
+
214
+ 1 style module(s) would be exported, 1 source file(s) rewritten.
215
+ Run without --dry-run to apply.
216
+ ```
217
+
96
218
  ## `rename-prop`
97
219
 
98
220
  Renames the styling prop across your source. The names are arguments, so it
package/dist/cli.js CHANGED
@@ -43,10 +43,12 @@ const eslint_1 = require("eslint");
43
43
  const tsParser = __importStar(require("@typescript-eslint/parser"));
44
44
  const rename_prop_1 = require("./transforms/rename-prop");
45
45
  const adopt_styles_1 = require("./transforms/adopt-styles");
46
+ const release_styles_1 = require("./transforms/release-styles");
46
47
  const migrate_1 = require("./migrate");
48
+ const release_1 = require("./release");
47
49
  const { version } = require('../package.json');
48
50
  const TRANSFORMS = ['rename-prop', 'migrate'];
49
- const SOURCES = ['css-modules'];
51
+ const SOURCES = ['css-modules', 'plumeria'];
50
52
  const SOURCE_FILES = '**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}';
51
53
  const IGNORES = [
52
54
  '**/dist/**',
@@ -62,6 +64,7 @@ const USAGE = `plumeria-codemod — codemods for migrating Plumeria APIs
62
64
  Usage
63
65
  npx @plumeria/codemod rename-prop <from> <to> [paths...]
64
66
  npx @plumeria/codemod migrate --from css-modules [paths...]
67
+ npx @plumeria/codemod migrate --from plumeria [paths...]
65
68
 
66
69
  Options
67
70
  -d, --dry-run report what would change without writing
@@ -74,6 +77,7 @@ Examples
74
77
  npx @plumeria/codemod rename-prop classStyle sx
75
78
  npx @plumeria/codemod rename-prop classStyle sx src app --dry-run
76
79
  npx @plumeria/codemod migrate --from css-modules
80
+ npx @plumeria/codemod migrate --from plumeria --dry-run
77
81
 
78
82
  Paths default to the current directory. After the rewrite, point the toolchain
79
83
  at the new name with \`styleProp\` on your bundler plugin, and with
@@ -200,8 +204,11 @@ async function main(argv) {
200
204
  }
201
205
  if (!options)
202
206
  return 0;
203
- if (options.transform === 'migrate')
204
- return migrate(options);
207
+ if (options.transform === 'migrate') {
208
+ return options.source === 'plumeria'
209
+ ? migrateFromPlumeria(options)
210
+ : migrateFromCssModules(options);
211
+ }
205
212
  const { from, to, targets, dryRun } = options;
206
213
  const baseConfig = {
207
214
  overrideConfigFile: true,
@@ -285,7 +292,7 @@ function migrateConfig(modules) {
285
292
  },
286
293
  ];
287
294
  }
288
- async function migrate(options) {
295
+ async function migrateFromCssModules(options) {
289
296
  const { targets, dryRun } = options;
290
297
  const cwd = process.cwd();
291
298
  const relative = (filePath) => node_path_1.default.relative(cwd, filePath) || '.';
@@ -324,3 +331,68 @@ async function migrate(options) {
324
331
  console.log(line);
325
332
  return 1;
326
333
  }
334
+ function releaseConfig(modules, themes, animations, statics) {
335
+ return [
336
+ { ignores: IGNORES },
337
+ {
338
+ files: [SOURCE_FILES],
339
+ languageOptions: {
340
+ parser: tsParser,
341
+ parserOptions: {
342
+ sourceType: 'module',
343
+ ecmaFeatures: { jsx: true },
344
+ },
345
+ },
346
+ plugins: { codemod: { rules: { 'release-styles': release_styles_1.releaseStyles } } },
347
+ rules: {
348
+ 'codemod/release-styles': [
349
+ 'error',
350
+ { modules, themes, animations, statics },
351
+ ],
352
+ },
353
+ },
354
+ ];
355
+ }
356
+ async function migrateFromPlumeria(options) {
357
+ const { targets, dryRun } = options;
358
+ const cwd = process.cwd();
359
+ const relative = (filePath) => node_path_1.default.relative(cwd, filePath) || '.';
360
+ const planned = (0, release_1.planRelease)(targets);
361
+ if (planned.stylesheets.length === 0 &&
362
+ Object.keys(planned.themes).length === 0 &&
363
+ Object.keys(planned.animations).length === 0) {
364
+ console.log('No Plumeria styles found.');
365
+ return 0;
366
+ }
367
+ for (const sheet of planned.stylesheets) {
368
+ console.log(` ${relative(sheet.source)} -> ${relative(sheet.target)}`);
369
+ }
370
+ if (planned.global) {
371
+ console.log(` global styles -> ${relative(planned.global.target)}`);
372
+ }
373
+ const config = {
374
+ overrideConfigFile: true,
375
+ overrideConfig: releaseConfig(planned.modules, planned.themes, planned.animations, planned.statics),
376
+ errorOnUnmatchedPattern: false,
377
+ };
378
+ const preview = await new eslint_1.ESLint(config).lintFiles(targets);
379
+ const touched = preview.filter((result) => result.messages.some((message) => message.fix));
380
+ if (dryRun) {
381
+ console.log(`\n${Object.keys(planned.modules).length} style module(s) would be exported, ${touched.length} source file(s) rewritten.`);
382
+ console.log('Run without --dry-run to apply.');
383
+ }
384
+ else {
385
+ warnIfDirty();
386
+ (0, release_1.writeRelease)(planned);
387
+ const applied = await new eslint_1.ESLint({ ...config, fix: true }).lintFiles(targets);
388
+ await eslint_1.ESLint.outputFixes(applied);
389
+ console.log(`\n✔ exported ${Object.keys(planned.modules).length} style module(s) and rewrote ${touched.length} source file(s).`);
390
+ }
391
+ const lines = (0, release_1.formatReleaseReports)(planned.stylesheets, cwd);
392
+ if (lines.length === 0)
393
+ return 0;
394
+ console.log('\nLeft in Plumeria — these styles were not exported:\n');
395
+ for (const line of lines)
396
+ console.log(line);
397
+ return 1;
398
+ }
@@ -0,0 +1,23 @@
1
+ import type { PlumeriaReport } from './transforms/from-plumeria';
2
+ import type { ReleaseModule } from './transforms/release-styles';
3
+ export interface ReleasedStylesheet {
4
+ source: string;
5
+ target: string;
6
+ css: string;
7
+ reports: PlumeriaReport[];
8
+ }
9
+ export interface ReleasePlan {
10
+ stylesheets: ReleasedStylesheet[];
11
+ modules: Record<string, ReleaseModule>;
12
+ themes: Record<string, string[]>;
13
+ animations: Record<string, string[]>;
14
+ statics: Record<string, string[]>;
15
+ global?: {
16
+ target: string;
17
+ css: string;
18
+ };
19
+ }
20
+ export declare const releasedPath: (source: string) => string;
21
+ export declare function planRelease(targets: string[]): ReleasePlan;
22
+ export declare function writeRelease(plan: ReleasePlan): void;
23
+ export declare function formatReleaseReports(sheets: ReleasedStylesheet[], cwd: string): string[];
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.releasedPath = void 0;
37
+ exports.planRelease = planRelease;
38
+ exports.writeRelease = writeRelease;
39
+ exports.formatReleaseReports = formatReleaseReports;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const parser_1 = require("@typescript-eslint/parser");
43
+ const resolve_1 = require("./resolve");
44
+ const from_plumeria_1 = require("./transforms/from-plumeria");
45
+ const EXTENSION = /\.(?:[cm]?[jt]sx?)$/;
46
+ const IGNORED = new Set([
47
+ 'node_modules',
48
+ 'dist',
49
+ 'build',
50
+ 'out',
51
+ '.next',
52
+ '.git',
53
+ 'coverage',
54
+ ]);
55
+ const findSources = (targets) => {
56
+ const found = [];
57
+ const walk = (entry) => {
58
+ const stats = fs.statSync(entry);
59
+ if (stats.isFile()) {
60
+ if (EXTENSION.test(entry))
61
+ found.push(path.resolve(entry));
62
+ return;
63
+ }
64
+ for (const name of fs.readdirSync(entry)) {
65
+ if (!IGNORED.has(name))
66
+ walk(path.join(entry, name));
67
+ }
68
+ };
69
+ for (const target of targets) {
70
+ try {
71
+ walk(target);
72
+ }
73
+ catch {
74
+ }
75
+ }
76
+ return found.sort();
77
+ };
78
+ const releasedPath = (source) => source.replace(/(?:\.styles)?\.[^.]+$/, '.module.css');
79
+ exports.releasedPath = releasedPath;
80
+ const globalPath = (targets) => {
81
+ const first = path.resolve(targets[0]);
82
+ const root = fs.existsSync(first) && fs.statSync(first).isDirectory()
83
+ ? first
84
+ : path.dirname(first);
85
+ const candidates = [
86
+ path.join(root, 'src', 'styles', 'global.css'),
87
+ path.join(root, 'styles', 'global.css'),
88
+ ];
89
+ return (candidates.find((candidate) => fs.existsSync(candidate)) ??
90
+ (fs.existsSync(path.join(root, 'src')) ? candidates[0] : candidates[1]));
91
+ };
92
+ function planRelease(targets) {
93
+ const stylesheets = [];
94
+ const modules = {};
95
+ const themes = {};
96
+ const animations = {};
97
+ const statics = {};
98
+ const globalRules = [];
99
+ const sources = findSources(targets);
100
+ const sourceText = new Map(sources.map((source) => [source, fs.readFileSync(source, 'utf8')]));
101
+ const themeValues = new Map();
102
+ const animationValues = new Map();
103
+ const staticValues = new Map();
104
+ for (const source of sources) {
105
+ try {
106
+ const extracted = (0, from_plumeria_1.extractPlumeriaStatics)(sourceText.get(source));
107
+ if (Object.keys(extracted.bindings).length > 0)
108
+ staticValues.set(source, extracted.bindings);
109
+ }
110
+ catch {
111
+ }
112
+ }
113
+ for (const source of sources) {
114
+ try {
115
+ const extracted = (0, from_plumeria_1.extractPlumeriaThemes)(sourceText.get(source));
116
+ if (Object.keys(extracted.bindings).length === 0)
117
+ continue;
118
+ themeValues.set(source, extracted.bindings);
119
+ themes[source] = Object.keys(extracted.bindings);
120
+ globalRules.push(extracted.globalCss.trim());
121
+ }
122
+ catch {
123
+ }
124
+ }
125
+ for (const source of sources) {
126
+ try {
127
+ const extracted = (0, from_plumeria_1.extractPlumeriaAnimations)(sourceText.get(source), {
128
+ ...(themeValues.get(source) ?? {}),
129
+ });
130
+ if (Object.keys(extracted.bindings).length > 0)
131
+ animationValues.set(source, extracted.bindings);
132
+ }
133
+ catch {
134
+ }
135
+ }
136
+ const importedValues = (source, availableBySource) => {
137
+ const result = {};
138
+ const ast = (0, parser_1.parse)(sourceText.get(source), {
139
+ sourceType: 'module',
140
+ ecmaFeatures: { jsx: true },
141
+ });
142
+ for (const node of ast.body) {
143
+ if (node.type !== 'ImportDeclaration' ||
144
+ typeof node.source.value !== 'string')
145
+ continue;
146
+ const target = (0, resolve_1.resolveSourcePath)(node.source.value, source);
147
+ if (!target)
148
+ continue;
149
+ const available = availableBySource.get(target);
150
+ if (!available)
151
+ continue;
152
+ for (const specifier of node.specifiers) {
153
+ if (specifier.type === 'ImportSpecifier') {
154
+ const imported = specifier.imported.name ?? specifier.imported.value;
155
+ if (available[imported])
156
+ result[specifier.local.name] = available[imported];
157
+ }
158
+ else if (specifier.type === 'ImportNamespaceSpecifier') {
159
+ result[specifier.local.name] = available;
160
+ }
161
+ }
162
+ }
163
+ return result;
164
+ };
165
+ const importedPlumeriaValues = (source) => {
166
+ const merged = {};
167
+ for (const table of [staticValues, themeValues, animationValues]) {
168
+ for (const [key, value] of Object.entries(importedValues(source, table))) {
169
+ const previous = merged[key];
170
+ merged[key] =
171
+ previous &&
172
+ typeof previous === 'object' &&
173
+ value &&
174
+ typeof value === 'object'
175
+ ? { ...previous, ...value }
176
+ : value;
177
+ }
178
+ }
179
+ return merged;
180
+ };
181
+ for (const source of sources) {
182
+ try {
183
+ const extracted = (0, from_plumeria_1.extractPlumeriaStatics)(sourceText.get(source), importedPlumeriaValues(source));
184
+ if (Object.keys(extracted.bindings).length === 0)
185
+ continue;
186
+ staticValues.set(source, extracted.bindings);
187
+ statics[source] = Object.keys(extracted.bindings);
188
+ }
189
+ catch {
190
+ }
191
+ }
192
+ for (const source of sources) {
193
+ try {
194
+ const extracted = (0, from_plumeria_1.extractPlumeriaAnimations)(sourceText.get(source), {
195
+ ...importedPlumeriaValues(source),
196
+ ...(themeValues.get(source) ?? {}),
197
+ });
198
+ if (Object.keys(extracted.bindings).length === 0)
199
+ continue;
200
+ animationValues.set(source, extracted.bindings);
201
+ animations[source] = [
202
+ ...extracted.keyframes,
203
+ ...extracted.viewTransitions,
204
+ ];
205
+ globalRules.push(extracted.globalCss.trim());
206
+ }
207
+ catch {
208
+ }
209
+ }
210
+ for (const source of sources) {
211
+ let converted;
212
+ try {
213
+ converted = (0, from_plumeria_1.convertPlumeriaModule)(sourceText.get(source), importedPlumeriaValues(source));
214
+ }
215
+ catch {
216
+ continue;
217
+ }
218
+ if (!converted)
219
+ continue;
220
+ const target = (0, exports.releasedPath)(source);
221
+ const specifier = `./${path.basename(target)}`;
222
+ const reports = [...converted.reports];
223
+ if (fs.existsSync(target)) {
224
+ reports.push({
225
+ line: 0,
226
+ column: 0,
227
+ kind: 'target-exists',
228
+ hint: `${path.basename(target)} already exists and was not overwritten.`,
229
+ });
230
+ }
231
+ stylesheets.push({
232
+ source,
233
+ target,
234
+ css: converted.css,
235
+ reports,
236
+ });
237
+ if (reports.length === 0) {
238
+ modules[source] = {
239
+ source: specifier,
240
+ target,
241
+ binding: converted.binding,
242
+ ...(converted.definitionOnly ? { definitionOnly: true } : {}),
243
+ ...(Object.keys(converted.aliases).length > 0
244
+ ? { aliases: converted.aliases }
245
+ : {}),
246
+ ...(Object.keys(converted.functions).length > 0
247
+ ? { functions: converted.functions }
248
+ : {}),
249
+ };
250
+ }
251
+ }
252
+ return {
253
+ stylesheets,
254
+ modules,
255
+ themes,
256
+ animations,
257
+ statics,
258
+ global: globalRules.length > 0
259
+ ? {
260
+ target: globalPath(targets),
261
+ css: `/* Generated from css.createTheme, css.keyframes, and css.viewTransition by @plumeria/codemod */\n${globalRules.join('\n\n')}\n`,
262
+ }
263
+ : undefined,
264
+ };
265
+ }
266
+ function writeRelease(plan) {
267
+ for (const sheet of plan.stylesheets) {
268
+ if (sheet.reports.length > 0)
269
+ continue;
270
+ fs.writeFileSync(sheet.target, sheet.css, 'utf8');
271
+ }
272
+ if (plan.global) {
273
+ fs.mkdirSync(path.dirname(plan.global.target), { recursive: true });
274
+ const previous = fs.existsSync(plan.global.target)
275
+ ? fs.readFileSync(plan.global.target, 'utf8')
276
+ : '';
277
+ const separator = previous.length > 0 && !previous.endsWith('\n') ? '\n\n' : '';
278
+ fs.writeFileSync(plan.global.target, `${previous}${separator}${plan.global.css}`, 'utf8');
279
+ }
280
+ }
281
+ function formatReleaseReports(sheets, cwd) {
282
+ const lines = [];
283
+ for (const sheet of sheets) {
284
+ if (sheet.reports.length === 0)
285
+ continue;
286
+ lines.push(path.relative(cwd, sheet.source) || sheet.source);
287
+ for (const report of sheet.reports) {
288
+ lines.push(` ${report.line}:${report.column} ${report.kind}`);
289
+ lines.push(` ${report.hint}`);
290
+ }
291
+ }
292
+ return lines;
293
+ }
@@ -0,0 +1,2 @@
1
+ export declare const resetTsconfigCache: () => void;
2
+ export declare function resolveSourcePath(specifier: string, importer: string): string | null;
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resetTsconfigCache = void 0;
37
+ exports.resolveSourcePath = resolveSourcePath;
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const get_tsconfig_1 = require("get-tsconfig");
41
+ const EXTENSIONS = [
42
+ '.ts',
43
+ '.tsx',
44
+ '.mts',
45
+ '.cts',
46
+ '.js',
47
+ '.jsx',
48
+ '.mjs',
49
+ '.cjs',
50
+ ];
51
+ const CANDIDATES = [
52
+ ...EXTENSIONS,
53
+ ...EXTENSIONS.map((extension) => `${path.sep}index${extension}`),
54
+ ];
55
+ const REWRITTEN = {
56
+ '.js': ['.ts', '.tsx'],
57
+ '.jsx': ['.tsx'],
58
+ '.mjs': ['.mts'],
59
+ '.cjs': ['.cts'],
60
+ };
61
+ let cachedMatcher;
62
+ const pathsMatcher = () => {
63
+ if (cachedMatcher === undefined) {
64
+ const tsconfig = (0, get_tsconfig_1.getTsconfig)(process.cwd());
65
+ cachedMatcher = tsconfig ? (0, get_tsconfig_1.createPathsMatcher)(tsconfig) : null;
66
+ }
67
+ return cachedMatcher;
68
+ };
69
+ const resetTsconfigCache = () => {
70
+ cachedMatcher = undefined;
71
+ };
72
+ exports.resetTsconfigCache = resetTsconfigCache;
73
+ const isFile = (candidate) => fs.statSync(candidate, { throwIfNoEntry: false })?.isFile() ?? false;
74
+ const resolveFile = (base) => {
75
+ if (isFile(base))
76
+ return base;
77
+ const extension = path.extname(base);
78
+ for (const rewritten of REWRITTEN[extension] ?? []) {
79
+ const candidate = `${base.slice(0, -extension.length)}${rewritten}`;
80
+ if (isFile(candidate))
81
+ return candidate;
82
+ }
83
+ for (const candidate of CANDIDATES) {
84
+ if (isFile(base + candidate))
85
+ return base + candidate;
86
+ }
87
+ return null;
88
+ };
89
+ function resolveSourcePath(specifier, importer) {
90
+ if (specifier === '@plumeria/core')
91
+ return null;
92
+ if (specifier.startsWith('.')) {
93
+ return resolveFile(path.resolve(path.dirname(importer), specifier));
94
+ }
95
+ const matcher = pathsMatcher();
96
+ if (!matcher)
97
+ return null;
98
+ for (const candidate of matcher(specifier)) {
99
+ const resolved = resolveFile(candidate);
100
+ if (resolved)
101
+ return resolved;
102
+ }
103
+ return null;
104
+ }