@sdk-it/core 0.30.0 → 0.31.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/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +4 -1
- package/dist/lib/paths.js.map +2 -2
- package/package.json +5 -4
- package/dist/lib/deriver.test.d.ts +0 -1
- package/dist/lib/deriver.test.d.ts.map +0 -1
- package/dist/lib/deriver.test.js +0 -382
- package/dist/lib/deriver.test.js.map +0 -7
- package/dist/lib/file-system.test.d.ts +0 -2
- package/dist/lib/file-system.test.d.ts.map +0 -1
- package/dist/lib/file-system.test.js +0 -357
- package/dist/lib/file-system.test.js.map +0 -7
- package/dist/lib/program.test.d.ts +0 -2
- package/dist/lib/program.test.d.ts.map +0 -1
- package/dist/lib/program.test.js +0 -289
- package/dist/lib/program.test.js.map +0 -7
package/dist/lib/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF,MAAM,MAAM,MAAM,GACd,KAAK,GACL,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,OAAO,GACP,MAAM,CAAC;AAEX,eAAO,MAAM,OAAO,qEAQV,CAAC;AACX,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAQd,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;CAChD;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,eAAe,KACvB,WAAW,CAAC;AACjB,qBAAa,KAAK;;gBAeJ,MAAM,EAAE;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE;IAK1E,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,WAAW,CAAC,EAAE,MAAM;IA2GtB,OAAO,IAAI,MAAM,EAAE;IAcb,QAAQ;CA+Df;
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EAEf,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF,MAAM,MAAM,MAAM,GACd,KAAK,GACL,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,OAAO,GACP,MAAM,CAAC;AAEX,eAAO,MAAM,OAAO,qEAQV,CAAC;AACX,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,SAAS,GACT,MAAM,GACN,QAAQ,GACR,SAAS,CAAC;AAQd,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;CAChD;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,eAAe,KACvB,WAAW,CAAC;AACjB,qBAAa,KAAK;;gBAeJ,MAAM,EAAE;QAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,WAAW,CAAA;KAAE;IAK1E,OAAO,CACL,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,YAAY,EAAE,EACzB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,EAAE,EACf,WAAW,CAAC,EAAE,MAAM;IA2GtB,OAAO,IAAI,MAAM,EAAE;IAcb,QAAQ;CA+Df;AA8BD,UAAU,QAAQ;IAChB,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,GAAG,CAyCxE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,MAAM,CAEzD"}
|
package/dist/lib/paths.js
CHANGED
|
@@ -192,7 +192,10 @@ async function evalZod(schema, imports = []) {
|
|
|
192
192
|
`export default jsonSchema;`
|
|
193
193
|
];
|
|
194
194
|
const base64 = Buffer.from(lines.join("\n")).toString("base64");
|
|
195
|
-
return import(
|
|
195
|
+
return import(
|
|
196
|
+
/* @vite-ignore */
|
|
197
|
+
`data:text/javascript;base64,${base64}`
|
|
198
|
+
).then((mod) => mod.default).then(({ $schema, ...result }) => result);
|
|
196
199
|
}
|
|
197
200
|
function toSchema(data) {
|
|
198
201
|
if (data === null || data === void 0) {
|
package/dist/lib/paths.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/paths.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n HeadersObject,\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from './deriver.js';\n\nexport type InjectImport = {\n import: string;\n from: string;\n};\nexport type Method =\n | 'get'\n | 'post'\n | 'put'\n | 'patch'\n | 'delete'\n | 'trace'\n | 'head';\n\nexport const methods = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'trace',\n 'head',\n] as const;\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n select: string;\n against: string;\n source: SemanticSource;\n nullable: boolean;\n required: boolean;\n}\n\nexport interface ResponseItem {\n statusCode: string;\n response?: DateType;\n contentType: string;\n headers: (string | Record<string, string[]>)[];\n}\n\nexport type OnOperation = (\n sourceFile: string,\n method: Method,\n path: string,\n operation: OperationObject,\n) => PathsObject;\nexport class Paths {\n #imports: InjectImport[] = [];\n #onOperation?: OnOperation;\n #operations: Array<{\n sourceFile: string;\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n contentType?: string;\n tags?: string[];\n description?: string;\n }> = [];\n\n constructor(config: { imports: InjectImport[]; onOperation?: OnOperation }) {\n this.#imports = config.imports;\n this.#onOperation = config.onOperation;\n }\n\n addPath(\n name: string,\n path: string,\n method: Method,\n contentType: string | undefined,\n selectors: Selector[],\n responses: ResponseItem[],\n sourceFile: string,\n tags?: string[],\n description?: string,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n\n this.#operations.push({\n name,\n path: this.#tunePath(path),\n sourceFile,\n contentType: contentType,\n method,\n selectors,\n responses: responsesObject,\n tags,\n description,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n const schema = item.response ? toSchema(item.response) : {};\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content:\n ct !== 'empty'\n ? {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n }\n : undefined,\n headers: item.headers.length\n ? item.headers.reduce<HeadersObject>((acc, current) => {\n const headers =\n typeof current === 'string' ? { [current]: [] } : current;\n return Object.entries(headers).reduce<HeadersObject>(\n (subAcc, [key, value]) => {\n const header: HeadersObject = {\n [key]: {\n schema: {\n type: 'string',\n enum: value.length ? value : undefined,\n },\n },\n };\n return { ...subAcc, ...header };\n },\n acc,\n );\n }, {})\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<\n string,\n { required: boolean; schema: SchemaObject }\n > = {};\n for (const selector of selectors) {\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = {\n required: selector.required,\n schema: await evalZod(selector.against, this.#imports),\n };\n continue;\n }\n\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: selector.required,\n schema: await evalZod(selector.against, this.#imports),\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n getTags(): string[] {\n const tags = new Set<string>();\n\n for (const operation of this.#operations) {\n if (operation.tags) {\n for (const tag of operation.tags) {\n tags.add(tag);\n }\n }\n }\n\n return Array.from(tags);\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n\n for (const operation of this.#operations) {\n const { path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const bodySchema: Record<string, SchemaObject> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(bodySchemaProps)) {\n if (value.required) {\n required.push(key);\n }\n bodySchema[key] = value.schema;\n }\n\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.tags,\n description: operation.description,\n requestBody: Object.keys(bodySchema).length\n ? {\n required: required.length ? true : false,\n content: {\n [operation.contentType || 'application/json']: {\n schema: {\n required: required.length ? required : undefined,\n type: 'object',\n properties: bodySchema,\n },\n },\n },\n }\n : undefined,\n responses:\n Object.keys(operation.responses).length === 0\n ? undefined\n : operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n if (this.#onOperation) {\n const paths = this.#onOperation?.(\n operation.sourceFile,\n method,\n path,\n operationObject,\n );\n Object.assign(operations, paths ?? {});\n }\n }\n return operations;\n }\n\n /**\n * Converts Express/Node.js style path parameters (/path/:param) to OpenAPI style (/path/{param})\n */\n #tunePath(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}');\n }\n}\n\nasync function evalZod(schema: string, imports: InjectImport[] = []) {\n // https://github.com/nodejs/node/issues/51956\n const lines = [\n `import { createRequire } from \"node:module\";`,\n `const filename = \"${import.meta.url}\";`,\n `const require = createRequire(filename);`,\n `const z = require(\"zod\");`,\n ...imports.map((imp) => `const ${imp.import} = require('${imp.from}');`),\n `const {zodToJsonSchema} = require('zod-to-json-schema');`,\n `const schema = ${schema.replace('.optional()', '').replaceAll('instanceof(File)', 'string().base64()')};`,\n `const jsonSchema = zodToJsonSchema(schema, {\n $refStrategy: 'root',\n basePath: ['#', 'components', 'schemas'],\n target: 'jsonSchema7',\n base64Strategy: 'format:binary',\n });`,\n `export default jsonSchema;`,\n ];\n\n const base64 = Buffer.from(lines.join('\\n')).toString('base64');\n /* @vite-ignore */\n return import(`data:text/javascript;base64,${base64}`)\n .then((mod) => mod.default)\n .then(({ $schema, ...result }) => result);\n}\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n value?: string;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return { type: data };\n } else if (data.kind === 'literal') {\n return { enum: [data.value], type: data[$types][0] };\n } else if (data.kind === 'record') {\n return {\n type: 'object',\n additionalProperties: toSchema(data[$types][0]),\n };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { anyOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(data)) {\n props[key] = toSchema(value as any);\n if (!(value as any).optional) {\n required.push(key);\n }\n }\n return {\n type: 'object',\n properties: props,\n required,\n additionalProperties: false,\n };\n }\n}\n\nexport function isHttpMethod(name: string): name is Method {\n return ['get', 'post', 'put', 'delete', 'patch'].includes(name);\n}\n"],
|
|
5
|
-
"mappings": "AAUA,SAAS,cAAc;AAehB,MAAM,UAAU;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQA,MAAM,0BAA0B;AAAA,EAC9B,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AACV;AAuBO,MAAM,MAAM;AAAA,EACjB,WAA2B,CAAC;AAAA,EAC5B;AAAA,EACA,cAUK,CAAC;AAAA,EAEN,YAAY,QAAgE;AAC1E,SAAK,WAAW,OAAO;AACvB,SAAK,eAAe,OAAO;AAAA,EAC7B;AAAA,EAEA,QACE,MACA,MACA,QACA,aACA,WACA,WACA,YACA,MACA,aACA;AACA,UAAM,kBAAkB,KAAK,yBAAyB,SAAS;AAE/D,SAAK,YAAY,KAAK;AAAA,MACpB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,yBAAyB,WAA4C;AACnE,UAAM,kBAAmC,CAAC;AAC1C,eAAW,QAAQ,WAAW;AAC5B,YAAM,KAAK,KAAK;AAChB,YAAM,SAAS,KAAK,WAAW,SAAS,KAAK,QAAQ,IAAI,CAAC;AAC1D,UAAI,CAAC,gBAAgB,KAAK,UAAU,GAAG;AACrC,wBAAgB,KAAK,UAAU,IAAI;AAAA,UACjC,aAAa,gBAAgB,KAAK,UAAU;AAAA,UAC5C,SACE,OAAO,UACH;AAAA,YACE,CAAC,EAAE,GACD,OAAO,6BACH,EAAE,QAAQ,EAAE,MAAM,UAAU,QAAQ,SAAS,EAAE,IAC/C,EAAE,OAAO;AAAA,UACjB,IACA;AAAA,UACN,SAAS,KAAK,QAAQ,SAClB,KAAK,QAAQ,OAAsB,CAAC,KAAK,YAAY;AACnD,kBAAM,UACJ,OAAO,YAAY,WAAW,EAAE,CAAC,OAAO,GAAG,CAAC,EAAE,IAAI;AACpD,mBAAO,OAAO,QAAQ,OAAO,EAAE;AAAA,cAC7B,CAAC,QAAQ,CAAC,KAAK,KAAK,MAAM;AACxB,sBAAM,SAAwB;AAAA,kBAC5B,CAAC,GAAG,GAAG;AAAA,oBACL,QAAQ;AAAA,sBACN,MAAM;AAAA,sBACN,MAAM,MAAM,SAAS,QAAQ;AAAA,oBAC/B;AAAA,kBACF;AAAA,gBACF;AACA,uBAAO,EAAE,GAAG,QAAQ,GAAG,OAAO;AAAA,cAChC;AAAA,cACA;AAAA,YACF;AAAA,UACF,GAAG,CAAC,CAAC,IACL;AAAA,QACN;AAAA,MACF,OAAO;AACL,YAAI,CAAC,gBAAgB,KAAK,UAAU,EAAE,QAAQ,EAAE,GAAG;AACjD,0BAAgB,KAAK,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO;AAAA,QAC1D,OAAO;AACL,gBAAM,WAAW,gBAAgB,KAAK,UAAU,EAAE,QAAQ,EAAE,EACzD;AACH,cAAI,SAAS,OAAO;AAClB,gBACE,CAAC,SAAS,MAAM;AAAA,cACd,CAAC,OAAO,KAAK,UAAU,EAAE,MAAM,KAAK,UAAU,MAAM;AAAA,YACtD,GACA;AACA,uBAAS,MAAM,KAAK,MAAM;AAAA,YAC5B;AAAA,UACF,WAAW,KAAK,UAAU,QAAQ,MAAM,KAAK,UAAU,MAAM,GAAG;AAC9D,4BAAgB,KAAK,UAAU,EAAE,QAAQ,EAAE,EAAE,SAAS;AAAA,cACpD,OAAO,CAAC,UAAU,MAAM;AAAA,YAC1B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,sBAAsB,WAAuB;AACjD,UAAM,aAAgC,CAAC;AACvC,UAAM,kBAGF,CAAC;AACL,eAAW,YAAY,WAAW;AAChC,UAAI,SAAS,WAAW,QAAQ;AAC9B,wBAAgB,SAAS,IAAI,IAAI;AAAA,UAC/B,UAAU,SAAS;AAAA,UACnB,QAAQ,MAAM,QAAQ,SAAS,SAAS,KAAK,QAAQ;AAAA,QACvD;AACA;AAAA,MACF;AAEA,YAAM,YAA6B;AAAA,QACjC,IAAI,wBAAwB,SAAS,MAAM;AAAA,QAC3C,MAAM,SAAS;AAAA,QACf,UAAU,SAAS;AAAA,QACnB,QAAQ,MAAM,QAAQ,SAAS,SAAS,KAAK,QAAQ;AAAA,MACvD;AACA,iBAAW,KAAK,SAAS;AAAA,IAC3B;AACA,WAAO,EAAE,YAAY,gBAAgB;AAAA,EACvC;AAAA,EAEA,UAAoB;AAClB,UAAM,OAAO,oBAAI,IAAY;AAE7B,eAAW,aAAa,KAAK,aAAa;AACxC,UAAI,UAAU,MAAM;AAClB,mBAAW,OAAO,UAAU,MAAM;AAChC,eAAK,IAAI,GAAG;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,MAAM,WAAW;AACf,UAAM,aAA0B,CAAC;AAEjC,eAAW,aAAa,KAAK,aAAa;AACxC,YAAM,EAAE,MAAM,QAAQ,UAAU,IAAI;AACpC,YAAM,EAAE,YAAY,gBAAgB,IAClC,MAAM,KAAK,sBAAsB,SAAS;AAC5C,YAAM,aAA2C,CAAC;AAClD,YAAM,WAAqB,CAAC;AAC5B,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,eAAe,GAAG;AAC1D,YAAI,MAAM,UAAU;AAClB,mBAAS,KAAK,GAAG;AAAA,QACnB;AACA,mBAAW,GAAG,IAAI,MAAM;AAAA,MAC1B;AAEA,YAAM,kBAAmC;AAAA,QACvC,aAAa,UAAU;AAAA,QACvB;AAAA,QACA,MAAM,UAAU;AAAA,QAChB,aAAa,UAAU;AAAA,QACvB,aAAa,OAAO,KAAK,UAAU,EAAE,SACjC;AAAA,UACE,UAAU,SAAS,SAAS,OAAO;AAAA,UACnC,SAAS;AAAA,YACP,CAAC,UAAU,eAAe,kBAAkB,GAAG;AAAA,cAC7C,QAAQ;AAAA,gBACN,UAAU,SAAS,SAAS,WAAW;AAAA,gBACvC,MAAM;AAAA,gBACN,YAAY;AAAA,cACd;AAAA,YACF;AAAA,UACF;AAAA,QACF,IACA;AAAA,QACJ,WACE,OAAO,KAAK,UAAU,SAAS,EAAE,WAAW,IACxC,SACA,UAAU;AAAA,MAClB;AACA,UAAI,CAAC,WAAW,IAAI,GAAG;AACrB,mBAAW,IAAI,IAAI,CAAC;AAAA,MACtB;AACA,iBAAW,IAAI,EAAE,MAAM,IAAI;AAC3B,UAAI,KAAK,cAAc;AACrB,cAAM,QAAQ,KAAK;AAAA,UACjB,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,eAAO,OAAO,YAAY,SAAS,CAAC,CAAC;AAAA,MACvC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,MAAsB;AAC9B,WAAO,KAAK,QAAQ,aAAa,MAAM;AAAA,EACzC;AACF;AAEA,eAAe,QAAQ,QAAgB,UAA0B,CAAC,GAAG;AAEnE,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,qBAAqB,YAAY,GAAG;AAAA,IACpC;AAAA,IACA;AAAA,IACA,GAAG,QAAQ,IAAI,CAAC,QAAQ,SAAS,IAAI,MAAM,eAAe,IAAI,IAAI,KAAK;AAAA,IACvE;AAAA,IACA,kBAAkB,OAAO,QAAQ,eAAe,EAAE,EAAE,WAAW,oBAAoB,mBAAmB,CAAC;AAAA,IACvG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMA;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,KAAK,MAAM,KAAK,IAAI,CAAC,EAAE,SAAS,QAAQ;
|
|
4
|
+
"sourcesContent": ["import type {\n HeadersObject,\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from './deriver.js';\n\nexport type InjectImport = {\n import: string;\n from: string;\n};\nexport type Method =\n | 'get'\n | 'post'\n | 'put'\n | 'patch'\n | 'delete'\n | 'trace'\n | 'head';\n\nexport const methods = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'trace',\n 'head',\n] as const;\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n select: string;\n against: string;\n source: SemanticSource;\n nullable: boolean;\n required: boolean;\n}\n\nexport interface ResponseItem {\n statusCode: string;\n response?: DateType;\n contentType: string;\n headers: (string | Record<string, string[]>)[];\n}\n\nexport type OnOperation = (\n sourceFile: string,\n method: Method,\n path: string,\n operation: OperationObject,\n) => PathsObject;\nexport class Paths {\n #imports: InjectImport[] = [];\n #onOperation?: OnOperation;\n #operations: Array<{\n sourceFile: string;\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n contentType?: string;\n tags?: string[];\n description?: string;\n }> = [];\n\n constructor(config: { imports: InjectImport[]; onOperation?: OnOperation }) {\n this.#imports = config.imports;\n this.#onOperation = config.onOperation;\n }\n\n addPath(\n name: string,\n path: string,\n method: Method,\n contentType: string | undefined,\n selectors: Selector[],\n responses: ResponseItem[],\n sourceFile: string,\n tags?: string[],\n description?: string,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n\n this.#operations.push({\n name,\n path: this.#tunePath(path),\n sourceFile,\n contentType: contentType,\n method,\n selectors,\n responses: responsesObject,\n tags,\n description,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n const schema = item.response ? toSchema(item.response) : {};\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content:\n ct !== 'empty'\n ? {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n }\n : undefined,\n headers: item.headers.length\n ? item.headers.reduce<HeadersObject>((acc, current) => {\n const headers =\n typeof current === 'string' ? { [current]: [] } : current;\n return Object.entries(headers).reduce<HeadersObject>(\n (subAcc, [key, value]) => {\n const header: HeadersObject = {\n [key]: {\n schema: {\n type: 'string',\n enum: value.length ? value : undefined,\n },\n },\n };\n return { ...subAcc, ...header };\n },\n acc,\n );\n }, {})\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<\n string,\n { required: boolean; schema: SchemaObject }\n > = {};\n for (const selector of selectors) {\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = {\n required: selector.required,\n schema: await evalZod(selector.against, this.#imports),\n };\n continue;\n }\n\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: selector.required,\n schema: await evalZod(selector.against, this.#imports),\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n getTags(): string[] {\n const tags = new Set<string>();\n\n for (const operation of this.#operations) {\n if (operation.tags) {\n for (const tag of operation.tags) {\n tags.add(tag);\n }\n }\n }\n\n return Array.from(tags);\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n\n for (const operation of this.#operations) {\n const { path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const bodySchema: Record<string, SchemaObject> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(bodySchemaProps)) {\n if (value.required) {\n required.push(key);\n }\n bodySchema[key] = value.schema;\n }\n\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.tags,\n description: operation.description,\n requestBody: Object.keys(bodySchema).length\n ? {\n required: required.length ? true : false,\n content: {\n [operation.contentType || 'application/json']: {\n schema: {\n required: required.length ? required : undefined,\n type: 'object',\n properties: bodySchema,\n },\n },\n },\n }\n : undefined,\n responses:\n Object.keys(operation.responses).length === 0\n ? undefined\n : operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n if (this.#onOperation) {\n const paths = this.#onOperation?.(\n operation.sourceFile,\n method,\n path,\n operationObject,\n );\n Object.assign(operations, paths ?? {});\n }\n }\n return operations;\n }\n\n /**\n * Converts Express/Node.js style path parameters (/path/:param) to OpenAPI style (/path/{param})\n */\n #tunePath(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}');\n }\n}\n\nasync function evalZod(schema: string, imports: InjectImport[] = []) {\n // https://github.com/nodejs/node/issues/51956\n const lines = [\n `import { createRequire } from \"node:module\";`,\n `const filename = \"${import.meta.url}\";`,\n `const require = createRequire(filename);`,\n `const z = require(\"zod\");`,\n ...imports.map((imp) => `const ${imp.import} = require('${imp.from}');`),\n `const {zodToJsonSchema} = require('zod-to-json-schema');`,\n `const schema = ${schema.replace('.optional()', '').replaceAll('instanceof(File)', 'string().base64()')};`,\n `const jsonSchema = zodToJsonSchema(schema, {\n $refStrategy: 'root',\n basePath: ['#', 'components', 'schemas'],\n target: 'jsonSchema7',\n base64Strategy: 'format:binary',\n });`,\n `export default jsonSchema;`,\n ];\n\n const base64 = Buffer.from(lines.join('\\n')).toString('base64');\n return import(\n /* @vite-ignore */\n `data:text/javascript;base64,${base64}`\n )\n .then((mod) => mod.default)\n .then(({ $schema, ...result }) => result);\n}\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n value?: string;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return { type: data };\n } else if (data.kind === 'literal') {\n return { enum: [data.value], type: data[$types][0] };\n } else if (data.kind === 'record') {\n return {\n type: 'object',\n additionalProperties: toSchema(data[$types][0]),\n };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { anyOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(data)) {\n props[key] = toSchema(value as any);\n if (!(value as any).optional) {\n required.push(key);\n }\n }\n return {\n type: 'object',\n properties: props,\n required,\n additionalProperties: false,\n };\n }\n}\n\nexport function isHttpMethod(name: string): name is Method {\n return ['get', 'post', 'put', 'delete', 'patch'].includes(name);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdk-it/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -23,18 +23,19 @@
|
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"dist",
|
|
26
|
-
"!**/*.tsbuildinfo"
|
|
26
|
+
"!**/*.tsbuildinfo",
|
|
27
|
+
"!**/*.test.*"
|
|
27
28
|
],
|
|
28
29
|
"dependencies": {
|
|
29
30
|
"debug": "^4.4.0",
|
|
30
31
|
"stringcase": "^4.3.1",
|
|
31
32
|
"lodash-es": "^4.17.21",
|
|
32
|
-
"zod-to-json-schema": "^3.24.
|
|
33
|
+
"zod-to-json-schema": "^3.24.6"
|
|
33
34
|
},
|
|
34
35
|
"peerDependencies": {
|
|
35
36
|
"typescript": "^5.8.3",
|
|
36
37
|
"openapi3-ts": "^4.4.0",
|
|
37
|
-
"zod": "^3.
|
|
38
|
+
"zod": "^3.25.76 || ^4.0.0"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@types/debug": "^4.1.12"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=deriver.test.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deriver.test.d.ts","sourceRoot":"","sources":["../../src/lib/deriver.test.ts"],"names":[],"mappings":""}
|
package/dist/lib/deriver.test.js
DELETED
|
@@ -1,382 +0,0 @@
|
|
|
1
|
-
import { describe, it } from "node:test";
|
|
2
|
-
describe("serializeType: Basic Primitive and Special Types", () => {
|
|
3
|
-
it.todo("serializes `any` type to an empty type list", () => {
|
|
4
|
-
});
|
|
5
|
-
it.todo("serializes `unknown` type to an empty type list", () => {
|
|
6
|
-
});
|
|
7
|
-
it.todo("serializes `string` type", () => {
|
|
8
|
-
});
|
|
9
|
-
it.todo("serializes `number` type", () => {
|
|
10
|
-
});
|
|
11
|
-
it.todo("serializes `boolean` type", () => {
|
|
12
|
-
});
|
|
13
|
-
it.todo("serializes `null` type as optional", () => {
|
|
14
|
-
});
|
|
15
|
-
it.todo(
|
|
16
|
-
"serializes `void` type (likely falls back to Any/Unknown or unhandled)",
|
|
17
|
-
() => {
|
|
18
|
-
}
|
|
19
|
-
);
|
|
20
|
-
it.todo(
|
|
21
|
-
"serializes `never` type (likely falls back to Any/Unknown or unhandled)",
|
|
22
|
-
() => {
|
|
23
|
-
}
|
|
24
|
-
);
|
|
25
|
-
it.todo(
|
|
26
|
-
"serializes `undefined` type implicitly via union/intersection optional flag",
|
|
27
|
-
() => {
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
describe("serializeType: Literal Types", () => {
|
|
32
|
-
it.todo("serializes string literal types with their value", () => {
|
|
33
|
-
});
|
|
34
|
-
it.todo("serializes numeric literal types with their value", () => {
|
|
35
|
-
});
|
|
36
|
-
it.todo("serializes boolean literal `true` type", () => {
|
|
37
|
-
});
|
|
38
|
-
it.todo("serializes boolean literal `false` type", () => {
|
|
39
|
-
});
|
|
40
|
-
it.todo("serializes template literal types as base `string`", () => {
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
describe("serializeType: Enum Types", () => {
|
|
44
|
-
it.todo(
|
|
45
|
-
"serializes an Enum type (e.g., `enum Color {}`) potentially via unhandled path",
|
|
46
|
-
() => {
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
it.todo(
|
|
50
|
-
"serializes an EnumLiteral type (e.g., `Color.Red`) potentially via unhandled path or base type",
|
|
51
|
-
() => {
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
describe("serializeType: Union Types (`|`)", () => {
|
|
56
|
-
it.todo(
|
|
57
|
-
"serializes a union of primitive types (e.g., string | number)",
|
|
58
|
-
() => {
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
it.todo(
|
|
62
|
-
"serializes a union type including `null` (e.g., string | null)",
|
|
63
|
-
() => {
|
|
64
|
-
}
|
|
65
|
-
);
|
|
66
|
-
it.todo(
|
|
67
|
-
"serializes a union type including `undefined`, setting optional flag and filtering `undefined`",
|
|
68
|
-
() => {
|
|
69
|
-
}
|
|
70
|
-
);
|
|
71
|
-
it.todo(
|
|
72
|
-
"serializes a union type including both `null` and `undefined`",
|
|
73
|
-
() => {
|
|
74
|
-
}
|
|
75
|
-
);
|
|
76
|
-
it.todo('serializes a union of literal types (e.g., "a" | "b" | 1)', () => {
|
|
77
|
-
});
|
|
78
|
-
it.todo(
|
|
79
|
-
"serializes a union including complex types (e.g., string | MyInterface)",
|
|
80
|
-
() => {
|
|
81
|
-
}
|
|
82
|
-
);
|
|
83
|
-
it.todo("serializes a union containing only `undefined`", () => {
|
|
84
|
-
});
|
|
85
|
-
it.todo("serializes a union containing only `null`", () => {
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
describe("serializeType: Intersection Types (`&`)", () => {
|
|
89
|
-
it.todo(
|
|
90
|
-
"serializes an intersection of object/interface types (e.g., A & B)",
|
|
91
|
-
() => {
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
it.todo(
|
|
95
|
-
"serializes an intersection type including `undefined`, setting optional flag and filtering `undefined`",
|
|
96
|
-
() => {
|
|
97
|
-
}
|
|
98
|
-
);
|
|
99
|
-
it.todo("serializes an intersection containing only `undefined`", () => {
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
describe("serializeType: Array and Tuple Types", () => {
|
|
103
|
-
it.todo("serializes a simple array type (e.g., string[])", () => {
|
|
104
|
-
});
|
|
105
|
-
it.todo("serializes readonly array types (e.g., readonly number[])", () => {
|
|
106
|
-
});
|
|
107
|
-
it.todo(
|
|
108
|
-
"serializes an array type with object elements (e.g., MyInterface[])",
|
|
109
|
-
() => {
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
it.todo(
|
|
113
|
-
"serializes an array type with union elements (e.g., (string | number)[])",
|
|
114
|
-
() => {
|
|
115
|
-
}
|
|
116
|
-
);
|
|
117
|
-
it.todo("serializes an array type where element type has no symbol", () => {
|
|
118
|
-
});
|
|
119
|
-
it.todo(
|
|
120
|
-
"serializes an array type where element symbol has no value declaration but has declarations",
|
|
121
|
-
() => {
|
|
122
|
-
}
|
|
123
|
-
);
|
|
124
|
-
it.todo(
|
|
125
|
-
"serializes an array type with a mapped type element (e.g., MappedType[])",
|
|
126
|
-
() => {
|
|
127
|
-
}
|
|
128
|
-
);
|
|
129
|
-
it.todo(
|
|
130
|
-
"handles array-like types with missing type arguments gracefully (e.g., Array)",
|
|
131
|
-
() => {
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
it.todo(
|
|
135
|
-
"serializes tuple types (e.g., [string, number]) potentially as array of union",
|
|
136
|
-
() => {
|
|
137
|
-
}
|
|
138
|
-
);
|
|
139
|
-
});
|
|
140
|
-
describe("serializeType: Record/Index Types", () => {
|
|
141
|
-
it.todo(
|
|
142
|
-
"serializes a string index signature type (Record<string, number>)",
|
|
143
|
-
() => {
|
|
144
|
-
}
|
|
145
|
-
);
|
|
146
|
-
it.todo(
|
|
147
|
-
"serializes a string index signature type with complex value (Record<string, MyInterface>)",
|
|
148
|
-
() => {
|
|
149
|
-
}
|
|
150
|
-
);
|
|
151
|
-
it.todo(
|
|
152
|
-
"serializes a type with only a number index signature ([key: number]: boolean)",
|
|
153
|
-
() => {
|
|
154
|
-
}
|
|
155
|
-
);
|
|
156
|
-
});
|
|
157
|
-
describe("serializeType: Object Types (Interfaces, Classes, Inline, Mapped)", () => {
|
|
158
|
-
it.todo("serializes an inline object type literal (passed as type)", () => {
|
|
159
|
-
});
|
|
160
|
-
it.todo(
|
|
161
|
-
"serializes a mapped type directly (e.g., type M = { [K in keyof T]: T[K] })",
|
|
162
|
-
() => {
|
|
163
|
-
}
|
|
164
|
-
);
|
|
165
|
-
it.todo(
|
|
166
|
-
"serializes an object type using literal property assignments from declarations",
|
|
167
|
-
() => {
|
|
168
|
-
}
|
|
169
|
-
);
|
|
170
|
-
it.todo(
|
|
171
|
-
"serializes an object type with mixed declared types (PropertySignature) and literal assignments (PropertyAssignment)",
|
|
172
|
-
() => {
|
|
173
|
-
}
|
|
174
|
-
);
|
|
175
|
-
it.todo(
|
|
176
|
-
"serializes an empty object type `{}` potentially falling back to name or generic",
|
|
177
|
-
() => {
|
|
178
|
-
}
|
|
179
|
-
);
|
|
180
|
-
it.todo(
|
|
181
|
-
"handles object types matching default overrides (e.g., DateConstructor -> string)",
|
|
182
|
-
() => {
|
|
183
|
-
}
|
|
184
|
-
);
|
|
185
|
-
it.todo(
|
|
186
|
-
"handles known object types NOT in defaults (e.g., RegExp) by attempting standard object serialization",
|
|
187
|
-
() => {
|
|
188
|
-
}
|
|
189
|
-
);
|
|
190
|
-
it.todo(
|
|
191
|
-
"serializes an interface type by deferring to serializeNode for reference/collection",
|
|
192
|
-
() => {
|
|
193
|
-
}
|
|
194
|
-
);
|
|
195
|
-
it.todo(
|
|
196
|
-
"serializes a class type by deferring to serializeNode for reference/collection",
|
|
197
|
-
() => {
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
it.todo(
|
|
201
|
-
"serializes an interface type using its name when its declaration cannot be found",
|
|
202
|
-
() => {
|
|
203
|
-
}
|
|
204
|
-
);
|
|
205
|
-
it.todo(
|
|
206
|
-
"serializes a class type using its name when its declaration cannot be found",
|
|
207
|
-
() => {
|
|
208
|
-
}
|
|
209
|
-
);
|
|
210
|
-
});
|
|
211
|
-
describe("serializeType: Unhandled Types", () => {
|
|
212
|
-
it.todo(
|
|
213
|
-
"handles an unhandled type flag by using checker.typeToString and warns",
|
|
214
|
-
() => {
|
|
215
|
-
}
|
|
216
|
-
);
|
|
217
|
-
});
|
|
218
|
-
describe("serializeNode: Object Literal Expressions (`{ ... }`)", () => {
|
|
219
|
-
it.todo(
|
|
220
|
-
"serializes an object literal node with various primitive property types",
|
|
221
|
-
() => {
|
|
222
|
-
}
|
|
223
|
-
);
|
|
224
|
-
it.todo(
|
|
225
|
-
"serializes an object literal node with nested object/array literals",
|
|
226
|
-
() => {
|
|
227
|
-
}
|
|
228
|
-
);
|
|
229
|
-
it.todo("serializes an empty object literal node `{}`", () => {
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
describe("serializeNode: Property Access/Signature/Declaration", () => {
|
|
233
|
-
it.todo(
|
|
234
|
-
"serializes a PropertyAccessExpression node (e.g., `obj.prop`) by resolving its type",
|
|
235
|
-
() => {
|
|
236
|
-
}
|
|
237
|
-
);
|
|
238
|
-
it.todo(
|
|
239
|
-
"serializes a PropertySignature node (e.g., `prop: string;`) by resolving its type",
|
|
240
|
-
() => {
|
|
241
|
-
}
|
|
242
|
-
);
|
|
243
|
-
it.todo(
|
|
244
|
-
"serializes a PropertyDeclaration node (e.g., `prop: number;`) by resolving its type",
|
|
245
|
-
() => {
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
it.todo(
|
|
249
|
-
"handles property nodes where symbol cannot be found for the property name and warns",
|
|
250
|
-
() => {
|
|
251
|
-
}
|
|
252
|
-
);
|
|
253
|
-
});
|
|
254
|
-
describe("serializeNode: Interface Declarations (`interface ...`) and Collector Interaction", () => {
|
|
255
|
-
it.todo(
|
|
256
|
-
"serializes a new interface declaration, adding its structure to the collector",
|
|
257
|
-
() => {
|
|
258
|
-
}
|
|
259
|
-
);
|
|
260
|
-
it.todo(
|
|
261
|
-
"returns only a reference for an already serialized interface declaration (present in collector)",
|
|
262
|
-
() => {
|
|
263
|
-
}
|
|
264
|
-
);
|
|
265
|
-
it.todo(
|
|
266
|
-
"handles interface declarations matching default overrides without adding to collector",
|
|
267
|
-
() => {
|
|
268
|
-
}
|
|
269
|
-
);
|
|
270
|
-
it.todo("throws an error for an interface declaration without a name", () => {
|
|
271
|
-
});
|
|
272
|
-
it.todo(
|
|
273
|
-
"handles interfaces with no members correctly (adds empty object to collector)",
|
|
274
|
-
() => {
|
|
275
|
-
}
|
|
276
|
-
);
|
|
277
|
-
it.todo(
|
|
278
|
-
"handles interfaces extending other interfaces (serialization includes only own properties)",
|
|
279
|
-
() => {
|
|
280
|
-
}
|
|
281
|
-
);
|
|
282
|
-
});
|
|
283
|
-
describe("serializeNode: Class Declarations (`class ...`) and Collector Interaction", () => {
|
|
284
|
-
it.todo(
|
|
285
|
-
"serializes a new class declaration, adding its property structure to the collector",
|
|
286
|
-
() => {
|
|
287
|
-
}
|
|
288
|
-
);
|
|
289
|
-
it.todo(
|
|
290
|
-
"returns only a reference for an already serialized class declaration (present in collector)",
|
|
291
|
-
() => {
|
|
292
|
-
}
|
|
293
|
-
);
|
|
294
|
-
it.todo(
|
|
295
|
-
"handles class declarations matching default overrides without adding to collector",
|
|
296
|
-
() => {
|
|
297
|
-
}
|
|
298
|
-
);
|
|
299
|
-
it.todo(
|
|
300
|
-
"throws an error for a class declaration without a name (e.g., anonymous default export)",
|
|
301
|
-
() => {
|
|
302
|
-
}
|
|
303
|
-
);
|
|
304
|
-
it.todo(
|
|
305
|
-
"handles classes with no property declarations (only methods/constructor) correctly (adds empty object to collector)",
|
|
306
|
-
() => {
|
|
307
|
-
}
|
|
308
|
-
);
|
|
309
|
-
it.todo(
|
|
310
|
-
"handles classes implementing interfaces (serialization includes only own properties)",
|
|
311
|
-
() => {
|
|
312
|
-
}
|
|
313
|
-
);
|
|
314
|
-
it.todo(
|
|
315
|
-
"handles classes extending other classes (serialization includes only own properties)",
|
|
316
|
-
() => {
|
|
317
|
-
}
|
|
318
|
-
);
|
|
319
|
-
});
|
|
320
|
-
describe("serializeNode: Other Node Types", () => {
|
|
321
|
-
it.todo(
|
|
322
|
-
"serializes a VariableDeclaration node with an explicit type annotation",
|
|
323
|
-
() => {
|
|
324
|
-
}
|
|
325
|
-
);
|
|
326
|
-
it.todo(
|
|
327
|
-
"handles VariableDeclaration node without a type annotation and warns",
|
|
328
|
-
() => {
|
|
329
|
-
}
|
|
330
|
-
);
|
|
331
|
-
it.todo(
|
|
332
|
-
"handles VariableDeclaration node where symbol cannot be found for the variable name and warns",
|
|
333
|
-
() => {
|
|
334
|
-
}
|
|
335
|
-
);
|
|
336
|
-
it.todo(
|
|
337
|
-
"serializes an Identifier node by resolving its type at that location",
|
|
338
|
-
() => {
|
|
339
|
-
}
|
|
340
|
-
);
|
|
341
|
-
it.todo(
|
|
342
|
-
"handles Identifier node where symbol cannot be found and warns",
|
|
343
|
-
() => {
|
|
344
|
-
}
|
|
345
|
-
);
|
|
346
|
-
it.todo(
|
|
347
|
-
"serializes an AwaitExpression node by resolving the awaited type",
|
|
348
|
-
() => {
|
|
349
|
-
}
|
|
350
|
-
);
|
|
351
|
-
it.todo(
|
|
352
|
-
"serializes a CallExpression node by resolving its return type",
|
|
353
|
-
() => {
|
|
354
|
-
}
|
|
355
|
-
);
|
|
356
|
-
it.todo(
|
|
357
|
-
"serializes an AsExpression node by resolving the asserted type",
|
|
358
|
-
() => {
|
|
359
|
-
}
|
|
360
|
-
);
|
|
361
|
-
it.todo(
|
|
362
|
-
"serializes a TypeLiteralNode (`{ ... }` used as a type) by resolving its properties",
|
|
363
|
-
() => {
|
|
364
|
-
}
|
|
365
|
-
);
|
|
366
|
-
it.todo("serializes NullKeyword node", () => {
|
|
367
|
-
});
|
|
368
|
-
it.todo("serializes BooleanKeyword node", () => {
|
|
369
|
-
});
|
|
370
|
-
it.todo("serializes TrueKeyword node as boolean literal", () => {
|
|
371
|
-
});
|
|
372
|
-
it.todo("serializes FalseKeyword node as boolean literal", () => {
|
|
373
|
-
});
|
|
374
|
-
it.todo(
|
|
375
|
-
"serializes an ArrayLiteralExpression node by resolving its inferred type",
|
|
376
|
-
() => {
|
|
377
|
-
}
|
|
378
|
-
);
|
|
379
|
-
it.todo("handles an unhandled node kind by returning `any` and warns", () => {
|
|
380
|
-
});
|
|
381
|
-
});
|
|
382
|
-
//# sourceMappingURL=deriver.test.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/lib/deriver.test.ts"],
|
|
4
|
-
"sourcesContent": ["import { describe, it } from 'node:test';\n\n// --- serializeType Functionality ---\n\ndescribe('serializeType: Basic Primitive and Special Types', () => {\n it.todo('serializes `any` type to an empty type list', () => {\n // Input: ts.Type with TypeFlags.Any\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [] }\n });\n it.todo('serializes `unknown` type to an empty type list', () => {\n // Input: ts.Type with TypeFlags.Unknown\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [] }\n });\n it.todo('serializes `string` type', () => {\n // Input: ts.Type with TypeFlags.String\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['string'] }\n });\n it.todo('serializes `number` type', () => {\n // Input: ts.Type with TypeFlags.Number\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['number'] }\n });\n it.todo('serializes `boolean` type', () => {\n // Input: ts.Type with TypeFlags.Boolean\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['boolean'] }\n });\n it.todo('serializes `null` type as optional', () => {\n // Input: ts.Type with TypeFlags.Null\n // Output: { [deriveSymbol]: true, optional: true, [$types]: ['null'] }\n });\n it.todo(\n 'serializes `void` type (likely falls back to Any/Unknown or unhandled)',\n () => {\n // Input: ts.Type with TypeFlags.Void (or VoidLike)\n // Determine expected output based on how TS checker presents this type and how the unhandled path works. Likely results in `[$types]: []` or `[$types]: ['void']`.\n },\n );\n it.todo(\n 'serializes `never` type (likely falls back to Any/Unknown or unhandled)',\n () => {\n // Input: ts.Type with TypeFlags.Never\n // Determine expected output. Likely results in `[$types]: []` or `[$types]: ['never']`.\n },\n );\n it.todo(\n 'serializes `undefined` type implicitly via union/intersection optional flag',\n () => {\n // Note: Undefined itself isn't directly serialized as a standalone type by this logic.\n // Its presence in unions/intersections correctly sets the `optional` flag. Tests are under Union/Intersection sections.\n },\n );\n});\n\ndescribe('serializeType: Literal Types', () => {\n it.todo('serializes string literal types with their value', () => {\n // Input: ts.StringLiteralType (e.g., type of \"constant\")\n // Output: { [deriveSymbol]: true, optional: false, kind: 'literal', value: 'constant', [$types]: ['string'] }\n });\n it.todo('serializes numeric literal types with their value', () => {\n // Input: ts.NumberLiteralType (e.g., type of 123)\n // Output: { [deriveSymbol]: true, optional: false, kind: 'literal', value: 123, [$types]: ['number'] }\n });\n it.todo('serializes boolean literal `true` type', () => {\n // Input: ts.BooleanLiteralType (true) checked via TypeFlags.BooleanLiteral\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['boolean'] }\n // Note: Current code identifies it's boolean but doesn't store the literal `true` value.\n });\n it.todo('serializes boolean literal `false` type', () => {\n // Input: ts.BooleanLiteralType (false) checked via TypeFlags.BooleanLiteral\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['boolean'] }\n // Note: Current code identifies it's boolean but doesn't store the literal `false` value.\n });\n it.todo('serializes template literal types as base `string`', () => {\n // Input: ts.Type with TypeFlags.TemplateLiteral (e.g. type of `ID-${number}`)\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['string'] }\n });\n // Note: BigIntLiteral is not explicitly handled, would fall under unhandled.\n});\n\ndescribe('serializeType: Enum Types', () => {\n it.todo(\n 'serializes an Enum type (e.g., `enum Color {}`) potentially via unhandled path',\n () => {\n // Input: ts.Type with TypeFlags.Enum (representing the enum itself, e.g., `Color`)\n // Expect it to fall into the unhandled path, likely using checker.typeToString.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['Color'] } or similar based on typeToString. Check console warning.\n },\n );\n it.todo(\n 'serializes an EnumLiteral type (e.g., `Color.Red`) potentially via unhandled path or base type',\n () => {\n // Input: ts.Type with TypeFlags.EnumLiteral (representing the enum member, e.g., `Color.Red`)\n // Check if TS resolves this to its base type (string/number) or if it falls to unhandled.\n // If number enum: Potentially { [deriveSymbol]: true, optional: false, [$types]: ['number'] }\n // If string enum: Potentially { [deriveSymbol]: true, optional: false, [$types]: ['string'] } or a literal string.\n // If unhandled: { [deriveSymbol]: true, optional: false, [$types]: ['Color.Red'] } or similar. Check console warning.\n },\n );\n});\n\ndescribe('serializeType: Union Types (`|`)', () => {\n it.todo(\n 'serializes a union of primitive types (e.g., string | number)',\n () => {\n // Input: ts.UnionType with string and number types\n // Output: { [deriveSymbol]: true, kind: 'union', optional: false, [$types]: [serializedString, serializedNumber] }\n },\n );\n it.todo(\n 'serializes a union type including `null` (e.g., string | null)',\n () => {\n // Input: ts.UnionType with string and null types\n // Output: { [deriveSymbol]: true, kind: 'union', optional: false, [$types]: [serializedString, serializedNull] }\n // Note: `optional` remains false because `null` is treated as a distinct type here.\n },\n );\n it.todo(\n 'serializes a union type including `undefined`, setting optional flag and filtering `undefined`',\n () => {\n // Input: ts.UnionType with string and undefined types\n // Output: { [deriveSymbol]: true, kind: 'union', optional: true, [$types]: [serializedString] } // undefined is filtered out, optional set to true\n },\n );\n it.todo(\n 'serializes a union type including both `null` and `undefined`',\n () => {\n // Input: ts.UnionType with string, null, and undefined types\n // Output: { [deriveSymbol]: true, kind: 'union', optional: true, [$types]: [serializedString, serializedNull] } // undefined filtered, optional true\n },\n );\n it.todo('serializes a union of literal types (e.g., \"a\" | \"b\" | 1)', () => {\n // Input: ts.UnionType with \"a\", \"b\", 1 types\n // Output: { [deriveSymbol]: true, kind: 'union', optional: false, [$types]: [serializedLiteralA, serializedLiteralB, serializedLiteral1] }\n });\n it.todo(\n 'serializes a union including complex types (e.g., string | MyInterface)',\n () => {\n // Input: ts.UnionType with string and an interface type\n // Output: { [deriveSymbol]: true, kind: 'union', optional: false, [$types]: [serializedString, serializedInterfaceRef] }\n },\n );\n it.todo('serializes a union containing only `undefined`', () => {\n // Input: ts.UnionType with only undefined type\n // Output: { [deriveSymbol]: true, kind: 'union', optional: true, [$types]: [] }\n });\n it.todo('serializes a union containing only `null`', () => {\n // Input: ts.UnionType with only null type\n // Output: { [deriveSymbol]: true, kind: 'union', optional: false, [$types]: [serializedNull] }\n });\n});\n\ndescribe('serializeType: Intersection Types (`&`)', () => {\n it.todo(\n 'serializes an intersection of object/interface types (e.g., A & B)',\n () => {\n // Input: ts.IntersectionType with two interface types A and B\n // Output: { [deriveSymbol]: true, kind: 'intersection', optional: false, [$types]: [serializedInterfaceA, serializedInterfaceB] }\n },\n );\n it.todo(\n 'serializes an intersection type including `undefined`, setting optional flag and filtering `undefined`',\n () => {\n // Input: ts.IntersectionType with an interface type A and undefined\n // Output: { [deriveSymbol]: true, kind: 'intersection', optional: true, [$types]: [serializedInterfaceA] }\n },\n );\n it.todo('serializes an intersection containing only `undefined`', () => {\n // Input: ts.IntersectionType with only undefined type\n // Output: { [deriveSymbol]: true, kind: 'intersection', optional: true, [$types]: [] }\n });\n // Note: Intersections of primitives often resolve to `never`. The serialization of `never` itself is tested separately.\n});\n\ndescribe('serializeType: Array and Tuple Types', () => {\n it.todo('serializes a simple array type (e.g., string[])', () => {\n // Input: ts.TypeReference to Array<string>\n // Mock checker.isArrayLikeType -> true, checker.getTypeArguments -> [stringType]\n // Output: { [deriveSymbol]: true, kind: 'array', optional: false, [$types]: [serializedString] }\n });\n it.todo('serializes readonly array types (e.g., readonly number[])', () => {\n // Input: ts.TypeReference to ReadonlyArray<number>\n // Mock checker.isArrayLikeType -> true, checker.getTypeArguments -> [numberType]\n // Output: { [deriveSymbol]: true, kind: 'array', optional: false, [$types]: [serializedNumber] }\n });\n it.todo(\n 'serializes an array type with object elements (e.g., MyInterface[])',\n () => {\n // Input: ts.TypeReference to Array<MyInterface>\n // Mock checker.getTypeArguments -> [interfaceType], interfaceType.symbol.valueDeclaration -> InterfaceDeclaration Node\n // Output: { [deriveSymbol]: true, kind: 'array', optional: false, [$types]: [serializedInterfaceRef] } // Relies on serializeNode call\n },\n );\n it.todo(\n 'serializes an array type with union elements (e.g., (string | number)[])',\n () => {\n // Input: ts.TypeReference to Array<string | number>\n // Mock checker.getTypeArguments -> [unionType]\n // Output: { [deriveSymbol]: true, kind: 'array', optional: false, [$types]: [serializedUnionStringNumber] }\n },\n );\n it.todo('serializes an array type where element type has no symbol', () => {\n // Input: ts.TypeReference to Array<{inline: boolean}>\n // Mock checker.getTypeArguments -> [inlineObjectType], inlineObjectType.getSymbol() -> undefined\n // Output: { [deriveSymbol]: true, kind: 'array', optional: false, [$types]: [serializedInlineObject] } // Relies on serializeType(inlineObjectType)\n });\n it.todo(\n 'serializes an array type where element symbol has no value declaration but has declarations',\n () => {\n // Input: ts.TypeReference to Array<SomeType>\n // Mock checker.getTypeArguments -> [someType], someType.symbol.valueDeclaration -> undefined, someType.symbol.declarations -> [TypeAliasDeclaration Node?]\n // Expect serializeNode to be called with declarations[0]. Verify output based on that node type.\n },\n );\n it.todo(\n 'serializes an array type with a mapped type element (e.g., MappedType[])',\n () => {\n // Input: ts.TypeReference to Array<MappedType>\n // Mock checker.getTypeArguments -> [mappedType], mappedType symbol has declarations[0] as MappedTypeNode\n // Mock checker.getPropertiesOfType for mappedType\n // Output: { kind: 'array', optional: false, [deriveSymbol]: true, [$types]: [resolvedMappedObject] }\n },\n );\n it.todo(\n 'handles array-like types with missing type arguments gracefully (e.g., Array)',\n () => {\n // Input: ts.TypeReference to Array (no <T>)\n // Mock checker.getTypeArguments -> undefined or []\n // Output: { [deriveSymbol]: true, optional: false, kind: 'array', [$types]: ['any'] } // Check console warning\n },\n );\n it.todo(\n 'serializes tuple types (e.g., [string, number]) potentially as array of union',\n () => {\n // Input: ts.TupleTypeReference for [string, number]\n // Mock checker.isArrayLikeType -> true. Check what checker.getTypeArguments returns (likely the tuple element types).\n // Current code likely serializes as Array<string | number>.\n // Expected Output (based on current code): { [deriveSymbol]: true, kind: 'array', optional: false, [$types]: [serializedUnionStringNumber] } or similar union.\n // Note: A more precise tuple serialization would require specific handling of ts.TupleTypeReference.\n },\n );\n});\n\ndescribe('serializeType: Record/Index Types', () => {\n it.todo(\n 'serializes a string index signature type (Record<string, number>)',\n () => {\n // Input: ts.Type where type.getStringIndexType() returns numberType\n // Output: { [deriveSymbol]: true, kind: 'record', optional: false, [$types]: [serializedNumber] }\n },\n );\n it.todo(\n 'serializes a string index signature type with complex value (Record<string, MyInterface>)',\n () => {\n // Input: ts.Type where type.getStringIndexType() returns interfaceType\n // Output: { [deriveSymbol]: true, kind: 'record', optional: false, [$types]: [serializedInterfaceRef] }\n },\n );\n it.todo(\n 'serializes a type with only a number index signature ([key: number]: boolean)',\n () => {\n // Input: ts.Type where type.getStringIndexType() is undefined, but type.getNumberIndexType() exists.\n // Expect this to *not* take the `getStringIndexType` path.\n // It should fall into the `TypeFlags.Object` path.\n // Mock checker.getPropertiesOfType (might be empty or special symbol).\n // Mock type.symbol.declarations to include the IndexSignature node.\n // Expected Output: Likely falls back to generic object or potentially unhandled `{ [deriveSymbol]: true, optional: false, [$types]: ['<some object representation>'] }`. Needs verification against actual TS behavior.\n },\n );\n});\n\ndescribe('serializeType: Object Types (Interfaces, Classes, Inline, Mapped)', () => {\n it.todo('serializes an inline object type literal (passed as type)', () => {\n // Input: ts.Type representing `{ a: string; b?: number }` (TypeFlags.Object)\n // Mock checker.getPropertiesOfType -> [symbolA, symbolB]\n // Mock checker.getTypeOfSymbol for 'a' (string) and 'b' (number | undefined)\n // Output: { [deriveSymbol]: true, kind: 'object', optional: false, [$types]: [{ a: serializedString, b: serializedUnionNumberUndefined }] }\n });\n it.todo(\n 'serializes a mapped type directly (e.g., type M = { [K in keyof T]: T[K] })',\n () => {\n // Input: ts.Type representing a mapped type (TypeFlags.Object, potentially others)\n // Mock checker.getPropertiesOfType to return the mapped properties.\n // Mock checker.getTypeOfSymbol for each mapped property.\n // Output: { [deriveSymbol]: true, kind: 'object', optional: false, [$types]: [{ /* serialized mapped properties */ }] }\n },\n );\n it.todo(\n 'serializes an object type using literal property assignments from declarations',\n () => {\n // Input: ts.Type representing an object like `const x = { val: 123 }`\n // Mock checker.getPropertiesOfType -> [symbolVal]\n // Mock symbolVal.getDeclarations() -> [PropertyAssignment node with literal 123]\n // Mock checker.getTypeAtLocation for the literal initializer -> numberLiteralType(123)\n // Output: { [deriveSymbol]: true, kind: 'object', optional: false, [$types]: [{ val: serializedLiteral123 }] }\n },\n );\n it.todo(\n 'serializes an object type with mixed declared types (PropertySignature) and literal assignments (PropertyAssignment)',\n () => {\n // Input: ts.Type representing `{ prop: string; literal: \"hello\" }` where `prop` comes from signature and `literal` from assignment.\n // Ensure both `isPropertyAssignment` and `isPropertySignature` paths within the loop are tested.\n // Output: { [deriveSymbol]: true, kind: 'object', optional: false, [$types]: [{ prop: serializedString, literal: serializedLiteralHello }] }\n },\n );\n it.todo(\n 'serializes an empty object type `{}` potentially falling back to name or generic',\n () => {\n // Input: ts.Type representing `{}` (TypeFlags.Object)\n // Mock checker.getPropertiesOfType -> []\n // Mock type.symbol.valueDeclaration / declarations -> undefined\n // Mock type.symbol.getName() -> 'Object' or similar\n // Expected Output: Depends on fallback logic. Potentially `{ [deriveSymbol]: true, optional: false, [$types]: ['Object'] }` or a generic object representation if name is unhelpful.\n },\n );\n it.todo(\n 'handles object types matching default overrides (e.g., DateConstructor -> string)',\n () => {\n // Input: ts.Type whose symbol name is 'DateConstructor' (present in `defaults`)\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['string'] } // Value from `defaults` map\n },\n );\n it.todo(\n 'handles known object types NOT in defaults (e.g., RegExp) by attempting standard object serialization',\n () => {\n // Input: ts.Type for RegExp (not in `defaults`)\n // Mock checker.getPropertiesOfType (likely empty or methods)\n // Mock symbol.valueDeclaration / declarations (likely points to lib.d.ts)\n // Expect standard object serialization attempt, possibly resulting in an empty object or reference if declaration is found.\n // Output: { [deriveSymbol]: true, kind: 'object', optional: false, [$types]: [{ /* properties or empty */ }] } or a reference via serializeNode.\n },\n );\n it.todo(\n 'serializes an interface type by deferring to serializeNode for reference/collection',\n () => {\n // Input: ts.InterfaceType (an interface type verified by type.isClassOrInterface() and symbol flags)\n // Mock type.symbol.valueDeclaration or declarations[0] -> InterfaceDeclaration node\n // Verify serializeNode is called with the declaration node.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/MyInterface`] }\n },\n );\n it.todo(\n 'serializes a class type by deferring to serializeNode for reference/collection',\n () => {\n // Input: ts.Type representing a class (isClass returns true)\n // Mock type.symbol.valueDeclaration -> ClassDeclaration node\n // Verify serializeNode is called with the declaration node.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/MyClass`], $ref: `#/components/schemas/MyClass` }\n },\n );\n it.todo(\n 'serializes an interface type using its name when its declaration cannot be found',\n () => {\n // Input: ts.InterfaceType where type.symbol has no valueDeclaration or declarations[0]\n // Mock type.symbol.getName() -> 'MyInterface'\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['MyInterface'] }\n },\n );\n it.todo(\n 'serializes a class type using its name when its declaration cannot be found',\n () => {\n // Input: ts.Type for a class where type.symbol has no valueDeclaration\n // Mock type.symbol.getName() -> 'MyClass'\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['MyClass'] }\n },\n );\n});\n\ndescribe('serializeType: Unhandled Types', () => {\n it.todo(\n 'handles an unhandled type flag by using checker.typeToString and warns',\n () => {\n // Input: A ts.Type with flags not explicitly handled (e.g., potentially Enum, Index, IndexedAccess if not resolved)\n // Mock checker.typeToString -> '<specific unhandled representation>'\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['<specific unhandled representation>'] } // Check console warning\n },\n );\n // Note: Complex types like ConditionalType, IndexedAccessType are expected to be resolved by the checker *before* this function sees them.\n // We serialize the *result* of the resolution, not the conditional/indexed access type itself.\n});\n\n// --- serializeNode Functionality ---\n\ndescribe('serializeNode: Object Literal Expressions (`{ ... }`)', () => {\n it.todo(\n 'serializes an object literal node with various primitive property types',\n () => {\n // Input: ts.ObjectLiteralExpression node `{ a: 1, b: \"s\", c: true, d: null, e: undefined }`\n // Mock checker.getTypeAtLocation for the node itself\n // Mock checker.getTypeOfSymbol for properties 'a', 'b', 'c', 'd', 'e'\n // Mock checker.getTypeAtLocation for literal initializers (1, \"s\", true, null, undefined)\n // Output: { a: serializedLiteral1, b: serializedLiteralS, c: serializedLiteralTrue, d: serializedNull, e: serializedUndefined } // Note: undefined serialization depends on serializeType\n },\n );\n it.todo(\n 'serializes an object literal node with nested object/array literals',\n () => {\n // Input: ts.ObjectLiteralExpression node `{ data: { values: [1, 2] } }`\n // Ensure recursive serialization via serializeType/serializeNode works.\n // Output: { data: { values: serializedArrayLiteral12 } }\n },\n );\n it.todo('serializes an empty object literal node `{}`', () => {\n // Input: ts.ObjectLiteralExpression node `{}`\n // Mock checker.getTypeAtLocation -> empty object type\n // Output: {}\n });\n});\n\ndescribe('serializeNode: Property Access/Signature/Declaration', () => {\n it.todo(\n 'serializes a PropertyAccessExpression node (e.g., `obj.prop`) by resolving its type',\n () => {\n // Input: ts.PropertyAccessExpression node `obj.prop`\n // Mock checker.getSymbolAtLocation for `prop` -> symbolProp\n // Mock checker.getTypeOfSymbol(symbolProp) -> typeProp\n // Verify serializeType is called with typeProp.\n // Output: Result of serializeType(typeProp)\n },\n );\n it.todo(\n 'serializes a PropertySignature node (e.g., `prop: string;`) by resolving its type',\n () => {\n // Input: ts.PropertySignature node `prop: string;` (within an InterfaceDeclaration or TypeLiteral)\n // Mock checker.getSymbolAtLocation for `prop` -> symbolProp\n // Mock checker.getTypeOfSymbol(symbolProp) -> stringType\n // Verify serializeType is called with stringType.\n // Output: Result of serializeType(stringType)\n },\n );\n it.todo(\n 'serializes a PropertyDeclaration node (e.g., `prop: number;`) by resolving its type',\n () => {\n // Input: ts.PropertyDeclaration node `prop: number;` (within a ClassDeclaration)\n // Mock checker.getSymbolAtLocation for `prop` -> symbolProp\n // Mock checker.getTypeOfSymbol(symbolProp) -> numberType\n // Verify serializeType is called with numberType.\n // Output: Result of serializeType(numberType)\n },\n );\n it.todo(\n 'handles property nodes where symbol cannot be found for the property name and warns',\n () => {\n // Input: A PropertySignature/Declaration/Access node where checker.getSymbolAtLocation(node.name) returns undefined\n // Output: null // Check console warning\n },\n );\n});\n\ndescribe('serializeNode: Interface Declarations (`interface ...`) and Collector Interaction', () => {\n it.todo(\n 'serializes a new interface declaration, adding its structure to the collector',\n () => {\n // Input: ts.InterfaceDeclaration node `interface MyInterface { id: number; name?: string; }`\n // Ensure collector['MyInterface'] is initially empty/undefined.\n // Mock members `id` and `name` and their serialization via serializeNode(PropertySignature).\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/MyInterface`] }\n // Verify collector['MyInterface'] now contains { id: serializedNumber, name: serializedUnionStringUndefined }\n },\n );\n it.todo(\n 'returns only a reference for an already serialized interface declaration (present in collector)',\n () => {\n // Input: ts.InterfaceDeclaration node `interface MyInterface { ... }`\n // Pre-populate collector['MyInterface'] with a placeholder or previous result.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/MyInterface`] }\n // Verify collector['MyInterface'] was not overwritten if already fully populated.\n },\n );\n it.todo(\n 'handles interface declarations matching default overrides without adding to collector',\n () => {\n // Input: ts.InterfaceDeclaration node `interface Readable { ... }` (name is in `defaults`)\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['any'] } // Value from `defaults` map\n // Verify collector['Readable'] remains undefined or unchanged.\n },\n );\n it.todo('throws an error for an interface declaration without a name', () => {\n // Input: An InterfaceDeclaration node where node.name is undefined.\n // Expect the function to throw 'Interface has no name'.\n });\n it.todo(\n 'handles interfaces with no members correctly (adds empty object to collector)',\n () => {\n // Input: ts.InterfaceDeclaration node `interface Empty {}`\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/Empty`] }\n // Verify collector['Empty'] is `{}`.\n },\n );\n it.todo(\n 'handles interfaces extending other interfaces (serialization includes only own properties)',\n () => {\n // Input: `interface B extends A { propB: string; }` (where A is `interface A { propA: number }`)\n // Serialize B.\n // Output: Reference `#/components/schemas/B`\n // Verify collector['B'] contains only `{ propB: serializedString }`. (Inherited props are resolved by tools consuming the schema, not duplicated here).\n // Note: Actual inheritance representation might need adjustment based on target schema format (e.g., OpenAPI `allOf`). This test verifies the *collector* content based on current code.\n },\n );\n});\n\ndescribe('serializeNode: Class Declarations (`class ...`) and Collector Interaction', () => {\n it.todo(\n 'serializes a new class declaration, adding its property structure to the collector',\n () => {\n // Input: ts.ClassDeclaration node `class MyClass { id: number; private secret: string; constructor() {} }`\n // Ensure collector['MyClass'] is initially empty/undefined.\n // Mock members `id` and `secret` and their serialization via serializeNode(PropertyDeclaration). Ignore constructor/methods.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/MyClass`], $ref: `#/components/schemas/MyClass` }\n // Verify collector['MyClass'] now contains { id: serializedNumber, secret: serializedString } (Includes private members)\n },\n );\n it.todo(\n 'returns only a reference for an already serialized class declaration (present in collector)',\n () => {\n // Input: ts.ClassDeclaration node `class MyClass { ... }`\n // Pre-populate collector['MyClass'] with a placeholder or previous result.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/MyClass`], $ref: `#/components/schemas/MyClass` }\n // Verify collector['MyClass'] was not overwritten if already fully populated.\n },\n );\n it.todo(\n 'handles class declarations matching default overrides without adding to collector',\n () => {\n // Input: ts.ClassDeclaration node `class Uint8Array { ... }` (name is in `defaults`)\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['any'] } // Value from `defaults` map\n // Verify collector['Uint8Array'] remains undefined or unchanged.\n },\n );\n it.todo(\n 'throws an error for a class declaration without a name (e.g., anonymous default export)',\n () => {\n // Input: A ClassDeclaration node where node.name is undefined.\n // Expect the function to throw 'Class has no name'.\n },\n );\n it.todo(\n 'handles classes with no property declarations (only methods/constructor) correctly (adds empty object to collector)',\n () => {\n // Input: ts.ClassDeclaration node `class Service { constructor() {} process() {} }`\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [`#/components/schemas/Service`], $ref: `#/components/schemas/Service` }\n // Verify collector['Service'] is `{}`.\n },\n );\n it.todo(\n 'handles classes implementing interfaces (serialization includes only own properties)',\n () => {\n // Input: `class B implements A { propB: string; }` (where A is `interface A { propA: number }`)\n // Serialize B.\n // Output: Reference `#/components/schemas/B`\n // Verify collector['B'] contains only `{ propB: serializedString }`.\n },\n );\n it.todo(\n 'handles classes extending other classes (serialization includes only own properties)',\n () => {\n // Input: `class D extends C { propD: string; }` (where C is `class C { propC: number }`)\n // Serialize D.\n // Output: Reference `#/components/schemas/D`\n // Verify collector['D'] contains only `{ propD: serializedString }`.\n },\n );\n});\n\ndescribe('serializeNode: Other Node Types', () => {\n it.todo(\n 'serializes a VariableDeclaration node with an explicit type annotation',\n () => {\n // Input: ts.VariableDeclaration node `const user: IUser;`\n // Mock node.type to be a TypeReference node pointing to IUser\n // Mock checker.getTypeFromTypeNode -> interfaceType IUser\n // Verify serializeType is called with interfaceType IUser.\n // Output: Result of serializeType(interfaceType IUser) -> likely interface reference\n },\n );\n it.todo(\n 'handles VariableDeclaration node without a type annotation and warns',\n () => {\n // Input: ts.VariableDeclaration node `const count = 5;` (node.type is undefined)\n // Output: 'any' // Check console warning\n },\n );\n it.todo(\n 'handles VariableDeclaration node where symbol cannot be found for the variable name and warns',\n () => {\n // Input: ts.VariableDeclaration node where checker.getSymbolAtLocation(node.name) returns undefined\n // Output: null // Check console warning\n },\n );\n it.todo(\n 'serializes an Identifier node by resolving its type at that location',\n () => {\n // Input: ts.Identifier node `myVar` (where myVar is declared as string)\n // Mock checker.getSymbolAtLocation for the identifier -> symbolMyVar\n // Mock checker.getTypeAtLocation for the identifier node -> stringType\n // Verify serializeType is called with stringType.\n // Output: Result of serializeType(stringType)\n },\n );\n it.todo(\n 'handles Identifier node where symbol cannot be found and warns',\n () => {\n // Input: ts.Identifier node where checker.getSymbolAtLocation returns undefined\n // Output: null // Check console warning\n },\n );\n it.todo(\n 'serializes an AwaitExpression node by resolving the awaited type',\n () => {\n // Input: ts.AwaitExpression node `await getUser()` where getUser returns Promise<User>\n // Mock checker.getTypeAtLocation(node) -> User type (checker resolves the Promise)\n // Verify serializeType is called with the User type.\n // Output: Result of serializeType(User type)\n },\n );\n it.todo(\n 'serializes a CallExpression node by resolving its return type',\n () => {\n // Input: ts.CallExpression node `calculateTotal()` where calculateTotal returns number\n // Mock checker.getTypeAtLocation(node) -> numberType\n // Verify serializeType is called with numberType.\n // Output: Result of serializeType(numberType)\n },\n );\n it.todo(\n 'serializes an AsExpression node by resolving the asserted type',\n () => {\n // Input: ts.AsExpression node `data as Product`\n // Mock checker.getTypeAtLocation(node) -> Product type (the asserted type)\n // Verify serializeType is called with the Product type.\n // Output: Result of serializeType(Product type)\n },\n );\n it.todo(\n 'serializes a TypeLiteralNode (`{ ... }` used as a type) by resolving its properties',\n () => {\n // Input: ts.TypeLiteralNode node `{ id: number; value: string }`\n // Mock checker.getTypeAtLocation(node) -> objectType\n // Mock checker.getPropertiesOfType(objectType) -> [symbolId, symbolValue]\n // Mock checker.getTypeOfSymbol for each property.\n // Output: { [deriveSymbol]: true, optional: false, [$types]: [{ id: serializedNumber, value: serializedString }] }\n },\n );\n it.todo('serializes NullKeyword node', () => {\n // Input: Node with kind ts.SyntaxKind.NullKeyword\n // Output: { [deriveSymbol]: true, optional: true, [$types]: ['null'] }\n });\n it.todo('serializes BooleanKeyword node', () => {\n // Input: Node with kind ts.SyntaxKind.BooleanKeyword\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['boolean'] }\n });\n it.todo('serializes TrueKeyword node as boolean literal', () => {\n // Input: Node with kind ts.SyntaxKind.TrueKeyword\n // Output: { [deriveSymbol]: true, optional: false, kind: 'literal', value: true, [$types]: ['boolean'] }\n });\n it.todo('serializes FalseKeyword node as boolean literal', () => {\n // Input: Node with kind ts.SyntaxKind.FalseKeyword\n // Output: { [deriveSymbol]: true, optional: false, kind: 'literal', value: false, [$types]: ['boolean'] }\n });\n it.todo(\n 'serializes an ArrayLiteralExpression node by resolving its inferred type',\n () => {\n // Input: ts.ArrayLiteralExpression node `[1, \"a\", null]`\n // Mock checker.getTypeAtLocation(node) -> inferred array type (e.g., (number | string | null)[])\n // Verify serializeType is called with the inferred type.\n // Output: Result of serializeType(inferred array type) -> likely array of union\n },\n );\n it.todo('handles an unhandled node kind by returning `any` and warns', () => {\n // Input: A node with a kind not explicitly handled (e.g., ts.SyntaxKind.IfStatement)\n // Output: { [deriveSymbol]: true, optional: false, [$types]: ['any'] } // Check console warning\n });\n});\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-system.test.d.ts","sourceRoot":"","sources":["../../src/lib/file-system.test.ts"],"names":[],"mappings":""}
|