Skip to content

Commit a3d0dfc

Browse files
committed
feat(cli): normalize variable names for OpenAPI paths
Non-word characters in variable names for OpenAPI paths are not allowed by `@loopback/rest`.
1 parent 4843a1f commit a3d0dfc

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

packages/cli/generators/openapi/spec-helper.js

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,13 @@ function buildMethodSpec(controllerSpec, op, options) {
203203
const pType = mapSchemaType(p.schema, options);
204204
addImportsForType(pType);
205205
comments.push(`@param ${name} ${p.description || ''}`);
206-
return `@param({name: '${p.name}', in: '${p.in}'}) ${name}: ${
206+
207+
// Normalize parameter name to match `\w`
208+
let paramName = p.name;
209+
if (p.in === 'path') {
210+
paramName = paramName.replace(/[^\w]+/g, '_');
211+
}
212+
return `@param({name: '${paramName}', in: '${p.in}'}) ${name}: ${
207213
pType.signature
208214
}`;
209215
});
@@ -285,10 +291,17 @@ function buildMethodSpec(controllerSpec, op, options) {
285291
returnType.signature
286292
}>`;
287293
comments.unshift(op.spec.description || '', '\n');
294+
295+
// Normalize path variable names to alphanumeric characters including the
296+
// underscore (Equivalent to [A-Za-z0-9_]). Please note `@loopback/rest`
297+
// does not allow other characters that don't match `\w`.
298+
const opPath = op.path.replace(/\{[^\}]+\}/g, varName =>
299+
varName.replace(/[^\w\{\}]+/g, '_'),
300+
);
288301
const methodSpec = {
289302
description: op.spec.description,
290303
comments,
291-
decoration: `@operation('${op.verb}', '${op.path}')`,
304+
decoration: `@operation('${op.verb}', '${opPath}')`,
292305
signature,
293306
};
294307
if (op.spec['x-implementation']) {

packages/cli/test/fixtures/openapi/3.0/customer.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ paths:
6969
application/json:
7070
schema:
7171
$ref: '#/components/schemas/Customer'
72-
/customers/{id}:
72+
/customers/{customer-id}:
7373
get:
7474
tags:
7575
- Customer
7676
description: Returns a customer based on a single ID
7777
x-implementation: "return {id: id, 'first-name': 'John', last-name: 'Smith'};"
7878
operationId: find customer by id
7979
parameters:
80-
- name: id
80+
- name: customer-id
8181
in: path
8282
description: ID of customer to fetch
8383
required: true

packages/cli/test/unit/openapi/controller-spec.unit.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ describe('openapi to controllers/models', () => {
5959
comments: [
6060
'Returns a customer based on a single ID',
6161
'\n',
62-
'@param id ID of customer to fetch',
62+
'@param customerId ID of customer to fetch',
6363
'@returns customer response',
6464
],
65-
decoration: "@operation('get', '/customers/{id}')",
65+
decoration: "@operation('get', '/customers/{customer_id}')",
6666
signature:
67-
"async findCustomerById(@param({name: 'id', in: 'path'}) " +
68-
'id: number): Promise<Customer>',
67+
"async findCustomerById(@param({name: 'customer_id', " +
68+
"in: 'path'}) customerId: number): Promise<Customer>",
6969
implementation:
7070
"return {id: id, 'first-name': 'John', last-name: 'Smith'};",
7171
},

0 commit comments

Comments
 (0)