@apso/cli 0.0.45 → 0.1.4
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 +2 -0
- package/dist/commands/server/scaffold.d.ts +1 -1
- package/dist/commands/server/scaffold.js +5 -6
- package/dist/lib/apsorc-parser.d.ts +27 -1
- package/dist/lib/apsorc-parser.js +97 -3
- package/dist/lib/controller.d.ts +8 -0
- package/dist/lib/controller.js +24 -9
- package/dist/lib/dto.d.ts +13 -7
- package/dist/lib/dto.js +33 -25
- package/dist/lib/entity.d.ts +9 -0
- package/dist/lib/entity.js +13 -3
- package/dist/lib/index-module.d.ts +11 -0
- package/dist/lib/index-module.js +11 -0
- package/dist/lib/module.d.ts +13 -1
- package/dist/lib/module.js +26 -10
- package/dist/lib/service.d.ts +9 -1
- package/dist/lib/service.js +22 -7
- package/dist/lib/templates/entities/entity.eta +30 -15
- package/dist/lib/templates/rest/controller-rest.eta +1 -0
- package/dist/lib/templates/rest/service-rest-spec.eta +38 -0
- package/dist/lib/types/relationship.d.ts +8 -0
- package/dist/lib/utils/relationships/parse-v1.js +15 -9
- package/dist/lib/utils/relationships/parse.d.ts +47 -3
- package/dist/lib/utils/relationships/parse.js +316 -53
- package/dist/lib/utils/relationships/parse.spec.d.ts +1 -0
- package/dist/lib/utils/relationships/parse.spec.js +218 -0
- package/dist/tests/utils/relationship-deduplication.spec.d.ts +1 -0
- package/dist/tests/utils/relationship-deduplication.spec.js +97 -0
- package/oclif.manifest.json +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -47,6 +47,8 @@ Then navigate to the newly created service and update the apsorc file according
|
|
|
47
47
|
|
|
48
48
|
Sample of apsorc files for both v1 and v2 are given in apso-cli code at "test/apsorc-json" so you can check it out in order to make sure that your apsorc file follows the right pattern.
|
|
49
49
|
|
|
50
|
+
For detailed examples of configuring complex relationships, especially ManyToMany and self-referencing patterns, see the [Relationship Configuration Use Cases](./UseCases.md).
|
|
51
|
+
|
|
50
52
|
You can also provide the key "apiType" in the apsorc file e.g (Rest, Graphql) incase you want to generate the GraphQL backend by default it would be REST.
|
|
51
53
|
|
|
52
54
|
Install the npm modules before continuing further.
|
|
@@ -8,7 +8,7 @@ export default class Scaffold extends BaseCommand {
|
|
|
8
8
|
};
|
|
9
9
|
static args: {};
|
|
10
10
|
scaffoldServer(dir: string, entity: Entity, relationshipMap: RelationshipMap, apiType: string): Promise<void>;
|
|
11
|
-
setupRestFiles(dir: string, entity: Entity, relationshipMap: RelationshipMap): Promise<void>;
|
|
11
|
+
setupRestFiles(dir: string, entity: Entity, relationshipMap: RelationshipMap, apiType: string): Promise<void>;
|
|
12
12
|
setupGraphqlFiles(dir: string, entity: Entity, relationshipMap: RelationshipMap): Promise<void>;
|
|
13
13
|
run(): Promise<void>;
|
|
14
14
|
}
|
|
@@ -18,18 +18,17 @@ class Scaffold extends base_command_1.default {
|
|
|
18
18
|
await this.setupGraphqlFiles(dir, entity, relationshipMap);
|
|
19
19
|
break;
|
|
20
20
|
case apsorc_parser_1.ApiType.Rest:
|
|
21
|
-
await this.setupRestFiles(dir, entity, relationshipMap);
|
|
21
|
+
await this.setupRestFiles(dir, entity, relationshipMap, apiType);
|
|
22
22
|
break;
|
|
23
23
|
default:
|
|
24
24
|
break;
|
|
25
25
|
}
|
|
26
|
-
await (0, lib_1.createModule)(filePath,
|
|
26
|
+
await (0, lib_1.createModule)(filePath, entity, { apiType });
|
|
27
27
|
}
|
|
28
|
-
async setupRestFiles(dir, entity, relationshipMap) {
|
|
28
|
+
async setupRestFiles(dir, entity, relationshipMap, apiType) {
|
|
29
29
|
const filePath = path.join(dir, entity.name);
|
|
30
|
-
|
|
31
|
-
await (0, lib_1.
|
|
32
|
-
await (0, lib_1.createService)(filePath, entity.name);
|
|
30
|
+
await (0, lib_1.createDto)(filePath, entity, { apiType });
|
|
31
|
+
await (0, lib_1.createService)(filePath, entity);
|
|
33
32
|
await (0, lib_1.createController)(filePath, entity, relationshipMap);
|
|
34
33
|
}
|
|
35
34
|
async setupGraphqlFiles(dir, entity, relationshipMap) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Entity } from "./types/entity";
|
|
2
|
+
import { ApsorcRelationship, RelationshipMap } from "./types/relationship";
|
|
2
3
|
export declare enum ApiType {
|
|
3
4
|
Graphql = "graphql",
|
|
4
5
|
Rest = "rest"
|
|
@@ -23,4 +24,29 @@ type ParsedApsorc = {
|
|
|
23
24
|
export declare const parseApsorcV1: (apsorc: ApsorcType) => ParsedApsorcData;
|
|
24
25
|
export declare const parseApsorcV2: (apsorc: ApsorcType) => ParsedApsorcData;
|
|
25
26
|
export declare const parseApsorc: () => ParsedApsorc;
|
|
27
|
+
/**
|
|
28
|
+
* Represents the unified configuration structure after parsing and potential migration.
|
|
29
|
+
*/
|
|
30
|
+
interface UnifiedConfig {
|
|
31
|
+
entities: Entity[];
|
|
32
|
+
relationships: ApsorcRelationship[];
|
|
33
|
+
rootFolder: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Finds the .apsorc configuration file path.
|
|
37
|
+
* Searches upwards from the current working directory.
|
|
38
|
+
* @returns The absolute path to the .apsorc file, or null if not found.
|
|
39
|
+
*/
|
|
40
|
+
export declare const findConfigPath: () => string | null;
|
|
41
|
+
/**
|
|
42
|
+
* Loads, validates, and potentially migrates the .apsorc configuration.
|
|
43
|
+
* Uses the `rc` library to find and load the .apsorc file.
|
|
44
|
+
* Detects config version (V1 or V2) and migrates V1 to V2 if necessary.
|
|
45
|
+
* Performs basic validation on the final V2 structure.
|
|
46
|
+
* @param appName The name of the application (used by `rc`). Defaults to 'apso'.
|
|
47
|
+
* @param defaults Default configuration values (used by `rc`).
|
|
48
|
+
* @returns The unified configuration (entities, relationships, rootFolder).
|
|
49
|
+
* @throws Error if the config file cannot be found, is invalid, or migration fails.
|
|
50
|
+
*/
|
|
51
|
+
export declare const loadConfig: (appName?: string, defaults?: {}) => UnifiedConfig;
|
|
26
52
|
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseApsorc = exports.parseApsorcV2 = exports.parseApsorcV1 = exports.ApiType = void 0;
|
|
4
|
-
const
|
|
3
|
+
exports.loadConfig = exports.findConfigPath = exports.parseApsorc = exports.parseApsorcV2 = exports.parseApsorcV1 = exports.ApiType = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const fs = tslib_1.__importStar(require("fs"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const rc_1 = tslib_1.__importDefault(require("rc"));
|
|
5
8
|
const relationships_1 = require("./utils/relationships");
|
|
6
9
|
var ApiType;
|
|
7
10
|
(function (ApiType) {
|
|
@@ -24,7 +27,7 @@ const parseApsorcV2 = (apsorc) => {
|
|
|
24
27
|
};
|
|
25
28
|
exports.parseApsorcV2 = parseApsorcV2;
|
|
26
29
|
const parseRc = () => {
|
|
27
|
-
const apsoConfig =
|
|
30
|
+
const apsoConfig = (0, rc_1.default)("apso");
|
|
28
31
|
const rootFolder = apsoConfig.rootFolder || "src";
|
|
29
32
|
const apiType = apsoConfig.apiType || "Rest";
|
|
30
33
|
const version = apsoConfig.version || 1;
|
|
@@ -63,3 +66,94 @@ const parseApsorc = () => {
|
|
|
63
66
|
}
|
|
64
67
|
};
|
|
65
68
|
exports.parseApsorc = parseApsorc;
|
|
69
|
+
/**
|
|
70
|
+
* Finds the .apsorc configuration file path.
|
|
71
|
+
* Searches upwards from the current working directory.
|
|
72
|
+
* @returns The absolute path to the .apsorc file, or null if not found.
|
|
73
|
+
*/
|
|
74
|
+
const findConfigPath = () => {
|
|
75
|
+
let currentDir = process.cwd();
|
|
76
|
+
// Search upwards
|
|
77
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
78
|
+
const configPath = path.join(currentDir, ".apsorc");
|
|
79
|
+
if (fs.existsSync(configPath)) {
|
|
80
|
+
return configPath;
|
|
81
|
+
}
|
|
82
|
+
currentDir = path.dirname(currentDir);
|
|
83
|
+
}
|
|
84
|
+
// Check root directory as well
|
|
85
|
+
const rootConfigPath = path.join(currentDir, ".apsorc");
|
|
86
|
+
if (fs.existsSync(rootConfigPath)) {
|
|
87
|
+
return rootConfigPath;
|
|
88
|
+
}
|
|
89
|
+
return null; // Not found
|
|
90
|
+
};
|
|
91
|
+
exports.findConfigPath = findConfigPath;
|
|
92
|
+
/**
|
|
93
|
+
* Loads, validates, and potentially migrates the .apsorc configuration.
|
|
94
|
+
* Uses the `rc` library to find and load the .apsorc file.
|
|
95
|
+
* Detects config version (V1 or V2) and migrates V1 to V2 if necessary.
|
|
96
|
+
* Performs basic validation on the final V2 structure.
|
|
97
|
+
* @param appName The name of the application (used by `rc`). Defaults to 'apso'.
|
|
98
|
+
* @param defaults Default configuration values (used by `rc`).
|
|
99
|
+
* @returns The unified configuration (entities, relationships, rootFolder).
|
|
100
|
+
* @throws Error if the config file cannot be found, is invalid, or migration fails.
|
|
101
|
+
*/
|
|
102
|
+
const loadConfig = (appName = "apso", defaults = {}) => {
|
|
103
|
+
// Use rc to find and load the configuration file (.apsorc)
|
|
104
|
+
const configData = (0, rc_1.default)(appName, defaults);
|
|
105
|
+
const rootFolder = configData.rootFolder || "src"; // Get rootFolder early
|
|
106
|
+
// Check if rc found and loaded the config
|
|
107
|
+
// rc returns an object with default keys if nothing is found,
|
|
108
|
+
// so check for more than just default keys or if configData.config exists
|
|
109
|
+
const hasMeaningfulConfig = configData &&
|
|
110
|
+
Object.keys(configData).some(key => !Object.prototype.hasOwnProperty.call(defaults, key) && key !== '_') &&
|
|
111
|
+
configData.configs && configData.configs.length > 0;
|
|
112
|
+
if (!hasMeaningfulConfig) {
|
|
113
|
+
// If rc didn't find it, try our manual search as a fallback
|
|
114
|
+
const foundPath = (0, exports.findConfigPath)();
|
|
115
|
+
// Use ternary to satisfy unicorn/prefer-ternary rule
|
|
116
|
+
throw foundPath
|
|
117
|
+
? new Error(`Configuration file found at: ${foundPath}, but failed to parse. Ensure it is valid JSON or INI.`)
|
|
118
|
+
: new Error(".apsorc configuration file not found in the current directory or any parent directory.");
|
|
119
|
+
}
|
|
120
|
+
// Determine version and parse accordingly using existing functions
|
|
121
|
+
const version = configData.version || 1; // Default to 1 if undefined
|
|
122
|
+
let parsedData;
|
|
123
|
+
// Create an object matching ApsorcType structure from rc data
|
|
124
|
+
const apsorcInput = {
|
|
125
|
+
version: version,
|
|
126
|
+
rootFolder: rootFolder,
|
|
127
|
+
entities: configData.entities || [],
|
|
128
|
+
apiType: configData.apiType || ApiType.Rest,
|
|
129
|
+
relationships: configData.relationships || []
|
|
130
|
+
};
|
|
131
|
+
if (version === 1) {
|
|
132
|
+
// Pass the correctly structured object
|
|
133
|
+
parsedData = (0, exports.parseApsorcV1)(apsorcInput);
|
|
134
|
+
}
|
|
135
|
+
else if (version === 2 && Array.isArray(configData.relationships)) {
|
|
136
|
+
// Pass the correctly structured object
|
|
137
|
+
parsedData = (0, exports.parseApsorcV2)(apsorcInput);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
throw new Error("Invalid .apsorc format. Could not determine configuration version or structure.");
|
|
141
|
+
}
|
|
142
|
+
// Basic validation on the result of parsing
|
|
143
|
+
if (!parsedData.entities || !Array.isArray(parsedData.entities)) {
|
|
144
|
+
throw new Error("Invalid config: 'entities' array is missing or invalid after parsing.");
|
|
145
|
+
}
|
|
146
|
+
if (!rootFolder || typeof rootFolder !== 'string') {
|
|
147
|
+
throw new Error("Invalid config: 'rootFolder' string is missing or invalid.");
|
|
148
|
+
}
|
|
149
|
+
// Relationships are implicitly validated by parseRelationships/parseV1Relationships
|
|
150
|
+
return {
|
|
151
|
+
entities: parsedData.entities,
|
|
152
|
+
// Extract relationships from the relationshipMap keys/values if needed,
|
|
153
|
+
// or adjust UnifiedConfig. For now, returning empty array as placeholder.
|
|
154
|
+
// The relationshipMap is the primary output needed by downstream code.
|
|
155
|
+
relationships: [],
|
|
156
|
+
rootFolder: rootFolder
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
exports.loadConfig = loadConfig;
|
package/dist/lib/controller.d.ts
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
1
|
import { Entity, RelationshipMap } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates NestJS controller and spec files for a given entity.
|
|
4
|
+
*
|
|
5
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
6
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
7
|
+
* @param relationshipMap The complete RelationshipMap generated from parsing all relationships.
|
|
8
|
+
* @returns {Promise<void>} A promise that resolves when the controller and spec files are created.
|
|
9
|
+
*/
|
|
2
10
|
export declare const createController: (apiBaseDir: string, entity: Entity, relationshipMap: RelationshipMap) => Promise<void>;
|
package/dist/lib/controller.js
CHANGED
|
@@ -6,31 +6,46 @@ const Eta = tslib_1.__importStar(require("eta"));
|
|
|
6
6
|
const path = tslib_1.__importStar(require("path"));
|
|
7
7
|
const file_system_1 = require("./utils/file-system");
|
|
8
8
|
const relationships_1 = require("./utils/relationships");
|
|
9
|
+
const pluralize_1 = tslib_1.__importDefault(require("pluralize"));
|
|
10
|
+
/**
|
|
11
|
+
* Generates NestJS controller and spec files for a given entity.
|
|
12
|
+
*
|
|
13
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
14
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
15
|
+
* @param relationshipMap The complete RelationshipMap generated from parsing all relationships.
|
|
16
|
+
* @returns {Promise<void>} A promise that resolves when the controller and spec files are created.
|
|
17
|
+
*/
|
|
9
18
|
const createController = async (apiBaseDir, entity, relationshipMap) => {
|
|
10
19
|
const { name: entityName } = entity;
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
// Dependencies
|
|
20
|
+
const controllerFileName = path.join(apiBaseDir, `${entityName}.controller.ts`);
|
|
21
|
+
const specFileName = path.join(apiBaseDir, `${entityName}.controller.spec.ts`);
|
|
22
|
+
// Dependencies and names needed by the template
|
|
14
23
|
const svcName = `${entityName}Service`;
|
|
15
24
|
const ctrlName = `${entityName}Controller`;
|
|
16
|
-
const pluralEntityName =
|
|
25
|
+
const pluralEntityName = (0, pluralize_1.default)(entityName);
|
|
26
|
+
// Get processed relationships specific to this entity
|
|
17
27
|
const relationships = (0, relationships_1.getRelationshipForTemplate)(entityName, relationshipMap[entityName]);
|
|
28
|
+
// Get nested relationship paths for the @Crud join configuration
|
|
18
29
|
const nestedRelationships = (0, relationships_1.getNestedRelationships)(entityName, relationshipMap);
|
|
30
|
+
// Data object for the Eta template
|
|
19
31
|
const data = {
|
|
20
32
|
svcName,
|
|
21
33
|
ctrlName,
|
|
22
34
|
entityName,
|
|
23
35
|
pluralEntityName,
|
|
24
|
-
//
|
|
36
|
+
// Ensure uniqueness in associations (though getRelationshipForTemplate might handle this)
|
|
25
37
|
associations: [...new Set(relationships)],
|
|
26
38
|
nestedAssociations: [...new Set(nestedRelationships)],
|
|
27
39
|
};
|
|
40
|
+
// Configure Eta
|
|
28
41
|
Eta.configure({
|
|
29
42
|
views: path.join(__dirname, "templates"),
|
|
30
43
|
});
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
// Render controller template
|
|
45
|
+
const controllerContent = await Eta.renderFileAsync("./rest/controller-rest", data);
|
|
46
|
+
(0, file_system_1.createFile)(controllerFileName, controllerContent);
|
|
47
|
+
// Render spec template
|
|
48
|
+
const specContent = await Eta.renderFileAsync("./rest/controller-rest-spec", data);
|
|
49
|
+
(0, file_system_1.createFile)(specFileName, specContent);
|
|
35
50
|
};
|
|
36
51
|
exports.createController = createController;
|
package/dist/lib/dto.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import { Entity
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Entity } from "./types/entity";
|
|
2
|
+
/**
|
|
3
|
+
* Generates Data Transfer Object (DTO) files (create and update) for a given entity.
|
|
4
|
+
*
|
|
5
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
6
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
7
|
+
* @param options Optional configuration flags.
|
|
8
|
+
* @param options.apiType The type of API being generated (default: "rest").
|
|
9
|
+
* @returns {Promise<void>} A promise that resolves when the DTO files are created.
|
|
10
|
+
*/
|
|
11
|
+
export declare const createDto: (apiBaseDir: string, entity: Entity, options?: {
|
|
12
|
+
apiType?: string;
|
|
13
|
+
}) => Promise<void>;
|
package/dist/lib/dto.js
CHANGED
|
@@ -7,43 +7,51 @@ const path = tslib_1.__importStar(require("path"));
|
|
|
7
7
|
const file_system_1 = require("./utils/file-system");
|
|
8
8
|
const field_1 = require("./utils/field");
|
|
9
9
|
const relationships_1 = require("./utils/relationships");
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
name: fieldName,
|
|
28
|
-
dataType: "number",
|
|
29
|
-
})),
|
|
30
|
-
];
|
|
10
|
+
const casing_1 = require("./utils/casing");
|
|
11
|
+
/**
|
|
12
|
+
* Generates Data Transfer Object (DTO) files (create and update) for a given entity.
|
|
13
|
+
*
|
|
14
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
15
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
16
|
+
* @param options Optional configuration flags.
|
|
17
|
+
* @param options.apiType The type of API being generated (default: "rest").
|
|
18
|
+
* @returns {Promise<void>} A promise that resolves when the DTO files are created.
|
|
19
|
+
*/
|
|
20
|
+
const createDto = async (apiBaseDir, entity, options) => {
|
|
21
|
+
var _a;
|
|
22
|
+
const { name: entityName, fields = [], associations } = entity;
|
|
23
|
+
const dtoDir = path.join(apiBaseDir, "dto");
|
|
24
|
+
const dtoFile = path.join(dtoDir, `${entityName}.dto.ts`);
|
|
25
|
+
const columns = (0, field_1.getFieldForTemplate)(fields, entityName);
|
|
26
|
+
const relationshipsTemplate = (0, relationships_1.getRelationshipForTemplate)(entityName, associations || []);
|
|
31
27
|
const primaryKeyColumns = columns.filter((column) => column.primary === true);
|
|
32
28
|
const addDefaultPKProperty = primaryKeyColumns.length === 0;
|
|
33
29
|
const createdAt = entity.created_at;
|
|
34
30
|
const updatedAt = entity.updated_at;
|
|
31
|
+
// Filter columns: remove id, createdAt, updatedAt
|
|
32
|
+
const dtoColumns = columns.filter((col) => !["id", "createdAt", "updatedAt"].includes(col.name));
|
|
33
|
+
// Class names
|
|
34
|
+
const createDtoName = `Create${(0, casing_1.camelCase)(entityName, true)}Dto`;
|
|
35
|
+
const updateDtoName = `Update${(0, casing_1.camelCase)(entityName, true)}Dto`;
|
|
35
36
|
const data = {
|
|
36
|
-
|
|
37
|
+
entityName,
|
|
37
38
|
addDefaultPKProperty,
|
|
38
39
|
createdAt,
|
|
39
40
|
updatedAt,
|
|
40
|
-
columns,
|
|
41
|
+
columns: dtoColumns,
|
|
42
|
+
associations: relationshipsTemplate,
|
|
43
|
+
createDtoName,
|
|
44
|
+
updateDtoName,
|
|
45
|
+
apiType: (_a = options === null || options === void 0 ? void 0 : options.apiType) !== null && _a !== void 0 ? _a : "rest",
|
|
41
46
|
importEnums: (0, field_1.typeExistsInEntity)(entity, "enum") !== -1,
|
|
42
47
|
};
|
|
48
|
+
// Configure Eta
|
|
43
49
|
Eta.configure({
|
|
44
50
|
views: path.join(__dirname, "templates"),
|
|
45
51
|
});
|
|
46
|
-
|
|
47
|
-
|
|
52
|
+
// Render the unified template only once
|
|
53
|
+
const dtoContent = await Eta.renderFileAsync("./rest/dto-rest", data);
|
|
54
|
+
// Create only one DTO file
|
|
55
|
+
(0, file_system_1.createFile)(dtoFile, dtoContent);
|
|
48
56
|
};
|
|
49
57
|
exports.createDto = createDto;
|
package/dist/lib/entity.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
import { Entity, Relationship } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates a TypeORM entity file based on the entity definition and relationships.
|
|
4
|
+
*
|
|
5
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
6
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
7
|
+
* @param relationshipsNew An array of processed Relationship objects for this entity.
|
|
8
|
+
* @param apiType The type of API being generated (e.g., "rest", "graphql").
|
|
9
|
+
* @returns {Promise<void>} A promise that resolves when the entity file is created.
|
|
10
|
+
*/
|
|
2
11
|
export declare const createEntity: (apiBaseDir: string, entity: Entity, relationshipsNew: Relationship[], apiType: string) => Promise<void>;
|
package/dist/lib/entity.js
CHANGED
|
@@ -4,11 +4,20 @@ exports.createEntity = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const Eta = tslib_1.__importStar(require("eta"));
|
|
6
6
|
const path = tslib_1.__importStar(require("path"));
|
|
7
|
-
const pluralize_1 = tslib_1.__importDefault(require("pluralize"));
|
|
8
7
|
const file_system_1 = require("./utils/file-system");
|
|
9
|
-
const casing_1 = require("./utils/casing");
|
|
10
8
|
const field_1 = require("./utils/field");
|
|
11
9
|
const relationships_1 = require("./utils/relationships");
|
|
10
|
+
const casing_1 = require("./utils/casing");
|
|
11
|
+
const pluralize_1 = tslib_1.__importDefault(require("pluralize"));
|
|
12
|
+
/**
|
|
13
|
+
* Generates a TypeORM entity file based on the entity definition and relationships.
|
|
14
|
+
*
|
|
15
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
16
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
17
|
+
* @param relationshipsNew An array of processed Relationship objects for this entity.
|
|
18
|
+
* @param apiType The type of API being generated (e.g., "rest", "graphql").
|
|
19
|
+
* @returns {Promise<void>} A promise that resolves when the entity file is created.
|
|
20
|
+
*/
|
|
12
21
|
const createEntity = async (apiBaseDir, entity, relationshipsNew, apiType) => {
|
|
13
22
|
const { name, fields = [], indexes, uniques } = entity;
|
|
14
23
|
const File = path.join(apiBaseDir, `${name}.entity.ts`);
|
|
@@ -37,7 +46,8 @@ const createEntity = async (apiBaseDir, entity, relationshipsNew, apiType) => {
|
|
|
37
46
|
Eta.configure({
|
|
38
47
|
views: path.join(__dirname, "templates"),
|
|
39
48
|
});
|
|
40
|
-
const
|
|
49
|
+
const templatePath = apiType === "graphql" ? "./graphql/gql-entity-graphql" : "./entities/entity";
|
|
50
|
+
const content = await Eta.renderFileAsync(templatePath, data);
|
|
41
51
|
(0, file_system_1.createFile)(File, content);
|
|
42
52
|
};
|
|
43
53
|
exports.createEntity = createEntity;
|
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
import { Entity } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates an index file (e.g., index.ts) that exports all generated entity modules.
|
|
4
|
+
*
|
|
5
|
+
* This file serves as a central point for importing and managing the generated modules
|
|
6
|
+
* within the application, tailored to the specified API type (REST or GraphQL).
|
|
7
|
+
*
|
|
8
|
+
* @param apiBaseDir The base directory where the generated API modules reside (e.g., 'src/autogen').
|
|
9
|
+
* @param entities An array of Entity definition objects, used to determine which modules to export.
|
|
10
|
+
* @param apiType The type of API being generated ('rest' or 'graphql'), which determines the template used.
|
|
11
|
+
* @returns {Promise<void>} A promise that resolves when the index file is created.
|
|
12
|
+
*/
|
|
2
13
|
export declare const createIndexAppModule: (apiBaseDir: string, entities: Entity[], apiType: string) => Promise<void>;
|
package/dist/lib/index-module.js
CHANGED
|
@@ -5,6 +5,17 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const file_system_1 = require("./utils/file-system");
|
|
6
6
|
const Eta = tslib_1.__importStar(require("eta"));
|
|
7
7
|
const path = tslib_1.__importStar(require("path"));
|
|
8
|
+
/**
|
|
9
|
+
* Generates an index file (e.g., index.ts) that exports all generated entity modules.
|
|
10
|
+
*
|
|
11
|
+
* This file serves as a central point for importing and managing the generated modules
|
|
12
|
+
* within the application, tailored to the specified API type (REST or GraphQL).
|
|
13
|
+
*
|
|
14
|
+
* @param apiBaseDir The base directory where the generated API modules reside (e.g., 'src/autogen').
|
|
15
|
+
* @param entities An array of Entity definition objects, used to determine which modules to export.
|
|
16
|
+
* @param apiType The type of API being generated ('rest' or 'graphql'), which determines the template used.
|
|
17
|
+
* @returns {Promise<void>} A promise that resolves when the index file is created.
|
|
18
|
+
*/
|
|
8
19
|
const createIndexAppModule = async (apiBaseDir, entities, apiType) => {
|
|
9
20
|
const File = path.join(apiBaseDir, `index.ts`);
|
|
10
21
|
Eta.configure({
|
package/dist/lib/module.d.ts
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { Entity } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates a NestJS module file for a given entity.
|
|
4
|
+
*
|
|
5
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
6
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
7
|
+
* @param options Optional configuration flags.
|
|
8
|
+
* @param options.apiType The type of API being generated (default: "rest").
|
|
9
|
+
* @returns {Promise<void>} A promise that resolves when the module file is created.
|
|
10
|
+
*/
|
|
11
|
+
export declare const createModule: (apiBaseDir: string, entity: Entity, options?: {
|
|
12
|
+
apiType?: string;
|
|
13
|
+
}) => Promise<void>;
|
package/dist/lib/module.js
CHANGED
|
@@ -5,24 +5,40 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const Eta = tslib_1.__importStar(require("eta"));
|
|
6
6
|
const path = tslib_1.__importStar(require("path"));
|
|
7
7
|
const file_system_1 = require("./utils/file-system");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Generates a NestJS module file for a given entity.
|
|
10
|
+
*
|
|
11
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
12
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
13
|
+
* @param options Optional configuration flags.
|
|
14
|
+
* @param options.apiType The type of API being generated (default: "rest").
|
|
15
|
+
* @returns {Promise<void>} A promise that resolves when the module file is created.
|
|
16
|
+
*/
|
|
17
|
+
const createModule = async (apiBaseDir, entity, options) => {
|
|
18
|
+
const { name: entityName } = entity;
|
|
19
|
+
const moduleFileName = path.join(apiBaseDir, `${entityName}.module.ts`);
|
|
20
|
+
// Names needed by the templates
|
|
21
|
+
const moduleName = `${entityName}Module`;
|
|
11
22
|
const svcName = `${entityName}Service`;
|
|
12
|
-
const ctrlName = `${entityName}Controller`;
|
|
13
|
-
const
|
|
14
|
-
|
|
23
|
+
const ctrlName = `${entityName}Controller`; // Used by REST template
|
|
24
|
+
const resolverName = `${entityName}Resolver`; // Used by GQL template
|
|
25
|
+
// Data for the Eta templates
|
|
15
26
|
const data = {
|
|
27
|
+
moduleName,
|
|
16
28
|
svcName,
|
|
17
29
|
ctrlName,
|
|
18
|
-
|
|
30
|
+
resolverName,
|
|
19
31
|
entityName,
|
|
20
|
-
pluralEntityName,
|
|
21
32
|
};
|
|
33
|
+
// Configure Eta
|
|
22
34
|
Eta.configure({
|
|
23
35
|
views: path.join(__dirname, "templates"),
|
|
24
36
|
});
|
|
25
|
-
|
|
26
|
-
(0
|
|
37
|
+
// Determine template based on API type
|
|
38
|
+
const templatePath = (options === null || options === void 0 ? void 0 : options.apiType) === "graphql" ? "./graphql/gql-module-graphql" : "./rest/module-rest";
|
|
39
|
+
// Render the template
|
|
40
|
+
const content = await Eta.renderFileAsync(templatePath, data);
|
|
41
|
+
// Create the module file
|
|
42
|
+
(0, file_system_1.createFile)(moduleFileName, content);
|
|
27
43
|
};
|
|
28
44
|
exports.createModule = createModule;
|
package/dist/lib/service.d.ts
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import { Entity } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Generates NestJS service and spec files for a given entity.
|
|
4
|
+
*
|
|
5
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
6
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
7
|
+
* @returns {Promise<void>} A promise that resolves when the service and spec files are created.
|
|
8
|
+
*/
|
|
9
|
+
export declare const createService: (apiBaseDir: string, entity: Entity) => Promise<void>;
|
package/dist/lib/service.js
CHANGED
|
@@ -5,20 +5,35 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const file_system_1 = require("./utils/file-system");
|
|
6
6
|
const Eta = tslib_1.__importStar(require("eta"));
|
|
7
7
|
const path = tslib_1.__importStar(require("path"));
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Generates NestJS service and spec files for a given entity.
|
|
10
|
+
*
|
|
11
|
+
* @param apiBaseDir The base directory for the generated API module (e.g., 'src/autogen/users').
|
|
12
|
+
* @param entity The entity definition object from the parsed .apsorc.
|
|
13
|
+
* @returns {Promise<void>} A promise that resolves when the service and spec files are created.
|
|
14
|
+
*/
|
|
15
|
+
const createService = async (apiBaseDir, entity) => {
|
|
16
|
+
const { name: entityName } = entity;
|
|
17
|
+
const serviceFileName = path.join(apiBaseDir, `${entityName}.service.ts`);
|
|
18
|
+
const specFileName = path.join(apiBaseDir, `${entityName}.service.spec.ts`);
|
|
19
|
+
// Names needed by the templates
|
|
11
20
|
const svcName = `${entityName}Service`;
|
|
12
|
-
const
|
|
21
|
+
const repoName = `${entityName}Repository`; // Assuming convention
|
|
22
|
+
// Data for the Eta templates
|
|
13
23
|
const data = {
|
|
14
24
|
svcName,
|
|
25
|
+
repoName,
|
|
15
26
|
entityName,
|
|
16
|
-
pluralEntityName,
|
|
17
27
|
};
|
|
28
|
+
// Configure Eta
|
|
18
29
|
Eta.configure({
|
|
19
30
|
views: path.join(__dirname, "templates"),
|
|
20
31
|
});
|
|
21
|
-
|
|
22
|
-
|
|
32
|
+
// Render service template
|
|
33
|
+
const serviceContent = await Eta.renderFileAsync("./rest/service-rest", data);
|
|
34
|
+
(0, file_system_1.createFile)(serviceFileName, serviceContent);
|
|
35
|
+
// Render spec template
|
|
36
|
+
const specContent = await Eta.renderFileAsync("./rest/service-rest-spec", data);
|
|
37
|
+
(0, file_system_1.createFile)(specFileName, specContent);
|
|
23
38
|
};
|
|
24
39
|
exports.createService = createService;
|