Skip to content

Commit d63fd60

Browse files
authored
refactor: use Integer type from io-ts (#84)
BREAKING CHANGE: removed empty utils file
1 parent ff937aa commit d63fd60

File tree

12 files changed

+33
-100
lines changed

12 files changed

+33
-100
lines changed

src/language/typescript/2.0/serializers/items-object.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { ItemsObject } from '../../../../schema/2.0/items-object';
22
import {
33
getSerializedArrayType,
4-
getSerializedIntegerType,
54
getSerializedStringType,
65
SERIALIZED_BOOLEAN_TYPE,
6+
SERIALIZED_INTEGER_TYPE,
77
SERIALIZED_NUMBER_TYPE,
88
SerializedType,
99
} from '../../common/data/serialized-type';
1010
import { Ref } from '../../../../utils/ref';
11-
import { utilsRef } from '../../common/bundled/utils';
1211
import { pipe } from 'fp-ts/lib/pipeable';
1312
import { either } from 'fp-ts';
1413
import { Either, right } from 'fp-ts/lib/Either';
@@ -28,10 +27,7 @@ export const serializeItemsObject = (from: Ref, itemsObject: ItemsObject): Eithe
2827
return right(SERIALIZED_NUMBER_TYPE);
2928
}
3029
case 'integer': {
31-
return pipe(
32-
utilsRef,
33-
either.map(utilsRef => getSerializedIntegerType(from, utilsRef)),
34-
);
30+
return right(SERIALIZED_INTEGER_TYPE);
3531
}
3632
case 'boolean': {
3733
return right(SERIALIZED_BOOLEAN_TYPE);

src/language/typescript/2.0/serializers/parameter-object.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { Ref } from '../../../../utils/ref';
22
import { ParameterObject } from '../../../../schema/2.0/parameter-object';
33
import {
44
getSerializedArrayType,
5-
getSerializedIntegerType,
65
getSerializedStringType,
76
SERIALIZED_BOOLEAN_TYPE,
7+
SERIALIZED_INTEGER_TYPE,
88
SERIALIZED_NUMBER_TYPE,
99
SERIALIZED_UNKNOWN_TYPE,
1010
} from '../../common/data/serialized-type';
@@ -15,7 +15,6 @@ import { fromSerializedType, SerializedParameter } from '../../common/data/seria
1515
import { pipe } from 'fp-ts/lib/pipeable';
1616
import { either, option } from 'fp-ts';
1717
import { constFalse } from 'fp-ts/lib/function';
18-
import { utilsRef } from '../../common/bundled/utils';
1918

2019
export const serializeParameterObject = (
2120
from: Ref,
@@ -35,10 +34,7 @@ export const serializeParameterObject = (
3534
return right(toSerializedParameter(SERIALIZED_NUMBER_TYPE));
3635
}
3736
case 'integer': {
38-
return pipe(
39-
utilsRef,
40-
either.map(utilsRef => toSerializedParameter(getSerializedIntegerType(from, utilsRef))),
41-
);
37+
return right(toSerializedParameter(SERIALIZED_INTEGER_TYPE));
4238
}
4339
case 'boolean': {
4440
return right(toSerializedParameter(SERIALIZED_BOOLEAN_TYPE));

src/language/typescript/2.0/serializers/schema-object.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import {
1313
getSerializedIntersectionType,
1414
getSerializedEnumType,
1515
SERIALIZED_NULL_TYPE,
16-
getSerializedIntegerType,
1716
getSerializedStringType,
17+
SERIALIZED_INTEGER_TYPE,
1818
} from '../../common/data/serialized-type';
1919
import { serializedDependency } from '../../common/data/serialized-dependency';
2020
import {
@@ -33,7 +33,6 @@ import { either, option, record } from 'fp-ts';
3333
import { traverseNEAEither } from '../../../../utils/either';
3434
import { ReferenceObject, ReferenceObjectCodec } from '../../../../schema/2.0/reference-object';
3535
import { NonEmptyArray } from 'fp-ts/lib/NonEmptyArray';
36-
import { utilsRef } from '../../common/bundled/utils';
3736

3837
export const serializeSchemaObject = (from: Ref, schema: SchemaObject): Either<Error, SerializedType> =>
3938
serializeSchemaObjectWithRecursion(from, schema, true);
@@ -149,10 +148,7 @@ const serializePrimitive = (from: Ref, schemaObject: PrimitiveSchemaObject): Eit
149148
return right(SERIALIZED_NUMBER_TYPE);
150149
}
151150
case 'integer': {
152-
return pipe(
153-
utilsRef,
154-
either.map(utilsRef => getSerializedIntegerType(from, utilsRef)),
155-
);
151+
return right(SERIALIZED_INTEGER_TYPE);
156152
}
157153
case 'boolean': {
158154
return right(SERIALIZED_BOOLEAN_TYPE);

src/language/typescript/2.0/serializers/swagger-object.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { clientFile } from '../../common/bundled/client';
1212
import { serializeParametersDefinitionsObject } from './parameters-definitions-object';
1313
import { combineReader } from '@devexperts/utils/dist/adt/reader.utils';
1414
import { serializeResponsesDefinitionsObject } from './responses-definitions-object';
15-
import { utilsFile } from '../../common/bundled/utils';
1615

1716
const definitionsRef = fromString('#/definitions');
1817
const parametersRef = fromString('#/parameters');
@@ -57,8 +56,8 @@ export const serializeSwaggerObject = combineReader(
5756
pathsRef,
5857
either.chain(from => serializePaths(from, swaggerObject.paths)),
5958
);
60-
return combineEither(additional, paths, clientFile, utilsFile, (additional, paths, clientFile, utilsFile) =>
61-
directory(name, [clientFile, utilsFile, ...additional, paths]),
59+
return combineEither(additional, paths, clientFile, (additional, paths, clientFile) =>
60+
directory(name, [clientFile, ...additional, paths]),
6261
);
6362
},
6463
);

src/language/typescript/3.0/serializers/document.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { applyTo } from '../../../../utils/function';
1111
import { OpenapiObject } from '../../../../schema/3.0/openapi-object';
1212
import { pathsRef } from '../../common/utils';
1313
import { clientFile } from '../../common/bundled/client';
14-
import { utilsFile } from '../../common/bundled/utils';
1514
import { openapi3utilsFile } from '../bundled/openapi-3-utils';
1615

1716
export const serializeDocument = combineReader(
@@ -48,10 +47,9 @@ export const serializeDocument = combineReader(
4847
paths,
4948
additional,
5049
clientFile,
51-
utilsFile,
5250
openapi3utilsFile,
53-
(paths, additional, clientFile, utilsFile, openapi3utilsFile) =>
54-
directory(name, [paths, ...additional, clientFile, utilsFile, openapi3utilsFile]),
51+
(paths, additional, clientFile, openapi3utilsFile) =>
52+
directory(name, [paths, ...additional, clientFile, openapi3utilsFile]),
5553
);
5654
},
5755
);

src/language/typescript/3.0/serializers/schema-object.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
getSerializedArrayType,
33
getSerializedDictionaryType,
44
getSerializedEnumType,
5-
getSerializedIntegerType,
65
getSerializedIntersectionType,
76
getSerializedObjectType,
87
getSerializedOptionPropertyType,
@@ -12,6 +11,7 @@ import {
1211
getSerializedUnionType,
1312
intercalateSerializedTypes,
1413
SERIALIZED_BOOLEAN_TYPE,
14+
SERIALIZED_INTEGER_TYPE,
1515
SERIALIZED_NUMBER_TYPE,
1616
SERIALIZED_UNKNOWN_TYPE,
1717
SerializedType,
@@ -35,7 +35,6 @@ import {
3535
import { ReferenceObject, ReferenceObjectCodec } from '../../../../schema/3.0/reference-object';
3636
import { traverseNEAEither } from '../../../../utils/either';
3737
import { NonEmptyArray } from 'fp-ts/lib/NonEmptyArray';
38-
import { utilsRef } from '../../common/bundled/utils';
3938

4039
type AdditionalProperties = boolean | ReferenceObject | SchemaObject;
4140
type AllowedAdditionalProperties = true | ReferenceObject | SchemaObject;
@@ -199,10 +198,7 @@ const serializePrimitive = (from: Ref, schemaObject: PrimitiveSchemaObject): Eit
199198
return right(SERIALIZED_NUMBER_TYPE);
200199
}
201200
case 'integer': {
202-
return pipe(
203-
utilsRef,
204-
either.map(utilsRef => getSerializedIntegerType(from, utilsRef)),
205-
);
201+
return right(SERIALIZED_INTEGER_TYPE);
206202
}
207203
case 'boolean': {
208204
return right(SERIALIZED_BOOLEAN_TYPE);

src/language/typescript/asyncapi-2.0.0/serializers/asyncapi-object.ts

+2-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { array, either, option } from 'fp-ts';
99
import { combineEither, sequenceEither } from '@devexperts/utils/dist/adt/either.utils';
1010
import { serializeChannelsObject } from './channels-object';
1111
import { clientFile } from '../../common/bundled/client';
12-
import { utilsFile } from '../../common/bundled/utils';
1312

1413
export const serializeAsyncAPIObject = combineReader(
1514
serializeComponentsObject,
@@ -33,13 +32,8 @@ export const serializeAsyncAPIObject = combineReader(
3332
either.chain(from => serializeChannelsObject(from, asyncAPIObject.channels)),
3433
either.map(content => directory('channels', [content])),
3534
);
36-
return combineEither(
37-
channels,
38-
additional,
39-
clientFile,
40-
utilsFile,
41-
(channels, additional, clientFile, utilsFile) =>
42-
directory(name, [channels, clientFile, utilsFile, ...additional]),
35+
return combineEither(channels, additional, clientFile, (channels, additional, clientFile) =>
36+
directory(name, [channels, clientFile, ...additional]),
4337
);
4438
},
4539
);

src/language/typescript/asyncapi-2.0.0/serializers/schema-object.ts

+2-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
SerializedType,
2020
getSerializedEnumType,
2121
getSerializedStringType,
22-
getSerializedIntegerType,
22+
SERIALIZED_INTEGER_TYPE,
2323
} from '../../common/data/serialized-type';
2424
import {
2525
AllOfSchemaObjectCodec,
@@ -37,7 +37,6 @@ import { traverseNEAEither } from '../../../../utils/either';
3737
import { constFalse } from 'fp-ts/lib/function';
3838
import { sequenceEither } from '@devexperts/utils/dist/adt/either.utils';
3939
import { Option } from 'fp-ts/lib/Option';
40-
import { utilsRef } from '../../common/bundled/utils';
4140

4241
export const serializeSchemaObject = (
4342
from: Ref,
@@ -77,10 +76,7 @@ const serializeSchemaObjectWithRecursion = (
7776
return right(SERIALIZED_NUMBER_TYPE);
7877
}
7978
case 'integer': {
80-
return pipe(
81-
utilsRef,
82-
either.map(utilsRef => getSerializedIntegerType(from, utilsRef)),
83-
);
79+
return right(SERIALIZED_INTEGER_TYPE);
8480
}
8581
case 'boolean': {
8682
return right(SERIALIZED_BOOLEAN_TYPE);

src/language/typescript/common/bundled/utils.ts

-29
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,6 @@ import { fromRef } from '../../../../utils/fs';
66
export const utilsRef = fromString('#/utils/utils');
77

88
const utils = `
9-
import { brand, Branded, intersection, number, string, success, Type } from 'io-ts';
10-
11-
export interface IntegerBrand {
12-
readonly Integer: unique symbol;
13-
}
14-
export type Integer = Branded<number, IntegerBrand>;
15-
export const integer: Type<Integer, number> = brand(
16-
number,
17-
(n): n is Integer => n !== -Infinity && n !== Infinity && Math.floor(n) === n,
18-
'Integer',
19-
);
20-
21-
export interface NonNegativeBrand {
22-
readonly NonNegative: unique symbol;
23-
}
24-
export type NonNegative = Branded<number, NonNegativeBrand>;
25-
export const nonNegative: Type<NonNegative, number> = brand(number, (n): n is NonNegative => n >= 0.0, 'NonNegative');
26-
27-
export interface PositiveBrand {
28-
readonly Positive: unique symbol;
29-
}
30-
export type Positive = Branded<number, PositiveBrand>;
31-
export const positive: Type<Positive, number> = brand(number, (n): n is Positive => n > 0.0, 'Positive');
32-
33-
export type Natural = NonNegative & Integer;
34-
export const natural: Type<Natural, number> = intersection([nonNegative, integer], 'Natural');
35-
36-
export const split = (separator: string): Type<string[], string, string> =>
37-
new Type('Split', (u): u is string[] => string.is(u), u => success(u.split(separator)), as => as.join(separator));
389
`;
3910

4011
export const utilsFile = pipe(

src/language/typescript/common/data/__tests__/serialized-type.spec.ts

+5-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { getRelativePath } from '../../../../../utils/ref';
1616
import { pipe } from 'fp-ts/lib/pipeable';
1717
import { arbitrary, nonEmptyArray } from '../../../../../utils/fast-check';
1818
import { none, some } from 'fp-ts/lib/Option';
19-
import { getIOName, getTypeName } from '../../utils';
19+
import { getIOName, getTypeName, UNSAFE_PROPERTY_PATTERN } from '../../utils';
2020
import { when } from '../../../../../utils/string';
2121
import { head } from 'fp-ts/lib/NonEmptyArray';
2222

@@ -55,17 +55,12 @@ describe('SerializedType', () => {
5555
assert(
5656
property(string(), serializedTypeArbitrary, boolean(), (name, s, isRequired) => {
5757
const serialized = getSerializedOptionPropertyType(name, isRequired)(s);
58-
const fixedName = (name: string) => (name.includes('-') ? `['${name}']` : name);
58+
const safeName = UNSAFE_PROPERTY_PATTERN.test(name) ? `['${name}']` : name;
5959
const expected = isRequired
60-
? serializedType(
61-
`${fixedName(name)}: ${s.type}`,
62-
`${fixedName(name)}: ${s.io}`,
63-
s.dependencies,
64-
s.refs,
65-
)
60+
? serializedType(`${safeName}: ${s.type}`, `${safeName}: ${s.io}`, s.dependencies, s.refs)
6661
: serializedType(
67-
`${fixedName(name)}: Option<${s.type}>`,
68-
`${fixedName(name)}: optionFromNullable(${s.io})`,
62+
`${safeName}: Option<${s.type}>`,
63+
`${safeName}: optionFromNullable(${s.io})`,
6964
[
7065
...s.dependencies,
7166
serializedDependency('Option', 'fp-ts/lib/Option'),

src/language/typescript/common/data/serialized-type.ts

+8-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { intercalate } from 'fp-ts/lib/Foldable';
1111
import { array, getMonoid, uniq } from 'fp-ts/lib/Array';
1212
import { Eq, eqString, getStructEq } from 'fp-ts/lib/Eq';
1313
import { getRelativePath, Ref, uniqRefs } from '../../../../utils/ref';
14-
import { getIOName, getTypeName } from '../utils';
14+
import { getIOName, getTypeName, UNSAFE_PROPERTY_PATTERN } from '../utils';
1515
import { concatIfL } from '../../../../utils/array';
1616
import { when } from '../../../../utils/string';
1717
import { head, NonEmptyArray } from 'fp-ts/lib/NonEmptyArray';
@@ -72,15 +72,7 @@ export const SERIALIZED_BOOLEAN_TYPE = serializedType(
7272
[],
7373
);
7474
export const SERIALIZED_NUMBER_TYPE = serializedType('number', 'number', [serializedDependency('number', 'io-ts')], []);
75-
export const getSerializedIntegerType = (from: Ref, utilsRef: Ref): SerializedType => {
76-
const pathToUtils = getRelativePath(from, utilsRef);
77-
return serializedType(
78-
'Integer',
79-
'integer',
80-
[serializedDependency('Integer', pathToUtils), serializedDependency('integer', pathToUtils)],
81-
[],
82-
);
83-
};
75+
export const SERIALIZED_INTEGER_TYPE = serializedType('Int', 'Int', [serializedDependency('Int', 'io-ts')], []);
8476
export const SERIALIZED_DATE_TYPE = serializedType(
8577
'Date',
8678
'DateFromISOString',
@@ -218,13 +210,15 @@ export const getSerializedPropertyType = (
218210
name: string,
219211
isRequired: boolean,
220212
serialized: SerializedType,
221-
): SerializedType =>
222-
serializedType(
223-
`${name.includes('-') ? `['${name}']` : name}${when(!isRequired, '?')}: ${serialized.type}`,
224-
`${name.includes('-') ? `['${name}']` : name}: ${serialized.io}`,
213+
): SerializedType => {
214+
const safeName = UNSAFE_PROPERTY_PATTERN.test(name) ? `['${name}']` : name;
215+
return serializedType(
216+
`${safeName}${when(!isRequired, '?')}: ${serialized.type}`,
217+
`${safeName}: ${serialized.io}`,
225218
serialized.dependencies,
226219
serialized.refs,
227220
);
221+
};
228222

229223
export const getSerializedOptionPropertyType = (name: string, isRequired: boolean) => (
230224
serialized: SerializedType,

src/language/typescript/common/utils.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const getURL = (pattern: string, pathParameters: SerializedPathParameter[
2222
export const getJSDoc = (lines: string[]): string =>
2323
unless(
2424
lines.length === 0,
25-
`/**
25+
`/**
2626
${lines.map(line => `* ${line}`).join('\n')}
2727
*/`,
2828
);
@@ -65,5 +65,7 @@ export const getKindValue = (kind: Kind, value: string): string => {
6565

6666
export const getControllerName = (name: string): string => `${name}Controller`;
6767

68+
export const UNSAFE_PROPERTY_PATTERN = /[^a-zA-Z_0-9]/;
69+
const REPLACE_PATTERN = new RegExp(UNSAFE_PROPERTY_PATTERN, 'g');
6870
export const getSafePropertyName = (value: string): string =>
69-
value.replace(/[^a-zA-Z_0-9]/g, '_').replace(/^(\d)/, '_$1') || '_';
71+
value.replace(REPLACE_PATTERN, '_').replace(/^(\d)/, '_$1') || '_';

0 commit comments

Comments
 (0)