@techspokes/typescript-wsdl-client 0.6.3 → 0.7.1
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 +296 -166
- package/dist/cli.js +239 -1
- package/dist/compiler/schemaCompiler.d.ts +54 -0
- package/dist/compiler/schemaCompiler.d.ts.map +1 -1
- package/dist/compiler/schemaCompiler.js +74 -7
- package/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/emit/catalogEmitter.d.ts +18 -0
- package/dist/emit/catalogEmitter.d.ts.map +1 -1
- package/dist/emit/catalogEmitter.js +31 -0
- package/dist/emit/clientEmitter.d.ts +17 -0
- package/dist/emit/clientEmitter.d.ts.map +1 -1
- package/dist/emit/clientEmitter.js +33 -3
- package/dist/emit/typesEmitter.d.ts +16 -5
- package/dist/emit/typesEmitter.d.ts.map +1 -1
- package/dist/emit/typesEmitter.js +30 -5
- package/dist/emit/utilsEmitter.d.ts +18 -0
- package/dist/emit/utilsEmitter.d.ts.map +1 -1
- package/dist/emit/utilsEmitter.js +30 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -1
- package/dist/loader/fetch.d.ts +31 -0
- package/dist/loader/fetch.d.ts.map +1 -1
- package/dist/loader/fetch.js +31 -0
- package/dist/loader/wsdlLoader.d.ts +32 -0
- package/dist/loader/wsdlLoader.d.ts.map +1 -1
- package/dist/loader/wsdlLoader.js +80 -9
- package/dist/openapi/buildPaths.d.ts +74 -0
- package/dist/openapi/buildPaths.d.ts.map +1 -0
- package/dist/openapi/buildPaths.js +66 -0
- package/dist/openapi/buildSchemas.d.ts +44 -0
- package/dist/openapi/buildSchemas.d.ts.map +1 -0
- package/dist/openapi/buildSchemas.js +196 -0
- package/dist/openapi/casing.d.ts +38 -0
- package/dist/openapi/casing.d.ts.map +1 -0
- package/dist/openapi/casing.js +49 -0
- package/dist/openapi/generateOpenAPI.d.ts +61 -0
- package/dist/openapi/generateOpenAPI.d.ts.map +1 -0
- package/dist/openapi/generateOpenAPI.js +315 -0
- package/dist/openapi/security.d.ts +82 -0
- package/dist/openapi/security.d.ts.map +1 -0
- package/dist/openapi/security.js +145 -0
- package/dist/pipeline.d.ts +37 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +72 -0
- package/dist/util/tools.d.ts +100 -7
- package/dist/util/tools.d.ts.map +1 -1
- package/dist/util/tools.js +85 -7
- package/dist/xsd/primitives.d.ts +33 -0
- package/dist/xsd/primitives.d.ts.map +1 -1
- package/dist/xsd/primitives.js +59 -7
- package/package.json +7 -2
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { toPathSegment } from "./casing.js";
|
|
2
|
+
export function buildPaths(compiled, opts) {
|
|
3
|
+
const paths = {};
|
|
4
|
+
const base = normalizeBase(opts.basePath || "/");
|
|
5
|
+
for (const op of compiled.operations) {
|
|
6
|
+
const seg = toPathSegment(op.name, opts.pathStyle);
|
|
7
|
+
const fullPath = (base.endsWith("/") ? base.slice(0, -1) : base) + "/" + seg;
|
|
8
|
+
const override = opts.overrides?.[op.name] || {};
|
|
9
|
+
const method = (override.method || opts.defaultMethod || "post").toLowerCase();
|
|
10
|
+
const tag = opts.tagsMap?.[op.name] || opts.defaultTag;
|
|
11
|
+
const inputRef = op.inputElement?.local ? { $ref: `#/components/schemas/${op.inputElement.local}` } : { type: "object" };
|
|
12
|
+
const outputRef = op.outputElement?.local ? { $ref: `#/components/schemas/${op.outputElement.local}` } : { type: "object" };
|
|
13
|
+
const parameters = [];
|
|
14
|
+
// Header parameters from security builder
|
|
15
|
+
const headerParamNames = opts.opHeaderParameters[op.name] || [];
|
|
16
|
+
for (const pName of headerParamNames) {
|
|
17
|
+
parameters.push({ $ref: `#/components/parameters/${pName}` });
|
|
18
|
+
}
|
|
19
|
+
const operationObject = {
|
|
20
|
+
operationId: op.name,
|
|
21
|
+
tags: [tag],
|
|
22
|
+
requestBody: {
|
|
23
|
+
required: true,
|
|
24
|
+
content: {
|
|
25
|
+
"application/json": { schema: inputRef }
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
responses: {
|
|
29
|
+
"200": {
|
|
30
|
+
description: "Successful SOAP operation response",
|
|
31
|
+
content: {
|
|
32
|
+
"application/json": { schema: outputRef }
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
default: {
|
|
36
|
+
description: "Error response",
|
|
37
|
+
content: {
|
|
38
|
+
"application/json": { schema: { $ref: "#/components/schemas/ErrorEnvelope" } }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
if (override.summary)
|
|
44
|
+
operationObject.summary = override.summary;
|
|
45
|
+
if (override.description)
|
|
46
|
+
operationObject.description = override.description;
|
|
47
|
+
if (override.deprecated)
|
|
48
|
+
operationObject.deprecated = true;
|
|
49
|
+
if (parameters.length)
|
|
50
|
+
operationObject.parameters = parameters;
|
|
51
|
+
const opSec = opts.opSecurity[op.name];
|
|
52
|
+
if (opSec)
|
|
53
|
+
operationObject.security = opSec;
|
|
54
|
+
if (!paths[fullPath])
|
|
55
|
+
paths[fullPath] = {};
|
|
56
|
+
paths[fullPath][method] = operationObject;
|
|
57
|
+
}
|
|
58
|
+
return paths;
|
|
59
|
+
}
|
|
60
|
+
function normalizeBase(base) {
|
|
61
|
+
if (!base.startsWith("/"))
|
|
62
|
+
base = "/" + base;
|
|
63
|
+
if (base.endsWith("/"))
|
|
64
|
+
return base;
|
|
65
|
+
return base;
|
|
66
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Schema Component Builder
|
|
3
|
+
*
|
|
4
|
+
* This module transforms the compiled TypeScript types from the WSDL catalog
|
|
5
|
+
* into OpenAPI 3.1 schema components. It handles the conversion of complex types,
|
|
6
|
+
* type aliases, arrays, and primitive types to their JSON Schema equivalents.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - Converts TypeScript interfaces to JSON Schema objects
|
|
10
|
+
* - Handles type aliases and enumerations
|
|
11
|
+
* - Supports array types with appropriate item definitions
|
|
12
|
+
* - Manages property requirements based on XML schema constraints
|
|
13
|
+
* - Optionally enforces closed schemas with additionalProperties:false
|
|
14
|
+
* - Can prune schemas that aren't referenced by any operation
|
|
15
|
+
*/
|
|
16
|
+
import type { CompiledCatalog } from "../compiler/schemaCompiler.js";
|
|
17
|
+
/**
|
|
18
|
+
* Options for building OpenAPI schema components
|
|
19
|
+
*
|
|
20
|
+
* @interface BuildSchemasOptions
|
|
21
|
+
* @property {boolean} [closedSchemas] - Whether to add additionalProperties:false to object schemas
|
|
22
|
+
* @property {boolean} [pruneUnusedSchemas] - Whether to exclude schemas not referenced by operations
|
|
23
|
+
*/
|
|
24
|
+
export interface BuildSchemasOptions {
|
|
25
|
+
closedSchemas?: boolean;
|
|
26
|
+
pruneUnusedSchemas?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type ComponentsSchemas = Record<string, any>;
|
|
29
|
+
/**
|
|
30
|
+
* Transforms the compiled WSDL catalog into OpenAPI schema components
|
|
31
|
+
*
|
|
32
|
+
* @function buildSchemas
|
|
33
|
+
* @param {CompiledCatalog} compiled - The compiled WSDL catalog containing types, aliases, and operations
|
|
34
|
+
* @param {BuildSchemasOptions} opts - Options for schema generation
|
|
35
|
+
* @returns {ComponentsSchemas} - A record of schema component names to their JSON Schema definitions
|
|
36
|
+
*
|
|
37
|
+
* @throws Will throw an error if there are unknown referenced types or bases while building schemas
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Example usage: building schemas with closed schemas enforcement and unused schema pruning
|
|
41
|
+
* const schemas = buildSchemas(compiledCatalog, { closedSchemas: true, pruneUnusedSchemas: true });
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildSchemas(compiled: CompiledCatalog, opts: BuildSchemasOptions): ComponentsSchemas;
|
|
44
|
+
//# sourceMappingURL=buildSchemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildSchemas.d.ts","sourceRoot":"","sources":["../../src/openapi/buildSchemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAgB,eAAe,EAAe,MAAM,+BAA+B,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAmIpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,mBAAmB,GAAG,iBAAiB,CA8CpG"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
function isLiteralUnion(ts) {
|
|
2
|
+
// very naive: split by | and ensure each trimmed starts and ends with quotes
|
|
3
|
+
const parts = ts.split("|").map(p => p.trim()).filter(Boolean);
|
|
4
|
+
if (!parts.length)
|
|
5
|
+
return null;
|
|
6
|
+
if (parts.every(p => /^".*"$/.test(p))) {
|
|
7
|
+
return parts.map(p => p.slice(1, -1));
|
|
8
|
+
}
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
function primitiveSchema(ts) {
|
|
12
|
+
switch (ts) {
|
|
13
|
+
case "string":
|
|
14
|
+
return { type: "string" };
|
|
15
|
+
case "number":
|
|
16
|
+
return { type: "number" };
|
|
17
|
+
case "boolean":
|
|
18
|
+
return { type: "boolean" };
|
|
19
|
+
case "any":
|
|
20
|
+
return {};
|
|
21
|
+
default:
|
|
22
|
+
if (ts.endsWith("[]")) {
|
|
23
|
+
return { type: "array", items: primitiveSchema(ts.slice(0, -2)) };
|
|
24
|
+
}
|
|
25
|
+
return { $ref: `#/components/schemas/${ts}` };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function buildAliasSchema(a) {
|
|
29
|
+
const lit = isLiteralUnion(a.tsType);
|
|
30
|
+
if (lit) {
|
|
31
|
+
return { type: "string", enum: lit };
|
|
32
|
+
}
|
|
33
|
+
// If alias wraps primitive
|
|
34
|
+
if (["string", "number", "boolean", "any"].includes(a.tsType) || a.tsType.endsWith("[]")) {
|
|
35
|
+
return primitiveSchema(a.tsType);
|
|
36
|
+
}
|
|
37
|
+
// alias of another complex/alias type -> allOf wrapper preserves name
|
|
38
|
+
return { allOf: [{ $ref: `#/components/schemas/${a.tsType}` }] };
|
|
39
|
+
}
|
|
40
|
+
function isArrayWrapper(t) {
|
|
41
|
+
if (t.attrs.length !== 0)
|
|
42
|
+
return null;
|
|
43
|
+
if (t.elems.length !== 1)
|
|
44
|
+
return null;
|
|
45
|
+
const e = t.elems[0];
|
|
46
|
+
if (e.max !== "unbounded" && !(e.max > 1))
|
|
47
|
+
return null;
|
|
48
|
+
return { itemType: e.tsType };
|
|
49
|
+
}
|
|
50
|
+
function buildComplexSchema(t, closed, knownTypeNames, aliasNames) {
|
|
51
|
+
// Use knownTypeNames/aliasNames to validate $ref targets so we surface
|
|
52
|
+
// compiler issues early instead of emitting dangling references in OpenAPI output.
|
|
53
|
+
function refOrPrimitive(ts) {
|
|
54
|
+
switch (ts) {
|
|
55
|
+
case "string":
|
|
56
|
+
return { type: "string" };
|
|
57
|
+
case "number":
|
|
58
|
+
return { type: "number" };
|
|
59
|
+
case "boolean":
|
|
60
|
+
return { type: "boolean" };
|
|
61
|
+
case "any":
|
|
62
|
+
return {}; // intentionally permissive
|
|
63
|
+
default:
|
|
64
|
+
if (ts.endsWith("[]")) {
|
|
65
|
+
const inner = ts.slice(0, -2);
|
|
66
|
+
return { type: "array", items: refOrPrimitive(inner) };
|
|
67
|
+
}
|
|
68
|
+
if (!knownTypeNames.has(ts) && !aliasNames.has(ts)) {
|
|
69
|
+
// Fail fast: this indicates a mismatch between schemaCompiler output and OpenAPI builder expectations.
|
|
70
|
+
throw new Error(`[openapi] unknown referenced type '${ts}' while building schema '${t.name}'`);
|
|
71
|
+
}
|
|
72
|
+
return { $ref: `#/components/schemas/${ts}` };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const arrayWrap = isArrayWrapper(t);
|
|
76
|
+
if (arrayWrap) {
|
|
77
|
+
const item = refOrPrimitive(String(arrayWrap.itemType));
|
|
78
|
+
return { type: "array", items: item };
|
|
79
|
+
}
|
|
80
|
+
const properties = {};
|
|
81
|
+
const required = [];
|
|
82
|
+
// attributes
|
|
83
|
+
for (const a of t.attrs) {
|
|
84
|
+
properties[a.name] = refOrPrimitive(a.tsType);
|
|
85
|
+
if (a.use === "required")
|
|
86
|
+
required.push(a.name);
|
|
87
|
+
}
|
|
88
|
+
// elements
|
|
89
|
+
for (const e of t.elems) {
|
|
90
|
+
const baseSchema = refOrPrimitive(e.tsType);
|
|
91
|
+
const isArray = e.max === "unbounded" || (e.max > 1);
|
|
92
|
+
let schema = baseSchema;
|
|
93
|
+
if (isArray)
|
|
94
|
+
schema = { type: "array", items: baseSchema };
|
|
95
|
+
if (e.nillable) {
|
|
96
|
+
schema = { anyOf: [schema, { type: "null" }] };
|
|
97
|
+
}
|
|
98
|
+
properties[e.name] = schema;
|
|
99
|
+
if (e.name === "$value") {
|
|
100
|
+
// never required
|
|
101
|
+
}
|
|
102
|
+
else if (e.min >= 1) {
|
|
103
|
+
required.push(e.name);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const obj = {
|
|
107
|
+
type: "object",
|
|
108
|
+
properties,
|
|
109
|
+
};
|
|
110
|
+
if (required.length)
|
|
111
|
+
obj.required = Array.from(new Set(required));
|
|
112
|
+
if (closed)
|
|
113
|
+
obj.additionalProperties = false;
|
|
114
|
+
// inheritance via base => allOf
|
|
115
|
+
if (t.base) {
|
|
116
|
+
const baseName = t.base;
|
|
117
|
+
// Validate base reference explicitly (using helper ensures error if unknown)
|
|
118
|
+
if (!knownTypeNames.has(baseName) && !aliasNames.has(baseName)) {
|
|
119
|
+
throw new Error(`[openapi] unknown base type '${baseName}' while building schema '${t.name}'`);
|
|
120
|
+
}
|
|
121
|
+
obj.allOf = [{ $ref: `#/components/schemas/${baseName}` }, { ...obj }];
|
|
122
|
+
delete obj.type; // inner object part handled in allOf
|
|
123
|
+
delete obj.properties;
|
|
124
|
+
if (!required.length)
|
|
125
|
+
delete obj.required;
|
|
126
|
+
if (!closed)
|
|
127
|
+
delete obj.additionalProperties; // put closed only on leaf part
|
|
128
|
+
}
|
|
129
|
+
return obj;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Transforms the compiled WSDL catalog into OpenAPI schema components
|
|
133
|
+
*
|
|
134
|
+
* @function buildSchemas
|
|
135
|
+
* @param {CompiledCatalog} compiled - The compiled WSDL catalog containing types, aliases, and operations
|
|
136
|
+
* @param {BuildSchemasOptions} opts - Options for schema generation
|
|
137
|
+
* @returns {ComponentsSchemas} - A record of schema component names to their JSON Schema definitions
|
|
138
|
+
*
|
|
139
|
+
* @throws Will throw an error if there are unknown referenced types or bases while building schemas
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* // Example usage: building schemas with closed schemas enforcement and unused schema pruning
|
|
143
|
+
* const schemas = buildSchemas(compiledCatalog, { closedSchemas: true, pruneUnusedSchemas: true });
|
|
144
|
+
*/
|
|
145
|
+
export function buildSchemas(compiled, opts) {
|
|
146
|
+
const closed = !!opts.closedSchemas;
|
|
147
|
+
const schemas = {};
|
|
148
|
+
const typeNames = new Set(compiled.types.map(t => t.name));
|
|
149
|
+
const aliasNames = new Set(compiled.aliases.map(a => a.name));
|
|
150
|
+
// Build alias schemas first so complex types can reference them
|
|
151
|
+
for (const a of compiled.aliases) {
|
|
152
|
+
schemas[a.name] = buildAliasSchema(a);
|
|
153
|
+
}
|
|
154
|
+
for (const t of compiled.types) {
|
|
155
|
+
schemas[t.name] = buildComplexSchema(t, closed, typeNames, aliasNames);
|
|
156
|
+
}
|
|
157
|
+
if (opts.pruneUnusedSchemas) {
|
|
158
|
+
// Root references: each operation's inputElement.local, outputElement.local
|
|
159
|
+
const roots = new Set();
|
|
160
|
+
for (const op of compiled.operations) {
|
|
161
|
+
if (op.inputElement?.local)
|
|
162
|
+
roots.add(op.inputElement.local);
|
|
163
|
+
if (op.outputElement?.local)
|
|
164
|
+
roots.add(op.outputElement.local);
|
|
165
|
+
}
|
|
166
|
+
// BFS through $ref graph
|
|
167
|
+
const reachable = new Set();
|
|
168
|
+
const queue = Array.from(roots);
|
|
169
|
+
while (queue.length) {
|
|
170
|
+
const cur = queue.shift();
|
|
171
|
+
if (reachable.has(cur))
|
|
172
|
+
continue;
|
|
173
|
+
if (!schemas[cur])
|
|
174
|
+
continue; // unknown
|
|
175
|
+
reachable.add(cur);
|
|
176
|
+
const scan = (node) => {
|
|
177
|
+
if (!node || typeof node !== "object")
|
|
178
|
+
return;
|
|
179
|
+
if (node.$ref) {
|
|
180
|
+
const name = node.$ref.split("/").pop();
|
|
181
|
+
if (name && !reachable.has(name))
|
|
182
|
+
queue.push(name);
|
|
183
|
+
}
|
|
184
|
+
for (const v of Object.values(node))
|
|
185
|
+
scan(v);
|
|
186
|
+
};
|
|
187
|
+
scan(schemas[cur]);
|
|
188
|
+
}
|
|
189
|
+
// prune
|
|
190
|
+
for (const k of Object.keys(schemas)) {
|
|
191
|
+
if (!reachable.has(k))
|
|
192
|
+
delete schemas[k];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return schemas;
|
|
196
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Segment Styling for OpenAPI Generation
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for converting operation names to appropriately styled
|
|
5
|
+
* path segments in the OpenAPI specification. It supports multiple styling options to
|
|
6
|
+
* accommodate different API design preferences:
|
|
7
|
+
*
|
|
8
|
+
* - kebab-case: Transforms "GetUserDetails" to "get-user-details"
|
|
9
|
+
* - as-is: Preserves the original operation name without modification
|
|
10
|
+
* - lowercase: Converts to lowercase and removes all non-alphanumeric characters
|
|
11
|
+
*
|
|
12
|
+
* These transformations ensure that the generated API paths follow consistent conventions
|
|
13
|
+
* and are properly formatted for RESTful API design.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Path segment styling options for OpenAPI generation
|
|
17
|
+
*
|
|
18
|
+
* @property {"kebab"} string Convert to kebab-case (e.g., "get-user-details")
|
|
19
|
+
* @property {"asis"} string Keep the original operation name unchanged
|
|
20
|
+
* @property {"lower"} string Convert to lowercase and remove non-alphanumeric characters
|
|
21
|
+
*/
|
|
22
|
+
export type PathStyle = "kebab" | "asis" | "lower";
|
|
23
|
+
/**
|
|
24
|
+
* Converts an operation name to a path segment according to the specified style
|
|
25
|
+
*
|
|
26
|
+
* This function transforms operation names like "GetUserDetails" or "createNewOrder"
|
|
27
|
+
* into appropriately styled path segments based on the selected style:
|
|
28
|
+
*
|
|
29
|
+
* - kebab: "GetUserDetails" → "get-user-details"
|
|
30
|
+
* - asis: "GetUserDetails" → "GetUserDetails"
|
|
31
|
+
* - lower: "GetUserDetails" → "getuserdetails"
|
|
32
|
+
*
|
|
33
|
+
* @param {string} name - Operation name to convert
|
|
34
|
+
* @param {PathStyle} style - Path segment style to apply
|
|
35
|
+
* @returns {string} - Formatted path segment
|
|
36
|
+
*/
|
|
37
|
+
export declare function toPathSegment(name: string, style: PathStyle): string;
|
|
38
|
+
//# sourceMappingURL=casing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"casing.d.ts","sourceRoot":"","sources":["../../src/openapi/casing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAQnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAepE"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Segment Styling for OpenAPI Generation
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for converting operation names to appropriately styled
|
|
5
|
+
* path segments in the OpenAPI specification. It supports multiple styling options to
|
|
6
|
+
* accommodate different API design preferences:
|
|
7
|
+
*
|
|
8
|
+
* - kebab-case: Transforms "GetUserDetails" to "get-user-details"
|
|
9
|
+
* - as-is: Preserves the original operation name without modification
|
|
10
|
+
* - lowercase: Converts to lowercase and removes all non-alphanumeric characters
|
|
11
|
+
*
|
|
12
|
+
* These transformations ensure that the generated API paths follow consistent conventions
|
|
13
|
+
* and are properly formatted for RESTful API design.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Regular expression for detecting boundaries between words in camelCase
|
|
17
|
+
* Matches transitions from lowercase/digit to uppercase letter
|
|
18
|
+
*/
|
|
19
|
+
const CAMEL_BOUNDARY = /([a-z0-9])([A-Z])/g;
|
|
20
|
+
/**
|
|
21
|
+
* Converts an operation name to a path segment according to the specified style
|
|
22
|
+
*
|
|
23
|
+
* This function transforms operation names like "GetUserDetails" or "createNewOrder"
|
|
24
|
+
* into appropriately styled path segments based on the selected style:
|
|
25
|
+
*
|
|
26
|
+
* - kebab: "GetUserDetails" → "get-user-details"
|
|
27
|
+
* - asis: "GetUserDetails" → "GetUserDetails"
|
|
28
|
+
* - lower: "GetUserDetails" → "getuserdetails"
|
|
29
|
+
*
|
|
30
|
+
* @param {string} name - Operation name to convert
|
|
31
|
+
* @param {PathStyle} style - Path segment style to apply
|
|
32
|
+
* @returns {string} - Formatted path segment
|
|
33
|
+
*/
|
|
34
|
+
export function toPathSegment(name, style) {
|
|
35
|
+
switch (style) {
|
|
36
|
+
case "asis":
|
|
37
|
+
return name;
|
|
38
|
+
case "lower":
|
|
39
|
+
return name.replace(/[^A-Za-z0-9]/g, "").toLowerCase();
|
|
40
|
+
case "kebab":
|
|
41
|
+
default:
|
|
42
|
+
// insert hyphen between camelCase boundaries then sanitize
|
|
43
|
+
return name
|
|
44
|
+
.replace(CAMEL_BOUNDARY, "$1-$2")
|
|
45
|
+
.replace(/[^A-Za-z0-9]+/g, "-")
|
|
46
|
+
.replace(/^-+|-+$/g, "")
|
|
47
|
+
.toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type CompiledCatalog } from "../compiler/schemaCompiler.js";
|
|
2
|
+
import type { PathStyle } from "./casing.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for OpenAPI generation from WSDL
|
|
5
|
+
*
|
|
6
|
+
* @interface GenerateOpenAPIOptions
|
|
7
|
+
* @property {string} [wsdl] - Path or URL to WSDL file (exclusive with catalogFile and compiledCatalog)
|
|
8
|
+
* @property {string} [catalogFile] - Path to existing compiled catalog.json (exclusive with wsdl and compiledCatalog)
|
|
9
|
+
* @property {CompiledCatalog} [compiledCatalog] - Pre-compiled catalog in memory (exclusive with wsdl and catalogFile)
|
|
10
|
+
* @property {string} [outFile] - Output path for generated OpenAPI specification
|
|
11
|
+
* @property {string} [title] - API title (defaults to derived service name)
|
|
12
|
+
* @property {string} [version] - API version for info.version (default 0.0.0)
|
|
13
|
+
* @property {string} [description] - API description
|
|
14
|
+
* @property {string[]} [servers] - List of server URLs
|
|
15
|
+
* @property {string} [basePath] - Base path prefix (e.g., /v1/soap)
|
|
16
|
+
* @property {PathStyle} [pathStyle] - Path segment style: kebab, asis, or lower
|
|
17
|
+
* @property {string} [defaultMethod] - Default HTTP method: post, get, put, patch, delete
|
|
18
|
+
* @property {string} [securityConfigFile] - Path to security.json configuration
|
|
19
|
+
* @property {string} [tagsFile] - Path to tags.json mapping operation names to tags
|
|
20
|
+
* @property {string} [opsFile] - Path to ops.json with per-operation overrides
|
|
21
|
+
* @property {boolean} [closedSchemas] - Whether to emit additionalProperties:false
|
|
22
|
+
* @property {boolean} [pruneUnusedSchemas] - Whether to exclude schemas not referenced by operations
|
|
23
|
+
* @property {boolean} [asYaml] - Force YAML output regardless of extension (deprecated)
|
|
24
|
+
* @property {boolean} [validate] - Whether to validate using swagger-parser
|
|
25
|
+
* @property {"default"|"first"|"service"} [tagStyle] - Heuristic for deriving tags
|
|
26
|
+
* @property {"json"|"yaml"|"both"} [format] - Output format (default: json)
|
|
27
|
+
* @property {boolean} [skipValidate] - Skip validation (default: false)
|
|
28
|
+
* @property {string} [envelopeNamespace] - Namespace segment for envelope (default ResponseEnvelope)
|
|
29
|
+
* @property {string} [errorNamespace] - Namespace segment for error object (default ErrorObject)
|
|
30
|
+
*/
|
|
31
|
+
export interface GenerateOpenAPIOptions {
|
|
32
|
+
wsdl?: string;
|
|
33
|
+
catalogFile?: string;
|
|
34
|
+
outFile?: string;
|
|
35
|
+
title?: string;
|
|
36
|
+
version?: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
servers?: string[];
|
|
39
|
+
basePath?: string;
|
|
40
|
+
pathStyle?: PathStyle;
|
|
41
|
+
defaultMethod?: string;
|
|
42
|
+
securityConfigFile?: string;
|
|
43
|
+
tagsFile?: string;
|
|
44
|
+
opsFile?: string;
|
|
45
|
+
closedSchemas?: boolean;
|
|
46
|
+
pruneUnusedSchemas?: boolean;
|
|
47
|
+
asYaml?: boolean;
|
|
48
|
+
validate?: boolean;
|
|
49
|
+
tagStyle?: "default" | "first" | "service";
|
|
50
|
+
compiledCatalog?: CompiledCatalog;
|
|
51
|
+
format?: "json" | "yaml" | "both";
|
|
52
|
+
skipValidate?: boolean;
|
|
53
|
+
envelopeNamespace?: string;
|
|
54
|
+
errorNamespace?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function generateOpenAPI(opts: GenerateOpenAPIOptions): Promise<{
|
|
57
|
+
doc: any;
|
|
58
|
+
jsonPath?: string;
|
|
59
|
+
yamlPath?: string;
|
|
60
|
+
}>;
|
|
61
|
+
//# sourceMappingURL=generateOpenAPI.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateOpenAPI.d.ts","sourceRoot":"","sources":["../../src/openapi/generateOpenAPI.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAiB,KAAK,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAInF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC;IAC3E,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAyRD"}
|