@kithinji/pod 1.0.20 → 1.0.22

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.
Files changed (40) hide show
  1. package/README.md +439 -0
  2. package/dist/main.js +109 -2
  3. package/dist/main.js.map +2 -2
  4. package/dist/types/docker/docker.d.ts.map +1 -1
  5. package/package.json +31 -8
  6. package/build.js +0 -22
  7. package/src/add/component/component.ts +0 -496
  8. package/src/add/component/index.ts +0 -1
  9. package/src/add/index.ts +0 -3
  10. package/src/add/module/index.ts +0 -1
  11. package/src/add/module/module.ts +0 -545
  12. package/src/add/new/index.ts +0 -198
  13. package/src/config/config.ts +0 -141
  14. package/src/config/index.ts +0 -1
  15. package/src/deploy/deploy.ts +0 -592
  16. package/src/deploy/index.ts +0 -1
  17. package/src/dev/index.ts +0 -1
  18. package/src/dev/project.ts +0 -45
  19. package/src/dev/server.ts +0 -191
  20. package/src/docker/docker.ts +0 -592
  21. package/src/docker/index.ts +0 -1
  22. package/src/macros/expand_macros.ts +0 -791
  23. package/src/macros/index.ts +0 -2
  24. package/src/macros/macro_executer.ts +0 -189
  25. package/src/main.ts +0 -106
  26. package/src/plugins/analyzers/graph.ts +0 -279
  27. package/src/plugins/css/index.ts +0 -25
  28. package/src/plugins/generators/generate_controller.ts +0 -308
  29. package/src/plugins/generators/generate_rsc.ts +0 -274
  30. package/src/plugins/generators/generate_server_component.ts +0 -455
  31. package/src/plugins/generators/tsx_server_stub.ts +0 -315
  32. package/src/plugins/index.ts +0 -3
  33. package/src/plugins/my.ts +0 -282
  34. package/src/plugins/transformers/j2d.ts +0 -1080
  35. package/src/store/index.ts +0 -1
  36. package/src/store/store.ts +0 -44
  37. package/src/utils/cases.ts +0 -15
  38. package/src/utils/create.ts +0 -26
  39. package/src/utils/index.ts +0 -2
  40. package/tsconfig.json +0 -27
@@ -1,545 +0,0 @@
1
- import { createStructure, DirEntry, toCamelCase, toPascalCase } from "@/utils";
2
- import * as path from "path";
3
- import * as fs from "fs";
4
- import * as ts from "typescript";
5
-
6
- export function addFeature(name: string) {
7
- const featureDir = path.join(process.cwd(), "src", "features", name);
8
-
9
- addModule(name, featureDir);
10
-
11
- updateFeaturesIndex(name);
12
-
13
- updateAppModule(name);
14
- }
15
-
16
- export function addModule(name: string, baseDir: string, root?: boolean) {
17
- const structure: DirEntry = {
18
- files: [
19
- { name: `${name}.module.ts`, content: createModule(name, root) },
20
- { name: `${name}.service.ts`, content: createService(name) },
21
- { name: `${name}.page.tsx`, content: createPage(name) },
22
- ],
23
- dirs: [
24
- {
25
- name: "schemas",
26
- files: [
27
- {
28
- name: "get.ts",
29
- content: createGetSchema(name),
30
- },
31
- {
32
- name: "create.ts",
33
- content: createCreateSchema(name),
34
- },
35
- {
36
- name: "update.ts",
37
- content: createUpdateSchema(name),
38
- },
39
- {
40
- name: "list.ts",
41
- content: createListSchema(name),
42
- },
43
- {
44
- name: "delete.ts",
45
- content: createDeleteSchema(name),
46
- },
47
- ],
48
- },
49
- {
50
- name: "components",
51
- files: [
52
- {
53
- name: `${name}-list.component.tsx`,
54
- content: createListComponent(name),
55
- },
56
- ],
57
- },
58
- ],
59
- };
60
-
61
- createStructure(baseDir, structure);
62
- }
63
-
64
- function updateFeaturesIndex(featureName: string) {
65
- const featuresIndexPath = path.join(
66
- process.cwd(),
67
- "src",
68
- "features",
69
- "index.ts"
70
- );
71
-
72
- const moduleName = toPascalCase(featureName + "_" + "Module");
73
- const importPath = `./${featureName}/${featureName}.module`;
74
-
75
- if (fs.existsSync(featuresIndexPath)) {
76
- let content = fs.readFileSync(featuresIndexPath, "utf-8");
77
- const sourceFile = ts.createSourceFile(
78
- "index.ts",
79
- content,
80
- ts.ScriptTarget.Latest,
81
- true
82
- );
83
-
84
- const hasExport = sourceFile.statements.some((statement) => {
85
- if (ts.isExportDeclaration(statement)) {
86
- const moduleSpecifier = statement.moduleSpecifier;
87
- if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier)) {
88
- return moduleSpecifier.text === importPath;
89
- }
90
- if (
91
- statement.exportClause &&
92
- ts.isNamedExports(statement.exportClause)
93
- ) {
94
- return statement.exportClause.elements.some(
95
- (element) => element.name.text === moduleName
96
- );
97
- }
98
- }
99
- return false;
100
- });
101
-
102
- if (hasExport) {
103
- return;
104
- }
105
-
106
- const exportStatement = `export { ${moduleName} } from "${importPath}";\n`;
107
- fs.appendFileSync(featuresIndexPath, exportStatement);
108
- } else {
109
- const featuresDir = path.dirname(featuresIndexPath);
110
- if (!fs.existsSync(featuresDir)) {
111
- fs.mkdirSync(featuresDir, { recursive: true });
112
- }
113
-
114
- const exportStatement = `export { ${moduleName} } from "${importPath}";\n`;
115
- fs.writeFileSync(featuresIndexPath, exportStatement, "utf-8");
116
- }
117
- }
118
-
119
- function updateAppModule(featureName: string) {
120
- const appModulePath = path.join(process.cwd(), "src", "app", "app.module.ts");
121
-
122
- if (!fs.existsSync(appModulePath)) {
123
- return;
124
- }
125
-
126
- const moduleName = toPascalCase(featureName + "_" + "Module");
127
- let content = fs.readFileSync(appModulePath, "utf-8");
128
-
129
- const sourceFile = ts.createSourceFile(
130
- "app.module.ts",
131
- content,
132
- ts.ScriptTarget.Latest,
133
- true
134
- );
135
-
136
- const hasImport = sourceFile.statements.some((statement) => {
137
- if (ts.isImportDeclaration(statement)) {
138
- const moduleSpecifier = statement.moduleSpecifier;
139
- if (ts.isStringLiteral(moduleSpecifier)) {
140
- const importPath = moduleSpecifier.text;
141
- return importPath.includes(`/${featureName}/${featureName}.module`);
142
- }
143
-
144
- if (
145
- statement.importClause?.namedBindings &&
146
- ts.isNamedImports(statement.importClause.namedBindings)
147
- ) {
148
- return statement.importClause.namedBindings.elements.some(
149
- (element) => element.name.text === moduleName
150
- );
151
- }
152
- }
153
- return false;
154
- });
155
-
156
- if (hasImport) {
157
- content = addToModuleImportsArray(content, sourceFile, moduleName);
158
- fs.writeFileSync(appModulePath, content, "utf-8");
159
- return;
160
- }
161
-
162
- let lastImportEnd = 0;
163
- sourceFile.statements.forEach((statement) => {
164
- if (ts.isImportDeclaration(statement)) {
165
- lastImportEnd = statement.end;
166
- }
167
- });
168
-
169
- const importStatement = `import { ${moduleName} } from "../features/${featureName}/${featureName}.module";\n`;
170
- content =
171
- content.slice(0, lastImportEnd) +
172
- "\n" +
173
- importStatement +
174
- content.slice(lastImportEnd);
175
-
176
- const newSourceFile = ts.createSourceFile(
177
- "app.module.ts",
178
- content,
179
- ts.ScriptTarget.Latest,
180
- true
181
- );
182
-
183
- content = addToModuleImportsArray(content, newSourceFile, moduleName);
184
-
185
- fs.writeFileSync(appModulePath, content, "utf-8");
186
- }
187
-
188
- function addToModuleImportsArray(
189
- content: string,
190
- sourceFile: ts.SourceFile,
191
- moduleName: string
192
- ): string {
193
- let decoratorNode: ts.Decorator | undefined;
194
-
195
- sourceFile.statements.forEach((statement) => {
196
- if (ts.isClassDeclaration(statement) && statement.modifiers) {
197
- statement.modifiers.forEach((modifier) => {
198
- if (ts.isDecorator(modifier)) {
199
- const expression = modifier.expression;
200
- if (ts.isCallExpression(expression)) {
201
- const expressionText = expression.expression.getText(sourceFile);
202
- if (expressionText === "Module") {
203
- decoratorNode = modifier;
204
- }
205
- }
206
- }
207
- });
208
- }
209
- });
210
-
211
- if (!decoratorNode) {
212
- return content;
213
- }
214
-
215
- const callExpression = decoratorNode.expression as ts.CallExpression;
216
- const objectLiteral = callExpression
217
- .arguments[0] as ts.ObjectLiteralExpression;
218
-
219
- if (!objectLiteral || !ts.isObjectLiteralExpression(objectLiteral)) {
220
- return content;
221
- }
222
-
223
- let importsProperty: ts.PropertyAssignment | undefined;
224
- objectLiteral.properties.forEach((prop) => {
225
- if (ts.isPropertyAssignment(prop)) {
226
- const propName = prop.name.getText(sourceFile);
227
- if (propName === "imports") {
228
- importsProperty = prop;
229
- }
230
- }
231
- });
232
-
233
- if (!importsProperty) {
234
- return content;
235
- }
236
-
237
- const arrayLiteral = importsProperty.initializer;
238
- if (!ts.isArrayLiteralExpression(arrayLiteral)) {
239
- return content;
240
- }
241
-
242
- const hasModule = arrayLiteral.elements.some((element) => {
243
- return element.getText(sourceFile).trim() === moduleName;
244
- });
245
-
246
- if (hasModule) {
247
- return content;
248
- }
249
-
250
- const arrayStart = arrayLiteral.getStart(sourceFile);
251
- const arrayEnd = arrayLiteral.getEnd();
252
-
253
- if (arrayLiteral.elements.length === 0) {
254
- const newArray = `[${moduleName}]`;
255
- return (
256
- content.substring(0, arrayStart) + newArray + content.substring(arrayEnd)
257
- );
258
- }
259
-
260
- const lastElement = arrayLiteral.elements[arrayLiteral.elements.length - 1];
261
- const insertPos = lastElement.getEnd();
262
- const newElement = `, ${moduleName}`;
263
-
264
- return (
265
- content.substring(0, insertPos) + newElement + content.substring(insertPos)
266
- );
267
- }
268
-
269
- function createModule(name: string, root?: boolean) {
270
- const serviceName = toPascalCase(name + "_" + "Service");
271
- const pageName = toPascalCase(name + "_" + "Page");
272
- const moduleName = toPascalCase(name + "_" + "Module");
273
- const componentName = toPascalCase(name + "_" + "List");
274
-
275
- if (root) {
276
- return `import { Module, RouterModule, ServeStaticModule } from "@kithinji/orca";
277
- import { ComponentModule } from "@/component/component.module";
278
- import { ${serviceName} } from "./${name}.service";
279
- import { ${pageName} } from "./${name}.page";
280
- import { ${componentName} } from "./components/${name}-list.component";
281
-
282
- @Module({
283
- imports: [
284
- ServeStaticModule.forRoot({
285
- rootPath: "./public",
286
- }),
287
- RouterModule.forRoot(),
288
- ComponentModule
289
- ],
290
- providers: [${serviceName}],
291
- declarations: [${pageName}, ${componentName}],
292
- exports: [${serviceName}, ${pageName}],
293
- bootstrap: ${pageName}
294
- })
295
- export class ${moduleName} {}
296
- `;
297
- }
298
-
299
- return `import { Module } from "@kithinji/orca";
300
- import { ComponentModule } from "@/component/component.module";
301
- import { ${serviceName} } from "./${name}.service";
302
- import { ${pageName} } from "./${name}.page";
303
- import { ${componentName} } from "./components/${name}-list.component";
304
-
305
- @Module({
306
- imports: [ComponentModule],
307
- providers: [${serviceName}],
308
- declarations: [${pageName}, ${componentName}],
309
- exports: [${serviceName}, ${pageName}],
310
- })
311
- export class ${moduleName} {}
312
- `;
313
- }
314
-
315
- function createGetSchema(name: string) {
316
- return `import { z } from "zod";
317
-
318
- export const ${toCamelCase(name + "_" + "GetInput")} = z.object({
319
- id: z.string().uuid(),
320
- });
321
-
322
- export const ${toCamelCase(name + "_" + "GetOutput")} = z.object({
323
- id: z.string().uuid(),
324
- name: z.string(),
325
- description: z.string().optional(),
326
- createdAt: z.date(),
327
- updatedAt: z.date().optional(),
328
- });
329
- `;
330
- }
331
-
332
- function createCreateSchema(name: string) {
333
- return `import { z } from "zod";
334
-
335
- export const ${toCamelCase(name + "_" + "CreateInput")} = z.object({
336
- name: z.string().min(1),
337
- description: z.string().optional(),
338
- });
339
-
340
- export const ${toCamelCase(name + "_" + "CreateOutput")} = z.object({
341
- id: z.string().uuid(),
342
- name: z.string(),
343
- description: z.string().optional(),
344
- createdAt: z.date(),
345
- });
346
- `;
347
- }
348
-
349
- function createUpdateSchema(name: string) {
350
- return `import { z } from "zod";
351
-
352
- export const ${toCamelCase(name + "_" + "UpdateInput")} = z.object({
353
- id: z.string().uuid(),
354
- name: z.string().min(1).optional(),
355
- description: z.string().optional(),
356
- });
357
-
358
- export const ${toCamelCase(name + "_" + "UpdateOutput")} = z.object({
359
- id: z.string().uuid(),
360
- name: z.string(),
361
- description: z.string().optional(),
362
- createdAt: z.date(),
363
- updatedAt: z.date(),
364
- });
365
- `;
366
- }
367
-
368
- function createListSchema(name: string) {
369
- return `import { z } from "zod";
370
-
371
- export const ${toCamelCase(name + "_" + "ListOutput")} = z.array(
372
- z.object({
373
- id: z.string().uuid(),
374
- name: z.string(),
375
- description: z.string().optional(),
376
- createdAt: z.date(),
377
- updatedAt: z.date().optional(),
378
- })
379
- );
380
- `;
381
- }
382
-
383
- function createDeleteSchema(name: string) {
384
- return `import { z } from "zod";
385
-
386
- export const ${toCamelCase(name + "_" + "DeleteInput")} = z.object({
387
- id: z.string().uuid(),
388
- });
389
-
390
- export const ${toCamelCase(name + "_" + "DeleteOutput")} = z.object({
391
- id: z.string().uuid(),
392
- name: z.string(),
393
- description: z.string().optional(),
394
- createdAt: z.date(),
395
- updatedAt: z.date().optional(),
396
- });
397
- `;
398
- }
399
-
400
- function createService(name: string) {
401
- const serviceName = toPascalCase(name + "_" + "Service");
402
-
403
- return `"use public";
404
-
405
- import { Injectable, Signature } from "@kithinji/orca";
406
- import {
407
- ${toCamelCase(name + "_" + "CreateInput")},
408
- ${toCamelCase(name + "_" + "CreateOutput")}
409
- } from "./schemas/create";
410
- import {
411
- ${toCamelCase(name + "_" + "GetInput")},
412
- ${toCamelCase(name + "_" + "GetOutput")}
413
- } from "./schemas/get";
414
- import {
415
- ${toCamelCase(name + "_" + "UpdateInput")},
416
- ${toCamelCase(name + "_" + "UpdateOutput")}
417
- } from "./schemas/update";
418
- import { ${toCamelCase(name + "_" + "ListOutput")} } from "./schemas/list";
419
- import {
420
- ${toCamelCase(name + "_" + "DeleteInput")},
421
- ${toCamelCase(name + "_" + "DeleteOutput")}
422
- } from "./schemas/delete";
423
-
424
- @Injectable()
425
- export class ${serviceName} {
426
- private items: any[] = [];
427
-
428
- @Signature(${toCamelCase(name + "_" + "CreateInput")}, ${toCamelCase(
429
- name + "_" + "CreateOutput"
430
- )})
431
- public async create(input: any) {
432
- const item = {
433
- id: crypto.randomUUID(),
434
- ...input,
435
- createdAt: new Date(),
436
- };
437
- this.items.push(item);
438
- return item;
439
- }
440
-
441
- @Signature(${toCamelCase(name + "_" + "GetInput")}, ${toCamelCase(
442
- name + "_" + "GetOutput"
443
- )})
444
- public async get(input: any) {
445
- const item = this.items.find((i) => i.id === input.id);
446
- if (!item) {
447
- throw new Error("Item not found");
448
- }
449
- return item;
450
- }
451
-
452
- @Signature(${toCamelCase(name + "_" + "ListOutput")})
453
- public async list() {
454
- return this.items;
455
- }
456
-
457
- @Signature(${toCamelCase(name + "_" + "UpdateInput")}, ${toCamelCase(
458
- name + "_" + "UpdateOutput"
459
- )})
460
- public async update(input: any) {
461
- const index = this.items.findIndex((i) => i.id === input.id);
462
- if (index === -1) {
463
- throw new Error("Item not found");
464
- }
465
-
466
- this.items[index] = {
467
- ...this.items[index],
468
- ...input,
469
- updatedAt: new Date(),
470
- };
471
-
472
- return this.items[index];
473
- }
474
-
475
- @Signature(${toCamelCase(name + "_" + "DeleteInput")}, ${toCamelCase(
476
- name + "_" + "DeleteOutput"
477
- )})
478
- public async delete(input: any) {
479
- const index = this.items.findIndex((i) => i.id === input.id);
480
- if (index === -1) {
481
- throw new Error("Item not found");
482
- }
483
-
484
- const deleted = this.items.splice(index, 1)[0];
485
- return deleted;
486
- }
487
- }
488
- `;
489
- }
490
-
491
- function createPage(name: string) {
492
- const pageName = toPascalCase(name + "_" + "Page");
493
- const serviceName = toPascalCase(name + "_" + "Service");
494
- const serviceVar = toCamelCase(name + "_" + "Service");
495
- const listComponent = toPascalCase(name + "_" + "List");
496
-
497
- return `import { Component } from "@kithinji/orca";
498
- import { ${serviceName} } from "./${name}.service";
499
- import { ${listComponent} } from "./components/${name}-list.component";
500
-
501
- @Component()
502
- export class ${pageName} {
503
- constructor(
504
- public ${serviceVar}: ${serviceName}
505
- ) {}
506
-
507
- build() {
508
- return (
509
- <div>
510
- <h1>${toPascalCase(name)} Management</h1>
511
- <${listComponent} service={this.${serviceVar}} />
512
- </div>
513
- );
514
- }
515
- }
516
- `;
517
- }
518
-
519
- function createListComponent(name: string) {
520
- const componentName = toPascalCase(name + "_" + "List");
521
- const serviceName = toPascalCase(name + "_" + "Service");
522
-
523
- return `"use interactive";
524
-
525
- import { Component } from "@kithinji/orca";
526
- import { ${serviceName} } from "../${name}.service";
527
-
528
- @Component()
529
- export class ${componentName} {
530
- props!: {
531
- service: ${serviceName};
532
- };
533
-
534
- build() {
535
- return (
536
- <div>
537
- <h2>${toPascalCase(name)} List</h2>
538
- <p>List component for ${name}</p>
539
- {/* Add your list implementation here */}
540
- </div>
541
- );
542
- }
543
- }
544
- `;
545
- }