@rudderjs/cli 0.0.6

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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/dist/commands/make/agent.d.ts +4 -0
  4. package/dist/commands/make/agent.d.ts.map +1 -0
  5. package/dist/commands/make/agent.js +41 -0
  6. package/dist/commands/make/agent.js.map +1 -0
  7. package/dist/commands/make/command.d.ts +4 -0
  8. package/dist/commands/make/command.d.ts.map +1 -0
  9. package/dist/commands/make/command.js +46 -0
  10. package/dist/commands/make/command.js.map +1 -0
  11. package/dist/commands/make/controller.d.ts +5 -0
  12. package/dist/commands/make/controller.d.ts.map +1 -0
  13. package/dist/commands/make/controller.js +46 -0
  14. package/dist/commands/make/controller.js.map +1 -0
  15. package/dist/commands/make/event.d.ts +4 -0
  16. package/dist/commands/make/event.d.ts.map +1 -0
  17. package/dist/commands/make/event.js +32 -0
  18. package/dist/commands/make/event.js.map +1 -0
  19. package/dist/commands/make/job.d.ts +4 -0
  20. package/dist/commands/make/job.d.ts.map +1 -0
  21. package/dist/commands/make/job.js +41 -0
  22. package/dist/commands/make/job.js.map +1 -0
  23. package/dist/commands/make/listener.d.ts +4 -0
  24. package/dist/commands/make/listener.d.ts.map +1 -0
  25. package/dist/commands/make/listener.js +34 -0
  26. package/dist/commands/make/listener.js.map +1 -0
  27. package/dist/commands/make/mail.d.ts +4 -0
  28. package/dist/commands/make/mail.d.ts.map +1 -0
  29. package/dist/commands/make/mail.js +41 -0
  30. package/dist/commands/make/mail.js.map +1 -0
  31. package/dist/commands/make/mcp-prompt.d.ts +4 -0
  32. package/dist/commands/make/mcp-prompt.d.ts.map +1 -0
  33. package/dist/commands/make/mcp-prompt.js +45 -0
  34. package/dist/commands/make/mcp-prompt.js.map +1 -0
  35. package/dist/commands/make/mcp-resource.d.ts +4 -0
  36. package/dist/commands/make/mcp-resource.d.ts.map +1 -0
  37. package/dist/commands/make/mcp-resource.js +44 -0
  38. package/dist/commands/make/mcp-resource.js.map +1 -0
  39. package/dist/commands/make/mcp-server.d.ts +4 -0
  40. package/dist/commands/make/mcp-server.d.ts.map +1 -0
  41. package/dist/commands/make/mcp-server.js +46 -0
  42. package/dist/commands/make/mcp-server.js.map +1 -0
  43. package/dist/commands/make/mcp-tool.d.ts +4 -0
  44. package/dist/commands/make/mcp-tool.d.ts.map +1 -0
  45. package/dist/commands/make/mcp-tool.js +43 -0
  46. package/dist/commands/make/mcp-tool.js.map +1 -0
  47. package/dist/commands/make/middleware.d.ts +4 -0
  48. package/dist/commands/make/middleware.d.ts.map +1 -0
  49. package/dist/commands/make/middleware.js +40 -0
  50. package/dist/commands/make/middleware.js.map +1 -0
  51. package/dist/commands/make/model.d.ts +5 -0
  52. package/dist/commands/make/model.d.ts.map +1 -0
  53. package/dist/commands/make/model.js +43 -0
  54. package/dist/commands/make/model.js.map +1 -0
  55. package/dist/commands/make/provider.d.ts +4 -0
  56. package/dist/commands/make/provider.d.ts.map +1 -0
  57. package/dist/commands/make/provider.js +39 -0
  58. package/dist/commands/make/provider.js.map +1 -0
  59. package/dist/commands/make/request.d.ts +4 -0
  60. package/dist/commands/make/request.d.ts.map +1 -0
  61. package/dist/commands/make/request.js +40 -0
  62. package/dist/commands/make/request.js.map +1 -0
  63. package/dist/commands/make.d.ts +3 -0
  64. package/dist/commands/make.d.ts.map +1 -0
  65. package/dist/commands/make.js +33 -0
  66. package/dist/commands/make.js.map +1 -0
  67. package/dist/commands/migrate.d.ts +11 -0
  68. package/dist/commands/migrate.d.ts.map +1 -0
  69. package/dist/commands/migrate.js +152 -0
  70. package/dist/commands/migrate.js.map +1 -0
  71. package/dist/commands/module/make.d.ts +9 -0
  72. package/dist/commands/module/make.d.ts.map +1 -0
  73. package/dist/commands/module/make.js +190 -0
  74. package/dist/commands/module/make.js.map +1 -0
  75. package/dist/commands/module/publish.d.ts +14 -0
  76. package/dist/commands/module/publish.d.ts.map +1 -0
  77. package/dist/commands/module/publish.js +117 -0
  78. package/dist/commands/module/publish.js.map +1 -0
  79. package/dist/commands/module.d.ts +3 -0
  80. package/dist/commands/module.d.ts.map +1 -0
  81. package/dist/commands/module.js +7 -0
  82. package/dist/commands/module.js.map +1 -0
  83. package/dist/commands/vendor-publish.d.ts +5 -0
  84. package/dist/commands/vendor-publish.d.ts.map +1 -0
  85. package/dist/commands/vendor-publish.js +190 -0
  86. package/dist/commands/vendor-publish.js.map +1 -0
  87. package/dist/index.d.ts +3 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +253 -0
  90. package/dist/index.js.map +1 -0
  91. package/package.json +40 -0
@@ -0,0 +1,9 @@
1
+ import type { Command } from 'commander';
2
+ export declare function schemaStub(name: string): string;
3
+ export declare function serviceStub(name: string): string;
4
+ export declare function providerStub(name: string): string;
5
+ export declare function testStub(name: string): string;
6
+ export declare function prismaStub(name: string): string;
7
+ export declare function autoRegisterProvider(name: string, cwd: string): Promise<void>;
8
+ export declare function makeModule(program: Command): void;
9
+ //# sourceMappingURL=make.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make.d.ts","sourceRoot":"","sources":["../../../src/commands/module/make.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkB/C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAwBhD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiCjD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiB7C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ/C;AAID,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CnF;AAID,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6CjD"}
@@ -0,0 +1,190 @@
1
+ import { writeFile, mkdir, readFile } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { resolve, dirname } from 'node:path';
4
+ import { intro, outro, spinner, log } from '@clack/prompts';
5
+ // ─── File stubs ────────────────────────────────────────────
6
+ export function schemaStub(name) {
7
+ return `import { z } from 'zod'
8
+
9
+ export const ${name}InputSchema = z.object({
10
+ // TODO: define input fields
11
+ name: z.string().min(1),
12
+ })
13
+
14
+ export const ${name}OutputSchema = z.object({
15
+ id: z.string(),
16
+ name: z.string(),
17
+ createdAt: z.date(),
18
+ updatedAt: z.date(),
19
+ })
20
+
21
+ export type ${name}Input = z.infer<typeof ${name}InputSchema>
22
+ export type ${name} = z.infer<typeof ${name}OutputSchema>
23
+ `;
24
+ }
25
+ export function serviceStub(name) {
26
+ return `import { Injectable } from '@rudderjs/core'
27
+ import type { ${name}Input, ${name} } from './${name}Schema.js'
28
+
29
+ @Injectable()
30
+ export class ${name}Service {
31
+ // TODO: inject PrismaAdapter or ORM adapter
32
+
33
+ async findAll(): Promise<${name}[]> {
34
+ // TODO: replace with real DB call
35
+ return []
36
+ }
37
+
38
+ async findById(id: string): Promise<${name} | null> {
39
+ // TODO: replace with real DB call
40
+ return null
41
+ }
42
+
43
+ async create(input: ${name}Input): Promise<${name}> {
44
+ // TODO: replace with real DB call
45
+ throw new Error('Not implemented')
46
+ }
47
+ }
48
+ `;
49
+ }
50
+ export function providerStub(name) {
51
+ const prefix = `/api/${name.replace(/([A-Z])/g, (m, l, i) => (i === 0 ? l : `-${l}`)).toLowerCase()}s`;
52
+ return `import { ServiceProvider } from '@rudderjs/core'
53
+ import { router } from '@rudderjs/router'
54
+ import { ${name}Service } from './${name}Service.js'
55
+ import { ${name}InputSchema } from './${name}Schema.js'
56
+
57
+ export class ${name}ServiceProvider extends ServiceProvider {
58
+ register(): void {
59
+ this.app.singleton(${name}Service, () => new ${name}Service())
60
+ }
61
+
62
+ override async boot(): Promise<void> {
63
+ const service = this.app.make<${name}Service>(${name}Service)
64
+
65
+ router.get('${prefix}', async (_req, res) => {
66
+ res.json({ data: await service.findAll() })
67
+ })
68
+
69
+ router.get('${prefix}/:id', async (req, res) => {
70
+ const item = await service.findById(req.params['id']!)
71
+ if (!item) { res.status(404).json({ message: 'Not found.' }); return }
72
+ res.json({ data: item })
73
+ })
74
+
75
+ router.post('${prefix}', async (req, res) => {
76
+ const parsed = ${name}InputSchema.safeParse(req.body)
77
+ if (!parsed.success) { res.status(422).json({ errors: parsed.error.flatten().fieldErrors }); return }
78
+ res.status(201).json({ data: await service.create(parsed.data) })
79
+ })
80
+ }
81
+ }
82
+ `;
83
+ }
84
+ export function testStub(name) {
85
+ return `import { describe, it } from 'node:test'
86
+ import assert from 'node:assert/strict'
87
+ import { ${name}InputSchema } from './${name}Schema.js'
88
+
89
+ describe('${name}', () => {
90
+ it('validates a valid input', () => {
91
+ const result = ${name}InputSchema.safeParse({ name: 'Test' })
92
+ assert.strictEqual(result.success, true)
93
+ })
94
+
95
+ it('rejects an empty name', () => {
96
+ const result = ${name}InputSchema.safeParse({ name: '' })
97
+ assert.strictEqual(result.success, false)
98
+ })
99
+ })
100
+ `;
101
+ }
102
+ export function prismaStub(name) {
103
+ return `model ${name} {
104
+ id String @id @default(cuid())
105
+ // TODO: add fields
106
+ createdAt DateTime @default(now())
107
+ updatedAt DateTime @updatedAt
108
+ }
109
+ `;
110
+ }
111
+ // ─── Auto-registration ─────────────────────────────────────
112
+ export async function autoRegisterProvider(name, cwd) {
113
+ const bootstrapPath = resolve(cwd, 'bootstrap/providers.ts');
114
+ const importLine = `import { ${name}ServiceProvider } from '../app/Modules/${name}/${name}ServiceProvider.js'`;
115
+ const pushLine = ` ${name}ServiceProvider,`;
116
+ const template = `import type { ServiceProvider } from '@rudderjs/core'
117
+ import type { Application } from '@rudderjs/core'
118
+
119
+ export const providers: (new (app: Application) => ServiceProvider)[] = []\n`;
120
+ let content;
121
+ if (!existsSync(bootstrapPath)) {
122
+ await mkdir(dirname(bootstrapPath), { recursive: true });
123
+ content = template;
124
+ }
125
+ else {
126
+ content = await readFile(bootstrapPath, 'utf8');
127
+ }
128
+ // Skip if already registered
129
+ if (content.includes(`${name}ServiceProvider`))
130
+ return;
131
+ // Insert import after last existing import line
132
+ const importMatch = content.match(/^(import [^\n]+\n)+/m);
133
+ if (importMatch) {
134
+ const lastImportEnd = content.lastIndexOf('\nimport ');
135
+ const insertAt = content.indexOf('\n', lastImportEnd + 1) + 1;
136
+ content = content.slice(0, insertAt) + importLine + '\n' + content.slice(insertAt);
137
+ }
138
+ else {
139
+ content = importLine + '\n' + content;
140
+ }
141
+ // Insert into providers array
142
+ content = content.replace(/providers:\s*\[([^\]]*)\]/s, (_, inner) => {
143
+ const trimmed = inner.trimEnd();
144
+ const comma = trimmed.length > 0 && !trimmed.endsWith(',') ? ',' : '';
145
+ return `providers: [${trimmed}${comma}\n${pushLine}\n]`;
146
+ });
147
+ await writeFile(bootstrapPath, content);
148
+ }
149
+ // ─── Command ───────────────────────────────────────────────
150
+ export function makeModule(program) {
151
+ program
152
+ .command('make:module <name>')
153
+ .description('Scaffold a new module with schema, service, provider, test, and Prisma model')
154
+ .option('-f, --force', 'Overwrite existing files')
155
+ .action(async (name, opts) => {
156
+ intro(`Creating module: ${name}`);
157
+ const moduleDir = resolve(process.cwd(), `app/Modules/${name}`);
158
+ const files = [
159
+ { path: `${moduleDir}/${name}Schema.ts`, content: schemaStub(name) },
160
+ { path: `${moduleDir}/${name}Service.ts`, content: serviceStub(name) },
161
+ { path: `${moduleDir}/${name}ServiceProvider.ts`, content: providerStub(name) },
162
+ { path: `${moduleDir}/${name}.test.ts`, content: testStub(name) },
163
+ { path: `${moduleDir}/${name}.prisma`, content: prismaStub(name) },
164
+ ];
165
+ const s = spinner();
166
+ s.start('Generating files');
167
+ await mkdir(moduleDir, { recursive: true });
168
+ for (const file of files) {
169
+ if (existsSync(file.path) && !opts.force) {
170
+ s.stop('Aborted');
171
+ log.error(`File already exists: ${file.path}\nUse --force to overwrite.`);
172
+ return;
173
+ }
174
+ await writeFile(file.path, file.content);
175
+ log.success(`Created ${file.path.replace(process.cwd() + '/', '')}`);
176
+ }
177
+ s.stop('Files generated');
178
+ const s2 = spinner();
179
+ s2.start('Registering provider');
180
+ try {
181
+ await autoRegisterProvider(name, process.cwd());
182
+ s2.stop('Provider registered in app/bootstrap/providers.ts');
183
+ }
184
+ catch (_e) {
185
+ s2.stop('Could not auto-register provider');
186
+ }
187
+ outro(`Module ${name} created successfully`);
188
+ });
189
+ }
190
+ //# sourceMappingURL=make.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make.js","sourceRoot":"","sources":["../../../src/commands/module/make.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Command } from 'commander';
2
+ export declare const MARKERS_RE: RegExp;
3
+ export declare function findPrismaFiles(modulesDir: string, moduleFilter?: string): Promise<Array<{
4
+ module: string;
5
+ file: string;
6
+ content: string;
7
+ }>>;
8
+ export declare function buildMergedBlock(shards: Array<{
9
+ module: string;
10
+ file: string;
11
+ content: string;
12
+ }>): string;
13
+ export declare function publishModule(program: Command): void;
14
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../../../src/commands/module/publish.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,eAAO,MAAM,UAAU,QAAsE,CAAA;AAI7F,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAsBlJ;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAMzG;AAeD,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4EpD"}
@@ -0,0 +1,117 @@
1
+ import { readFile, writeFile, readdir } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { resolve, join } from 'node:path';
4
+ import { spawn } from 'node:child_process';
5
+ import { intro, outro, spinner, log } from '@clack/prompts';
6
+ export const MARKERS_RE = /\/\/ <rudderjs:modules:start>[\s\S]*?\/\/ <rudderjs:modules:end>/m;
7
+ // ─── Helpers ───────────────────────────────────────────────
8
+ export async function findPrismaFiles(modulesDir, moduleFilter) {
9
+ const results = [];
10
+ if (!existsSync(modulesDir))
11
+ return results;
12
+ const entries = await readdir(modulesDir, { withFileTypes: true });
13
+ for (const entry of entries) {
14
+ if (!entry.isDirectory())
15
+ continue;
16
+ if (moduleFilter && entry.name !== moduleFilter)
17
+ continue;
18
+ const moduleDir = join(modulesDir, entry.name);
19
+ const moduleFiles = await readdir(moduleDir);
20
+ for (const f of moduleFiles) {
21
+ if (!f.endsWith('.prisma'))
22
+ continue;
23
+ const filePath = join(moduleDir, f);
24
+ const content = await readFile(filePath, 'utf8');
25
+ results.push({ module: entry.name, file: f, content });
26
+ }
27
+ }
28
+ return results;
29
+ }
30
+ export function buildMergedBlock(shards) {
31
+ const inner = shards
32
+ .map(s => `// module: ${s.module} (${s.file})\n${s.content.trim()}`)
33
+ .join('\n\n');
34
+ return `// <rudderjs:modules:start>\n${inner}\n// <rudderjs:modules:end>`;
35
+ }
36
+ function runCommand(cmd, args, cwd) {
37
+ return new Promise((resolve, reject) => {
38
+ const proc = spawn(cmd, args, { cwd, stdio: 'inherit', shell: true });
39
+ proc.on('close', code => {
40
+ if (code === 0)
41
+ resolve();
42
+ else
43
+ reject(new Error(`Command exited with code ${code}`));
44
+ });
45
+ proc.on('error', reject);
46
+ });
47
+ }
48
+ // ─── Command ───────────────────────────────────────────────
49
+ export function publishModule(program) {
50
+ program
51
+ .command('module:publish [module]')
52
+ .description('Merge module Prisma shards into prisma/schema.prisma')
53
+ .option('--generate', 'Run prisma generate after merging')
54
+ .option('--migrate', 'Run prisma migrate dev after merging')
55
+ .option('--name <name>', 'Migration name (used with --migrate)', 'auto')
56
+ .action(async (moduleFilter, opts) => {
57
+ intro('Publishing module Prisma shards');
58
+ const cwd = process.cwd();
59
+ const modulesDir = resolve(cwd, 'app/Modules');
60
+ const schemaPath = resolve(cwd, 'prisma/schema.prisma');
61
+ const s = spinner();
62
+ s.start('Scanning for .prisma files');
63
+ const shards = await findPrismaFiles(modulesDir, moduleFilter);
64
+ s.stop(`Found ${shards.length} shard(s)`);
65
+ if (shards.length === 0) {
66
+ log.error('No .prisma files found in app/Modules/');
67
+ return;
68
+ }
69
+ for (const shard of shards) {
70
+ log.success(` ${shard.module}/${shard.file}`);
71
+ }
72
+ const mergedBlock = buildMergedBlock(shards);
73
+ let schema;
74
+ if (existsSync(schemaPath)) {
75
+ schema = await readFile(schemaPath, 'utf8');
76
+ if (MARKERS_RE.test(schema)) {
77
+ schema = schema.replace(MARKERS_RE, mergedBlock);
78
+ }
79
+ else {
80
+ schema = schema.trimEnd() + '\n\n' + mergedBlock + '\n';
81
+ }
82
+ }
83
+ else {
84
+ schema = mergedBlock + '\n';
85
+ }
86
+ const s2 = spinner();
87
+ s2.start('Writing prisma/schema.prisma');
88
+ await writeFile(schemaPath, schema);
89
+ s2.stop('prisma/schema.prisma updated');
90
+ if (opts.generate) {
91
+ const sg = spinner();
92
+ sg.start('Running prisma generate');
93
+ try {
94
+ await runCommand('pnpm', ['exec', 'prisma', 'generate'], cwd);
95
+ sg.stop('prisma generate complete');
96
+ }
97
+ catch (e) {
98
+ sg.stop('prisma generate failed');
99
+ log.error(String(e));
100
+ }
101
+ }
102
+ if (opts.migrate) {
103
+ const sm = spinner();
104
+ sm.start('Running prisma migrate dev');
105
+ try {
106
+ await runCommand('pnpm', ['exec', 'prisma', 'migrate', 'dev', '--name', opts.name], cwd);
107
+ sm.stop('prisma migrate dev complete');
108
+ }
109
+ catch (e) {
110
+ sm.stop('prisma migrate dev failed');
111
+ log.error(String(e));
112
+ }
113
+ }
114
+ outro('Publish complete');
115
+ });
116
+ }
117
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/commands/module/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAA;AAE3D,MAAM,CAAC,MAAM,UAAU,GAAG,mEAAmE,CAAA;AAE7F,8DAA8D;AAE9D,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,UAAkB,EAAE,YAAqB;IAC7E,MAAM,OAAO,GAA6D,EAAE,CAAA;IAE5E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,OAAO,CAAA;IAE3C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;IAClE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,SAAQ;QAClC,IAAI,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,SAAQ;QAEzD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QAC9C,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;QAE5C,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAAE,SAAQ;YACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAA;YACnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAChD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QACxD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAgE;IAC/F,MAAM,KAAK,GAAG,MAAM;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;SACnE,IAAI,CAAC,MAAM,CAAC,CAAA;IAEf,OAAO,gCAAgC,KAAK,6BAA6B,CAAA;AAC3E,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,IAAc,EAAE,GAAW;IAC1D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACrE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;YACtB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAA;;gBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC,CAAA;QAC5D,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC1B,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,8DAA8D;AAE9D,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO;SACJ,OAAO,CAAC,yBAAyB,CAAC;SAClC,WAAW,CAAC,sDAAsD,CAAC;SACnE,MAAM,CAAC,YAAY,EAAE,mCAAmC,CAAC;SACzD,MAAM,CAAC,WAAW,EAAE,sCAAsC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,sCAAsC,EAAE,MAAM,CAAC;SACvE,MAAM,CAAC,KAAK,EACX,YAAgC,EAChC,IAA6D,EAC7D,EAAE;QACF,KAAK,CAAC,iCAAiC,CAAC,CAAA;QAExC,MAAM,GAAG,GAAU,OAAO,CAAC,GAAG,EAAE,CAAA;QAChC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,aAAa,CAAC,CAAA;QAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAA;QAEvD,MAAM,CAAC,GAAG,OAAO,EAAE,CAAA;QACnB,CAAC,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAA;QACrC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,CAAA;QAC9D,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,WAAW,CAAC,CAAA;QAEzC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;QAChD,CAAC;QAED,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;QAE5C,IAAI,MAAc,CAAA;QAClB,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;YAC3C,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;YAClD,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;YACzD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;QAC7B,CAAC;QAED,MAAM,EAAE,GAAG,OAAO,EAAE,CAAA;QACpB,EAAE,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACxC,MAAM,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,CAAA;QACnC,EAAE,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;QAEvC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,EAAE,GAAG,OAAO,EAAE,CAAA;YACpB,EAAE,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;YACnC,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,EAAE,GAAG,CAAC,CAAA;gBAC7D,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;YACrC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;gBACjC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,EAAE,GAAG,OAAO,EAAE,CAAA;YACpB,EAAE,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAA;YACtC,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;gBACxF,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAA;YACxC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,EAAE,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;gBACpC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,CAAA;IAC3B,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function moduleCommand(program: Command): void;
3
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/commands/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAIxC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAGpD"}
@@ -0,0 +1,7 @@
1
+ import { makeModule } from './module/make.js';
2
+ import { publishModule } from './module/publish.js';
3
+ export function moduleCommand(program) {
4
+ makeModule(program);
5
+ publishModule(program);
6
+ }
7
+ //# sourceMappingURL=module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/commands/module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,UAAU,CAAC,OAAO,CAAC,CAAA;IACnB,aAAa,CAAC,OAAO,CAAC,CAAA;AACxB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { Command } from 'commander';
2
+ /** Detect the database driver from Prisma schema or config. */
3
+ export declare function detectDriver(cwd?: string): 'sqlite' | 'postgresql' | 'mysql' | null;
4
+ export declare function vendorPublishCommand(program: Command): void;
5
+ //# sourceMappingURL=vendor-publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor-publish.d.ts","sourceRoot":"","sources":["../../src/commands/vendor-publish.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgBxC,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAsB,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,IAAI,CAsBlG;AAID,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4H3D"}
@@ -0,0 +1,190 @@
1
+ import { cp, mkdir, readdir, stat } from 'node:fs/promises';
2
+ import { readFileSync } from 'node:fs';
3
+ import { resolve, join } from 'node:path';
4
+ import { intro, outro, log, spinner } from '@clack/prompts';
5
+ import { detectORM } from './migrate.js';
6
+ /** Detect the database driver from Prisma schema or config. */
7
+ export function detectDriver(cwd = process.cwd()) {
8
+ // Try prisma/schema/base.prisma (multi-file)
9
+ for (const schemaPath of [
10
+ join(cwd, 'prisma', 'schema', 'base.prisma'),
11
+ join(cwd, 'prisma', 'schema.prisma'),
12
+ ]) {
13
+ try {
14
+ const content = readFileSync(schemaPath, 'utf8');
15
+ const match = content.match(/provider\s*=\s*"(sqlite|postgresql|mysql)"/);
16
+ if (match?.[1])
17
+ return match[1];
18
+ }
19
+ catch { /* file not found */ }
20
+ }
21
+ // Try config/database.ts — look for default driver
22
+ try {
23
+ const content = readFileSync(join(cwd, 'config', 'database.ts'), 'utf8');
24
+ if (content.includes("'postgresql'") || content.includes('"postgresql"'))
25
+ return 'postgresql';
26
+ if (content.includes("'mysql'") || content.includes('"mysql"'))
27
+ return 'mysql';
28
+ if (content.includes("'sqlite'") || content.includes('"sqlite"'))
29
+ return 'sqlite';
30
+ }
31
+ catch { /* file not found */ }
32
+ return null;
33
+ }
34
+ // ─── Command ───────────────────────────────────────────────
35
+ export function vendorPublishCommand(program) {
36
+ program
37
+ .command('vendor:publish')
38
+ .description('Publish package assets (pages, config, migrations) to your application')
39
+ .option('--provider <provider>', 'Only publish assets from the given provider')
40
+ .option('--tag <tag>', 'Only publish assets with the given tag')
41
+ .option('--list', 'List available publishable assets without copying')
42
+ .option('--force', 'Overwrite existing files')
43
+ .action(async (opts) => {
44
+ intro('vendor:publish');
45
+ // Read from globalThis — populated by ServiceProvider.publishes() during app boot.
46
+ // Using globalThis avoids module-cache fragmentation across tsx/ESM load paths.
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ const registry = globalThis.__rudderjs_publish_registry__ ?? new Map();
49
+ const cwd = process.cwd();
50
+ // ── Build filtered entries ───────────────────────────
51
+ let entries = [...registry.entries()];
52
+ if (opts.provider) {
53
+ entries = entries.filter(([name]) => name === opts.provider);
54
+ if (entries.length === 0) {
55
+ log.error(`No publishable assets found for provider "${opts.provider}"`);
56
+ outro('');
57
+ return;
58
+ }
59
+ }
60
+ if (opts.tag) {
61
+ entries = entries
62
+ .map(([name, groups]) => [
63
+ name,
64
+ groups.filter((g) => g.tag === opts.tag),
65
+ ])
66
+ .filter(([, groups]) => groups.length > 0);
67
+ if (entries.length === 0) {
68
+ log.error(`No publishable assets found with tag "${opts.tag}"`);
69
+ outro('');
70
+ return;
71
+ }
72
+ }
73
+ if (entries.length === 0) {
74
+ log.warn('No publishable assets are registered.');
75
+ outro('');
76
+ return;
77
+ }
78
+ // ── Deduplicate by destination (no-tag mode only) ──
79
+ // When no --tag is given, multiple groups from the same provider may target the
80
+ // same `to` path (e.g. auth publishes React, Vue, Solid variants all to pages/(auth)).
81
+ // Only the first registered group per destination is published — that is the default.
82
+ // Users must pass --tag to get a specific variant.
83
+ if (!opts.tag) {
84
+ entries = entries.map(([name, groups]) => {
85
+ const seen = new Set();
86
+ return [name, groups.filter((g) => {
87
+ if (seen.has(g.to))
88
+ return false;
89
+ seen.add(g.to);
90
+ return true;
91
+ })];
92
+ }).filter(([, groups]) => groups.length > 0);
93
+ }
94
+ // ── Filter by ORM + driver ─────────────────────────
95
+ // Only applied to groups that have orm/driver set — generic groups always pass.
96
+ const detectedOrm = detectORM(cwd);
97
+ const detectedDriver = detectDriver(cwd);
98
+ entries = entries
99
+ .map(([name, groups]) => [
100
+ name,
101
+ groups.filter((g) => {
102
+ if (g.orm && g.orm !== detectedOrm)
103
+ return false;
104
+ if (g.driver && g.driver !== detectedDriver)
105
+ return false;
106
+ return true;
107
+ }),
108
+ ])
109
+ .filter(([, groups]) => groups.length > 0);
110
+ // ── List mode ────────────────────────────────────────
111
+ if (opts.list) {
112
+ for (const [provider, groups] of entries) {
113
+ log.message(`\n ${provider}`);
114
+ for (const g of groups) {
115
+ const tag = g.tag ? ` [${g.tag}]` : '';
116
+ const orm = g.orm ? ` (${g.orm})` : '';
117
+ const driver = g.driver ? ` (${g.driver})` : '';
118
+ log.message(` ${g.from}`);
119
+ log.message(` → ${g.to}${tag}${orm}${driver}`);
120
+ }
121
+ }
122
+ outro('Use vendor:publish to copy the files above into your application.');
123
+ return;
124
+ }
125
+ // ── Copy files ───────────────────────────────────────
126
+ let published = 0;
127
+ for (const [, groups] of entries) {
128
+ for (const group of groups) {
129
+ const dest = resolve(cwd, group.to);
130
+ const s = spinner();
131
+ s.start(`Copying to ${group.to}`);
132
+ await mkdir(dest, { recursive: true });
133
+ const forceGroup = !!(opts.force || group.force);
134
+ const skipped = await copyDir(group.from, dest, forceGroup);
135
+ if (skipped > 0 && !forceGroup) {
136
+ s.stop(`Published to ${group.to} (${skipped} file(s) skipped — use --force to overwrite)`);
137
+ }
138
+ else {
139
+ s.stop(`Published to ${group.to}`);
140
+ }
141
+ published++;
142
+ }
143
+ }
144
+ outro(published > 0 ? 'Assets published successfully.' : 'Nothing was published.');
145
+ });
146
+ }
147
+ // ─── Helpers ───────────────────────────────────────────────
148
+ /**
149
+ * Recursively copy `src` into `dest`.
150
+ * Returns the number of files skipped (already exist and force=false).
151
+ */
152
+ async function copyDir(src, dest, force) {
153
+ let skipped = 0;
154
+ const srcStat = await stat(src).catch(() => null);
155
+ if (!srcStat) {
156
+ log.warn(`Source not found: ${src}`);
157
+ return 0;
158
+ }
159
+ if (srcStat.isFile()) {
160
+ if (!force) {
161
+ const { existsSync } = await import('node:fs');
162
+ const target = join(dest, src.split('/').pop() ?? '');
163
+ if (existsSync(target))
164
+ return 1;
165
+ }
166
+ await cp(src, dest, { recursive: true, force });
167
+ return 0;
168
+ }
169
+ const entries = await readdir(src, { withFileTypes: true });
170
+ for (const entry of entries) {
171
+ const srcPath = join(src, entry.name);
172
+ const destPath = join(dest, entry.name);
173
+ if (entry.isDirectory()) {
174
+ await mkdir(destPath, { recursive: true });
175
+ skipped += await copyDir(srcPath, destPath, force);
176
+ }
177
+ else {
178
+ if (!force) {
179
+ const { existsSync } = await import('node:fs');
180
+ if (existsSync(destPath)) {
181
+ skipped++;
182
+ continue;
183
+ }
184
+ }
185
+ await cp(srcPath, destPath, { force });
186
+ }
187
+ }
188
+ return skipped;
189
+ }
190
+ //# sourceMappingURL=vendor-publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vendor-publish.js","sourceRoot":"","sources":["../../src/commands/vendor-publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}