@sdk-it/generic 0.25.0 → 0.26.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.
package/README.md CHANGED
@@ -58,7 +58,6 @@ const { paths, components } = await analyze('path/to/tsconfig.json', {
58
58
  responseAnalyzer,
59
59
  });
60
60
 
61
- // Now you can use the generated specification to create an SDK or save it to a file
62
61
  const spec = {
63
62
  info: {
64
63
  title: 'My API',
@@ -67,13 +66,15 @@ const spec = {
67
66
  paths,
68
67
  components,
69
68
  };
70
- await generate(spec, {
71
- output: join(process.cwd(), './client'),
72
- });
69
+
70
+ await writeFile(
71
+ join(process.cwd(), 'openapi.json'),
72
+ JSON.stringify(spec, null, 2),
73
+ );
73
74
  ```
74
75
 
75
76
  > [!TIP]
76
- > See [typescript](../typescript/README.md) for more info.
77
+ > See [typescript](../typescript/README.md) to create fully functional SDKs from the generated OpenAPI specification.
77
78
 
78
79
  ### Customizing Operations
79
80
 
@@ -115,3 +116,46 @@ const { paths, components } = await analyze('apps/backend/tsconfig.app.json', {
115
116
  },
116
117
  });
117
118
  ```
119
+
120
+ ### Customizing Type Mappings
121
+
122
+ The type analysis can be customized to handle types that are not standard in TypeScript, such as `Decimal` from Prisma. The `typesMap` option in the `analyze` function allows you to provide your own type mappings.
123
+
124
+ The example below shows how to map a `Decimal` type to a `string`.
125
+
126
+ ```typescript
127
+ import { writeFile } from 'node:fs/promises';
128
+ import { join } from 'node:path';
129
+ import { cwd } from 'node:process';
130
+
131
+ import { defaultTypesMap } from '@sdk-it/core';
132
+ import { analyze } from '@sdk-it/generic';
133
+ import { responseAnalyzer } from '@sdk-it/hono';
134
+
135
+ // Define custom type mappings
136
+ const customTypeMappings = {
137
+ Decimal: 'string',
138
+ };
139
+
140
+ const { paths, components } = await analyze('path/to/tsconfig.json', {
141
+ responseAnalyzer,
142
+ typesMap: {
143
+ ...defaultTypesMap,
144
+ Decimal: 'string',
145
+ },
146
+ });
147
+
148
+ const spec = {
149
+ openapi: '3.1.0',
150
+ info: {
151
+ title: 'My API',
152
+ version: '1.0.0',
153
+ },
154
+ paths,
155
+ components,
156
+ };
157
+
158
+ await writeFile('openapi.json', JSON.stringify(spec, null, 2));
159
+ ```
160
+
161
+ This configuration ensures that any property with the `Decimal` type is represented as a `string` in the generated OpenAPI specification.
package/dist/index.js CHANGED
@@ -201,6 +201,7 @@ async function analyze(tsconfigPath, config) {
201
201
  };
202
202
  return {
203
203
  paths: await paths.getPaths(),
204
+ tags: paths.getTags(),
204
205
  components
205
206
  };
206
207
  }
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/lib/generic.ts", "../src/lib/response-analyzer.ts"],
4
- "sourcesContent": ["import debug from 'debug';\nimport type { ComponentsObject } from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\nimport ts from 'typescript';\n\nimport {\n type InjectImport,\n type NaunceResponseAnalyzer,\n type OnOperation,\n Paths,\n type ResponseAnalyzerFn,\n type ResponseItem,\n type Selector,\n type SemanticSource,\n TypeDeriver,\n getProgram,\n isCallExpression,\n isHttpMethod,\n toSchema,\n} from '@sdk-it/core';\n\nexport const returnToken = (node: ts.ArrowFunction) => {\n const tokens: { token: string; node: ts.Expression }[] = [];\n\n const visitor: ts.Visitor = (node) => {\n if (ts.isThrowStatement(node)) {\n if (ts.isNewExpression(node.expression)) {\n tokens.push({\n token: `throw.new.${node.expression.expression.getText()}`,\n node: node.expression,\n });\n }\n }\n\n if (ts.isReturnStatement(node) && node.expression) {\n if (ts.isCallExpression(node.expression)) {\n tokens.push({\n token: node.expression.expression.getText(),\n node: node.expression,\n });\n }\n return undefined;\n }\n\n return ts.forEachChild(node, visitor);\n };\n\n ts.forEachChild(node, visitor);\n return tokens;\n};\n\nconst logger = debug('@sdk-it/generic');\n\nconst jsDocsTags = ['openapi', 'tags', 'description'];\n\nfunction parseJSDocComment(node: ts.Node) {\n let tags: string[] = [];\n let name = '';\n let description = '';\n for (const tag of ts.getAllJSDocTags(node, (tag): tag is ts.JSDocTag =>\n jsDocsTags.includes(tag.tagName.text),\n )) {\n if (typeof tag.comment !== 'string') {\n continue;\n }\n switch (tag.tagName.text) {\n case 'openapi':\n name = tag.comment;\n break;\n case 'tags':\n tags = tag.comment.split(',').map((tag) => tag.trim());\n break;\n case 'description':\n description = tag.comment;\n break;\n }\n }\n return {\n name,\n tags,\n description,\n };\n}\n\nfunction visit(\n node: ts.Node,\n responseAnalyzer: (\n handler: ts.ArrowFunction,\n token: string,\n node: ts.Node,\n ) => ResponseItem[],\n paths: Paths,\n) {\n if (!ts.isCallExpression(node) || node.arguments.length < 2) {\n return moveOn();\n }\n if (\n !ts.isPropertyAccessExpression(node.expression) ||\n !ts.isIdentifier(node.expression.name) ||\n !isHttpMethod(node.expression.name.text)\n ) {\n return moveOn();\n }\n\n const [pathNode] = node.arguments;\n if (!ts.isStringLiteral(pathNode)) {\n return moveOn();\n }\n const method = node.expression.name.text;\n const path = pathNode.text;\n const validate = node.arguments.find((arg) =>\n isCallExpression(arg, 'validate'),\n );\n if (!validate) {\n return moveOn();\n }\n const handler = node.arguments.at(-1);\n if (!handler || !ts.isArrowFunction(handler)) {\n return moveOn();\n }\n\n const metadata = parseJSDocComment(node.parent);\n const operationName =\n metadata.name ||\n camelcase(`${method} ${path.replace(/[^a-zA-Z0-9]/g, '')}`);\n if (!validate.arguments.length) {\n return moveOn();\n }\n let selector: ts.Expression | undefined;\n let contentType: ts.Expression | undefined;\n if (validate.arguments.length === 2) {\n contentType = validate.arguments[0];\n selector = validate.arguments[1];\n } else {\n selector = validate.arguments[0];\n }\n if (!ts.isArrowFunction(selector)) {\n return moveOn();\n }\n if (\n !selector ||\n !ts.isParenthesizedExpression(selector.body) ||\n !ts.isObjectLiteralExpression(selector.body.expression)\n ) {\n return moveOn();\n }\n const props = selector.body.expression.properties.filter(\n ts.isPropertyAssignment,\n );\n\n const sourceFile = node.getSourceFile();\n const tokens = returnToken(handler);\n\n const responses: ResponseItem[] = [];\n for (const { token, node } of tokens) {\n responses.push(...responseAnalyzer(handler, token, node));\n }\n\n paths.addPath(\n operationName,\n path,\n method,\n contentType\n ? ts.isStringLiteral(contentType)\n ? contentType.text\n : undefined\n : undefined,\n toSelectors(props),\n responses,\n sourceFile.fileName,\n metadata.tags,\n metadata.description,\n );\n\n function moveOn() {\n ts.forEachChild(node, (node) => visit(node, responseAnalyzer, paths));\n }\n}\n\nfunction toSelectors(props: ts.PropertyAssignment[]) {\n const selectors: Selector[] = [];\n for (const prop of props) {\n if (!ts.isObjectLiteralExpression(prop.initializer)) {\n continue;\n }\n const name = prop.name.getText();\n const select = prop.initializer.properties\n .filter(ts.isPropertyAssignment)\n .find((prop) => prop.name.getText() === 'select');\n if (!select) {\n console.warn(`No select found in ${name}`);\n continue;\n }\n const against = prop.initializer.properties\n .filter(ts.isPropertyAssignment)\n .find((prop) => prop.name.getText() === 'against');\n if (!against) {\n console.warn(`No against found in ${name}`);\n continue;\n }\n const [, source, selectText] = select.initializer.getText().split('.');\n selectors.push({\n name,\n nullable: against.initializer.getText().includes('nullable'),\n required: !against.initializer.getText().includes('optional'),\n select: selectText,\n against: against.initializer.getText(),\n source: source as SemanticSource,\n });\n }\n return selectors;\n}\n\nexport async function analyze(\n tsconfigPath: string,\n config: {\n /**\n * Additional code to inject before resolving zod schemas\n */\n imports?: InjectImport[];\n typesMap?: Record<string, string>;\n responseAnalyzer: ResponseAnalyzerFn | NaunceResponseAnalyzer;\n onOperation?: OnOperation;\n },\n) {\n logger(`Parsing tsconfig`);\n const program = getProgram(tsconfigPath);\n logger(`Program created`);\n const typeChecker = program.getTypeChecker();\n\n logger(`Type checker created`);\n const typeDeriver = new TypeDeriver(typeChecker, config.typesMap);\n const paths = new Paths({\n imports: config.imports ?? [],\n onOperation: config.onOperation,\n });\n\n for (const sourceFile of program.getSourceFiles()) {\n logger(`Analyzing ${sourceFile.fileName}`);\n if (!sourceFile.isDeclarationFile) {\n logger(`Visiting ${sourceFile.fileName}`);\n visit(\n sourceFile,\n (handler, token, node) => {\n const responseAnalyzer = config.responseAnalyzer;\n if (typeof responseAnalyzer !== 'function') {\n const naunce =\n responseAnalyzer[token] || responseAnalyzer['default'];\n if (!naunce) {\n throw new Error(`No response analyzer for token ${token}`);\n }\n return naunce(handler, typeDeriver, node);\n }\n return responseAnalyzer(handler, typeDeriver);\n },\n paths,\n );\n }\n }\n\n const components: ComponentsObject = {\n schemas: Object.entries(typeDeriver.collector).reduce(\n (acc, [key, value]) => ({ ...acc, [key]: toSchema(value) }),\n {},\n ),\n };\n\n return {\n paths: await paths.getPaths(),\n components,\n };\n}\n\nexport type Serialized = ReturnType<typeof analyze>;\n", "import ts from 'typescript';\n\nimport type {\n NaunceResponseAnalyzer,\n ResponseItem,\n TypeDeriver,\n} from '@sdk-it/core';\n\nconst handlerVisitor: (\n on: (\n node: ts.Node | undefined,\n statusCode: ts.Node | undefined,\n headers: ts.Node | undefined,\n contentType: string,\n ) => void,\n) => ts.Visitor = (callback) => {\n return (node: ts.Node) => {\n if (ts.isReturnStatement(node) && node.expression) {\n if (\n ts.isCallExpression(node.expression) &&\n ts.isPropertyAccessExpression(node.expression.expression)\n ) {\n const propAccess = node.expression.expression;\n if (\n ts.isIdentifier(propAccess.expression) &&\n propAccess.expression.text === 'output'\n ) {\n let contentType = 'application/json';\n const callerMethod = propAccess.name.text;\n const [body, statusCode, headers] = node.expression.arguments;\n if (callerMethod === 'attachment') {\n contentType = 'application/octet-stream';\n }\n if (!body) {\n contentType = 'empty';\n }\n callback(body, statusCode, headers, contentType);\n }\n }\n }\n return ts.forEachChild(node, handlerVisitor(callback));\n };\n};\n\nfunction toResponses(handler: ts.ArrowFunction, deriver: TypeDeriver) {\n const responsesList: ResponseItem[] = [];\n const visit = handlerVisitor((node, statusCode, headers, contentType) => {\n responsesList.push({\n headers: headers ? Object.keys(deriver.serializeNode(headers)) : [],\n contentType,\n statusCode: statusCode ? resolveStatusCode(statusCode) : '200',\n response: node ? deriver.serializeNode(node) : undefined,\n });\n });\n visit(handler.body);\n return responsesList;\n}\n\nfunction resolveStatusCode(node: ts.Node) {\n if (ts.isNumericLiteral(node)) {\n return node.text;\n }\n throw new Error(`Could not resolve status code`);\n}\n\nexport function defaultResponseAnalyzer(\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n) {\n try {\n return toResponses(handler, deriver);\n } catch (error) {\n console.error('Error analyzing response\\n', handler.getText());\n throw error;\n }\n}\n\nexport const responseAnalyzer: NaunceResponseAnalyzer = {\n 'throw.new.ProblemDetailsException': (handler, deriver, node) => {\n if (ts.isNewExpression(node)) {\n const [problem] = node.arguments ?? [];\n if (!ts.isObjectLiteralExpression(problem)) {\n return [];\n }\n const properties = problem.properties.reduce<Record<string, string>>(\n (acc, prop) => {\n if (ts.isPropertyAssignment(prop)) {\n const key = prop.name.getText();\n if (ts.isLiteralExpression(prop.initializer)) {\n acc[key] = prop.initializer.text;\n } else {\n acc[key] = prop.initializer.getText();\n }\n }\n return acc;\n },\n {},\n );\n return [\n {\n contentType: 'application/problem+json',\n headers: [],\n statusCode: properties.status,\n response: problem ? deriver.serializeNode(problem) : undefined,\n },\n ];\n }\n return [];\n },\n default: defaultResponseAnalyzer,\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import debug from 'debug';\nimport type { ComponentsObject } from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\nimport ts from 'typescript';\n\nimport {\n type InjectImport,\n type NaunceResponseAnalyzer,\n type OnOperation,\n Paths,\n type ResponseAnalyzerFn,\n type ResponseItem,\n type Selector,\n type SemanticSource,\n TypeDeriver,\n getProgram,\n isCallExpression,\n isHttpMethod,\n toSchema,\n} from '@sdk-it/core';\n\nexport const returnToken = (node: ts.ArrowFunction) => {\n const tokens: { token: string; node: ts.Expression }[] = [];\n\n const visitor: ts.Visitor = (node) => {\n if (ts.isThrowStatement(node)) {\n if (ts.isNewExpression(node.expression)) {\n tokens.push({\n token: `throw.new.${node.expression.expression.getText()}`,\n node: node.expression,\n });\n }\n }\n\n if (ts.isReturnStatement(node) && node.expression) {\n if (ts.isCallExpression(node.expression)) {\n tokens.push({\n token: node.expression.expression.getText(),\n node: node.expression,\n });\n }\n return undefined;\n }\n\n return ts.forEachChild(node, visitor);\n };\n\n ts.forEachChild(node, visitor);\n return tokens;\n};\n\nconst logger = debug('@sdk-it/generic');\n\nconst jsDocsTags = ['openapi', 'tags', 'description'];\n\nfunction parseJSDocComment(node: ts.Node) {\n let tags: string[] = [];\n let name = '';\n let description = '';\n for (const tag of ts.getAllJSDocTags(node, (tag): tag is ts.JSDocTag =>\n jsDocsTags.includes(tag.tagName.text),\n )) {\n if (typeof tag.comment !== 'string') {\n continue;\n }\n switch (tag.tagName.text) {\n case 'openapi':\n name = tag.comment;\n break;\n case 'tags':\n tags = tag.comment.split(',').map((tag) => tag.trim());\n break;\n case 'description':\n description = tag.comment;\n break;\n }\n }\n return {\n name,\n tags,\n description,\n };\n}\n\nfunction visit(\n node: ts.Node,\n responseAnalyzer: (\n handler: ts.ArrowFunction,\n token: string,\n node: ts.Node,\n ) => ResponseItem[],\n paths: Paths,\n) {\n if (!ts.isCallExpression(node) || node.arguments.length < 2) {\n return moveOn();\n }\n if (\n !ts.isPropertyAccessExpression(node.expression) ||\n !ts.isIdentifier(node.expression.name) ||\n !isHttpMethod(node.expression.name.text)\n ) {\n return moveOn();\n }\n\n const [pathNode] = node.arguments;\n if (!ts.isStringLiteral(pathNode)) {\n return moveOn();\n }\n const method = node.expression.name.text;\n const path = pathNode.text;\n const validate = node.arguments.find((arg) =>\n isCallExpression(arg, 'validate'),\n );\n if (!validate) {\n return moveOn();\n }\n const handler = node.arguments.at(-1);\n if (!handler || !ts.isArrowFunction(handler)) {\n return moveOn();\n }\n\n const metadata = parseJSDocComment(node.parent);\n const operationName =\n metadata.name ||\n camelcase(`${method} ${path.replace(/[^a-zA-Z0-9]/g, '')}`);\n if (!validate.arguments.length) {\n return moveOn();\n }\n let selector: ts.Expression | undefined;\n let contentType: ts.Expression | undefined;\n if (validate.arguments.length === 2) {\n contentType = validate.arguments[0];\n selector = validate.arguments[1];\n } else {\n selector = validate.arguments[0];\n }\n if (!ts.isArrowFunction(selector)) {\n return moveOn();\n }\n if (\n !selector ||\n !ts.isParenthesizedExpression(selector.body) ||\n !ts.isObjectLiteralExpression(selector.body.expression)\n ) {\n return moveOn();\n }\n const props = selector.body.expression.properties.filter(\n ts.isPropertyAssignment,\n );\n\n const sourceFile = node.getSourceFile();\n const tokens = returnToken(handler);\n\n const responses: ResponseItem[] = [];\n for (const { token, node } of tokens) {\n responses.push(...responseAnalyzer(handler, token, node));\n }\n\n paths.addPath(\n operationName,\n path,\n method,\n contentType\n ? ts.isStringLiteral(contentType)\n ? contentType.text\n : undefined\n : undefined,\n toSelectors(props),\n responses,\n sourceFile.fileName,\n metadata.tags,\n metadata.description,\n );\n\n function moveOn() {\n ts.forEachChild(node, (node) => visit(node, responseAnalyzer, paths));\n }\n}\n\nfunction toSelectors(props: ts.PropertyAssignment[]) {\n const selectors: Selector[] = [];\n for (const prop of props) {\n if (!ts.isObjectLiteralExpression(prop.initializer)) {\n continue;\n }\n const name = prop.name.getText();\n const select = prop.initializer.properties\n .filter(ts.isPropertyAssignment)\n .find((prop) => prop.name.getText() === 'select');\n if (!select) {\n console.warn(`No select found in ${name}`);\n continue;\n }\n const against = prop.initializer.properties\n .filter(ts.isPropertyAssignment)\n .find((prop) => prop.name.getText() === 'against');\n if (!against) {\n console.warn(`No against found in ${name}`);\n continue;\n }\n const [, source, selectText] = select.initializer.getText().split('.');\n selectors.push({\n name,\n nullable: against.initializer.getText().includes('nullable'),\n required: !against.initializer.getText().includes('optional'),\n select: selectText,\n against: against.initializer.getText(),\n source: source as SemanticSource,\n });\n }\n return selectors;\n}\n\nexport async function analyze(\n tsconfigPath: string,\n config: {\n /**\n * Additional code to inject before resolving zod schemas\n */\n imports?: InjectImport[];\n typesMap?: Record<string, string>;\n responseAnalyzer: ResponseAnalyzerFn | NaunceResponseAnalyzer;\n onOperation?: OnOperation;\n },\n) {\n logger(`Parsing tsconfig`);\n const program = getProgram(tsconfigPath);\n logger(`Program created`);\n const typeChecker = program.getTypeChecker();\n\n logger(`Type checker created`);\n const typeDeriver = new TypeDeriver(typeChecker, config.typesMap);\n const paths = new Paths({\n imports: config.imports ?? [],\n onOperation: config.onOperation,\n });\n\n for (const sourceFile of program.getSourceFiles()) {\n logger(`Analyzing ${sourceFile.fileName}`);\n if (!sourceFile.isDeclarationFile) {\n logger(`Visiting ${sourceFile.fileName}`);\n visit(\n sourceFile,\n (handler, token, node) => {\n const responseAnalyzer = config.responseAnalyzer;\n if (typeof responseAnalyzer !== 'function') {\n const naunce =\n responseAnalyzer[token] || responseAnalyzer['default'];\n if (!naunce) {\n throw new Error(`No response analyzer for token ${token}`);\n }\n return naunce(handler, typeDeriver, node);\n }\n return responseAnalyzer(handler, typeDeriver);\n },\n paths,\n );\n }\n }\n\n const components: ComponentsObject = {\n schemas: Object.entries(typeDeriver.collector).reduce(\n (acc, [key, value]) => ({ ...acc, [key]: toSchema(value) }),\n {},\n ),\n };\n\n return {\n paths: await paths.getPaths(),\n tags: paths.getTags(),\n components,\n };\n}\n\nexport type Serialized = ReturnType<typeof analyze>;\n", "import ts from 'typescript';\n\nimport type {\n NaunceResponseAnalyzer,\n ResponseItem,\n TypeDeriver,\n} from '@sdk-it/core';\n\nconst handlerVisitor: (\n on: (\n node: ts.Node | undefined,\n statusCode: ts.Node | undefined,\n headers: ts.Node | undefined,\n contentType: string,\n ) => void,\n) => ts.Visitor = (callback) => {\n return (node: ts.Node) => {\n if (ts.isReturnStatement(node) && node.expression) {\n if (\n ts.isCallExpression(node.expression) &&\n ts.isPropertyAccessExpression(node.expression.expression)\n ) {\n const propAccess = node.expression.expression;\n if (\n ts.isIdentifier(propAccess.expression) &&\n propAccess.expression.text === 'output'\n ) {\n let contentType = 'application/json';\n const callerMethod = propAccess.name.text;\n const [body, statusCode, headers] = node.expression.arguments;\n if (callerMethod === 'attachment') {\n contentType = 'application/octet-stream';\n }\n if (!body) {\n contentType = 'empty';\n }\n callback(body, statusCode, headers, contentType);\n }\n }\n }\n return ts.forEachChild(node, handlerVisitor(callback));\n };\n};\n\nfunction toResponses(handler: ts.ArrowFunction, deriver: TypeDeriver) {\n const responsesList: ResponseItem[] = [];\n const visit = handlerVisitor((node, statusCode, headers, contentType) => {\n responsesList.push({\n headers: headers ? Object.keys(deriver.serializeNode(headers)) : [],\n contentType,\n statusCode: statusCode ? resolveStatusCode(statusCode) : '200',\n response: node ? deriver.serializeNode(node) : undefined,\n });\n });\n visit(handler.body);\n return responsesList;\n}\n\nfunction resolveStatusCode(node: ts.Node) {\n if (ts.isNumericLiteral(node)) {\n return node.text;\n }\n throw new Error(`Could not resolve status code`);\n}\n\nexport function defaultResponseAnalyzer(\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n) {\n try {\n return toResponses(handler, deriver);\n } catch (error) {\n console.error('Error analyzing response\\n', handler.getText());\n throw error;\n }\n}\n\nexport const responseAnalyzer: NaunceResponseAnalyzer = {\n 'throw.new.ProblemDetailsException': (handler, deriver, node) => {\n if (ts.isNewExpression(node)) {\n const [problem] = node.arguments ?? [];\n if (!ts.isObjectLiteralExpression(problem)) {\n return [];\n }\n const properties = problem.properties.reduce<Record<string, string>>(\n (acc, prop) => {\n if (ts.isPropertyAssignment(prop)) {\n const key = prop.name.getText();\n if (ts.isLiteralExpression(prop.initializer)) {\n acc[key] = prop.initializer.text;\n } else {\n acc[key] = prop.initializer.getText();\n }\n }\n return acc;\n },\n {},\n );\n return [\n {\n contentType: 'application/problem+json',\n headers: [],\n statusCode: properties.status,\n response: problem ? deriver.serializeNode(problem) : undefined,\n },\n ];\n }\n return [];\n },\n default: defaultResponseAnalyzer,\n};\n"],
5
+ "mappings": ";AAAA,OAAO,WAAW;AAElB,SAAS,iBAAiB;AAC1B,OAAO,QAAQ;AAEf;AAAA,EAIE;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,IAAM,cAAc,CAAC,SAA2B;AACrD,QAAM,SAAmD,CAAC;AAE1D,QAAM,UAAsB,CAACA,UAAS;AACpC,QAAI,GAAG,iBAAiBA,KAAI,GAAG;AAC7B,UAAI,GAAG,gBAAgBA,MAAK,UAAU,GAAG;AACvC,eAAO,KAAK;AAAA,UACV,OAAO,aAAaA,MAAK,WAAW,WAAW,QAAQ,CAAC;AAAA,UACxD,MAAMA,MAAK;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,GAAG,kBAAkBA,KAAI,KAAKA,MAAK,YAAY;AACjD,UAAI,GAAG,iBAAiBA,MAAK,UAAU,GAAG;AACxC,eAAO,KAAK;AAAA,UACV,OAAOA,MAAK,WAAW,WAAW,QAAQ;AAAA,UAC1C,MAAMA,MAAK;AAAA,QACb,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT;AAEA,WAAO,GAAG,aAAaA,OAAM,OAAO;AAAA,EACtC;AAEA,KAAG,aAAa,MAAM,OAAO;AAC7B,SAAO;AACT;AAEA,IAAM,SAAS,MAAM,iBAAiB;AAEtC,IAAM,aAAa,CAAC,WAAW,QAAQ,aAAa;AAEpD,SAAS,kBAAkB,MAAe;AACxC,MAAI,OAAiB,CAAC;AACtB,MAAI,OAAO;AACX,MAAI,cAAc;AAClB,aAAW,OAAO,GAAG;AAAA,IAAgB;AAAA,IAAM,CAACC,SAC1C,WAAW,SAASA,KAAI,QAAQ,IAAI;AAAA,EACtC,GAAG;AACD,QAAI,OAAO,IAAI,YAAY,UAAU;AACnC;AAAA,IACF;AACA,YAAQ,IAAI,QAAQ,MAAM;AAAA,MACxB,KAAK;AACH,eAAO,IAAI;AACX;AAAA,MACF,KAAK;AACH,eAAO,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,CAACA,SAAQA,KAAI,KAAK,CAAC;AACrD;AAAA,MACF,KAAK;AACH,sBAAc,IAAI;AAClB;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,MACP,MACAC,mBAKA,OACA;AACA,MAAI,CAAC,GAAG,iBAAiB,IAAI,KAAK,KAAK,UAAU,SAAS,GAAG;AAC3D,WAAO,OAAO;AAAA,EAChB;AACA,MACE,CAAC,GAAG,2BAA2B,KAAK,UAAU,KAC9C,CAAC,GAAG,aAAa,KAAK,WAAW,IAAI,KACrC,CAAC,aAAa,KAAK,WAAW,KAAK,IAAI,GACvC;AACA,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,CAAC,QAAQ,IAAI,KAAK;AACxB,MAAI,CAAC,GAAG,gBAAgB,QAAQ,GAAG;AACjC,WAAO,OAAO;AAAA,EAChB;AACA,QAAM,SAAS,KAAK,WAAW,KAAK;AACpC,QAAM,OAAO,SAAS;AACtB,QAAM,WAAW,KAAK,UAAU;AAAA,IAAK,CAAC,QACpC,iBAAiB,KAAK,UAAU;AAAA,EAClC;AACA,MAAI,CAAC,UAAU;AACb,WAAO,OAAO;AAAA,EAChB;AACA,QAAM,UAAU,KAAK,UAAU,GAAG,EAAE;AACpC,MAAI,CAAC,WAAW,CAAC,GAAG,gBAAgB,OAAO,GAAG;AAC5C,WAAO,OAAO;AAAA,EAChB;AAEA,QAAM,WAAW,kBAAkB,KAAK,MAAM;AAC9C,QAAM,gBACJ,SAAS,QACT,UAAU,GAAG,MAAM,IAAI,KAAK,QAAQ,iBAAiB,EAAE,CAAC,EAAE;AAC5D,MAAI,CAAC,SAAS,UAAU,QAAQ;AAC9B,WAAO,OAAO;AAAA,EAChB;AACA,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS,UAAU,WAAW,GAAG;AACnC,kBAAc,SAAS,UAAU,CAAC;AAClC,eAAW,SAAS,UAAU,CAAC;AAAA,EACjC,OAAO;AACL,eAAW,SAAS,UAAU,CAAC;AAAA,EACjC;AACA,MAAI,CAAC,GAAG,gBAAgB,QAAQ,GAAG;AACjC,WAAO,OAAO;AAAA,EAChB;AACA,MACE,CAAC,YACD,CAAC,GAAG,0BAA0B,SAAS,IAAI,KAC3C,CAAC,GAAG,0BAA0B,SAAS,KAAK,UAAU,GACtD;AACA,WAAO,OAAO;AAAA,EAChB;AACA,QAAM,QAAQ,SAAS,KAAK,WAAW,WAAW;AAAA,IAChD,GAAG;AAAA,EACL;AAEA,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,SAAS,YAAY,OAAO;AAElC,QAAM,YAA4B,CAAC;AACnC,aAAW,EAAE,OAAO,MAAAF,MAAK,KAAK,QAAQ;AACpC,cAAU,KAAK,GAAGE,kBAAiB,SAAS,OAAOF,KAAI,CAAC;AAAA,EAC1D;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,cACI,GAAG,gBAAgB,WAAW,IAC5B,YAAY,OACZ,SACF;AAAA,IACJ,YAAY,KAAK;AAAA,IACjB;AAAA,IACA,WAAW;AAAA,IACX,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAEA,WAAS,SAAS;AAChB,OAAG,aAAa,MAAM,CAACA,UAAS,MAAMA,OAAME,mBAAkB,KAAK,CAAC;AAAA,EACtE;AACF;AAEA,SAAS,YAAY,OAAgC;AACnD,QAAM,YAAwB,CAAC;AAC/B,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,GAAG,0BAA0B,KAAK,WAAW,GAAG;AACnD;AAAA,IACF;AACA,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,UAAM,SAAS,KAAK,YAAY,WAC7B,OAAO,GAAG,oBAAoB,EAC9B,KAAK,CAACC,UAASA,MAAK,KAAK,QAAQ,MAAM,QAAQ;AAClD,QAAI,CAAC,QAAQ;AACX,cAAQ,KAAK,sBAAsB,IAAI,EAAE;AACzC;AAAA,IACF;AACA,UAAM,UAAU,KAAK,YAAY,WAC9B,OAAO,GAAG,oBAAoB,EAC9B,KAAK,CAACA,UAASA,MAAK,KAAK,QAAQ,MAAM,SAAS;AACnD,QAAI,CAAC,SAAS;AACZ,cAAQ,KAAK,uBAAuB,IAAI,EAAE;AAC1C;AAAA,IACF;AACA,UAAM,CAAC,EAAE,QAAQ,UAAU,IAAI,OAAO,YAAY,QAAQ,EAAE,MAAM,GAAG;AACrE,cAAU,KAAK;AAAA,MACb;AAAA,MACA,UAAU,QAAQ,YAAY,QAAQ,EAAE,SAAS,UAAU;AAAA,MAC3D,UAAU,CAAC,QAAQ,YAAY,QAAQ,EAAE,SAAS,UAAU;AAAA,MAC5D,QAAQ;AAAA,MACR,SAAS,QAAQ,YAAY,QAAQ;AAAA,MACrC;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,eAAsB,QACpB,cACA,QASA;AACA,SAAO,kBAAkB;AACzB,QAAM,UAAU,WAAW,YAAY;AACvC,SAAO,iBAAiB;AACxB,QAAM,cAAc,QAAQ,eAAe;AAE3C,SAAO,sBAAsB;AAC7B,QAAM,cAAc,IAAI,YAAY,aAAa,OAAO,QAAQ;AAChE,QAAM,QAAQ,IAAI,MAAM;AAAA,IACtB,SAAS,OAAO,WAAW,CAAC;AAAA,IAC5B,aAAa,OAAO;AAAA,EACtB,CAAC;AAED,aAAW,cAAc,QAAQ,eAAe,GAAG;AACjD,WAAO,aAAa,WAAW,QAAQ,EAAE;AACzC,QAAI,CAAC,WAAW,mBAAmB;AACjC,aAAO,YAAY,WAAW,QAAQ,EAAE;AACxC;AAAA,QACE;AAAA,QACA,CAAC,SAAS,OAAO,SAAS;AACxB,gBAAMD,oBAAmB,OAAO;AAChC,cAAI,OAAOA,sBAAqB,YAAY;AAC1C,kBAAM,SACJA,kBAAiB,KAAK,KAAKA,kBAAiB,SAAS;AACvD,gBAAI,CAAC,QAAQ;AACX,oBAAM,IAAI,MAAM,kCAAkC,KAAK,EAAE;AAAA,YAC3D;AACA,mBAAO,OAAO,SAAS,aAAa,IAAI;AAAA,UAC1C;AACA,iBAAOA,kBAAiB,SAAS,WAAW;AAAA,QAC9C;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAA+B;AAAA,IACnC,SAAS,OAAO,QAAQ,YAAY,SAAS,EAAE;AAAA,MAC7C,CAAC,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,SAAS,KAAK,EAAE;AAAA,MACzD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,MAAM,MAAM,SAAS;AAAA,IAC5B,MAAM,MAAM,QAAQ;AAAA,IACpB;AAAA,EACF;AACF;;;AChRA,OAAOE,SAAQ;AAQf,IAAM,iBAOY,CAAC,aAAa;AAC9B,SAAO,CAAC,SAAkB;AACxB,QAAIA,IAAG,kBAAkB,IAAI,KAAK,KAAK,YAAY;AACjD,UACEA,IAAG,iBAAiB,KAAK,UAAU,KACnCA,IAAG,2BAA2B,KAAK,WAAW,UAAU,GACxD;AACA,cAAM,aAAa,KAAK,WAAW;AACnC,YACEA,IAAG,aAAa,WAAW,UAAU,KACrC,WAAW,WAAW,SAAS,UAC/B;AACA,cAAI,cAAc;AAClB,gBAAM,eAAe,WAAW,KAAK;AACrC,gBAAM,CAAC,MAAM,YAAY,OAAO,IAAI,KAAK,WAAW;AACpD,cAAI,iBAAiB,cAAc;AACjC,0BAAc;AAAA,UAChB;AACA,cAAI,CAAC,MAAM;AACT,0BAAc;AAAA,UAChB;AACA,mBAAS,MAAM,YAAY,SAAS,WAAW;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AACA,WAAOA,IAAG,aAAa,MAAM,eAAe,QAAQ,CAAC;AAAA,EACvD;AACF;AAEA,SAAS,YAAY,SAA2B,SAAsB;AACpE,QAAM,gBAAgC,CAAC;AACvC,QAAMC,SAAQ,eAAe,CAAC,MAAM,YAAY,SAAS,gBAAgB;AACvE,kBAAc,KAAK;AAAA,MACjB,SAAS,UAAU,OAAO,KAAK,QAAQ,cAAc,OAAO,CAAC,IAAI,CAAC;AAAA,MAClE;AAAA,MACA,YAAY,aAAa,kBAAkB,UAAU,IAAI;AAAA,MACzD,UAAU,OAAO,QAAQ,cAAc,IAAI,IAAI;AAAA,IACjD,CAAC;AAAA,EACH,CAAC;AACD,EAAAA,OAAM,QAAQ,IAAI;AAClB,SAAO;AACT;AAEA,SAAS,kBAAkB,MAAe;AACxC,MAAID,IAAG,iBAAiB,IAAI,GAAG;AAC7B,WAAO,KAAK;AAAA,EACd;AACA,QAAM,IAAI,MAAM,+BAA+B;AACjD;AAEO,SAAS,wBACd,SACA,SACA;AACA,MAAI;AACF,WAAO,YAAY,SAAS,OAAO;AAAA,EACrC,SAAS,OAAO;AACd,YAAQ,MAAM,8BAA8B,QAAQ,QAAQ,CAAC;AAC7D,UAAM;AAAA,EACR;AACF;AAEO,IAAM,mBAA2C;AAAA,EACtD,qCAAqC,CAAC,SAAS,SAAS,SAAS;AAC/D,QAAIA,IAAG,gBAAgB,IAAI,GAAG;AAC5B,YAAM,CAAC,OAAO,IAAI,KAAK,aAAa,CAAC;AACrC,UAAI,CAACA,IAAG,0BAA0B,OAAO,GAAG;AAC1C,eAAO,CAAC;AAAA,MACV;AACA,YAAM,aAAa,QAAQ,WAAW;AAAA,QACpC,CAAC,KAAK,SAAS;AACb,cAAIA,IAAG,qBAAqB,IAAI,GAAG;AACjC,kBAAM,MAAM,KAAK,KAAK,QAAQ;AAC9B,gBAAIA,IAAG,oBAAoB,KAAK,WAAW,GAAG;AAC5C,kBAAI,GAAG,IAAI,KAAK,YAAY;AAAA,YAC9B,OAAO;AACL,kBAAI,GAAG,IAAI,KAAK,YAAY,QAAQ;AAAA,YACtC;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,MACH;AACA,aAAO;AAAA,QACL;AAAA,UACE,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,YAAY,WAAW;AAAA,UACvB,UAAU,UAAU,QAAQ,cAAc,OAAO,IAAI;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AACA,WAAO,CAAC;AAAA,EACV;AAAA,EACA,SAAS;AACX;",
6
6
  "names": ["node", "tag", "responseAnalyzer", "prop", "ts", "visit"]
7
7
  }
@@ -15,6 +15,7 @@ export declare function analyze(tsconfigPath: string, config: {
15
15
  onOperation?: OnOperation;
16
16
  }): Promise<{
17
17
  paths: import("openapi3-ts/oas31").PathsObject;
18
+ tags: string[];
18
19
  components: ComponentsObject;
19
20
  }>;
20
21
  export type Serialized = ReturnType<typeof analyze>;
@@ -1 +1 @@
1
- {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/lib/generic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAEhB,KAAK,kBAAkB,EASxB,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,WAAW,GAAI,MAAM,EAAE,CAAC,aAAa;WACzB,MAAM;UAAQ,EAAE,CAAC,UAAU;GA2BnD,CAAC;AAoKF,wBAAsB,OAAO,CAC3B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE;IACN;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,gBAAgB,EAAE,kBAAkB,GAAG,sBAAsB,CAAC;IAC9D,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;;;GAgDF;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"generic.d.ts","sourceRoot":"","sources":["../../src/lib/generic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAEhB,KAAK,kBAAkB,EASxB,MAAM,cAAc,CAAC;AAEtB,eAAO,MAAM,WAAW,GAAI,MAAM,EAAE,CAAC,aAAa;WACzB,MAAM;UAAQ,EAAE,CAAC,UAAU;GA2BnD,CAAC;AAoKF,wBAAsB,OAAO,CAC3B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE;IACN;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,gBAAgB,EAAE,kBAAkB,GAAG,sBAAsB,CAAC;IAC9D,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;;;;GAiDF;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdk-it/generic",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "!**/*.tsbuildinfo"
22
22
  ],
23
23
  "dependencies": {
24
- "@sdk-it/core": "0.25.0",
24
+ "@sdk-it/core": "0.26.0",
25
25
  "stringcase": "^4.3.1",
26
26
  "debug": "^4.4.0",
27
27
  "openapi3-ts": "^4.4.0"