diff --git a/deno.json b/deno.json index ef33f06..ad77a3d 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "@denosaurs/typefetch", - "version": "0.0.32", + "version": "0.0.33", "exports": { ".": "./main.ts" }, diff --git a/main.ts b/main.ts index a66c9a5..43d8420 100644 --- a/main.ts +++ b/main.ts @@ -17,6 +17,7 @@ const parseOptions = { "config", "import", "base-urls", + "experimental-discriminator", ], boolean: [ "help", @@ -24,6 +25,7 @@ const parseOptions = { "include-server-urls", "include-relative-url", "experimental-urlsearchparams", + "experimental-require-discriminator", ], alias: { "output": "o", "help": "h", "version": "V" }, default: { @@ -35,6 +37,8 @@ const parseOptions = { "include-absolute-url": false, "include-relative-url": false, "experimental-urlsearchparams": false, + "experimental-discriminator": false, + "experimental-require-discriminator": false, }, unknown: (arg: string, key?: string) => { if (key === undefined) return; @@ -54,16 +58,18 @@ if (args.help) { console.log( `Usage: typefetch [OPTIONS] \n\n` + `Options:\n` + - ` -h, --help Print this help message\n` + - ` -V, --version Print the version of TypeFetch\n` + - ` -o, --output Output file path (default: ${parseOptions.default["output"]})\n` + - ` --config File path to the tsconfig.json file\n` + - ` --import Import path for TypeFetch (default: ${parseOptions.default["import"]})\n` + - ` --base-urls A comma separated list of custom base urls for paths to start with\n` + - ` --include-server-urls Include server URLs from the schema in the generated paths (default: ${parseOptions.default["include-server-urls"]})\n` + - ` --include-absolute-url Include absolute URLs in the generated paths (default: ${parseOptions.default["include-absolute-url"]})\n` + - ` --include-relative-url Include relative URLs in the generated paths (default: ${parseOptions.default["include-relative-url"]})\n` + - ` --experimental-urlsearchparams Enable the experimental fully typed URLSearchParamsString type (default: ${parseOptions.default["experimental-urlsearchparams"]})\n`, + ` -h, --help Print this help message\n` + + ` -V, --version Print the version of TypeFetch\n` + + ` -o, --output Output file path (default: ${parseOptions.default["output"]})\n` + + ` --config File path to the tsconfig.json file\n` + + ` --import Import path for TypeFetch (default: ${parseOptions.default["import"]})\n` + + ` --base-urls A comma separated list of custom base urls for paths to start with\n` + + ` --include-server-urls Include server URLs from the schema in the generated paths (default: ${parseOptions.default["include-server-urls"]})\n` + + ` --include-absolute-url Include absolute URLs in the generated paths (default: ${parseOptions.default["include-absolute-url"]})\n` + + ` --include-relative-url Include relative URLs in the generated paths (default: ${parseOptions.default["include-relative-url"]})\n` + + ` --experimental-urlsearchparams Enable the experimental fully typed URLSearchParamsString type (default: ${parseOptions.default["experimental-urlsearchparams"]})\n` + + ` --experimental-discriminator Allows you to specify a discriminator generic argument to fetch (default: ${parseOptions.default["experimental-discriminator"]})\n` + + ` --experimental-require-discriminator Makes the use of a discriminator generic argument required (default: ${parseOptions.default["experimental-require-discriminator"]})\n`, ); Deno.exit(0); } @@ -111,6 +117,8 @@ const options = { includeServerUrls: args["include-server-urls"], includeRelativeUrl: args["include-relative-url"], experimentalURLSearchParams: args["experimental-urlsearchparams"], + discriminator: args["experimental-discriminator"], + requireDiscriminator: args["experimental-require-discriminator"], }; const project = new Project({ tsConfigFilePath: args.config }); diff --git a/mod.ts b/mod.ts index 1d606f3..3901dc6 100644 --- a/mod.ts +++ b/mod.ts @@ -2,7 +2,9 @@ import type { CodeBlockWriter, JSDocStructure, ModuleDeclaration, + OptionalKind, SourceFile, + TypeParameterDeclarationStructure, } from "ts-morph"; import { STATUS_CODE } from "@std/http/status"; @@ -34,6 +36,8 @@ export interface Options { includeRelativeUrl?: boolean; includeServerUrls?: boolean; experimentalURLSearchParams?: boolean; + experimentalDiscriminator?: string | false; + experimentalRequireDiscriminator?: boolean; } export function escapeObjectKey(key: string): string { @@ -677,10 +681,23 @@ export function addOperationObject( const input = inputs.map((template) => `\`${template}\``).join("|"); + const typeParameters: OptionalKind[] = []; + if (options.experimentalDiscriminator) { + const discriminatorType = `"${options.experimentalDiscriminator}"`; + typeParameters.push({ + name: "T", + constraint: discriminatorType, + default: options.experimentalRequireDiscriminator + ? undefined + : discriminatorType, + }); + } + global.addFunctions( requestBodyTypes.map(({ contentType, requestBodyType }) => ({ name: "fetch", docs: notEmpty(doc) ? [doc] : [], + typeParameters: typeParameters, parameters: [ { name: "input",