@postxl/generator 0.0.1
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/README.md +3 -0
- package/dist/jest.config.d.ts +3 -0
- package/dist/src/generator.d.ts +12 -0
- package/dist/src/generator.js +164 -0
- package/dist/src/generators/enums/react.generator.d.ts +10 -0
- package/dist/src/generators/enums/react.generator.js +81 -0
- package/dist/src/generators/enums/types.generator.d.ts +10 -0
- package/dist/src/generators/enums/types.generator.js +18 -0
- package/dist/src/generators/indices/datamockmodule.generator.d.ts +9 -0
- package/dist/src/generators/indices/datamockmodule.generator.js +104 -0
- package/dist/src/generators/indices/datamodule.generator.d.ts +9 -0
- package/dist/src/generators/indices/datamodule.generator.js +128 -0
- package/dist/src/generators/indices/dataservice.generator.d.ts +9 -0
- package/dist/src/generators/indices/dataservice.generator.js +47 -0
- package/dist/src/generators/indices/repositories.generator.d.ts +9 -0
- package/dist/src/generators/indices/repositories.generator.js +17 -0
- package/dist/src/generators/indices/seed.generator.d.ts +9 -0
- package/dist/src/generators/indices/seed.generator.js +17 -0
- package/dist/src/generators/indices/stubs.generator.d.ts +9 -0
- package/dist/src/generators/indices/stubs.generator.js +17 -0
- package/dist/src/generators/indices/testdataservice.generator.d.ts +7 -0
- package/dist/src/generators/indices/testdataservice.generator.js +61 -0
- package/dist/src/generators/indices/types.generator.d.ts +10 -0
- package/dist/src/generators/indices/types.generator.js +21 -0
- package/dist/src/generators/models/react.generator/context.generator.d.ts +9 -0
- package/dist/src/generators/models/react.generator/context.generator.js +66 -0
- package/dist/src/generators/models/react.generator/index.d.ts +10 -0
- package/dist/src/generators/models/react.generator/index.js +32 -0
- package/dist/src/generators/models/react.generator/library.generator.d.ts +9 -0
- package/dist/src/generators/models/react.generator/library.generator.js +113 -0
- package/dist/src/generators/models/react.generator/lookup.generator.d.ts +9 -0
- package/dist/src/generators/models/react.generator/lookup.generator.js +97 -0
- package/dist/src/generators/models/react.generator/modals.generator.d.ts +23 -0
- package/dist/src/generators/models/react.generator/modals.generator.js +521 -0
- package/dist/src/generators/models/repository.generator.d.ts +9 -0
- package/dist/src/generators/models/repository.generator.js +282 -0
- package/dist/src/generators/models/route.generator.d.ts +16 -0
- package/dist/src/generators/models/route.generator.js +112 -0
- package/dist/src/generators/models/seed.generator.d.ts +20 -0
- package/dist/src/generators/models/seed.generator.js +185 -0
- package/dist/src/generators/models/stub.generator.d.ts +9 -0
- package/dist/src/generators/models/stub.generator.js +74 -0
- package/dist/src/generators/models/types.generator.d.ts +9 -0
- package/dist/src/generators/models/types.generator.js +116 -0
- package/dist/src/lib/attributes.d.ts +43 -0
- package/dist/src/lib/attributes.js +2 -0
- package/dist/src/lib/exports.d.ts +26 -0
- package/dist/src/lib/exports.js +38 -0
- package/dist/src/lib/imports.d.ts +35 -0
- package/dist/src/lib/imports.js +55 -0
- package/dist/src/lib/meta.d.ts +359 -0
- package/dist/src/lib/meta.js +195 -0
- package/dist/src/lib/schema/fields.d.ts +35 -0
- package/dist/src/lib/schema/fields.js +49 -0
- package/dist/src/lib/schema/schema.d.ts +275 -0
- package/dist/src/lib/schema/schema.js +2 -0
- package/dist/src/lib/schema/types.d.ts +72 -0
- package/dist/src/lib/schema/types.js +41 -0
- package/dist/src/lib/schema/zod.d.ts +8 -0
- package/dist/src/lib/schema/zod.js +44 -0
- package/dist/src/lib/serializer.d.ts +15 -0
- package/dist/src/lib/serializer.js +24 -0
- package/dist/src/lib/utils/error.d.ts +5 -0
- package/dist/src/lib/utils/error.js +13 -0
- package/dist/src/lib/utils/file.d.ts +10 -0
- package/dist/src/lib/utils/file.js +54 -0
- package/dist/src/lib/utils/logger.d.ts +11 -0
- package/dist/src/lib/utils/logger.js +2 -0
- package/dist/src/lib/utils/string.d.ts +29 -0
- package/dist/src/lib/utils/string.js +75 -0
- package/dist/src/lib/utils/types.d.ts +12 -0
- package/dist/src/lib/utils/types.js +2 -0
- package/dist/src/lib/vfs.d.ts +137 -0
- package/dist/src/lib/vfs.js +419 -0
- package/dist/src/prisma/attributes.d.ts +17 -0
- package/dist/src/prisma/attributes.js +80 -0
- package/dist/src/prisma/client-path.d.ts +7 -0
- package/dist/src/prisma/client-path.js +29 -0
- package/dist/src/prisma/parse.d.ts +12 -0
- package/dist/src/prisma/parse.js +276 -0
- package/dist/tests/attributes.test.d.ts +1 -0
- package/dist/tests/attributes.test.js +76 -0
- package/dist/tests/file.test.d.ts +1 -0
- package/dist/tests/file.test.js +26 -0
- package/dist/tests/utils/random.d.ts +3 -0
- package/dist/tests/utils/random.js +15 -0
- package/dist/tests/vfs.test.d.ts +1 -0
- package/dist/tests/vfs.test.js +74 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/jest.config.ts +18 -0
- package/package.json +42 -0
- package/tests/attributes.test.ts +91 -0
- package/tests/file.test.ts +32 -0
- package/tests/utils/random.ts +11 -0
- package/tests/vfs.test.ts +92 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateStub = void 0;
|
|
7
|
+
const assert_never_1 = __importDefault(require("assert-never"));
|
|
8
|
+
const meta_1 = require("../../lib/meta");
|
|
9
|
+
const fields_1 = require("../../lib/schema/fields");
|
|
10
|
+
const imports_1 = require("../../lib/imports");
|
|
11
|
+
/**
|
|
12
|
+
* Generates a stub definition file for a given model.
|
|
13
|
+
*/
|
|
14
|
+
function generateStub({ model, meta }) {
|
|
15
|
+
const { fields } = model;
|
|
16
|
+
const imports = imports_1.ImportsGenerator.from(meta.data.stubFilePath).addImport({
|
|
17
|
+
items: [model.typeName, meta.types.toBrandedIdTypeFnName],
|
|
18
|
+
from: meta.types.importPath,
|
|
19
|
+
});
|
|
20
|
+
for (const relation of (0, fields_1.getRelationFields)(model)) {
|
|
21
|
+
const depMeta = (0, meta_1.getModelMetadata)({ model: relation.relationToModel });
|
|
22
|
+
imports.addImport({
|
|
23
|
+
items: [relation.relationToModel.typeName, depMeta.types.toBrandedIdTypeFnName],
|
|
24
|
+
from: meta.types.importPath,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return `
|
|
28
|
+
${imports.generate()}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Utility object containing default values for all fields in a model.
|
|
32
|
+
*/
|
|
33
|
+
export const ${meta.data.defaultStubConstantName}: ${model.typeName} = {
|
|
34
|
+
${getAssigmentStatementModel({ fields })}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Utility function that creates a new ${meta.userFriendlyName} object from a partial object of values.
|
|
39
|
+
*/
|
|
40
|
+
export const ${meta.data.stubGenerationFnName} = (
|
|
41
|
+
item: Partial<${model.typeName}>
|
|
42
|
+
): ${model.typeName} => ({
|
|
43
|
+
...${meta.data.defaultStubConstantName},
|
|
44
|
+
...item,
|
|
45
|
+
})
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
exports.generateStub = generateStub;
|
|
49
|
+
/**
|
|
50
|
+
* Return an assignment statement for a model where each field is assigned null or its type's default value.
|
|
51
|
+
*/
|
|
52
|
+
function getAssigmentStatementModel({ fields }) {
|
|
53
|
+
return fields
|
|
54
|
+
.map((f) => {
|
|
55
|
+
if (!f.isRequired) {
|
|
56
|
+
return `${f.name}: null`;
|
|
57
|
+
}
|
|
58
|
+
switch (f.kind) {
|
|
59
|
+
case 'scalar':
|
|
60
|
+
return `${f.name}: ${(0, fields_1.getDefaultValueForType)(f.typeName)}`;
|
|
61
|
+
case 'id':
|
|
62
|
+
const idRefMeta = (0, meta_1.getModelMetadata)({ model: f.model });
|
|
63
|
+
return `${f.name}: ${idRefMeta.types.toBrandedIdTypeFnName}(${(0, fields_1.getDefaultValueForType)(f.unbrandedTypeName)})`;
|
|
64
|
+
case 'relation':
|
|
65
|
+
const refModelMeta = (0, meta_1.getModelMetadata)({ model: f.relationToModel });
|
|
66
|
+
return `${f.name}: ${refModelMeta.types.toBrandedIdTypeFnName}(${(0, fields_1.getDefaultValueForType)(f.unbrandedTypeName)})`;
|
|
67
|
+
case 'enum':
|
|
68
|
+
return `${f.name}: "${f.enumerator.values[0]}"`;
|
|
69
|
+
default:
|
|
70
|
+
(0, assert_never_1.default)(f);
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
.join(',\n');
|
|
74
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ModelMetaData } from '../../lib/meta';
|
|
2
|
+
import { Model } from '../../lib/schema/schema';
|
|
3
|
+
/**
|
|
4
|
+
* Generates types for a given model.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateModelTypes({ model, meta }: {
|
|
7
|
+
model: Model;
|
|
8
|
+
meta: ModelMetaData;
|
|
9
|
+
}): string;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateModelTypes = void 0;
|
|
7
|
+
const assert_never_1 = __importDefault(require("assert-never"));
|
|
8
|
+
const meta_1 = require("../../lib/meta");
|
|
9
|
+
const fields_1 = require("../../lib/schema/fields");
|
|
10
|
+
const zod_1 = require("../../lib/schema/zod");
|
|
11
|
+
const imports_1 = require("../../lib/imports");
|
|
12
|
+
/**
|
|
13
|
+
* Generates types for a given model.
|
|
14
|
+
*/
|
|
15
|
+
function generateModelTypes({ model, meta }) {
|
|
16
|
+
const idField = model.idField;
|
|
17
|
+
const imports = imports_1.ImportsGenerator.from(meta.types.filePath);
|
|
18
|
+
for (const relation of (0, fields_1.getRelationFields)(model)) {
|
|
19
|
+
if (relation.relationToModel.typeName === model.typeName) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const refModel = relation.relationToModel;
|
|
23
|
+
const refMeta = (0, meta_1.getModelMetadata)({ model: refModel });
|
|
24
|
+
imports.addImport({
|
|
25
|
+
items: [refMeta.types.toBrandedIdTypeFnName, refModel.brandedIdType],
|
|
26
|
+
from: refMeta.types.filePath,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
for (const f of (0, fields_1.getEnumFields)(model)) {
|
|
30
|
+
const refEnumMeta = (0, meta_1.getEnumMetadata)({ enumerator: f.enumerator });
|
|
31
|
+
imports.addImport({
|
|
32
|
+
items: [f.enumerator.typeName],
|
|
33
|
+
from: refEnumMeta.types.filePath,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return `
|
|
37
|
+
import { z } from 'zod'
|
|
38
|
+
|
|
39
|
+
${imports.generate()}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
${model.description
|
|
43
|
+
? `
|
|
44
|
+
/**
|
|
45
|
+
* ${model.description.split('\n').join('\n * ')}
|
|
46
|
+
*/`
|
|
47
|
+
: ''}
|
|
48
|
+
export type ${model.typeName} = {
|
|
49
|
+
${model.fields
|
|
50
|
+
.map((f) => `
|
|
51
|
+
${getFieldComment(f)}
|
|
52
|
+
${f.name}: ${getFieldType(f)}${f.isRequired ? '' : ' | null'}`)
|
|
53
|
+
.join('\n')}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Branded Id type that should be used to identify an instance of this model.
|
|
58
|
+
*/
|
|
59
|
+
export type ${model.brandedIdType} = ${idField.unbrandedTypeName} & {
|
|
60
|
+
readonly is${model.typeName}: unique symbol
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Converts a given scalar to a branded id type.
|
|
65
|
+
*/
|
|
66
|
+
export function ${meta.types.toBrandedIdTypeFnName}(id: ${idField.unbrandedTypeName}): ${model.brandedIdType} {
|
|
67
|
+
return id as ${model.brandedIdType}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Zod decoder for validating a Participant object.
|
|
72
|
+
*/
|
|
73
|
+
export const ${meta.types.zodDecoderFnName} = z.object({
|
|
74
|
+
${model.fields.map((field) => `${field.name}: z.${(0, zod_1.getZodDecoderDefinition)({ field })}`).join(',')}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
`;
|
|
78
|
+
}
|
|
79
|
+
exports.generateModelTypes = generateModelTypes;
|
|
80
|
+
function getFieldComment(f) {
|
|
81
|
+
const examples = getFieldExamples(f);
|
|
82
|
+
let comment = '';
|
|
83
|
+
if (f.description) {
|
|
84
|
+
comment = ` * ${f.description.split('\n').join('\n * ')}\n`;
|
|
85
|
+
}
|
|
86
|
+
if (examples) {
|
|
87
|
+
comment += ` * ${examples}\n`;
|
|
88
|
+
}
|
|
89
|
+
if (comment === '')
|
|
90
|
+
return '';
|
|
91
|
+
return `
|
|
92
|
+
/**
|
|
93
|
+
${comment}*/`;
|
|
94
|
+
}
|
|
95
|
+
function getFieldExamples(f) {
|
|
96
|
+
if (!f.attributes.examples)
|
|
97
|
+
return undefined;
|
|
98
|
+
return `Examples: ${f.attributes.examples.map((e) => `"${e}"`).join(', ')}`;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Converts a field to a TypeScript type definition.
|
|
102
|
+
*/
|
|
103
|
+
function getFieldType(f) {
|
|
104
|
+
switch (f.kind) {
|
|
105
|
+
case 'enum':
|
|
106
|
+
return f.typeName;
|
|
107
|
+
case 'relation':
|
|
108
|
+
return f.relationToModel.brandedIdType;
|
|
109
|
+
case 'id':
|
|
110
|
+
return f.model.brandedIdType;
|
|
111
|
+
case 'scalar':
|
|
112
|
+
return f.typeName;
|
|
113
|
+
default:
|
|
114
|
+
(0, assert_never_1.default)(f);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export type AttributeValue = unknown;
|
|
2
|
+
export type Attributes = Record<string, AttributeValue>;
|
|
3
|
+
export type ModelAttributes = {
|
|
4
|
+
/**
|
|
5
|
+
* Schema tag: ´@@Ignore()`
|
|
6
|
+
*/
|
|
7
|
+
ignore: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Schema tag: ´@@SkipUpdate()`
|
|
10
|
+
*/
|
|
11
|
+
skipUpdate: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Schema tag: ´@@SkipCreate()`
|
|
14
|
+
*/
|
|
15
|
+
skipCreate: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Schema tag: ´@@SkipDelete()`
|
|
18
|
+
*/
|
|
19
|
+
skipDelete: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Schema tag: ´@@Description("Description of the model")`
|
|
22
|
+
*/
|
|
23
|
+
description?: string;
|
|
24
|
+
};
|
|
25
|
+
export type FieldAttributes = {
|
|
26
|
+
/**
|
|
27
|
+
* Schema tag: ´@@Ignore()`
|
|
28
|
+
*/
|
|
29
|
+
ignore: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Schema tag: ´@@Description("Description of the field")`
|
|
32
|
+
*/
|
|
33
|
+
description?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Schema tag: ´@@Examples("Example1", "Example2")`
|
|
36
|
+
*/
|
|
37
|
+
examples?: unknown[];
|
|
38
|
+
/**
|
|
39
|
+
* Schema tag: ´@@DefaultField()`
|
|
40
|
+
* The property of the model that identifies the default row.
|
|
41
|
+
*/
|
|
42
|
+
isDefaultField?: boolean;
|
|
43
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as Types from './schema/types';
|
|
2
|
+
/**
|
|
3
|
+
* A utility component that lets you generate TypeScript export statements that export all items from a given file.
|
|
4
|
+
*/
|
|
5
|
+
export declare class ExportsGenerator {
|
|
6
|
+
private _exports;
|
|
7
|
+
/**
|
|
8
|
+
* Path of the file we're generating exports for.
|
|
9
|
+
*/
|
|
10
|
+
private _path;
|
|
11
|
+
constructor({ path }: {
|
|
12
|
+
path: string;
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new instance of the exports generator.
|
|
16
|
+
*/
|
|
17
|
+
static from(path: Types.Path): ExportsGenerator;
|
|
18
|
+
/**
|
|
19
|
+
* Adds a given file to the collection of files we're exporting everything from.
|
|
20
|
+
*/
|
|
21
|
+
exportEverythingFrom(from: Types.Path): ExportsGenerator;
|
|
22
|
+
/**
|
|
23
|
+
* Returns the TypeScript export statements.
|
|
24
|
+
*/
|
|
25
|
+
generate(): string;
|
|
26
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExportsGenerator = void 0;
|
|
4
|
+
const file_1 = require("./utils/file");
|
|
5
|
+
/**
|
|
6
|
+
* A utility component that lets you generate TypeScript export statements that export all items from a given file.
|
|
7
|
+
*/
|
|
8
|
+
class ExportsGenerator {
|
|
9
|
+
constructor({ path }) {
|
|
10
|
+
this._path = path;
|
|
11
|
+
this._exports = new Set();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new instance of the exports generator.
|
|
15
|
+
*/
|
|
16
|
+
static from(path) {
|
|
17
|
+
return new ExportsGenerator({ path });
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Adds a given file to the collection of files we're exporting everything from.
|
|
21
|
+
*/
|
|
22
|
+
exportEverythingFrom(from) {
|
|
23
|
+
const resolvedPath = (0, file_1.getRelativePath)({ from: this._path, to: from });
|
|
24
|
+
this._exports.add(resolvedPath);
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns the TypeScript export statements.
|
|
29
|
+
*/
|
|
30
|
+
generate() {
|
|
31
|
+
const stetements = [...this._exports.values()]
|
|
32
|
+
.sort((a, b) => a.localeCompare(b))
|
|
33
|
+
.map((path) => `export * from '${path}'`)
|
|
34
|
+
.join('\n');
|
|
35
|
+
return stetements;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.ExportsGenerator = ExportsGenerator;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as Types from './schema/types';
|
|
2
|
+
/**
|
|
3
|
+
* A utility component that lets you generate TypeScript import statements
|
|
4
|
+
* and makes sure every import is only added once.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ImportsGenerator {
|
|
7
|
+
/**
|
|
8
|
+
* Lists of values and types we import from a given path indexed by the path.
|
|
9
|
+
*/
|
|
10
|
+
private _imports;
|
|
11
|
+
/**
|
|
12
|
+
* Path of the file we're generating imports for.
|
|
13
|
+
*/
|
|
14
|
+
private _path;
|
|
15
|
+
constructor({ path }: {
|
|
16
|
+
path: string;
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new instance of the imports generator.
|
|
20
|
+
*/
|
|
21
|
+
static from(path: Types.Path): ImportsGenerator;
|
|
22
|
+
/**
|
|
23
|
+
* Adds a given import statement to the imports list.
|
|
24
|
+
*
|
|
25
|
+
* NOTE: You should never add no items from a given path.
|
|
26
|
+
*/
|
|
27
|
+
addImport({ items, from, }: {
|
|
28
|
+
items: (Types.Function | Types.ClassName | Types.TypeName | Types.VariableName)[];
|
|
29
|
+
from: Types.Path;
|
|
30
|
+
}): ImportsGenerator;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the TypeScript import statement.
|
|
33
|
+
*/
|
|
34
|
+
generate(): string;
|
|
35
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ImportsGenerator = void 0;
|
|
4
|
+
const file_1 = require("./utils/file");
|
|
5
|
+
/**
|
|
6
|
+
* A utility component that lets you generate TypeScript import statements
|
|
7
|
+
* and makes sure every import is only added once.
|
|
8
|
+
*/
|
|
9
|
+
class ImportsGenerator {
|
|
10
|
+
constructor({ path }) {
|
|
11
|
+
/**
|
|
12
|
+
* Lists of values and types we import from a given path indexed by the path.
|
|
13
|
+
*/
|
|
14
|
+
this._imports = {};
|
|
15
|
+
this._path = path;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new instance of the imports generator.
|
|
19
|
+
*/
|
|
20
|
+
static from(path) {
|
|
21
|
+
return new ImportsGenerator({ path });
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Adds a given import statement to the imports list.
|
|
25
|
+
*
|
|
26
|
+
* NOTE: You should never add no items from a given path.
|
|
27
|
+
*/
|
|
28
|
+
addImport({ items, from, }) {
|
|
29
|
+
// NOTE: Generator relies that there's at least one import statement from a given path.
|
|
30
|
+
if (items.length === 0) {
|
|
31
|
+
throw new Error(`You cannot add an import statement without any items from ${from}.`);
|
|
32
|
+
}
|
|
33
|
+
const resolvedPath = (0, file_1.getRelativePath)({ from: this._path, to: from });
|
|
34
|
+
if (!this._imports[resolvedPath]) {
|
|
35
|
+
this._imports[resolvedPath] = new Set();
|
|
36
|
+
}
|
|
37
|
+
items.forEach((item) => this._imports[resolvedPath].add(item));
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns the TypeScript import statement.
|
|
42
|
+
*/
|
|
43
|
+
generate() {
|
|
44
|
+
const stetements = Object.entries(this._imports)
|
|
45
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
46
|
+
.map(([path, items]) => {
|
|
47
|
+
const alphabeticallySortedItems = Array.from(items).sort((a, b) => a.localeCompare(b));
|
|
48
|
+
// NOTE: You cannot remove imports and we check that there's at least one imported item for every path.
|
|
49
|
+
return `import { ${alphabeticallySortedItems.join(', ')} } from '${path}'`;
|
|
50
|
+
})
|
|
51
|
+
.join('\n');
|
|
52
|
+
return stetements;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.ImportsGenerator = ImportsGenerator;
|