vitek-plugin 0.1.2-beta.3 → 0.1.2-beta.5
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/core/types/generate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/core/types/generate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAyB/C;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA+FvF;AA4LD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,EAAE,EACrB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAE,OAAc,GAAG,MAAM,CAuKxH;AAmKD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,WAAW,EAAE,EACrB,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,OAAc,GAC3B,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
|
@@ -18,6 +18,13 @@ function deduplicateRoutesByKey(routes) {
|
|
|
18
18
|
return true;
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
+
function partToIdentifier(part) {
|
|
22
|
+
const clean = part.replace(/^[:*]/, '');
|
|
23
|
+
return clean
|
|
24
|
+
.split('-')
|
|
25
|
+
.map(word => capitalize(word))
|
|
26
|
+
.join('');
|
|
27
|
+
}
|
|
21
28
|
/**
|
|
22
29
|
* Generates the content of the generated types file
|
|
23
30
|
*/
|
|
@@ -480,13 +487,8 @@ function generateFunctionNameBase(route) {
|
|
|
480
487
|
const parts = route.pattern
|
|
481
488
|
.split('/')
|
|
482
489
|
.filter(Boolean)
|
|
483
|
-
.filter(part => part !== 'index')
|
|
484
|
-
.map(part =>
|
|
485
|
-
// Remove : or * from the beginning
|
|
486
|
-
const clean = part.replace(/^[:*]/, '');
|
|
487
|
-
// Capitalize
|
|
488
|
-
return capitalize(clean);
|
|
489
|
-
});
|
|
490
|
+
.filter(part => part !== 'index')
|
|
491
|
+
.map(part => partToIdentifier(part));
|
|
490
492
|
const pathName = parts.join('');
|
|
491
493
|
return `${method}${pathName}`;
|
|
492
494
|
}
|
|
@@ -500,12 +502,7 @@ function generateUniqueFunctionName(route, baseName, conflictingRoutes, existing
|
|
|
500
502
|
// Remove "index" but keep other parts (including params for context)
|
|
501
503
|
const allParts = patternParts
|
|
502
504
|
.filter(part => part !== 'index')
|
|
503
|
-
.map(part =>
|
|
504
|
-
// For parameters, include the name as context to differentiate
|
|
505
|
-
// Example: ":id" becomes "Id", "*ids" becomes "Ids"
|
|
506
|
-
const clean = part.replace(/^[:*]/, '');
|
|
507
|
-
return capitalize(clean);
|
|
508
|
-
});
|
|
505
|
+
.map(part => partToIdentifier(part));
|
|
509
506
|
// Use all parts of the path to ensure uniqueness from the start
|
|
510
507
|
if (allParts.length > 0) {
|
|
511
508
|
const fullPathName = allParts.join('');
|
|
@@ -211,6 +211,20 @@ describe('generateServicesContent', () => {
|
|
|
211
211
|
expect(count).toBe(1);
|
|
212
212
|
});
|
|
213
213
|
});
|
|
214
|
+
it('generates valid identifiers for paths with hyphens (e.g. inter-squad)', () => {
|
|
215
|
+
const routes = [
|
|
216
|
+
route('inter-squad/requests', 'post', []),
|
|
217
|
+
route('inter-squad/requests/:id/status', 'put', ['id']),
|
|
218
|
+
];
|
|
219
|
+
const content = generateServicesContent(routes, API_BASE, true);
|
|
220
|
+
const names = getExportedFunctionNames(content);
|
|
221
|
+
expect(names).toHaveLength(2);
|
|
222
|
+
expect(names).toContain('postInterSquadRequests');
|
|
223
|
+
expect(names).toContain('putInterSquadRequestsIdStatus');
|
|
224
|
+
names.forEach((name) => {
|
|
225
|
+
expect(name).toMatch(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
214
228
|
it('regression: flows/id/versions GET and POST each appear once', () => {
|
|
215
229
|
const routes = [
|
|
216
230
|
route('flows/:id/versions', 'get', ['id']),
|
package/dist/plugin.js
CHANGED
|
@@ -57,12 +57,12 @@ export function vitek(options = {}) {
|
|
|
57
57
|
},
|
|
58
58
|
transform(code, id) {
|
|
59
59
|
const idPath = id.startsWith('file:') ? fileURLToPath(id) : id;
|
|
60
|
-
const
|
|
60
|
+
const srcDir = path.resolve(root, 'src');
|
|
61
61
|
const virtualCandidate = idPath.startsWith('/') ? path.join(root, idPath.replace(/^\//, '')) : null;
|
|
62
62
|
const normalizedId = virtualCandidate != null && fs.existsSync(virtualCandidate)
|
|
63
63
|
? virtualCandidate
|
|
64
64
|
: path.resolve(idPath);
|
|
65
|
-
if (!normalizedId.startsWith(
|
|
65
|
+
if (!normalizedId.startsWith(srcDir))
|
|
66
66
|
return null;
|
|
67
67
|
const dir = path.dirname(normalizedId);
|
|
68
68
|
const rootSlash = path.resolve(root) + path.sep;
|
package/dist/plugin.test.js
CHANGED
|
@@ -87,13 +87,32 @@ describe('vitek plugin resolveId and transform', () => {
|
|
|
87
87
|
});
|
|
88
88
|
});
|
|
89
89
|
describe('transform', () => {
|
|
90
|
-
|
|
91
|
-
it('returns null when id is not under apiDir', () => {
|
|
90
|
+
it('returns null when id is not under src', () => {
|
|
92
91
|
const code = "import x from '../lib/greeting';";
|
|
93
|
-
|
|
92
|
+
fs.mkdirSync(path.join(rootDir, 'other'), { recursive: true });
|
|
93
|
+
const idOutside = pathToFileURL(path.join(rootDir, 'other', 'main.ts')).href;
|
|
94
94
|
const result = callTransform(plugin, code, idOutside);
|
|
95
95
|
expect(result).toBeNull();
|
|
96
96
|
});
|
|
97
|
+
it('rewrites relative import when id is under src/lib (not only api)', () => {
|
|
98
|
+
fs.writeFileSync(path.join(rootDir, 'src', 'lib', 'executor.ts'), "import { getGreeting } from './greeting';\nexport function run() { return getGreeting(); }\n", 'utf-8');
|
|
99
|
+
const code = "import { getGreeting } from './greeting';\nexport function run() { return getGreeting(); }\n";
|
|
100
|
+
const id = pathToFileURL(path.join(rootDir, 'src', 'lib', 'executor.ts')).href;
|
|
101
|
+
const result = callTransform(plugin, code, id);
|
|
102
|
+
expect(result).not.toBeNull();
|
|
103
|
+
expect(result.code).toContain("/src/lib/greeting");
|
|
104
|
+
expect(result.code).not.toContain("from './greeting'");
|
|
105
|
+
});
|
|
106
|
+
it('rewrites relative import in src/lib file that imports from subpath', () => {
|
|
107
|
+
fs.mkdirSync(path.join(rootDir, 'src', 'lib', 'nested'), { recursive: true });
|
|
108
|
+
fs.writeFileSync(path.join(rootDir, 'src', 'lib', 'nested', 'helper.ts'), "export function getMessage() { return 'ok'; }\n", 'utf-8');
|
|
109
|
+
fs.writeFileSync(path.join(rootDir, 'src', 'lib', 'nested', 'index.ts'), "export { getMessage } from './helper';\n", 'utf-8');
|
|
110
|
+
const code = "export { getMessage } from './helper';\n";
|
|
111
|
+
const id = pathToFileURL(path.join(rootDir, 'src', 'lib', 'nested', 'index.ts')).href;
|
|
112
|
+
const result = callTransform(plugin, code, id);
|
|
113
|
+
expect(result).not.toBeNull();
|
|
114
|
+
expect(result.code).toContain("/src/lib/nested/helper");
|
|
115
|
+
});
|
|
97
116
|
it('rewrites relative import to root-relative path when id is under apiDir', () => {
|
|
98
117
|
const code = "import { getGreeting } from '../lib/greeting';\nexport default function handler() {}";
|
|
99
118
|
const id = pathToFileURL(path.join(apiDir, 'health.get.ts')).href;
|