@l4yercak3/cli 1.2.15 → 1.2.18
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/docs/INTEGRATION_PATHS_ARCHITECTURE.md +1543 -0
- package/package.json +1 -1
- package/src/commands/spread.js +101 -6
- package/src/detectors/database-detector.js +245 -0
- package/src/detectors/index.js +17 -4
- package/src/generators/api-only/client.js +683 -0
- package/src/generators/api-only/index.js +96 -0
- package/src/generators/api-only/types.js +618 -0
- package/src/generators/api-only/webhooks.js +377 -0
- package/src/generators/index.js +88 -2
- package/src/generators/mcp-guide-generator.js +256 -0
- package/src/generators/quickstart/components/index.js +1699 -0
- package/src/generators/quickstart/database/convex.js +1257 -0
- package/src/generators/quickstart/database/index.js +34 -0
- package/src/generators/quickstart/database/supabase.js +1132 -0
- package/src/generators/quickstart/hooks/index.js +1047 -0
- package/src/generators/quickstart/index.js +151 -0
- package/src/generators/quickstart/pages/index.js +1466 -0
- package/src/mcp/registry/domains/applications.js +4 -4
- package/src/mcp/registry/domains/benefits.js +798 -0
- package/src/mcp/registry/domains/crm.js +11 -11
- package/src/mcp/registry/domains/events.js +12 -12
- package/src/mcp/registry/domains/forms.js +12 -12
- package/src/mcp/registry/index.js +2 -0
- package/tests/database-detector.test.js +221 -0
- package/tests/generators-index.test.js +215 -3
|
@@ -27,7 +27,7 @@ describe('FileGenerator', () => {
|
|
|
27
27
|
fs.readFileSync.mockReturnValue('');
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
describe('generate', () => {
|
|
30
|
+
describe('legacy generate (backward compatibility)', () => {
|
|
31
31
|
it('returns results object with expected structure', async () => {
|
|
32
32
|
const options = {
|
|
33
33
|
projectPath: mockProjectPath,
|
|
@@ -38,6 +38,7 @@ describe('FileGenerator', () => {
|
|
|
38
38
|
oauthProviders: [],
|
|
39
39
|
isTypeScript: false,
|
|
40
40
|
routerType: 'app',
|
|
41
|
+
integrationPath: 'legacy', // Use legacy path for backward compatibility tests
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
const result = await FileGenerator.generate(options);
|
|
@@ -58,6 +59,7 @@ describe('FileGenerator', () => {
|
|
|
58
59
|
features: ['crm'],
|
|
59
60
|
oauthProviders: [],
|
|
60
61
|
isTypeScript: false,
|
|
62
|
+
integrationPath: 'legacy',
|
|
61
63
|
};
|
|
62
64
|
|
|
63
65
|
const result = await FileGenerator.generate(options);
|
|
@@ -75,6 +77,7 @@ describe('FileGenerator', () => {
|
|
|
75
77
|
features: [],
|
|
76
78
|
oauthProviders: [],
|
|
77
79
|
isTypeScript: false,
|
|
80
|
+
integrationPath: 'legacy',
|
|
78
81
|
};
|
|
79
82
|
|
|
80
83
|
const result = await FileGenerator.generate(options);
|
|
@@ -90,6 +93,7 @@ describe('FileGenerator', () => {
|
|
|
90
93
|
organizationId: 'org-123',
|
|
91
94
|
features: [],
|
|
92
95
|
oauthProviders: [],
|
|
96
|
+
integrationPath: 'legacy',
|
|
93
97
|
};
|
|
94
98
|
|
|
95
99
|
const result = await FileGenerator.generate(options);
|
|
@@ -108,7 +112,8 @@ describe('FileGenerator', () => {
|
|
|
108
112
|
oauthProviders: ['google'],
|
|
109
113
|
isTypeScript: false,
|
|
110
114
|
routerType: 'app',
|
|
111
|
-
frameworkType: 'nextjs',
|
|
115
|
+
frameworkType: 'nextjs',
|
|
116
|
+
integrationPath: 'legacy',
|
|
112
117
|
};
|
|
113
118
|
|
|
114
119
|
const result = await FileGenerator.generate(options);
|
|
@@ -126,6 +131,7 @@ describe('FileGenerator', () => {
|
|
|
126
131
|
oauthProviders: ['google'],
|
|
127
132
|
isTypeScript: true,
|
|
128
133
|
frameworkType: 'expo',
|
|
134
|
+
integrationPath: 'legacy',
|
|
129
135
|
};
|
|
130
136
|
|
|
131
137
|
const result = await FileGenerator.generate(options);
|
|
@@ -143,6 +149,7 @@ describe('FileGenerator', () => {
|
|
|
143
149
|
oauthProviders: ['google'],
|
|
144
150
|
isTypeScript: false,
|
|
145
151
|
routerType: 'app',
|
|
152
|
+
integrationPath: 'legacy',
|
|
146
153
|
};
|
|
147
154
|
|
|
148
155
|
const result = await FileGenerator.generate(options);
|
|
@@ -160,6 +167,7 @@ describe('FileGenerator', () => {
|
|
|
160
167
|
oauthProviders: null,
|
|
161
168
|
isTypeScript: false,
|
|
162
169
|
routerType: 'app',
|
|
170
|
+
integrationPath: 'legacy',
|
|
163
171
|
};
|
|
164
172
|
|
|
165
173
|
const result = await FileGenerator.generate(options);
|
|
@@ -177,6 +185,7 @@ describe('FileGenerator', () => {
|
|
|
177
185
|
oauthProviders: ['google'],
|
|
178
186
|
productionDomain: 'example.com',
|
|
179
187
|
appName: 'Test App',
|
|
188
|
+
integrationPath: 'legacy',
|
|
180
189
|
};
|
|
181
190
|
|
|
182
191
|
const result = await FileGenerator.generate(options);
|
|
@@ -193,6 +202,7 @@ describe('FileGenerator', () => {
|
|
|
193
202
|
organizationId: 'org-123',
|
|
194
203
|
features: ['crm'],
|
|
195
204
|
oauthProviders: [],
|
|
205
|
+
integrationPath: 'legacy',
|
|
196
206
|
};
|
|
197
207
|
|
|
198
208
|
const result = await FileGenerator.generate(options);
|
|
@@ -208,11 +218,11 @@ describe('FileGenerator', () => {
|
|
|
208
218
|
organizationId: 'org-123',
|
|
209
219
|
features: [],
|
|
210
220
|
oauthProviders: [],
|
|
221
|
+
integrationPath: 'legacy',
|
|
211
222
|
};
|
|
212
223
|
|
|
213
224
|
const result = await FileGenerator.generate(options);
|
|
214
225
|
|
|
215
|
-
// gitignore generator returns path or null depending on if update needed
|
|
216
226
|
expect(result).toHaveProperty('gitignore');
|
|
217
227
|
});
|
|
218
228
|
|
|
@@ -229,6 +239,7 @@ describe('FileGenerator', () => {
|
|
|
229
239
|
productionDomain: 'example.com',
|
|
230
240
|
appName: 'Full App',
|
|
231
241
|
frameworkType: 'nextjs',
|
|
242
|
+
integrationPath: 'legacy',
|
|
232
243
|
};
|
|
233
244
|
|
|
234
245
|
const result = await FileGenerator.generate(options);
|
|
@@ -239,4 +250,205 @@ describe('FileGenerator', () => {
|
|
|
239
250
|
expect(result.oauthGuide).not.toBeNull();
|
|
240
251
|
});
|
|
241
252
|
});
|
|
253
|
+
|
|
254
|
+
describe('api-only integration path', () => {
|
|
255
|
+
it('returns results object with expected structure', async () => {
|
|
256
|
+
const options = {
|
|
257
|
+
projectPath: mockProjectPath,
|
|
258
|
+
apiKey: 'test-key',
|
|
259
|
+
backendUrl: 'https://backend.test.com',
|
|
260
|
+
organizationId: 'org-123',
|
|
261
|
+
features: ['crm'],
|
|
262
|
+
oauthProviders: [],
|
|
263
|
+
isTypeScript: true,
|
|
264
|
+
integrationPath: 'api-only',
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const result = await FileGenerator.generate(options);
|
|
268
|
+
|
|
269
|
+
expect(result).toHaveProperty('apiClient');
|
|
270
|
+
expect(result).toHaveProperty('types');
|
|
271
|
+
expect(result).toHaveProperty('webhooks');
|
|
272
|
+
expect(result).toHaveProperty('index');
|
|
273
|
+
expect(result).toHaveProperty('envFile');
|
|
274
|
+
expect(result).toHaveProperty('gitignore');
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
it('generates typed client file', async () => {
|
|
278
|
+
const options = {
|
|
279
|
+
projectPath: mockProjectPath,
|
|
280
|
+
apiKey: 'test-key',
|
|
281
|
+
backendUrl: 'https://backend.test.com',
|
|
282
|
+
organizationId: 'org-123',
|
|
283
|
+
features: ['crm'],
|
|
284
|
+
oauthProviders: [],
|
|
285
|
+
isTypeScript: true,
|
|
286
|
+
integrationPath: 'api-only',
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const result = await FileGenerator.generate(options);
|
|
290
|
+
|
|
291
|
+
expect(result.apiClient).not.toBeNull();
|
|
292
|
+
expect(result.apiClient).toContain('client.ts');
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it('generates types file for TypeScript projects', async () => {
|
|
296
|
+
const options = {
|
|
297
|
+
projectPath: mockProjectPath,
|
|
298
|
+
apiKey: 'test-key',
|
|
299
|
+
backendUrl: 'https://backend.test.com',
|
|
300
|
+
organizationId: 'org-123',
|
|
301
|
+
features: ['crm'],
|
|
302
|
+
oauthProviders: [],
|
|
303
|
+
isTypeScript: true,
|
|
304
|
+
integrationPath: 'api-only',
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
const result = await FileGenerator.generate(options);
|
|
308
|
+
|
|
309
|
+
expect(result.types).not.toBeNull();
|
|
310
|
+
expect(result.types).toContain('types.ts');
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
it('does not generate types file for JavaScript projects', async () => {
|
|
314
|
+
const options = {
|
|
315
|
+
projectPath: mockProjectPath,
|
|
316
|
+
apiKey: 'test-key',
|
|
317
|
+
backendUrl: 'https://backend.test.com',
|
|
318
|
+
organizationId: 'org-123',
|
|
319
|
+
features: ['crm'],
|
|
320
|
+
oauthProviders: [],
|
|
321
|
+
isTypeScript: false,
|
|
322
|
+
integrationPath: 'api-only',
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const result = await FileGenerator.generate(options);
|
|
326
|
+
|
|
327
|
+
expect(result.types).toBeNull();
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it('generates webhooks utility file', async () => {
|
|
331
|
+
const options = {
|
|
332
|
+
projectPath: mockProjectPath,
|
|
333
|
+
apiKey: 'test-key',
|
|
334
|
+
backendUrl: 'https://backend.test.com',
|
|
335
|
+
organizationId: 'org-123',
|
|
336
|
+
features: ['crm'],
|
|
337
|
+
oauthProviders: [],
|
|
338
|
+
isTypeScript: true,
|
|
339
|
+
integrationPath: 'api-only',
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const result = await FileGenerator.generate(options);
|
|
343
|
+
|
|
344
|
+
expect(result.webhooks).not.toBeNull();
|
|
345
|
+
expect(result.webhooks).toContain('webhooks.ts');
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
describe('quickstart integration path', () => {
|
|
350
|
+
it('returns results object with expected structure', async () => {
|
|
351
|
+
const options = {
|
|
352
|
+
projectPath: mockProjectPath,
|
|
353
|
+
apiKey: 'test-key',
|
|
354
|
+
backendUrl: 'https://backend.test.com',
|
|
355
|
+
organizationId: 'org-123',
|
|
356
|
+
features: ['crm', 'oauth'],
|
|
357
|
+
oauthProviders: ['google'],
|
|
358
|
+
isTypeScript: true,
|
|
359
|
+
frameworkType: 'nextjs',
|
|
360
|
+
integrationPath: 'quickstart',
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const result = await FileGenerator.generate(options);
|
|
364
|
+
|
|
365
|
+
expect(result).toHaveProperty('apiClient');
|
|
366
|
+
expect(result).toHaveProperty('types');
|
|
367
|
+
expect(result).toHaveProperty('webhooks');
|
|
368
|
+
expect(result).toHaveProperty('envFile');
|
|
369
|
+
expect(result).toHaveProperty('nextauth');
|
|
370
|
+
expect(result).toHaveProperty('oauthGuide');
|
|
371
|
+
expect(result).toHaveProperty('gitignore');
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it('generates NextAuth for Next.js with oauth feature', async () => {
|
|
375
|
+
const options = {
|
|
376
|
+
projectPath: mockProjectPath,
|
|
377
|
+
apiKey: 'test-key',
|
|
378
|
+
backendUrl: 'https://backend.test.com',
|
|
379
|
+
organizationId: 'org-123',
|
|
380
|
+
features: ['crm', 'oauth'],
|
|
381
|
+
oauthProviders: ['google'],
|
|
382
|
+
isTypeScript: true,
|
|
383
|
+
frameworkType: 'nextjs',
|
|
384
|
+
integrationPath: 'quickstart',
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const result = await FileGenerator.generate(options);
|
|
388
|
+
|
|
389
|
+
expect(result.nextauth).not.toBeNull();
|
|
390
|
+
expect(result.oauthGuide).not.toBeNull();
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
describe('mcp-assisted integration path', () => {
|
|
395
|
+
it('returns results object with expected structure', async () => {
|
|
396
|
+
const options = {
|
|
397
|
+
projectPath: mockProjectPath,
|
|
398
|
+
apiKey: 'test-key',
|
|
399
|
+
backendUrl: 'https://backend.test.com',
|
|
400
|
+
organizationId: 'org-123',
|
|
401
|
+
organizationName: 'Test Org',
|
|
402
|
+
features: ['crm'],
|
|
403
|
+
oauthProviders: [],
|
|
404
|
+
isTypeScript: true,
|
|
405
|
+
integrationPath: 'mcp-assisted',
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
const result = await FileGenerator.generate(options);
|
|
409
|
+
|
|
410
|
+
expect(result).toHaveProperty('mcpConfig');
|
|
411
|
+
expect(result).toHaveProperty('mcpGuide');
|
|
412
|
+
expect(result).toHaveProperty('envFile');
|
|
413
|
+
expect(result).toHaveProperty('gitignore');
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('generates MCP config file', async () => {
|
|
417
|
+
const options = {
|
|
418
|
+
projectPath: mockProjectPath,
|
|
419
|
+
apiKey: 'test-key',
|
|
420
|
+
backendUrl: 'https://backend.test.com',
|
|
421
|
+
organizationId: 'org-123',
|
|
422
|
+
organizationName: 'Test Org',
|
|
423
|
+
features: ['crm'],
|
|
424
|
+
oauthProviders: [],
|
|
425
|
+
isTypeScript: true,
|
|
426
|
+
integrationPath: 'mcp-assisted',
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const result = await FileGenerator.generate(options);
|
|
430
|
+
|
|
431
|
+
expect(result.mcpConfig).not.toBeNull();
|
|
432
|
+
expect(result.mcpConfig).toContain('mcp.json');
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
it('generates MCP guide file', async () => {
|
|
436
|
+
const options = {
|
|
437
|
+
projectPath: mockProjectPath,
|
|
438
|
+
apiKey: 'test-key',
|
|
439
|
+
backendUrl: 'https://backend.test.com',
|
|
440
|
+
organizationId: 'org-123',
|
|
441
|
+
organizationName: 'Test Org',
|
|
442
|
+
features: ['crm'],
|
|
443
|
+
oauthProviders: [],
|
|
444
|
+
isTypeScript: true,
|
|
445
|
+
integrationPath: 'mcp-assisted',
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
const result = await FileGenerator.generate(options);
|
|
449
|
+
|
|
450
|
+
expect(result.mcpGuide).not.toBeNull();
|
|
451
|
+
expect(result.mcpGuide).toContain('L4YERCAK3_MCP_GUIDE.md');
|
|
452
|
+
});
|
|
453
|
+
});
|
|
242
454
|
});
|