@lenne.tech/cli 0.0.124 → 0.0.125
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/build/commands/claude/claude.js +25 -0
- package/build/commands/claude/install-skill.js +93 -0
- package/build/commands/fullstack/init.js +38 -16
- package/build/commands/server/add-property.js +38 -11
- package/build/commands/server/module.js +21 -11
- package/build/commands/server/object.js +17 -9
- package/build/extensions/parse-properties.js +119 -0
- package/build/templates/claude-skills/lt-cli/SKILL.md +341 -0
- package/build/templates/claude-skills/lt-cli/examples.md +312 -0
- package/build/templates/claude-skills/lt-cli/reference.md +332 -0
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/**
|
|
13
|
+
* Extend toolbox with parseProperties() helper.
|
|
14
|
+
*/
|
|
15
|
+
exports.default = (toolbox) => {
|
|
16
|
+
toolbox.parseProperties = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const { parameters: globalParameters, server: globalServer } = toolbox;
|
|
18
|
+
const { argProps = Object.keys(globalParameters.options || {}).filter(key => key.startsWith('prop')), objectsToAdd = [], parameters = globalParameters, referencesToAdd = [], server = globalServer, } = options || {};
|
|
19
|
+
// --- CLI Mode ---
|
|
20
|
+
if (argProps.length > 0) {
|
|
21
|
+
const { print } = toolbox;
|
|
22
|
+
// Count how many prop-name flags exist
|
|
23
|
+
const propNameFlags = argProps.filter(key => key.startsWith('prop-name'));
|
|
24
|
+
const hasMultipleProps = propNameFlags.length > 1;
|
|
25
|
+
// If multiple properties, all must have numeric indices
|
|
26
|
+
if (hasMultipleProps) {
|
|
27
|
+
const hasNonIndexed = propNameFlags.some(key => !key.match(/^prop-name-\d+$/));
|
|
28
|
+
if (hasNonIndexed) {
|
|
29
|
+
print.error('When adding multiple properties, all must use numeric indices (e.g., --prop-name-0, --prop-name-1)');
|
|
30
|
+
print.info('');
|
|
31
|
+
print.info('Example:');
|
|
32
|
+
print.info(' lt server addProp --type Module --element User \\');
|
|
33
|
+
print.info(' --prop-name-0 email --prop-type-0 string \\');
|
|
34
|
+
print.info(' --prop-name-1 age --prop-type-1 number');
|
|
35
|
+
throw new Error('Invalid property flags: Multiple properties require numeric indices');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Extract index from prop key (e.g., 'prop-name-1' -> 1)
|
|
39
|
+
const extractIndex = (key, prefix) => {
|
|
40
|
+
const match = key.match(new RegExp(`^${prefix}-(\\d+)$`));
|
|
41
|
+
return match ? parseInt(match[1], 10) : -1;
|
|
42
|
+
};
|
|
43
|
+
// Build a map of index -> property data
|
|
44
|
+
const propDataByIndex = new Map();
|
|
45
|
+
for (const key of argProps) {
|
|
46
|
+
let index = -1;
|
|
47
|
+
let field = '';
|
|
48
|
+
if (key.startsWith('prop-name-')) {
|
|
49
|
+
index = extractIndex(key, 'prop-name');
|
|
50
|
+
field = 'name';
|
|
51
|
+
}
|
|
52
|
+
else if (key.startsWith('prop-type-')) {
|
|
53
|
+
index = extractIndex(key, 'prop-type');
|
|
54
|
+
field = 'type';
|
|
55
|
+
}
|
|
56
|
+
else if (key.startsWith('prop-nullable-')) {
|
|
57
|
+
index = extractIndex(key, 'prop-nullable');
|
|
58
|
+
field = 'nullable';
|
|
59
|
+
}
|
|
60
|
+
else if (key.startsWith('prop-array-')) {
|
|
61
|
+
index = extractIndex(key, 'prop-array');
|
|
62
|
+
field = 'isArray';
|
|
63
|
+
}
|
|
64
|
+
else if (key.startsWith('prop-enum-')) {
|
|
65
|
+
index = extractIndex(key, 'prop-enum');
|
|
66
|
+
field = 'enumRef';
|
|
67
|
+
}
|
|
68
|
+
else if (key.startsWith('prop-schema-')) {
|
|
69
|
+
index = extractIndex(key, 'prop-schema');
|
|
70
|
+
field = 'schema';
|
|
71
|
+
}
|
|
72
|
+
else if (key.startsWith('prop-reference-')) {
|
|
73
|
+
index = extractIndex(key, 'prop-reference');
|
|
74
|
+
field = 'reference';
|
|
75
|
+
}
|
|
76
|
+
if (index >= 0 && field) {
|
|
77
|
+
if (!propDataByIndex.has(index)) {
|
|
78
|
+
propDataByIndex.set(index, {
|
|
79
|
+
enumRef: null,
|
|
80
|
+
isArray: false,
|
|
81
|
+
name: '',
|
|
82
|
+
nullable: false,
|
|
83
|
+
reference: null,
|
|
84
|
+
schema: null,
|
|
85
|
+
type: 'string',
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const propData = propDataByIndex.get(index);
|
|
89
|
+
const value = parameters.options[key];
|
|
90
|
+
if (field === 'nullable' || field === 'isArray') {
|
|
91
|
+
propData[field] = value === 'true';
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
propData[field] = value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Convert map to props object
|
|
99
|
+
const props = {};
|
|
100
|
+
for (const propData of propDataByIndex.values()) {
|
|
101
|
+
if (!propData.name) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
props[propData.name] = propData;
|
|
105
|
+
}
|
|
106
|
+
return { objectsToAdd, props, referencesToAdd, refsSet: false, schemaSet: false };
|
|
107
|
+
}
|
|
108
|
+
// --- Interactive Mode ---
|
|
109
|
+
const result = yield server.addProperties({ objectsToAdd, referencesToAdd });
|
|
110
|
+
return {
|
|
111
|
+
objectsToAdd: result.objectsToAdd,
|
|
112
|
+
props: result.props,
|
|
113
|
+
referencesToAdd: result.referencesToAdd,
|
|
114
|
+
refsSet: result.refsSet,
|
|
115
|
+
schemaSet: result.schemaSet,
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2UtcHJvcGVydGllcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9leHRlbnNpb25zL3BhcnNlLXByb3BlcnRpZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFVQTs7R0FFRztBQUNILGtCQUFlLENBQUMsT0FBK0IsRUFBRSxFQUFFO0lBQ2pELE9BQU8sQ0FBQyxlQUFlLEdBQUcsQ0FDeEIsT0FNQyxFQUMyQixFQUFFO1FBQzlCLE1BQU0sRUFBRSxVQUFVLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxHQUFHLE9BQU8sQ0FBQztRQUN2RSxNQUFNLEVBQ0osUUFBUSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsRUFDNUYsWUFBWSxHQUFHLEVBQUUsRUFDakIsVUFBVSxHQUFHLGdCQUFnQixFQUM3QixlQUFlLEdBQUcsRUFBRSxFQUNwQixNQUFNLEdBQUcsWUFBWSxHQUN0QixHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDbEIsbUJBQW1CO1FBQ25CLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsT0FBTyxDQUFDO1lBRTFCLHVDQUF1QztZQUN2QyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzFFLE1BQU0sZ0JBQWdCLEdBQUcsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7WUFFbEQsd0RBQXdEO1lBQ3hELElBQUksZ0JBQWdCLEVBQUUsQ0FBQztnQkFDckIsTUFBTSxhQUFh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
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lt-cli
|
|
3
|
+
description: Expert assistance with lenne.tech CLI for NestJS/TypeScript backend development. Use when creating server modules, objects, or adding properties to NestJS backends. Generates correct lt server commands with proper --prop-name-X syntax. Helps with lt server module, lt server object, lt server addProp, and lt fullstack init commands.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# LT CLI Expert
|
|
7
|
+
|
|
8
|
+
You are an expert in the lenne.tech CLI tool for NestJS/TypeScript backend development. When this skill is active, help users generate correct LT CLI commands and work efficiently with the framework.
|
|
9
|
+
|
|
10
|
+
## Available Commands
|
|
11
|
+
|
|
12
|
+
### 1. Create Server Module
|
|
13
|
+
**Command**: `lt server module` (alias: `lt server m`)
|
|
14
|
+
|
|
15
|
+
Creates a complete NestJS module with model, service, controller/resolver, and DTOs.
|
|
16
|
+
|
|
17
|
+
**Non-interactive syntax**:
|
|
18
|
+
```bash
|
|
19
|
+
lt server module --name <ModuleName> --controller <Rest|GraphQL|Both> [property-flags]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Property flags** (multiple properties with different indices):
|
|
23
|
+
- `--prop-name-X <name>` - Property name (X = 0, 1, 2...)
|
|
24
|
+
- `--prop-type-X <type>` - string, number, boolean, ObjectId, Json, Date, etc.
|
|
25
|
+
- `--prop-nullable-X <true|false>` - Optional property
|
|
26
|
+
- `--prop-array-X <true|false>` - Array type
|
|
27
|
+
- `--prop-enum-X <EnumName>` - Enum reference
|
|
28
|
+
- `--prop-schema-X <SchemaName>` - Object/schema reference
|
|
29
|
+
- `--prop-reference-X <RefName>` - Reference name for ObjectId
|
|
30
|
+
- `--skipLint` - Skip lint prompt
|
|
31
|
+
|
|
32
|
+
**Example**:
|
|
33
|
+
```bash
|
|
34
|
+
lt server module --name Post --controller GraphQL \
|
|
35
|
+
--prop-name-0 title --prop-type-0 string \
|
|
36
|
+
--prop-name-1 content --prop-type-1 string --prop-nullable-1 true \
|
|
37
|
+
--prop-name-2 author --prop-type-2 ObjectId --prop-reference-2 User \
|
|
38
|
+
--prop-name-3 tags --prop-type-3 string --prop-array-3 true
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 2. Add Properties to Existing Module/Object
|
|
42
|
+
**Command**: `lt server addProp` (alias: `lt server ap`)
|
|
43
|
+
|
|
44
|
+
Adds properties to existing modules or objects, updating model and input files.
|
|
45
|
+
|
|
46
|
+
**Non-interactive syntax**:
|
|
47
|
+
```bash
|
|
48
|
+
lt server addProp --type <Module|Object> --element <name> [property-flags]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Example**:
|
|
52
|
+
```bash
|
|
53
|
+
lt server addProp --type Module --element User \
|
|
54
|
+
--prop-name-0 email --prop-type-0 string \
|
|
55
|
+
--prop-name-1 age --prop-type-1 number --prop-nullable-1 true
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. Create Server Object
|
|
59
|
+
**Command**: `lt server object` (alias: `lt server o`)
|
|
60
|
+
|
|
61
|
+
Creates reusable data structures (objects) for embedding in modules.
|
|
62
|
+
|
|
63
|
+
**Non-interactive syntax**:
|
|
64
|
+
```bash
|
|
65
|
+
lt server object --name <ObjectName> [property-flags] [--skipLint]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Example**:
|
|
69
|
+
```bash
|
|
70
|
+
lt server object --name Address \
|
|
71
|
+
--prop-name-0 street --prop-type-0 string \
|
|
72
|
+
--prop-name-1 city --prop-type-1 string \
|
|
73
|
+
--prop-name-2 zipCode --prop-type-2 string
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 4. Initialize Fullstack Workspace
|
|
77
|
+
**Command**: `lt fullstack init` (alias: `lt full init`)
|
|
78
|
+
|
|
79
|
+
Creates complete fullstack workspace with frontend and backend.
|
|
80
|
+
|
|
81
|
+
**Non-interactive syntax**:
|
|
82
|
+
```bash
|
|
83
|
+
lt fullstack init --name <WorkspaceName> --frontend <angular|nuxt> --git <true|false> --git-link <GitURL>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Example**:
|
|
87
|
+
```bash
|
|
88
|
+
lt fullstack init --name MyApp --frontend angular --git true --git-link https://github.com/user/repo.git
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Critical Rules for Command Generation
|
|
92
|
+
|
|
93
|
+
### 1. Index-Based Property Flags
|
|
94
|
+
Always use numbered indices for property flags:
|
|
95
|
+
```bash
|
|
96
|
+
# CORRECT
|
|
97
|
+
--prop-name-0 title --prop-type-0 string \
|
|
98
|
+
--prop-name-1 content --prop-type-1 string
|
|
99
|
+
|
|
100
|
+
# WRONG - Don't use sequential arrays
|
|
101
|
+
--prop-name title --prop-type string
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 2. Match Indices Across Flags
|
|
105
|
+
All flags for one property must use the same index:
|
|
106
|
+
```bash
|
|
107
|
+
# CORRECT
|
|
108
|
+
--prop-name-1 company --prop-type-1 string --prop-nullable-1 false
|
|
109
|
+
|
|
110
|
+
# WRONG - Mixed indices
|
|
111
|
+
--prop-name-1 company --prop-type-0 string --prop-nullable-2 false
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 3. ObjectId References
|
|
115
|
+
Always include `--prop-reference-X` with ObjectId type:
|
|
116
|
+
```bash
|
|
117
|
+
--prop-name-0 author --prop-type-0 ObjectId --prop-reference-0 User
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 4. Schema/Object Properties
|
|
121
|
+
Use `--prop-schema-X` for embedding objects:
|
|
122
|
+
```bash
|
|
123
|
+
--prop-name-0 address --prop-schema-0 Address
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 5. Boolean Values
|
|
127
|
+
Use lowercase string literals:
|
|
128
|
+
```bash
|
|
129
|
+
--prop-nullable-0 true # CORRECT
|
|
130
|
+
--prop-nullable-0 True # WRONG
|
|
131
|
+
--prop-nullable-0 TRUE # WRONG
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Property Types Reference
|
|
135
|
+
|
|
136
|
+
### Primitive Types
|
|
137
|
+
- `string` - Text values
|
|
138
|
+
- `number` - Numeric values
|
|
139
|
+
- `boolean` - True/false
|
|
140
|
+
- `bigint` - Large integers
|
|
141
|
+
- `Date` - Date/time values
|
|
142
|
+
|
|
143
|
+
### Special Types
|
|
144
|
+
- `ObjectId` - MongoDB reference (requires `--prop-reference-X`)
|
|
145
|
+
- `Json` - JSON data for flexible metadata
|
|
146
|
+
- Custom objects (requires `--prop-schema-X`)
|
|
147
|
+
- Custom enums (requires `--prop-enum-X`) - **Note: CLI generates the reference, but you must create the enum file manually afterwards**
|
|
148
|
+
|
|
149
|
+
### Modifiers
|
|
150
|
+
- `--prop-nullable-X true` - Makes property optional
|
|
151
|
+
- `--prop-array-X true` - Makes property an array type
|
|
152
|
+
|
|
153
|
+
## Common Patterns
|
|
154
|
+
|
|
155
|
+
### User Authentication
|
|
156
|
+
```bash
|
|
157
|
+
lt server module --name User --controller Both \
|
|
158
|
+
--prop-name-0 email --prop-type-0 string \
|
|
159
|
+
--prop-name-1 username --prop-type-1 string \
|
|
160
|
+
--prop-name-2 roles --prop-type-2 string --prop-array-2 true \
|
|
161
|
+
--prop-name-3 verified --prop-type-3 boolean
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Blog Post with Relationships
|
|
165
|
+
```bash
|
|
166
|
+
lt server module --name Post --controller GraphQL \
|
|
167
|
+
--prop-name-0 title --prop-type-0 string \
|
|
168
|
+
--prop-name-1 content --prop-type-1 string \
|
|
169
|
+
--prop-name-2 author --prop-type-2 ObjectId --prop-reference-2 User \
|
|
170
|
+
--prop-name-3 tags --prop-type-3 string --prop-array-3 true \
|
|
171
|
+
--prop-name-4 published --prop-type-4 boolean
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### E-commerce Product
|
|
175
|
+
```bash
|
|
176
|
+
lt server module --name Product --controller Both \
|
|
177
|
+
--prop-name-0 name --prop-type-0 string \
|
|
178
|
+
--prop-name-1 description --prop-type-1 string --prop-nullable-1 true \
|
|
179
|
+
--prop-name-2 price --prop-type-2 number \
|
|
180
|
+
--prop-name-3 stock --prop-type-3 number \
|
|
181
|
+
--prop-name-4 category --prop-enum-4 ProductCategoryEnum \
|
|
182
|
+
--prop-name-5 metadata --prop-type-5 Json --prop-nullable-5 true
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Nested Object Pattern
|
|
186
|
+
```bash
|
|
187
|
+
# First create the object
|
|
188
|
+
lt server object --name Address \
|
|
189
|
+
--prop-name-0 street --prop-type-0 string \
|
|
190
|
+
--prop-name-1 city --prop-type-1 string \
|
|
191
|
+
--prop-name-2 country --prop-type-2 string
|
|
192
|
+
|
|
193
|
+
# Then use it in a module
|
|
194
|
+
lt server addProp --type Module --element User \
|
|
195
|
+
--prop-name-0 address --prop-schema-0 Address
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Project Structure
|
|
199
|
+
|
|
200
|
+
The CLI expects this structure:
|
|
201
|
+
```
|
|
202
|
+
src/
|
|
203
|
+
server/
|
|
204
|
+
modules/
|
|
205
|
+
<module-name>/
|
|
206
|
+
<module-name>.model.ts # MongoDB schema
|
|
207
|
+
<module-name>.service.ts # Business logic
|
|
208
|
+
<module-name>.controller.ts # REST controller
|
|
209
|
+
<module-name>.resolver.ts # GraphQL resolver
|
|
210
|
+
<module-name>.module.ts # NestJS module
|
|
211
|
+
inputs/
|
|
212
|
+
<module-name>.input.ts # Update DTO
|
|
213
|
+
<module-name>-create.input.ts # Create DTO
|
|
214
|
+
outputs/
|
|
215
|
+
find-and-count-<module-name>s-result.output.ts
|
|
216
|
+
common/
|
|
217
|
+
objects/
|
|
218
|
+
<object-name>/
|
|
219
|
+
<object-name>.object.ts
|
|
220
|
+
<object-name>.input.ts
|
|
221
|
+
<object-name>-create.input.ts
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Generated Code Features
|
|
225
|
+
|
|
226
|
+
### Model Files (.model.ts)
|
|
227
|
+
- MongoDB schema with `@Prop()` decorator
|
|
228
|
+
- `@UnifiedField()` decorator for GraphQL/REST
|
|
229
|
+
- Mongoose schema definition
|
|
230
|
+
- TypeScript typing with proper suffixes
|
|
231
|
+
|
|
232
|
+
### Input Files (.input.ts / -create.input.ts)
|
|
233
|
+
- `@UnifiedField()` decorator
|
|
234
|
+
- Validation decorators
|
|
235
|
+
- TypeScript typing
|
|
236
|
+
- Generic support for references
|
|
237
|
+
|
|
238
|
+
### Service Files (.service.ts)
|
|
239
|
+
- CRUD operations
|
|
240
|
+
- Pagination support
|
|
241
|
+
- Reference handling
|
|
242
|
+
- Business logic structure
|
|
243
|
+
|
|
244
|
+
### Controller/Resolver Files
|
|
245
|
+
- REST endpoints (controller)
|
|
246
|
+
- GraphQL queries/mutations (resolver)
|
|
247
|
+
- Proper authentication guards
|
|
248
|
+
- DTO validation
|
|
249
|
+
|
|
250
|
+
## Troubleshooting
|
|
251
|
+
|
|
252
|
+
### Property Index Mismatch
|
|
253
|
+
**Symptom**: Properties not created correctly or values mixed up
|
|
254
|
+
**Cause**: Using wrong indices (e.g., `--prop-name-1` with `--prop-type-0`)
|
|
255
|
+
**Solution**: Ensure all flags for one property use the same index
|
|
256
|
+
|
|
257
|
+
### ObjectId Without Reference
|
|
258
|
+
**Symptom**: TypeScript errors about missing reference
|
|
259
|
+
**Cause**: Using `ObjectId` type without `--prop-reference-X`
|
|
260
|
+
**Solution**: Always pair ObjectId with reference:
|
|
261
|
+
```bash
|
|
262
|
+
--prop-type-0 ObjectId --prop-reference-0 User
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Module Already Exists
|
|
266
|
+
**Symptom**: Error that module directory exists
|
|
267
|
+
**Solution**: Use `lt server addProp` instead to add to existing modules
|
|
268
|
+
|
|
269
|
+
### Empty Property Lists
|
|
270
|
+
**Symptom**: "Cannot read properties of undefined"
|
|
271
|
+
**Status**: Fixed in latest version
|
|
272
|
+
**Solution**: Update to latest CLI version
|
|
273
|
+
|
|
274
|
+
## Best Practices
|
|
275
|
+
|
|
276
|
+
1. **Plan relationships first**: Sketch entity relationships before generating
|
|
277
|
+
2. **Create objects for reusable structures**: Don't duplicate data structures
|
|
278
|
+
3. **Use meaningful names**: PascalCase for modules/objects, camelCase for properties
|
|
279
|
+
4. **Start with one API type**: Use Rest or GraphQL, add Both later if needed
|
|
280
|
+
5. **Create enum files after generation**: CLI generates enum references, you create the actual enum files manually afterwards in `src/server/common/enums/`
|
|
281
|
+
6. **Mark truly optional fields**: Only use nullable for genuinely optional data
|
|
282
|
+
7. **Use JSON for extensibility**: Metadata and flexible fields work well as JSON
|
|
283
|
+
8. **Run lint after generation**: Always run lint fix for code quality
|
|
284
|
+
9. **Test incrementally**: Generate one module, test, then continue
|
|
285
|
+
10. **Version control**: Commit after successful generation
|
|
286
|
+
|
|
287
|
+
## Working with This Skill
|
|
288
|
+
|
|
289
|
+
When helping users:
|
|
290
|
+
|
|
291
|
+
1. **Clarify requirements**: Ask about API type (REST/GraphQL/Both), relationships, data types
|
|
292
|
+
2. **Suggest architecture**: Recommend objects for shared structures, modules for entities
|
|
293
|
+
3. **Generate complete commands**: Include all necessary flags with correct syntax
|
|
294
|
+
4. **Explain side effects**: Describe what files will be created and where
|
|
295
|
+
5. **Provide next steps**: Suggest related modules, testing, or additional properties
|
|
296
|
+
|
|
297
|
+
### Example Response Pattern
|
|
298
|
+
|
|
299
|
+
User: "Create a Task module with title, description, due date, and assignee"
|
|
300
|
+
|
|
301
|
+
Your response:
|
|
302
|
+
```bash
|
|
303
|
+
# First ensure User module exists, then create Task module
|
|
304
|
+
lt server module --name Task --controller Both \
|
|
305
|
+
--prop-name-0 title --prop-type-0 string \
|
|
306
|
+
--prop-name-1 description --prop-type-1 string --prop-nullable-1 true \
|
|
307
|
+
--prop-name-2 dueDate --prop-type-2 Date --prop-nullable-2 true \
|
|
308
|
+
--prop-name-3 assignee --prop-type-3 ObjectId --prop-reference-3 User \
|
|
309
|
+
--prop-name-4 status --prop-enum-4 TaskStatusEnum
|
|
310
|
+
|
|
311
|
+
# This creates:
|
|
312
|
+
# ✓ Task model with MongoDB schema
|
|
313
|
+
# ✓ Task service with CRUD operations
|
|
314
|
+
# ✓ REST controller and GraphQL resolver
|
|
315
|
+
# ✓ Input DTOs for create/update
|
|
316
|
+
|
|
317
|
+
# Next steps:
|
|
318
|
+
# 1. Manually create TaskStatusEnum file in src/server/common/enums/task-status.enum.ts
|
|
319
|
+
# 2. Verify User module exists
|
|
320
|
+
# 3. Run lint fix
|
|
321
|
+
# 4. Add custom business logic to TaskService
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## Integration Details
|
|
325
|
+
|
|
326
|
+
- Uses `ts-morph` for AST manipulation
|
|
327
|
+
- Integrates with `@lenne.tech/nest-server` package
|
|
328
|
+
- Generates `@UnifiedField()` decorators for dual REST/GraphQL support
|
|
329
|
+
- Handles `useDefineForClassFields` TypeScript config
|
|
330
|
+
- Automatically adds properties to `.model.ts`, `.input.ts`, and `-create.input.ts`
|
|
331
|
+
- Manages imports and decorators automatically
|
|
332
|
+
|
|
333
|
+
## Important Notes
|
|
334
|
+
|
|
335
|
+
- CLI works from anywhere in project directory
|
|
336
|
+
- Automatically finds nearest `src/` directory
|
|
337
|
+
- Properties are added with proper TypeScript typing
|
|
338
|
+
- ObjectId properties become Reference/ReferenceInput in generated code
|
|
339
|
+
- The CLI prompts for lint fix after generation (use `--skipLint` to skip)
|
|
340
|
+
- Manual imports may be needed for references and schemas
|
|
341
|
+
- **Enum files must be created manually**: When using `--prop-enum-X`, the CLI generates the reference in your code, but you must create the actual enum file yourself afterwards in `src/server/common/enums/<enum-name>.enum.ts`
|