@constructive-io/graphql-codegen 2.32.0 → 3.0.1

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 (270) hide show
  1. package/README.md +429 -1691
  2. package/cli/index.d.ts +5 -2
  3. package/cli/index.js +98 -581
  4. package/cli/shared.d.ts +35 -0
  5. package/cli/shared.js +106 -0
  6. package/{esm/cli → core}/codegen/barrel.d.ts +1 -1
  7. package/{cli → core}/codegen/barrel.js +1 -4
  8. package/{esm/cli → core}/codegen/index.d.ts +15 -5
  9. package/{cli → core}/codegen/index.js +44 -24
  10. package/{cli → core}/codegen/invalidation.d.ts +2 -2
  11. package/{esm/cli → core}/codegen/mutation-keys.d.ts +2 -2
  12. package/{cli → core}/codegen/orm/client-generator.js +2 -3
  13. package/{esm/cli → core}/codegen/orm/index.d.ts +9 -2
  14. package/{cli → core}/codegen/orm/index.js +3 -2
  15. package/{cli → core}/codegen/query-keys.d.ts +2 -2
  16. package/core/codegen/shared/index.d.ts +39 -0
  17. package/core/codegen/shared/index.js +118 -0
  18. package/core/config/index.d.ts +5 -0
  19. package/core/config/index.js +13 -0
  20. package/core/config/loader.d.ts +18 -0
  21. package/{cli/commands/init.js → core/config/loader.js} +7 -94
  22. package/core/config/resolver.d.ts +46 -0
  23. package/core/config/resolver.js +104 -0
  24. package/core/database/index.d.ts +43 -0
  25. package/core/database/index.js +85 -0
  26. package/core/generate.d.ts +22 -0
  27. package/core/generate.js +192 -0
  28. package/core/index.d.ts +13 -1
  29. package/core/index.js +22 -2
  30. package/{cli → core}/introspect/fetch-schema.js +58 -9
  31. package/core/introspect/source/api-schemas.d.ts +44 -0
  32. package/core/introspect/source/api-schemas.js +122 -0
  33. package/core/introspect/source/database.d.ts +32 -0
  34. package/core/introspect/source/database.js +91 -0
  35. package/core/introspect/source/index.d.ts +112 -0
  36. package/core/introspect/source/index.js +173 -0
  37. package/core/introspect/source/pgpm-module.d.ts +83 -0
  38. package/core/introspect/source/pgpm-module.js +200 -0
  39. package/core/output/index.d.ts +4 -0
  40. package/core/output/index.js +9 -0
  41. package/core/output/writer.d.ts +38 -0
  42. package/core/output/writer.js +156 -0
  43. package/{cli/commands/shared.d.ts → core/pipeline/index.d.ts} +5 -3
  44. package/{cli/commands/shared.js → core/pipeline/index.js} +4 -0
  45. package/{cli → core}/watch/orchestrator.d.ts +25 -3
  46. package/{cli → core}/watch/orchestrator.js +35 -27
  47. package/{cli → core}/watch/types.d.ts +1 -1
  48. package/esm/cli/index.d.ts +5 -2
  49. package/esm/cli/index.js +97 -547
  50. package/esm/cli/shared.d.ts +35 -0
  51. package/esm/cli/shared.js +101 -0
  52. package/{cli → esm/core}/codegen/barrel.d.ts +1 -1
  53. package/esm/{cli → core}/codegen/barrel.js +1 -4
  54. package/{cli → esm/core}/codegen/index.d.ts +15 -5
  55. package/esm/{cli → core}/codegen/index.js +44 -24
  56. package/esm/{cli → core}/codegen/invalidation.d.ts +2 -2
  57. package/{cli → esm/core}/codegen/mutation-keys.d.ts +2 -2
  58. package/esm/{cli → core}/codegen/orm/client-generator.js +2 -3
  59. package/{cli → esm/core}/codegen/orm/index.d.ts +9 -2
  60. package/esm/{cli → core}/codegen/orm/index.js +3 -2
  61. package/esm/{cli → core}/codegen/query-keys.d.ts +2 -2
  62. package/esm/core/codegen/shared/index.d.ts +39 -0
  63. package/esm/core/codegen/shared/index.js +79 -0
  64. package/esm/core/config/index.d.ts +5 -0
  65. package/esm/core/config/index.js +5 -0
  66. package/esm/core/config/loader.d.ts +18 -0
  67. package/esm/core/config/loader.js +71 -0
  68. package/esm/core/config/resolver.d.ts +46 -0
  69. package/esm/core/config/resolver.js +100 -0
  70. package/esm/core/database/index.d.ts +43 -0
  71. package/esm/core/database/index.js +48 -0
  72. package/esm/core/generate.d.ts +22 -0
  73. package/esm/core/generate.js +186 -0
  74. package/esm/core/index.d.ts +13 -1
  75. package/esm/core/index.js +20 -1
  76. package/esm/{cli → core}/introspect/fetch-schema.js +55 -9
  77. package/esm/core/introspect/source/api-schemas.d.ts +44 -0
  78. package/esm/core/introspect/source/api-schemas.js +117 -0
  79. package/esm/core/introspect/source/database.d.ts +32 -0
  80. package/esm/core/introspect/source/database.js +87 -0
  81. package/esm/core/introspect/source/index.d.ts +112 -0
  82. package/esm/core/introspect/source/index.js +154 -0
  83. package/esm/core/introspect/source/pgpm-module.d.ts +83 -0
  84. package/esm/core/introspect/source/pgpm-module.js +194 -0
  85. package/esm/core/output/index.d.ts +4 -0
  86. package/esm/core/output/index.js +4 -0
  87. package/esm/core/output/writer.d.ts +38 -0
  88. package/esm/core/output/writer.js +119 -0
  89. package/esm/{cli/commands/shared.d.ts → core/pipeline/index.d.ts} +5 -3
  90. package/esm/{cli/commands/shared.js → core/pipeline/index.js} +1 -0
  91. package/esm/{cli → core}/watch/orchestrator.d.ts +25 -3
  92. package/esm/{cli → core}/watch/orchestrator.js +35 -27
  93. package/esm/{cli → core}/watch/types.d.ts +1 -1
  94. package/esm/index.d.ts +8 -3
  95. package/esm/index.js +9 -3
  96. package/esm/types/config.d.ts +101 -138
  97. package/esm/types/config.js +8 -35
  98. package/esm/types/index.d.ts +2 -2
  99. package/esm/types/index.js +1 -1
  100. package/index.d.ts +8 -3
  101. package/index.js +18 -8
  102. package/package.json +18 -11
  103. package/types/config.d.ts +101 -138
  104. package/types/config.js +9 -38
  105. package/types/index.d.ts +2 -2
  106. package/types/index.js +3 -3
  107. package/cli/commands/generate-orm.d.ts +0 -53
  108. package/cli/commands/generate-orm.js +0 -292
  109. package/cli/commands/generate.d.ts +0 -66
  110. package/cli/commands/generate.js +0 -431
  111. package/cli/commands/index.d.ts +0 -9
  112. package/cli/commands/index.js +0 -14
  113. package/cli/commands/init.d.ts +0 -35
  114. package/cli/introspect/source/index.d.ts +0 -48
  115. package/cli/introspect/source/index.js +0 -72
  116. package/esm/cli/commands/generate-orm.d.ts +0 -53
  117. package/esm/cli/commands/generate-orm.js +0 -289
  118. package/esm/cli/commands/generate.d.ts +0 -66
  119. package/esm/cli/commands/generate.js +0 -393
  120. package/esm/cli/commands/index.d.ts +0 -9
  121. package/esm/cli/commands/index.js +0 -6
  122. package/esm/cli/commands/init.d.ts +0 -35
  123. package/esm/cli/commands/init.js +0 -158
  124. package/esm/cli/introspect/source/index.d.ts +0 -48
  125. package/esm/cli/introspect/source/index.js +0 -54
  126. /package/{cli → core}/codegen/babel-ast.d.ts +0 -0
  127. /package/{cli → core}/codegen/babel-ast.js +0 -0
  128. /package/{cli → core}/codegen/client.d.ts +0 -0
  129. /package/{cli → core}/codegen/client.js +0 -0
  130. /package/{cli → core}/codegen/custom-mutations.d.ts +0 -0
  131. /package/{cli → core}/codegen/custom-mutations.js +0 -0
  132. /package/{cli → core}/codegen/custom-queries.d.ts +0 -0
  133. /package/{cli → core}/codegen/custom-queries.js +0 -0
  134. /package/{cli → core}/codegen/gql-ast.d.ts +0 -0
  135. /package/{cli → core}/codegen/gql-ast.js +0 -0
  136. /package/{cli → core}/codegen/invalidation.js +0 -0
  137. /package/{cli → core}/codegen/mutation-keys.js +0 -0
  138. /package/{cli → core}/codegen/mutations.d.ts +0 -0
  139. /package/{cli → core}/codegen/mutations.js +0 -0
  140. /package/{cli → core}/codegen/orm/barrel.d.ts +0 -0
  141. /package/{cli → core}/codegen/orm/barrel.js +0 -0
  142. /package/{cli → core}/codegen/orm/client-generator.d.ts +0 -0
  143. /package/{cli → core}/codegen/orm/client.d.ts +0 -0
  144. /package/{cli → core}/codegen/orm/client.js +0 -0
  145. /package/{cli → core}/codegen/orm/custom-ops-generator.d.ts +0 -0
  146. /package/{cli → core}/codegen/orm/custom-ops-generator.js +0 -0
  147. /package/{cli → core}/codegen/orm/input-types-generator.d.ts +0 -0
  148. /package/{cli → core}/codegen/orm/input-types-generator.js +0 -0
  149. /package/{cli → core}/codegen/orm/model-generator.d.ts +0 -0
  150. /package/{cli → core}/codegen/orm/model-generator.js +0 -0
  151. /package/{cli → core}/codegen/orm/query-builder.d.ts +0 -0
  152. /package/{cli → core}/codegen/orm/query-builder.js +0 -0
  153. /package/{cli → core}/codegen/orm/query-builder.ts +0 -0
  154. /package/{cli → core}/codegen/orm/select-types.d.ts +0 -0
  155. /package/{cli → core}/codegen/orm/select-types.js +0 -0
  156. /package/{cli → core}/codegen/queries.d.ts +0 -0
  157. /package/{cli → core}/codegen/queries.js +0 -0
  158. /package/{cli → core}/codegen/query-keys.js +0 -0
  159. /package/{cli → core}/codegen/scalars.d.ts +0 -0
  160. /package/{cli → core}/codegen/scalars.js +0 -0
  161. /package/{cli → core}/codegen/schema-gql-ast.d.ts +0 -0
  162. /package/{cli → core}/codegen/schema-gql-ast.js +0 -0
  163. /package/{cli → core}/codegen/schema-types-generator.d.ts +0 -0
  164. /package/{cli → core}/codegen/schema-types-generator.js +0 -0
  165. /package/{cli → core}/codegen/type-resolver.d.ts +0 -0
  166. /package/{cli → core}/codegen/type-resolver.js +0 -0
  167. /package/{cli → core}/codegen/types.d.ts +0 -0
  168. /package/{cli → core}/codegen/types.js +0 -0
  169. /package/{cli → core}/codegen/utils.d.ts +0 -0
  170. /package/{cli → core}/codegen/utils.js +0 -0
  171. /package/{cli → core}/introspect/fetch-schema.d.ts +0 -0
  172. /package/{cli → core}/introspect/index.d.ts +0 -0
  173. /package/{cli → core}/introspect/index.js +0 -0
  174. /package/{cli → core}/introspect/infer-tables.d.ts +0 -0
  175. /package/{cli → core}/introspect/infer-tables.js +0 -0
  176. /package/{cli → core}/introspect/schema-query.d.ts +0 -0
  177. /package/{cli → core}/introspect/schema-query.js +0 -0
  178. /package/{cli → core}/introspect/source/endpoint.d.ts +0 -0
  179. /package/{cli → core}/introspect/source/endpoint.js +0 -0
  180. /package/{cli → core}/introspect/source/file.d.ts +0 -0
  181. /package/{cli → core}/introspect/source/file.js +0 -0
  182. /package/{cli → core}/introspect/source/types.d.ts +0 -0
  183. /package/{cli → core}/introspect/source/types.js +0 -0
  184. /package/{cli → core}/introspect/transform-schema.d.ts +0 -0
  185. /package/{cli → core}/introspect/transform-schema.js +0 -0
  186. /package/{cli → core}/introspect/transform.d.ts +0 -0
  187. /package/{cli → core}/introspect/transform.js +0 -0
  188. /package/{cli → core}/watch/cache.d.ts +0 -0
  189. /package/{cli → core}/watch/cache.js +0 -0
  190. /package/{cli → core}/watch/debounce.d.ts +0 -0
  191. /package/{cli → core}/watch/debounce.js +0 -0
  192. /package/{cli → core}/watch/hash.d.ts +0 -0
  193. /package/{cli → core}/watch/hash.js +0 -0
  194. /package/{cli → core}/watch/index.d.ts +0 -0
  195. /package/{cli → core}/watch/index.js +0 -0
  196. /package/{cli → core}/watch/poller.d.ts +0 -0
  197. /package/{cli → core}/watch/poller.js +0 -0
  198. /package/{cli → core}/watch/types.js +0 -0
  199. /package/esm/{cli → core}/codegen/babel-ast.d.ts +0 -0
  200. /package/esm/{cli → core}/codegen/babel-ast.js +0 -0
  201. /package/esm/{cli → core}/codegen/client.d.ts +0 -0
  202. /package/esm/{cli → core}/codegen/client.js +0 -0
  203. /package/esm/{cli → core}/codegen/custom-mutations.d.ts +0 -0
  204. /package/esm/{cli → core}/codegen/custom-mutations.js +0 -0
  205. /package/esm/{cli → core}/codegen/custom-queries.d.ts +0 -0
  206. /package/esm/{cli → core}/codegen/custom-queries.js +0 -0
  207. /package/esm/{cli → core}/codegen/gql-ast.d.ts +0 -0
  208. /package/esm/{cli → core}/codegen/gql-ast.js +0 -0
  209. /package/esm/{cli → core}/codegen/invalidation.js +0 -0
  210. /package/esm/{cli → core}/codegen/mutation-keys.js +0 -0
  211. /package/esm/{cli → core}/codegen/mutations.d.ts +0 -0
  212. /package/esm/{cli → core}/codegen/mutations.js +0 -0
  213. /package/esm/{cli → core}/codegen/orm/barrel.d.ts +0 -0
  214. /package/esm/{cli → core}/codegen/orm/barrel.js +0 -0
  215. /package/esm/{cli → core}/codegen/orm/client-generator.d.ts +0 -0
  216. /package/esm/{cli → core}/codegen/orm/client.d.ts +0 -0
  217. /package/esm/{cli → core}/codegen/orm/client.js +0 -0
  218. /package/esm/{cli → core}/codegen/orm/custom-ops-generator.d.ts +0 -0
  219. /package/esm/{cli → core}/codegen/orm/custom-ops-generator.js +0 -0
  220. /package/esm/{cli → core}/codegen/orm/input-types-generator.d.ts +0 -0
  221. /package/esm/{cli → core}/codegen/orm/input-types-generator.js +0 -0
  222. /package/esm/{cli → core}/codegen/orm/model-generator.d.ts +0 -0
  223. /package/esm/{cli → core}/codegen/orm/model-generator.js +0 -0
  224. /package/esm/{cli → core}/codegen/orm/query-builder.d.ts +0 -0
  225. /package/esm/{cli → core}/codegen/orm/query-builder.js +0 -0
  226. /package/esm/{cli → core}/codegen/orm/select-types.d.ts +0 -0
  227. /package/esm/{cli → core}/codegen/orm/select-types.js +0 -0
  228. /package/esm/{cli → core}/codegen/queries.d.ts +0 -0
  229. /package/esm/{cli → core}/codegen/queries.js +0 -0
  230. /package/esm/{cli → core}/codegen/query-keys.js +0 -0
  231. /package/esm/{cli → core}/codegen/scalars.d.ts +0 -0
  232. /package/esm/{cli → core}/codegen/scalars.js +0 -0
  233. /package/esm/{cli → core}/codegen/schema-gql-ast.d.ts +0 -0
  234. /package/esm/{cli → core}/codegen/schema-gql-ast.js +0 -0
  235. /package/esm/{cli → core}/codegen/schema-types-generator.d.ts +0 -0
  236. /package/esm/{cli → core}/codegen/schema-types-generator.js +0 -0
  237. /package/esm/{cli → core}/codegen/type-resolver.d.ts +0 -0
  238. /package/esm/{cli → core}/codegen/type-resolver.js +0 -0
  239. /package/esm/{cli → core}/codegen/types.d.ts +0 -0
  240. /package/esm/{cli → core}/codegen/types.js +0 -0
  241. /package/esm/{cli → core}/codegen/utils.d.ts +0 -0
  242. /package/esm/{cli → core}/codegen/utils.js +0 -0
  243. /package/esm/{cli → core}/introspect/fetch-schema.d.ts +0 -0
  244. /package/esm/{cli → core}/introspect/index.d.ts +0 -0
  245. /package/esm/{cli → core}/introspect/index.js +0 -0
  246. /package/esm/{cli → core}/introspect/infer-tables.d.ts +0 -0
  247. /package/esm/{cli → core}/introspect/infer-tables.js +0 -0
  248. /package/esm/{cli → core}/introspect/schema-query.d.ts +0 -0
  249. /package/esm/{cli → core}/introspect/schema-query.js +0 -0
  250. /package/esm/{cli → core}/introspect/source/endpoint.d.ts +0 -0
  251. /package/esm/{cli → core}/introspect/source/endpoint.js +0 -0
  252. /package/esm/{cli → core}/introspect/source/file.d.ts +0 -0
  253. /package/esm/{cli → core}/introspect/source/file.js +0 -0
  254. /package/esm/{cli → core}/introspect/source/types.d.ts +0 -0
  255. /package/esm/{cli → core}/introspect/source/types.js +0 -0
  256. /package/esm/{cli → core}/introspect/transform-schema.d.ts +0 -0
  257. /package/esm/{cli → core}/introspect/transform-schema.js +0 -0
  258. /package/esm/{cli → core}/introspect/transform.d.ts +0 -0
  259. /package/esm/{cli → core}/introspect/transform.js +0 -0
  260. /package/esm/{cli → core}/watch/cache.d.ts +0 -0
  261. /package/esm/{cli → core}/watch/cache.js +0 -0
  262. /package/esm/{cli → core}/watch/debounce.d.ts +0 -0
  263. /package/esm/{cli → core}/watch/debounce.js +0 -0
  264. /package/esm/{cli → core}/watch/hash.d.ts +0 -0
  265. /package/esm/{cli → core}/watch/hash.js +0 -0
  266. /package/esm/{cli → core}/watch/index.d.ts +0 -0
  267. /package/esm/{cli → core}/watch/index.js +0 -0
  268. /package/esm/{cli → core}/watch/poller.d.ts +0 -0
  269. /package/esm/{cli → core}/watch/poller.js +0 -0
  270. /package/esm/{cli → core}/watch/types.js +0 -0
@@ -1,37 +1,86 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.fetchSchema = fetchSchema;
4
7
  /**
5
8
  * Fetch GraphQL schema introspection from an endpoint
6
9
  */
10
+ const node_dns_1 = __importDefault(require("node:dns"));
11
+ const undici_1 = require("undici");
7
12
  const schema_query_1 = require("./schema-query");
13
+ /**
14
+ * Check if a hostname is localhost or a localhost subdomain
15
+ */
16
+ function isLocalhostHostname(hostname) {
17
+ return hostname === 'localhost' || hostname.endsWith('.localhost');
18
+ }
19
+ /**
20
+ * Create an undici Agent that resolves *.localhost to 127.0.0.1
21
+ * This fixes DNS resolution issues on macOS where subdomains like api.localhost
22
+ * don't resolve automatically (unlike browsers which handle *.localhost).
23
+ */
24
+ function createLocalhostAgent() {
25
+ return new undici_1.Agent({
26
+ connect: {
27
+ lookup(hostname, opts, cb) {
28
+ if (isLocalhostHostname(hostname)) {
29
+ cb(null, '127.0.0.1', 4);
30
+ return;
31
+ }
32
+ node_dns_1.default.lookup(hostname, opts, cb);
33
+ },
34
+ },
35
+ });
36
+ }
37
+ let localhostAgent = null;
38
+ function getLocalhostAgent() {
39
+ if (!localhostAgent) {
40
+ localhostAgent = createLocalhostAgent();
41
+ }
42
+ return localhostAgent;
43
+ }
8
44
  /**
9
45
  * Fetch the full schema introspection from a GraphQL endpoint
10
46
  */
11
47
  async function fetchSchema(options) {
12
48
  const { endpoint, authorization, headers = {}, timeout = 30000 } = options;
49
+ // Parse the endpoint URL to check for localhost
50
+ const url = new URL(endpoint);
51
+ const useLocalhostAgent = isLocalhostHostname(url.hostname);
13
52
  // Build headers
14
53
  const requestHeaders = {
15
54
  'Content-Type': 'application/json',
16
55
  Accept: 'application/json',
17
56
  ...headers,
18
57
  };
58
+ // Set Host header for localhost subdomains to preserve routing
59
+ if (useLocalhostAgent && url.hostname !== 'localhost') {
60
+ requestHeaders['Host'] = url.hostname;
61
+ }
19
62
  if (authorization) {
20
63
  requestHeaders['Authorization'] = authorization;
21
64
  }
22
65
  // Create abort controller for timeout
23
66
  const controller = new AbortController();
24
67
  const timeoutId = setTimeout(() => controller.abort(), timeout);
68
+ // Build fetch options
69
+ const fetchOptions = {
70
+ method: 'POST',
71
+ headers: requestHeaders,
72
+ body: JSON.stringify({
73
+ query: schema_query_1.SCHEMA_INTROSPECTION_QUERY,
74
+ variables: {},
75
+ }),
76
+ signal: controller.signal,
77
+ };
78
+ // Use custom agent for localhost to fix DNS resolution on macOS
79
+ if (useLocalhostAgent) {
80
+ fetchOptions.dispatcher = getLocalhostAgent();
81
+ }
25
82
  try {
26
- const response = await fetch(endpoint, {
27
- method: 'POST',
28
- headers: requestHeaders,
29
- body: JSON.stringify({
30
- query: schema_query_1.SCHEMA_INTROSPECTION_QUERY,
31
- variables: {},
32
- }),
33
- signal: controller.signal,
34
- });
83
+ const response = await fetch(endpoint, fetchOptions);
35
84
  clearTimeout(timeoutId);
36
85
  if (!response.ok) {
37
86
  return {
@@ -0,0 +1,44 @@
1
+ /**
2
+ * API Schemas Resolution
3
+ *
4
+ * Utilities for resolving PostgreSQL schema names from API names
5
+ * by querying the services_public.api_schemas table.
6
+ */
7
+ import { Pool } from 'pg';
8
+ /**
9
+ * Result of validating services schema requirements
10
+ */
11
+ export interface ServicesSchemaValidation {
12
+ valid: boolean;
13
+ error?: string;
14
+ }
15
+ /**
16
+ * Validate that the required services schemas exist in the database
17
+ *
18
+ * Checks for:
19
+ * - services_public schema with apis and api_schemas tables
20
+ * - metaschema_public schema with schema table
21
+ *
22
+ * @param pool - Database connection pool
23
+ * @returns Validation result
24
+ */
25
+ export declare function validateServicesSchemas(pool: Pool): Promise<ServicesSchemaValidation>;
26
+ /**
27
+ * Resolve schema names from API names by querying services_public.api_schemas
28
+ *
29
+ * Joins services_public.apis, services_public.api_schemas, and metaschema_public.schema
30
+ * to get the actual PostgreSQL schema names for the given API names.
31
+ *
32
+ * @param pool - Database connection pool
33
+ * @param apiNames - Array of API names to resolve
34
+ * @returns Array of PostgreSQL schema names
35
+ * @throws Error if validation fails or no schemas found
36
+ */
37
+ export declare function resolveApiSchemas(pool: Pool, apiNames: string[]): Promise<string[]>;
38
+ /**
39
+ * Create a database pool for the given database name or connection string
40
+ *
41
+ * @param database - Database name or connection string
42
+ * @returns Database connection pool
43
+ */
44
+ export declare function createDatabasePool(database: string): Pool;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateServicesSchemas = validateServicesSchemas;
4
+ exports.resolveApiSchemas = resolveApiSchemas;
5
+ exports.createDatabasePool = createDatabasePool;
6
+ const pg_cache_1 = require("pg-cache");
7
+ const pg_env_1 = require("pg-env");
8
+ /**
9
+ * Validate that the required services schemas exist in the database
10
+ *
11
+ * Checks for:
12
+ * - services_public schema with apis and api_schemas tables
13
+ * - metaschema_public schema with schema table
14
+ *
15
+ * @param pool - Database connection pool
16
+ * @returns Validation result
17
+ */
18
+ async function validateServicesSchemas(pool) {
19
+ try {
20
+ // Check for services_public.apis table
21
+ const apisCheck = await pool.query(`
22
+ SELECT 1 FROM information_schema.tables
23
+ WHERE table_schema = 'services_public'
24
+ AND table_name = 'apis'
25
+ `);
26
+ if (apisCheck.rows.length === 0) {
27
+ return {
28
+ valid: false,
29
+ error: 'services_public.apis table not found. The database must have the services schema deployed.',
30
+ };
31
+ }
32
+ // Check for services_public.api_schemas table
33
+ const apiSchemasCheck = await pool.query(`
34
+ SELECT 1 FROM information_schema.tables
35
+ WHERE table_schema = 'services_public'
36
+ AND table_name = 'api_schemas'
37
+ `);
38
+ if (apiSchemasCheck.rows.length === 0) {
39
+ return {
40
+ valid: false,
41
+ error: 'services_public.api_schemas table not found. The database must have the services schema deployed.',
42
+ };
43
+ }
44
+ // Check for metaschema_public.schema table
45
+ const metaschemaCheck = await pool.query(`
46
+ SELECT 1 FROM information_schema.tables
47
+ WHERE table_schema = 'metaschema_public'
48
+ AND table_name = 'schema'
49
+ `);
50
+ if (metaschemaCheck.rows.length === 0) {
51
+ return {
52
+ valid: false,
53
+ error: 'metaschema_public.schema table not found. The database must have the metaschema deployed.',
54
+ };
55
+ }
56
+ return { valid: true };
57
+ }
58
+ catch (err) {
59
+ return {
60
+ valid: false,
61
+ error: `Failed to validate services schemas: ${err instanceof Error ? err.message : 'Unknown error'}`,
62
+ };
63
+ }
64
+ }
65
+ /**
66
+ * Resolve schema names from API names by querying services_public.api_schemas
67
+ *
68
+ * Joins services_public.apis, services_public.api_schemas, and metaschema_public.schema
69
+ * to get the actual PostgreSQL schema names for the given API names.
70
+ *
71
+ * @param pool - Database connection pool
72
+ * @param apiNames - Array of API names to resolve
73
+ * @returns Array of PostgreSQL schema names
74
+ * @throws Error if validation fails or no schemas found
75
+ */
76
+ async function resolveApiSchemas(pool, apiNames) {
77
+ // First validate that the required schemas exist
78
+ const validation = await validateServicesSchemas(pool);
79
+ if (!validation.valid) {
80
+ throw new Error(validation.error);
81
+ }
82
+ // Query to get schema names for the given API names
83
+ const result = await pool.query(`
84
+ SELECT DISTINCT ms.schema_name
85
+ FROM services_public.api_schemas as_tbl
86
+ JOIN services_public.apis api ON api.id = as_tbl.api_id
87
+ JOIN metaschema_public.schema ms ON ms.id = as_tbl.schema_id
88
+ WHERE api.name = ANY($1)
89
+ ORDER BY ms.schema_name
90
+ `, [apiNames]);
91
+ if (result.rows.length === 0) {
92
+ throw new Error(`No schemas found for API names: ${apiNames.join(', ')}. ` +
93
+ 'Ensure the APIs exist and have schemas assigned in services_public.api_schemas.');
94
+ }
95
+ return result.rows.map((row) => row.schema_name);
96
+ }
97
+ /**
98
+ * Create a database pool for the given database name or connection string
99
+ *
100
+ * @param database - Database name or connection string
101
+ * @returns Database connection pool
102
+ */
103
+ function createDatabasePool(database) {
104
+ // Check if it's a connection string or just a database name
105
+ const isConnectionString = database.startsWith('postgres://') || database.startsWith('postgresql://');
106
+ if (isConnectionString) {
107
+ // Parse connection string and extract database name
108
+ // Format: postgres://user:password@host:port/database
109
+ const url = new URL(database);
110
+ const dbName = url.pathname.slice(1); // Remove leading slash
111
+ return (0, pg_cache_1.getPgPool)({
112
+ host: url.hostname,
113
+ port: parseInt(url.port || '5432', 10),
114
+ user: url.username,
115
+ password: url.password,
116
+ database: dbName,
117
+ });
118
+ }
119
+ // Use environment variables for connection, just override database name
120
+ const config = (0, pg_env_1.getPgEnvOptions)({ database });
121
+ return (0, pg_cache_1.getPgPool)(config);
122
+ }
@@ -0,0 +1,32 @@
1
+ import type { SchemaSource, SchemaSourceResult } from './types';
2
+ export interface DatabaseSchemaSourceOptions {
3
+ /**
4
+ * Database name or connection string
5
+ * Can be a simple database name (uses PGHOST, PGPORT, PGUSER, PGPASSWORD env vars)
6
+ * or a full connection string (postgres://user:pass@host:port/dbname)
7
+ */
8
+ database: string;
9
+ /**
10
+ * PostgreSQL schemas to include in introspection
11
+ * Mutually exclusive with apiNames
12
+ */
13
+ schemas?: string[];
14
+ /**
15
+ * API names to resolve schemas from
16
+ * Queries services_public.api_schemas to get schema names
17
+ * Mutually exclusive with schemas
18
+ */
19
+ apiNames?: string[];
20
+ }
21
+ /**
22
+ * Schema source that loads from a PostgreSQL database
23
+ *
24
+ * Uses PostGraphile to introspect the database and generate a GraphQL schema.
25
+ * The schema is built in-memory without writing to disk.
26
+ */
27
+ export declare class DatabaseSchemaSource implements SchemaSource {
28
+ private readonly options;
29
+ constructor(options: DatabaseSchemaSourceOptions);
30
+ fetch(): Promise<SchemaSourceResult>;
31
+ describe(): string;
32
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DatabaseSchemaSource = void 0;
4
+ /**
5
+ * Database Schema Source
6
+ *
7
+ * Loads GraphQL schema directly from a PostgreSQL database using PostGraphile
8
+ * introspection and converts it to introspection format.
9
+ */
10
+ const graphql_1 = require("graphql");
11
+ const types_1 = require("./types");
12
+ const database_1 = require("../../database");
13
+ const api_schemas_1 = require("./api-schemas");
14
+ /**
15
+ * Schema source that loads from a PostgreSQL database
16
+ *
17
+ * Uses PostGraphile to introspect the database and generate a GraphQL schema.
18
+ * The schema is built in-memory without writing to disk.
19
+ */
20
+ class DatabaseSchemaSource {
21
+ options;
22
+ constructor(options) {
23
+ this.options = options;
24
+ }
25
+ async fetch() {
26
+ const { database, apiNames } = this.options;
27
+ // Resolve schemas - either from explicit schemas option or from apiNames
28
+ let schemas;
29
+ if (apiNames && apiNames.length > 0) {
30
+ // Validate services schemas exist at the beginning for database mode
31
+ const pool = (0, api_schemas_1.createDatabasePool)(database);
32
+ try {
33
+ const validation = await (0, api_schemas_1.validateServicesSchemas)(pool);
34
+ if (!validation.valid) {
35
+ throw new types_1.SchemaSourceError(validation.error, this.describe());
36
+ }
37
+ schemas = await (0, api_schemas_1.resolveApiSchemas)(pool, apiNames);
38
+ }
39
+ catch (err) {
40
+ if (err instanceof types_1.SchemaSourceError)
41
+ throw err;
42
+ throw new types_1.SchemaSourceError(`Failed to resolve API schemas: ${err instanceof Error ? err.message : 'Unknown error'}`, this.describe(), err instanceof Error ? err : undefined);
43
+ }
44
+ }
45
+ else {
46
+ schemas = this.options.schemas ?? ['public'];
47
+ }
48
+ // Build SDL from database
49
+ let sdl;
50
+ try {
51
+ sdl = await (0, database_1.buildSchemaSDLFromDatabase)({
52
+ database,
53
+ schemas,
54
+ });
55
+ }
56
+ catch (err) {
57
+ throw new types_1.SchemaSourceError(`Failed to introspect database: ${err instanceof Error ? err.message : 'Unknown error'}`, this.describe(), err instanceof Error ? err : undefined);
58
+ }
59
+ // Validate non-empty
60
+ if (!sdl.trim()) {
61
+ throw new types_1.SchemaSourceError('Database introspection returned empty schema', this.describe());
62
+ }
63
+ // Parse SDL to GraphQL schema
64
+ let schema;
65
+ try {
66
+ schema = (0, graphql_1.buildSchema)(sdl);
67
+ }
68
+ catch (err) {
69
+ throw new types_1.SchemaSourceError(`Invalid GraphQL SDL from database: ${err instanceof Error ? err.message : 'Unknown error'}`, this.describe(), err instanceof Error ? err : undefined);
70
+ }
71
+ // Convert to introspection format
72
+ let introspectionResult;
73
+ try {
74
+ introspectionResult = (0, graphql_1.introspectionFromSchema)(schema);
75
+ }
76
+ catch (err) {
77
+ throw new types_1.SchemaSourceError(`Failed to generate introspection: ${err instanceof Error ? err.message : 'Unknown error'}`, this.describe(), err instanceof Error ? err : undefined);
78
+ }
79
+ // Convert graphql-js introspection result to our mutable type
80
+ const introspection = JSON.parse(JSON.stringify(introspectionResult));
81
+ return { introspection };
82
+ }
83
+ describe() {
84
+ const { database, schemas, apiNames } = this.options;
85
+ if (apiNames && apiNames.length > 0) {
86
+ return `database: ${database} (apiNames: ${apiNames.join(', ')})`;
87
+ }
88
+ return `database: ${database} (schemas: ${(schemas ?? ['public']).join(', ')})`;
89
+ }
90
+ }
91
+ exports.DatabaseSchemaSource = DatabaseSchemaSource;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Schema Source Module
3
+ *
4
+ * Provides a unified interface for loading GraphQL schemas from different sources:
5
+ * - Live GraphQL endpoints (via introspection)
6
+ * - Static .graphql schema files
7
+ * - PostgreSQL databases (via PostGraphile introspection)
8
+ * - PGPM modules (via ephemeral database deployment)
9
+ */
10
+ export * from './types';
11
+ export * from './endpoint';
12
+ export * from './file';
13
+ export * from './database';
14
+ export * from './pgpm-module';
15
+ export * from './api-schemas';
16
+ import type { SchemaSource } from './types';
17
+ import type { DbConfig } from '../../../types/config';
18
+ /**
19
+ * Options for endpoint-based schema source
20
+ */
21
+ export interface EndpointSourceOptions {
22
+ endpoint: string;
23
+ authorization?: string;
24
+ headers?: Record<string, string>;
25
+ timeout?: number;
26
+ }
27
+ /**
28
+ * Options for file-based schema source
29
+ */
30
+ export interface FileSourceOptions {
31
+ schemaFile: string;
32
+ }
33
+ /**
34
+ * Options for database-based schema source
35
+ */
36
+ export interface DatabaseSourceOptions {
37
+ database: string;
38
+ schemas?: string[];
39
+ apiNames?: string[];
40
+ }
41
+ /**
42
+ * Options for PGPM module-based schema source (direct path)
43
+ */
44
+ export interface PgpmModulePathSourceOptions {
45
+ pgpmModulePath: string;
46
+ schemas?: string[];
47
+ apiNames?: string[];
48
+ keepDb?: boolean;
49
+ }
50
+ /**
51
+ * Options for PGPM module-based schema source (workspace + module name)
52
+ */
53
+ export interface PgpmWorkspaceSourceOptions {
54
+ pgpmWorkspacePath: string;
55
+ pgpmModuleName: string;
56
+ schemas?: string[];
57
+ apiNames?: string[];
58
+ keepDb?: boolean;
59
+ }
60
+ export interface CreateSchemaSourceOptions {
61
+ /**
62
+ * GraphQL endpoint URL (for live introspection)
63
+ */
64
+ endpoint?: string;
65
+ /**
66
+ * Path to GraphQL schema file (.graphql)
67
+ */
68
+ schemaFile?: string;
69
+ /**
70
+ * Database configuration for direct database introspection or PGPM module
71
+ */
72
+ db?: DbConfig;
73
+ /**
74
+ * Optional authorization header for endpoint requests
75
+ */
76
+ authorization?: string;
77
+ /**
78
+ * Optional additional headers for endpoint requests
79
+ */
80
+ headers?: Record<string, string>;
81
+ /**
82
+ * Request timeout in milliseconds (for endpoint requests)
83
+ */
84
+ timeout?: number;
85
+ }
86
+ /**
87
+ * Detect which source mode is being used based on options
88
+ */
89
+ export type SourceMode = 'endpoint' | 'schemaFile' | 'database' | 'pgpm-module' | 'pgpm-workspace';
90
+ export declare function detectSourceMode(options: CreateSchemaSourceOptions): SourceMode | null;
91
+ /**
92
+ * Create a schema source based on configuration
93
+ *
94
+ * Supports five modes:
95
+ * - endpoint: Introspect from a live GraphQL endpoint
96
+ * - schemaFile: Load from a local .graphql file
97
+ * - database: Introspect directly from a PostgreSQL database
98
+ * - pgpm-module: Deploy a PGPM module to an ephemeral database and introspect
99
+ * - pgpm-workspace: Deploy a module from a PGPM workspace to an ephemeral database and introspect
100
+ *
101
+ * @param options - Source configuration
102
+ * @returns Appropriate SchemaSource implementation
103
+ * @throws Error if no valid source is provided
104
+ */
105
+ export declare function createSchemaSource(options: CreateSchemaSourceOptions): SchemaSource;
106
+ /**
107
+ * Validate that source options are valid (exactly one source specified)
108
+ */
109
+ export declare function validateSourceOptions(options: CreateSchemaSourceOptions): {
110
+ valid: boolean;
111
+ error?: string;
112
+ };
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.detectSourceMode = detectSourceMode;
18
+ exports.createSchemaSource = createSchemaSource;
19
+ exports.validateSourceOptions = validateSourceOptions;
20
+ /**
21
+ * Schema Source Module
22
+ *
23
+ * Provides a unified interface for loading GraphQL schemas from different sources:
24
+ * - Live GraphQL endpoints (via introspection)
25
+ * - Static .graphql schema files
26
+ * - PostgreSQL databases (via PostGraphile introspection)
27
+ * - PGPM modules (via ephemeral database deployment)
28
+ */
29
+ __exportStar(require("./types"), exports);
30
+ __exportStar(require("./endpoint"), exports);
31
+ __exportStar(require("./file"), exports);
32
+ __exportStar(require("./database"), exports);
33
+ __exportStar(require("./pgpm-module"), exports);
34
+ __exportStar(require("./api-schemas"), exports);
35
+ const endpoint_1 = require("./endpoint");
36
+ const file_1 = require("./file");
37
+ const database_1 = require("./database");
38
+ const pgpm_module_1 = require("./pgpm-module");
39
+ function detectSourceMode(options) {
40
+ if (options.endpoint)
41
+ return 'endpoint';
42
+ if (options.schemaFile)
43
+ return 'schemaFile';
44
+ if (options.db) {
45
+ // Check for PGPM modes first
46
+ if (options.db.pgpm?.modulePath)
47
+ return 'pgpm-module';
48
+ if (options.db.pgpm?.workspacePath && options.db.pgpm?.moduleName)
49
+ return 'pgpm-workspace';
50
+ // Default to database mode if db is specified without pgpm
51
+ return 'database';
52
+ }
53
+ return null;
54
+ }
55
+ /**
56
+ * Create a schema source based on configuration
57
+ *
58
+ * Supports five modes:
59
+ * - endpoint: Introspect from a live GraphQL endpoint
60
+ * - schemaFile: Load from a local .graphql file
61
+ * - database: Introspect directly from a PostgreSQL database
62
+ * - pgpm-module: Deploy a PGPM module to an ephemeral database and introspect
63
+ * - pgpm-workspace: Deploy a module from a PGPM workspace to an ephemeral database and introspect
64
+ *
65
+ * @param options - Source configuration
66
+ * @returns Appropriate SchemaSource implementation
67
+ * @throws Error if no valid source is provided
68
+ */
69
+ function createSchemaSource(options) {
70
+ const mode = detectSourceMode(options);
71
+ switch (mode) {
72
+ case 'schemaFile':
73
+ return new file_1.FileSchemaSource({
74
+ schemaPath: options.schemaFile,
75
+ });
76
+ case 'endpoint':
77
+ return new endpoint_1.EndpointSchemaSource({
78
+ endpoint: options.endpoint,
79
+ authorization: options.authorization,
80
+ headers: options.headers,
81
+ timeout: options.timeout,
82
+ });
83
+ case 'database':
84
+ // Database mode uses db.config for connection (falls back to env vars)
85
+ // and db.schemas or db.apiNames for schema selection
86
+ return new database_1.DatabaseSchemaSource({
87
+ database: options.db?.config?.database ?? '',
88
+ schemas: options.db?.schemas,
89
+ apiNames: options.db?.apiNames,
90
+ });
91
+ case 'pgpm-module':
92
+ return new pgpm_module_1.PgpmModuleSchemaSource({
93
+ pgpmModulePath: options.db.pgpm.modulePath,
94
+ schemas: options.db?.schemas,
95
+ apiNames: options.db?.apiNames,
96
+ keepDb: options.db?.keepDb,
97
+ });
98
+ case 'pgpm-workspace':
99
+ return new pgpm_module_1.PgpmModuleSchemaSource({
100
+ pgpmWorkspacePath: options.db.pgpm.workspacePath,
101
+ pgpmModuleName: options.db.pgpm.moduleName,
102
+ schemas: options.db?.schemas,
103
+ apiNames: options.db?.apiNames,
104
+ keepDb: options.db?.keepDb,
105
+ });
106
+ default:
107
+ throw new Error('No source specified. Use one of: endpoint, schemaFile, or db (with optional pgpm for module deployment).');
108
+ }
109
+ }
110
+ /**
111
+ * Validate that source options are valid (exactly one source specified)
112
+ */
113
+ function validateSourceOptions(options) {
114
+ // Count primary sources
115
+ const sources = [
116
+ options.endpoint,
117
+ options.schemaFile,
118
+ options.db,
119
+ ].filter(Boolean);
120
+ if (sources.length === 0) {
121
+ return {
122
+ valid: false,
123
+ error: 'No source specified. Use one of: endpoint, schemaFile, or db.',
124
+ };
125
+ }
126
+ if (sources.length > 1) {
127
+ return {
128
+ valid: false,
129
+ error: 'Multiple sources specified. Use only one of: endpoint, schemaFile, or db.',
130
+ };
131
+ }
132
+ // Validate pgpm workspace mode has both required fields
133
+ if (options.db?.pgpm) {
134
+ const pgpm = options.db.pgpm;
135
+ if (pgpm.workspacePath && !pgpm.moduleName) {
136
+ return {
137
+ valid: false,
138
+ error: 'db.pgpm.workspacePath requires db.pgpm.moduleName to be specified.',
139
+ };
140
+ }
141
+ if (pgpm.moduleName && !pgpm.workspacePath) {
142
+ return {
143
+ valid: false,
144
+ error: 'db.pgpm.moduleName requires db.pgpm.workspacePath to be specified.',
145
+ };
146
+ }
147
+ // Must have either modulePath or workspacePath+moduleName
148
+ if (!pgpm.modulePath && !(pgpm.workspacePath && pgpm.moduleName)) {
149
+ return {
150
+ valid: false,
151
+ error: 'db.pgpm requires either modulePath or both workspacePath and moduleName.',
152
+ };
153
+ }
154
+ }
155
+ // For database mode, validate schemas/apiNames mutual exclusivity
156
+ if (options.db) {
157
+ const hasSchemas = options.db.schemas && options.db.schemas.length > 0;
158
+ const hasApiNames = options.db.apiNames && options.db.apiNames.length > 0;
159
+ if (hasSchemas && hasApiNames) {
160
+ return {
161
+ valid: false,
162
+ error: 'Cannot specify both db.schemas and db.apiNames. Use one or the other.',
163
+ };
164
+ }
165
+ if (!hasSchemas && !hasApiNames) {
166
+ return {
167
+ valid: false,
168
+ error: 'Must specify either db.schemas or db.apiNames for database mode.',
169
+ };
170
+ }
171
+ }
172
+ return { valid: true };
173
+ }