@kithinji/pod 1.0.0
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.js +22 -0
- package/dist/main.js +4464 -0
- package/dist/main.js.map +7 -0
- package/dist/types/add/component/component.d.ts +5 -0
- package/dist/types/add/component/component.d.ts.map +1 -0
- package/dist/types/add/component/index.d.ts +2 -0
- package/dist/types/add/component/index.d.ts.map +1 -0
- package/dist/types/add/index.d.ts +4 -0
- package/dist/types/add/index.d.ts.map +1 -0
- package/dist/types/add/module/index.d.ts +2 -0
- package/dist/types/add/module/index.d.ts.map +1 -0
- package/dist/types/add/module/module.d.ts +3 -0
- package/dist/types/add/module/module.d.ts.map +1 -0
- package/dist/types/add/new/index.d.ts +2 -0
- package/dist/types/add/new/index.d.ts.map +1 -0
- package/dist/types/config/config.d.ts +18 -0
- package/dist/types/config/config.d.ts.map +1 -0
- package/dist/types/config/index.d.ts +2 -0
- package/dist/types/config/index.d.ts.map +1 -0
- package/dist/types/dev/index.d.ts +2 -0
- package/dist/types/dev/index.d.ts.map +1 -0
- package/dist/types/dev/project.d.ts +9 -0
- package/dist/types/dev/project.d.ts.map +1 -0
- package/dist/types/dev/server.d.ts +2 -0
- package/dist/types/dev/server.d.ts.map +1 -0
- package/dist/types/docker/docker.d.ts +2 -0
- package/dist/types/docker/docker.d.ts.map +1 -0
- package/dist/types/docker/index.d.ts +2 -0
- package/dist/types/docker/index.d.ts.map +1 -0
- package/dist/types/macros/expand_macros.d.ts +48 -0
- package/dist/types/macros/expand_macros.d.ts.map +1 -0
- package/dist/types/macros/index.d.ts +3 -0
- package/dist/types/macros/index.d.ts.map +1 -0
- package/dist/types/macros/macro_executer.d.ts +12 -0
- package/dist/types/macros/macro_executer.d.ts.map +1 -0
- package/dist/types/main.d.ts +13 -0
- package/dist/types/main.d.ts.map +1 -0
- package/dist/types/plugins/analyzers/graph.d.ts +25 -0
- package/dist/types/plugins/analyzers/graph.d.ts.map +1 -0
- package/dist/types/plugins/css/index.d.ts +7 -0
- package/dist/types/plugins/css/index.d.ts.map +1 -0
- package/dist/types/plugins/generators/generate_controller.d.ts +2 -0
- package/dist/types/plugins/generators/generate_controller.d.ts.map +1 -0
- package/dist/types/plugins/generators/generate_rsc.d.ts +2 -0
- package/dist/types/plugins/generators/generate_rsc.d.ts.map +1 -0
- package/dist/types/plugins/generators/generate_server_component.d.ts +2 -0
- package/dist/types/plugins/generators/generate_server_component.d.ts.map +1 -0
- package/dist/types/plugins/generators/tsx_server_stub.d.ts +2 -0
- package/dist/types/plugins/generators/tsx_server_stub.d.ts.map +1 -0
- package/dist/types/plugins/index.d.ts +4 -0
- package/dist/types/plugins/index.d.ts.map +1 -0
- package/dist/types/plugins/my.d.ts +10 -0
- package/dist/types/plugins/my.d.ts.map +1 -0
- package/dist/types/plugins/transformers/j2d.d.ts +11 -0
- package/dist/types/plugins/transformers/j2d.d.ts.map +1 -0
- package/dist/types/store/index.d.ts +2 -0
- package/dist/types/store/index.d.ts.map +1 -0
- package/dist/types/store/store.d.ts +14 -0
- package/dist/types/store/store.d.ts.map +1 -0
- package/dist/types/utils/cases.d.ts +4 -0
- package/dist/types/utils/cases.d.ts.map +1 -0
- package/dist/types/utils/create.d.ts +12 -0
- package/dist/types/utils/create.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +3 -0
- package/dist/types/utils/index.d.ts.map +1 -0
- package/package.json +44 -0
- package/src/add/component/component.ts +496 -0
- package/src/add/component/index.ts +1 -0
- package/src/add/index.ts +3 -0
- package/src/add/module/index.ts +1 -0
- package/src/add/module/module.ts +521 -0
- package/src/add/new/index.ts +135 -0
- package/src/config/config.ts +141 -0
- package/src/config/index.ts +1 -0
- package/src/dev/index.ts +1 -0
- package/src/dev/project.ts +45 -0
- package/src/dev/server.ts +190 -0
- package/src/docker/docker.ts +452 -0
- package/src/docker/index.ts +1 -0
- package/src/macros/expand_macros.ts +791 -0
- package/src/macros/index.ts +2 -0
- package/src/macros/macro_executer.ts +189 -0
- package/src/main.ts +95 -0
- package/src/plugins/analyzers/graph.ts +291 -0
- package/src/plugins/css/index.ts +25 -0
- package/src/plugins/generators/generate_controller.ts +308 -0
- package/src/plugins/generators/generate_rsc.ts +274 -0
- package/src/plugins/generators/generate_server_component.ts +279 -0
- package/src/plugins/generators/tsx_server_stub.ts +295 -0
- package/src/plugins/index.ts +3 -0
- package/src/plugins/my.ts +274 -0
- package/src/plugins/transformers/j2d.ts +1014 -0
- package/src/store/index.ts +1 -0
- package/src/store/store.ts +44 -0
- package/src/utils/cases.ts +15 -0
- package/src/utils/create.ts +26 -0
- package/src/utils/index.ts +2 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import * as ts from "typescript";
|
|
4
|
+
|
|
5
|
+
abstract class ComponentDefinition {
|
|
6
|
+
abstract name: string;
|
|
7
|
+
abstract dependencies: string[];
|
|
8
|
+
abstract generate(): string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class ButtonComponent extends ComponentDefinition {
|
|
12
|
+
name = "button";
|
|
13
|
+
dependencies: string[] = [];
|
|
14
|
+
|
|
15
|
+
generate(): string {
|
|
16
|
+
return `"use interactive";
|
|
17
|
+
|
|
18
|
+
import { Component, JSX } from "@kithinji/orca";
|
|
19
|
+
|
|
20
|
+
@Component()
|
|
21
|
+
export class Button {
|
|
22
|
+
props!: {
|
|
23
|
+
children: any
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
build() {
|
|
27
|
+
return (
|
|
28
|
+
<button>
|
|
29
|
+
{this.props.children}
|
|
30
|
+
</button>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
class InputComponent extends ComponentDefinition {
|
|
39
|
+
name = "input";
|
|
40
|
+
dependencies: string[] = [];
|
|
41
|
+
|
|
42
|
+
generate(): string {
|
|
43
|
+
return `"use interactive";
|
|
44
|
+
|
|
45
|
+
import { Component } from "@kithinji/orca";
|
|
46
|
+
|
|
47
|
+
@Component()
|
|
48
|
+
export class Input {
|
|
49
|
+
build() {
|
|
50
|
+
return (
|
|
51
|
+
<input />
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
class FormComponent extends ComponentDefinition {
|
|
60
|
+
name = "form";
|
|
61
|
+
dependencies = ["button", "input"];
|
|
62
|
+
|
|
63
|
+
generate(): string {
|
|
64
|
+
return `"use interactive";
|
|
65
|
+
|
|
66
|
+
import { Component } from "@kithinji/orca";
|
|
67
|
+
import { Button } from "./button.component";
|
|
68
|
+
import { Input } from "./input.component";
|
|
69
|
+
|
|
70
|
+
@Component()
|
|
71
|
+
export class Form {
|
|
72
|
+
props!: {
|
|
73
|
+
onSubmit?: () => void;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
build() {
|
|
77
|
+
return (
|
|
78
|
+
<form onSubmit={this.props.onSubmit}>
|
|
79
|
+
<Input />
|
|
80
|
+
<Button>Submit</Button>
|
|
81
|
+
</form>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
class CardComponent extends ComponentDefinition {
|
|
90
|
+
name = "card";
|
|
91
|
+
dependencies = ["button"];
|
|
92
|
+
|
|
93
|
+
generate(): string {
|
|
94
|
+
return `"use interactive";
|
|
95
|
+
|
|
96
|
+
import { Component } from "@kithinji/orca";
|
|
97
|
+
import { Button } from "./button.component";
|
|
98
|
+
|
|
99
|
+
@Component()
|
|
100
|
+
export class Card {
|
|
101
|
+
props!: {
|
|
102
|
+
title: string;
|
|
103
|
+
children: any;
|
|
104
|
+
onAction?: () => void;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
build() {
|
|
108
|
+
return (
|
|
109
|
+
<div className="card">
|
|
110
|
+
<h3>{this.props.title}</h3>
|
|
111
|
+
<div>{this.props.children}</div>
|
|
112
|
+
{this.props.onAction && (
|
|
113
|
+
<Button onClick={this.props.onAction}>Action</Button>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
class ComponentRegistry {
|
|
124
|
+
private static components = new Map<string, ComponentDefinition>([
|
|
125
|
+
["button", new ButtonComponent()],
|
|
126
|
+
["input", new InputComponent()],
|
|
127
|
+
["form", new FormComponent()],
|
|
128
|
+
["card", new CardComponent()],
|
|
129
|
+
]);
|
|
130
|
+
|
|
131
|
+
static get(name: string): ComponentDefinition | undefined {
|
|
132
|
+
return this.components.get(name);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static has(name: string): boolean {
|
|
136
|
+
return this.components.has(name);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static getAll(): string[] {
|
|
140
|
+
return Array.from(this.components.keys());
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static register(component: ComponentDefinition): void {
|
|
144
|
+
this.components.set(component.name, component);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function addComponent(
|
|
149
|
+
name: string,
|
|
150
|
+
processedComponents: Set<string> = new Set()
|
|
151
|
+
) {
|
|
152
|
+
if (processedComponents.has(name)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const component = ComponentRegistry.get(name);
|
|
157
|
+
if (!component) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`Component "${name}" not found. Available components: ${ComponentRegistry.getAll().join(
|
|
160
|
+
", "
|
|
161
|
+
)}`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
processedComponents.add(name);
|
|
166
|
+
|
|
167
|
+
if (component.dependencies.length > 0) {
|
|
168
|
+
console.log(
|
|
169
|
+
`\nProcessing dependencies for "${name}": [${component.dependencies.join(
|
|
170
|
+
", "
|
|
171
|
+
)}]`
|
|
172
|
+
);
|
|
173
|
+
for (const dependency of component.dependencies) {
|
|
174
|
+
addComponent(dependency, processedComponents);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const componentModulePath = path.join(
|
|
179
|
+
process.cwd(),
|
|
180
|
+
"src/component/component.module.ts"
|
|
181
|
+
);
|
|
182
|
+
const componentPath = path.join(
|
|
183
|
+
process.cwd(),
|
|
184
|
+
`src/component/component/${name}.component.tsx`
|
|
185
|
+
);
|
|
186
|
+
const componentDir = path.dirname(componentPath);
|
|
187
|
+
const appModulePath = path.join(process.cwd(), "src/app/app.module.ts");
|
|
188
|
+
|
|
189
|
+
if (!fs.existsSync(componentModulePath)) {
|
|
190
|
+
const moduleDir = path.dirname(componentModulePath);
|
|
191
|
+
if (!fs.existsSync(moduleDir)) {
|
|
192
|
+
fs.mkdirSync(moduleDir, { recursive: true });
|
|
193
|
+
}
|
|
194
|
+
fs.writeFileSync(componentModulePath, createModule(), "utf-8");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!fs.existsSync(componentDir)) {
|
|
198
|
+
fs.mkdirSync(componentDir, { recursive: true });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!fs.existsSync(componentPath)) {
|
|
202
|
+
fs.writeFileSync(componentPath, component.generate(), "utf-8");
|
|
203
|
+
console.log(`Created ${name}.component.tsx`);
|
|
204
|
+
} else {
|
|
205
|
+
console.log(`${name}.component.tsx already exists, skipping file creation`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const moduleContent = fs.readFileSync(componentModulePath, "utf-8");
|
|
209
|
+
const updatedModule = updateModuleWithComponent(moduleContent, name);
|
|
210
|
+
fs.writeFileSync(componentModulePath, updatedModule, "utf-8");
|
|
211
|
+
|
|
212
|
+
if (fs.existsSync(appModulePath)) {
|
|
213
|
+
const appModuleContent = fs.readFileSync(appModulePath, "utf-8");
|
|
214
|
+
const updatedAppModule = ensureComponentModuleImported(appModuleContent);
|
|
215
|
+
if (updatedAppModule !== appModuleContent) {
|
|
216
|
+
fs.writeFileSync(appModulePath, updatedAppModule, "utf-8");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function getComponentDependencies(
|
|
222
|
+
name: string,
|
|
223
|
+
visited: Set<string> = new Set()
|
|
224
|
+
): string[] {
|
|
225
|
+
if (visited.has(name)) {
|
|
226
|
+
return [];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const component = ComponentRegistry.get(name);
|
|
230
|
+
if (!component) {
|
|
231
|
+
return [];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
visited.add(name);
|
|
235
|
+
const allDeps: string[] = [];
|
|
236
|
+
|
|
237
|
+
for (const dep of component.dependencies) {
|
|
238
|
+
allDeps.push(dep);
|
|
239
|
+
allDeps.push(...getComponentDependencies(dep, visited));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return [...new Set(allDeps)];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function printDependencyTree(name: string, indent: string = ""): void {
|
|
246
|
+
const component = ComponentRegistry.get(name);
|
|
247
|
+
if (!component) {
|
|
248
|
+
console.log(`${indent}${name} (not found)`);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
console.log(`${indent}${name}`);
|
|
253
|
+
for (const dep of component.dependencies) {
|
|
254
|
+
printDependencyTree(dep, indent + " ├─ ");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function listComponents(): void {
|
|
259
|
+
console.log("\nAvailable components:");
|
|
260
|
+
for (const name of ComponentRegistry.getAll()) {
|
|
261
|
+
const component = ComponentRegistry.get(name)!;
|
|
262
|
+
const depsInfo =
|
|
263
|
+
component.dependencies.length > 0
|
|
264
|
+
? ` (depends on: ${component.dependencies.join(", ")})`
|
|
265
|
+
: " (no dependencies)";
|
|
266
|
+
console.log(` - ${name}${depsInfo}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function updateModuleWithComponent(
|
|
271
|
+
moduleContent: string,
|
|
272
|
+
componentName: string
|
|
273
|
+
): string {
|
|
274
|
+
const className = capitalize(componentName);
|
|
275
|
+
const importPath = `./component/${componentName}.component`;
|
|
276
|
+
|
|
277
|
+
const sourceFile = ts.createSourceFile(
|
|
278
|
+
"component.module.ts",
|
|
279
|
+
moduleContent,
|
|
280
|
+
ts.ScriptTarget.Latest,
|
|
281
|
+
true
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const hasImport = sourceFile.statements.some((statement) => {
|
|
285
|
+
if (ts.isImportDeclaration(statement)) {
|
|
286
|
+
const moduleSpecifier = statement.moduleSpecifier;
|
|
287
|
+
if (ts.isStringLiteral(moduleSpecifier)) {
|
|
288
|
+
return moduleSpecifier.text === importPath;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return false;
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
if (hasImport) {
|
|
295
|
+
return moduleContent;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
let lastImportEnd = 0;
|
|
299
|
+
sourceFile.statements.forEach((statement) => {
|
|
300
|
+
if (ts.isImportDeclaration(statement)) {
|
|
301
|
+
lastImportEnd = statement.end;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const importStatement = `import { ${className} } from "${importPath}";\n`;
|
|
306
|
+
let updatedContent =
|
|
307
|
+
moduleContent.slice(0, lastImportEnd) +
|
|
308
|
+
"\n" +
|
|
309
|
+
importStatement +
|
|
310
|
+
moduleContent.slice(lastImportEnd);
|
|
311
|
+
|
|
312
|
+
const newSourceFile = ts.createSourceFile(
|
|
313
|
+
"component.module.ts",
|
|
314
|
+
updatedContent,
|
|
315
|
+
ts.ScriptTarget.Latest,
|
|
316
|
+
true
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
updatedContent = addToDecoratorArray(
|
|
320
|
+
updatedContent,
|
|
321
|
+
newSourceFile,
|
|
322
|
+
"declarations",
|
|
323
|
+
className
|
|
324
|
+
);
|
|
325
|
+
updatedContent = addToDecoratorArray(
|
|
326
|
+
updatedContent,
|
|
327
|
+
ts.createSourceFile(
|
|
328
|
+
"component.module.ts",
|
|
329
|
+
updatedContent,
|
|
330
|
+
ts.ScriptTarget.Latest,
|
|
331
|
+
true
|
|
332
|
+
),
|
|
333
|
+
"exports",
|
|
334
|
+
className
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
return updatedContent;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function addToDecoratorArray(
|
|
341
|
+
content: string,
|
|
342
|
+
sourceFile: ts.SourceFile,
|
|
343
|
+
arrayName: string,
|
|
344
|
+
className: string
|
|
345
|
+
): string {
|
|
346
|
+
let decoratorNode: ts.Decorator | undefined;
|
|
347
|
+
|
|
348
|
+
sourceFile.statements.forEach((statement) => {
|
|
349
|
+
if (ts.isClassDeclaration(statement) && statement.modifiers) {
|
|
350
|
+
statement.modifiers.forEach((modifier) => {
|
|
351
|
+
if (ts.isDecorator(modifier)) {
|
|
352
|
+
const expression = modifier.expression;
|
|
353
|
+
if (ts.isCallExpression(expression)) {
|
|
354
|
+
const expressionText = expression.expression.getText(sourceFile);
|
|
355
|
+
if (expressionText === "Module") {
|
|
356
|
+
decoratorNode = modifier;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
if (!decoratorNode) {
|
|
365
|
+
console.warn("Could not find @Module decorator");
|
|
366
|
+
return content;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const callExpression = decoratorNode.expression as ts.CallExpression;
|
|
370
|
+
const objectLiteral = callExpression
|
|
371
|
+
.arguments[0] as ts.ObjectLiteralExpression;
|
|
372
|
+
|
|
373
|
+
if (!objectLiteral || !ts.isObjectLiteralExpression(objectLiteral)) {
|
|
374
|
+
return content;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
let targetProperty: ts.PropertyAssignment | undefined;
|
|
378
|
+
objectLiteral.properties.forEach((prop) => {
|
|
379
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
380
|
+
const propName = prop.name.getText(sourceFile);
|
|
381
|
+
if (propName === arrayName) {
|
|
382
|
+
targetProperty = prop;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
if (!targetProperty) {
|
|
388
|
+
console.warn(`Could not find ${arrayName} property`);
|
|
389
|
+
return content;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const arrayLiteral = targetProperty.initializer;
|
|
393
|
+
if (!ts.isArrayLiteralExpression(arrayLiteral)) {
|
|
394
|
+
return content;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
const hasClassName = arrayLiteral.elements.some((element) => {
|
|
398
|
+
return element.getText(sourceFile).trim() === className;
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
if (hasClassName) {
|
|
402
|
+
return content;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const arrayStart = arrayLiteral.getStart(sourceFile);
|
|
406
|
+
const arrayEnd = arrayLiteral.getEnd();
|
|
407
|
+
|
|
408
|
+
if (arrayLiteral.elements.length === 0) {
|
|
409
|
+
const newArray = `[${className}]`;
|
|
410
|
+
return (
|
|
411
|
+
content.substring(0, arrayStart) + newArray + content.substring(arrayEnd)
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const lastElement = arrayLiteral.elements[arrayLiteral.elements.length - 1];
|
|
416
|
+
const insertPos = lastElement.getEnd();
|
|
417
|
+
const newElement = `, ${className}`;
|
|
418
|
+
|
|
419
|
+
return (
|
|
420
|
+
content.substring(0, insertPos) + newElement + content.substring(insertPos)
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function ensureComponentModuleImported(appModuleContent: string): string {
|
|
425
|
+
const sourceFile = ts.createSourceFile(
|
|
426
|
+
"app.module.ts",
|
|
427
|
+
appModuleContent,
|
|
428
|
+
ts.ScriptTarget.Latest,
|
|
429
|
+
true
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
const hasComponentModuleImport = sourceFile.statements.some((statement) => {
|
|
433
|
+
if (ts.isImportDeclaration(statement) && statement.importClause) {
|
|
434
|
+
const namedBindings = statement.importClause.namedBindings;
|
|
435
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
436
|
+
return namedBindings.elements.some(
|
|
437
|
+
(element) => element.name.text === "ComponentModule"
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return false;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
if (hasComponentModuleImport) {
|
|
445
|
+
return ensureInImportsArray(appModuleContent, sourceFile);
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
let lastImportEnd = 0;
|
|
449
|
+
sourceFile.statements.forEach((statement) => {
|
|
450
|
+
if (ts.isImportDeclaration(statement)) {
|
|
451
|
+
lastImportEnd = statement.end;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
const importStatement = `import { ComponentModule } from "../component/component.module";\n`;
|
|
456
|
+
let updatedContent =
|
|
457
|
+
appModuleContent.slice(0, lastImportEnd) +
|
|
458
|
+
"\n" +
|
|
459
|
+
importStatement +
|
|
460
|
+
appModuleContent.slice(lastImportEnd);
|
|
461
|
+
|
|
462
|
+
const newSourceFile = ts.createSourceFile(
|
|
463
|
+
"app.module.ts",
|
|
464
|
+
updatedContent,
|
|
465
|
+
ts.ScriptTarget.Latest,
|
|
466
|
+
true
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
updatedContent = ensureInImportsArray(updatedContent, newSourceFile);
|
|
470
|
+
|
|
471
|
+
return updatedContent;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function ensureInImportsArray(
|
|
475
|
+
content: string,
|
|
476
|
+
sourceFile: ts.SourceFile
|
|
477
|
+
): string {
|
|
478
|
+
return addToDecoratorArray(content, sourceFile, "imports", "ComponentModule");
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function capitalize(str: string): string {
|
|
482
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
function createModule() {
|
|
486
|
+
return `import { Module } from "@kithinji/orca";
|
|
487
|
+
|
|
488
|
+
@Module({
|
|
489
|
+
imports: [],
|
|
490
|
+
providers: [],
|
|
491
|
+
declarations: [],
|
|
492
|
+
exports: [],
|
|
493
|
+
})
|
|
494
|
+
export class ComponentModule {}
|
|
495
|
+
`;
|
|
496
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./component";
|
package/src/add/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./module";
|