@constructive-io/graphql-codegen 4.46.0 → 4.47.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.
package/README.md CHANGED
@@ -937,6 +937,10 @@ Common issues and solutions for pgpm, PostgreSQL, and testing.
937
937
  * [@pgsql/types](https://www.npmjs.com/package/@pgsql/types): **📝 Type definitions** for PostgreSQL AST nodes in TypeScript.
938
938
  * [@pgsql/utils](https://www.npmjs.com/package/@pgsql/utils): **🛠️ AST utilities** for constructing and transforming PostgreSQL syntax trees.
939
939
 
940
+ ### 📚 Documentation & Skills
941
+
942
+ * [constructive-skills](https://github.com/constructive-io/constructive-skills): **📖 Platform documentation and AI agent skills** — feature catalog, blueprint reference, SDK guides (i18n, billing, limits, events, uploads, security, entities, search, AI), and deployment guides.
943
+
940
944
  ## Credits
941
945
 
942
946
  **🛠 Built by the [Constructive](https://constructive.io) team — creators of modular Postgres tooling for secure, composable backends. If you like our work, contribute on [GitHub](https://github.com/constructive-io).**
@@ -46,6 +46,8 @@ export interface GenerateMultiOptions {
46
46
  dryRun?: boolean;
47
47
  schema?: SchemaConfig;
48
48
  unifiedCli?: CliConfig | boolean;
49
+ /** Remove subdirectories in the output root that don't match any current target name. */
50
+ cleanStaleTargets?: boolean;
49
51
  }
50
52
  export interface GenerateMultiResult {
51
53
  results: Array<{
@@ -54,4 +56,10 @@ export interface GenerateMultiResult {
54
56
  }>;
55
57
  hasError: boolean;
56
58
  }
59
+ /**
60
+ * Remove subdirectories in `outputRoot` that are not in `currentTargetNames`.
61
+ * Useful for cleaning up stale target output before a fresh multi-target generate.
62
+ * Returns the list of directory names that were removed.
63
+ */
64
+ export declare function removeStaleTargetDirs(outputRoot: string, currentTargetNames: string[], verbose?: boolean): string[];
57
65
  export declare function generateMulti(options: GenerateMultiOptions): Promise<GenerateMultiResult>;
package/core/generate.js CHANGED
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.generate = generate;
40
40
  exports.expandApiNamesToMultiTarget = expandApiNamesToMultiTarget;
41
41
  exports.expandSchemaDirToMultiTarget = expandSchemaDirToMultiTarget;
42
+ exports.removeStaleTargetDirs = removeStaleTargetDirs;
42
43
  exports.generateMulti = generateMulti;
43
44
  /**
44
45
  * Main generate function - orchestrates the entire codegen pipeline
@@ -509,8 +510,30 @@ function applySharedPgpmDb(config, sharedSources) {
509
510
  db: sharedDbConfig,
510
511
  };
511
512
  }
513
+ /**
514
+ * Remove subdirectories in `outputRoot` that are not in `currentTargetNames`.
515
+ * Useful for cleaning up stale target output before a fresh multi-target generate.
516
+ * Returns the list of directory names that were removed.
517
+ */
518
+ function removeStaleTargetDirs(outputRoot, currentTargetNames, verbose) {
519
+ const removed = [];
520
+ if (!fs.existsSync(outputRoot))
521
+ return removed;
522
+ const currentTargets = new Set(currentTargetNames);
523
+ const entries = fs.readdirSync(outputRoot, { withFileTypes: true });
524
+ for (const entry of entries) {
525
+ if (entry.isDirectory() && !currentTargets.has(entry.name)) {
526
+ fs.rmSync(node_path_1.default.join(outputRoot, entry.name), { recursive: true, force: true });
527
+ removed.push(entry.name);
528
+ if (verbose) {
529
+ console.log(`Removed stale target directory: ${entry.name}`);
530
+ }
531
+ }
532
+ }
533
+ return removed;
534
+ }
512
535
  async function generateMulti(options) {
513
- const { configs, cliOverrides, verbose, dryRun, schema, unifiedCli } = options;
536
+ const { configs, cliOverrides, verbose, dryRun, schema, unifiedCli, cleanStaleTargets } = options;
514
537
  const names = Object.keys(configs);
515
538
  const results = [];
516
539
  let hasError = false;
@@ -518,6 +541,12 @@ async function generateMulti(options) {
518
541
  const targetInfos = [];
519
542
  const useUnifiedCli = !schemaEnabled && !!unifiedCli && names.length > 1;
520
543
  const cliTargets = [];
544
+ // Remove stale target directories before generating
545
+ if (cleanStaleTargets && names.length > 0 && !dryRun) {
546
+ const firstOutput = (0, config_1.getConfigOptions)(configs[names[0]]).output;
547
+ const outputRoot = node_path_1.default.dirname(firstOutput);
548
+ removeStaleTargetDirs(outputRoot, names, verbose);
549
+ }
521
550
  const sharedSources = await prepareSharedPgpmSources(configs, cliOverrides);
522
551
  try {
523
552
  for (const name of names) {
@@ -46,6 +46,8 @@ export interface GenerateMultiOptions {
46
46
  dryRun?: boolean;
47
47
  schema?: SchemaConfig;
48
48
  unifiedCli?: CliConfig | boolean;
49
+ /** Remove subdirectories in the output root that don't match any current target name. */
50
+ cleanStaleTargets?: boolean;
49
51
  }
50
52
  export interface GenerateMultiResult {
51
53
  results: Array<{
@@ -54,4 +56,10 @@ export interface GenerateMultiResult {
54
56
  }>;
55
57
  hasError: boolean;
56
58
  }
59
+ /**
60
+ * Remove subdirectories in `outputRoot` that are not in `currentTargetNames`.
61
+ * Useful for cleaning up stale target output before a fresh multi-target generate.
62
+ * Returns the list of directory names that were removed.
63
+ */
64
+ export declare function removeStaleTargetDirs(outputRoot: string, currentTargetNames: string[], verbose?: boolean): string[];
57
65
  export declare function generateMulti(options: GenerateMultiOptions): Promise<GenerateMultiResult>;
@@ -467,8 +467,30 @@ function applySharedPgpmDb(config, sharedSources) {
467
467
  db: sharedDbConfig,
468
468
  };
469
469
  }
470
+ /**
471
+ * Remove subdirectories in `outputRoot` that are not in `currentTargetNames`.
472
+ * Useful for cleaning up stale target output before a fresh multi-target generate.
473
+ * Returns the list of directory names that were removed.
474
+ */
475
+ export function removeStaleTargetDirs(outputRoot, currentTargetNames, verbose) {
476
+ const removed = [];
477
+ if (!fs.existsSync(outputRoot))
478
+ return removed;
479
+ const currentTargets = new Set(currentTargetNames);
480
+ const entries = fs.readdirSync(outputRoot, { withFileTypes: true });
481
+ for (const entry of entries) {
482
+ if (entry.isDirectory() && !currentTargets.has(entry.name)) {
483
+ fs.rmSync(path.join(outputRoot, entry.name), { recursive: true, force: true });
484
+ removed.push(entry.name);
485
+ if (verbose) {
486
+ console.log(`Removed stale target directory: ${entry.name}`);
487
+ }
488
+ }
489
+ }
490
+ return removed;
491
+ }
470
492
  export async function generateMulti(options) {
471
- const { configs, cliOverrides, verbose, dryRun, schema, unifiedCli } = options;
493
+ const { configs, cliOverrides, verbose, dryRun, schema, unifiedCli, cleanStaleTargets } = options;
472
494
  const names = Object.keys(configs);
473
495
  const results = [];
474
496
  let hasError = false;
@@ -476,6 +498,12 @@ export async function generateMulti(options) {
476
498
  const targetInfos = [];
477
499
  const useUnifiedCli = !schemaEnabled && !!unifiedCli && names.length > 1;
478
500
  const cliTargets = [];
501
+ // Remove stale target directories before generating
502
+ if (cleanStaleTargets && names.length > 0 && !dryRun) {
503
+ const firstOutput = getConfigOptions(configs[names[0]]).output;
504
+ const outputRoot = path.dirname(firstOutput);
505
+ removeStaleTargetDirs(outputRoot, names, verbose);
506
+ }
479
507
  const sharedSources = await prepareSharedPgpmSources(configs, cliOverrides);
480
508
  try {
481
509
  for (const name of names) {
package/esm/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export * from './generators';
11
11
  export * from './client';
12
12
  export { defineConfig } from './types/config';
13
13
  export type { GenerateOptions, GenerateResult, GenerateMultiOptions, GenerateMultiResult } from './core/generate';
14
- export { generate, generateMulti, expandApiNamesToMultiTarget, expandSchemaDirToMultiTarget } from './core/generate';
14
+ export { generate, generateMulti, expandApiNamesToMultiTarget, expandSchemaDirToMultiTarget, removeStaleTargetDirs } from './core/generate';
15
15
  export { findConfigFile, loadConfigFile } from './core/config';
16
16
  export { runCodegenHandler } from './cli/handler';
17
17
  export type { CodegenAnswers } from './cli/shared';
package/esm/index.js CHANGED
@@ -15,7 +15,7 @@ export * from './generators';
15
15
  export * from './client';
16
16
  // Config definition helper
17
17
  export { defineConfig } from './types/config';
18
- export { generate, generateMulti, expandApiNamesToMultiTarget, expandSchemaDirToMultiTarget } from './core/generate';
18
+ export { generate, generateMulti, expandApiNamesToMultiTarget, expandSchemaDirToMultiTarget, removeStaleTargetDirs } from './core/generate';
19
19
  // Config utilities
20
20
  export { findConfigFile, loadConfigFile } from './core/config';
21
21
  // CLI shared utilities (for packages/cli to import)
package/index.d.ts CHANGED
@@ -11,7 +11,7 @@ export * from './generators';
11
11
  export * from './client';
12
12
  export { defineConfig } from './types/config';
13
13
  export type { GenerateOptions, GenerateResult, GenerateMultiOptions, GenerateMultiResult } from './core/generate';
14
- export { generate, generateMulti, expandApiNamesToMultiTarget, expandSchemaDirToMultiTarget } from './core/generate';
14
+ export { generate, generateMulti, expandApiNamesToMultiTarget, expandSchemaDirToMultiTarget, removeStaleTargetDirs } from './core/generate';
15
15
  export { findConfigFile, loadConfigFile } from './core/config';
16
16
  export { runCodegenHandler } from './cli/handler';
17
17
  export type { CodegenAnswers } from './cli/shared';
package/index.js CHANGED
@@ -21,7 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
21
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.buildSchemaFromDatabase = exports.splitCommas = exports.seedArgvFromConfig = exports.printResult = exports.normalizeCodegenListOptions = exports.hyphenateKeys = exports.hasResolvedCodegenSource = exports.flattenDbFields = exports.filterDefined = exports.codegenQuestions = exports.camelizeArgv = exports.buildGenerateOptions = exports.buildDbConfig = exports.runCodegenHandler = exports.loadConfigFile = exports.findConfigFile = exports.expandSchemaDirToMultiTarget = exports.expandApiNamesToMultiTarget = exports.generateMulti = exports.generate = exports.defineConfig = void 0;
24
+ exports.buildSchemaFromDatabase = exports.splitCommas = exports.seedArgvFromConfig = exports.printResult = exports.normalizeCodegenListOptions = exports.hyphenateKeys = exports.hasResolvedCodegenSource = exports.flattenDbFields = exports.filterDefined = exports.codegenQuestions = exports.camelizeArgv = exports.buildGenerateOptions = exports.buildDbConfig = exports.runCodegenHandler = exports.loadConfigFile = exports.findConfigFile = exports.removeStaleTargetDirs = exports.expandSchemaDirToMultiTarget = exports.expandApiNamesToMultiTarget = exports.generateMulti = exports.generate = exports.defineConfig = void 0;
25
25
  // Core types
26
26
  __exportStar(require("./types"), exports);
27
27
  // Core query building
@@ -38,6 +38,7 @@ Object.defineProperty(exports, "generate", { enumerable: true, get: function ()
38
38
  Object.defineProperty(exports, "generateMulti", { enumerable: true, get: function () { return generate_1.generateMulti; } });
39
39
  Object.defineProperty(exports, "expandApiNamesToMultiTarget", { enumerable: true, get: function () { return generate_1.expandApiNamesToMultiTarget; } });
40
40
  Object.defineProperty(exports, "expandSchemaDirToMultiTarget", { enumerable: true, get: function () { return generate_1.expandSchemaDirToMultiTarget; } });
41
+ Object.defineProperty(exports, "removeStaleTargetDirs", { enumerable: true, get: function () { return generate_1.removeStaleTargetDirs; } });
41
42
  // Config utilities
42
43
  var config_2 = require("./core/config");
43
44
  Object.defineProperty(exports, "findConfigFile", { enumerable: true, get: function () { return config_2.findConfigFile; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constructive-io/graphql-codegen",
3
- "version": "4.46.0",
3
+ "version": "4.47.0",
4
4
  "description": "GraphQL SDK generator for Constructive databases with React Query hooks",
5
5
  "keywords": [
6
6
  "graphql",
@@ -56,7 +56,7 @@
56
56
  "@0no-co/graphql.web": "^1.1.2",
57
57
  "@babel/generator": "^7.29.1",
58
58
  "@babel/types": "^7.29.0",
59
- "@constructive-io/graphql-query": "^3.27.0",
59
+ "@constructive-io/graphql-query": "^3.27.1",
60
60
  "@constructive-io/graphql-types": "^3.12.0",
61
61
  "@inquirerer/utils": "^3.3.7",
62
62
  "@pgpmjs/core": "^6.21.0",
@@ -64,7 +64,7 @@
64
64
  "deepmerge": "^4.3.1",
65
65
  "find-and-require-package-json": "^0.9.1",
66
66
  "gql-ast": "^3.11.0",
67
- "graphile-schema": "^1.22.0",
67
+ "graphile-schema": "^1.22.1",
68
68
  "graphql": "16.13.0",
69
69
  "inflekt": "^0.7.1",
70
70
  "inquirerer": "^4.8.1",
@@ -100,5 +100,5 @@
100
100
  "tsx": "^4.21.0",
101
101
  "typescript": "^5.9.3"
102
102
  },
103
- "gitHead": "0503916f414a3b8a6f6cbe46e03a59988b2f3cb5"
103
+ "gitHead": "6e5e79cbc24e2861963aeb1f6daff6d55279f081"
104
104
  }