Skip to content

Commit ecd1080

Browse files
committed
fix(guards): circular dependency
all guard functions defined in the exported index file
1 parent abe073d commit ecd1080

File tree

290 files changed

+4659
-6381
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

290 files changed

+4659
-6381
lines changed

src/generator.ts

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -198,59 +198,26 @@ async function generateModelGuards(
198198
): Promise<string[]> {
199199
const outputDir = join(outputPath, MODEL_GUARDS_DIR_NAME);
200200
const outIndexFile = join(outputDir, '/index.ts');
201-
const outHelpersFile = join(outputDir, '/build-in.guards.ts');
202-
203-
const modelGuardTemplate = (
204-
await promisify(readFile)(
205-
`${__dirname}/../templates/ngx-model-guard.mustache`,
206-
)
207-
).toString();
208201

209202
const modelGuardsExportTemplate = (
210203
await promisify(readFile)(
211204
`${__dirname}/../templates/ngx-model-guards-export.mustache`,
212205
)
213206
).toString();
214207

215-
const modelGuardsHelpersTemplate = (
216-
await promisify(readFile)(
217-
`${__dirname}/../templates/ngx-model-guards-helpers.mustache`,
218-
)
219-
).toString();
220-
221208
if (!existsSync(outputDir)) {
222209
await promisify(mkdir)(outputDir);
223210
}
224211

225-
// generate model guards export index for all the generated models
212+
// generate model guards export index with all the generated guards
226213
await promisify(writeFile)(
227214
outIndexFile,
228215
Mustache.render(modelGuardsExportTemplate, { definitions }),
229216
'utf-8',
230217
);
231218

232-
// generate model guards pre prepared helper guards (for string, number, File, Blob, ...)
233-
await promisify(writeFile)(
234-
outHelpersFile,
235-
Mustache.render(modelGuardsHelpersTemplate, {}),
236-
'utf-8',
237-
);
238-
239219
// generate API models
240-
return Promise.all([
241-
...definitions.map(async definition => {
242-
const result = Mustache.render(modelGuardTemplate, definition);
243-
const outfile = join(
244-
outputDir,
245-
`${fileName(definition.definitionName, 'guard')}.ts`,
246-
);
247-
248-
await ensureDir(dirname(outfile));
249-
await promisify(writeFile)(outfile, result, 'utf-8');
250-
return outfile;
251-
}),
252-
outIndexFile,
253-
]);
220+
return [outIndexFile];
254221
}
255222

256223
async function generateModuleExportIndex(

src/helper.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { FileInfix } from './types';
33

44
export const BASIC_TS_TYPE_REGEX = /\b(?:string|number|integer|boolean|void)\b/;
55
const BUILD_IN_TS_TYPE_REGEX = /^(?:string|number|integer|boolean|null|undefined|any|void|Object|File|Blob)\b/i;
6-
export const BUILD_GUARD_HELPERS_REGEX = /is(string|number|integer|boolean|any|Object|File|Blob)\(/gm;
76

87
export const ADDITIONAL_PROPERTIES_KEY = '[key: string]';
98

src/parser.ts

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
compareStringByKey,
3131
isReference,
3232
ADDITIONAL_PROPERTIES_KEY,
33-
BUILD_GUARD_HELPERS_REGEX,
3433
} from './helper';
3534

3635
interface Parameters {
@@ -90,8 +89,8 @@ export function createMustacheViewModel(
9089
}
9190

9291
export function determineDomain({ schemes, host, basePath }: Swagger): string {
93-
// if the host is defined then try and use a protocol from the swagger file
94-
// otherwise use the current protocol of loaded app
92+
// if the host definition exists then try to use a protocol from the swagger file
93+
// otherwise, use the current protocol of loaded app
9594
const protocol =
9695
host && schemes && schemes.length > 0 ? `${schemes[0]}://` : '//';
9796

@@ -125,7 +124,7 @@ function parseMethods(
125124
return (
126125
supportedMethods.indexOf(methodType.toUpperCase()) !== -1 && // skip unsupported methods
127126
(!swaggerTag || (op.tags && op.tags.includes(swaggerTag)))
128-
); // if tag is defined take only paths including this tag
127+
); // if tag exists take only paths including this tag
129128
})
130129
.map(([methodType, operation]: [string, Operation]) => {
131130
// select the lowest success (code 20x) response
@@ -230,7 +229,7 @@ function parseDefinitions(
230229
({ definitionName }) =>
231230
definitionName === prop.typescriptType,
232231
)
233-
? a // do not parse if type def is already in parsed definitions
232+
? a // do not parse if type def already exists in parsed definitions
234233
: [...a, ...filterByName(prop.typescriptType!, namedDefs)],
235234
[],
236235
),
@@ -312,10 +311,6 @@ function defineEnum(
312311
text: string,
313312
render: Render,
314313
): string => fileName(render(text), 'enum'),
315-
renderFileNameGuard: (): RenderFileName => (
316-
text: string,
317-
render: Render,
318-
): string => fileName(render(text), 'guard'),
319314
};
320315
}
321316

@@ -509,43 +504,17 @@ function defineInterface(schema: Schema, definitionKey: string): Definition {
509504
// filter duplicate imports
510505
.filter((el, i, a) => (i === a.indexOf(el) ? 1 : 0));
511506

512-
const modelGuardImports = modelImports.map(
513-
el => `import { is${el} } from './${fileName(el, 'guard')}';`,
514-
);
515-
516-
const helpersGuardImports = Array.prototype.concat
517-
// tslint:disable-next-line:no-array-mutation
518-
.apply(
519-
[],
520-
properties.map(
521-
({ guard = '' }) => guard.match(BUILD_GUARD_HELPERS_REGEX) || [],
522-
),
523-
)
524-
.sort()
525-
.filter((guardHelper, index, self) =>
526-
index > 0 ? guardHelper !== self[index - 1] : true,
527-
)
528-
.map(
529-
guardHelper =>
530-
`import { ${guardHelper.slice(0, -1)} } from './build-in.guards';`,
531-
);
532-
533507
return {
534508
definitionName: name,
535509
description: replaceNewLines(schema.description, '$1 * '),
536510
properties: properties,
537511
imports: modelImports,
538-
guardImports: [...modelGuardImports, ...helpersGuardImports],
539512
isEnum: false,
540513
extend: extendInterface,
541514
renderFileName: (): RenderFileName => (
542515
text: string,
543516
render: Render,
544517
): string => fileName(render(text), 'model'),
545-
renderFileNameGuard: (): RenderFileName => (
546-
text: string,
547-
render: Render,
548-
): string => fileName(render(text), 'guard'),
549518
};
550519
}
551520

@@ -692,7 +661,7 @@ function determineParamType(
692661
case 'query' || 'modelbinding':
693662
return { isQueryParameter: true };
694663
default:
695-
logWarn(`Unsupported parameter type [ ${paramType} ]`);
664+
logWarn(`Unsupported parameter type [ ${paramType} ]`);
696665
return {};
697666
}
698667
}

src/types.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@ export interface Definition {
77
readonly definitionName: string;
88
readonly properties: Property[];
99
readonly imports: string[];
10-
readonly guardImports?: string[];
1110
readonly extend?: string;
1211
readonly description?: string;
1312
readonly isEnum?: boolean;
1413
readonly isNumeric?: boolean; // used for determining if string or numeric enum should be generated
1514
renderFileName(): RenderFileName; // generate dash-case file names to templates
16-
renderFileNameGuard(): RenderFileName; // generate dash-case file names to templates
1715
}
1816

1917
export interface MustacheData {
@@ -43,7 +41,7 @@ export type In =
4341
| 'header'
4442
| 'formData';
4543
export type MethodType = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
46-
export type FileInfix = 'model' | 'enum' | 'service' | 'interface' | 'guard';
44+
export type FileInfix = 'model' | 'enum' | 'service' | 'interface';
4745

4846
export interface Property {
4947
readonly camelCaseName?: string;

templates/ngx-model-guard.mustache

Lines changed: 0 additions & 38 deletions
This file was deleted.

templates/ngx-model-guards-export.mustache

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,69 @@
11
/* tslint:disable */
22

3+
import * as models from '../models';
4+
5+
/* pre-prepared guards for build in complex types */
6+
7+
export function isany(_: any): _ is any {
8+
return true;
9+
}
10+
11+
export function isstring(arg: any): arg is string {
12+
return typeof arg === 'string';
13+
}
14+
15+
export function isnumber(arg: any): arg is number {
16+
return typeof arg === 'number';
17+
}
18+
19+
export function isboolean(arg: any): arg is boolean {
20+
return typeof arg === 'boolean';
21+
}
22+
23+
export function isObject(arg: any): arg is any {
24+
return typeof arg === 'object';
25+
}
26+
27+
export function isBlob(arg: any): arg is Blob {
28+
return arg != null && typeof arg.size === 'number' && typeof arg.type === 'string' && typeof arg.slice === 'function';
29+
}
30+
31+
export function isFile(arg: any): arg is File {
32+
return arg != null && typeof arg.lastModified === 'number' && typeof arg.name === 'string' && isBlob(arg);
33+
}
34+
35+
/* generated type guards */
36+
337
{{#definitions}}
4-
export { is{{definitionName}} } from './{{#renderFileNameGuard}}{{definitionName}}{{/renderFileNameGuard}}';
38+
{{^isEnum}}
39+
export function is{{&definitionName}}(arg: any): arg is models.{{&definitionName}} {
40+
return (
41+
arg != null &&
42+
typeof arg === 'object' &&
43+
{{#properties}}
44+
// {{&name}}{{^isRequired}}?{{/isRequired}}: {{#isDictionary}}{ [key: string]: {{&typescriptType}} }{{/isDictionary}}{{^isDictionary}}{{&typescriptType}}{{/isDictionary}}{{#isArray}}[]{{/isArray}}
45+
{{&guard}}
46+
{{/properties}}
47+
{{#extend}}
48+
// extends {{&.}}
49+
is{{&.}}(arg) &&
50+
{{/extend}}
51+
52+
true
53+
);
54+
}
55+
56+
{{/isEnum}}{{#isEnum}}
57+
import {
58+
{{&definitionName}},
59+
} from '../models';
60+
61+
export function is{{&definitionName}}(arg: any): arg is {{&definitionName}} {
62+
return false
63+
{{#properties}} || arg === {{&definitionName}}.{{name}}
64+
{{/properties}};
65+
}
66+
67+
{{/isEnum}}
568
{{/definitions}}
669

7-
/* build in guard helpers */
8-
export * from './build-in.guards';

templates/ngx-model-guards-helpers.mustache

Lines changed: 0 additions & 31 deletions
This file was deleted.

tests/custom/api/guards/build-in.guards.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

tests/custom/api/guards/cat.guard.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)