api 7.0.0-alpha.2 → 7.0.0-alpha.5
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/bin/api.js +2 -0
- package/dist/bin.d.ts +1 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +6 -33
- package/dist/bin.js.map +1 -0
- package/dist/codegen/{language.d.ts → codegenerator.d.ts} +7 -4
- package/dist/codegen/codegenerator.d.ts.map +1 -0
- package/dist/codegen/{language.js → codegenerator.js} +4 -6
- package/dist/codegen/codegenerator.js.map +1 -0
- package/dist/codegen/factory.d.ts +7 -0
- package/dist/codegen/factory.d.ts.map +1 -0
- package/dist/codegen/factory.js +14 -0
- package/dist/codegen/factory.js.map +1 -0
- package/dist/codegen/languages/typescript/index.d.ts +90 -0
- package/dist/codegen/languages/typescript/index.d.ts.map +1 -0
- package/dist/codegen/languages/{typescript.js → typescript/index.js} +260 -206
- package/dist/codegen/languages/typescript/index.js.map +1 -0
- package/dist/codegen/languages/typescript/util.d.ts +1 -0
- package/dist/codegen/languages/typescript/util.d.ts.map +1 -0
- package/dist/codegen/languages/typescript/util.js +10 -18
- package/dist/codegen/languages/typescript/util.js.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +4 -8
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +52 -67
- package/dist/commands/install.js.map +1 -0
- package/dist/fetcher.d.ts +1 -0
- package/dist/fetcher.d.ts.map +1 -0
- package/dist/fetcher.js +12 -17
- package/dist/fetcher.js.map +1 -0
- package/dist/lib/prompt.d.ts +1 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +4 -9
- package/dist/lib/prompt.js.map +1 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +4 -9
- package/dist/logger.js.map +1 -0
- package/dist/packageInfo.d.ts +2 -1
- package/dist/packageInfo.d.ts.map +1 -0
- package/dist/packageInfo.js +3 -5
- package/dist/packageInfo.js.map +1 -0
- package/dist/storage.d.ts +2 -1
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +43 -40
- package/dist/storage.js.map +1 -0
- package/package.json +12 -10
- package/src/bin.ts +2 -2
- package/src/codegen/{language.ts → codegenerator.ts} +15 -6
- package/src/codegen/factory.ts +23 -0
- package/src/codegen/languages/{typescript.ts → typescript/index.ts} +269 -203
- package/src/commands/index.ts +1 -1
- package/src/commands/install.ts +21 -35
- package/src/packageInfo.ts +1 -1
- package/src/storage.ts +14 -5
- package/tsconfig.json +3 -10
- package/bin/api +0 -2
- package/dist/codegen/index.d.ts +0 -4
- package/dist/codegen/index.js +0 -23
- package/dist/codegen/languages/typescript.d.ts +0 -111
- package/src/codegen/index.ts +0 -31
package/src/commands/index.ts
CHANGED
package/src/commands/install.ts
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import type { SupportedLanguages } from '../codegen';
|
|
2
|
-
|
|
3
1
|
import { Command, Option } from 'commander';
|
|
4
2
|
import figures from 'figures';
|
|
5
3
|
import Oas from 'oas';
|
|
6
4
|
import ora from 'ora';
|
|
7
5
|
|
|
8
|
-
import
|
|
9
|
-
import Fetcher from '../fetcher';
|
|
10
|
-
import promptTerminal from '../lib/prompt';
|
|
11
|
-
import logger from '../logger';
|
|
12
|
-
import Storage from '../storage';
|
|
6
|
+
import codegenFactory, { SupportedLanguages } from '../codegen/factory.js';
|
|
7
|
+
import Fetcher from '../fetcher.js';
|
|
8
|
+
import promptTerminal from '../lib/prompt.js';
|
|
9
|
+
import logger from '../logger.js';
|
|
10
|
+
import Storage from '../storage.js';
|
|
13
11
|
|
|
14
12
|
// @todo log logs to `.api/.logs` and have `.logs` ignored
|
|
15
13
|
const cmd = new Command();
|
|
@@ -19,12 +17,7 @@ cmd
|
|
|
19
17
|
.argument('<uri>', 'an API to install')
|
|
20
18
|
.option('-i, --identifier <identifier>', 'API identifier (eg. `@api/petstore`)')
|
|
21
19
|
.addOption(
|
|
22
|
-
new Option('-l, --lang <language>', 'SDK language').choices([
|
|
23
|
-
'js', // User generally wants JS, we'll prompt if they want CJS or ESM files.
|
|
24
|
-
'js-cjs',
|
|
25
|
-
'js-esm',
|
|
26
|
-
'ts',
|
|
27
|
-
]),
|
|
20
|
+
new Option('-l, --lang <language>', 'SDK language').default(SupportedLanguages.JS).choices([SupportedLanguages.JS]),
|
|
28
21
|
)
|
|
29
22
|
.addOption(new Option('-y, --yes', 'Automatically answer "yes" to any prompts printed'))
|
|
30
23
|
.action(async (uri: string, options: { identifier?: string; lang: string; yes?: boolean }) => {
|
|
@@ -36,29 +29,11 @@ cmd
|
|
|
36
29
|
type: 'select',
|
|
37
30
|
name: 'value',
|
|
38
31
|
message: 'What language would you like to generate an SDK for?',
|
|
39
|
-
choices: [
|
|
40
|
-
{ title: 'TypeScript', value: 'ts' },
|
|
41
|
-
{ title: 'JavaScript', value: 'js' },
|
|
42
|
-
],
|
|
32
|
+
choices: [{ title: 'JavaScript', value: SupportedLanguages.JS }],
|
|
43
33
|
initial: 1,
|
|
44
34
|
}));
|
|
45
35
|
}
|
|
46
36
|
|
|
47
|
-
// Because our TS generation outputs raw TS source files we don't need to worry about CJS/ESM.
|
|
48
|
-
if (language === 'js') {
|
|
49
|
-
({ value: language } = await promptTerminal({
|
|
50
|
-
type: 'select',
|
|
51
|
-
name: 'value',
|
|
52
|
-
message: 'How are your project imports and exports structured?',
|
|
53
|
-
choices: [
|
|
54
|
-
{ title: 'CommonJS', description: 'require/exports', value: 'cjs' },
|
|
55
|
-
{ title: 'ECMAScript Modules', description: 'import/export', value: 'esm' },
|
|
56
|
-
],
|
|
57
|
-
initial: 0,
|
|
58
|
-
format: sel => (sel === 'cjs' ? 'js-cjs' : 'js-esm'),
|
|
59
|
-
}));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
37
|
// @todo let them know that we're going to be creating a `.api/ directory
|
|
63
38
|
// @todo detect if they have a gitigore and .npmignore and if .api woudl be ignored by that
|
|
64
39
|
// @todo don't support swagger files without upconverting them
|
|
@@ -120,9 +95,9 @@ cmd
|
|
|
120
95
|
|
|
121
96
|
// @todo look for a prettier config and if we find one ask them if we should use it
|
|
122
97
|
spinner = ora('Generating your SDK').start();
|
|
123
|
-
const generator =
|
|
98
|
+
const generator = codegenFactory(language, oas, '../openapi.json', identifier);
|
|
124
99
|
const sdkSource = await generator
|
|
125
|
-
.
|
|
100
|
+
.generate()
|
|
126
101
|
.then(res => {
|
|
127
102
|
spinner.succeed(spinner.text);
|
|
128
103
|
return res;
|
|
@@ -170,7 +145,7 @@ cmd
|
|
|
170
145
|
|
|
171
146
|
spinner = ora('Installing required packages').start();
|
|
172
147
|
try {
|
|
173
|
-
await generator.
|
|
148
|
+
await generator.install(storage);
|
|
174
149
|
spinner.succeed(spinner.text);
|
|
175
150
|
} catch (err) {
|
|
176
151
|
// @todo cleanup installed files
|
|
@@ -180,6 +155,17 @@ cmd
|
|
|
180
155
|
}
|
|
181
156
|
}
|
|
182
157
|
|
|
158
|
+
spinner = ora('Compiling your SDK').start();
|
|
159
|
+
try {
|
|
160
|
+
await generator.compile(storage);
|
|
161
|
+
spinner.succeed(spinner.text);
|
|
162
|
+
} catch (err) {
|
|
163
|
+
// @todo cleanup installed files
|
|
164
|
+
spinner.fail(spinner.text);
|
|
165
|
+
logger(err.message, true);
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
|
|
183
169
|
logger('🚀 All done!');
|
|
184
170
|
})
|
|
185
171
|
.addHelpText(
|
package/src/packageInfo.ts
CHANGED
package/src/storage.ts
CHANGED
|
@@ -3,12 +3,11 @@ import type { OASDocument } from 'oas/rmoas.types';
|
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
|
-
import makeDir from 'make-dir';
|
|
7
6
|
import ssri from 'ssri';
|
|
8
7
|
import validateNPMPackageName from 'validate-npm-package-name';
|
|
9
8
|
|
|
10
|
-
import Fetcher from './fetcher';
|
|
11
|
-
import { PACKAGE_VERSION } from './packageInfo';
|
|
9
|
+
import Fetcher from './fetcher.js';
|
|
10
|
+
import { PACKAGE_VERSION } from './packageInfo.js';
|
|
12
11
|
|
|
13
12
|
export default class Storage {
|
|
14
13
|
static dir: string;
|
|
@@ -57,9 +56,10 @@ export default class Storage {
|
|
|
57
56
|
return;
|
|
58
57
|
}
|
|
59
58
|
|
|
60
|
-
Storage.dir =
|
|
59
|
+
Storage.dir = path.join(process.cwd(), '.api');
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
fs.mkdirSync(Storage.dir, { recursive: true });
|
|
62
|
+
fs.mkdirSync(Storage.getAPIsDir(), { recursive: true });
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -194,6 +194,15 @@ export default class Storage {
|
|
|
194
194
|
Object.entries(files).forEach(([fileName, contents]) => {
|
|
195
195
|
const sourceFilePath = path.join(this.getIdentifierStorageDir(), fileName);
|
|
196
196
|
|
|
197
|
+
// If this file is stored in a subdirectory then we need to create it.
|
|
198
|
+
if (path.dirname(fileName) !== '.') {
|
|
199
|
+
const dir = path.dirname(fileName);
|
|
200
|
+
const dirPath = path.join(this.getIdentifierStorageDir(), dir);
|
|
201
|
+
if (!fs.existsSync(dirPath)) {
|
|
202
|
+
fs.mkdirSync(dirPath);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
197
206
|
fs.writeFileSync(sourceFilePath, contents);
|
|
198
207
|
|
|
199
208
|
savedSource.push(sourceFilePath);
|
package/tsconfig.json
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
+
"extends": "../../tsconfig.base.json",
|
|
2
3
|
"compilerOptions": {
|
|
3
|
-
"allowJs": true,
|
|
4
|
-
"baseUrl": "./src",
|
|
5
|
-
"declaration": true,
|
|
6
4
|
"esModuleInterop": true,
|
|
7
|
-
"lib": ["DOM", "DOM.Iterable", "
|
|
8
|
-
"
|
|
9
|
-
"noImplicitAny": true,
|
|
10
|
-
"outDir": "dist/",
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"strict": true,
|
|
13
|
-
"useUnknownInCatchVariables": false
|
|
5
|
+
"lib": ["DOM", "DOM.Iterable", "ES2023"],
|
|
6
|
+
"outDir": "dist/"
|
|
14
7
|
},
|
|
15
8
|
"include": ["./src/**/*"]
|
|
16
9
|
}
|
package/bin/api
DELETED
package/dist/codegen/index.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type CodeGeneratorLanguage from './language';
|
|
2
|
-
import type Oas from 'oas';
|
|
3
|
-
export type SupportedLanguages = 'js' | 'js-cjs' | 'js-esm' | 'ts';
|
|
4
|
-
export default function codegen(language: SupportedLanguages, spec: Oas, specPath: string, identifier: string): CodeGeneratorLanguage;
|
package/dist/codegen/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const typescript_1 = __importDefault(require("./languages/typescript"));
|
|
7
|
-
function codegen(language, spec, specPath, identifier) {
|
|
8
|
-
switch (language) {
|
|
9
|
-
case 'js':
|
|
10
|
-
throw new TypeError('An export format of CommonJS or ECMAScript is required for JavaScript compilation.');
|
|
11
|
-
case 'js-cjs':
|
|
12
|
-
case 'js-esm':
|
|
13
|
-
case 'ts':
|
|
14
|
-
return new typescript_1.default(spec, specPath, identifier, {
|
|
15
|
-
outputJS: ['js-cjs', 'js-esm'].includes(language),
|
|
16
|
-
// TS will always generate with ESM-like exports.
|
|
17
|
-
compilerTarget: language === 'js-cjs' ? 'cjs' : 'esm',
|
|
18
|
-
});
|
|
19
|
-
default:
|
|
20
|
-
throw new TypeError(`Unsupported language supplied: ${language}`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
exports.default = codegen;
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import type Storage from '../../storage';
|
|
2
|
-
import type { InstallerOptions } from '../language';
|
|
3
|
-
import type Oas from 'oas';
|
|
4
|
-
import type Operation from 'oas/operation';
|
|
5
|
-
import type { HttpMethods, SchemaObject } from 'oas/rmoas.types';
|
|
6
|
-
import type { ClassDeclaration, JSDocStructure, JSDocTagStructure, OptionalKind } from 'ts-morph';
|
|
7
|
-
import { Project } from 'ts-morph';
|
|
8
|
-
import CodeGeneratorLanguage from '../language';
|
|
9
|
-
export interface TSGeneratorOptions {
|
|
10
|
-
compilerTarget?: 'cjs' | 'esm';
|
|
11
|
-
outputJS?: boolean;
|
|
12
|
-
}
|
|
13
|
-
interface OperationTypeHousing {
|
|
14
|
-
operation: Operation;
|
|
15
|
-
types: {
|
|
16
|
-
params?: false | Record<'body' | 'formData' | 'metadata', string>;
|
|
17
|
-
responses?: Record<string | number, {
|
|
18
|
-
description?: string;
|
|
19
|
-
type: string;
|
|
20
|
-
}>;
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
export default class TSGenerator extends CodeGeneratorLanguage {
|
|
24
|
-
project: Project;
|
|
25
|
-
outputJS: boolean;
|
|
26
|
-
compilerTarget: 'cjs' | 'esm';
|
|
27
|
-
types: Map<string, string>;
|
|
28
|
-
sdk: ClassDeclaration;
|
|
29
|
-
schemas: Record<string, {
|
|
30
|
-
body?: unknown;
|
|
31
|
-
metadata?: unknown;
|
|
32
|
-
response?: Record<string, unknown>;
|
|
33
|
-
} | Record<string, unknown>>;
|
|
34
|
-
usesHTTPMethodRangeInterface: boolean;
|
|
35
|
-
constructor(spec: Oas, specPath: string, identifier: string, opts?: TSGeneratorOptions);
|
|
36
|
-
installer(storage: Storage, opts?: InstallerOptions): Promise<void>;
|
|
37
|
-
/**
|
|
38
|
-
* Compile the current OpenAPI definition into a TypeScript library.
|
|
39
|
-
*
|
|
40
|
-
*/
|
|
41
|
-
generator(): Promise<{
|
|
42
|
-
[x: string]: string;
|
|
43
|
-
}>;
|
|
44
|
-
/**
|
|
45
|
-
* Create our main SDK source file.
|
|
46
|
-
*
|
|
47
|
-
*/
|
|
48
|
-
createSourceFile(): import("ts-morph").SourceFile;
|
|
49
|
-
/**
|
|
50
|
-
* Create our main schemas file. This is where all of the JSON Schema that our TypeScript typing
|
|
51
|
-
* infrastructure sources its data from. Without this there are no types.
|
|
52
|
-
*
|
|
53
|
-
*/
|
|
54
|
-
createSchemasFile(): import("ts-morph").SourceFile;
|
|
55
|
-
/**
|
|
56
|
-
* Create our main types file. This sources its data from the JSON Schema `schemas.ts` file and
|
|
57
|
-
* will re-export types to be used in TypeScript implementations and IDE intellisense. This
|
|
58
|
-
* typing work is functional with the `json-schema-to-ts` library.
|
|
59
|
-
*
|
|
60
|
-
* @see {@link https://npm.im/json-schema-to-ts}
|
|
61
|
-
*/
|
|
62
|
-
createTypesFile(): import("ts-morph").SourceFile;
|
|
63
|
-
/**
|
|
64
|
-
* Add a new JSDoc `@tag` to an existing docblock.
|
|
65
|
-
*
|
|
66
|
-
*/
|
|
67
|
-
static addTagToDocblock(docblock: OptionalKind<JSDocStructure>, tag: OptionalKind<JSDocTagStructure>): {
|
|
68
|
-
tags: OptionalKind<JSDocTagStructure>[];
|
|
69
|
-
description?: string | import("ts-morph").WriterFunction | undefined;
|
|
70
|
-
leadingTrivia?: string | import("ts-morph").WriterFunction | (string | import("ts-morph").WriterFunction)[] | undefined;
|
|
71
|
-
trailingTrivia?: string | import("ts-morph").WriterFunction | (string | import("ts-morph").WriterFunction)[] | undefined;
|
|
72
|
-
kind?: import("ts-morph").StructureKind.JSDoc | undefined;
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Create operation accessors on the SDK.
|
|
76
|
-
*
|
|
77
|
-
*/
|
|
78
|
-
createOperationAccessor(operation: Operation, operationId: string, paramTypes?: OperationTypeHousing['types']['params'], responseTypes?: OperationTypeHousing['types']['responses']): void;
|
|
79
|
-
/**
|
|
80
|
-
* Scour through the current OpenAPI definition and compile a store of every operation, along
|
|
81
|
-
* with every HTTP method that's in use, and their available TypeScript types that we can use,
|
|
82
|
-
* along with every HTTP method that's in use.
|
|
83
|
-
*
|
|
84
|
-
*/
|
|
85
|
-
loadOperationsAndMethods(): {
|
|
86
|
-
operations: Record<string, OperationTypeHousing>;
|
|
87
|
-
methods: Set<HttpMethods>;
|
|
88
|
-
};
|
|
89
|
-
/**
|
|
90
|
-
* Compile the parameter (path, query, cookie, and header) schemas for an API operation into
|
|
91
|
-
* usable TypeScript types.
|
|
92
|
-
*
|
|
93
|
-
*/
|
|
94
|
-
prepareParameterTypesForOperation(operation: Operation, operationId: string): false | Record<"body" | "formData" | "metadata", string>;
|
|
95
|
-
/**
|
|
96
|
-
* Compile the response schemas for an API operation into usable TypeScript types.
|
|
97
|
-
*
|
|
98
|
-
*/
|
|
99
|
-
prepareResponseTypesForOperation(operation: Operation, operationId: string): {
|
|
100
|
-
[x: string]: {
|
|
101
|
-
type: string;
|
|
102
|
-
description: any;
|
|
103
|
-
};
|
|
104
|
-
} | undefined;
|
|
105
|
-
/**
|
|
106
|
-
* Add a given schema into our schema dataset that we'll be be exporting as types.
|
|
107
|
-
*
|
|
108
|
-
*/
|
|
109
|
-
addSchemaToExport(schema: SchemaObject, typeName: string, pointer: string): void;
|
|
110
|
-
}
|
|
111
|
-
export {};
|
package/src/codegen/index.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import type CodeGeneratorLanguage from './language';
|
|
2
|
-
import type Oas from 'oas';
|
|
3
|
-
|
|
4
|
-
import TSGenerator from './languages/typescript';
|
|
5
|
-
|
|
6
|
-
export type SupportedLanguages = 'js' | 'js-cjs' | 'js-esm' | 'ts';
|
|
7
|
-
|
|
8
|
-
export default function codegen(
|
|
9
|
-
language: SupportedLanguages,
|
|
10
|
-
spec: Oas,
|
|
11
|
-
specPath: string,
|
|
12
|
-
identifier: string,
|
|
13
|
-
): CodeGeneratorLanguage {
|
|
14
|
-
switch (language) {
|
|
15
|
-
case 'js':
|
|
16
|
-
throw new TypeError('An export format of CommonJS or ECMAScript is required for JavaScript compilation.');
|
|
17
|
-
|
|
18
|
-
case 'js-cjs':
|
|
19
|
-
case 'js-esm':
|
|
20
|
-
case 'ts':
|
|
21
|
-
return new TSGenerator(spec, specPath, identifier, {
|
|
22
|
-
outputJS: ['js-cjs', 'js-esm'].includes(language),
|
|
23
|
-
|
|
24
|
-
// TS will always generate with ESM-like exports.
|
|
25
|
-
compilerTarget: language === 'js-cjs' ? 'cjs' : 'esm',
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
default:
|
|
29
|
-
throw new TypeError(`Unsupported language supplied: ${language}`);
|
|
30
|
-
}
|
|
31
|
-
}
|