fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #409 from hey-api/fix/commonjs-and-esm-support

authored by

Jordan Shatford and committed by
GitHub
ddbda3dd 167bb75a

+126 -121
+5
.changeset/thick-fishes-search.md
··· 1 + --- 2 + "@hey-api/openapi-ts": patch 3 + --- 4 + 5 + fix: revert to generating commonjs for esm and commonjs support
+90
packages/openapi-ts/bin/index.cjs
··· 1 + #!/usr/bin/env node 2 + 3 + 'use strict'; 4 + 5 + const { writeFileSync } = require('fs'); 6 + const { resolve } = require('path'); 7 + 8 + const { program } = require('commander'); 9 + const pkg = require('../package.json'); 10 + 11 + const params = program 12 + .name(Object.keys(pkg.bin)[0]) 13 + .usage('[options]') 14 + .version(pkg.version) 15 + .option('-i, --input <value>', 'OpenAPI specification (path, url, or string content)') 16 + .option('-o, --output <value>', 'Output directory') 17 + .option('-c, --client <value>', 'HTTP client to generate [angular, axios, fetch, node, xhr]') 18 + .option('-d, --debug', 'Run in debug mode?') 19 + .option('--base [value]', 'Manually set base in OpenAPI config instead of inferring from server value') 20 + .option('--dry-run [value]', 'Skip writing files to disk?') 21 + .option('--enums <value>', 'Export enum definitions (javascript, typescript)') 22 + .option('--exportCore [value]', 'Write core files to disk') 23 + .option('--exportServices [value]', 'Write services to disk') 24 + .option('--format [value]', 'Process output folder with formatter?') 25 + .option('--lint [value]', 'Process output folder with linter?') 26 + .option('--name <value>', 'Custom client class name') 27 + .option('--operationId [value]', 'Use operationd ID?') 28 + .option('--postfixServices <value>', 'Service name postfix') 29 + .option('--request <value>', 'Path to custom request file') 30 + .option('--schemas [value]', 'Write schemas to disk') 31 + .option('--serviceResponse [value]', 'Define shape of returned value from service calls') 32 + .option('--types [value]', 'Write types to disk') 33 + .option('--useDateType [value]', 'Output Date instead of string for the format "date-time" in the models') 34 + .option('--useOptions [value]', 'Use options instead of arguments') 35 + .parse(process.argv) 36 + .opts(); 37 + 38 + const stringToBoolean = value => { 39 + if (value === 'true') { 40 + return true; 41 + } 42 + if (value === 'false') { 43 + return false; 44 + } 45 + return value; 46 + }; 47 + 48 + const processParams = (obj, booleanKeys) => { 49 + for (const key of booleanKeys) { 50 + const value = obj[key]; 51 + if (typeof value === 'string') { 52 + const parsedValue = stringToBoolean(value); 53 + delete obj[key]; 54 + obj[key] = parsedValue; 55 + } 56 + } 57 + return obj; 58 + }; 59 + 60 + async function start() { 61 + let userConfig; 62 + try { 63 + const { createClient } = require(resolve(__dirname, '../dist/node/index.cjs')); 64 + userConfig = processParams(params, [ 65 + 'dryRun', 66 + 'exportCore', 67 + 'exportServices', 68 + 'format', 69 + 'lint', 70 + 'operationId', 71 + 'schemas', 72 + 'types', 73 + 'useDateType', 74 + 'useOptions', 75 + ]); 76 + await createClient(userConfig); 77 + process.exit(0); 78 + } catch (error) { 79 + if (!userConfig.dryRun) { 80 + const logName = `openapi-ts-error-${Date.now()}.log`; 81 + const logPath = resolve(process.cwd(), logName); 82 + writeFileSync(logPath, `${error.message}\n${error.stack}`); 83 + console.error(`🔥 Unexpected error occurred. Log saved to ${logPath}`); 84 + } 85 + console.error(`🔥 Unexpected error occurred. ${error.message}`); 86 + process.exit(1); 87 + } 88 + } 89 + 90 + start();
-92
packages/openapi-ts/bin/index.js
··· 1 - #!/usr/bin/env node 2 - 3 - 'use strict'; 4 - 5 - import { readFileSync, writeFileSync } from 'node:fs'; 6 - import path from 'node:path'; 7 - 8 - import camelCase from 'camelcase'; 9 - import { program } from 'commander'; 10 - 11 - const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url)).toString()); 12 - 13 - const params = program 14 - .name(Object.keys(pkg.bin)[0]) 15 - .usage('[options]') 16 - .version(pkg.version) 17 - .option('-i, --input <value>', 'OpenAPI specification (path, url, or string content)') 18 - .option('-o, --output <value>', 'Output directory') 19 - .option('-c, --client <value>', 'HTTP client to generate [angular, axios, fetch, node, xhr]') 20 - .option('-d, --debug', 'Run in debug mode?') 21 - .option('--base [value]', 'Manually set base in OpenAPI config instead of inferring from server value') 22 - .option('--dry-run [value]', 'Skip writing files to disk?') 23 - .option('--enums <value>', 'Export enum definitions (javascript, typescript)') 24 - .option('--exportCore [value]', 'Write core files to disk') 25 - .option('--exportServices [value]', 'Write services to disk') 26 - .option('--format [value]', 'Process output folder with formatter?') 27 - .option('--lint [value]', 'Process output folder with linter?') 28 - .option('--name <value>', 'Custom client class name') 29 - .option('--operationId [value]', 'Use operationd ID?') 30 - .option('--postfixServices <value>', 'Service name postfix') 31 - .option('--request <value>', 'Path to custom request file') 32 - .option('--schemas [value]', 'Write schemas to disk') 33 - .option('--serviceResponse [value]', 'Define shape of returned value from service calls') 34 - .option('--types [value]', 'Write types to disk') 35 - .option('--useDateType [value]', 'Output Date instead of string for the format "date-time" in the models') 36 - .option('--useOptions [value]', 'Use options instead of arguments') 37 - .parse(process.argv) 38 - .opts(); 39 - 40 - const stringToBoolean = value => { 41 - if (value === 'true') { 42 - return true; 43 - } 44 - if (value === 'false') { 45 - return false; 46 - } 47 - return value; 48 - }; 49 - 50 - const processParams = (obj, booleanKeys) => { 51 - for (const key of booleanKeys) { 52 - const value = obj[key]; 53 - if (typeof value === 'string') { 54 - const parsedValue = stringToBoolean(value); 55 - delete obj[key]; 56 - obj[camelCase(key)] = parsedValue; 57 - } 58 - } 59 - return obj; 60 - }; 61 - 62 - async function start() { 63 - let userConfig; 64 - try { 65 - const { createClient } = await import(new URL('../dist/node/index.js', import.meta.url)); 66 - userConfig = processParams(params, [ 67 - 'dryRun', 68 - 'exportCore', 69 - 'exportServices', 70 - 'format', 71 - 'lint', 72 - 'operationId', 73 - 'schemas', 74 - 'types', 75 - 'useDateType', 76 - 'useOptions', 77 - ]); 78 - await createClient(userConfig); 79 - process.exit(0); 80 - } catch (error) { 81 - if (!userConfig.dryRun) { 82 - const logName = `openapi-ts-error-${Date.now()}.log`; 83 - const logPath = path.resolve(process.cwd(), logName); 84 - writeFileSync(logPath, `${error.message}\n${error.stack}`); 85 - console.error(`🔥 Unexpected error occurred. Log saved to ${logPath}`); 86 - } 87 - console.error(`🔥 Unexpected error occurred. ${error.message}`); 88 - process.exit(1); 89 - } 90 - } 91 - 92 - start();
+2 -2
packages/openapi-ts/package.json
··· 27 27 "angular", 28 28 "node" 29 29 ], 30 - "main": "./dist/node/index.js", 30 + "main": "./dist/node/index.cjs", 31 31 "types": "./dist/node/index.d.ts", 32 32 "bin": { 33 - "openapi-ts": "bin/index.js" 33 + "openapi-ts": "bin/index.cjs" 34 34 }, 35 35 "files": [ 36 36 "bin",
+10 -4
packages/openapi-ts/rollup.config.ts
··· 52 52 53 53 const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url)).toString()); 54 54 55 + // ESM only dependencies are not treated as external so that we can fully support CommonJS and ESM 56 + const esmDependencies = ['camelcase']; 57 + 58 + export const externalDependencies = [...Object.keys(pkg.dependencies), ...Object.keys(pkg.peerDependencies)].filter( 59 + dependency => !esmDependencies.includes(dependency) 60 + ); 61 + 55 62 function createConfig(isProduction: boolean) { 56 63 return defineConfig({ 57 - external: [...Object.keys(pkg.dependencies), ...Object.keys(pkg.peerDependencies)], 64 + external: externalDependencies, 58 65 input: path.resolve(__dirname, 'src/node/index.ts'), 59 66 output: { 60 - file: path.resolve(__dirname, 'dist/node/index.js'), 61 - format: 'esm', 67 + file: path.resolve(__dirname, 'dist/node/index.cjs'), 68 + format: 'cjs', 62 69 }, 63 70 plugins: [ 64 71 nodeResolve({ preferBuiltins: true }), ··· 67 74 tsconfig: path.resolve(__dirname, 'src/node/tsconfig.json'), 68 75 }), 69 76 commonjs({ 70 - extensions: ['.js'], 71 77 sourceMap: false, 72 78 }), 73 79 json(),
+3 -7
packages/openapi-ts/rollup.dts.config.ts
··· 1 - import { readFileSync } from 'node:fs'; 2 - 3 1 import { defineConfig } from 'rollup'; 4 2 import dts from 'rollup-plugin-dts'; 5 3 6 - const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url)).toString()); 7 - 8 - const external = [/^node:*/, ...Object.keys(pkg.dependencies), ...Object.keys(pkg.devDependencies)]; 4 + import { externalDependencies } from './rollup.config'; 9 5 10 6 export default defineConfig({ 11 - external, 7 + external: externalDependencies, 12 8 input: { 13 9 index: './temp/node/index.d.ts', 14 10 }, 15 11 output: { 16 12 dir: './dist/node', 17 - format: 'esm', 13 + format: 'cjs', 18 14 }, 19 15 plugins: [dts({ respectExternal: true })], 20 16 });
+16 -16
packages/openapi-ts/test/bin.spec.ts
··· 4 4 describe('bin', () => { 5 5 it('supports required parameters', () => { 6 6 const result = sync('node', [ 7 - './bin/index.js', 7 + './bin/index.cjs', 8 8 '--input', 9 9 './test/spec/v3.json', 10 10 '--output', ··· 19 19 20 20 it('generates angular client', () => { 21 21 const result = sync('node', [ 22 - './bin/index.js', 22 + './bin/index.cjs', 23 23 '--input', 24 24 './test/spec/v3.json', 25 25 '--output', ··· 35 35 36 36 it('generates axios client', () => { 37 37 const result = sync('node', [ 38 - './bin/index.js', 38 + './bin/index.cjs', 39 39 '--input', 40 40 './test/spec/v3.json', 41 41 '--output', ··· 51 51 52 52 it('generates fetch client', () => { 53 53 const result = sync('node', [ 54 - './bin/index.js', 54 + './bin/index.cjs', 55 55 '--input', 56 56 './test/spec/v3.json', 57 57 '--output', ··· 67 67 68 68 it('generates node client', () => { 69 69 const result = sync('node', [ 70 - './bin/index.js', 70 + './bin/index.cjs', 71 71 '--input', 72 72 './test/spec/v3.json', 73 73 '--output', ··· 83 83 84 84 it('generates xhr client', () => { 85 85 const result = sync('node', [ 86 - './bin/index.js', 86 + './bin/index.cjs', 87 87 '--input', 88 88 './test/spec/v3.json', 89 89 '--output', ··· 99 99 100 100 it('supports all parameters', () => { 101 101 const result = sync('node', [ 102 - './bin/index.js', 102 + './bin/index.cjs', 103 103 '--input', 104 104 './test/spec/v3.json', 105 105 '--output', ··· 124 124 125 125 it('supports regexp parameters', () => { 126 126 const result = sync('node', [ 127 - './bin/index.js', 127 + './bin/index.cjs', 128 128 '--input', 129 129 './test/spec/v3.json', 130 130 '--output', ··· 142 142 143 143 it('formats output with Prettier', () => { 144 144 const result = sync('node', [ 145 - './bin/index.js', 145 + './bin/index.cjs', 146 146 '--input', 147 147 './test/spec/v3.json', 148 148 '--output', ··· 154 154 155 155 it('lints output with ESLint', () => { 156 156 const result = sync('node', [ 157 - './bin/index.js', 157 + './bin/index.cjs', 158 158 '--input', 159 159 './test/spec/v3.json', 160 160 '--output', ··· 166 166 }); 167 167 168 168 it('throws error without parameters', () => { 169 - const result = sync('node', ['./bin/index.js', '--dry-run', 'true']); 169 + const result = sync('node', ['./bin/index.cjs', '--dry-run', 'true']); 170 170 expect(result.stdout.toString()).toBe(''); 171 171 expect(result.stderr.toString()).toContain('Unexpected error occurred'); 172 172 }); 173 173 174 174 it('throws error with wrong parameters', () => { 175 175 const result = sync('node', [ 176 - './bin/index.js', 176 + './bin/index.cjs', 177 177 '--input', 178 178 './test/spec/v3.json', 179 179 '--output', ··· 187 187 }); 188 188 189 189 it('displays help', () => { 190 - const result = sync('node', ['./bin/index.js', '--help', '--dry-run', 'true']); 190 + const result = sync('node', ['./bin/index.cjs', '--help', '--dry-run', 'true']); 191 191 expect(result.stdout.toString()).toContain(`Usage: openapi-ts [options]`); 192 192 expect(result.stdout.toString()).toContain(`-i, --input <value>`); 193 193 expect(result.stdout.toString()).toContain(`-o, --output <value>`); ··· 198 198 describe('cli', () => { 199 199 it('handles false booleans', () => { 200 200 const result = sync('node', [ 201 - './bin/index.js', 201 + './bin/index.cjs', 202 202 '--input', 203 203 './test/spec/v3.json', 204 204 '--output', ··· 240 240 241 241 it('handles true booleans', () => { 242 242 const result = sync('node', [ 243 - './bin/index.js', 243 + './bin/index.cjs', 244 244 '--input', 245 245 './test/spec/v3.json', 246 246 '--output', ··· 282 282 283 283 it('handles optional booleans', () => { 284 284 const result = sync('node', [ 285 - './bin/index.js', 285 + './bin/index.cjs', 286 286 '--input', 287 287 './test/spec/v3.json', 288 288 '--output',