@constructive-io/graphql-codegen 4.19.1 → 4.20.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.
@@ -34,6 +34,16 @@ export interface RootBarrelOptions {
34
34
  * Re-exports from subdirectories based on which generators are enabled.
35
35
  */
36
36
  export declare function generateRootBarrel(options?: RootBarrelOptions): string;
37
+ /**
38
+ * Generate a root index.ts for multi-target output that re-exports each
39
+ * target as a namespace.
40
+ *
41
+ * Example output:
42
+ * export * as admin from './admin';
43
+ * export * as auth from './auth';
44
+ * export * as public_ from './public';
45
+ */
46
+ export declare function generateMultiTargetBarrel(targetNames: string[]): string;
37
47
  /**
38
48
  * Generate queries barrel including custom query operations
39
49
  */
@@ -37,6 +37,7 @@ exports.generateQueriesBarrel = generateQueriesBarrel;
37
37
  exports.generateMutationsBarrel = generateMutationsBarrel;
38
38
  exports.generateMainBarrel = generateMainBarrel;
39
39
  exports.generateRootBarrel = generateRootBarrel;
40
+ exports.generateMultiTargetBarrel = generateMultiTargetBarrel;
40
41
  exports.generateCustomQueriesBarrel = generateCustomQueriesBarrel;
41
42
  exports.generateCustomMutationsBarrel = generateCustomMutationsBarrel;
42
43
  /**
@@ -200,6 +201,49 @@ function generateRootBarrel(options = {}) {
200
201
  return (0, babel_ast_1.generateCode)(statements);
201
202
  }
202
203
  // ============================================================================
204
+ // Multi-target root barrel (re-exports each target as a namespace)
205
+ // ============================================================================
206
+ /** JS reserved words that need an alias when used as export names */
207
+ const JS_RESERVED = new Set([
208
+ 'abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch',
209
+ 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do',
210
+ 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final',
211
+ 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import',
212
+ 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new',
213
+ 'null', 'package', 'private', 'protected', 'public', 'return', 'short',
214
+ 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws',
215
+ 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while',
216
+ 'with', 'yield',
217
+ ]);
218
+ /**
219
+ * Generate a root index.ts for multi-target output that re-exports each
220
+ * target as a namespace.
221
+ *
222
+ * Example output:
223
+ * export * as admin from './admin';
224
+ * export * as auth from './auth';
225
+ * export * as public_ from './public';
226
+ */
227
+ function generateMultiTargetBarrel(targetNames) {
228
+ const statements = [];
229
+ for (const name of targetNames) {
230
+ const alias = JS_RESERVED.has(name) ? `${name}_` : name;
231
+ const exportDecl = t.exportNamedDeclaration(null, [t.exportNamespaceSpecifier(t.identifier(alias))], t.stringLiteral(`./${name}`));
232
+ statements.push(exportDecl);
233
+ }
234
+ if (statements.length > 0) {
235
+ (0, babel_ast_1.addJSDocComment)(statements[0], [
236
+ '@constructive-io/sdk',
237
+ '',
238
+ 'Auto-generated GraphQL types and ORM client.',
239
+ 'Run `pnpm run generate` to populate this package from the schema files.',
240
+ '',
241
+ '@generated by @constructive-io/graphql-codegen',
242
+ ]);
243
+ }
244
+ return (0, babel_ast_1.generateCode)(statements);
245
+ }
246
+ // ============================================================================
203
247
  // Custom operation barrels (includes both table and custom hooks)
204
248
  // ============================================================================
205
249
  /**
package/core/generate.js CHANGED
@@ -675,11 +675,23 @@ async function generateMulti(options) {
675
675
  await writeFiles(cliSkillsToWrite, skillsOutputDir, [], { pruneStaleFiles: false });
676
676
  }
677
677
  }
678
- // Generate root-root README if multi-target
678
+ // Generate root-root README and barrel if multi-target
679
679
  if (names.length > 1 && targetInfos.length > 0 && !dryRun) {
680
- const rootReadme = (0, target_docs_generator_1.generateRootRootReadme)(targetInfos);
681
680
  const { writeGeneratedFiles: writeFiles } = await Promise.resolve().then(() => __importStar(require('./output')));
681
+ const rootReadme = (0, target_docs_generator_1.generateRootRootReadme)(targetInfos);
682
682
  await writeFiles([{ path: rootReadme.fileName, content: rootReadme.content }], '.', [], { pruneStaleFiles: false });
683
+ // Write a root barrel (index.ts) that re-exports each target as a
684
+ // namespace so the package has a single entry-point. Derive the
685
+ // common output root from the first target's output path.
686
+ const successfulNames = results
687
+ .filter((r) => r.result.success)
688
+ .map((r) => r.name);
689
+ if (successfulNames.length > 0) {
690
+ const firstOutput = (0, config_1.getConfigOptions)(configs[successfulNames[0]]).output;
691
+ const outputRoot = node_path_1.default.dirname(firstOutput);
692
+ const barrelContent = (0, barrel_1.generateMultiTargetBarrel)(successfulNames);
693
+ await writeFiles([{ path: 'index.ts', content: barrelContent }], outputRoot, [], { pruneStaleFiles: false });
694
+ }
683
695
  }
684
696
  }
685
697
  finally {
@@ -34,6 +34,16 @@ export interface RootBarrelOptions {
34
34
  * Re-exports from subdirectories based on which generators are enabled.
35
35
  */
36
36
  export declare function generateRootBarrel(options?: RootBarrelOptions): string;
37
+ /**
38
+ * Generate a root index.ts for multi-target output that re-exports each
39
+ * target as a namespace.
40
+ *
41
+ * Example output:
42
+ * export * as admin from './admin';
43
+ * export * as auth from './auth';
44
+ * export * as public_ from './public';
45
+ */
46
+ export declare function generateMultiTargetBarrel(targetNames: string[]): string;
37
47
  /**
38
48
  * Generate queries barrel including custom query operations
39
49
  */
@@ -159,6 +159,49 @@ export function generateRootBarrel(options = {}) {
159
159
  return generateCode(statements);
160
160
  }
161
161
  // ============================================================================
162
+ // Multi-target root barrel (re-exports each target as a namespace)
163
+ // ============================================================================
164
+ /** JS reserved words that need an alias when used as export names */
165
+ const JS_RESERVED = new Set([
166
+ 'abstract', 'arguments', 'await', 'boolean', 'break', 'byte', 'case', 'catch',
167
+ 'char', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do',
168
+ 'double', 'else', 'enum', 'eval', 'export', 'extends', 'false', 'final',
169
+ 'finally', 'float', 'for', 'function', 'goto', 'if', 'implements', 'import',
170
+ 'in', 'instanceof', 'int', 'interface', 'let', 'long', 'native', 'new',
171
+ 'null', 'package', 'private', 'protected', 'public', 'return', 'short',
172
+ 'static', 'super', 'switch', 'synchronized', 'this', 'throw', 'throws',
173
+ 'transient', 'true', 'try', 'typeof', 'var', 'void', 'volatile', 'while',
174
+ 'with', 'yield',
175
+ ]);
176
+ /**
177
+ * Generate a root index.ts for multi-target output that re-exports each
178
+ * target as a namespace.
179
+ *
180
+ * Example output:
181
+ * export * as admin from './admin';
182
+ * export * as auth from './auth';
183
+ * export * as public_ from './public';
184
+ */
185
+ export function generateMultiTargetBarrel(targetNames) {
186
+ const statements = [];
187
+ for (const name of targetNames) {
188
+ const alias = JS_RESERVED.has(name) ? `${name}_` : name;
189
+ const exportDecl = t.exportNamedDeclaration(null, [t.exportNamespaceSpecifier(t.identifier(alias))], t.stringLiteral(`./${name}`));
190
+ statements.push(exportDecl);
191
+ }
192
+ if (statements.length > 0) {
193
+ addJSDocComment(statements[0], [
194
+ '@constructive-io/sdk',
195
+ '',
196
+ 'Auto-generated GraphQL types and ORM client.',
197
+ 'Run `pnpm run generate` to populate this package from the schema files.',
198
+ '',
199
+ '@generated by @constructive-io/graphql-codegen',
200
+ ]);
201
+ }
202
+ return generateCode(statements);
203
+ }
204
+ // ============================================================================
162
205
  // Custom operation barrels (includes both table and custom hooks)
163
206
  // ============================================================================
164
207
  /**
@@ -13,7 +13,7 @@ import { createEphemeralDb } from 'pgsql-client';
13
13
  import { deployPgpm } from 'pgsql-seed';
14
14
  import { getConfigOptions } from '../types/config';
15
15
  import { generate as generateReactQueryFiles } from './codegen';
16
- import { generateRootBarrel } from './codegen/barrel';
16
+ import { generateRootBarrel, generateMultiTargetBarrel } from './codegen/barrel';
17
17
  import { generateCli as generateCliFiles, generateMultiTargetCli } from './codegen/cli';
18
18
  import { generateReadme as generateCliReadme, generateAgentsDocs as generateCliAgentsDocs, getCliMcpTools, generateSkills as generateCliSkills, generateMultiTargetReadme, generateMultiTargetAgentsDocs, getMultiTargetCliMcpTools, generateMultiTargetSkills, } from './codegen/cli/docs-generator';
19
19
  import { resolveDocsConfig } from './codegen/docs-utils';
@@ -633,11 +633,23 @@ export async function generateMulti(options) {
633
633
  await writeFiles(cliSkillsToWrite, skillsOutputDir, [], { pruneStaleFiles: false });
634
634
  }
635
635
  }
636
- // Generate root-root README if multi-target
636
+ // Generate root-root README and barrel if multi-target
637
637
  if (names.length > 1 && targetInfos.length > 0 && !dryRun) {
638
- const rootReadme = generateRootRootReadme(targetInfos);
639
638
  const { writeGeneratedFiles: writeFiles } = await import('./output');
639
+ const rootReadme = generateRootRootReadme(targetInfos);
640
640
  await writeFiles([{ path: rootReadme.fileName, content: rootReadme.content }], '.', [], { pruneStaleFiles: false });
641
+ // Write a root barrel (index.ts) that re-exports each target as a
642
+ // namespace so the package has a single entry-point. Derive the
643
+ // common output root from the first target's output path.
644
+ const successfulNames = results
645
+ .filter((r) => r.result.success)
646
+ .map((r) => r.name);
647
+ if (successfulNames.length > 0) {
648
+ const firstOutput = getConfigOptions(configs[successfulNames[0]]).output;
649
+ const outputRoot = path.dirname(firstOutput);
650
+ const barrelContent = generateMultiTargetBarrel(successfulNames);
651
+ await writeFiles([{ path: 'index.ts', content: barrelContent }], outputRoot, [], { pruneStaleFiles: false });
652
+ }
641
653
  }
642
654
  }
643
655
  finally {
@@ -138,8 +138,8 @@ export interface DocsConfig {
138
138
  */
139
139
  mcp?: boolean;
140
140
  /**
141
- * Generate skills/ directory — per-entity SKILL.md files with YAML frontmatter.
142
- * Skills are written to the workspace root skills/ directory (not nested in output).
141
+ * Generate .agents/skills/ directory — per-entity SKILL.md files with YAML frontmatter.
142
+ * Skills are written to {workspaceRoot}/.agents/skills/ (not nested in output).
143
143
  * Uses composable naming: orm-{target}-{entity}, hooks-{target}-{entity}, cli-{target}-{entity}.
144
144
  * @default false
145
145
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "4.19.1",
3
+ "version": "4.20.0",
4
4
  "description": "GraphQL SDK generator for Constructive databases with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -101,5 +101,5 @@
101
101
  "tsx": "^4.21.0",
102
102
  "typescript": "^5.9.3"
103
103
  },
104
- "gitHead": "b0ff4ed0025af0e5df91d8e3535c347e4cde6438"
104
+ "gitHead": "9bd7e1bb2eb2e66ac18dce50cc29b84ef667649e"
105
105
  }
package/types/config.d.ts CHANGED
@@ -138,8 +138,8 @@ export interface DocsConfig {
138
138
  */
139
139
  mcp?: boolean;
140
140
  /**
141
- * Generate skills/ directory — per-entity SKILL.md files with YAML frontmatter.
142
- * Skills are written to the workspace root skills/ directory (not nested in output).
141
+ * Generate .agents/skills/ directory — per-entity SKILL.md files with YAML frontmatter.
142
+ * Skills are written to {workspaceRoot}/.agents/skills/ (not nested in output).
143
143
  * Uses composable naming: orm-{target}-{entity}, hooks-{target}-{entity}, cli-{target}-{entity}.
144
144
  * @default false
145
145
  */