11import { generateCli } from '../../core/codegen/cli' ;
2+ import {
3+ generateReadme as generateCliReadme ,
4+ generateAgentsDocs as generateCliAgentsDocs ,
5+ getCliMcpTools ,
6+ generateSkills as generateCliSkills ,
7+ } from '../../core/codegen/cli/docs-generator' ;
8+ import { resolveDocsConfig } from '../../core/codegen/docs-utils' ;
9+ import {
10+ generateOrmReadme ,
11+ generateOrmAgentsDocs ,
12+ getOrmMcpTools ,
13+ generateOrmSkills ,
14+ } from '../../core/codegen/orm/docs-generator' ;
15+ import {
16+ generateHooksReadme ,
17+ generateHooksAgentsDocs ,
18+ getHooksMcpTools ,
19+ generateHooksSkills ,
20+ } from '../../core/codegen/hooks-docs-generator' ;
21+ import {
22+ generateTargetReadme ,
23+ generateCombinedMcpConfig ,
24+ generateRootRootReadme ,
25+ } from '../../core/codegen/target-docs-generator' ;
226import type {
327 CleanFieldType ,
428 CleanOperation ,
@@ -129,34 +153,10 @@ describe('cli-generator', () => {
129153 customQueries : 1 ,
130154 customMutations : 1 ,
131155 infraFiles : 3 ,
132- totalFiles : 10 ,
156+ totalFiles : 8 ,
133157 } ) ;
134158 } ) ;
135159
136- it ( 'generates README.md by default' , ( ) => {
137- const file = result . files . find ( ( f ) => f . fileName === 'README.md' ) ;
138- expect ( file ) . toBeDefined ( ) ;
139- expect ( file ! . content ) . toMatchSnapshot ( ) ;
140- } ) ;
141-
142- it ( 'generates AGENTS.md by default' , ( ) => {
143- const file = result . files . find ( ( f ) => f . fileName === 'AGENTS.md' ) ;
144- expect ( file ) . toBeDefined ( ) ;
145- expect ( file ! . content ) . toMatchSnapshot ( ) ;
146- } ) ;
147-
148- it ( 'does not generate mcp.json by default' , ( ) => {
149- const file = result . files . find ( ( f ) => f . fileName === 'mcp.json' ) ;
150- expect ( file ) . toBeUndefined ( ) ;
151- } ) ;
152-
153- it ( 'does not generate skills by default' , ( ) => {
154- const skillFiles = result . files . filter ( ( f ) =>
155- f . fileName . startsWith ( 'skills/' ) ,
156- ) ;
157- expect ( skillFiles ) . toHaveLength ( 0 ) ;
158- } ) ;
159-
160160 it ( 'generates executor.ts' , ( ) => {
161161 const file = result . files . find ( ( f ) => f . fileName === 'executor.ts' ) ;
162162 expect ( file ) . toBeDefined ( ) ;
@@ -241,8 +241,6 @@ describe('cli-generator', () => {
241241 it ( 'generates correct file names' , ( ) => {
242242 const fileNames = result . files . map ( ( f ) => f . fileName ) . sort ( ) ;
243243 expect ( fileNames ) . toEqual ( [
244- 'AGENTS.md' ,
245- 'README.md' ,
246244 'commands.ts' ,
247245 'commands/auth.ts' ,
248246 'commands/car.ts' ,
@@ -255,91 +253,159 @@ describe('cli-generator', () => {
255253 } ) ;
256254} ) ;
257255
258- describe ( 'cli-generator docs: true (all formats)' , ( ) => {
259- const result = generateCli ( {
260- tables : [ carTable , driverTable ] ,
261- customOperations : {
262- queries : [ currentUserQuery ] ,
263- mutations : [ loginMutation ] ,
264- } ,
265- config : {
266- cli : { toolName : 'myapp' , docs : true } ,
267- } ,
256+ const allCustomOps : CleanOperation [ ] = [ currentUserQuery , loginMutation ] ;
257+
258+ describe ( 'cli docs generator' , ( ) => {
259+ it ( 'generates CLI README' , ( ) => {
260+ const readme = generateCliReadme ( [ carTable , driverTable ] , allCustomOps , 'myapp' ) ;
261+ expect ( readme . fileName ) . toBe ( 'README.md' ) ;
262+ expect ( readme . content ) . toMatchSnapshot ( ) ;
268263 } ) ;
269264
270- it ( 'generates mcp.json ' , ( ) => {
271- const file = result . files . find ( ( f ) => f . fileName === 'mcp.json ') ;
272- expect ( file ) . toBeDefined ( ) ;
273- expect ( file ! . content ) . toMatchSnapshot ( ) ;
265+ it ( 'generates CLI AGENTS.md ' , ( ) => {
266+ const agents = generateCliAgentsDocs ( [ carTable , driverTable ] , allCustomOps , 'myapp ') ;
267+ expect ( agents . fileName ) . toBe ( 'AGENTS.md' ) ;
268+ expect ( agents . content ) . toMatchSnapshot ( ) ;
274269 } ) ;
275270
276- it ( 'generates skill files' , ( ) => {
277- const skillFiles = result . files . filter ( ( f ) =>
278- f . fileName . startsWith ( 'skills/' ) ,
279- ) ;
280- expect ( skillFiles . length ) . toBeGreaterThan ( 0 ) ;
281- for ( const sf of skillFiles ) {
271+ it ( 'generates CLI MCP tools' , ( ) => {
272+ const tools = getCliMcpTools ( [ carTable , driverTable ] , allCustomOps , 'myapp' ) ;
273+ expect ( tools . length ) . toBeGreaterThan ( 0 ) ;
274+ for ( const tool of tools ) {
275+ expect ( tool . name ) . toBeDefined ( ) ;
276+ expect ( tool . description ) . toBeDefined ( ) ;
277+ expect ( tool . inputSchema ) . toBeDefined ( ) ;
278+ }
279+ } ) ;
280+
281+ it ( 'generates CLI skill files' , ( ) => {
282+ const skills = generateCliSkills ( [ carTable , driverTable ] , allCustomOps , 'myapp' ) ;
283+ expect ( skills . length ) . toBeGreaterThan ( 0 ) ;
284+ for ( const sf of skills ) {
282285 expect ( sf . content ) . toMatchSnapshot ( ) ;
283286 }
284287 } ) ;
288+ } ) ;
285289
286- it ( 'generates correct file names with all docs' , ( ) => {
287- const fileNames = result . files . map ( ( f ) => f . fileName ) . sort ( ) ;
288- expect ( fileNames ) . toEqual ( [
289- 'AGENTS.md' ,
290- 'README.md' ,
291- 'commands.ts' ,
292- 'commands/auth.ts' ,
293- 'commands/car.ts' ,
294- 'commands/context.ts' ,
295- 'commands/current-user.ts' ,
296- 'commands/driver.ts' ,
297- 'commands/login.ts' ,
298- 'executor.ts' ,
299- 'mcp.json' ,
300- 'skills/auth.md' ,
301- 'skills/car.md' ,
302- 'skills/context.md' ,
303- 'skills/current-user.md' ,
304- 'skills/driver.md' ,
305- 'skills/login.md' ,
306- ] ) ;
290+ describe ( 'orm docs generator' , ( ) => {
291+ it ( 'generates ORM README' , ( ) => {
292+ const readme = generateOrmReadme ( [ carTable , driverTable ] , allCustomOps ) ;
293+ expect ( readme . fileName ) . toBe ( 'README.md' ) ;
294+ expect ( readme . content ) . toMatchSnapshot ( ) ;
307295 } ) ;
308296
309- it ( 'mcp.json has valid tool definitions' , ( ) => {
310- const file = result . files . find ( ( f ) => f . fileName === 'mcp.json' ) ;
311- const parsed = JSON . parse ( file ! . content ) ;
312- expect ( parsed . name ) . toBe ( 'myapp' ) ;
313- expect ( parsed . tools ) . toBeDefined ( ) ;
314- expect ( parsed . tools . length ) . toBeGreaterThan ( 0 ) ;
315- for ( const tool of parsed . tools ) {
297+ it ( 'generates ORM AGENTS.md' , ( ) => {
298+ const agents = generateOrmAgentsDocs ( [ carTable , driverTable ] , allCustomOps ) ;
299+ expect ( agents . fileName ) . toBe ( 'AGENTS.md' ) ;
300+ expect ( agents . content ) . toMatchSnapshot ( ) ;
301+ } ) ;
302+
303+ it ( 'generates ORM MCP tools' , ( ) => {
304+ const tools = getOrmMcpTools ( [ carTable , driverTable ] , allCustomOps ) ;
305+ expect ( tools . length ) . toBeGreaterThan ( 0 ) ;
306+ for ( const tool of tools ) {
316307 expect ( tool . name ) . toBeDefined ( ) ;
317308 expect ( tool . description ) . toBeDefined ( ) ;
318309 expect ( tool . inputSchema ) . toBeDefined ( ) ;
319310 }
320311 } ) ;
312+
313+ it ( 'generates ORM skill files' , ( ) => {
314+ const skills = generateOrmSkills ( [ carTable , driverTable ] , allCustomOps ) ;
315+ expect ( skills . length ) . toBeGreaterThan ( 0 ) ;
316+ for ( const sf of skills ) {
317+ expect ( sf . content ) . toMatchSnapshot ( ) ;
318+ }
319+ } ) ;
321320} ) ;
322321
323- describe ( 'cli-generator docs: false' , ( ) => {
324- const result = generateCli ( {
325- tables : [ carTable , driverTable ] ,
326- customOperations : {
327- queries : [ currentUserQuery ] ,
328- mutations : [ loginMutation ] ,
329- } ,
330- config : {
331- cli : { toolName : 'myapp' , docs : false } ,
332- } ,
322+ describe ( 'hooks docs generator' , ( ) => {
323+ it ( 'generates hooks README' , ( ) => {
324+ const readme = generateHooksReadme ( [ carTable , driverTable ] , allCustomOps ) ;
325+ expect ( readme . fileName ) . toBe ( 'README.md' ) ;
326+ expect ( readme . content ) . toMatchSnapshot ( ) ;
333327 } ) ;
334328
335- it ( 'generates no doc files' , ( ) => {
336- const docFiles = result . files . filter (
337- ( f ) =>
338- f . fileName === 'README.md' ||
339- f . fileName === 'AGENTS.md' ||
340- f . fileName === 'mcp.json' ||
341- f . fileName . startsWith ( 'skills/' ) ,
342- ) ;
343- expect ( docFiles ) . toHaveLength ( 0 ) ;
329+ it ( 'generates hooks AGENTS.md' , ( ) => {
330+ const agents = generateHooksAgentsDocs ( [ carTable , driverTable ] , allCustomOps ) ;
331+ expect ( agents . fileName ) . toBe ( 'AGENTS.md' ) ;
332+ expect ( agents . content ) . toMatchSnapshot ( ) ;
333+ } ) ;
334+
335+ it ( 'generates hooks MCP tools' , ( ) => {
336+ const tools = getHooksMcpTools ( [ carTable , driverTable ] , allCustomOps ) ;
337+ expect ( tools . length ) . toBeGreaterThan ( 0 ) ;
338+ for ( const tool of tools ) {
339+ expect ( tool . name ) . toBeDefined ( ) ;
340+ expect ( tool . description ) . toBeDefined ( ) ;
341+ expect ( tool . inputSchema ) . toBeDefined ( ) ;
342+ }
343+ } ) ;
344+
345+ it ( 'generates hooks skill files' , ( ) => {
346+ const skills = generateHooksSkills ( [ carTable , driverTable ] , allCustomOps ) ;
347+ expect ( skills . length ) . toBeGreaterThan ( 0 ) ;
348+ for ( const sf of skills ) {
349+ expect ( sf . content ) . toMatchSnapshot ( ) ;
350+ }
351+ } ) ;
352+ } ) ;
353+
354+ describe ( 'target docs generator' , ( ) => {
355+ it ( 'generates per-target README' , ( ) => {
356+ const readme = generateTargetReadme ( {
357+ hasOrm : true ,
358+ hasHooks : true ,
359+ hasCli : true ,
360+ tableCount : 2 ,
361+ customQueryCount : 1 ,
362+ customMutationCount : 1 ,
363+ config : { cli : { toolName : 'myapp' } } ,
364+ } ) ;
365+ expect ( readme . fileName ) . toBe ( 'README.md' ) ;
366+ expect ( readme . content ) . toMatchSnapshot ( ) ;
367+ } ) ;
368+
369+ it ( 'generates combined MCP config' , ( ) => {
370+ const cliTools = getCliMcpTools ( [ carTable , driverTable ] , allCustomOps , 'myapp' ) ;
371+ const ormTools = getOrmMcpTools ( [ carTable , driverTable ] , allCustomOps ) ;
372+ const allTools = [ ...cliTools , ...ormTools ] ;
373+ const mcp = generateCombinedMcpConfig ( allTools , 'myapp' ) ;
374+ expect ( mcp . fileName ) . toBe ( 'mcp.json' ) ;
375+ const parsed = JSON . parse ( mcp . content ) ;
376+ expect ( parsed . name ) . toBe ( 'myapp' ) ;
377+ expect ( parsed . tools . length ) . toBe ( allTools . length ) ;
378+ expect ( mcp . content ) . toMatchSnapshot ( ) ;
379+ } ) ;
380+
381+ it ( 'generates root-root README for multi-target' , ( ) => {
382+ const readme = generateRootRootReadme ( [
383+ { name : 'auth' , output : './generated/auth' , endpoint : 'http://auth.localhost/graphql' , generators : [ 'ORM' ] } ,
384+ { name : 'app' , output : './generated/app' , endpoint : 'http://app.localhost/graphql' , generators : [ 'ORM' , 'React Query' , 'CLI' ] } ,
385+ ] ) ;
386+ expect ( readme . fileName ) . toBe ( 'README.md' ) ;
387+ expect ( readme . content ) . toMatchSnapshot ( ) ;
388+ } ) ;
389+ } ) ;
390+
391+ describe ( 'resolveDocsConfig' , ( ) => {
392+ it ( 'defaults to readme + agents' , ( ) => {
393+ const config = resolveDocsConfig ( undefined ) ;
394+ expect ( config ) . toEqual ( { readme : true , agents : true , mcp : false , skills : false } ) ;
395+ } ) ;
396+
397+ it ( 'docs: true enables all' , ( ) => {
398+ const config = resolveDocsConfig ( true ) ;
399+ expect ( config ) . toEqual ( { readme : true , agents : true , mcp : true , skills : true } ) ;
400+ } ) ;
401+
402+ it ( 'docs: false disables all' , ( ) => {
403+ const config = resolveDocsConfig ( false ) ;
404+ expect ( config ) . toEqual ( { readme : false , agents : false , mcp : false , skills : false } ) ;
405+ } ) ;
406+
407+ it ( 'partial config fills defaults' , ( ) => {
408+ const config = resolveDocsConfig ( { mcp : true } ) ;
409+ expect ( config ) . toEqual ( { readme : true , agents : true , mcp : true , skills : false } ) ;
344410 } ) ;
345411} ) ;
0 commit comments