Skip to content

Commit

Permalink
path parameterがない場合、strict falseなら生成する様にしました
Browse files Browse the repository at this point in the history
  • Loading branch information
kahirokunn committed Nov 14, 2023
1 parent 0f5c743 commit f07a0da
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kubernetes-typescript-client-codegen-openapi",
"version": "0.0.12",
"version": "0.0.13",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"author": "kahirokunn",
Expand All @@ -20,7 +20,7 @@
"format": "prettier --write \"src/**/*.ts\"",
"esm:test:update": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand --updateSnapshot",
"test:update": "jest --runInBand --updateSnapshot",
"test": "jest --runInBand",
"test": "jest --runInBand --silent=false",
"cli": "esr src/bin/cli.ts"
},
"files": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export async function generateApi(
isDataResponse = defaultIsDataResponse,
filterEndpoints,
unionUndefined = true,
strict = true,
}: GenerationOptions
) {
const v3Doc = await getV3Doc(spec);
Expand Down Expand Up @@ -347,7 +348,7 @@ export async function generateApi(
[
factory.createPropertyAssignment(
factory.createIdentifier('path'),
generatePathExpression(path, pickParams('path'), rootObject)
generatePathExpression(path, pickParams('path'), rootObject, strict)
),
verb.toUpperCase() === 'GET'
? undefined
Expand Down Expand Up @@ -382,13 +383,30 @@ function accessProperty(rootObject: ts.Identifier, propertyName: string) {
: factory.createElementAccessExpression(rootObject, factory.createStringLiteral(propertyName));
}

function generatePathExpression(path: string, pathParameters: QueryArgDefinition[], rootObject: ts.Identifier) {
function generatePathExpression(path: string, pathParameters: QueryArgDefinition[], rootObject: ts.Identifier, strict: boolean) {
const expressions: Array<[string, string]> = [];

const head = path.replace(/\{(.*?)\}(.*?)(?=\{|$)/g, (_, expression, literal) => {
const param = pathParameters.find((p) => p.originalName === expression);
let param = pathParameters.find((p) => p.originalName === expression);
if (!param) {
throw new Error(`path parameter ${expression} does not seem to be defined in '${path}'!`);
if (strict) {
throw new Error(`path parameter ${expression} does not seem to be defined in '${path}'!`);
}
param = {
origin: 'param',
name: expression,
originalName: expression,
type: factory.createToken(ts.SyntaxKind.StringKeyword),
required: true,
param: {
name: expression,
in: 'path',
description: 'The name that needs to be deleted',
required: true,
schema: { type: 'string' },
},
};
pathParameters.push(param);
}
expressions.push([param.name, literal]);
return '';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ export interface CommonOptions {
* `true` will generate a union type for `undefined` properties like: `{ id?: string | undefined }` instead of `{ id?: string }`
*/
unionUndefined?: boolean;

/**
* defaults to true
* If `true`, an error will occur if the path parameter does not exist, but if `false`, it will be automatically filled in as a string.
*/
strict?: boolean;
}

export type TextMatcher = string | RegExp | (string | RegExp)[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@ import * as fs from 'fs';
import path from 'path';
import del from 'del';

function strictCli(
args: string[],
cwd: string
): Promise<{ error: ExecException | null; stdout: string; stderr: string }> {
const pwd = (process.env && process.env.PWD) || '.';
const cmd = `${require.resolve('ts-node/dist/bin')} -T -P ${path.resolve(pwd, 'tsconfig.json')} ${path.resolve(
pwd,
'src/bin/cli.ts'
)} ${args.join(' ')}`;
return new Promise((resolve) => {
exec(cmd, { cwd }, (error, stdout, stderr) => {
resolve({
error,
stdout,
stderr,
});
});
});
}

function cli(args: string[], cwd: string): Promise<{ error: ExecException | null; stdout: string; stderr: string }> {
const pwd = (process.env && process.env.PWD) || '.';
const cmd = `${require.resolve('ts-node/dist/bin')} -T -P ${path.resolve(pwd, 'tsconfig.json')} ${path.resolve(
Expand Down Expand Up @@ -33,7 +53,7 @@ afterEach(() => {

describe('CLI options testing', () => {
test('generation with `config.example.js`', async () => {
const out = await cli([`./config.example.js`], __dirname);
const out = await strictCli([`./config.example.js`], __dirname);

expect(out).toEqual({
stdout: `Generating ./tmp/example.ts
Expand All @@ -47,7 +67,7 @@ Done
}, 25000);

test('paths are relative to configfile, not to cwd', async () => {
const out = await cli([`../test/config.example.js`], path.resolve(__dirname, '../src'));
const out = await strictCli([`../test/config.example.js`], path.resolve(__dirname, '../src'));

expect(out).toEqual({
stdout: `Generating ./tmp/example.ts
Expand All @@ -61,19 +81,24 @@ Done
}, 25000);

test('ts, js and json all work the same', async () => {
await cli([`./config.example.js`], __dirname);
await strictCli([`./config.example.js`], __dirname);
const fromJs = fs.readFileSync(path.resolve(tmpDir, 'example.ts'), 'utf-8');
await cli([`./config.example.ts`], __dirname);
await strictCli([`./config.example.ts`], __dirname);
const fromTs = fs.readFileSync(path.resolve(tmpDir, 'example.ts'), 'utf-8');
await cli([`./config.example.json`], __dirname);
await strictCli([`./config.example.json`], __dirname);
const fromJson = fs.readFileSync(path.resolve(tmpDir, 'example.ts'), 'utf-8');

expect(fromTs).toEqual(fromJs);
expect(fromJson).toEqual(fromJs);
}, 45000);

test('missing parameters doesnt fail', async () => {
const out = await cli([`./config.invalid-example.json`], __dirname);
test("missing parameters doesn't fail", async () => {
const out = await strictCli([`./config.invalid-example.json`], __dirname);
expect(out.stderr).toContain("Error: path parameter petId does not seem to be defined in '/pet/{petId}'!");
}, 25000);

test('missing path parameters does fail', async () => {
const out = await cli([`./config.valid-example.ts`], __dirname);
expect(out.stderr).not.toContain("Error: path parameter petId does not seem to be defined in '/pet/{petId}'!");
}, 25000);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { ConfigFile } from 'kahirokunn/kubernetes-typescript-client-codegen-openapi';

const config: ConfigFile = {
schemaFile: './fixtures/invalid-petstore.json',
apiFile: './fixtures/k8sApiClient.ts',
outputFile: './tmp/example.ts',
strict: false,
};

export default config;

0 comments on commit f07a0da

Please sign in to comment.