Skip to content

Commit 1f85bef

Browse files
danielsharveytheoomoregbee
authored andcommitted
feat: Improve generateAttributeSchema() attribute handling
Includes: - Add handling of `regex` validation as Swagger `pattern`. - Fix handling of `isInteger`. - Fix handling of description; include both model/collection description **and** other provider Sails/Swagger descriptions. - Fix handling over extra 'annotations' (e.g. autoincrement) which overwrote description.
1 parent e10faa1 commit 1f85bef

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

lib/generators.ts

+23-12
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,25 @@ export const generateSwaggerPath = (path: string): { variables: string[]; path:
4242
* @see https://swagger.io/docs/specification/data-models/
4343
* @param {Record<string, any>} attribute Sails model attribute specification as per `Model.js` file
4444
*/
45-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
46-
export const generateAttributeSchema = (attribute: NameKeyMap<any>): OpenApi.UpdatedSchema => {
45+
export const generateAttributeSchema = (attribute: Sails.AttributeDefinition): OpenApi.UpdatedSchema => {
4746
const ai = attribute || {}, sts = swaggerTypes;
4847

49-
const type = attribute.type || 'string';
50-
const columnType = get(attribute, ['autoMigrations', 'columnType']);
51-
const autoIncrement = get(attribute, ['autoMigrations', 'autoIncrement']);
48+
const type = ai.type || 'string';
49+
const columnType = ai.autoMigrations?.columnType;
50+
const autoIncrement = ai.autoMigrations?.autoIncrement;
5251

5352
let schema: OpenApi.UpdatedSchema = {};
5453

54+
const formatDesc = (extra: string): string => {
55+
const ret: string[] = [];
56+
if(ai.description) ret.push(ai.description);
57+
if(extra) ret.push(extra);
58+
return ret.join(' ');
59+
}
60+
5561
if (ai.model) {
5662
assign(schema, {
57-
description: `JSON dictionary representing the **${ai.model}** instance or FK when creating / updating / not populated`,
63+
description: formatDesc(`JSON dictionary representing the **${ai.model}** instance or FK when creating / updating / not populated`),
5864
// '$ref': '#/components/schemas/' + ai.model,
5965
oneOf: [ // we use oneOf (rather than simple ref) so description rendered (!) (at least in redocly)
6066
{ '$ref': '#/components/schemas/' + ai.model },
@@ -63,14 +69,14 @@ export const generateAttributeSchema = (attribute: NameKeyMap<any>): OpenApi.Upd
6369

6470
} else if (ai.collection) {
6571
assign(schema, {
66-
description: `Array of **${ai.collection}**'s or array of FK's when creating / updating / not populated`,
72+
description: formatDesc(`Array of **${ai.collection}**'s or array of FK's when creating / updating / not populated`),
6773
type: 'array',
6874
items: { '$ref': '#/components/schemas/' + ai.collection },
6975
});
7076

7177
} else if (type == 'number') {
7278
let t = autoIncrement ? sts.integer : sts.double;
73-
if (ai.isInteger) {
79+
if (ai.validations?.isInteger) {
7480
t = sts.integer;
7581
} else if (columnType) {
7682
const ct = columnType;
@@ -106,6 +112,7 @@ export const generateAttributeSchema = (attribute: NameKeyMap<any>): OpenApi.Upd
106112
if (v.isIP) { isIP = true; schema.format = 'ipv4'; }
107113
if (v.isURL) schema.format = 'uri';
108114
if (v.isUUID) schema.format = 'uuid';
115+
if (v.regex) schema.pattern = v.regex.toString().slice(1, -1);
109116
}
110117
}
111118

@@ -129,15 +136,17 @@ export const generateAttributeSchema = (attribute: NameKeyMap<any>): OpenApi.Upd
129136
}
130137

131138
// process final autoMigrations: autoIncrement, unique
132-
if (autoIncrement) annotations.push('autoIncrement');
133-
if (get(attribute, ['autoMigrations', 'unique'])) {
139+
if (autoIncrement) {
140+
annotations.push('autoIncrement');
141+
}
142+
if (ai.autoMigrations?.unique) {
134143
schema.uniqueItems = true;
135144
}
136145

137146
// represent Sails `isIP` as one of ipv4/ipv6
138147
if (schema.type == 'string' && isIP) {
139148
schema = {
140-
description: 'ipv4 or ipv6 address',
149+
description: formatDesc('ipv4 or ipv6 address'),
141150
oneOf: [
142151
cloneDeep(schema),
143152
assign(cloneDeep(schema), { format: 'ipv6' }),
@@ -147,9 +156,11 @@ export const generateAttributeSchema = (attribute: NameKeyMap<any>): OpenApi.Upd
147156

148157
if (annotations.length > 0) {
149158
const s = `Note Sails special attributes: ${annotations.join(', ')}`;
150-
schema.description = schema.description ? `\n\n${s}` : s;
159+
schema.description = schema.description ? `${schema.description}\n\n${s}` : s;
151160
}
152161

162+
if(schema.description) schema.description = schema.description.trim();
163+
153164
// note: required --> required[] (not here, needs to be done at model level)
154165

155166
return schema;

0 commit comments

Comments
 (0)