@constructive-io/graphql-codegen 2.19.0 → 2.20.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 (301) hide show
  1. package/README.md +1818 -113
  2. package/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  3. package/__tests__/codegen/input-types-generator.test.js +635 -0
  4. package/cli/codegen/barrel.d.ts +27 -0
  5. package/cli/codegen/barrel.js +163 -0
  6. package/cli/codegen/client.d.ts +4 -0
  7. package/cli/codegen/client.js +170 -0
  8. package/cli/codegen/custom-mutations.d.ts +38 -0
  9. package/cli/codegen/custom-mutations.js +149 -0
  10. package/cli/codegen/custom-queries.d.ts +38 -0
  11. package/cli/codegen/custom-queries.js +358 -0
  12. package/cli/codegen/filters.d.ts +27 -0
  13. package/cli/codegen/filters.js +357 -0
  14. package/cli/codegen/gql-ast.d.ts +41 -0
  15. package/cli/codegen/gql-ast.js +329 -0
  16. package/cli/codegen/index.d.ts +71 -0
  17. package/cli/codegen/index.js +147 -0
  18. package/cli/codegen/mutations.d.ts +30 -0
  19. package/cli/codegen/mutations.js +410 -0
  20. package/cli/codegen/orm/barrel.d.ts +18 -0
  21. package/cli/codegen/orm/barrel.js +48 -0
  22. package/cli/codegen/orm/client-generator.d.ts +45 -0
  23. package/cli/codegen/orm/client-generator.js +646 -0
  24. package/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  25. package/cli/codegen/orm/custom-ops-generator.js +350 -0
  26. package/cli/codegen/orm/index.d.ts +38 -0
  27. package/cli/codegen/orm/index.js +88 -0
  28. package/cli/codegen/orm/input-types-generator.d.ts +21 -0
  29. package/cli/codegen/orm/input-types-generator.js +705 -0
  30. package/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  31. package/cli/codegen/orm/input-types-generator.test.js +75 -0
  32. package/cli/codegen/orm/model-generator.d.ts +32 -0
  33. package/cli/codegen/orm/model-generator.js +264 -0
  34. package/cli/codegen/orm/query-builder.d.ts +161 -0
  35. package/cli/codegen/orm/query-builder.js +366 -0
  36. package/cli/codegen/orm/select-types.d.ts +169 -0
  37. package/cli/codegen/orm/select-types.js +16 -0
  38. package/cli/codegen/orm/select-types.test.d.ts +11 -0
  39. package/cli/codegen/orm/select-types.test.js +22 -0
  40. package/cli/codegen/queries.d.ts +25 -0
  41. package/cli/codegen/queries.js +438 -0
  42. package/cli/codegen/scalars.d.ts +12 -0
  43. package/cli/codegen/scalars.js +71 -0
  44. package/cli/codegen/schema-gql-ast.d.ts +51 -0
  45. package/cli/codegen/schema-gql-ast.js +385 -0
  46. package/cli/codegen/ts-ast.d.ts +122 -0
  47. package/cli/codegen/ts-ast.js +280 -0
  48. package/cli/codegen/type-resolver.d.ts +96 -0
  49. package/cli/codegen/type-resolver.js +246 -0
  50. package/cli/codegen/types.d.ts +12 -0
  51. package/cli/codegen/types.js +69 -0
  52. package/cli/codegen/utils.d.ts +163 -0
  53. package/cli/codegen/utils.js +326 -0
  54. package/cli/commands/generate-orm.d.ts +37 -0
  55. package/cli/commands/generate-orm.js +195 -0
  56. package/cli/commands/generate.d.ts +39 -0
  57. package/cli/commands/generate.js +299 -0
  58. package/cli/commands/index.d.ts +7 -0
  59. package/cli/commands/index.js +12 -0
  60. package/cli/commands/init.d.ts +35 -0
  61. package/cli/commands/init.js +176 -0
  62. package/cli/index.d.ts +4 -0
  63. package/cli/index.js +291 -0
  64. package/cli/introspect/fetch-meta.d.ts +31 -0
  65. package/cli/introspect/fetch-meta.js +108 -0
  66. package/cli/introspect/fetch-schema.d.ts +21 -0
  67. package/cli/introspect/fetch-schema.js +86 -0
  68. package/cli/introspect/index.d.ts +8 -0
  69. package/cli/introspect/index.js +16 -0
  70. package/cli/introspect/meta-query.d.ts +111 -0
  71. package/cli/introspect/meta-query.js +191 -0
  72. package/cli/introspect/schema-query.d.ts +20 -0
  73. package/cli/introspect/schema-query.js +123 -0
  74. package/cli/introspect/transform-schema.d.ts +74 -0
  75. package/cli/introspect/transform-schema.js +269 -0
  76. package/cli/introspect/transform-schema.test.d.ts +1 -0
  77. package/cli/introspect/transform-schema.test.js +67 -0
  78. package/cli/introspect/transform.d.ts +21 -0
  79. package/cli/introspect/transform.js +216 -0
  80. package/cli/watch/cache.d.ts +45 -0
  81. package/cli/watch/cache.js +111 -0
  82. package/cli/watch/debounce.d.ts +19 -0
  83. package/cli/watch/debounce.js +89 -0
  84. package/cli/watch/hash.d.ts +17 -0
  85. package/cli/watch/hash.js +48 -0
  86. package/cli/watch/index.d.ts +10 -0
  87. package/cli/watch/index.js +22 -0
  88. package/cli/watch/orchestrator.d.ts +63 -0
  89. package/cli/watch/orchestrator.js +228 -0
  90. package/cli/watch/poller.d.ts +65 -0
  91. package/cli/watch/poller.js +203 -0
  92. package/cli/watch/types.d.ts +67 -0
  93. package/cli/watch/types.js +5 -0
  94. package/client/error.d.ts +95 -0
  95. package/client/error.js +255 -0
  96. package/client/execute.d.ts +57 -0
  97. package/client/execute.js +124 -0
  98. package/client/index.d.ts +6 -0
  99. package/client/index.js +18 -0
  100. package/client/typed-document.d.ts +31 -0
  101. package/client/typed-document.js +44 -0
  102. package/core/ast.d.ts +10 -0
  103. package/core/ast.js +593 -0
  104. package/core/custom-ast.d.ts +35 -0
  105. package/core/custom-ast.js +204 -0
  106. package/core/index.d.ts +8 -0
  107. package/core/index.js +33 -0
  108. package/core/meta-object/convert.d.ts +65 -0
  109. package/core/meta-object/convert.js +63 -0
  110. package/core/meta-object/format.json +93 -0
  111. package/core/meta-object/index.d.ts +2 -0
  112. package/core/meta-object/index.js +18 -0
  113. package/core/meta-object/validate.d.ts +9 -0
  114. package/core/meta-object/validate.js +34 -0
  115. package/core/query-builder.d.ts +46 -0
  116. package/core/query-builder.js +412 -0
  117. package/core/types.d.ts +139 -0
  118. package/core/types.js +28 -0
  119. package/esm/__tests__/codegen/input-types-generator.test.d.ts +1 -0
  120. package/esm/__tests__/codegen/input-types-generator.test.js +633 -0
  121. package/esm/cli/codegen/barrel.d.ts +27 -0
  122. package/esm/cli/codegen/barrel.js +156 -0
  123. package/esm/cli/codegen/client.d.ts +4 -0
  124. package/esm/cli/codegen/client.js +167 -0
  125. package/esm/cli/codegen/custom-mutations.d.ts +38 -0
  126. package/esm/cli/codegen/custom-mutations.js +145 -0
  127. package/esm/cli/codegen/custom-queries.d.ts +38 -0
  128. package/esm/cli/codegen/custom-queries.js +354 -0
  129. package/esm/cli/codegen/filters.d.ts +27 -0
  130. package/esm/cli/codegen/filters.js +351 -0
  131. package/esm/cli/codegen/gql-ast.d.ts +41 -0
  132. package/esm/cli/codegen/gql-ast.js +288 -0
  133. package/esm/cli/codegen/index.d.ts +71 -0
  134. package/esm/cli/codegen/index.js +124 -0
  135. package/esm/cli/codegen/mutations.d.ts +30 -0
  136. package/esm/cli/codegen/mutations.js +404 -0
  137. package/esm/cli/codegen/orm/barrel.d.ts +18 -0
  138. package/esm/cli/codegen/orm/barrel.js +44 -0
  139. package/esm/cli/codegen/orm/client-generator.d.ts +45 -0
  140. package/esm/cli/codegen/orm/client-generator.js +640 -0
  141. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +30 -0
  142. package/esm/cli/codegen/orm/custom-ops-generator.js +346 -0
  143. package/esm/cli/codegen/orm/index.d.ts +38 -0
  144. package/esm/cli/codegen/orm/index.js +75 -0
  145. package/esm/cli/codegen/orm/input-types-generator.d.ts +21 -0
  146. package/esm/cli/codegen/orm/input-types-generator.js +700 -0
  147. package/esm/cli/codegen/orm/input-types-generator.test.d.ts +1 -0
  148. package/esm/cli/codegen/orm/input-types-generator.test.js +73 -0
  149. package/esm/cli/codegen/orm/model-generator.d.ts +32 -0
  150. package/esm/cli/codegen/orm/model-generator.js +260 -0
  151. package/esm/cli/codegen/orm/query-builder.d.ts +161 -0
  152. package/esm/cli/codegen/orm/query-builder.js +353 -0
  153. package/esm/cli/codegen/orm/select-types.d.ts +169 -0
  154. package/esm/cli/codegen/orm/select-types.js +15 -0
  155. package/esm/cli/codegen/orm/select-types.test.d.ts +11 -0
  156. package/esm/cli/codegen/orm/select-types.test.js +21 -0
  157. package/esm/cli/codegen/queries.d.ts +25 -0
  158. package/esm/cli/codegen/queries.js +433 -0
  159. package/esm/cli/codegen/scalars.d.ts +12 -0
  160. package/esm/cli/codegen/scalars.js +66 -0
  161. package/esm/cli/codegen/schema-gql-ast.d.ts +51 -0
  162. package/esm/cli/codegen/schema-gql-ast.js +343 -0
  163. package/esm/cli/codegen/ts-ast.d.ts +122 -0
  164. package/esm/cli/codegen/ts-ast.js +260 -0
  165. package/esm/cli/codegen/type-resolver.d.ts +96 -0
  166. package/esm/cli/codegen/type-resolver.js +224 -0
  167. package/esm/cli/codegen/types.d.ts +12 -0
  168. package/esm/cli/codegen/types.js +65 -0
  169. package/esm/cli/codegen/utils.d.ts +163 -0
  170. package/esm/cli/codegen/utils.js +288 -0
  171. package/esm/cli/commands/generate-orm.d.ts +37 -0
  172. package/esm/cli/commands/generate-orm.js +192 -0
  173. package/esm/cli/commands/generate.d.ts +39 -0
  174. package/esm/cli/commands/generate.js +262 -0
  175. package/esm/cli/commands/index.d.ts +7 -0
  176. package/esm/cli/commands/index.js +5 -0
  177. package/esm/cli/commands/init.d.ts +35 -0
  178. package/esm/cli/commands/init.js +138 -0
  179. package/esm/cli/index.d.ts +4 -0
  180. package/esm/cli/index.js +256 -0
  181. package/esm/cli/introspect/fetch-meta.d.ts +31 -0
  182. package/esm/cli/introspect/fetch-meta.js +104 -0
  183. package/esm/cli/introspect/fetch-schema.d.ts +21 -0
  184. package/esm/cli/introspect/fetch-schema.js +83 -0
  185. package/esm/cli/introspect/index.d.ts +8 -0
  186. package/esm/cli/introspect/index.js +6 -0
  187. package/esm/cli/introspect/meta-query.d.ts +111 -0
  188. package/esm/cli/introspect/meta-query.js +188 -0
  189. package/esm/cli/introspect/schema-query.d.ts +20 -0
  190. package/esm/cli/introspect/schema-query.js +120 -0
  191. package/esm/cli/introspect/transform-schema.d.ts +74 -0
  192. package/esm/cli/introspect/transform-schema.js +259 -0
  193. package/esm/cli/introspect/transform-schema.test.d.ts +1 -0
  194. package/esm/cli/introspect/transform-schema.test.js +65 -0
  195. package/esm/cli/introspect/transform.d.ts +21 -0
  196. package/esm/cli/introspect/transform.js +210 -0
  197. package/esm/cli/watch/cache.d.ts +45 -0
  198. package/esm/cli/watch/cache.js +73 -0
  199. package/esm/cli/watch/debounce.d.ts +19 -0
  200. package/esm/cli/watch/debounce.js +85 -0
  201. package/esm/cli/watch/hash.d.ts +17 -0
  202. package/esm/cli/watch/hash.js +43 -0
  203. package/esm/cli/watch/index.d.ts +10 -0
  204. package/esm/cli/watch/index.js +8 -0
  205. package/esm/cli/watch/orchestrator.d.ts +63 -0
  206. package/esm/cli/watch/orchestrator.js +223 -0
  207. package/esm/cli/watch/poller.d.ts +65 -0
  208. package/esm/cli/watch/poller.js +198 -0
  209. package/esm/cli/watch/types.d.ts +67 -0
  210. package/esm/cli/watch/types.js +4 -0
  211. package/esm/client/error.d.ts +95 -0
  212. package/esm/client/error.js +249 -0
  213. package/esm/client/execute.d.ts +57 -0
  214. package/esm/client/execute.js +120 -0
  215. package/esm/client/index.d.ts +6 -0
  216. package/esm/client/index.js +6 -0
  217. package/esm/client/typed-document.d.ts +31 -0
  218. package/esm/client/typed-document.js +40 -0
  219. package/esm/core/ast.d.ts +10 -0
  220. package/esm/core/ast.js +549 -0
  221. package/esm/core/custom-ast.d.ts +35 -0
  222. package/esm/core/custom-ast.js +161 -0
  223. package/esm/core/index.d.ts +8 -0
  224. package/esm/core/index.js +12 -0
  225. package/esm/core/meta-object/convert.d.ts +65 -0
  226. package/esm/core/meta-object/convert.js +60 -0
  227. package/esm/core/meta-object/format.json +93 -0
  228. package/esm/core/meta-object/index.d.ts +2 -0
  229. package/esm/core/meta-object/index.js +2 -0
  230. package/esm/core/meta-object/validate.d.ts +9 -0
  231. package/esm/core/meta-object/validate.js +28 -0
  232. package/esm/core/query-builder.d.ts +46 -0
  233. package/esm/core/query-builder.js +375 -0
  234. package/esm/core/types.d.ts +139 -0
  235. package/esm/core/types.js +24 -0
  236. package/esm/generators/field-selector.d.ts +30 -0
  237. package/esm/generators/field-selector.js +355 -0
  238. package/esm/generators/index.d.ts +6 -0
  239. package/esm/generators/index.js +9 -0
  240. package/esm/generators/mutations.d.ts +31 -0
  241. package/esm/generators/mutations.js +197 -0
  242. package/esm/generators/select.d.ts +50 -0
  243. package/esm/generators/select.js +636 -0
  244. package/esm/index.d.ts +12 -0
  245. package/esm/index.js +17 -3
  246. package/esm/react/index.d.ts +5 -0
  247. package/esm/react/index.js +6 -0
  248. package/esm/types/config.d.ts +199 -0
  249. package/esm/types/config.js +106 -0
  250. package/esm/types/index.d.ts +9 -0
  251. package/esm/types/index.js +4 -0
  252. package/esm/types/introspection.d.ts +121 -0
  253. package/esm/types/introspection.js +54 -0
  254. package/esm/types/mutation.d.ts +45 -0
  255. package/esm/types/mutation.js +4 -0
  256. package/esm/types/query.d.ts +82 -0
  257. package/esm/types/query.js +4 -0
  258. package/esm/types/schema.d.ts +253 -0
  259. package/esm/types/schema.js +5 -0
  260. package/esm/types/selection.d.ts +43 -0
  261. package/esm/types/selection.js +4 -0
  262. package/esm/utils/index.d.ts +4 -0
  263. package/esm/utils/index.js +4 -0
  264. package/generators/field-selector.d.ts +30 -0
  265. package/generators/field-selector.js +361 -0
  266. package/generators/index.d.ts +6 -0
  267. package/generators/index.js +27 -0
  268. package/generators/mutations.d.ts +31 -0
  269. package/generators/mutations.js +235 -0
  270. package/generators/select.d.ts +50 -0
  271. package/generators/select.js +679 -0
  272. package/index.d.ts +12 -3
  273. package/index.js +19 -3
  274. package/package.json +59 -38
  275. package/react/index.d.ts +5 -0
  276. package/react/index.js +9 -0
  277. package/types/config.d.ts +199 -0
  278. package/types/config.js +111 -0
  279. package/types/index.d.ts +9 -0
  280. package/types/index.js +10 -0
  281. package/types/introspection.d.ts +121 -0
  282. package/types/introspection.js +62 -0
  283. package/types/mutation.d.ts +45 -0
  284. package/types/mutation.js +5 -0
  285. package/types/query.d.ts +82 -0
  286. package/types/query.js +5 -0
  287. package/types/schema.d.ts +253 -0
  288. package/types/schema.js +6 -0
  289. package/types/selection.d.ts +43 -0
  290. package/types/selection.js +5 -0
  291. package/utils/index.d.ts +4 -0
  292. package/utils/index.js +7 -0
  293. package/codegen.d.ts +0 -13
  294. package/codegen.js +0 -293
  295. package/esm/codegen.js +0 -253
  296. package/esm/gql.js +0 -939
  297. package/esm/options.js +0 -27
  298. package/gql.d.ts +0 -188
  299. package/gql.js +0 -992
  300. package/options.d.ts +0 -45
  301. package/options.js +0 -31
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Error handling for GraphQL operations
3
+ * Provides consistent error types and parsing for PostGraphile responses
4
+ */
5
+ // ============================================================================
6
+ // Error Types
7
+ // ============================================================================
8
+ export const DataErrorType = {
9
+ // Network/Connection errors
10
+ NETWORK_ERROR: 'NETWORK_ERROR',
11
+ TIMEOUT_ERROR: 'TIMEOUT_ERROR',
12
+ // Validation errors
13
+ VALIDATION_FAILED: 'VALIDATION_FAILED',
14
+ REQUIRED_FIELD_MISSING: 'REQUIRED_FIELD_MISSING',
15
+ INVALID_MUTATION_DATA: 'INVALID_MUTATION_DATA',
16
+ // Query errors
17
+ QUERY_GENERATION_FAILED: 'QUERY_GENERATION_FAILED',
18
+ QUERY_EXECUTION_FAILED: 'QUERY_EXECUTION_FAILED',
19
+ // Permission errors
20
+ UNAUTHORIZED: 'UNAUTHORIZED',
21
+ FORBIDDEN: 'FORBIDDEN',
22
+ // Schema errors
23
+ TABLE_NOT_FOUND: 'TABLE_NOT_FOUND',
24
+ // Request errors
25
+ BAD_REQUEST: 'BAD_REQUEST',
26
+ NOT_FOUND: 'NOT_FOUND',
27
+ // GraphQL-specific errors
28
+ GRAPHQL_ERROR: 'GRAPHQL_ERROR',
29
+ // PostgreSQL constraint errors (surfaced via PostGraphile)
30
+ UNIQUE_VIOLATION: 'UNIQUE_VIOLATION',
31
+ FOREIGN_KEY_VIOLATION: 'FOREIGN_KEY_VIOLATION',
32
+ NOT_NULL_VIOLATION: 'NOT_NULL_VIOLATION',
33
+ CHECK_VIOLATION: 'CHECK_VIOLATION',
34
+ EXCLUSION_VIOLATION: 'EXCLUSION_VIOLATION',
35
+ // Generic errors
36
+ UNKNOWN_ERROR: 'UNKNOWN_ERROR',
37
+ };
38
+ /**
39
+ * Standard error class for data layer operations
40
+ */
41
+ export class DataError extends Error {
42
+ type;
43
+ code;
44
+ originalError;
45
+ context;
46
+ tableName;
47
+ fieldName;
48
+ constraint;
49
+ constructor(type, message, options = {}) {
50
+ super(message);
51
+ this.name = 'DataError';
52
+ this.type = type;
53
+ this.code = options.code;
54
+ this.originalError = options.originalError;
55
+ this.context = options.context;
56
+ this.tableName = options.tableName;
57
+ this.fieldName = options.fieldName;
58
+ this.constraint = options.constraint;
59
+ if (Error.captureStackTrace) {
60
+ Error.captureStackTrace(this, DataError);
61
+ }
62
+ }
63
+ getUserMessage() {
64
+ switch (this.type) {
65
+ case DataErrorType.NETWORK_ERROR:
66
+ return 'Network error. Please check your connection and try again.';
67
+ case DataErrorType.TIMEOUT_ERROR:
68
+ return 'Request timed out. Please try again.';
69
+ case DataErrorType.UNAUTHORIZED:
70
+ return 'You are not authorized. Please log in and try again.';
71
+ case DataErrorType.FORBIDDEN:
72
+ return 'You do not have permission to access this resource.';
73
+ case DataErrorType.VALIDATION_FAILED:
74
+ return 'Validation failed. Please check your input and try again.';
75
+ case DataErrorType.REQUIRED_FIELD_MISSING:
76
+ return this.fieldName
77
+ ? `The field "${this.fieldName}" is required.`
78
+ : 'A required field is missing.';
79
+ case DataErrorType.UNIQUE_VIOLATION:
80
+ return this.fieldName
81
+ ? `A record with this ${this.fieldName} already exists.`
82
+ : 'A record with this value already exists.';
83
+ case DataErrorType.FOREIGN_KEY_VIOLATION:
84
+ return 'This record references a record that does not exist.';
85
+ case DataErrorType.NOT_NULL_VIOLATION:
86
+ return this.fieldName
87
+ ? `The field "${this.fieldName}" cannot be empty.`
88
+ : 'A required field cannot be empty.';
89
+ case DataErrorType.CHECK_VIOLATION:
90
+ return this.fieldName
91
+ ? `The value for "${this.fieldName}" is not valid.`
92
+ : 'The value does not meet the required constraints.';
93
+ default:
94
+ return this.message || 'An unexpected error occurred.';
95
+ }
96
+ }
97
+ isRetryable() {
98
+ return (this.type === DataErrorType.NETWORK_ERROR ||
99
+ this.type === DataErrorType.TIMEOUT_ERROR);
100
+ }
101
+ }
102
+ // ============================================================================
103
+ // PostgreSQL Error Codes
104
+ // ============================================================================
105
+ export const PG_ERROR_CODES = {
106
+ UNIQUE_VIOLATION: '23505',
107
+ FOREIGN_KEY_VIOLATION: '23503',
108
+ NOT_NULL_VIOLATION: '23502',
109
+ CHECK_VIOLATION: '23514',
110
+ EXCLUSION_VIOLATION: '23P01',
111
+ NUMERIC_VALUE_OUT_OF_RANGE: '22003',
112
+ STRING_DATA_RIGHT_TRUNCATION: '22001',
113
+ INVALID_TEXT_REPRESENTATION: '22P02',
114
+ DATETIME_FIELD_OVERFLOW: '22008',
115
+ UNDEFINED_TABLE: '42P01',
116
+ UNDEFINED_COLUMN: '42703',
117
+ INSUFFICIENT_PRIVILEGE: '42501',
118
+ };
119
+ // ============================================================================
120
+ // Error Factory
121
+ // ============================================================================
122
+ export const createError = {
123
+ network: (originalError) => new DataError(DataErrorType.NETWORK_ERROR, 'Network error occurred', { originalError }),
124
+ timeout: (originalError) => new DataError(DataErrorType.TIMEOUT_ERROR, 'Request timed out', { originalError }),
125
+ unauthorized: (message = 'Authentication required') => new DataError(DataErrorType.UNAUTHORIZED, message),
126
+ forbidden: (message = 'Access forbidden') => new DataError(DataErrorType.FORBIDDEN, message),
127
+ badRequest: (message, code) => new DataError(DataErrorType.BAD_REQUEST, message, { code }),
128
+ notFound: (message = 'Resource not found') => new DataError(DataErrorType.NOT_FOUND, message),
129
+ graphql: (message, code) => new DataError(DataErrorType.GRAPHQL_ERROR, message, { code }),
130
+ uniqueViolation: (message, fieldName, constraint) => new DataError(DataErrorType.UNIQUE_VIOLATION, message, { fieldName, constraint, code: '23505' }),
131
+ foreignKeyViolation: (message, fieldName, constraint) => new DataError(DataErrorType.FOREIGN_KEY_VIOLATION, message, { fieldName, constraint, code: '23503' }),
132
+ notNullViolation: (message, fieldName, constraint) => new DataError(DataErrorType.NOT_NULL_VIOLATION, message, { fieldName, constraint, code: '23502' }),
133
+ unknown: (originalError) => new DataError(DataErrorType.UNKNOWN_ERROR, originalError.message, { originalError }),
134
+ };
135
+ function parseGraphQLErrorCode(code) {
136
+ if (!code)
137
+ return DataErrorType.UNKNOWN_ERROR;
138
+ const normalized = code.toUpperCase();
139
+ // GraphQL standard codes
140
+ if (normalized === 'UNAUTHENTICATED')
141
+ return DataErrorType.UNAUTHORIZED;
142
+ if (normalized === 'FORBIDDEN')
143
+ return DataErrorType.FORBIDDEN;
144
+ if (normalized === 'GRAPHQL_VALIDATION_FAILED')
145
+ return DataErrorType.QUERY_GENERATION_FAILED;
146
+ // PostgreSQL SQLSTATE codes
147
+ if (code === PG_ERROR_CODES.UNIQUE_VIOLATION)
148
+ return DataErrorType.UNIQUE_VIOLATION;
149
+ if (code === PG_ERROR_CODES.FOREIGN_KEY_VIOLATION)
150
+ return DataErrorType.FOREIGN_KEY_VIOLATION;
151
+ if (code === PG_ERROR_CODES.NOT_NULL_VIOLATION)
152
+ return DataErrorType.NOT_NULL_VIOLATION;
153
+ if (code === PG_ERROR_CODES.CHECK_VIOLATION)
154
+ return DataErrorType.CHECK_VIOLATION;
155
+ if (code === PG_ERROR_CODES.EXCLUSION_VIOLATION)
156
+ return DataErrorType.EXCLUSION_VIOLATION;
157
+ return DataErrorType.UNKNOWN_ERROR;
158
+ }
159
+ function classifyByMessage(message) {
160
+ const lower = message.toLowerCase();
161
+ if (lower.includes('timeout') || lower.includes('timed out')) {
162
+ return DataErrorType.TIMEOUT_ERROR;
163
+ }
164
+ if (lower.includes('network') || lower.includes('fetch') || lower.includes('failed to fetch')) {
165
+ return DataErrorType.NETWORK_ERROR;
166
+ }
167
+ if (lower.includes('unauthorized') || lower.includes('authentication required')) {
168
+ return DataErrorType.UNAUTHORIZED;
169
+ }
170
+ if (lower.includes('forbidden') || lower.includes('permission')) {
171
+ return DataErrorType.FORBIDDEN;
172
+ }
173
+ if (lower.includes('duplicate key') || lower.includes('already exists')) {
174
+ return DataErrorType.UNIQUE_VIOLATION;
175
+ }
176
+ if (lower.includes('foreign key constraint')) {
177
+ return DataErrorType.FOREIGN_KEY_VIOLATION;
178
+ }
179
+ if (lower.includes('not-null constraint') || lower.includes('null value in column')) {
180
+ return DataErrorType.NOT_NULL_VIOLATION;
181
+ }
182
+ return DataErrorType.UNKNOWN_ERROR;
183
+ }
184
+ function extractFieldFromError(message, constraint, column) {
185
+ if (column)
186
+ return column;
187
+ const columnMatch = message.match(/column\s+"?([a-z_][a-z0-9_]*)"?/i);
188
+ if (columnMatch)
189
+ return columnMatch[1];
190
+ if (constraint) {
191
+ const constraintMatch = constraint.match(/_([a-z_][a-z0-9_]*)_(?:key|fkey|check|pkey)$/i);
192
+ if (constraintMatch)
193
+ return constraintMatch[1];
194
+ }
195
+ const keyMatch = message.match(/Key\s+\(([a-z_][a-z0-9_]*)\)/i);
196
+ if (keyMatch)
197
+ return keyMatch[1];
198
+ return undefined;
199
+ }
200
+ /**
201
+ * Parse any error into a DataError
202
+ */
203
+ export function parseGraphQLError(error) {
204
+ if (error instanceof DataError) {
205
+ return error;
206
+ }
207
+ // GraphQL error object
208
+ if (error &&
209
+ typeof error === 'object' &&
210
+ 'message' in error &&
211
+ typeof error.message === 'string') {
212
+ const gqlError = error;
213
+ const extCode = gqlError.extensions?.code;
214
+ const mappedType = parseGraphQLErrorCode(extCode);
215
+ const column = gqlError.extensions?.column;
216
+ const constraint = gqlError.extensions?.constraint;
217
+ const fieldName = extractFieldFromError(gqlError.message, constraint, column);
218
+ if (mappedType !== DataErrorType.UNKNOWN_ERROR) {
219
+ return new DataError(mappedType, gqlError.message, {
220
+ code: extCode,
221
+ fieldName,
222
+ constraint,
223
+ context: gqlError.extensions,
224
+ });
225
+ }
226
+ // Fallback: classify by message
227
+ const fallbackType = classifyByMessage(gqlError.message);
228
+ return new DataError(fallbackType, gqlError.message, {
229
+ code: extCode,
230
+ fieldName,
231
+ constraint,
232
+ context: gqlError.extensions,
233
+ });
234
+ }
235
+ // Standard Error
236
+ if (error instanceof Error) {
237
+ const type = classifyByMessage(error.message);
238
+ return new DataError(type, error.message, { originalError: error });
239
+ }
240
+ // Unknown
241
+ const message = typeof error === 'string' ? error : 'Unknown error occurred';
242
+ return new DataError(DataErrorType.UNKNOWN_ERROR, message);
243
+ }
244
+ /**
245
+ * Check if value is a DataError
246
+ */
247
+ export function isDataError(error) {
248
+ return error instanceof DataError;
249
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * GraphQL execution utilities
3
+ */
4
+ import type { DocumentNode } from 'graphql';
5
+ import { TypedDocumentString } from './typed-document';
6
+ type ExecutableDocument = TypedDocumentString<unknown, unknown> | DocumentNode | string;
7
+ type ResultOf<TDocument> = TDocument extends TypedDocumentString<infer TResult, unknown> ? TResult : unknown;
8
+ type VariablesOf<TDocument> = TDocument extends TypedDocumentString<unknown, infer TVariables> ? TVariables : Record<string, unknown>;
9
+ export interface ExecuteOptions {
10
+ /** Custom headers to include */
11
+ headers?: Record<string, string>;
12
+ /** Request timeout in milliseconds */
13
+ timeout?: number;
14
+ /** Signal for request cancellation */
15
+ signal?: AbortSignal;
16
+ }
17
+ export interface GraphQLResponse<T = unknown> {
18
+ data?: T;
19
+ errors?: Array<{
20
+ message: string;
21
+ extensions?: {
22
+ code?: string;
23
+ } & Record<string, unknown>;
24
+ locations?: Array<{
25
+ line: number;
26
+ column: number;
27
+ }>;
28
+ path?: Array<string | number>;
29
+ }>;
30
+ }
31
+ /**
32
+ * Execute a GraphQL operation against an endpoint
33
+ */
34
+ export declare function execute<TDocument extends ExecutableDocument>(endpoint: string, document: TDocument, variables?: VariablesOf<TDocument>, options?: ExecuteOptions): Promise<ResultOf<TDocument>>;
35
+ export interface GraphQLClientOptions {
36
+ /** GraphQL endpoint URL */
37
+ endpoint: string;
38
+ /** Default headers to include with every request */
39
+ headers?: Record<string, string>;
40
+ /** Default timeout in milliseconds */
41
+ timeout?: number;
42
+ }
43
+ /**
44
+ * Create a GraphQL client instance
45
+ */
46
+ export declare function createGraphQLClient(options: GraphQLClientOptions): {
47
+ /**
48
+ * Execute a GraphQL operation
49
+ */
50
+ execute<TDocument extends ExecutableDocument>(document: TDocument, variables?: VariablesOf<TDocument>, options?: ExecuteOptions): Promise<ResultOf<TDocument>>;
51
+ /**
52
+ * Get the endpoint URL
53
+ */
54
+ getEndpoint(): string;
55
+ };
56
+ export type GraphQLClient = ReturnType<typeof createGraphQLClient>;
57
+ export {};
@@ -0,0 +1,120 @@
1
+ /**
2
+ * GraphQL execution utilities
3
+ */
4
+ import { print } from 'graphql';
5
+ import { TypedDocumentString } from './typed-document';
6
+ import { createError, parseGraphQLError } from './error';
7
+ // ============================================================================
8
+ // Helpers
9
+ // ============================================================================
10
+ function documentToString(document) {
11
+ if (typeof document === 'string')
12
+ return document;
13
+ if (document instanceof TypedDocumentString)
14
+ return document.toString();
15
+ // DocumentNode
16
+ if (document && typeof document === 'object' && 'kind' in document) {
17
+ return print(document);
18
+ }
19
+ throw createError.badRequest('Invalid GraphQL document');
20
+ }
21
+ // ============================================================================
22
+ // Execute Function
23
+ // ============================================================================
24
+ /**
25
+ * Execute a GraphQL operation against an endpoint
26
+ */
27
+ export async function execute(endpoint, document, variables, options = {}) {
28
+ const { headers = {}, timeout = 30000, signal } = options;
29
+ // Create timeout controller
30
+ const controller = new AbortController();
31
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
32
+ // Combine signals if provided
33
+ const combinedSignal = signal
34
+ ? AbortSignal.any([signal, controller.signal])
35
+ : controller.signal;
36
+ try {
37
+ const response = await fetch(endpoint, {
38
+ method: 'POST',
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ Accept: 'application/graphql-response+json, application/json',
42
+ ...headers,
43
+ },
44
+ body: JSON.stringify({
45
+ query: documentToString(document),
46
+ ...(variables !== undefined && { variables }),
47
+ }),
48
+ signal: combinedSignal,
49
+ });
50
+ clearTimeout(timeoutId);
51
+ if (!response.ok) {
52
+ throw await handleHttpError(response);
53
+ }
54
+ const result = await response.json();
55
+ if (result.errors?.length) {
56
+ throw parseGraphQLError(result.errors[0]);
57
+ }
58
+ return result.data;
59
+ }
60
+ catch (error) {
61
+ clearTimeout(timeoutId);
62
+ if (error instanceof Error && error.name === 'AbortError') {
63
+ throw createError.timeout();
64
+ }
65
+ if (error instanceof Error && error.message.includes('fetch')) {
66
+ throw createError.network(error);
67
+ }
68
+ throw parseGraphQLError(error);
69
+ }
70
+ }
71
+ async function handleHttpError(response) {
72
+ const { status, statusText } = response;
73
+ if (status === 401) {
74
+ return createError.unauthorized('Authentication required');
75
+ }
76
+ if (status === 403) {
77
+ return createError.forbidden('Access forbidden');
78
+ }
79
+ if (status === 404) {
80
+ return createError.notFound('GraphQL endpoint not found');
81
+ }
82
+ // Try to extract error from response body
83
+ try {
84
+ const body = await response.json();
85
+ if (body.errors?.length) {
86
+ return parseGraphQLError(body.errors[0]);
87
+ }
88
+ if (body.message) {
89
+ return createError.badRequest(body.message);
90
+ }
91
+ }
92
+ catch {
93
+ // Couldn't parse response
94
+ }
95
+ return createError.badRequest(`Request failed: ${status} ${statusText}`);
96
+ }
97
+ /**
98
+ * Create a GraphQL client instance
99
+ */
100
+ export function createGraphQLClient(options) {
101
+ const { endpoint, headers: defaultHeaders = {}, timeout: defaultTimeout = 30000 } = options;
102
+ return {
103
+ /**
104
+ * Execute a GraphQL operation
105
+ */
106
+ async execute(document, variables, options = {}) {
107
+ return execute(endpoint, document, variables, {
108
+ headers: { ...defaultHeaders, ...options.headers },
109
+ timeout: options.timeout ?? defaultTimeout,
110
+ signal: options.signal,
111
+ });
112
+ },
113
+ /**
114
+ * Get the endpoint URL
115
+ */
116
+ getEndpoint() {
117
+ return endpoint;
118
+ },
119
+ };
120
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Client exports
3
+ */
4
+ export { TypedDocumentString, type DocumentTypeDecoration } from './typed-document';
5
+ export { DataError, DataErrorType, createError, parseGraphQLError, isDataError, PG_ERROR_CODES, type DataErrorOptions, type GraphQLError, } from './error';
6
+ export { execute, createGraphQLClient, type ExecuteOptions, type GraphQLClientOptions, type GraphQLClient, type GraphQLResponse, } from './execute';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Client exports
3
+ */
4
+ export { TypedDocumentString } from './typed-document';
5
+ export { DataError, DataErrorType, createError, parseGraphQLError, isDataError, PG_ERROR_CODES, } from './error';
6
+ export { execute, createGraphQLClient, } from './execute';
@@ -0,0 +1,31 @@
1
+ /**
2
+ * TypedDocumentString - Type-safe wrapper for GraphQL documents
3
+ * Compatible with GraphQL codegen client preset
4
+ */
5
+ /**
6
+ * Document type decoration interface (from @graphql-typed-document-node/core)
7
+ */
8
+ export interface DocumentTypeDecoration<TResult, TVariables> {
9
+ /**
10
+ * This type is used to ensure that the variables you pass in to the query are assignable to Variables
11
+ * and that the Result is assignable to whatever you pass your result to.
12
+ */
13
+ __apiType?: (variables: TVariables) => TResult;
14
+ }
15
+ /**
16
+ * Enhanced TypedDocumentString with type inference capabilities
17
+ * Compatible with GraphQL codegen client preset
18
+ */
19
+ export declare class TypedDocumentString<TResult = unknown, TVariables = unknown> extends String implements DocumentTypeDecoration<TResult, TVariables> {
20
+ /** Same shape as the codegen implementation for structural typing */
21
+ __apiType?: (variables: TVariables) => TResult;
22
+ __meta__?: Record<string, unknown>;
23
+ private value;
24
+ constructor(value: string, meta?: Record<string, unknown>);
25
+ private generateHash;
26
+ toString(): string;
27
+ /**
28
+ * Get the hash for caching purposes
29
+ */
30
+ getHash(): string;
31
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * TypedDocumentString - Type-safe wrapper for GraphQL documents
3
+ * Compatible with GraphQL codegen client preset
4
+ */
5
+ /**
6
+ * Enhanced TypedDocumentString with type inference capabilities
7
+ * Compatible with GraphQL codegen client preset
8
+ */
9
+ export class TypedDocumentString extends String {
10
+ /** Same shape as the codegen implementation for structural typing */
11
+ __apiType;
12
+ __meta__;
13
+ value;
14
+ constructor(value, meta) {
15
+ super(value);
16
+ this.value = value;
17
+ this.__meta__ = {
18
+ hash: this.generateHash(value),
19
+ ...meta,
20
+ };
21
+ }
22
+ generateHash(value) {
23
+ let hash = 0;
24
+ for (let i = 0; i < value.length; i++) {
25
+ const char = value.charCodeAt(i);
26
+ hash = (hash << 5) - hash + char;
27
+ hash = hash & hash; // Convert to 32-bit integer
28
+ }
29
+ return Math.abs(hash).toString(36);
30
+ }
31
+ toString() {
32
+ return this.value;
33
+ }
34
+ /**
35
+ * Get the hash for caching purposes
36
+ */
37
+ getHash() {
38
+ return this.__meta__?.hash;
39
+ }
40
+ }
@@ -0,0 +1,10 @@
1
+ import type { DocumentNode, FieldNode } from 'graphql';
2
+ import type { ASTFunctionParams, QueryFieldSelection, MutationASTParams } from './types';
3
+ export declare const getAll: ({ queryName, operationName, selection, }: ASTFunctionParams) => DocumentNode;
4
+ export declare const getCount: ({ queryName, operationName, query, }: Omit<ASTFunctionParams, "selection">) => DocumentNode;
5
+ export declare const getMany: ({ builder, queryName, operationName, query, selection, }: ASTFunctionParams) => DocumentNode;
6
+ export declare const getOne: ({ queryName, operationName, query, selection, }: ASTFunctionParams) => DocumentNode;
7
+ export declare const createOne: ({ mutationName, operationName, mutation, selection, }: MutationASTParams) => DocumentNode;
8
+ export declare const patchOne: ({ mutationName, operationName, mutation, selection, }: MutationASTParams) => DocumentNode;
9
+ export declare const deleteOne: ({ mutationName, operationName, mutation, }: Omit<MutationASTParams, "selection">) => DocumentNode;
10
+ export declare function getSelections(selection?: QueryFieldSelection[]): FieldNode[];