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.
Files changed (64) hide show
  1. package/bin/api.js +2 -0
  2. package/dist/bin.d.ts +1 -0
  3. package/dist/bin.d.ts.map +1 -0
  4. package/dist/bin.js +6 -33
  5. package/dist/bin.js.map +1 -0
  6. package/dist/codegen/{language.d.ts → codegenerator.d.ts} +7 -4
  7. package/dist/codegen/codegenerator.d.ts.map +1 -0
  8. package/dist/codegen/{language.js → codegenerator.js} +4 -6
  9. package/dist/codegen/codegenerator.js.map +1 -0
  10. package/dist/codegen/factory.d.ts +7 -0
  11. package/dist/codegen/factory.d.ts.map +1 -0
  12. package/dist/codegen/factory.js +14 -0
  13. package/dist/codegen/factory.js.map +1 -0
  14. package/dist/codegen/languages/typescript/index.d.ts +90 -0
  15. package/dist/codegen/languages/typescript/index.d.ts.map +1 -0
  16. package/dist/codegen/languages/{typescript.js → typescript/index.js} +260 -206
  17. package/dist/codegen/languages/typescript/index.js.map +1 -0
  18. package/dist/codegen/languages/typescript/util.d.ts +1 -0
  19. package/dist/codegen/languages/typescript/util.d.ts.map +1 -0
  20. package/dist/codegen/languages/typescript/util.js +10 -18
  21. package/dist/codegen/languages/typescript/util.js.map +1 -0
  22. package/dist/commands/index.d.ts +1 -0
  23. package/dist/commands/index.d.ts.map +1 -0
  24. package/dist/commands/index.js +4 -8
  25. package/dist/commands/index.js.map +1 -0
  26. package/dist/commands/install.d.ts +1 -0
  27. package/dist/commands/install.d.ts.map +1 -0
  28. package/dist/commands/install.js +52 -67
  29. package/dist/commands/install.js.map +1 -0
  30. package/dist/fetcher.d.ts +1 -0
  31. package/dist/fetcher.d.ts.map +1 -0
  32. package/dist/fetcher.js +12 -17
  33. package/dist/fetcher.js.map +1 -0
  34. package/dist/lib/prompt.d.ts +1 -0
  35. package/dist/lib/prompt.d.ts.map +1 -0
  36. package/dist/lib/prompt.js +4 -9
  37. package/dist/lib/prompt.js.map +1 -0
  38. package/dist/logger.d.ts +1 -0
  39. package/dist/logger.d.ts.map +1 -0
  40. package/dist/logger.js +4 -9
  41. package/dist/logger.js.map +1 -0
  42. package/dist/packageInfo.d.ts +2 -1
  43. package/dist/packageInfo.d.ts.map +1 -0
  44. package/dist/packageInfo.js +3 -5
  45. package/dist/packageInfo.js.map +1 -0
  46. package/dist/storage.d.ts +2 -1
  47. package/dist/storage.d.ts.map +1 -0
  48. package/dist/storage.js +43 -40
  49. package/dist/storage.js.map +1 -0
  50. package/package.json +12 -10
  51. package/src/bin.ts +2 -2
  52. package/src/codegen/{language.ts → codegenerator.ts} +15 -6
  53. package/src/codegen/factory.ts +23 -0
  54. package/src/codegen/languages/{typescript.ts → typescript/index.ts} +269 -203
  55. package/src/commands/index.ts +1 -1
  56. package/src/commands/install.ts +21 -35
  57. package/src/packageInfo.ts +1 -1
  58. package/src/storage.ts +14 -5
  59. package/tsconfig.json +3 -10
  60. package/bin/api +0 -2
  61. package/dist/codegen/index.d.ts +0 -4
  62. package/dist/codegen/index.js +0 -23
  63. package/dist/codegen/languages/typescript.d.ts +0 -111
  64. package/src/codegen/index.ts +0 -31
@@ -1,4 +1,4 @@
1
- import installCommand from './install';
1
+ import installCommand from './install.js';
2
2
 
3
3
  export default {
4
4
  install: installCommand,
@@ -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 codegen from '../codegen';
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 = codegen(language, oas, './openapi.json', identifier);
98
+ const generator = codegenFactory(language, oas, '../openapi.json', identifier);
124
99
  const sdkSource = await generator
125
- .generator()
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.installer(storage);
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(
@@ -1,3 +1,3 @@
1
1
  // This file is automatically updated by the build script.
2
2
  export const PACKAGE_NAME = 'api';
3
- export const PACKAGE_VERSION = '7.0.0-alpha.2';
3
+ export const PACKAGE_VERSION = '7.0.0-alpha.5';
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 = makeDir.sync(path.join(process.cwd(), '.api'));
59
+ Storage.dir = path.join(process.cwd(), '.api');
61
60
 
62
- makeDir.sync(Storage.getAPIsDir());
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", "ES2020"],
8
- "module": "NodeNext",
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
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- require('../dist/bin');
@@ -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;
@@ -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 {};
@@ -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
- }