@travetto/openapi 7.0.0-rc.2 → 7.0.0-rc.3

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/__index__.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from './src/spec-generate.ts';
1
+ export * from './src/generate.ts';
2
2
  export * from './src/service.ts';
3
3
  export * from './src/config.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/openapi",
3
- "version": "7.0.0-rc.2",
3
+ "version": "7.0.0-rc.3",
4
4
  "description": "OpenAPI integration support for the Travetto framework",
5
5
  "keywords": [
6
6
  "web",
@@ -26,14 +26,14 @@
26
26
  "directory": "module/openapi"
27
27
  },
28
28
  "dependencies": {
29
- "@travetto/config": "^7.0.0-rc.1",
30
- "@travetto/schema": "^7.0.0-rc.1",
31
- "@travetto/web": "^7.0.0-rc.2",
29
+ "@travetto/config": "^7.0.0-rc.2",
30
+ "@travetto/schema": "^7.0.0-rc.2",
31
+ "@travetto/web": "^7.0.0-rc.3",
32
32
  "openapi3-ts": "^4.5.0",
33
33
  "yaml": "^2.8.1"
34
34
  },
35
35
  "peerDependencies": {
36
- "@travetto/cli": "^7.0.0-rc.1"
36
+ "@travetto/cli": "^7.0.0-rc.2"
37
37
  },
38
38
  "peerDependenciesMeta": {
39
39
  "@travetto/cli": {
@@ -12,8 +12,8 @@ import { ApiSpecConfig } from './config.ts';
12
12
 
13
13
  const DEFINITION = '#/components/schemas';
14
14
 
15
- const isInputConfig = (val: object): val is SchemaInputConfig => !!val && 'owner' in val && 'type' in val;
16
- const isFieldConfig = (val: object): val is SchemaFieldConfig => isInputConfig(val) && 'name' in val;
15
+ const isInputConfig = (value: object): value is SchemaInputConfig => !!value && 'owner' in value && 'type' in value;
16
+ const isFieldConfig = (value: object): value is SchemaFieldConfig => isInputConfig(value) && 'name' in value;
17
17
 
18
18
  type GeneratedSpec = {
19
19
  tags: TagObject[];
@@ -51,7 +51,7 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
51
51
  const fields = SchemaRegistryIndex.get(input.type).getFields(input.view);
52
52
  const params: ParameterObject[] = [];
53
53
  for (const sub of Object.values(fields)) {
54
- const name = sub.name.toString();
54
+ const name = sub.name;
55
55
  if (SchemaRegistryIndex.has(sub.type)) {
56
56
  const suffix = (sub.array) ? '[]' : '';
57
57
  params.push(...this.#schemaToDotParams(location, sub, prefix ? `${prefix}.${name}${suffix}` : `${name}${suffix}.`, rootField));
@@ -131,48 +131,48 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
131
131
  * Process schema field
132
132
  */
133
133
  #processSchemaField(input: SchemaInputConfig, required: string[]): SchemaObject {
134
- let prop: SchemaObject = this.#getType(input);
134
+ let config: SchemaObject = this.#getType(input);
135
135
 
136
136
  if (input.examples) {
137
- prop.example = input.examples;
137
+ config.example = input.examples;
138
138
  }
139
- prop.description = input.description;
139
+ config.description = input.description;
140
140
  if (input.match) {
141
- prop.pattern = input.match.re!.source;
141
+ config.pattern = input.match.re!.source;
142
142
  }
143
143
  if (input.maxlength) {
144
- prop.maxLength = input.maxlength.n;
144
+ config.maxLength = input.maxlength.n;
145
145
  }
146
146
  if (input.minlength) {
147
- prop.minLength = input.minlength.n;
147
+ config.minLength = input.minlength.n;
148
148
  }
149
149
  if (input.min) {
150
- prop.minimum = typeof input.min.n === 'number' ? input.min.n : input.min.n.getTime();
150
+ config.minimum = typeof input.min.n === 'number' ? input.min.n : input.min.n.getTime();
151
151
  }
152
152
  if (input.max) {
153
- prop.maximum = typeof input.max.n === 'number' ? input.max.n : input.max.n.getTime();
153
+ config.maximum = typeof input.max.n === 'number' ? input.max.n : input.max.n.getTime();
154
154
  }
155
155
  if (input.enum) {
156
- prop.enum = input.enum.values;
156
+ config.enum = input.enum.values;
157
157
  }
158
158
  if (isFieldConfig(input)) {
159
159
  if (input.required?.active !== false) {
160
- required.push(input.name.toString());
160
+ required.push(input.name);
161
161
  }
162
162
  if (input.access === 'readonly') {
163
- prop.readOnly = true;
163
+ config.readOnly = true;
164
164
  } else if (input.access === 'writeonly') {
165
- prop.writeOnly = true;
165
+ config.writeOnly = true;
166
166
  }
167
167
  }
168
168
  if (input.array) {
169
- prop = {
169
+ config = {
170
170
  type: 'array',
171
- items: prop
171
+ items: config
172
172
  };
173
173
  }
174
174
 
175
- return prop;
175
+ return config;
176
176
  }
177
177
 
178
178
  /**
@@ -195,25 +195,25 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
195
195
  };
196
196
 
197
197
  const properties: Record<string, SchemaObject> = {};
198
- const def = config;
198
+ const base = config;
199
199
  const required: string[] = [];
200
200
 
201
- for (const fieldName of Object.keys(def.fields)) {
202
- if (SchemaRegistryIndex.has(def.fields[fieldName].type)) {
203
- this.onSchema(SchemaRegistryIndex.getConfig(def.fields[fieldName].type));
201
+ for (const fieldName of Object.keys(base.fields)) {
202
+ if (SchemaRegistryIndex.has(base.fields[fieldName].type)) {
203
+ this.onSchema(SchemaRegistryIndex.getConfig(base.fields[fieldName].type));
204
204
  }
205
- properties[fieldName] = this.#processSchemaField(def.fields[fieldName], required);
205
+ properties[fieldName] = this.#processSchemaField(base.fields[fieldName], required);
206
206
  }
207
207
 
208
208
  const extra: Record<string, unknown> = {};
209
209
  if (config.discriminatedBase) {
210
- const map = SchemaRegistryIndex.getDiscriminatedClasses(cls);
211
- if (map) {
212
- extra.oneOf = map
213
- .filter(x => !describeFunction(x)?.abstract)
214
- .map(c => {
215
- this.onSchema(SchemaRegistryIndex.getConfig(c));
216
- return this.#getType(c);
210
+ const subClasses = SchemaRegistryIndex.getDiscriminatedClasses(cls);
211
+ if (subClasses) {
212
+ extra.oneOf = subClasses
213
+ .filter(subCls => !describeFunction(subCls)?.abstract)
214
+ .map(subCls => {
215
+ this.onSchema(SchemaRegistryIndex.getConfig(subCls));
216
+ return this.#getType(subCls);
217
217
  });
218
218
  }
219
219
  }
@@ -260,7 +260,7 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
260
260
  /**
261
261
  * Process endpoint parameter
262
262
  */
263
- #processEndpointParam(ep: EndpointConfig, param: EndpointParameterConfig, input: SchemaParameterConfig): (
263
+ #processEndpointParam(endpoint: EndpointConfig, param: EndpointParameterConfig, input: SchemaParameterConfig): (
264
264
  { requestBody: RequestBodyObject } |
265
265
  { parameters: ParameterObject[] } |
266
266
  undefined
@@ -269,7 +269,7 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
269
269
 
270
270
  if (param.location) {
271
271
  if (param.location === 'body') {
272
- const acceptsMime = ep.finalizedResponseHeaders.get('accepts');
272
+ const acceptsMime = endpoint.finalizedResponseHeaders.get('accepts');
273
273
  return {
274
274
  requestBody: input.specifiers?.includes('file') ? this.#buildUploadBody() : this.#getEndpointBody(input, acceptsMime)
275
275
  };
@@ -291,47 +291,47 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
291
291
  /**
292
292
  * Process controller endpoint
293
293
  */
294
- onEndpointEnd(ep: EndpointConfig, ctrl: ControllerConfig): void {
295
- if (this.#config.skipEndpoints || !ep.httpMethod) {
294
+ onEndpointEnd(endpoint: EndpointConfig, controller: ControllerConfig): void {
295
+ if (this.#config.skipEndpoints || !endpoint.httpMethod) {
296
296
  return;
297
297
  }
298
298
 
299
- const tagName = ctrl.externalName;
299
+ const tagName = controller.externalName;
300
300
 
301
- const schema = SchemaRegistryIndex.get(ep.class).getMethod(ep.methodName);
301
+ const schema = SchemaRegistryIndex.get(endpoint.class).getMethod(endpoint.methodName);
302
302
 
303
- const op: OperationObject = {
303
+ const apiConfig: OperationObject = {
304
304
  tags: [tagName],
305
305
  responses: {},
306
306
  summary: schema.description,
307
307
  description: schema.description,
308
- operationId: `${ep.class.name}_${ep.methodName.toString()}`,
308
+ operationId: `${endpoint.class.name}_${endpoint.methodName}`,
309
309
  parameters: []
310
310
  };
311
311
 
312
- const contentTypeMime = ep.finalizedResponseHeaders.get('content-type');
313
- const pConf = this.#getEndpointBody(schema.returnType, contentTypeMime);
314
- const code = Object.keys(pConf.content).length ? 200 : 201;
315
- op.responses![code] = pConf;
312
+ const contentTypeMime = endpoint.finalizedResponseHeaders.get('content-type');
313
+ const bodyConfig = this.#getEndpointBody(schema.returnType, contentTypeMime);
314
+ const code = Object.keys(bodyConfig.content).length ? 200 : 201;
315
+ apiConfig.responses![code] = bodyConfig;
316
316
 
317
- const methodSchema = SchemaRegistryIndex.get(ep.class).getMethod(ep.methodName);
317
+ const methodSchema = SchemaRegistryIndex.get(endpoint.class).getMethod(endpoint.methodName);
318
318
 
319
319
  for (const param of methodSchema.parameters) {
320
- const result = this.#processEndpointParam(ep, ep.parameters[param.index] ?? {}, param);
320
+ const result = this.#processEndpointParam(endpoint, endpoint.parameters[param.index] ?? {}, param);
321
321
  if (result) {
322
322
  if ('parameters' in result) {
323
- (op.parameters ??= []).push(...result.parameters);
323
+ (apiConfig.parameters ??= []).push(...result.parameters);
324
324
  } else {
325
- op.requestBody ??= result.requestBody;
325
+ apiConfig.requestBody ??= result.requestBody;
326
326
  }
327
327
  }
328
328
  }
329
329
 
330
- const key = ep.fullPath.replace(/:([A-Za-z0-9_]+)\b/g, (__, param) => `{${param}}`);
330
+ const key = endpoint.fullPath.replace(/:([A-Za-z0-9_]+)\b/g, (__, param) => `{${param}}`);
331
331
 
332
332
  this.#paths[key] = {
333
333
  ...(this.#paths[key] ?? {}),
334
- [HTTP_METHODS[ep.httpMethod].lower]: op
334
+ [HTTP_METHODS[endpoint.httpMethod].lower]: apiConfig
335
335
  };
336
336
  }
337
337
 
@@ -356,8 +356,8 @@ export class OpenapiVisitor implements ControllerVisitor<GeneratedSpec> {
356
356
  paths: Object.fromEntries(
357
357
  Object.entries(this.#paths)
358
358
  .toSorted(([a], [b]) => a.localeCompare(b))
359
- .map(([k, v]) => [k, Object.fromEntries(
360
- Object.entries(v)
359
+ .map(([key, value]) => [key, Object.fromEntries(
360
+ Object.entries(value)
361
361
  .toSorted(([a], [b]) => a.localeCompare(b))
362
362
  )])
363
363
  ),
package/src/service.ts CHANGED
@@ -8,7 +8,7 @@ import { SchemaRegistryIndex } from '@travetto/schema';
8
8
  import { Registry } from '@travetto/registry';
9
9
 
10
10
  import { ApiHostConfig, ApiInfoConfig, ApiSpecConfig } from './config.ts';
11
- import { OpenapiVisitor } from './spec-generate.ts';
11
+ import { OpenapiVisitor } from './generate.ts';
12
12
 
13
13
  /**
14
14
  * Open API generation service
@@ -82,8 +82,8 @@ export class OpenApiService {
82
82
  stringify(spec);
83
83
 
84
84
  await BinaryUtil.bufferedFileWrite(this.apiSpecConfig.output, output, true);
85
- } catch (err) {
86
- console.error('Unable to persist openapi spec', err);
85
+ } catch (error) {
86
+ console.error('Unable to persist openapi spec', error);
87
87
  }
88
88
  }
89
89
  }
@@ -18,8 +18,8 @@ export class OpenApiClientHelp {
18
18
  .split('DOCUMENTATION')[0]
19
19
  .trim()
20
20
  .split(/\n/g)
21
- .filter(x => /^\s+-/.test(x) && !/\((beta|experimental)\)/.test(x))
22
- .map(x => x.replace(/^\s+-\s+/, '').trim());
21
+ .filter(line => /^\s+-/.test(line) && !/\((beta|experimental)\)/.test(line))
22
+ .map(line => line.replace(/^\s+-\s+/, '').trim());
23
23
 
24
24
  await fs.mkdir(path.dirname(formatCache), { recursive: true });
25
25
  await fs.writeFile(formatCache, JSON.stringify([...lines.toSorted(),]));
@@ -36,7 +36,7 @@ export class OpenApiClientHelp {
36
36
  '',
37
37
  cliTpl`${{ subtitle: 'Available Formats' }}`,
38
38
  '----------------------------------',
39
- ...formats.map(x => cliTpl`* ${{ input: x }}`)
39
+ ...formats.map(format => cliTpl`* ${{ input: format }}`)
40
40
  );
41
41
  }
42
42
  return help;
@@ -16,7 +16,7 @@ export class OpenApiClientCommand implements CliCommandShape {
16
16
  extendedHelp: boolean = false;
17
17
  /** Additional Properties */
18
18
  @CliFlag({ short: '-a', full: '--additional-properties' })
19
- props: string[] = [];
19
+ properties: string[] = [];
20
20
  /** Input file */
21
21
  input = './openapi.yml';
22
22
  /** Output folder */
@@ -32,7 +32,7 @@ export class OpenApiClientCommand implements CliCommandShape {
32
32
  this.output = path.resolve(this.output);
33
33
  this.input = path.resolve(this.input);
34
34
 
35
- const proc = cp.spawn('docker', [
35
+ const subProcess = cp.spawn('docker', [
36
36
  'run',
37
37
  '--rm',
38
38
  '-i',
@@ -47,12 +47,12 @@ export class OpenApiClientCommand implements CliCommandShape {
47
47
  '-g', format,
48
48
  '-o', '/workspace',
49
49
  '-i', `/input/${path.basename(this.input)}`,
50
- ...(this.props.length ? ['--additional-properties', this.props.join(',')] : [])
50
+ ...(this.properties.length ? ['--additional-properties', this.properties.join(',')] : [])
51
51
  ], {
52
52
  stdio: 'inherit'
53
53
  });
54
54
 
55
- const result = await ExecUtil.getResult(proc);
55
+ const result = await ExecUtil.getResult(subProcess);
56
56
 
57
57
  if (!result.valid) {
58
58
  process.exitCode = 1;