@kargojs/cli 0.1.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.
Files changed (47) hide show
  1. package/bin/kargo.js +7 -0
  2. package/dist/commands/create.d.ts +6 -0
  3. package/dist/commands/create.d.ts.map +1 -0
  4. package/dist/commands/create.js +48 -0
  5. package/dist/commands/make-panel.d.ts +7 -0
  6. package/dist/commands/make-panel.d.ts.map +1 -0
  7. package/dist/commands/make-panel.js +39 -0
  8. package/dist/commands/make-resource.d.ts +14 -0
  9. package/dist/commands/make-resource.d.ts.map +1 -0
  10. package/dist/commands/make-resource.js +101 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +43 -0
  14. package/dist/templates/database.d.ts +13 -0
  15. package/dist/templates/database.d.ts.map +1 -0
  16. package/dist/templates/database.js +43 -0
  17. package/dist/templates/form.d.ts +3 -0
  18. package/dist/templates/form.d.ts.map +1 -0
  19. package/dist/templates/form.js +11 -0
  20. package/dist/templates/project.d.ts +7 -0
  21. package/dist/templates/project.d.ts.map +1 -0
  22. package/dist/templates/project.js +459 -0
  23. package/dist/templates/resource.d.ts +3 -0
  24. package/dist/templates/resource.d.ts.map +1 -0
  25. package/dist/templates/resource.js +15 -0
  26. package/dist/templates/service-in-memory.d.ts +3 -0
  27. package/dist/templates/service-in-memory.d.ts.map +1 -0
  28. package/dist/templates/service-in-memory.js +47 -0
  29. package/dist/templates/service.d.ts +3 -0
  30. package/dist/templates/service.d.ts.map +1 -0
  31. package/dist/templates/service.js +21 -0
  32. package/dist/templates/table.d.ts +3 -0
  33. package/dist/templates/table.d.ts.map +1 -0
  34. package/dist/templates/table.js +31 -0
  35. package/dist/utils/fs.d.ts +12 -0
  36. package/dist/utils/fs.d.ts.map +1 -0
  37. package/dist/utils/fs.js +26 -0
  38. package/dist/utils/log.d.ts +11 -0
  39. package/dist/utils/log.d.ts.map +1 -0
  40. package/dist/utils/log.js +16 -0
  41. package/dist/utils/register-resource.d.ts +22 -0
  42. package/dist/utils/register-resource.d.ts.map +1 -0
  43. package/dist/utils/register-resource.js +71 -0
  44. package/dist/utils/strings.d.ts +31 -0
  45. package/dist/utils/strings.d.ts.map +1 -0
  46. package/dist/utils/strings.js +63 -0
  47. package/package.json +31 -0
@@ -0,0 +1,459 @@
1
+ import { getDbConfig } from './database.js';
2
+ /** All files generated by `kargo create <name>`. Returns an array of {path, content}. */
3
+ export function projectFiles(name, database = 'sqlite') {
4
+ const base = name;
5
+ const db = getDbConfig(database);
6
+ return [
7
+ // ── Root ──────────────────────────────────────────────────────────────
8
+ {
9
+ path: `${base}/package.json`,
10
+ content: JSON.stringify({
11
+ name,
12
+ private: true,
13
+ scripts: {
14
+ build: 'turbo run build',
15
+ dev: 'turbo run dev',
16
+ lint: 'turbo run lint',
17
+ },
18
+ devDependencies: {
19
+ turbo: '^2.0.0',
20
+ typescript: '7.0.2',
21
+ },
22
+ workspaces: ['apps/*'],
23
+ }, null, 2) + '\n',
24
+ },
25
+ {
26
+ path: `${base}/turbo.json`,
27
+ content: JSON.stringify({
28
+ $schema: 'https://turbo.build/schema.json',
29
+ tasks: {
30
+ build: { dependsOn: ['^build'], outputs: ['dist/**'] },
31
+ dev: { persistent: true, cache: false },
32
+ lint: {},
33
+ },
34
+ }, null, 2) + '\n',
35
+ },
36
+ {
37
+ path: `${base}/.gitignore`,
38
+ content: [
39
+ 'node_modules/',
40
+ 'dist/',
41
+ '.turbo/',
42
+ '.next/',
43
+ '*.env',
44
+ '*.env.local',
45
+ '*.db',
46
+ '*.db-journal',
47
+ '',
48
+ ].join('\n'),
49
+ },
50
+ // ── NestJS API ────────────────────────────────────────────────────────
51
+ {
52
+ path: `${base}/apps/api/package.json`,
53
+ content: JSON.stringify({
54
+ name: `${name}-api`,
55
+ type: 'module',
56
+ private: true,
57
+ scripts: {
58
+ build: 'tsc',
59
+ dev: 'tsx src/main.ts',
60
+ start: 'node dist/main.js',
61
+ postinstall: 'prisma generate',
62
+ 'db:migrate': 'prisma migrate dev',
63
+ 'db:seed': 'tsx prisma/seed.ts',
64
+ },
65
+ dependencies: {
66
+ '@kargojs/core': 'latest',
67
+ '@kargojs/forms': 'latest',
68
+ '@kargojs/nestjs': 'latest',
69
+ '@kargojs/prisma': 'latest',
70
+ '@kargojs/tables': 'latest',
71
+ '@nestjs/common': '^12.0.0',
72
+ '@nestjs/core': '^12.0.0',
73
+ '@nestjs/platform-express': '^12.0.0',
74
+ [db.adapterPackage]: '^7.10.0',
75
+ '@prisma/client': '^7.10.0',
76
+ 'reflect-metadata': '^0.2.0',
77
+ rxjs: '^7.8.0',
78
+ },
79
+ devDependencies: {
80
+ '@types/express': '^5.0.0',
81
+ '@types/node': '^22.0.0',
82
+ dotenv: '^16.4.5',
83
+ prisma: '^7.10.0',
84
+ tsx: '^4.19.0',
85
+ typescript: '7.0.2',
86
+ },
87
+ }, null, 2) + '\n',
88
+ },
89
+ {
90
+ path: `${base}/apps/api/tsconfig.json`,
91
+ content: JSON.stringify({
92
+ compilerOptions: {
93
+ target: 'ES2022',
94
+ module: 'NodeNext',
95
+ moduleResolution: 'NodeNext',
96
+ strict: true,
97
+ skipLibCheck: true,
98
+ esModuleInterop: true,
99
+ experimentalDecorators: true,
100
+ emitDecoratorMetadata: true,
101
+ outDir: 'dist',
102
+ rootDir: 'src',
103
+ types: ['node'],
104
+ },
105
+ include: ['src'],
106
+ exclude: ['node_modules', 'dist'],
107
+ }, null, 2) + '\n',
108
+ },
109
+ {
110
+ path: `${base}/apps/api/prisma.config.ts`,
111
+ content: `import 'dotenv/config';
112
+ import { defineConfig, env } from 'prisma/config';
113
+
114
+ export default defineConfig({
115
+ schema: 'prisma/schema.prisma',
116
+ migrations: {
117
+ path: 'prisma/migrations',
118
+ seed: 'tsx prisma/seed.ts',
119
+ },
120
+ datasource: {
121
+ url: env('DATABASE_URL'),
122
+ },
123
+ });
124
+ `,
125
+ },
126
+ {
127
+ path: `${base}/apps/api/.env`,
128
+ content: db.envContent,
129
+ },
130
+ {
131
+ path: `${base}/apps/api/prisma/schema.prisma`,
132
+ content: `generator client {
133
+ provider = "prisma-client-js"
134
+ }
135
+
136
+ datasource db {
137
+ // Connection config lives in prisma.config.ts / the driver adapter at
138
+ // runtime (src/prisma.service.ts) — schema-level \`url\` isn't supported.
139
+ provider = "${db.prismaProvider}"
140
+ }
141
+
142
+ model Example {
143
+ id Int @id @default(autoincrement())
144
+ name String
145
+ description String
146
+ createdAt DateTime @default(now())
147
+ }
148
+ `,
149
+ },
150
+ {
151
+ path: `${base}/apps/api/prisma/seed.ts`,
152
+ content: `import { PrismaClient } from '@prisma/client';
153
+ import { ${db.adapterClass} } from '${db.adapterPackage}';
154
+
155
+ const adapter = ${db.adapterConstructor};
156
+ const prisma = new PrismaClient({ adapter });
157
+
158
+ async function main() {
159
+ await prisma.example.createMany({
160
+ data: [
161
+ { name: 'First record', description: 'Hello from Kargo' },
162
+ { name: 'Second record', description: 'Edit or delete me from the admin panel' },
163
+ ],
164
+ });
165
+ console.log('Seeded example records.');
166
+ }
167
+
168
+ main()
169
+ .catch((e) => { console.error(e); process.exit(1); })
170
+ .finally(() => prisma.$disconnect());
171
+ `,
172
+ },
173
+ {
174
+ path: `${base}/apps/api/src/main.ts`,
175
+ content: `import 'reflect-metadata';
176
+ import { NestFactory } from '@nestjs/core';
177
+ import { AppModule } from './app.module.js';
178
+
179
+ async function bootstrap() {
180
+ const app = await NestFactory.create(AppModule);
181
+ app.enableCors();
182
+ await app.listen(3001);
183
+ console.log('Kargo API running on http://localhost:3001');
184
+ }
185
+
186
+ void bootstrap();
187
+ `,
188
+ },
189
+ {
190
+ path: `${base}/apps/api/src/panel.ts`,
191
+ content: `import { Panel } from '@kargojs/core';
192
+
193
+ export const adminPanel = Panel.make({
194
+ id: 'admin',
195
+ path: '/admin',
196
+ globalSearch: true,
197
+ });
198
+ `,
199
+ },
200
+ {
201
+ path: `${base}/apps/api/src/prisma.service.ts`,
202
+ content: `import { Injectable, type OnModuleInit, type OnModuleDestroy } from '@nestjs/common';
203
+ import { PrismaClient } from '@prisma/client';
204
+ import { ${db.adapterClass} } from '${db.adapterPackage}';
205
+
206
+ // Prisma generates its client per-project against this project's own
207
+ // schema.prisma, so this small wrapper lives here rather than in a shared
208
+ // package — see @kargojs/prisma's PrismaResourceService for the reusable
209
+ // generic CRUD layer built on top of whatever delegate this client exposes.
210
+ const adapter = ${db.adapterConstructor};
211
+
212
+ @Injectable()
213
+ export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
214
+ constructor() {
215
+ super({ adapter });
216
+ }
217
+
218
+ async onModuleInit(): Promise<void> {
219
+ await this.$connect();
220
+ }
221
+
222
+ async onModuleDestroy(): Promise<void> {
223
+ await this.$disconnect();
224
+ }
225
+ }
226
+ `,
227
+ },
228
+ {
229
+ path: `${base}/apps/api/src/prisma.module.ts`,
230
+ content: `import { Global, Module } from '@nestjs/common';
231
+ import { PrismaService } from './prisma.service.js';
232
+
233
+ // @Global() so PrismaService resolves inside KargoModule.forRoot()'s
234
+ // dynamically-registered resource services too, not just AppModule's own
235
+ // provider scope — those services live in a separate module boundary that
236
+ // KargoModule.forRoot() constructs at runtime and never imports this module.
237
+ @Global()
238
+ @Module({
239
+ providers: [PrismaService],
240
+ exports: [PrismaService],
241
+ })
242
+ export class PrismaModule {}
243
+ `,
244
+ },
245
+ {
246
+ path: `${base}/apps/api/src/app.module.ts`,
247
+ content: `import 'reflect-metadata';
248
+ import { Module } from '@nestjs/common';
249
+ import { KargoModule } from '@kargojs/nestjs';
250
+ import { adminPanel } from './panel.js';
251
+ import { PrismaModule } from './prisma.module.js';
252
+ import { ExampleResource } from './resources/example/example.resource.js';
253
+ import { ExampleService } from './services/example.service.js';
254
+
255
+ @Module({
256
+ imports: [
257
+ PrismaModule,
258
+ KargoModule.forRoot({
259
+ panel: adminPanel,
260
+ resources: [
261
+ { resource: ExampleResource, service: ExampleService },
262
+ ],
263
+ }),
264
+ ],
265
+ })
266
+ export class AppModule {}
267
+ `,
268
+ },
269
+ // ── Split Resource / Form / Table (Filament-style single responsibility) ──
270
+ {
271
+ path: `${base}/apps/api/src/resources/example/example.resource.ts`,
272
+ content: `import { Resource } from '@kargojs/core';
273
+ import { exampleForm } from './example.form.js';
274
+ import { exampleTable } from './example.table.js';
275
+
276
+ export class ExampleResource extends Resource {
277
+ static readonly navigationLabel = 'Examples';
278
+ static readonly navigationIcon = 'document';
279
+
280
+ static form() { return exampleForm(); }
281
+ static table() { return exampleTable(); }
282
+ }
283
+ `,
284
+ },
285
+ {
286
+ path: `${base}/apps/api/src/resources/example/example.form.ts`,
287
+ content: `import { FormSchema } from '@kargojs/core';
288
+ import { TextInput } from '@kargojs/forms';
289
+
290
+ export function exampleForm(): FormSchema {
291
+ return FormSchema.make([
292
+ TextInput.make('name').label('Name').required(),
293
+ TextInput.make('description').label('Description'),
294
+ ]).columns(2);
295
+ }
296
+ `,
297
+ },
298
+ {
299
+ path: `${base}/apps/api/src/resources/example/example.table.ts`,
300
+ content: `import { TableSchema } from '@kargojs/core';
301
+ import { TextColumn, DateColumn } from '@kargojs/tables';
302
+ import { EditAction, DeleteAction } from '@kargojs/core';
303
+
304
+ export function exampleTable(): TableSchema {
305
+ return TableSchema.make([
306
+ TextColumn.make('id').label('ID').sortable(),
307
+ TextColumn.make('name').label('Name').searchable().sortable(),
308
+ DateColumn.make('createdAt').label('Created').sortable().since(),
309
+ ])
310
+ .actions([EditAction.make(), DeleteAction.make()])
311
+ .searchable()
312
+ .paginated();
313
+ }
314
+ `,
315
+ },
316
+ {
317
+ path: `${base}/apps/api/src/services/example.service.ts`,
318
+ content: `import 'reflect-metadata';
319
+ import { Inject, Injectable } from '@nestjs/common';
320
+ import { PrismaResourceService } from '@kargojs/prisma';
321
+ import { PrismaService } from '../prisma.service.js';
322
+ import { ExampleResource } from '../resources/example/example.resource.js';
323
+
324
+ export interface Example {
325
+ id: number;
326
+ name: string;
327
+ description: string;
328
+ createdAt: Date;
329
+ }
330
+
331
+ @Injectable()
332
+ export class ExampleService extends PrismaResourceService<Example> {
333
+ constructor(@Inject(PrismaService) prisma: PrismaService) {
334
+ super(prisma.example, ExampleResource);
335
+ }
336
+ }
337
+ `,
338
+ },
339
+ // ── Next.js web ───────────────────────────────────────────────────────
340
+ {
341
+ path: `${base}/apps/web/package.json`,
342
+ content: JSON.stringify({
343
+ name: `${name}-web`,
344
+ type: 'module',
345
+ private: true,
346
+ scripts: {
347
+ build: 'next build',
348
+ dev: 'next dev --port 3000',
349
+ start: 'next start',
350
+ lint: 'next lint',
351
+ },
352
+ dependencies: {
353
+ '@kargojs/core': 'latest',
354
+ '@kargojs/next': 'latest',
355
+ next: '^16.0.0',
356
+ react: '^19.0.0',
357
+ 'react-dom': '^19.0.0',
358
+ },
359
+ devDependencies: {
360
+ '@types/node': '^22.0.0',
361
+ '@types/react': '^19.0.0',
362
+ '@types/react-dom': '^19.0.0',
363
+ typescript: '7.0.2',
364
+ },
365
+ }, null, 2) + '\n',
366
+ },
367
+ {
368
+ path: `${base}/apps/web/tsconfig.json`,
369
+ content: JSON.stringify({
370
+ compilerOptions: {
371
+ target: 'ES2022',
372
+ lib: ['dom', 'dom.iterable', 'esnext'],
373
+ module: 'ESNext',
374
+ moduleResolution: 'bundler',
375
+ jsx: 'react-jsx',
376
+ strict: true,
377
+ skipLibCheck: true,
378
+ esModuleInterop: true,
379
+ incremental: true,
380
+ plugins: [{ name: 'next' }],
381
+ types: ['node'],
382
+ },
383
+ include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'],
384
+ exclude: ['node_modules'],
385
+ }, null, 2) + '\n',
386
+ },
387
+ {
388
+ path: `${base}/apps/web/next.config.mjs`,
389
+ content: `/** @type {import('next').NextConfig} */
390
+ const nextConfig = {
391
+ transpilePackages: ['@kargojs/next'],
392
+ };
393
+
394
+ export default nextConfig;
395
+ `,
396
+ },
397
+ {
398
+ path: `${base}/apps/web/app/layout.tsx`,
399
+ content: `import type { ReactNode } from 'react';
400
+
401
+ export const metadata = { title: '${name} Admin' };
402
+
403
+ export default function RootLayout({ children }: { children: ReactNode }) {
404
+ return (
405
+ <html lang="en">
406
+ <body style={{ margin: 0, padding: 0, fontFamily: 'system-ui, sans-serif' }}>
407
+ {children}
408
+ </body>
409
+ </html>
410
+ );
411
+ }
412
+ `,
413
+ },
414
+ {
415
+ path: `${base}/apps/web/app/admin/layout.tsx`,
416
+ content: `'use client';
417
+ import type { ReactNode } from 'react';
418
+ import { useRouter, usePathname } from 'next/navigation';
419
+ import { KargoAdminLayout } from '@kargojs/next';
420
+
421
+ // Point this at your running NestJS API
422
+ const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'http://localhost:3001';
423
+
424
+ export default function AdminLayout({ children }: { children: ReactNode }) {
425
+ const router = useRouter();
426
+ const pathname = usePathname();
427
+ const activeSlug = pathname.replace(/^\\/admin\\/?/, '').split('/')[0] || undefined;
428
+
429
+ return (
430
+ <KargoAdminLayout
431
+ apiBase={API_BASE}
432
+ brandName="${name}"
433
+ activeSlug={activeSlug}
434
+ onNavigate={(slug) => router.push(\`/admin/\${slug}\`)}
435
+ >
436
+ {children}
437
+ </KargoAdminLayout>
438
+ );
439
+ }
440
+ `,
441
+ },
442
+ {
443
+ path: `${base}/apps/web/app/admin/[[...slug]]/page.tsx`,
444
+ content: `'use client';
445
+ import { use } from 'react';
446
+ import { KargoRouter } from '@kargojs/next';
447
+
448
+ interface Props {
449
+ params: Promise<{ slug?: string[] }>;
450
+ }
451
+
452
+ export default function AdminPage({ params }: Props) {
453
+ const { slug } = use(params);
454
+ return <KargoRouter slug={slug} basePath="/admin" />;
455
+ }
456
+ `,
457
+ },
458
+ ];
459
+ }
@@ -0,0 +1,3 @@
1
+ import type { ResourceNames } from '../utils/strings.js';
2
+ export declare function resourceTemplate(n: ResourceNames): string;
3
+ //# sourceMappingURL=resource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/templates/resource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAczD"}
@@ -0,0 +1,15 @@
1
+ export function resourceTemplate(n) {
2
+ return `import { Resource } from '@kargojs/core';
3
+ import { ${n.camel}Form } from './${n.kebab}.form.js';
4
+ import { ${n.camel}Table } from './${n.kebab}.table.js';
5
+
6
+ export class ${n.pascal}Resource extends Resource {
7
+ static readonly navigationLabel = '${n.pluralTitle}';
8
+ static readonly navigationIcon = 'document';
9
+ static readonly recordLabel = 'id';
10
+
11
+ static form() { return ${n.camel}Form(); }
12
+ static table() { return ${n.camel}Table(); }
13
+ }
14
+ `;
15
+ }
@@ -0,0 +1,3 @@
1
+ import type { ResourceNames } from '../utils/strings.js';
2
+ export declare function serviceInMemoryTemplate(n: ResourceNames): string;
3
+ //# sourceMappingURL=service-in-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-in-memory.d.ts","sourceRoot":"","sources":["../../src/templates/service-in-memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CA8ChE"}
@@ -0,0 +1,47 @@
1
+ export function serviceInMemoryTemplate(n) {
2
+ return `import { Injectable } from '@nestjs/common';
3
+ import {
4
+ KargoResourceService,
5
+ type KargoQuery,
6
+ type KargoPagedResult,
7
+ } from '@kargojs/nestjs';
8
+
9
+ // Replace with your entity / DTO type
10
+ export interface ${n.pascal} {
11
+ id: number;
12
+ name: string;
13
+ createdAt: Date;
14
+ }
15
+
16
+ @Injectable()
17
+ export class ${n.pascal}Service extends KargoResourceService<${n.pascal}> {
18
+ // TODO: inject your repository / ORM client here
19
+ // constructor(@InjectRepository(${n.pascal}) private repo: Repository<${n.pascal}>) { super(); }
20
+
21
+ async findAll(query: KargoQuery): Promise<KargoPagedResult<${n.pascal}>> {
22
+ // TODO: implement list with pagination + sorting + search
23
+ throw new Error('${n.pascal}Service.findAll not implemented');
24
+ }
25
+
26
+ async findOne(id: string | number): Promise<${n.pascal} | null> {
27
+ // TODO: implement single record fetch
28
+ throw new Error('${n.pascal}Service.findOne not implemented');
29
+ }
30
+
31
+ async create(data: Partial<${n.pascal}>): Promise<${n.pascal}> {
32
+ // TODO: implement create
33
+ throw new Error('${n.pascal}Service.create not implemented');
34
+ }
35
+
36
+ async update(id: string | number, data: Partial<${n.pascal}>): Promise<${n.pascal}> {
37
+ // TODO: implement update
38
+ throw new Error('${n.pascal}Service.update not implemented');
39
+ }
40
+
41
+ async delete(id: string | number): Promise<void> {
42
+ // TODO: implement delete
43
+ throw new Error('${n.pascal}Service.delete not implemented');
44
+ }
45
+ }
46
+ `;
47
+ }
@@ -0,0 +1,3 @@
1
+ import type { ResourceNames } from '../utils/strings.js';
2
+ export declare function serviceTemplate(n: ResourceNames): string;
3
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/templates/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,wBAAgB,eAAe,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAoBxD"}
@@ -0,0 +1,21 @@
1
+ export function serviceTemplate(n) {
2
+ return `import 'reflect-metadata';
3
+ import { Inject, Injectable } from '@nestjs/common';
4
+ import { PrismaResourceService } from '@kargojs/prisma';
5
+ import { PrismaService } from '../prisma.service.js';
6
+ import { ${n.pascal}Resource } from '../resources/${n.kebab}/${n.kebab}.resource.js';
7
+
8
+ export interface ${n.pascal} {
9
+ id: number;
10
+ name: string;
11
+ createdAt: Date;
12
+ }
13
+
14
+ @Injectable()
15
+ export class ${n.pascal}Service extends PrismaResourceService<${n.pascal}> {
16
+ constructor(@Inject(PrismaService) prisma: PrismaService) {
17
+ super(prisma.${n.camel}, ${n.pascal}Resource);
18
+ }
19
+ }
20
+ `;
21
+ }
@@ -0,0 +1,3 @@
1
+ import type { ResourceNames } from '../utils/strings.js';
2
+ export declare function tableTemplate(n: ResourceNames): string;
3
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/templates/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,wBAAgB,aAAa,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CA8BtD"}
@@ -0,0 +1,31 @@
1
+ export function tableTemplate(n) {
2
+ return `import { TableSchema, EditAction, DeleteAction } from '@kargojs/core';
3
+ import { TextColumn, DateColumn } from '@kargojs/tables';
4
+ // import { ServerAction, ActionResult } from '@kargojs/actions'; // uncomment to add custom actions
5
+
6
+ export function ${n.camel}Table(): TableSchema {
7
+ return TableSchema.make([
8
+ TextColumn.make('id').label('ID').sortable(),
9
+ TextColumn.make('name').label('Name').searchable().sortable(),
10
+ DateColumn.make('createdAt').label('Created').sortable().since(),
11
+ ])
12
+ .actions([
13
+ EditAction.make(),
14
+ DeleteAction.make(),
15
+ // Example server action — uncomment and implement the handler:
16
+ // ServerAction.make('archive')
17
+ // .label('Archive')
18
+ // .color('warning')
19
+ // .requiresConfirmation()
20
+ // .confirmationMessage('Archive this record?')
21
+ // .handle(async ({ id, service }) => {
22
+ // const svc = service as ${n.pascal}Service;
23
+ // await svc.archive(id!);
24
+ // return ActionResult.success('Archived successfully');
25
+ // }),
26
+ ])
27
+ .searchable()
28
+ .paginated();
29
+ }
30
+ `;
31
+ }
@@ -0,0 +1,12 @@
1
+ /** Write a file, creating parent directories as needed. */
2
+ export declare function writeGeneratedFile(filePath: string, content: string, { force }?: {
3
+ force?: boolean | undefined;
4
+ }): Promise<void>;
5
+ /** Write multiple files in order. */
6
+ export declare function writeFiles(files: Array<{
7
+ path: string;
8
+ content: string;
9
+ }>, opts?: {
10
+ force?: boolean;
11
+ }): Promise<void>;
12
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA,2DAA2D;AAC3D,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,EAAE,KAAa,EAAE;;CAAK,GACrB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,qCAAqC;AACrC,wBAAsB,UAAU,CAC9B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CAIf"}
@@ -0,0 +1,26 @@
1
+ import { mkdir, writeFile, access } from 'node:fs/promises';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { log } from './log.js';
4
+ /** Write a file, creating parent directories as needed. */
5
+ export async function writeGeneratedFile(filePath, content, { force = false } = {}) {
6
+ const abs = resolve(filePath);
7
+ if (!force) {
8
+ try {
9
+ await access(abs);
10
+ log.warn(`Already exists — skipped: ${filePath}`);
11
+ return;
12
+ }
13
+ catch {
14
+ // file doesn't exist — proceed
15
+ }
16
+ }
17
+ await mkdir(dirname(abs), { recursive: true });
18
+ await writeFile(abs, content, 'utf8');
19
+ log.file(filePath);
20
+ }
21
+ /** Write multiple files in order. */
22
+ export async function writeFiles(files, opts) {
23
+ for (const { path, content } of files) {
24
+ await writeGeneratedFile(path, content, opts);
25
+ }
26
+ }
@@ -0,0 +1,11 @@
1
+ export declare const log: {
2
+ info: (msg: string) => void;
3
+ success: (msg: string) => void;
4
+ warn: (msg: string) => void;
5
+ error: (msg: string) => void;
6
+ file: (path: string) => void;
7
+ step: (msg: string) => void;
8
+ blank: () => void;
9
+ };
10
+ export declare function banner(name: string, version: string): void;
11
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/utils/log.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;gBACF,MAAM;mBACH,MAAM;gBACT,MAAM;iBACL,MAAM;iBACN,MAAM;gBACP,MAAM;;CAEnB,CAAC;AAEF,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAKnD"}