openapi-import 0.0.3 → 0.0.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.
- package/README.md +3 -0
- package/dist/server.js +96 -87
- package/dist/server.js.map +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -70,6 +70,7 @@ Each schema and operation in the spec becomes a type. Schema types keep the name
|
|
|
70
70
|
- Hover, go to definition and find references jump from each name in the table to its key in the spec.
|
|
71
71
|
- Renaming a schema type renames its key in the spec, and the `$ref`s on a property, an array item or a schema alias that point at it. Update other `$ref`s, such as inside `allOf` or a response, yourself.
|
|
72
72
|
- Spec errors, such as an unresolved `$ref`, show on the key they point at.
|
|
73
|
+
- A `$ref` to another file, such as `./schemas/pet.yaml`, is read from disk. Editing that file updates the types and errors, the same as editing the spec.
|
|
73
74
|
- `tsc --runExternalCode` reports the same errors in CI.
|
|
74
75
|
|
|
75
76
|
## Add Zod schemas and more
|
|
@@ -128,6 +129,8 @@ Leave `input` out of the config to import specs only. With an `input`, the bundl
|
|
|
128
129
|
- Code a plugin writes to a separate file, such as a bundled client runtime, is not included. Point imports like a client's `importPath` at a package.
|
|
129
130
|
- Properties of operation types don't link to the spec, and renaming one doesn't rename its key.
|
|
130
131
|
- Files that `kubb.config.ts` imports are not watched. Restart the TypeScript server after you change them.
|
|
132
|
+
- A `$ref` to a URL is fetched on each rebuild but not watched. Edit the spec or restart the TypeScript server to pick up a change to it.
|
|
133
|
+
- `$ref` files are watched from the start for specs under the `tsconfig.json` folder. For a spec outside it, they are watched from the next time the project reloads, such as after a change to `kubb.config.ts`.
|
|
131
134
|
- A changed spec rebuilds all of its types: about 0.4 s for a 10 KB spec and 2.6 s for a 1.4 MB spec.
|
|
132
135
|
|
|
133
136
|
## Sponsors
|
package/dist/server.js
CHANGED
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
import { dirname, resolve } from "node:path";
|
|
2
|
-
import { configFileCandidates, findConfigFile, generateModule, loadConfigFile, selectConfig } from "unplugin-kubb";
|
|
3
1
|
import { createHash } from "node:crypto";
|
|
4
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { globSync, readFileSync } from "node:fs";
|
|
3
|
+
import { basename, dirname, resolve } from "node:path";
|
|
5
4
|
import ts from "@typescript/typescript6";
|
|
5
|
+
import { configFileCandidates, findConfigFile, generateModule, loadConfigFile, selectConfig } from "unplugin-kubb";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
6
7
|
import { Hookable } from "kubb/kit";
|
|
7
8
|
import { pluginTs, pluginTsName, resolverTs } from "@kubb/plugin-ts";
|
|
8
9
|
import * as yaml from "yaml";
|
|
9
|
-
import { parseDocument } from "yaml";
|
|
10
|
-
|
|
10
|
+
import { parse, parseDocument } from "yaml";
|
|
11
|
+
// src/cache.ts
|
|
12
|
+
/**
|
|
13
|
+
* The text of `file`, or `null` when it cannot be read.
|
|
14
|
+
*/
|
|
15
|
+
const readOrNull = (file) => {
|
|
16
|
+
try {
|
|
17
|
+
return readFileSync(file, "utf8");
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
11
22
|
/**
|
|
12
23
|
* Wraps a transform so a repeated request for the same file, content and config returns the
|
|
13
24
|
* previous result. TypeScript asks again for specs it already transformed (another project, a
|
|
14
|
-
* reload), and a Kubb build of a large spec takes seconds. A
|
|
25
|
+
* reload, a changed file next to the spec), and a Kubb build of a large spec takes seconds. A
|
|
26
|
+
* result whose `dependencies` changed on disk, the files its external `$ref`s read, is
|
|
27
|
+
* transformed again. A failed transform is not kept.
|
|
15
28
|
*/
|
|
16
29
|
function cacheTransform(transform) {
|
|
17
30
|
const results = /* @__PURE__ */ new Map();
|
|
18
|
-
|
|
19
|
-
const cached = results.get(params.fileName);
|
|
20
|
-
if (cached && cached.content === params.content && cached.config === config) return cached.result;
|
|
31
|
+
const run = (params, config) => {
|
|
21
32
|
const result = transform(params, config);
|
|
22
33
|
results.set(params.fileName, {
|
|
23
34
|
content: params.content,
|
|
@@ -27,9 +38,14 @@ function cacheTransform(transform) {
|
|
|
27
38
|
result.catch(() => results.delete(params.fileName));
|
|
28
39
|
return result;
|
|
29
40
|
};
|
|
41
|
+
return async (params, config) => {
|
|
42
|
+
const cached = results.get(params.fileName);
|
|
43
|
+
if (!cached || cached.content !== params.content || cached.config !== config) return run(params, config);
|
|
44
|
+
const result = await cached.result;
|
|
45
|
+
return Object.entries(result.dependencies ?? {}).every(([file, text]) => readOrNull(file) === text) ? result : run(params, config);
|
|
46
|
+
};
|
|
30
47
|
}
|
|
31
|
-
|
|
32
|
-
//#region src/config.ts
|
|
48
|
+
// src/config.ts
|
|
33
49
|
/**
|
|
34
50
|
* Finds the Kubb config the way the Kubb CLI does, from `dir` up, and loads it. A config that
|
|
35
51
|
* exports a function is called with no CLI options.
|
|
@@ -65,8 +81,7 @@ async function loadProjectConfig(dir) {
|
|
|
65
81
|
};
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
|
-
|
|
69
|
-
//#region src/rpc.ts
|
|
84
|
+
// src/rpc.ts
|
|
70
85
|
const separator = "\r\n\r\n";
|
|
71
86
|
/**
|
|
72
87
|
* Frames a message with the LSP base protocol `Content-Length` header the host reads.
|
|
@@ -100,8 +115,7 @@ function createDecoder(onMessage) {
|
|
|
100
115
|
}
|
|
101
116
|
};
|
|
102
117
|
}
|
|
103
|
-
|
|
104
|
-
//#region src/locate.ts
|
|
118
|
+
// src/locate.ts
|
|
105
119
|
const toRange = ([start, end]) => ({
|
|
106
120
|
start,
|
|
107
121
|
end
|
|
@@ -154,43 +168,13 @@ function findRefUsage(document, ref) {
|
|
|
154
168
|
function createLocator(document) {
|
|
155
169
|
return ({ pointer, ref, value }) => findPointer(document, pointer, value) ?? (ref ? findRefUsage(document, ref) : void 0);
|
|
156
170
|
}
|
|
157
|
-
|
|
158
|
-
//#region src/mappings.ts
|
|
171
|
+
// src/mappings.ts
|
|
159
172
|
const kindVerbatim = 0;
|
|
160
173
|
const kindAlias = 2;
|
|
161
174
|
const features = 249;
|
|
162
175
|
const refPrefix = "#/components/schemas/";
|
|
163
176
|
const escapeToken = (token) => token.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
164
|
-
|
|
165
|
-
* Narrows an operation type to the part of the operation it was generated from, by the suffix
|
|
166
|
-
* `@kubb/plugin-ts` appends to the operation name.
|
|
167
|
-
*/
|
|
168
|
-
function operationPointer(base, suffix) {
|
|
169
|
-
const status = /^Status(\d{3}|Default)/.exec(suffix)?.[1];
|
|
170
|
-
if (status) return `${base}/responses/${status === "Default" ? "default" : status}`;
|
|
171
|
-
if (/^(Path|Query|Header)/.test(suffix)) return `${base}/parameters`;
|
|
172
|
-
if (/^(Body|Request|MutationRequest)/.test(suffix)) return `${base}/requestBody`;
|
|
173
|
-
return base;
|
|
174
|
-
}
|
|
175
|
-
const longestPrefix = (keys, name) => [...keys].filter((key) => name.startsWith(key)).sort((a, b) => b.length - a.length)[0];
|
|
176
|
-
/**
|
|
177
|
-
* Pointers to try for one declaration, most specific first. Enums extracted from a schema property
|
|
178
|
-
* (`OrderStatusEnumKey`, `orderStatusEnum`) point at that property, then at the schema.
|
|
179
|
-
*/
|
|
180
|
-
function declarationPointers(name, { schemas, operations }) {
|
|
181
|
-
const schema = schemas.get(name);
|
|
182
|
-
if (schema) return [`#/components/schemas/${escapeToken(schema)}`];
|
|
183
|
-
const schemaPrefix = longestPrefix(schemas.keys(), name);
|
|
184
|
-
const operationPrefix = longestPrefix(operations.keys(), name);
|
|
185
|
-
if (schemaPrefix !== void 0 && (operationPrefix === void 0 || schemaPrefix.length > operationPrefix.length)) {
|
|
186
|
-
const base = `#/components/schemas/${escapeToken(schemas.get(schemaPrefix))}`;
|
|
187
|
-
const property = name.slice(schemaPrefix.length).replace(/(Enum)?Key$|Enum$/, "");
|
|
188
|
-
return property ? [`${base}/properties/${escapeToken(property[0].toLowerCase() + property.slice(1))}`, base] : [base];
|
|
189
|
-
}
|
|
190
|
-
if (operationPrefix === void 0) return [];
|
|
191
|
-
const { path, method } = operations.get(operationPrefix);
|
|
192
|
-
return [operationPointer(`#/paths/${escapeToken(path)}/${method.toLowerCase()}`, name.slice(operationPrefix.length))];
|
|
193
|
-
}
|
|
177
|
+
const isSchemaPointer = (pointer) => !!pointer?.startsWith(refPrefix) && !pointer.slice(21).includes("/");
|
|
194
178
|
/**
|
|
195
179
|
* A property type without `| null` and one level of `T[]` or `Array<T>`, which the spec writes under `items`.
|
|
196
180
|
*/
|
|
@@ -223,12 +207,13 @@ function typeMembers(statement) {
|
|
|
223
207
|
* and operation types to the operation, parameters, request body or response. A schema type named
|
|
224
208
|
* exactly like its key is verbatim, so a rename in TypeScript renames the key. A reference to a
|
|
225
209
|
* schema type maps to the end of the `$ref` that points at that schema, so the rename updates it too.
|
|
210
|
+
* `pointers` maps each emitted declaration name to the JSON pointer it came from.
|
|
226
211
|
*/
|
|
227
|
-
function createMappings(text, content, { locate, locateValue },
|
|
212
|
+
function createMappings(text, content, { locate, locateValue }, pointers) {
|
|
228
213
|
const sourceFile = ts.createSourceFile("index.ts", text, ts.ScriptTarget.Latest, true);
|
|
229
214
|
const segments = [];
|
|
230
|
-
const add = (name, rename,
|
|
231
|
-
const range =
|
|
215
|
+
const add = (name, rename, pointer) => {
|
|
216
|
+
const range = pointer ? locate(pointer) : void 0;
|
|
232
217
|
if (!range) return;
|
|
233
218
|
const verbatim = rename && content.slice(range.start, range.end) === name.getText(sourceFile);
|
|
234
219
|
segments.push([
|
|
@@ -244,7 +229,7 @@ function createMappings(text, content, { locate, locateValue }, targets) {
|
|
|
244
229
|
if (!inner || !ts.isTypeReferenceNode(inner.type) || !ts.isIdentifier(inner.type.typeName)) return;
|
|
245
230
|
const reference = inner.type.typeName;
|
|
246
231
|
const name = reference.text;
|
|
247
|
-
if (!
|
|
232
|
+
if (!isSchemaPointer(pointers.get(name))) return;
|
|
248
233
|
const range = locateValue(`${pointer}${inner.items ? "/items" : ""}/$ref`);
|
|
249
234
|
if (!range) return;
|
|
250
235
|
const start = range.start + content.slice(range.start, range.end).replace(/['"]$/, "").length - name.length;
|
|
@@ -270,27 +255,38 @@ function createMappings(text, content, { locate, locateValue }, targets) {
|
|
|
270
255
|
};
|
|
271
256
|
for (const statement of sourceFile.statements) {
|
|
272
257
|
if (ts.isVariableStatement(statement)) {
|
|
273
|
-
for (const declaration of statement.declarationList.declarations)
|
|
274
|
-
if (!ts.isIdentifier(declaration.name)) continue;
|
|
275
|
-
const name = declaration.name.text;
|
|
276
|
-
add(declaration.name, false, ...declarationPointers(name, targets), ...declarationPointers(name[0].toUpperCase() + name.slice(1), targets));
|
|
277
|
-
}
|
|
258
|
+
for (const declaration of statement.declarationList.declarations) if (ts.isIdentifier(declaration.name)) add(declaration.name, false, pointers.get(declaration.name.text));
|
|
278
259
|
continue;
|
|
279
260
|
}
|
|
280
261
|
if (!ts.isTypeAliasDeclaration(statement) && !ts.isInterfaceDeclaration(statement)) continue;
|
|
281
|
-
const
|
|
282
|
-
const isSchema =
|
|
283
|
-
add(statement.name, isSchema,
|
|
284
|
-
|
|
285
|
-
if (!pointer || !isSchema) continue;
|
|
262
|
+
const pointer = pointers.get(statement.name.text);
|
|
263
|
+
const isSchema = isSchemaPointer(pointer);
|
|
264
|
+
add(statement.name, isSchema, pointer);
|
|
265
|
+
if (!isSchema) continue;
|
|
286
266
|
const members = typeMembers(statement);
|
|
287
267
|
if (members) addMembers(members, pointer);
|
|
288
268
|
else if (ts.isTypeAliasDeclaration(statement)) addRef(unwrap(statement.type), pointer);
|
|
289
269
|
}
|
|
290
270
|
return segments;
|
|
291
271
|
}
|
|
292
|
-
|
|
293
|
-
|
|
272
|
+
// src/transform.ts
|
|
273
|
+
const isUrl = (source) => /^https?:\/\//i.test(source);
|
|
274
|
+
const toDependencies = (sources) => Object.fromEntries(sources.filter((source) => !isUrl(source)).map((file) => [file, readOrNull(file)]));
|
|
275
|
+
/**
|
|
276
|
+
* The files that external `$ref`s in the spec at `fileName` read, with the spec as saved on disk.
|
|
277
|
+
*/
|
|
278
|
+
async function readDependencies(fileName) {
|
|
279
|
+
const input = parse(await readFile(fileName, "utf8"));
|
|
280
|
+
const { sources } = await generateModule({
|
|
281
|
+
root: dirname(fileName),
|
|
282
|
+
input,
|
|
283
|
+
config: {
|
|
284
|
+
output: { path: "." },
|
|
285
|
+
plugins: []
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
return sources.filter((source) => !isUrl(source));
|
|
289
|
+
}
|
|
294
290
|
const scanner = ts.createScanner(ts.ScriptTarget.Latest, true);
|
|
295
291
|
function isPlainIdentifier(name) {
|
|
296
292
|
scanner.setText(name);
|
|
@@ -338,22 +334,11 @@ async function transform({ fileName, content }, config) {
|
|
|
338
334
|
}))
|
|
339
335
|
};
|
|
340
336
|
const hooks = new Hookable();
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
};
|
|
345
|
-
hooks.hook("kubb:generate:schema", (node, { resolver }) => {
|
|
346
|
-
if (node.name) targets.schemas.set(resolver.name(node.name), node.name);
|
|
337
|
+
const pointers = /* @__PURE__ */ new Map();
|
|
338
|
+
hooks.hook("kubb:build:end", ({ files }) => {
|
|
339
|
+
for (const source of files.flatMap((file) => file.sources)) if (source.name && source.pointer) pointers.set(source.name, source.pointer);
|
|
347
340
|
});
|
|
348
|
-
|
|
349
|
-
if (!("path" in node && node.path && node.method)) return;
|
|
350
|
-
const target = {
|
|
351
|
-
path: node.path,
|
|
352
|
-
method: node.method
|
|
353
|
-
};
|
|
354
|
-
targets.operations.set(resolver.name(node.operationId), target).set(resolverTs.name(node.operationId), target);
|
|
355
|
-
});
|
|
356
|
-
const { text, errors } = await generateModule({
|
|
341
|
+
const { text, errors, sources } = await generateModule({
|
|
357
342
|
root: dirname(fileName),
|
|
358
343
|
input: document.toJS(),
|
|
359
344
|
config: keepSpecCasing(config ?? {
|
|
@@ -363,6 +348,7 @@ async function transform({ fileName, content }, config) {
|
|
|
363
348
|
hooks
|
|
364
349
|
});
|
|
365
350
|
const locate = createLocator(document);
|
|
351
|
+
const dependencies = toDependencies(sources);
|
|
366
352
|
if (errors.length) return {
|
|
367
353
|
text: "export {}",
|
|
368
354
|
extension: ".ts",
|
|
@@ -373,7 +359,8 @@ async function transform({ fileName, content }, config) {
|
|
|
373
359
|
start: range?.start ?? 0,
|
|
374
360
|
length: range ? range.end - range.start : 0
|
|
375
361
|
};
|
|
376
|
-
})
|
|
362
|
+
}),
|
|
363
|
+
dependencies
|
|
377
364
|
};
|
|
378
365
|
if (config && !text) return {
|
|
379
366
|
text: "export {}",
|
|
@@ -382,7 +369,8 @@ async function transform({ fileName, content }, config) {
|
|
|
382
369
|
messageText: "kubb.config.ts generated no code for this spec. Add a plugin such as pluginTs().",
|
|
383
370
|
start: 0,
|
|
384
371
|
length: 0
|
|
385
|
-
}]
|
|
372
|
+
}],
|
|
373
|
+
dependencies
|
|
386
374
|
};
|
|
387
375
|
return {
|
|
388
376
|
text,
|
|
@@ -393,15 +381,32 @@ async function transform({ fileName, content }, config) {
|
|
|
393
381
|
pointer,
|
|
394
382
|
value: true
|
|
395
383
|
})
|
|
396
|
-
},
|
|
384
|
+
}, pointers),
|
|
385
|
+
dependencies
|
|
397
386
|
};
|
|
398
387
|
}
|
|
399
|
-
|
|
400
|
-
//#region src/server.ts
|
|
388
|
+
// src/server.ts
|
|
401
389
|
const writeProtocol = process.stdout.write.bind(process.stdout);
|
|
402
390
|
process.stdout.write = process.stderr.write.bind(process.stderr);
|
|
403
391
|
const projects = /* @__PURE__ */ new Map();
|
|
404
392
|
const cachedTransform = cacheTransform(transform);
|
|
393
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
394
|
+
/**
|
|
395
|
+
* The files that external `$ref`s read in the specs under the tsconfig folder, outside
|
|
396
|
+
* `node_modules`, with an extension that `contentMappers` maps to this package. TypeScript only
|
|
397
|
+
* watches what `openProject` returns, so these are found before the first transform.
|
|
398
|
+
*/
|
|
399
|
+
async function findDependencies(configFileName) {
|
|
400
|
+
const { config } = ts.readConfigFile(configFileName, ts.sys.readFile);
|
|
401
|
+
const extensions = (config?.contentMappers ?? []).filter((mapper) => mapper.package === "openapi-import").flatMap((mapper) => mapper.extensions ?? []);
|
|
402
|
+
if (!extensions.length) return [];
|
|
403
|
+
const dir = dirname(configFileName);
|
|
404
|
+
const specs = globSync(extensions.map((extension) => `**/*${extension}`), {
|
|
405
|
+
cwd: dir,
|
|
406
|
+
exclude: (file) => basename(String(file)) === "node_modules"
|
|
407
|
+
});
|
|
408
|
+
return (await Promise.all(specs.map((spec) => readDependencies(resolve(dir, spec)).catch(() => [])))).flat();
|
|
409
|
+
}
|
|
405
410
|
const handlers = {
|
|
406
411
|
initialize: () => ({
|
|
407
412
|
protocolVersion: 1,
|
|
@@ -412,9 +417,12 @@ const handlers = {
|
|
|
412
417
|
const loading = loadProjectConfig(configFileName ? dirname(configFileName) : process.cwd());
|
|
413
418
|
projects.set(projectHandle, loading);
|
|
414
419
|
const project = await loading;
|
|
420
|
+
for (const file of configFileName ? await findDependencies(configFileName) : []) dependencies.add(file);
|
|
421
|
+
const identity = createHash("sha256").update(project.identity);
|
|
422
|
+
for (const file of dependencies) identity.update(`\0${file}\0${readOrNull(file) ?? ""}`);
|
|
415
423
|
return {
|
|
416
|
-
configIdentity: project.identity,
|
|
417
|
-
watchedFiles: project.watchedFiles,
|
|
424
|
+
configIdentity: dependencies.size ? identity.digest("hex") : project.identity,
|
|
425
|
+
watchedFiles: [.../* @__PURE__ */ new Set([...project.watchedFiles, ...dependencies])],
|
|
418
426
|
...options != null && { optionDiagnostics: [{
|
|
419
427
|
path: [],
|
|
420
428
|
messageText: "openapi-import has no options. Set plugin options in kubb.config.ts."
|
|
@@ -436,11 +444,13 @@ const handlers = {
|
|
|
436
444
|
length: 0
|
|
437
445
|
}]
|
|
438
446
|
};
|
|
439
|
-
|
|
447
|
+
const { dependencies: files, ...result } = await cachedTransform(params, project && selectConfig({
|
|
440
448
|
configs: project.configs,
|
|
441
449
|
fileName: params.fileName,
|
|
442
450
|
cwd: project.dir
|
|
443
451
|
}));
|
|
452
|
+
for (const file of Object.keys(files ?? {})) dependencies.add(file);
|
|
453
|
+
return result;
|
|
444
454
|
}
|
|
445
455
|
};
|
|
446
456
|
async function handle({ id, method = "", params }) {
|
|
@@ -473,7 +483,6 @@ async function handle({ id, method = "", params }) {
|
|
|
473
483
|
}
|
|
474
484
|
}
|
|
475
485
|
process.stdin.on("data", createDecoder((message) => void handle(message)));
|
|
476
|
-
//#endregion
|
|
477
486
|
export {};
|
|
478
487
|
|
|
479
488
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","names":[],"sources":["../src/cache.ts","../src/config.ts","../src/rpc.ts","../src/locate.ts","../src/mappings.ts","../src/transform.ts","../src/server.ts"],"sourcesContent":["import type { UserConfig } from 'kubb'\nimport type { TransformParams } from './transform.ts'\n\n/**\n * Wraps a transform so a repeated request for the same file, content and config returns the\n * previous result. TypeScript asks again for specs it already transformed (another project, a\n * reload), and a Kubb build of a large spec takes seconds. A failed transform is not kept.\n */\nexport function cacheTransform<TResult>(\n transform: (params: TransformParams, config?: UserConfig) => Promise<TResult>,\n): (params: TransformParams, config?: UserConfig) => Promise<TResult> {\n const results = new Map<string, { content: string; config?: UserConfig; result: Promise<TResult> }>()\n\n return (params, config) => {\n const cached = results.get(params.fileName)\n // A reloaded config is a new object, so comparing by reference catches every config change.\n if (cached && cached.content === params.content && cached.config === config) return cached.result\n\n const result = transform(params, config)\n results.set(params.fileName, { content: params.content, config, result })\n result.catch(() => results.delete(params.fileName))\n return result\n }\n}\n","import { createHash } from 'node:crypto'\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { UserConfig } from 'kubb'\nimport { configFileCandidates, findConfigFile, loadConfigFile } from 'unplugin-kubb'\n\n/**\n * A Kubb config found for a TypeScript project, with what TypeScript needs to reload it.\n */\nexport type ProjectConfig = {\n /**\n * The project folder.\n */\n dir: string\n /**\n * The configs the file exports, empty when there is no config file.\n */\n configs: Array<UserConfig>\n /**\n * The config file, plus every file the CLI would pick up in `dir`, so adding one reloads too.\n */\n watchedFiles: Array<string>\n /**\n * Changes when the config file changes, so TypeScript transforms its specs again.\n */\n identity: string\n /**\n * Why the config file failed to load. Each transform reports it on the spec.\n */\n error?: string\n}\n\n/**\n * Finds the Kubb config the way the Kubb CLI does, from `dir` up, and loads it. A config that\n * exports a function is called with no CLI options.\n */\nexport async function loadProjectConfig(dir: string): Promise<ProjectConfig> {\n dir = resolve(dir)\n const file = findConfigFile(dir)\n const watchedFiles = [...new Set([...(file ? [file] : []), ...configFileCandidates(dir)])]\n if (!file) return { dir, configs: [], watchedFiles, identity: 'none' }\n\n const identity = createHash('sha256').update(readFileSync(file)).digest('hex')\n try {\n return { dir, configs: await loadConfigFile<UserConfig>({ file, cli: {} }), watchedFiles, identity }\n } catch (error) {\n return { dir, configs: [], watchedFiles, identity, error: `${file} failed to load: ${error instanceof Error ? error.message : String(error)}` }\n }\n}\n","/**\n * A JSON-RPC 2.0 message as the TypeScript content mapper host sends and expects it.\n */\nexport type Message = {\n id?: number | string\n method?: string\n params?: unknown\n result?: unknown\n error?: { code: number; message: string }\n}\n\nconst separator = '\\r\\n\\r\\n'\n\n/**\n * Frames a message with the LSP base protocol `Content-Length` header the host reads.\n */\nexport function encode(message: Message): Buffer {\n const body = Buffer.from(JSON.stringify({ jsonrpc: '2.0', ...message }))\n\n return Buffer.concat([Buffer.from(`Content-Length: ${body.length}${separator}`), body])\n}\n\n/**\n * Returns a stream handler that collects `Content-Length` framed chunks and calls `onMessage`\n * once per complete message, however the chunks split the frames.\n */\nexport function createDecoder(onMessage: (message: Message) => void): (chunk: Buffer) => void {\n let buffer = Buffer.alloc(0)\n\n return (chunk) => {\n buffer = Buffer.concat([buffer, chunk])\n\n while (true) {\n const headerEnd = buffer.indexOf(separator)\n if (headerEnd === -1) return\n\n const header = buffer.subarray(0, headerEnd).toString()\n const length = Number(/content-length:\\s*(\\d+)/i.exec(header)?.[1])\n if (!Number.isInteger(length)) throw new Error(`Missing Content-Length header in \"${header}\"`)\n\n const start = headerEnd + separator.length\n if (buffer.length < start + length) return\n\n const body = buffer.subarray(start, start + length).toString()\n buffer = buffer.subarray(start + length)\n onMessage(JSON.parse(body) as Message)\n }\n }\n}\n","import * as yaml from 'yaml'\n\n/**\n * A range in the spec text, as `[start, end)` offsets.\n */\nexport type Range = { start: number; end: number }\n\nconst toRange = ([start, end]: yaml.Range): Range => ({ start, end })\n\nconst unescapeToken = (token: string) => token.replaceAll('~1', '/').replaceAll('~0', '~')\n\n/**\n * Walks a JSON pointer through maps and sequences; the range is the last key or item it reached,\n * or with `value` the scalar value of that key.\n */\nfunction findPointer(document: yaml.Document, pointer: string, value = false): Range | undefined {\n const tokens = pointer.replace(/^#/, '').split('/').slice(1).map(unescapeToken)\n const reached = tokens.reduce<{ node: unknown; range: Range | undefined } | undefined>(\n (at, token) => {\n if (yaml.isMap(at?.node)) {\n const pair = at.node.items.find((item) => yaml.isScalar(item.key) && String(item.key.value) === token)\n return pair && yaml.isScalar(pair.key) && pair.key.range ? { node: pair.value, range: toRange(pair.key.range) } : undefined\n }\n if (yaml.isSeq(at?.node)) {\n const item = at.node.items[Number(token)]\n return yaml.isNode(item) && item.range ? { node: item, range: toRange(item.range) } : undefined\n }\n return undefined\n },\n { node: document.contents, range: undefined },\n )\n if (!value) return reached?.range\n return yaml.isScalar(reached?.node) && reached.node.range ? toRange(reached.node.range) : undefined\n}\n\n/**\n * The first `$ref` whose value is `ref`.\n */\nfunction findRefUsage(document: yaml.Document, ref: string): Range | undefined {\n let found: Range | undefined\n yaml.visit(document, {\n Pair(_, { key, value }) {\n if (!yaml.isScalar(key) || key.value !== '$ref' || !yaml.isScalar(value) || value.value !== ref || !value.range) return\n found = toRange(value.range)\n return yaml.visit.BREAK\n },\n })\n return found\n}\n\n/**\n * Maps JSON pointers to ranges in an already parsed spec, the same way `@kubb/adapter-oas`'s\n * `locate` does from the spec text. Reusing the document the build parsed saves a second parse of\n * the spec on every transform. An unresolved `$ref` falls back to its first usage.\n */\nexport function createLocator(document: yaml.Document): (location: { pointer: string; ref?: string; value?: boolean }) => Range | undefined {\n return ({ pointer, ref, value }) => findPointer(document, pointer, value) ?? (ref ? findRefUsage(document, ref) : undefined)\n}\n","import ts from '@typescript/typescript6'\n\n/**\n * A span map segment in the tuple form TypeScript reads:\n * `[virtualStart, virtualLength, originalStart, originalLength, kind, features]`.\n */\nexport type Segment = [number, number, number, number, number, number]\n\n/**\n * What the build saw, keyed by the names `@kubb/plugin-ts` emitted.\n */\nexport type Targets = {\n /**\n * Emitted type name to the `components.schemas` key it came from.\n */\n schemas: Map<string, string>\n /**\n * Emitted operation name prefix (such as `GetPetById`) to its path and method.\n */\n operations: Map<string, { path: string; method: string }>\n}\n\ntype Locate = (pointer: string) => { start: number; end: number } | undefined\n\n/**\n * Finds a spec key (`locate`) or the scalar value of a key (`locateValue`) from a JSON pointer.\n */\ntype Locators = { locate: Locate; locateValue: Locate }\n\nconst kindVerbatim = 0\nconst kindAlias = 2\n// Hover, Definition, TypeDefinition, Implementation, References, DocumentHighlights.\nconst features = 1 | 8 | 16 | 32 | 64 | 128\n// Only schema names rename into the spec. A stale `$ref` shows as an error, but a stale `required` entry fails silently.\nconst renameFeature = 256\n\nconst refPrefix = '#/components/schemas/'\n\nconst escapeToken = (token: string) => token.replaceAll('~', '~0').replaceAll('/', '~1')\n\n/**\n * Narrows an operation type to the part of the operation it was generated from, by the suffix\n * `@kubb/plugin-ts` appends to the operation name.\n */\nfunction operationPointer(base: string, suffix: string): string {\n const status = /^Status(\\d{3}|Default)/.exec(suffix)?.[1]\n if (status) return `${base}/responses/${status === 'Default' ? 'default' : status}`\n if (/^(Path|Query|Header)/.test(suffix)) return `${base}/parameters`\n if (/^(Body|Request|MutationRequest)/.test(suffix)) return `${base}/requestBody`\n return base\n}\n\nconst longestPrefix = (keys: Iterable<string>, name: string) => [...keys].filter((key) => name.startsWith(key)).sort((a, b) => b.length - a.length)[0]\n\n/**\n * Pointers to try for one declaration, most specific first. Enums extracted from a schema property\n * (`OrderStatusEnumKey`, `orderStatusEnum`) point at that property, then at the schema.\n */\nfunction declarationPointers(name: string, { schemas, operations }: Targets): Array<string> {\n const schema = schemas.get(name)\n if (schema) return [`#/components/schemas/${escapeToken(schema)}`]\n\n const schemaPrefix = longestPrefix(schemas.keys(), name)\n const operationPrefix = longestPrefix(operations.keys(), name)\n\n if (schemaPrefix !== undefined && (operationPrefix === undefined || schemaPrefix.length > operationPrefix.length)) {\n const base = `#/components/schemas/${escapeToken(schemas.get(schemaPrefix)!)}`\n const property = name.slice(schemaPrefix.length).replace(/(Enum)?Key$|Enum$/, '')\n return property ? [`${base}/properties/${escapeToken(property[0]!.toLowerCase() + property.slice(1))}`, base] : [base]\n }\n if (operationPrefix === undefined) return []\n\n const { path, method } = operations.get(operationPrefix)!\n return [operationPointer(`#/paths/${escapeToken(path)}/${method.toLowerCase()}`, name.slice(operationPrefix.length))]\n}\n\n/**\n * A property type without `| null` and one level of `T[]` or `Array<T>`, which the spec writes under `items`.\n */\nfunction unwrap(type: ts.TypeNode | undefined): { type: ts.TypeNode; items: boolean } | undefined {\n const members =\n type && ts.isUnionTypeNode(type)\n ? type.types.filter((member) => !(ts.isLiteralTypeNode(member) && member.literal.kind === ts.SyntaxKind.NullKeyword))\n : [type]\n const [single] = members.length === 1 ? members : []\n if (!single) return undefined\n if (ts.isArrayTypeNode(single)) return { type: single.elementType, items: true }\n if (ts.isTypeReferenceNode(single) && single.typeName.getText() === 'Array' && single.typeArguments?.length === 1)\n return { type: single.typeArguments[0]!, items: true }\n return { type: single, items: false }\n}\n\n/**\n * The members of an interface, or of a type alias for an object literal.\n */\nfunction typeMembers(statement: ts.TypeAliasDeclaration | ts.InterfaceDeclaration): ts.NodeArray<ts.TypeElement> | undefined {\n if (ts.isInterfaceDeclaration(statement)) return statement.members\n return ts.isTypeLiteralNode(statement.type) ? statement.type.members : undefined\n}\n\n/**\n * Links generated names to the spec keys they came from: schemas and their (nested) properties,\n * and operation types to the operation, parameters, request body or response. A schema type named\n * exactly like its key is verbatim, so a rename in TypeScript renames the key. A reference to a\n * schema type maps to the end of the `$ref` that points at that schema, so the rename updates it too.\n */\nexport function createMappings(text: string, content: string, { locate, locateValue }: Locators, targets: Targets): Array<Segment> {\n const sourceFile = ts.createSourceFile('index.ts', text, ts.ScriptTarget.Latest, true)\n const segments: Array<Segment> = []\n\n const add = (name: ts.Node, rename: boolean, ...pointers: Array<string>) => {\n const range = pointers.map(locate).find(Boolean)\n if (!range) return\n const verbatim = rename && content.slice(range.start, range.end) === name.getText(sourceFile)\n segments.push([\n name.getStart(sourceFile),\n name.getWidth(sourceFile),\n range.start,\n range.end - range.start,\n verbatim ? kindVerbatim : kindAlias,\n verbatim ? features | renameFeature : features,\n ])\n }\n\n // Only a reference whose `$ref` ends in the same text renames; anything else would break the spec.\n const addRef = (inner: ReturnType<typeof unwrap>, pointer: string) => {\n if (!inner || !ts.isTypeReferenceNode(inner.type) || !ts.isIdentifier(inner.type.typeName)) return\n const reference = inner.type.typeName\n const name = reference.text\n if (!targets.schemas.has(name)) return\n const range = locateValue(`${pointer}${inner.items ? '/items' : ''}/$ref`)\n if (!range) return\n // The `$ref` value may be quoted, so count the name back from the end of its text.\n const start = range.start + content.slice(range.start, range.end).replace(/['\"]$/, '').length - name.length\n if (content.slice(start - refPrefix.length, start + name.length) !== refPrefix + name) return\n segments.push([reference.getStart(sourceFile), reference.getWidth(sourceFile), start, name.length, kindVerbatim, features | renameFeature])\n }\n\n const addMembers = (members: ts.NodeArray<ts.TypeElement>, pointer: string) => {\n for (const member of members) {\n if (!ts.isPropertySignature(member) || !(ts.isIdentifier(member.name) || ts.isStringLiteral(member.name))) continue\n const propertyPointer = `${pointer}/properties/${escapeToken(member.name.text)}`\n add(member.name, false, propertyPointer)\n const inner = unwrap(member.type)\n addRef(inner, propertyPointer)\n if (inner && ts.isTypeLiteralNode(inner.type)) addMembers(inner.type.members, inner.items ? `${propertyPointer}/items` : propertyPointer)\n }\n }\n\n for (const statement of sourceFile.statements) {\n if (ts.isVariableStatement(statement)) {\n // Enum objects (`export const orderStatusEnum = { ... } as const`) match like their `Key` type.\n for (const declaration of statement.declarationList.declarations) {\n if (!ts.isIdentifier(declaration.name)) continue\n const name = declaration.name.text\n add(declaration.name, false, ...declarationPointers(name, targets), ...declarationPointers(name[0]!.toUpperCase() + name.slice(1), targets))\n }\n continue\n }\n if (!ts.isTypeAliasDeclaration(statement) && !ts.isInterfaceDeclaration(statement)) continue\n const pointers = declarationPointers(statement.name.text, targets)\n const isSchema = targets.schemas.has(statement.name.text)\n add(statement.name, isSchema, ...pointers)\n\n // Property names only resolve under a schema, not under operation parameters or responses.\n const pointer = pointers[0]\n if (!pointer || !isSchema) continue\n const members = typeMembers(statement)\n if (members) addMembers(members, pointer)\n else if (ts.isTypeAliasDeclaration(statement)) addRef(unwrap(statement.type), pointer)\n }\n\n return segments\n}\n","import { dirname } from 'node:path'\nimport ts from '@typescript/typescript6'\nimport type { UserConfig } from 'kubb'\nimport { Hookable, type KubbHooks } from 'kubb/kit'\nimport { pluginTs, pluginTsName, resolverTs } from '@kubb/plugin-ts'\nimport { generateModule } from 'unplugin-kubb'\nimport { parseDocument } from 'yaml'\nimport { createLocator } from './locate.ts'\nimport { createMappings, type Segment, type Targets } from './mappings.ts'\n\n/**\n * Parameters of the content mapper `transform` request.\n */\nexport type TransformParams = {\n fileName: string\n content: string\n}\n\n/**\n * The module TypeScript checks in place of the spec, and the segments linking it to the spec.\n */\nexport type TransformResult = {\n text: string\n extension: '.ts'\n mappings?: Array<Segment>\n diagnostics?: Array<{ messageText: string; start: number; length: number }>\n}\n\nconst scanner = ts.createScanner(ts.ScriptTarget.Latest, true)\n\n// A keyword such as `string` or `class` scans as a keyword, not an identifier, so it is not kept.\nfunction isPlainIdentifier(name: string): boolean {\n scanner.setText(name)\n return scanner.scan() === ts.SyntaxKind.Identifier && scanner.getTokenEnd() === name.length\n}\n\n/**\n * Keeps a name that is already a valid type name as the spec wrote it (`pet`, `PET_STATUS`), so a\n * schema type matches its key and renames it. Composed names such as `getPetById Status 200` and\n * keys that are not identifiers keep the `@kubb/plugin-ts` PascalCase.\n */\nconst specName = (name: string) => (isPlainIdentifier(name) ? name : resolverTs.name(name))\n\n/**\n * Lets `@kubb/plugin-ts` name schema types after their spec keys, unless the config sets its own `resolver.name`.\n */\nfunction keepSpecCasing(config: UserConfig): UserConfig {\n return {\n ...config,\n plugins: config.plugins?.map((plugin) =>\n plugin.name === pluginTsName\n ? { ...plugin, options: { ...plugin.options, resolver: { name: specName, ...(plugin.options as { resolver?: object })?.resolver } } }\n : plugin,\n ),\n }\n}\n\n/**\n * Generates the module for one spec with `generateModule` from `unplugin-kubb`, the same one a\n * bundler loads. Without a config, only `@kubb/plugin-ts` runs. The spec text comes from the\n * request, so unsaved edits are checked too. It is parsed once and shared by the build, the\n * diagnostics and the mappings.\n */\nexport async function transform({ fileName, content }: TransformParams, config?: UserConfig): Promise<TransformResult> {\n const document = parseDocument(content)\n if (document.errors.length) {\n return {\n text: 'export {}',\n extension: '.ts',\n diagnostics: document.errors.map((error) => ({ messageText: error.message, start: error.pos[0], length: error.pos[1] - error.pos[0] })),\n }\n }\n\n const hooks = new Hookable<KubbHooks>()\n const targets: Targets = { schemas: new Map(), operations: new Map() }\n hooks.hook('kubb:generate:schema', (node, { resolver }) => {\n if (node.name) targets.schemas.set(resolver.name(node.name), node.name)\n })\n hooks.hook('kubb:generate:operation', (node, { resolver }) => {\n if (!('path' in node && node.path && node.method)) return\n // Operation types are always PascalCase, whatever casing a schema type keeps.\n const target = { path: node.path, method: node.method }\n targets.operations.set(resolver.name(node.operationId), target).set(resolverTs.name(node.operationId), target)\n })\n\n const { text, errors } = await generateModule({\n root: dirname(fileName),\n input: document.toJS(),\n config: keepSpecCasing(config ?? { output: { path: '.' }, plugins: [pluginTs()] }),\n hooks,\n })\n\n const locate = createLocator(document)\n\n if (errors.length) {\n return {\n text: 'export {}',\n extension: '.ts',\n diagnostics: errors.map((error) => {\n const range = error.location && 'pointer' in error.location ? locate(error.location) : undefined\n return { messageText: error.message, start: range?.start ?? 0, length: range ? range.end - range.start : 0 }\n }),\n }\n }\n\n if (config && !text) {\n return {\n text: 'export {}',\n extension: '.ts',\n diagnostics: [{ messageText: 'kubb.config.ts generated no code for this spec. Add a plugin such as pluginTs().', start: 0, length: 0 }],\n }\n }\n\n return {\n text,\n extension: '.ts',\n mappings: createMappings(text, content, { locate: (pointer) => locate({ pointer }), locateValue: (pointer) => locate({ pointer, value: true }) }, targets),\n }\n}\n","import { dirname } from 'node:path'\nimport { selectConfig } from 'unplugin-kubb'\nimport { cacheTransform } from './cache.ts'\nimport { loadProjectConfig, type ProjectConfig } from './config.ts'\nimport { createDecoder, encode, type Message } from './rpc.ts'\nimport { transform, type TransformParams } from './transform.ts'\n\n// stdout carries the protocol, so every other stdout write (any console method, direct writes from\n// Kubb or its plugins) goes to stderr.\nconst writeProtocol = process.stdout.write.bind(process.stdout)\nprocess.stdout.write = process.stderr.write.bind(process.stderr) as typeof process.stdout.write\n\n// The load promise is stored right away, so a transform sent before the load finishes waits for it.\nconst projects = new Map<string, Promise<ProjectConfig>>()\n\nconst cachedTransform = cacheTransform(transform)\n\nconst handlers: Record<string, (params: never) => unknown> = {\n initialize: () => ({ protocolVersion: 1, positionEncoding: 'utf-16', diagnosticSource: 'kubb' }),\n // `dynamicConfig` in package.json: TypeScript watches `watchedFiles` and opens the project again\n // when one changes, then transforms its specs again when `configIdentity` differs.\n openProject: async ({ projectHandle, configFileName, options }: { projectHandle: string; configFileName?: string; options?: unknown }) => {\n const loading = loadProjectConfig(configFileName ? dirname(configFileName) : process.cwd())\n projects.set(projectHandle, loading)\n const project = await loading\n\n return {\n configIdentity: project.identity,\n watchedFiles: project.watchedFiles,\n ...(options != null && { optionDiagnostics: [{ path: [], messageText: 'openapi-import has no options. Set plugin options in kubb.config.ts.' }] }),\n }\n },\n closeProject: ({ projectHandle }: { projectHandle: string }) => {\n projects.delete(projectHandle)\n return null\n },\n transform: async (params: TransformParams & { projectHandle: string }) => {\n const project = await projects.get(params.projectHandle)\n if (project?.error) return { text: 'export {}', extension: '.ts', diagnostics: [{ messageText: project.error, start: 0, length: 0 }] }\n\n return cachedTransform(params, project && selectConfig({ configs: project.configs, fileName: params.fileName, cwd: project.dir }))\n },\n}\n\nasync function handle({ id, method = '', params }: Message): Promise<void> {\n const handler = handlers[method]\n if (id === undefined) return\n\n try {\n if (!handler) {\n writeProtocol(encode({ id, error: { code: -32601, message: `Unknown method \"${method}\"` } }))\n return\n }\n const result = await handler(params as never)\n writeProtocol(encode({ id, result: result ?? null }))\n } catch (error) {\n writeProtocol(encode({ id, error: { code: -32603, message: error instanceof Error ? (error.stack ?? error.message) : String(error) } }))\n }\n}\n\nprocess.stdin.on(\n 'data',\n createDecoder((message) => void handle(message)),\n)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","names":[],"sources":["../src/cache.ts","../src/config.ts","../src/rpc.ts","../src/locate.ts","../src/mappings.ts","../src/transform.ts","../src/server.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport type { UserConfig } from 'kubb'\nimport type { TransformParams, TransformResult } from './transform.ts'\n\n/**\n * The text of `file`, or `null` when it cannot be read.\n */\nexport const readOrNull = (file: string): string | null => {\n try {\n return readFileSync(file, 'utf8')\n } catch {\n return null\n }\n}\n\n/**\n * Wraps a transform so a repeated request for the same file, content and config returns the\n * previous result. TypeScript asks again for specs it already transformed (another project, a\n * reload, a changed file next to the spec), and a Kubb build of a large spec takes seconds. A\n * result whose `dependencies` changed on disk, the files its external `$ref`s read, is\n * transformed again. A failed transform is not kept.\n */\nexport function cacheTransform<TResult extends Pick<TransformResult, 'text' | 'dependencies'>>(\n transform: (params: TransformParams, config?: UserConfig) => Promise<TResult>,\n): (params: TransformParams, config?: UserConfig) => Promise<TResult> {\n const results = new Map<string, { content: string; config?: UserConfig; result: Promise<TResult> }>()\n\n const run = (params: TransformParams, config?: UserConfig) => {\n const result = transform(params, config)\n results.set(params.fileName, { content: params.content, config, result })\n result.catch(() => results.delete(params.fileName))\n return result\n }\n\n return async (params, config) => {\n const cached = results.get(params.fileName)\n // A reloaded config is a new object, so comparing by reference catches every config change.\n if (!cached || cached.content !== params.content || cached.config !== config) return run(params, config)\n\n const result = await cached.result\n const fresh = Object.entries(result.dependencies ?? {}).every(([file, text]) => readOrNull(file) === text)\n return fresh ? result : run(params, config)\n }\n}\n","import { createHash } from 'node:crypto'\nimport { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { UserConfig } from 'kubb'\nimport { configFileCandidates, findConfigFile, loadConfigFile } from 'unplugin-kubb'\n\n/**\n * A Kubb config found for a TypeScript project, with what TypeScript needs to reload it.\n */\nexport type ProjectConfig = {\n /**\n * The project folder.\n */\n dir: string\n /**\n * The configs the file exports, empty when there is no config file.\n */\n configs: Array<UserConfig>\n /**\n * The config file, plus every file the CLI would pick up in `dir`, so adding one reloads too.\n */\n watchedFiles: Array<string>\n /**\n * Changes when the config file changes, so TypeScript transforms its specs again.\n */\n identity: string\n /**\n * Why the config file failed to load. Each transform reports it on the spec.\n */\n error?: string\n}\n\n/**\n * Finds the Kubb config the way the Kubb CLI does, from `dir` up, and loads it. A config that\n * exports a function is called with no CLI options.\n */\nexport async function loadProjectConfig(dir: string): Promise<ProjectConfig> {\n dir = resolve(dir)\n const file = findConfigFile(dir)\n const watchedFiles = [...new Set([...(file ? [file] : []), ...configFileCandidates(dir)])]\n if (!file) return { dir, configs: [], watchedFiles, identity: 'none' }\n\n const identity = createHash('sha256').update(readFileSync(file)).digest('hex')\n try {\n return { dir, configs: await loadConfigFile<UserConfig>({ file, cli: {} }), watchedFiles, identity }\n } catch (error) {\n return { dir, configs: [], watchedFiles, identity, error: `${file} failed to load: ${error instanceof Error ? error.message : String(error)}` }\n }\n}\n","/**\n * A JSON-RPC 2.0 message as the TypeScript content mapper host sends and expects it.\n */\nexport type Message = {\n id?: number | string\n method?: string\n params?: unknown\n result?: unknown\n error?: { code: number; message: string }\n}\n\nconst separator = '\\r\\n\\r\\n'\n\n/**\n * Frames a message with the LSP base protocol `Content-Length` header the host reads.\n */\nexport function encode(message: Message): Buffer {\n const body = Buffer.from(JSON.stringify({ jsonrpc: '2.0', ...message }))\n\n return Buffer.concat([Buffer.from(`Content-Length: ${body.length}${separator}`), body])\n}\n\n/**\n * Returns a stream handler that collects `Content-Length` framed chunks and calls `onMessage`\n * once per complete message, however the chunks split the frames.\n */\nexport function createDecoder(onMessage: (message: Message) => void): (chunk: Buffer) => void {\n let buffer = Buffer.alloc(0)\n\n return (chunk) => {\n buffer = Buffer.concat([buffer, chunk])\n\n while (true) {\n const headerEnd = buffer.indexOf(separator)\n if (headerEnd === -1) return\n\n const header = buffer.subarray(0, headerEnd).toString()\n const length = Number(/content-length:\\s*(\\d+)/i.exec(header)?.[1])\n if (!Number.isInteger(length)) throw new Error(`Missing Content-Length header in \"${header}\"`)\n\n const start = headerEnd + separator.length\n if (buffer.length < start + length) return\n\n const body = buffer.subarray(start, start + length).toString()\n buffer = buffer.subarray(start + length)\n onMessage(JSON.parse(body) as Message)\n }\n }\n}\n","import * as yaml from 'yaml'\n\n/**\n * A range in the spec text, as `[start, end)` offsets.\n */\nexport type Range = { start: number; end: number }\n\nconst toRange = ([start, end]: yaml.Range): Range => ({ start, end })\n\nconst unescapeToken = (token: string) => token.replaceAll('~1', '/').replaceAll('~0', '~')\n\n/**\n * Walks a JSON pointer through maps and sequences; the range is the last key or item it reached,\n * or with `value` the scalar value of that key.\n */\nfunction findPointer(document: yaml.Document, pointer: string, value = false): Range | undefined {\n const tokens = pointer.replace(/^#/, '').split('/').slice(1).map(unescapeToken)\n const reached = tokens.reduce<{ node: unknown; range: Range | undefined } | undefined>(\n (at, token) => {\n if (yaml.isMap(at?.node)) {\n const pair = at.node.items.find((item) => yaml.isScalar(item.key) && String(item.key.value) === token)\n return pair && yaml.isScalar(pair.key) && pair.key.range ? { node: pair.value, range: toRange(pair.key.range) } : undefined\n }\n if (yaml.isSeq(at?.node)) {\n const item = at.node.items[Number(token)]\n return yaml.isNode(item) && item.range ? { node: item, range: toRange(item.range) } : undefined\n }\n return undefined\n },\n { node: document.contents, range: undefined },\n )\n if (!value) return reached?.range\n return yaml.isScalar(reached?.node) && reached.node.range ? toRange(reached.node.range) : undefined\n}\n\n/**\n * The first `$ref` whose value is `ref`.\n */\nfunction findRefUsage(document: yaml.Document, ref: string): Range | undefined {\n let found: Range | undefined\n yaml.visit(document, {\n Pair(_, { key, value }) {\n if (!yaml.isScalar(key) || key.value !== '$ref' || !yaml.isScalar(value) || value.value !== ref || !value.range) return\n found = toRange(value.range)\n return yaml.visit.BREAK\n },\n })\n return found\n}\n\n/**\n * Maps JSON pointers to ranges in an already parsed spec, the same way `@kubb/adapter-oas`'s\n * `locate` does from the spec text. Reusing the document the build parsed saves a second parse of\n * the spec on every transform. An unresolved `$ref` falls back to its first usage.\n */\nexport function createLocator(document: yaml.Document): (location: { pointer: string; ref?: string; value?: boolean }) => Range | undefined {\n return ({ pointer, ref, value }) => findPointer(document, pointer, value) ?? (ref ? findRefUsage(document, ref) : undefined)\n}\n","import ts from '@typescript/typescript6'\n\n/**\n * A span map segment in the tuple form TypeScript reads:\n * `[virtualStart, virtualLength, originalStart, originalLength, kind, features]`.\n */\nexport type Segment = [number, number, number, number, number, number]\n\ntype Locate = (pointer: string) => { start: number; end: number } | undefined\n\n/**\n * Finds a spec key (`locate`) or the scalar value of a key (`locateValue`) from a JSON pointer.\n */\ntype Locators = { locate: Locate; locateValue: Locate }\n\nconst kindVerbatim = 0\nconst kindAlias = 2\n// Hover, Definition, TypeDefinition, Implementation, References, DocumentHighlights.\nconst features = 1 | 8 | 16 | 32 | 64 | 128\n// Only schema names rename into the spec. A stale `$ref` shows as an error, but a stale `required` entry fails silently.\nconst renameFeature = 256\n\nconst refPrefix = '#/components/schemas/'\n\nconst escapeToken = (token: string) => token.replaceAll('~', '~0').replaceAll('/', '~1')\n\n// A schema type's own key: `#/components/schemas/Pet`, not a property or an operation part under it.\nconst isSchemaPointer = (pointer: string | undefined): pointer is string => !!pointer?.startsWith(refPrefix) && !pointer.slice(refPrefix.length).includes('/')\n\n/**\n * A property type without `| null` and one level of `T[]` or `Array<T>`, which the spec writes under `items`.\n */\nfunction unwrap(type: ts.TypeNode | undefined): { type: ts.TypeNode; items: boolean } | undefined {\n const members =\n type && ts.isUnionTypeNode(type)\n ? type.types.filter((member) => !(ts.isLiteralTypeNode(member) && member.literal.kind === ts.SyntaxKind.NullKeyword))\n : [type]\n const [single] = members.length === 1 ? members : []\n if (!single) return undefined\n if (ts.isArrayTypeNode(single)) return { type: single.elementType, items: true }\n if (ts.isTypeReferenceNode(single) && single.typeName.getText() === 'Array' && single.typeArguments?.length === 1)\n return { type: single.typeArguments[0]!, items: true }\n return { type: single, items: false }\n}\n\n/**\n * The members of an interface, or of a type alias for an object literal.\n */\nfunction typeMembers(statement: ts.TypeAliasDeclaration | ts.InterfaceDeclaration): ts.NodeArray<ts.TypeElement> | undefined {\n if (ts.isInterfaceDeclaration(statement)) return statement.members\n return ts.isTypeLiteralNode(statement.type) ? statement.type.members : undefined\n}\n\n/**\n * Links generated names to the spec keys they came from: schemas and their (nested) properties,\n * and operation types to the operation, parameters, request body or response. A schema type named\n * exactly like its key is verbatim, so a rename in TypeScript renames the key. A reference to a\n * schema type maps to the end of the `$ref` that points at that schema, so the rename updates it too.\n * `pointers` maps each emitted declaration name to the JSON pointer it came from.\n */\nexport function createMappings(text: string, content: string, { locate, locateValue }: Locators, pointers: Map<string, string>): Array<Segment> {\n const sourceFile = ts.createSourceFile('index.ts', text, ts.ScriptTarget.Latest, true)\n const segments: Array<Segment> = []\n\n const add = (name: ts.Node, rename: boolean, pointer: string | undefined) => {\n const range = pointer ? locate(pointer) : undefined\n if (!range) return\n const verbatim = rename && content.slice(range.start, range.end) === name.getText(sourceFile)\n segments.push([\n name.getStart(sourceFile),\n name.getWidth(sourceFile),\n range.start,\n range.end - range.start,\n verbatim ? kindVerbatim : kindAlias,\n verbatim ? features | renameFeature : features,\n ])\n }\n\n // Only a reference whose `$ref` ends in the same text renames; anything else would break the spec.\n const addRef = (inner: ReturnType<typeof unwrap>, pointer: string) => {\n if (!inner || !ts.isTypeReferenceNode(inner.type) || !ts.isIdentifier(inner.type.typeName)) return\n const reference = inner.type.typeName\n const name = reference.text\n if (!isSchemaPointer(pointers.get(name))) return\n const range = locateValue(`${pointer}${inner.items ? '/items' : ''}/$ref`)\n if (!range) return\n // The `$ref` value may be quoted, so count the name back from the end of its text.\n const start = range.start + content.slice(range.start, range.end).replace(/['\"]$/, '').length - name.length\n if (content.slice(start - refPrefix.length, start + name.length) !== refPrefix + name) return\n segments.push([reference.getStart(sourceFile), reference.getWidth(sourceFile), start, name.length, kindVerbatim, features | renameFeature])\n }\n\n const addMembers = (members: ts.NodeArray<ts.TypeElement>, pointer: string) => {\n for (const member of members) {\n if (!ts.isPropertySignature(member) || !(ts.isIdentifier(member.name) || ts.isStringLiteral(member.name))) continue\n const propertyPointer = `${pointer}/properties/${escapeToken(member.name.text)}`\n add(member.name, false, propertyPointer)\n const inner = unwrap(member.type)\n addRef(inner, propertyPointer)\n if (inner && ts.isTypeLiteralNode(inner.type)) addMembers(inner.type.members, inner.items ? `${propertyPointer}/items` : propertyPointer)\n }\n }\n\n for (const statement of sourceFile.statements) {\n if (ts.isVariableStatement(statement)) {\n // Enum objects (`export const orderStatusEnum = { ... } as const`) carry their own pointer.\n for (const declaration of statement.declarationList.declarations) {\n if (ts.isIdentifier(declaration.name)) add(declaration.name, false, pointers.get(declaration.name.text))\n }\n continue\n }\n if (!ts.isTypeAliasDeclaration(statement) && !ts.isInterfaceDeclaration(statement)) continue\n const pointer = pointers.get(statement.name.text)\n const isSchema = isSchemaPointer(pointer)\n add(statement.name, isSchema, pointer)\n\n // Property names only resolve under a schema, not under operation parameters or responses.\n if (!isSchema) continue\n const members = typeMembers(statement)\n if (members) addMembers(members, pointer)\n else if (ts.isTypeAliasDeclaration(statement)) addRef(unwrap(statement.type), pointer)\n }\n\n return segments\n}\n","import { readFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport ts from '@typescript/typescript6'\nimport type { UserConfig } from 'kubb'\nimport { Hookable, type KubbHooks } from 'kubb/kit'\nimport { pluginTs, pluginTsName, resolverTs } from '@kubb/plugin-ts'\nimport { generateModule } from 'unplugin-kubb'\nimport { parse, parseDocument } from 'yaml'\nimport { readOrNull } from './cache.ts'\nimport { createLocator } from './locate.ts'\nimport { createMappings, type Segment } from './mappings.ts'\n\n/**\n * Parameters of the content mapper `transform` request.\n */\nexport type TransformParams = {\n fileName: string\n content: string\n}\n\n/**\n * The module TypeScript checks in place of the spec, and the segments linking it to the spec.\n */\nexport type TransformResult = {\n text: string\n extension: '.ts'\n mappings?: Array<Segment>\n diagnostics?: Array<{ messageText: string; start: number; length: number }>\n /**\n * The text of each file an external `$ref` read, by absolute path, or `null` when it is missing.\n * The server watches these files. It is not part of the protocol.\n */\n dependencies?: Record<string, string | null>\n}\n\nconst isUrl = (source: string) => /^https?:\\/\\//i.test(source)\n\n// shortcut: Kubb reads each file before this does, so an edit in between is stored as already built; read through Kubb if that shows up.\nconst toDependencies = (sources: Array<string>) => Object.fromEntries(sources.filter((source) => !isUrl(source)).map((file) => [file, readOrNull(file)]))\n\n/**\n * The files that external `$ref`s in the spec at `fileName` read, with the spec as saved on disk.\n */\nexport async function readDependencies(fileName: string): Promise<Array<string>> {\n const input = parse(await readFile(fileName, 'utf8'))\n const { sources } = await generateModule({ root: dirname(fileName), input, config: { output: { path: '.' }, plugins: [] } })\n return sources.filter((source) => !isUrl(source))\n}\n\nconst scanner = ts.createScanner(ts.ScriptTarget.Latest, true)\n\n// A keyword such as `string` or `class` scans as a keyword, not an identifier, so it is not kept.\nfunction isPlainIdentifier(name: string): boolean {\n scanner.setText(name)\n return scanner.scan() === ts.SyntaxKind.Identifier && scanner.getTokenEnd() === name.length\n}\n\n/**\n * Keeps a name that is already a valid type name as the spec wrote it (`pet`, `PET_STATUS`), so a\n * schema type matches its key and renames it. Composed names such as `getPetById Status 200` and\n * keys that are not identifiers keep the `@kubb/plugin-ts` PascalCase.\n */\nconst specName = (name: string) => (isPlainIdentifier(name) ? name : resolverTs.name(name))\n\n/**\n * Lets `@kubb/plugin-ts` name schema types after their spec keys, unless the config sets its own `resolver.name`.\n */\nfunction keepSpecCasing(config: UserConfig): UserConfig {\n return {\n ...config,\n plugins: config.plugins?.map((plugin) =>\n plugin.name === pluginTsName\n ? { ...plugin, options: { ...plugin.options, resolver: { name: specName, ...(plugin.options as { resolver?: object })?.resolver } } }\n : plugin,\n ),\n }\n}\n\n/**\n * Generates the module for one spec with `generateModule` from `unplugin-kubb`, the same one a\n * bundler loads. Without a config, only `@kubb/plugin-ts` runs. The spec text comes from the\n * request, so unsaved edits are checked too. It is parsed once and shared by the build, the\n * diagnostics and the mappings.\n */\nexport async function transform({ fileName, content }: TransformParams, config?: UserConfig): Promise<TransformResult> {\n const document = parseDocument(content)\n if (document.errors.length) {\n return {\n text: 'export {}',\n extension: '.ts',\n diagnostics: document.errors.map((error) => ({ messageText: error.message, start: error.pos[0], length: error.pos[1] - error.pos[0] })),\n }\n }\n\n const hooks = new Hookable<KubbHooks>()\n const pointers = new Map<string, string>()\n hooks.hook('kubb:build:end', ({ files }) => {\n for (const source of files.flatMap((file) => file.sources)) {\n if (source.name && source.pointer) pointers.set(source.name, source.pointer)\n }\n })\n\n const { text, errors, sources } = await generateModule({\n root: dirname(fileName),\n input: document.toJS(),\n config: keepSpecCasing(config ?? { output: { path: '.' }, plugins: [pluginTs()] }),\n hooks,\n })\n\n const locate = createLocator(document)\n const dependencies = toDependencies(sources)\n\n if (errors.length) {\n return {\n text: 'export {}',\n extension: '.ts',\n diagnostics: errors.map((error) => {\n const range = error.location && 'pointer' in error.location ? locate(error.location) : undefined\n return { messageText: error.message, start: range?.start ?? 0, length: range ? range.end - range.start : 0 }\n }),\n dependencies,\n }\n }\n\n if (config && !text) {\n return {\n text: 'export {}',\n extension: '.ts',\n diagnostics: [{ messageText: 'kubb.config.ts generated no code for this spec. Add a plugin such as pluginTs().', start: 0, length: 0 }],\n dependencies,\n }\n }\n\n return {\n text,\n extension: '.ts',\n mappings: createMappings(text, content, { locate: (pointer) => locate({ pointer }), locateValue: (pointer) => locate({ pointer, value: true }) }, pointers),\n dependencies,\n }\n}\n","import { createHash } from 'node:crypto'\nimport { globSync } from 'node:fs'\nimport { basename, dirname, resolve } from 'node:path'\nimport ts from '@typescript/typescript6'\nimport { selectConfig } from 'unplugin-kubb'\nimport { cacheTransform, readOrNull } from './cache.ts'\nimport { loadProjectConfig, type ProjectConfig } from './config.ts'\nimport { createDecoder, encode, type Message } from './rpc.ts'\nimport { readDependencies, transform, type TransformParams } from './transform.ts'\n\n// stdout carries the protocol, so every other stdout write (any console method, direct writes from\n// Kubb or its plugins) goes to stderr.\nconst writeProtocol = process.stdout.write.bind(process.stdout)\nprocess.stdout.write = process.stderr.write.bind(process.stderr) as typeof process.stdout.write\n\n// The load promise is stored right away, so a transform sent before the load finishes waits for it.\nconst projects = new Map<string, Promise<ProjectConfig>>()\n\nconst cachedTransform = cacheTransform(transform)\n\n// shortcut: one list for every project, and a file stays watched after its `$ref` is gone; split it per project if a stray reload matters.\nconst dependencies = new Set<string>()\n\n/**\n * The files that external `$ref`s read in the specs under the tsconfig folder, outside\n * `node_modules`, with an extension that `contentMappers` maps to this package. TypeScript only\n * watches what `openProject` returns, so these are found before the first transform.\n */\nasync function findDependencies(configFileName: string): Promise<Array<string>> {\n const { config } = ts.readConfigFile(configFileName, ts.sys.readFile)\n const mappers: Array<{ package?: string; extensions?: Array<string> }> = config?.contentMappers ?? []\n // shortcut: a `contentMappers` entry that comes from `extends` is not read, look it up too if someone relies on it.\n const extensions = mappers.filter((mapper) => mapper.package === 'openapi-import').flatMap((mapper) => mapper.extensions ?? [])\n if (!extensions.length) return []\n\n const dir = dirname(configFileName)\n const specs = globSync(\n extensions.map((extension) => `**/*${extension}`),\n { cwd: dir, exclude: (file) => basename(String(file)) === 'node_modules' },\n )\n // A spec that does not parse has nothing to watch yet; its transform reports the error.\n const found = await Promise.all(specs.map((spec) => readDependencies(resolve(dir, spec)).catch(() => [])))\n return found.flat()\n}\n\nconst handlers: Record<string, (params: never) => unknown> = {\n initialize: () => ({ protocolVersion: 1, positionEncoding: 'utf-16', diagnosticSource: 'kubb' }),\n // `dynamicConfig` in package.json: TypeScript watches `watchedFiles` and opens the project again\n // when one changes, then transforms its specs again when `configIdentity` differs. The files that\n // external `$ref`s read are watched too, so a changed schema file updates the spec that points at it.\n openProject: async ({ projectHandle, configFileName, options }: { projectHandle: string; configFileName?: string; options?: unknown }) => {\n const loading = loadProjectConfig(configFileName ? dirname(configFileName) : process.cwd())\n projects.set(projectHandle, loading)\n const project = await loading\n for (const file of configFileName ? await findDependencies(configFileName) : []) dependencies.add(file)\n // TypeScript only transforms again when the identity changes, so it covers the `$ref` files too.\n const identity = createHash('sha256').update(project.identity)\n for (const file of dependencies) identity.update(`\\0${file}\\0${readOrNull(file) ?? ''}`)\n\n return {\n configIdentity: dependencies.size ? identity.digest('hex') : project.identity,\n watchedFiles: [...new Set([...project.watchedFiles, ...dependencies])],\n ...(options != null && { optionDiagnostics: [{ path: [], messageText: 'openapi-import has no options. Set plugin options in kubb.config.ts.' }] }),\n }\n },\n closeProject: ({ projectHandle }: { projectHandle: string }) => {\n projects.delete(projectHandle)\n return null\n },\n transform: async (params: TransformParams & { projectHandle: string }) => {\n const project = await projects.get(params.projectHandle)\n if (project?.error) return { text: 'export {}', extension: '.ts', diagnostics: [{ messageText: project.error, start: 0, length: 0 }] }\n\n const { dependencies: files, ...result } = await cachedTransform(\n params,\n project && selectConfig({ configs: project.configs, fileName: params.fileName, cwd: project.dir }),\n )\n for (const file of Object.keys(files ?? {})) dependencies.add(file)\n return result\n },\n}\n\nasync function handle({ id, method = '', params }: Message): Promise<void> {\n const handler = handlers[method]\n if (id === undefined) return\n\n try {\n if (!handler) {\n writeProtocol(encode({ id, error: { code: -32601, message: `Unknown method \"${method}\"` } }))\n return\n }\n const result = await handler(params as never)\n writeProtocol(encode({ id, result: result ?? null }))\n } catch (error) {\n writeProtocol(encode({ id, error: { code: -32603, message: error instanceof Error ? (error.stack ?? error.message) : String(error) } }))\n }\n}\n\nprocess.stdin.on(\n 'data',\n createDecoder((message) => void handle(message)),\n)\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openapi-import",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Import OpenAPI specs in TypeScript with types from Kubb, through TypeScript 7.1 content mappers. No generated files.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"code-generation",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"registry": "https://registry.npmjs.org/"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@kubb/plugin-ts": "^5.0
|
|
52
|
+
"@kubb/plugin-ts": "^5.1.0",
|
|
53
53
|
"@typescript/typescript6": "^6.0.2",
|
|
54
|
-
"unplugin-kubb": "^5.
|
|
54
|
+
"unplugin-kubb": "^5.14.5",
|
|
55
55
|
"yaml": "^2.9.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@kubb/plugin-zod": "^5.4.12",
|
|
61
61
|
"@types/node": "22.20.2",
|
|
62
62
|
"@vitest/coverage-v8": "^5.0.5",
|
|
63
|
-
"kubb": "^5.
|
|
63
|
+
"kubb": "^5.14.5",
|
|
64
64
|
"oxfmt": "^0.72.0",
|
|
65
65
|
"oxlint": "^1.88.0",
|
|
66
66
|
"tsdown": "^0.23.1",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"vitest": "^5.0.5"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"kubb": "^5.
|
|
71
|
+
"kubb": "^5.14.5"
|
|
72
72
|
},
|
|
73
73
|
"typescript": {
|
|
74
74
|
"contentMapper": {
|
|
@@ -80,8 +80,7 @@
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
"engines": {
|
|
83
|
-
"node": ">=22.12"
|
|
84
|
-
"pnpm": ">=11.0.0"
|
|
83
|
+
"node": ">=22.12"
|
|
85
84
|
},
|
|
86
85
|
"scripts": {
|
|
87
86
|
"build": "tsdown",
|