@sdk-it/spec 0.17.0

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.
@@ -0,0 +1,3 @@
1
+ export * from './lib/loaders/load-spec.js';
2
+ export * from './lib/operation.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./lib/loaders/load-spec.js";
2
+ export * from "./lib/operation.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["export * from './lib/loaders/load-spec.js';\nexport * from './lib/operation.js';\n"],
5
+ "mappings": "AAAA,cAAc;AACd,cAAc;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpenAPIObject } from 'openapi3-ts/oas31';
2
+ export declare function loadSpec(location: string): Promise<OpenAPIObject>;
3
+ //# sourceMappingURL=load-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-spec.d.ts","sourceRoot":"","sources":["../../../src/lib/loaders/load-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAMjE"}
@@ -0,0 +1,13 @@
1
+ import { loadLocal } from "./local-loader.js";
2
+ import { loadRemote } from "./remote-loader.js";
3
+ function loadSpec(location) {
4
+ const [protocol] = location.split(":");
5
+ if (protocol === "http" || protocol === "https") {
6
+ return loadRemote(location);
7
+ }
8
+ return loadLocal(location);
9
+ }
10
+ export {
11
+ loadSpec
12
+ };
13
+ //# sourceMappingURL=load-spec.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/loaders/load-spec.ts"],
4
+ "sourcesContent": ["import type { OpenAPIObject } from 'openapi3-ts/oas31';\n\nimport { loadLocal } from './local-loader.js';\nimport { loadRemote } from './remote-loader.js';\n\nexport function loadSpec(location: string): Promise<OpenAPIObject> {\n const [protocol] = location.split(':');\n if (protocol === 'http' || protocol === 'https') {\n return loadRemote(location);\n }\n return loadLocal(location);\n}\n"],
5
+ "mappings": "AAEA,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAEpB,SAAS,SAAS,UAA0C;AACjE,QAAM,CAAC,QAAQ,IAAI,SAAS,MAAM,GAAG;AACrC,MAAI,aAAa,UAAU,aAAa,SAAS;AAC/C,WAAO,WAAW,QAAQ;AAAA,EAC5B;AACA,SAAO,UAAU,QAAQ;AAC3B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export declare function loadLocal(location: string): Promise<any>;
2
+ //# sourceMappingURL=local-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-loader.d.ts","sourceRoot":"","sources":["../../../src/lib/loaders/local-loader.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,gBAY/C"}
@@ -0,0 +1,20 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { extname } from "node:path";
3
+ import { parse } from "yaml";
4
+ async function loadLocal(location) {
5
+ const extName = extname(location);
6
+ const text = await readFile(location, "utf-8");
7
+ switch (extName) {
8
+ case ".json":
9
+ return JSON.parse(text);
10
+ case ".yaml":
11
+ case ".yml":
12
+ return parse(text);
13
+ default:
14
+ throw new Error(`Unsupported file extension: ${extName}`);
15
+ }
16
+ }
17
+ export {
18
+ loadLocal
19
+ };
20
+ //# sourceMappingURL=local-loader.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/loaders/local-loader.ts"],
4
+ "sourcesContent": ["import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { parse } from 'yaml';\n\nexport async function loadLocal(location: string) {\n const extName = extname(location);\n const text = await readFile(location, 'utf-8');\n switch (extName) {\n case '.json':\n return JSON.parse(text);\n case '.yaml':\n case '.yml':\n return parse(text);\n default:\n throw new Error(`Unsupported file extension: ${extName}`);\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,gBAAgB;AACzB,SAAS,eAAe;AACxB,SAAS,aAAa;AAEtB,eAAsB,UAAU,UAAkB;AAChD,QAAM,UAAU,QAAQ,QAAQ;AAChC,QAAM,OAAO,MAAM,SAAS,UAAU,OAAO;AAC7C,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,KAAK;AAAA,IACL,KAAK;AACH,aAAO,MAAM,IAAI;AAAA,IACnB;AACE,YAAM,IAAI,MAAM,+BAA+B,OAAO,EAAE;AAAA,EAC5D;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpenAPIObject } from 'openapi3-ts/oas31';
2
+ export declare function loadRemote(location: string): Promise<OpenAPIObject>;
3
+ //# sourceMappingURL=remote-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-loader.d.ts","sourceRoot":"","sources":["../../../src/lib/loaders/remote-loader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvD,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAqBzE"}
@@ -0,0 +1,26 @@
1
+ import { extname } from "node:path";
2
+ import { parse } from "yaml";
3
+ async function loadRemote(location) {
4
+ const extName = extname(location);
5
+ const response = await fetch(location);
6
+ switch (extName) {
7
+ case ".json":
8
+ return response.json();
9
+ case ".yaml":
10
+ case ".yml": {
11
+ const text = await response.text();
12
+ return parse(text);
13
+ }
14
+ default:
15
+ try {
16
+ return response.json();
17
+ } catch {
18
+ const text = await response.text();
19
+ return parse(text);
20
+ }
21
+ }
22
+ }
23
+ export {
24
+ loadRemote
25
+ };
26
+ //# sourceMappingURL=remote-loader.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/lib/loaders/remote-loader.ts"],
4
+ "sourcesContent": ["import { extname } from 'node:path';\nimport type { OpenAPIObject } from 'openapi3-ts/oas31';\nimport { parse } from 'yaml';\n\nexport async function loadRemote(location: string): Promise<OpenAPIObject> {\n const extName = extname(location);\n const response = await fetch(location);\n switch (extName) {\n case '.json':\n return response.json() as Promise<OpenAPIObject>;\n case '.yaml':\n case '.yml': {\n const text = await response.text();\n return parse(text);\n }\n default:\n try {\n // try to parse it as json first\n return response.json() as Promise<OpenAPIObject>;\n } catch {\n // parse as yaml\n const text = await response.text();\n return parse(text) as Promise<OpenAPIObject>;\n }\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,eAAe;AAExB,SAAS,aAAa;AAEtB,eAAsB,WAAW,UAA0C;AACzE,QAAM,UAAU,QAAQ,QAAQ;AAChC,QAAM,WAAW,MAAM,MAAM,QAAQ;AACrC,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,SAAS,KAAK;AAAA,IACvB,KAAK;AAAA,IACL,KAAK,QAAQ;AACX,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA,IACA;AACE,UAAI;AAEF,eAAO,SAAS,KAAK;AAAA,MACvB,QAAQ;AAEN,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAO,MAAM,IAAI;AAAA,MACnB;AAAA,EACJ;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,43 @@
1
+ import type { OpenAPIObject, OperationObject, ParameterObject, ReferenceObject } from 'openapi3-ts/oas31';
2
+ export declare const defaults: Partial<GenerateSdkConfig> & Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>>;
3
+ export type TunedOperationObject = OperationObject & {
4
+ operationId: string;
5
+ parameters: (ParameterObject | ReferenceObject)[];
6
+ };
7
+ export interface OperationEntry {
8
+ name?: string;
9
+ method: string;
10
+ path: string;
11
+ groupName: string;
12
+ tag: string;
13
+ }
14
+ export type Operation = {
15
+ entry: OperationEntry;
16
+ operation: TunedOperationObject;
17
+ };
18
+ export declare function forEachOperation<T>(config: GenerateSdkConfig, callback: (entry: OperationEntry, operation: TunedOperationObject) => T): T[];
19
+ export interface GenerateSdkConfig {
20
+ spec: OpenAPIObject;
21
+ operationId?: (operation: OperationObject, path: string, method: string) => string;
22
+ tag?: (operation: OperationObject, path: string) => string;
23
+ }
24
+ /**
25
+ * Attempts to determine a generic tag for an OpenAPI operation based on path and operationId.
26
+ * Rules and fallbacks are documented within the code.
27
+ * @param pathString The path string.
28
+ * @param operation The OpenAPI Operation Object.
29
+ * @returns A sanitized, camelCased tag name string.
30
+ */
31
+ export declare function determineGenericTag(pathString: string, operation: OperationObject): string;
32
+ export declare function parseJsonContentType(contentType: string | null | undefined): string | null;
33
+ /**
34
+ * Checks if a given content type string represents Server-Sent Events (SSE).
35
+ * Handles case-insensitivity, parameters (like charset), and leading/trailing whitespace.
36
+ *
37
+ * @param contentType The content type string to check (e.g., from a Content-Type header).
38
+ * @returns True if the content type is 'text/event-stream', false otherwise.
39
+ */
40
+ export declare function isSseContentType(contentType: string | null | undefined): boolean;
41
+ export declare function isStreamingContentType(contentType: string | null | undefined): boolean;
42
+ export declare function isSuccessStatusCode(statusCode: number | string): boolean;
43
+ //# sourceMappingURL=operation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation.d.ts","sourceRoot":"","sources":["../../src/lib/operation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,eAAe,EACf,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/C,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,KAAK,CAAC,CAmBxD,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,eAAe,GAAG;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,eAAe,GAAG,eAAe,CAAC,EAAE,CAAC;CACnD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,EAAE,cAAc,CAAC;IACtB,SAAS,EAAE,oBAAoB,CAAC;CACjC,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,MAAM,EAAE,iBAAiB,EACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,oBAAoB,KAAK,CAAC,OAqCxE;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,CAAC,EAAE,CACZ,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,KACX,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC5D;AAoHD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,eAAe,GACzB,MAAM,CAoLR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,iBAuB1E;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAoBT;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAET;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAGxE"}
@@ -0,0 +1,306 @@
1
+ import { camelcase } from "stringcase";
2
+ const defaults = {
3
+ operationId: (operation, path, method) => {
4
+ if (operation.operationId) {
5
+ return camelcase(operation.operationId);
6
+ }
7
+ const metadata = operation["x-oaiMeta"];
8
+ if (metadata && metadata.name) {
9
+ return camelcase(metadata.name);
10
+ }
11
+ return camelcase(
12
+ [method, ...path.replace(/[\\/\\{\\}]/g, " ").split(" ")].filter(Boolean).join(" ").trim()
13
+ );
14
+ },
15
+ tag: (operation, path) => {
16
+ return operation.tags?.[0] || determineGenericTag(path, operation);
17
+ }
18
+ };
19
+ function forEachOperation(config, callback) {
20
+ const result = [];
21
+ for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {
22
+ const { parameters = [], ...methods } = pathItem;
23
+ const fixedPath = path.replace(/:([^/]+)/g, "{$1}");
24
+ for (const [method, operation] of Object.entries(methods)) {
25
+ const formatOperationId = config.operationId ?? defaults.operationId;
26
+ const formatTag = config.tag ?? defaults.tag;
27
+ const operationName = formatOperationId(operation, fixedPath, method);
28
+ const operationTag = formatTag(operation, fixedPath);
29
+ const metadata = operation["x-oaiMeta"] ?? {};
30
+ result.push(
31
+ callback(
32
+ {
33
+ name: metadata.name,
34
+ method,
35
+ path: fixedPath,
36
+ groupName: operationTag,
37
+ tag: operationTag
38
+ },
39
+ {
40
+ ...operation,
41
+ parameters: [...parameters, ...operation.parameters ?? []],
42
+ operationId: operationName
43
+ }
44
+ )
45
+ );
46
+ }
47
+ }
48
+ return result;
49
+ }
50
+ const reservedKeywords = /* @__PURE__ */ new Set([
51
+ "abstract",
52
+ "arguments",
53
+ "await",
54
+ "boolean",
55
+ "break",
56
+ "byte",
57
+ "case",
58
+ "catch",
59
+ "char",
60
+ "class",
61
+ "const",
62
+ "continue",
63
+ "debugger",
64
+ "default",
65
+ "delete",
66
+ "do",
67
+ "double",
68
+ "else",
69
+ "enum",
70
+ "eval",
71
+ "export",
72
+ "extends",
73
+ "false",
74
+ "final",
75
+ "finally",
76
+ "float",
77
+ "for",
78
+ "function",
79
+ "goto",
80
+ "if",
81
+ "implements",
82
+ "import",
83
+ "in",
84
+ "instanceof",
85
+ "int",
86
+ "interface",
87
+ "let",
88
+ "long",
89
+ "native",
90
+ "new",
91
+ "null",
92
+ "package",
93
+ "private",
94
+ "protected",
95
+ "public",
96
+ "return",
97
+ "short",
98
+ "static",
99
+ "super",
100
+ "switch",
101
+ "synchronized",
102
+ "this",
103
+ "throw",
104
+ "throws",
105
+ "transient",
106
+ "true",
107
+ "try",
108
+ "typeof",
109
+ "var",
110
+ "void",
111
+ "volatile",
112
+ "while",
113
+ "with",
114
+ "yield",
115
+ // Potentially problematic identifiers / Common Verbs used as tags
116
+ "object",
117
+ "string",
118
+ "number",
119
+ "any",
120
+ "unknown",
121
+ "never",
122
+ "get",
123
+ "list",
124
+ "create",
125
+ "update",
126
+ "delete",
127
+ "post",
128
+ "put",
129
+ "patch",
130
+ "do",
131
+ "send",
132
+ "add",
133
+ "remove",
134
+ "set",
135
+ "find",
136
+ "search",
137
+ "check",
138
+ "make"
139
+ // Added make, check
140
+ ]);
141
+ function sanitizeTag(camelCasedTag) {
142
+ if (/^\d/.test(camelCasedTag)) {
143
+ return `_${camelCasedTag}`;
144
+ }
145
+ return reservedKeywords.has(camelCasedTag) ? `${camelCasedTag}_` : camelCasedTag;
146
+ }
147
+ function determineGenericTag(pathString, operation) {
148
+ const operationId = operation.operationId || "";
149
+ const VERSION_REGEX = /^[vV]\d+$/;
150
+ const commonVerbs = /* @__PURE__ */ new Set([
151
+ // Verbs to potentially strip from operationId prefix
152
+ "get",
153
+ "list",
154
+ "create",
155
+ "update",
156
+ "delete",
157
+ "post",
158
+ "put",
159
+ "patch",
160
+ "do",
161
+ "send",
162
+ "add",
163
+ "remove",
164
+ "set",
165
+ "find",
166
+ "search",
167
+ "check",
168
+ "make"
169
+ // Added make
170
+ ]);
171
+ const segments = pathString.split("/").filter(Boolean);
172
+ const potentialCandidates = segments.filter(
173
+ (segment) => segment && !segment.startsWith("{") && !segment.endsWith("}") && !VERSION_REGEX.test(segment)
174
+ );
175
+ for (let i = potentialCandidates.length - 1; i >= 0; i--) {
176
+ const segment = potentialCandidates[i];
177
+ if (!segment.startsWith("@")) {
178
+ return sanitizeTag(camelcase(segment));
179
+ }
180
+ }
181
+ const canFallbackToPathSegment = potentialCandidates.length > 0;
182
+ if (operationId) {
183
+ const lowerOpId = operationId.toLowerCase();
184
+ const parts = operationId.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").replace(/([a-zA-Z])(\d)/g, "$1_$2").replace(/(\d)([a-zA-Z])/g, "$1_$2").toLowerCase().split(/[_-\s]+/);
185
+ const validParts = parts.filter(Boolean);
186
+ if (commonVerbs.has(lowerOpId) && validParts.length === 1 && canFallbackToPathSegment) {
187
+ } else if (validParts.length > 0) {
188
+ const firstPart = validParts[0];
189
+ const isFirstPartVerb = commonVerbs.has(firstPart);
190
+ if (isFirstPartVerb && validParts.length > 1) {
191
+ const verbPrefixLength = firstPart.length;
192
+ let nextPartStartIndex = -1;
193
+ if (operationId.length > verbPrefixLength) {
194
+ const charAfterPrefix = operationId[verbPrefixLength];
195
+ if (charAfterPrefix >= "A" && charAfterPrefix <= "Z") {
196
+ nextPartStartIndex = verbPrefixLength;
197
+ } else if (charAfterPrefix >= "0" && charAfterPrefix <= "9") {
198
+ nextPartStartIndex = verbPrefixLength;
199
+ } else if (["_", "-"].includes(charAfterPrefix)) {
200
+ nextPartStartIndex = verbPrefixLength + 1;
201
+ } else {
202
+ const match = operationId.substring(verbPrefixLength).match(/[A-Z0-9]/);
203
+ if (match && match.index !== void 0) {
204
+ nextPartStartIndex = verbPrefixLength + match.index;
205
+ }
206
+ if (nextPartStartIndex === -1 && operationId.length > verbPrefixLength) {
207
+ nextPartStartIndex = verbPrefixLength;
208
+ }
209
+ }
210
+ }
211
+ if (nextPartStartIndex !== -1 && nextPartStartIndex < operationId.length) {
212
+ const remainingOriginalSubstring = operationId.substring(nextPartStartIndex);
213
+ const potentialTag = camelcase(remainingOriginalSubstring);
214
+ if (potentialTag) {
215
+ return sanitizeTag(potentialTag);
216
+ }
217
+ }
218
+ const potentialTagJoined = camelcase(validParts.slice(1).join("_"));
219
+ if (potentialTagJoined) {
220
+ return sanitizeTag(potentialTagJoined);
221
+ }
222
+ }
223
+ const potentialTagFull = camelcase(operationId);
224
+ if (potentialTagFull) {
225
+ const isResultSingleVerb = validParts.length === 1 && isFirstPartVerb;
226
+ if (!(isResultSingleVerb && canFallbackToPathSegment)) {
227
+ if (potentialTagFull.length > 0) {
228
+ return sanitizeTag(potentialTagFull);
229
+ }
230
+ }
231
+ }
232
+ const firstPartCamel = camelcase(firstPart);
233
+ if (firstPartCamel) {
234
+ const isFirstPartCamelVerb = commonVerbs.has(firstPartCamel);
235
+ if (!isFirstPartCamelVerb || validParts.length === 1 || !canFallbackToPathSegment) {
236
+ return sanitizeTag(firstPartCamel);
237
+ }
238
+ }
239
+ if (isFirstPartVerb && validParts.length > 1 && validParts[1] && canFallbackToPathSegment) {
240
+ const secondPartCamel = camelcase(validParts[1]);
241
+ if (secondPartCamel) {
242
+ return sanitizeTag(secondPartCamel);
243
+ }
244
+ }
245
+ }
246
+ }
247
+ if (potentialCandidates.length > 0) {
248
+ let firstCandidate = potentialCandidates[0];
249
+ if (firstCandidate.startsWith("@")) {
250
+ firstCandidate = firstCandidate.substring(1);
251
+ }
252
+ if (firstCandidate) {
253
+ return sanitizeTag(camelcase(firstCandidate));
254
+ }
255
+ }
256
+ console.warn(
257
+ `Could not determine a suitable tag for path: ${pathString}, operationId: ${operationId}. Using 'unknown'.`
258
+ );
259
+ return "unknown";
260
+ }
261
+ function parseJsonContentType(contentType) {
262
+ if (!contentType) {
263
+ return null;
264
+ }
265
+ let mainType = contentType.trim();
266
+ const semicolonIndex = mainType.indexOf(";");
267
+ if (semicolonIndex !== -1) {
268
+ mainType = mainType.substring(0, semicolonIndex).trim();
269
+ }
270
+ mainType = mainType.toLowerCase();
271
+ if (mainType.endsWith("/json")) {
272
+ return mainType.split("/")[1];
273
+ } else if (mainType.endsWith("+json")) {
274
+ return mainType.split("+")[1];
275
+ }
276
+ return null;
277
+ }
278
+ function isSseContentType(contentType) {
279
+ if (!contentType) {
280
+ return false;
281
+ }
282
+ let mainType = contentType.trim();
283
+ const semicolonIndex = mainType.indexOf(";");
284
+ if (semicolonIndex !== -1) {
285
+ mainType = mainType.substring(0, semicolonIndex).trim();
286
+ }
287
+ mainType = mainType.toLowerCase();
288
+ return mainType === "text/event-stream";
289
+ }
290
+ function isStreamingContentType(contentType) {
291
+ return contentType === "application/octet-stream";
292
+ }
293
+ function isSuccessStatusCode(statusCode) {
294
+ statusCode = Number(statusCode);
295
+ return statusCode >= 200 && statusCode < 300;
296
+ }
297
+ export {
298
+ defaults,
299
+ determineGenericTag,
300
+ forEachOperation,
301
+ isSseContentType,
302
+ isStreamingContentType,
303
+ isSuccessStatusCode,
304
+ parseJsonContentType
305
+ };
306
+ //# sourceMappingURL=operation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/operation.ts"],
4
+ "sourcesContent": ["import type {\n OpenAPIObject,\n OperationObject,\n ParameterObject,\n ReferenceObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>> = {\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return camelcase(operation.operationId);\n }\n const metadata = operation['x-oaiMeta'];\n if (metadata && metadata.name) {\n return camelcase(metadata.name);\n }\n return camelcase(\n [method, ...path.replace(/[\\\\/\\\\{\\\\}]/g, ' ').split(' ')]\n .filter(Boolean)\n .join(' ')\n .trim(),\n );\n },\n tag: (operation, path) => {\n return operation.tags?.[0] || determineGenericTag(path, operation);\n },\n};\n\nexport type TunedOperationObject = OperationObject & {\n operationId: string;\n parameters: (ParameterObject | ReferenceObject)[];\n};\n\nexport interface OperationEntry {\n name?: string;\n method: string;\n path: string;\n groupName: string;\n tag: string;\n}\nexport type Operation = {\n entry: OperationEntry;\n operation: TunedOperationObject;\n};\n\nexport function forEachOperation<T>(\n config: GenerateSdkConfig,\n callback: (entry: OperationEntry, operation: TunedOperationObject) => T,\n) {\n const result: T[] = [];\n for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {\n const { parameters = [], ...methods } = pathItem;\n\n // Convert Express-style routes (:param) to OpenAPI-style routes ({param})\n const fixedPath = path.replace(/:([^/]+)/g, '{$1}');\n\n for (const [method, operation] of Object.entries(methods) as [\n string,\n OperationObject,\n ][]) {\n const formatOperationId = config.operationId ?? defaults.operationId;\n const formatTag = config.tag ?? defaults.tag;\n const operationName = formatOperationId(operation, fixedPath, method);\n const operationTag = formatTag(operation, fixedPath);\n const metadata = operation['x-oaiMeta'] ?? {};\n result.push(\n callback(\n {\n name: metadata.name,\n method,\n path: fixedPath,\n groupName: operationTag,\n tag: operationTag,\n },\n {\n ...operation,\n parameters: [...parameters, ...(operation.parameters ?? [])],\n operationId: operationName,\n },\n ),\n );\n }\n }\n return result;\n}\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n tag?: (operation: OperationObject, path: string) => string;\n}\n\n// --- Function Definition (determineGenericTag, sanitizeTag, reservedKeywords, commonVerbs) ---\n/**\n * Set of reserved TypeScript keywords and common verbs potentially used as tags.\n */\nconst reservedKeywords = new Set([\n 'abstract',\n 'arguments',\n 'await',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n // Potentially problematic identifiers / Common Verbs used as tags\n 'object',\n 'string',\n 'number',\n 'any',\n 'unknown',\n 'never',\n 'get',\n 'list',\n 'create',\n 'update',\n 'delete',\n 'post',\n 'put',\n 'patch',\n 'do',\n 'send',\n 'add',\n 'remove',\n 'set',\n 'find',\n 'search',\n 'check',\n 'make', // Added make, check\n]);\n\n/**\n * Sanitizes a potential tag name (assumed to be already camelCased)\n * to avoid conflicts with reserved keywords or invalid starting characters (numbers).\n * Appends an underscore if the tag matches a reserved keyword.\n * Prepends an underscore if the tag starts with a number.\n * @param camelCasedTag The potential tag name, already camelCased.\n * @returns The sanitized tag name.\n */\nfunction sanitizeTag(camelCasedTag: string): string {\n // Prepend underscore if starts with a number\n if (/^\\d/.test(camelCasedTag)) {\n return `_${camelCasedTag}`;\n }\n // Append underscore if it's a reserved keyword\n return reservedKeywords.has(camelCasedTag)\n ? `${camelCasedTag}_`\n : camelCasedTag;\n}\n\n/**\n * Attempts to determine a generic tag for an OpenAPI operation based on path and operationId.\n * Rules and fallbacks are documented within the code.\n * @param pathString The path string.\n * @param operation The OpenAPI Operation Object.\n * @returns A sanitized, camelCased tag name string.\n */\nexport function determineGenericTag(\n pathString: string,\n operation: OperationObject,\n): string {\n const operationId = operation.operationId || '';\n const VERSION_REGEX = /^[vV]\\d+$/;\n const commonVerbs = new Set([\n // Verbs to potentially strip from operationId prefix\n 'get',\n 'list',\n 'create',\n 'update',\n 'delete',\n 'post',\n 'put',\n 'patch',\n 'do',\n 'send',\n 'add',\n 'remove',\n 'set',\n 'find',\n 'search',\n 'check',\n 'make', // Added make\n ]);\n\n const segments = pathString.split('/').filter(Boolean);\n\n const potentialCandidates = segments.filter(\n (segment) =>\n segment &&\n !segment.startsWith('{') &&\n !segment.endsWith('}') &&\n !VERSION_REGEX.test(segment),\n );\n\n // --- Heuristic 1: Last non-'@' path segment ---\n for (let i = potentialCandidates.length - 1; i >= 0; i--) {\n const segment = potentialCandidates[i];\n if (!segment.startsWith('@')) {\n // Sanitize just before returning\n return sanitizeTag(camelcase(segment));\n }\n }\n\n const canFallbackToPathSegment = potentialCandidates.length > 0;\n\n // --- Heuristic 2: OperationId parsing ---\n if (operationId) {\n const lowerOpId = operationId.toLowerCase();\n const parts = operationId\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')\n .replace(/([a-zA-Z])(\\d)/g, '$1_$2')\n .replace(/(\\d)([a-zA-Z])/g, '$1_$2')\n .toLowerCase()\n .split(/[_-\\s]+/);\n\n const validParts = parts.filter(Boolean);\n\n // Quick skip: If opId is just a verb and we can use Heuristic 3, prefer that.\n if (\n commonVerbs.has(lowerOpId) &&\n validParts.length === 1 &&\n canFallbackToPathSegment\n ) {\n // Proceed directly to Heuristic 3\n }\n // Only process if there are valid parts and the quick skip didn't happen\n else if (validParts.length > 0) {\n const firstPart = validParts[0];\n const isFirstPartVerb = commonVerbs.has(firstPart);\n\n // Case 2a: Starts with verb, has following parts\n if (isFirstPartVerb && validParts.length > 1) {\n const verbPrefixLength = firstPart.length;\n let nextPartStartIndex = -1;\n if (operationId.length > verbPrefixLength) {\n // Simplified check for next part start\n const charAfterPrefix = operationId[verbPrefixLength];\n if (charAfterPrefix >= 'A' && charAfterPrefix <= 'Z') {\n nextPartStartIndex = verbPrefixLength;\n } else if (charAfterPrefix >= '0' && charAfterPrefix <= '9') {\n nextPartStartIndex = verbPrefixLength;\n } else if (['_', '-'].includes(charAfterPrefix)) {\n nextPartStartIndex = verbPrefixLength + 1;\n } else {\n const match = operationId\n .substring(verbPrefixLength)\n .match(/[A-Z0-9]/);\n if (match && match.index !== undefined) {\n nextPartStartIndex = verbPrefixLength + match.index;\n }\n if (\n nextPartStartIndex === -1 &&\n operationId.length > verbPrefixLength\n ) {\n nextPartStartIndex = verbPrefixLength; // Default guess\n }\n }\n }\n\n if (\n nextPartStartIndex !== -1 &&\n nextPartStartIndex < operationId.length\n ) {\n const remainingOriginalSubstring =\n operationId.substring(nextPartStartIndex);\n const potentialTag = camelcase(remainingOriginalSubstring);\n if (potentialTag) {\n // Sanitize just before returning\n return sanitizeTag(potentialTag);\n }\n }\n\n // Fallback: join remaining lowercased parts\n const potentialTagJoined = camelcase(validParts.slice(1).join('_'));\n if (potentialTagJoined) {\n // Sanitize just before returning\n return sanitizeTag(potentialTagJoined);\n }\n }\n\n // Case 2b: Doesn't start with verb, or only one part (might be verb)\n const potentialTagFull = camelcase(operationId);\n if (potentialTagFull) {\n const isResultSingleVerb = validParts.length === 1 && isFirstPartVerb;\n\n // Avoid returning only a verb if Heuristic 3 is possible\n if (!(isResultSingleVerb && canFallbackToPathSegment)) {\n if (potentialTagFull.length > 0) {\n // Sanitize just before returning\n return sanitizeTag(potentialTagFull);\n }\n }\n }\n\n // Case 2c: Further fallbacks within OpId if above failed/skipped\n const firstPartCamel = camelcase(firstPart);\n if (firstPartCamel) {\n const isFirstPartCamelVerb = commonVerbs.has(firstPartCamel);\n if (\n !isFirstPartCamelVerb ||\n validParts.length === 1 ||\n !canFallbackToPathSegment\n ) {\n // Sanitize just before returning\n return sanitizeTag(firstPartCamel);\n }\n }\n if (\n isFirstPartVerb &&\n validParts.length > 1 &&\n validParts[1] &&\n canFallbackToPathSegment\n ) {\n const secondPartCamel = camelcase(validParts[1]);\n if (secondPartCamel) {\n // Sanitize just before returning\n return sanitizeTag(secondPartCamel);\n }\n }\n } // End if(validParts.length > 0) after quick skip check\n } // End if(operationId)\n\n // --- Heuristic 3: First path segment (stripping '@') ---\n if (potentialCandidates.length > 0) {\n let firstCandidate = potentialCandidates[0];\n if (firstCandidate.startsWith('@')) {\n firstCandidate = firstCandidate.substring(1);\n }\n if (firstCandidate) {\n // Sanitize just before returning\n return sanitizeTag(camelcase(firstCandidate));\n }\n }\n\n // --- Heuristic 4: Default ---\n console.warn(\n `Could not determine a suitable tag for path: ${pathString}, operationId: ${operationId}. Using 'unknown'.`,\n );\n return 'unknown'; // 'unknown' is safe\n}\n\nexport function parseJsonContentType(contentType: string | null | undefined) {\n if (!contentType) {\n return null;\n }\n\n // 1. Trim whitespace\n let mainType = contentType.trim();\n\n // 2. Remove parameters (anything after the first ';')\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim(); // Trim potential space before ';'\n }\n\n // 3. Convert to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n if (mainType.endsWith('/json')) {\n return mainType.split('/')[1];\n } else if (mainType.endsWith('+json')) {\n return mainType.split('+')[1];\n }\n return null;\n}\n\n/**\n * Checks if a given content type string represents Server-Sent Events (SSE).\n * Handles case-insensitivity, parameters (like charset), and leading/trailing whitespace.\n *\n * @param contentType The content type string to check (e.g., from a Content-Type header).\n * @returns True if the content type is 'text/event-stream', false otherwise.\n */\nexport function isSseContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n // 4. Compare against the standard SSE MIME type\n return mainType === 'text/event-stream';\n}\n\nexport function isStreamingContentType(\n contentType: string | null | undefined,\n): boolean {\n return contentType === 'application/octet-stream';\n}\n\nexport function isSuccessStatusCode(statusCode: number | string): boolean {\n statusCode = Number(statusCode);\n return statusCode >= 200 && statusCode < 300;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/lib/test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,261 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, test } from "node:test";
3
+ import { determineGenericTag } from "./operation.ts";
4
+ const mockOperation = (operationId = "") => ({ operationId });
5
+ describe("determineGenericTag", () => {
6
+ describe("Heuristic 1: Path-Based Tag Determination", () => {
7
+ test("should use the last non-parameter, non-version, non-@ segment", () => {
8
+ assert.strictEqual(
9
+ determineGenericTag("/users", mockOperation()),
10
+ "users"
11
+ );
12
+ assert.strictEqual(
13
+ determineGenericTag("/users/{userId}/orders", mockOperation()),
14
+ "orders"
15
+ );
16
+ assert.strictEqual(
17
+ determineGenericTag("/admin/system/logs", mockOperation()),
18
+ "logs"
19
+ );
20
+ });
21
+ test("should ignore path parameters", () => {
22
+ assert.strictEqual(
23
+ determineGenericTag("/users/{userId}", mockOperation()),
24
+ "users"
25
+ );
26
+ assert.strictEqual(
27
+ determineGenericTag("/items/{itemId}", mockOperation()),
28
+ "items"
29
+ );
30
+ });
31
+ test("should ignore version segments", () => {
32
+ assert.strictEqual(
33
+ determineGenericTag("/v1/products", mockOperation()),
34
+ "products"
35
+ );
36
+ assert.strictEqual(
37
+ determineGenericTag("/api/V2/items/{itemId}/details", mockOperation()),
38
+ "details"
39
+ );
40
+ assert.strictEqual(
41
+ determineGenericTag("/api/resource/v2", mockOperation()),
42
+ "resource"
43
+ );
44
+ });
45
+ test("should ignore segments starting with @", () => {
46
+ assert.strictEqual(
47
+ determineGenericTag("/users/@me", mockOperation()),
48
+ "users"
49
+ );
50
+ assert.strictEqual(
51
+ determineGenericTag("/users/@me/guilds", mockOperation()),
52
+ "guilds"
53
+ );
54
+ assert.strictEqual(
55
+ determineGenericTag(
56
+ "/webhooks/{webhookId}/messages/@original",
57
+ mockOperation()
58
+ ),
59
+ "messages"
60
+ );
61
+ assert.strictEqual(
62
+ determineGenericTag("/@admin/users/{userId}", mockOperation()),
63
+ "users"
64
+ );
65
+ assert.strictEqual(
66
+ determineGenericTag(
67
+ "/guilds/{guild_id}/@audit-log/users/@me/settings",
68
+ mockOperation()
69
+ ),
70
+ "settings"
71
+ );
72
+ assert.strictEqual(
73
+ determineGenericTag("/system/tasks/@scheduled-jobs", mockOperation()),
74
+ "tasks"
75
+ );
76
+ });
77
+ test("should sanitize results matching reserved keywords", () => {
78
+ assert.strictEqual(
79
+ determineGenericTag("/api/v1/public", mockOperation()),
80
+ "public_"
81
+ );
82
+ assert.strictEqual(
83
+ determineGenericTag("/api/case/{id}", mockOperation()),
84
+ "case_"
85
+ );
86
+ assert.strictEqual(
87
+ determineGenericTag("/permissions/check", mockOperation()),
88
+ "check_"
89
+ );
90
+ });
91
+ test("should sanitize results starting with numbers", () => {
92
+ assert.strictEqual(
93
+ determineGenericTag("/api/2fa/enable", mockOperation()),
94
+ "enable"
95
+ );
96
+ });
97
+ test("should handle mixed separators via camelcase", () => {
98
+ assert.strictEqual(
99
+ determineGenericTag("/user-profiles/{id}", mockOperation()),
100
+ "userProfiles"
101
+ );
102
+ });
103
+ });
104
+ describe("Heuristic 2: OperationId Fallback", () => {
105
+ test("should be used when path has no valid segments (root)", () => {
106
+ assert.strictEqual(
107
+ determineGenericTag("/", mockOperation("getRootResource")),
108
+ "rootResource"
109
+ );
110
+ assert.strictEqual(
111
+ determineGenericTag("/", mockOperation("healthCheck")),
112
+ "healthCheck"
113
+ );
114
+ });
115
+ test("should be used when path has only params/version segments", () => {
116
+ assert.strictEqual(
117
+ determineGenericTag("/v3/{tenantId}/", mockOperation("getTenantRoot")),
118
+ "tenantRoot"
119
+ );
120
+ assert.strictEqual(
121
+ determineGenericTag("/v1/{userId}/", mockOperation("listUserItems")),
122
+ "userItems"
123
+ );
124
+ });
125
+ test("should extract nouns after common verb prefixes", () => {
126
+ assert.strictEqual(
127
+ determineGenericTag("/v1/", mockOperation("postUserPreferences")),
128
+ "userPreferences"
129
+ );
130
+ assert.strictEqual(
131
+ determineGenericTag("/v1/", mockOperation("doFoo")),
132
+ "foo"
133
+ );
134
+ assert.strictEqual(
135
+ determineGenericTag("/v1/", mockOperation("addUser")),
136
+ "user"
137
+ );
138
+ assert.strictEqual(
139
+ determineGenericTag("/v1/", mockOperation("makePublic")),
140
+ "public_"
141
+ );
142
+ });
143
+ test("should use the full operationId if no common verb prefix", () => {
144
+ assert.strictEqual(
145
+ determineGenericTag("/v1/", mockOperation("metrics")),
146
+ "metrics"
147
+ );
148
+ assert.strictEqual(
149
+ determineGenericTag("/v1/", mockOperation("tenantAdminSettings")),
150
+ "tenantAdminSettings"
151
+ );
152
+ });
153
+ test("should handle numbers within the operationId correctly", () => {
154
+ assert.strictEqual(
155
+ determineGenericTag("/v1/", mockOperation("getUser2FAStatus")),
156
+ "user2FAStatus"
157
+ );
158
+ assert.strictEqual(
159
+ determineGenericTag("/api/", mockOperation("get2FAStatus")),
160
+ "api"
161
+ );
162
+ });
163
+ test("should sanitize results matching reserved keywords", () => {
164
+ assert.strictEqual(
165
+ determineGenericTag("/v1/{id}", mockOperation("delete")),
166
+ "delete_"
167
+ );
168
+ assert.strictEqual(
169
+ determineGenericTag("/v1/{id}", mockOperation("createCase")),
170
+ "case_"
171
+ );
172
+ assert.strictEqual(
173
+ determineGenericTag("/v1/{id}", mockOperation("get")),
174
+ "get_"
175
+ );
176
+ });
177
+ test("should use verb if it is the only part and no path fallback", () => {
178
+ assert.strictEqual(
179
+ determineGenericTag("/v1/", mockOperation("get")),
180
+ "get_"
181
+ );
182
+ assert.strictEqual(
183
+ determineGenericTag("/v1/{id}", mockOperation("list")),
184
+ "list_"
185
+ );
186
+ });
187
+ });
188
+ describe("Heuristic 3: First Path Segment Fallback", () => {
189
+ test("should be used when path only has @ segments and no suitable opId", () => {
190
+ assert.strictEqual(
191
+ determineGenericTag("/@system/@status", mockOperation()),
192
+ "system"
193
+ );
194
+ assert.strictEqual(
195
+ determineGenericTag("/@audit-log/@entries", mockOperation()),
196
+ "auditLog"
197
+ );
198
+ });
199
+ test("should be used when opId fallback yields only a common verb", () => {
200
+ assert.strictEqual(
201
+ determineGenericTag("/@system/@status", mockOperation("get")),
202
+ "system"
203
+ );
204
+ });
205
+ test("should strip leading @ before using segment", () => {
206
+ assert.strictEqual(
207
+ determineGenericTag("/@system/@status", mockOperation()),
208
+ "system"
209
+ );
210
+ });
211
+ test("should sanitize results matching reserved keywords", () => {
212
+ assert.strictEqual(
213
+ determineGenericTag("/@public/@data", mockOperation()),
214
+ "public_"
215
+ );
216
+ });
217
+ test("should sanitize results starting with numbers", () => {
218
+ assert.strictEqual(
219
+ determineGenericTag("/@2fa/@status", mockOperation()),
220
+ "_2fa"
221
+ );
222
+ });
223
+ });
224
+ describe("Heuristic Priority", () => {
225
+ test("Path (Heuristic 1) should take priority over OperationId (Heuristic 2)", () => {
226
+ const tag = determineGenericTag(
227
+ "/users/{id}/permissions/check",
228
+ // Path -> 'check' -> sanitized 'check_'
229
+ mockOperation("verifyPermissions")
230
+ // opId -> 'permissions'
231
+ );
232
+ assert.strictEqual(tag, "check_");
233
+ });
234
+ test("OperationId (Heuristic 2) should take priority over First Path Segment (Heuristic 3)", () => {
235
+ const tag = determineGenericTag(
236
+ "/@system/@status",
237
+ mockOperation("getSystemStatus")
238
+ );
239
+ assert.strictEqual(tag, "systemStatus");
240
+ });
241
+ test("First Path Segment (Heuristic 3) is used if OperationId is skipped (verb-only)", () => {
242
+ const tag = determineGenericTag("/@system/@status", mockOperation("get"));
243
+ assert.strictEqual(tag, "system");
244
+ });
245
+ });
246
+ describe("Heuristic 4: Unknown Fallback", () => {
247
+ test('should return "unknown" when no path segments and no operationId', () => {
248
+ assert.strictEqual(determineGenericTag("/", mockOperation()), "unknown");
249
+ });
250
+ test('should return "unknown" when path has only params/version and no operationId', () => {
251
+ assert.strictEqual(
252
+ determineGenericTag("/v3/{tenantId}/", mockOperation()),
253
+ "unknown"
254
+ );
255
+ });
256
+ test('should return "unknown" for empty path string', () => {
257
+ assert.strictEqual(determineGenericTag("", mockOperation()), "unknown");
258
+ });
259
+ });
260
+ });
261
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/test.ts"],
4
+ "sourcesContent": ["import assert from 'node:assert/strict';\nimport { describe, test } from 'node:test';\nimport type { OperationObject } from 'openapi3-ts/oas31';\n\nimport { determineGenericTag } from './operation.ts';\n\nconst mockOperation = (operationId = ''): OperationObject => ({ operationId });\n\ndescribe('determineGenericTag', () => {\n describe('Heuristic 1: Path-Based Tag Determination', () => {\n test('should use the last non-parameter, non-version, non-@ segment', () => {\n assert.strictEqual(\n determineGenericTag('/users', mockOperation()),\n 'users',\n );\n assert.strictEqual(\n determineGenericTag('/users/{userId}/orders', mockOperation()),\n 'orders',\n );\n assert.strictEqual(\n determineGenericTag('/admin/system/logs', mockOperation()),\n 'logs',\n );\n });\n\n test('should ignore path parameters', () => {\n assert.strictEqual(\n determineGenericTag('/users/{userId}', mockOperation()),\n 'users',\n );\n assert.strictEqual(\n determineGenericTag('/items/{itemId}', mockOperation()),\n 'items',\n );\n });\n\n test('should ignore version segments', () => {\n assert.strictEqual(\n determineGenericTag('/v1/products', mockOperation()),\n 'products',\n );\n assert.strictEqual(\n determineGenericTag('/api/V2/items/{itemId}/details', mockOperation()),\n 'details',\n );\n assert.strictEqual(\n determineGenericTag('/api/resource/v2', mockOperation()),\n 'resource',\n );\n });\n\n test('should ignore segments starting with @', () => {\n assert.strictEqual(\n determineGenericTag('/users/@me', mockOperation()),\n 'users',\n );\n assert.strictEqual(\n determineGenericTag('/users/@me/guilds', mockOperation()),\n 'guilds',\n );\n assert.strictEqual(\n determineGenericTag(\n '/webhooks/{webhookId}/messages/@original',\n mockOperation(),\n ),\n 'messages',\n );\n assert.strictEqual(\n determineGenericTag('/@admin/users/{userId}', mockOperation()),\n 'users',\n );\n assert.strictEqual(\n determineGenericTag(\n '/guilds/{guild_id}/@audit-log/users/@me/settings',\n mockOperation(),\n ),\n 'settings',\n );\n assert.strictEqual(\n determineGenericTag('/system/tasks/@scheduled-jobs', mockOperation()),\n 'tasks',\n );\n });\n\n test('should sanitize results matching reserved keywords', () => {\n assert.strictEqual(\n determineGenericTag('/api/v1/public', mockOperation()),\n 'public_',\n );\n assert.strictEqual(\n determineGenericTag('/api/case/{id}', mockOperation()),\n 'case_',\n );\n assert.strictEqual(\n determineGenericTag('/permissions/check', mockOperation()),\n 'check_',\n );\n });\n\n test('should sanitize results starting with numbers', () => {\n // FIX: Expectation changed - last valid segment is 'enable'\n assert.strictEqual(\n determineGenericTag('/api/2fa/enable', mockOperation()),\n 'enable',\n );\n });\n\n test('should handle mixed separators via camelcase', () => {\n assert.strictEqual(\n determineGenericTag('/user-profiles/{id}', mockOperation()),\n 'userProfiles',\n );\n });\n });\n\n describe('Heuristic 2: OperationId Fallback', () => {\n test('should be used when path has no valid segments (root)', () => {\n assert.strictEqual(\n determineGenericTag('/', mockOperation('getRootResource')),\n 'rootResource',\n );\n // FIX: Expectation changed - 'healthCheck' is not reserved\n assert.strictEqual(\n determineGenericTag('/', mockOperation('healthCheck')),\n 'healthCheck',\n );\n });\n\n test('should be used when path has only params/version segments', () => {\n assert.strictEqual(\n determineGenericTag('/v3/{tenantId}/', mockOperation('getTenantRoot')),\n 'tenantRoot',\n );\n assert.strictEqual(\n determineGenericTag('/v1/{userId}/', mockOperation('listUserItems')),\n 'userItems',\n );\n });\n\n test('should extract nouns after common verb prefixes', () => {\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('postUserPreferences')),\n 'userPreferences',\n );\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('doFoo')),\n 'foo',\n );\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('addUser')),\n 'user',\n );\n // FIX: Added 'make' to commonVerbs\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('makePublic')),\n 'public_',\n );\n });\n\n test('should use the full operationId if no common verb prefix', () => {\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('metrics')),\n 'metrics',\n );\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('tenantAdminSettings')),\n 'tenantAdminSettings',\n );\n });\n\n test('should handle numbers within the operationId correctly', () => {\n // FIX: Expectation aligned with stringcase behavior\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('getUser2FAStatus')),\n 'user2FAStatus',\n );\n assert.strictEqual(\n determineGenericTag('/api/', mockOperation('get2FAStatus')),\n 'api',\n ); // Sanitized (starts with number after verb removal)\n });\n\n test('should sanitize results matching reserved keywords', () => {\n assert.strictEqual(\n determineGenericTag('/v1/{id}', mockOperation('delete')),\n 'delete_',\n );\n assert.strictEqual(\n determineGenericTag('/v1/{id}', mockOperation('createCase')),\n 'case_',\n );\n assert.strictEqual(\n determineGenericTag('/v1/{id}', mockOperation('get')),\n 'get_',\n );\n });\n\n test('should use verb if it is the only part and no path fallback', () => {\n assert.strictEqual(\n determineGenericTag('/v1/', mockOperation('get')),\n 'get_',\n );\n assert.strictEqual(\n determineGenericTag('/v1/{id}', mockOperation('list')),\n 'list_',\n );\n });\n });\n\n describe('Heuristic 3: First Path Segment Fallback', () => {\n test('should be used when path only has @ segments and no suitable opId', () => {\n assert.strictEqual(\n determineGenericTag('/@system/@status', mockOperation()),\n 'system',\n );\n assert.strictEqual(\n determineGenericTag('/@audit-log/@entries', mockOperation()),\n 'auditLog',\n );\n });\n\n test('should be used when opId fallback yields only a common verb', () => {\n assert.strictEqual(\n determineGenericTag('/@system/@status', mockOperation('get')),\n 'system',\n );\n });\n\n test('should strip leading @ before using segment', () => {\n assert.strictEqual(\n determineGenericTag('/@system/@status', mockOperation()),\n 'system',\n );\n });\n\n test('should sanitize results matching reserved keywords', () => {\n assert.strictEqual(\n determineGenericTag('/@public/@data', mockOperation()),\n 'public_',\n );\n });\n\n test('should sanitize results starting with numbers', () => {\n assert.strictEqual(\n determineGenericTag('/@2fa/@status', mockOperation()),\n '_2fa',\n );\n });\n });\n\n describe('Heuristic Priority', () => {\n test('Path (Heuristic 1) should take priority over OperationId (Heuristic 2)', () => {\n const tag = determineGenericTag(\n '/users/{id}/permissions/check', // Path -> 'check' -> sanitized 'check_'\n mockOperation('verifyPermissions'), // opId -> 'permissions'\n );\n assert.strictEqual(tag, 'check_');\n });\n\n test('OperationId (Heuristic 2) should take priority over First Path Segment (Heuristic 3)', () => {\n const tag = determineGenericTag(\n '/@system/@status',\n mockOperation('getSystemStatus'),\n );\n assert.strictEqual(tag, 'systemStatus');\n });\n\n test('First Path Segment (Heuristic 3) is used if OperationId is skipped (verb-only)', () => {\n const tag = determineGenericTag('/@system/@status', mockOperation('get'));\n assert.strictEqual(tag, 'system');\n });\n });\n\n describe('Heuristic 4: Unknown Fallback', () => {\n test('should return \"unknown\" when no path segments and no operationId', () => {\n assert.strictEqual(determineGenericTag('/', mockOperation()), 'unknown');\n });\n\n test('should return \"unknown\" when path has only params/version and no operationId', () => {\n assert.strictEqual(\n determineGenericTag('/v3/{tenantId}/', mockOperation()),\n 'unknown',\n );\n });\n\n test('should return \"unknown\" for empty path string', () => {\n assert.strictEqual(determineGenericTag('', mockOperation()), 'unknown');\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@sdk-it/spec",
3
+ "version": "0.17.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "exports": {
12
+ "./package.json": "./package.json",
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ },
18
+ "./*": {
19
+ "types": "./dist/lib/*",
20
+ "import": "./dist/lib/*",
21
+ "default": "./dist/lib/*"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "!**/*.tsbuildinfo"
27
+ ],
28
+ "dependencies": {
29
+ "openapi3-ts": "4.4.0",
30
+ "yaml": "^2.7.0",
31
+ "stringcase": "^4.3.1"
32
+ }
33
+ }