@fragno-dev/db 0.1.14 → 0.1.15

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 (183) hide show
  1. package/.turbo/turbo-build.log +179 -139
  2. package/CHANGELOG.md +24 -0
  3. package/dist/adapters/adapters.d.ts +15 -1
  4. package/dist/adapters/adapters.d.ts.map +1 -1
  5. package/dist/adapters/adapters.js.map +1 -1
  6. package/dist/adapters/drizzle/drizzle-adapter.d.ts +3 -1
  7. package/dist/adapters/drizzle/drizzle-adapter.d.ts.map +1 -1
  8. package/dist/adapters/drizzle/drizzle-adapter.js +9 -2
  9. package/dist/adapters/drizzle/drizzle-adapter.js.map +1 -1
  10. package/dist/adapters/drizzle/drizzle-query.js +2 -2
  11. package/dist/adapters/drizzle/drizzle-query.js.map +1 -1
  12. package/dist/adapters/drizzle/drizzle-uow-compiler.js +27 -8
  13. package/dist/adapters/drizzle/drizzle-uow-compiler.js.map +1 -1
  14. package/dist/adapters/drizzle/drizzle-uow-decoder.js +22 -15
  15. package/dist/adapters/drizzle/drizzle-uow-decoder.js.map +1 -1
  16. package/dist/adapters/drizzle/drizzle-uow-executor.js +18 -7
  17. package/dist/adapters/drizzle/drizzle-uow-executor.js.map +1 -1
  18. package/dist/adapters/drizzle/generate.d.ts +4 -1
  19. package/dist/adapters/drizzle/generate.d.ts.map +1 -1
  20. package/dist/adapters/drizzle/generate.js +11 -18
  21. package/dist/adapters/drizzle/generate.js.map +1 -1
  22. package/dist/adapters/kysely/kysely-adapter.d.ts +3 -1
  23. package/dist/adapters/kysely/kysely-adapter.d.ts.map +1 -1
  24. package/dist/adapters/kysely/kysely-adapter.js +7 -1
  25. package/dist/adapters/kysely/kysely-adapter.js.map +1 -1
  26. package/dist/adapters/kysely/kysely-query-builder.js +1 -1
  27. package/dist/adapters/kysely/kysely-query-compiler.js +3 -2
  28. package/dist/adapters/kysely/kysely-query-compiler.js.map +1 -1
  29. package/dist/adapters/kysely/kysely-query.d.ts +1 -0
  30. package/dist/adapters/kysely/kysely-query.d.ts.map +1 -1
  31. package/dist/adapters/kysely/kysely-query.js +25 -18
  32. package/dist/adapters/kysely/kysely-query.js.map +1 -1
  33. package/dist/adapters/kysely/kysely-shared.d.ts +3 -0
  34. package/dist/adapters/kysely/kysely-shared.d.ts.map +1 -1
  35. package/dist/adapters/kysely/kysely-shared.js +16 -1
  36. package/dist/adapters/kysely/kysely-shared.js.map +1 -1
  37. package/dist/adapters/kysely/kysely-uow-compiler.js +34 -11
  38. package/dist/adapters/kysely/kysely-uow-compiler.js.map +1 -1
  39. package/dist/adapters/kysely/kysely-uow-executor.js +8 -4
  40. package/dist/adapters/kysely/kysely-uow-executor.js.map +1 -1
  41. package/dist/adapters/kysely/migration/execute-base.js +1 -1
  42. package/dist/adapters/kysely/migration/execute-base.js.map +1 -1
  43. package/dist/db-fragment-definition-builder.d.ts +152 -0
  44. package/dist/db-fragment-definition-builder.d.ts.map +1 -0
  45. package/dist/db-fragment-definition-builder.js +137 -0
  46. package/dist/db-fragment-definition-builder.js.map +1 -0
  47. package/dist/fragments/internal-fragment.d.ts +19 -0
  48. package/dist/fragments/internal-fragment.d.ts.map +1 -0
  49. package/dist/fragments/internal-fragment.js +39 -0
  50. package/dist/fragments/internal-fragment.js.map +1 -0
  51. package/dist/migration-engine/generation-engine.d.ts.map +1 -1
  52. package/dist/migration-engine/generation-engine.js +35 -15
  53. package/dist/migration-engine/generation-engine.js.map +1 -1
  54. package/dist/mod.d.ts +8 -20
  55. package/dist/mod.d.ts.map +1 -1
  56. package/dist/mod.js +7 -35
  57. package/dist/mod.js.map +1 -1
  58. package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js +165 -0
  59. package/dist/node_modules/.pnpm/rou3@0.7.8/node_modules/rou3/dist/index.js.map +1 -0
  60. package/dist/packages/fragno/dist/api/bind-services.js +20 -0
  61. package/dist/packages/fragno/dist/api/bind-services.js.map +1 -0
  62. package/dist/packages/fragno/dist/api/error.js +48 -0
  63. package/dist/packages/fragno/dist/api/error.js.map +1 -0
  64. package/dist/packages/fragno/dist/api/fragment-definition-builder.js +320 -0
  65. package/dist/packages/fragno/dist/api/fragment-definition-builder.js.map +1 -0
  66. package/dist/packages/fragno/dist/api/fragment-instantiator.js +487 -0
  67. package/dist/packages/fragno/dist/api/fragment-instantiator.js.map +1 -0
  68. package/dist/packages/fragno/dist/api/fragno-response.js +73 -0
  69. package/dist/packages/fragno/dist/api/fragno-response.js.map +1 -0
  70. package/dist/packages/fragno/dist/api/internal/response-stream.js +81 -0
  71. package/dist/packages/fragno/dist/api/internal/response-stream.js.map +1 -0
  72. package/dist/packages/fragno/dist/api/internal/route.js +10 -0
  73. package/dist/packages/fragno/dist/api/internal/route.js.map +1 -0
  74. package/dist/packages/fragno/dist/api/mutable-request-state.js +97 -0
  75. package/dist/packages/fragno/dist/api/mutable-request-state.js.map +1 -0
  76. package/dist/packages/fragno/dist/api/request-context-storage.js +43 -0
  77. package/dist/packages/fragno/dist/api/request-context-storage.js.map +1 -0
  78. package/dist/packages/fragno/dist/api/request-input-context.js +118 -0
  79. package/dist/packages/fragno/dist/api/request-input-context.js.map +1 -0
  80. package/dist/packages/fragno/dist/api/request-middleware.js +83 -0
  81. package/dist/packages/fragno/dist/api/request-middleware.js.map +1 -0
  82. package/dist/packages/fragno/dist/api/request-output-context.js +119 -0
  83. package/dist/packages/fragno/dist/api/request-output-context.js.map +1 -0
  84. package/dist/packages/fragno/dist/api/route.js +17 -0
  85. package/dist/packages/fragno/dist/api/route.js.map +1 -0
  86. package/dist/packages/fragno/dist/internal/symbols.js +10 -0
  87. package/dist/packages/fragno/dist/internal/symbols.js.map +1 -0
  88. package/dist/query/cursor.d.ts +10 -2
  89. package/dist/query/cursor.d.ts.map +1 -1
  90. package/dist/query/cursor.js +11 -4
  91. package/dist/query/cursor.js.map +1 -1
  92. package/dist/query/execute-unit-of-work.d.ts +123 -0
  93. package/dist/query/execute-unit-of-work.d.ts.map +1 -0
  94. package/dist/query/execute-unit-of-work.js +184 -0
  95. package/dist/query/execute-unit-of-work.js.map +1 -0
  96. package/dist/query/query.d.ts +2 -2
  97. package/dist/query/query.d.ts.map +1 -1
  98. package/dist/query/result-transform.js +4 -2
  99. package/dist/query/result-transform.js.map +1 -1
  100. package/dist/query/retry-policy.d.ts +88 -0
  101. package/dist/query/retry-policy.d.ts.map +1 -0
  102. package/dist/query/retry-policy.js +61 -0
  103. package/dist/query/retry-policy.js.map +1 -0
  104. package/dist/query/unit-of-work.d.ts +104 -50
  105. package/dist/query/unit-of-work.d.ts.map +1 -1
  106. package/dist/query/unit-of-work.js +384 -194
  107. package/dist/query/unit-of-work.js.map +1 -1
  108. package/dist/schema/serialize.js +12 -7
  109. package/dist/schema/serialize.js.map +1 -1
  110. package/dist/with-database.d.ts +28 -0
  111. package/dist/with-database.d.ts.map +1 -0
  112. package/dist/with-database.js +34 -0
  113. package/dist/with-database.js.map +1 -0
  114. package/package.json +9 -2
  115. package/src/adapters/adapters.ts +16 -0
  116. package/src/adapters/drizzle/drizzle-adapter-pglite.test.ts +80 -16
  117. package/src/adapters/drizzle/drizzle-adapter-sqlite.test.ts +158 -2
  118. package/src/adapters/drizzle/drizzle-adapter.test.ts +3 -51
  119. package/src/adapters/drizzle/drizzle-adapter.ts +20 -7
  120. package/src/adapters/drizzle/drizzle-query.ts +1 -2
  121. package/src/adapters/drizzle/drizzle-uow-compiler-mysql.test.ts +1442 -0
  122. package/src/adapters/drizzle/drizzle-uow-compiler-sqlite.test.ts +1414 -0
  123. package/src/adapters/drizzle/drizzle-uow-compiler.test.ts +21 -4
  124. package/src/adapters/drizzle/drizzle-uow-compiler.ts +44 -3
  125. package/src/adapters/drizzle/drizzle-uow-decoder.ts +32 -22
  126. package/src/adapters/drizzle/drizzle-uow-executor.ts +41 -8
  127. package/src/adapters/drizzle/generate.test.ts +102 -269
  128. package/src/adapters/drizzle/generate.ts +12 -30
  129. package/src/adapters/drizzle/test-utils.ts +36 -5
  130. package/src/adapters/kysely/kysely-adapter-pglite.test.ts +64 -20
  131. package/src/adapters/kysely/kysely-adapter-sqlite.test.ts +156 -0
  132. package/src/adapters/kysely/kysely-adapter.ts +9 -1
  133. package/src/adapters/kysely/kysely-query-compiler.ts +3 -8
  134. package/src/adapters/kysely/kysely-query.ts +34 -25
  135. package/src/adapters/kysely/kysely-shared.ts +34 -0
  136. package/src/adapters/kysely/kysely-uow-compiler.test.ts +61 -73
  137. package/src/adapters/kysely/kysely-uow-compiler.ts +44 -12
  138. package/src/adapters/kysely/kysely-uow-executor.ts +26 -7
  139. package/src/adapters/kysely/kysely-uow-joins.test.ts +31 -48
  140. package/src/adapters/kysely/migration/execute-base.ts +1 -1
  141. package/src/db-fragment-definition-builder.test.ts +887 -0
  142. package/src/db-fragment-definition-builder.ts +506 -0
  143. package/src/db-fragment-instantiator.test.ts +467 -0
  144. package/src/db-fragment-integration.test.ts +408 -0
  145. package/src/fragments/internal-fragment.test.ts +160 -0
  146. package/src/fragments/internal-fragment.ts +85 -0
  147. package/src/migration-engine/generation-engine.test.ts +58 -15
  148. package/src/migration-engine/generation-engine.ts +78 -25
  149. package/src/mod.ts +25 -52
  150. package/src/query/cursor.test.ts +119 -0
  151. package/src/query/cursor.ts +17 -4
  152. package/src/query/execute-unit-of-work.test.ts +1310 -0
  153. package/src/query/execute-unit-of-work.ts +463 -0
  154. package/src/query/query.ts +2 -2
  155. package/src/query/result-transform.test.ts +129 -0
  156. package/src/query/result-transform.ts +4 -1
  157. package/src/query/retry-policy.test.ts +217 -0
  158. package/src/query/retry-policy.ts +141 -0
  159. package/src/query/unit-of-work-coordinator.test.ts +833 -0
  160. package/src/query/unit-of-work-types.test.ts +2 -2
  161. package/src/query/unit-of-work.test.ts +873 -191
  162. package/src/query/unit-of-work.ts +602 -409
  163. package/src/schema/serialize.ts +22 -11
  164. package/src/with-database.ts +140 -0
  165. package/tsdown.config.ts +1 -0
  166. package/dist/bind-services.d.ts +0 -7
  167. package/dist/bind-services.d.ts.map +0 -1
  168. package/dist/bind-services.js +0 -14
  169. package/dist/bind-services.js.map +0 -1
  170. package/dist/fragment.d.ts +0 -173
  171. package/dist/fragment.d.ts.map +0 -1
  172. package/dist/fragment.js +0 -191
  173. package/dist/fragment.js.map +0 -1
  174. package/dist/shared/settings-schema.js +0 -36
  175. package/dist/shared/settings-schema.js.map +0 -1
  176. package/src/bind-services.test.ts +0 -214
  177. package/src/bind-services.ts +0 -37
  178. package/src/db-fragment.test.ts +0 -800
  179. package/src/fragment.ts +0 -727
  180. package/src/query/unit-of-work-multi-schema.test.ts +0 -64
  181. package/src/shared/settings-schema.ts +0 -61
  182. package/src/uow-context-integration.test.ts +0 -102
  183. package/src/uow-context.test.ts +0 -182
@@ -337,8 +337,16 @@ export function deserialize(value: unknown, col: AnyColumn, provider: SQLProvide
337
337
 
338
338
  /**
339
339
  * Encode to driver value
340
+ *
341
+ * @param skipDriverConversions - Skip driver-level type conversions (Date->number, boolean->0/1, bigint->Buffer).
342
+ * Set to true when using ORMs like Drizzle that handle these conversions internally.
340
343
  */
341
- export function serialize(value: unknown, col: AnyColumn, provider: SQLProvider) {
344
+ export function serialize(
345
+ value: unknown,
346
+ col: AnyColumn,
347
+ provider: SQLProvider,
348
+ skipDriverConversions = false,
349
+ ) {
342
350
  if (value === null) {
343
351
  return null;
344
352
  }
@@ -373,18 +381,21 @@ export function serialize(value: unknown, col: AnyColumn, provider: SQLProvider)
373
381
  return JSON.stringify(value);
374
382
  }
375
383
 
376
- if (provider === "sqlite" && value instanceof Date) {
377
- return value.getTime();
378
- }
384
+ // Skip driver-specific type conversions when using ORMs that handle them internally
385
+ if (!skipDriverConversions) {
386
+ if (provider === "sqlite" && value instanceof Date) {
387
+ return value.getTime();
388
+ }
379
389
 
380
- if (provider === "sqlite" && typeof value === "boolean") {
381
- return value ? 1 : 0;
382
- }
390
+ if (provider === "sqlite" && typeof value === "boolean") {
391
+ return value ? 1 : 0;
392
+ }
383
393
 
384
- if (provider === "sqlite" && typeof value === "bigint") {
385
- const buf = Buffer.alloc(8);
386
- buf.writeBigInt64BE(value);
387
- return buf;
394
+ if (provider === "sqlite" && typeof value === "bigint") {
395
+ const buf = Buffer.alloc(8);
396
+ buf.writeBigInt64BE(value);
397
+ return buf;
398
+ }
388
399
  }
389
400
 
390
401
  // most drivers accept Buffer
@@ -0,0 +1,140 @@
1
+ import type { AnySchema } from "./schema/create";
2
+ import type { RequestThisContext, FragnoPublicConfig } from "@fragno-dev/core";
3
+ import { FragmentDefinitionBuilder, instantiate } from "@fragno-dev/core";
4
+ import {
5
+ DatabaseFragmentDefinitionBuilder,
6
+ type DatabaseServiceContext,
7
+ type DatabaseHandlerContext,
8
+ type ImplicitDatabaseDependencies,
9
+ type FragnoPublicConfigWithDatabase,
10
+ type DatabaseRequestStorage,
11
+ } from "./db-fragment-definition-builder";
12
+ import { internalFragmentDef } from "./fragments/internal-fragment";
13
+
14
+ /**
15
+ * Helper to add database support to a fragment builder.
16
+ * Automatically links the internal fragment and adds ImplicitDatabaseDependencies to the TDeps type.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * // With .extend() - recommended
21
+ * const def = defineFragment("my-frag")
22
+ * .extend(withDatabase(mySchema))
23
+ * .withDependencies(...)
24
+ * .build();
25
+ *
26
+ * // Or as a function wrapper
27
+ * const def = withDatabase(mySchema)(defineFragment("my-frag"))
28
+ * .withDependencies(...)
29
+ * .build();
30
+ * ```
31
+ */
32
+ export function withDatabase<TSchema extends AnySchema>(
33
+ schema: TSchema,
34
+ namespace?: string,
35
+ ): <
36
+ TConfig,
37
+ TDeps,
38
+ TBaseServices,
39
+ TServices,
40
+ TServiceDeps,
41
+ TPrivateServices,
42
+ TServiceThisContext extends RequestThisContext,
43
+ THandlerThisContext extends RequestThisContext,
44
+ TRequestStorage,
45
+ >(
46
+ builder: FragmentDefinitionBuilder<
47
+ TConfig,
48
+ FragnoPublicConfig,
49
+ TDeps,
50
+ TBaseServices,
51
+ TServices,
52
+ TServiceDeps,
53
+ TPrivateServices,
54
+ TServiceThisContext,
55
+ THandlerThisContext,
56
+ TRequestStorage
57
+ >,
58
+ ) => DatabaseFragmentDefinitionBuilder<
59
+ TSchema,
60
+ TConfig,
61
+ TDeps & ImplicitDatabaseDependencies<TSchema>,
62
+ TBaseServices,
63
+ TServices,
64
+ TServiceDeps,
65
+ TPrivateServices,
66
+ DatabaseServiceContext,
67
+ DatabaseHandlerContext
68
+ > {
69
+ return <
70
+ TConfig,
71
+ TDeps,
72
+ TBaseServices,
73
+ TServices,
74
+ TServiceDeps,
75
+ TPrivateServices,
76
+ TServiceThisContext extends RequestThisContext,
77
+ THandlerThisContext extends RequestThisContext,
78
+ TRequestStorage,
79
+ >(
80
+ builder: FragmentDefinitionBuilder<
81
+ TConfig,
82
+ FragnoPublicConfig,
83
+ TDeps,
84
+ TBaseServices,
85
+ TServices,
86
+ TServiceDeps,
87
+ TPrivateServices,
88
+ TServiceThisContext,
89
+ THandlerThisContext,
90
+ TRequestStorage
91
+ >,
92
+ ) => {
93
+ // Link the internal fragment to all database fragments (except the internal fragment itself)
94
+ // No circular dependency: internal-fragment.ts uses DatabaseFragmentDefinitionBuilder directly
95
+ const isInternalFragment = builder.name === "$fragno-internal-fragment";
96
+ const builderWithInternal = isInternalFragment
97
+ ? builder
98
+ : builder.withLinkedFragment("_fragno_internal", ({ config, options }) => {
99
+ // Cast is safe: by the time this callback is invoked during fragment instantiation,
100
+ // the options will be FragnoPublicConfigWithDatabase (enforced by DatabaseFragmentDefinitionBuilder)
101
+ return instantiate(internalFragmentDef)
102
+ .withConfig(config as {})
103
+ .withOptions(options as FragnoPublicConfigWithDatabase)
104
+ .build();
105
+ });
106
+
107
+ // Cast is safe: we're creating a DatabaseFragmentDefinitionBuilder which internally uses
108
+ // FragnoPublicConfigWithDatabase, but the input builder uses FragnoPublicConfig.
109
+ // The database builder's build() method will enforce FragnoPublicConfigWithDatabase at the end.
110
+ // We also add ImplicitDatabaseDependencies to TDeps so they're available in service constructors.
111
+ // Note: We discard TRequestStorage here because database fragments manage their own storage (DatabaseRequestStorage).
112
+ // We set TServiceThisContext to DatabaseServiceContext (restricted) and THandlerThisContext to DatabaseHandlerContext (full).
113
+ return new DatabaseFragmentDefinitionBuilder<
114
+ TSchema,
115
+ TConfig,
116
+ TDeps & ImplicitDatabaseDependencies<TSchema>,
117
+ TBaseServices,
118
+ TServices,
119
+ TServiceDeps,
120
+ TPrivateServices,
121
+ DatabaseServiceContext,
122
+ DatabaseHandlerContext
123
+ >(
124
+ builderWithInternal as unknown as FragmentDefinitionBuilder<
125
+ TConfig,
126
+ FragnoPublicConfigWithDatabase,
127
+ TDeps & ImplicitDatabaseDependencies<TSchema>,
128
+ TBaseServices,
129
+ TServices,
130
+ TServiceDeps,
131
+ TPrivateServices,
132
+ DatabaseServiceContext,
133
+ DatabaseHandlerContext,
134
+ DatabaseRequestStorage
135
+ >,
136
+ schema,
137
+ namespace,
138
+ );
139
+ };
140
+ }
package/tsdown.config.ts CHANGED
@@ -13,6 +13,7 @@ export default defineConfig({
13
13
  "./src/query/unit-of-work.ts",
14
14
  "./src/query/cursor.ts",
15
15
  "./src/fragment.ts",
16
+ "./src/db-fragment-definition-builder.ts",
16
17
  "./src/migration-engine/generation-engine.ts",
17
18
  ],
18
19
  dts: true,
@@ -1,7 +0,0 @@
1
- //#region src/bind-services.d.ts
2
- type OmitThisParameter<T> = T extends ((this: infer _This, ...args: infer A) => infer R) ? (...args: A) => R : T;
3
- type BoundServices<T> = { [K in keyof T]: T[K] extends ((...args: never[]) => unknown) ? OmitThisParameter<T[K]> : T[K] extends Record<string, unknown> ? BoundServices<T[K]> : T[K] };
4
- declare function bindServicesToContext<T extends Record<string, unknown>>(services: T): BoundServices<T>;
5
- //#endregion
6
- export { BoundServices, bindServicesToContext };
7
- //# sourceMappingURL=bind-services.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bind-services.d.ts","names":[],"sources":["../src/bind-services.ts"],"sourcesContent":[],"mappings":";KAGK,uBAAuB,yEACd,MAAM,IAChB;AAFC,KAKO,aALU,CAAA,CAAA,CAAA,GAAA,QAAM,MAMd,CANc,GAMV,CANU,CAMR,CANQ,CAAA,UAAA,CAAA,GAAA,IAAA,EAAA,KAAA,EAAA,EAAA,GAAA,OAAA,IAOtB,iBAPsB,CAOJ,CAPI,CAOF,CAPE,CAAA,CAAA,GAQtB,CARsB,CAQpB,CARoB,CAAA,SAQT,MARS,CAAA,MAAA,EAAA,OAAA,CAAA,GASpB,aAToB,CASN,CATM,CASJ,CATI,CAAA,CAAA,GAUpB,CAVoB,CAUlB,CAVkB,CAAA,EACd;AAAM,iBAYJ,qBAZI,CAAA,UAY4B,MAZ5B,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,CAAA,QAAA,EAaR,CAbQ,CAAA,EAcjB,aAdiB,CAcH,CAdG,CAAA"}
@@ -1,14 +0,0 @@
1
- import { serviceContext } from "./fragment.js";
2
-
3
- //#region src/bind-services.ts
4
- function bindServicesToContext(services) {
5
- const bound = {};
6
- for (const [key, value] of Object.entries(services)) if (typeof value === "function") bound[key] = value.bind(serviceContext);
7
- else if (value && typeof value === "object" && !Array.isArray(value)) bound[key] = bindServicesToContext(value);
8
- else bound[key] = value;
9
- return bound;
10
- }
11
-
12
- //#endregion
13
- export { bindServicesToContext };
14
- //# sourceMappingURL=bind-services.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bind-services.js","names":[],"sources":["../src/bind-services.ts"],"sourcesContent":["import { serviceContext } from \"./fragment\";\n\n// Type helper to remove 'this' parameter from functions\ntype OmitThisParameter<T> = T extends (this: infer _This, ...args: infer A) => infer R\n ? (...args: A) => R\n : T;\n\n// Recursively remove 'this' parameter from all functions in an object\nexport type BoundServices<T> = {\n [K in keyof T]: T[K] extends (...args: never[]) => unknown\n ? OmitThisParameter<T[K]>\n : T[K] extends Record<string, unknown>\n ? BoundServices<T[K]>\n : T[K];\n};\n\nexport function bindServicesToContext<T extends Record<string, unknown>>(\n services: T,\n): BoundServices<T> {\n const bound = {} as BoundServices<T>;\n\n for (const [key, value] of Object.entries(services)) {\n if (typeof value === \"function\") {\n // Bind function to serviceContext\n bound[key as keyof T] = value.bind(serviceContext) as BoundServices<T>[keyof T];\n } else if (value && typeof value === \"object\" && !Array.isArray(value)) {\n // Recursively bind nested service objects\n bound[key as keyof T] = bindServicesToContext(\n value as Record<string, unknown>,\n ) as BoundServices<T>[keyof T];\n } else {\n bound[key as keyof T] = value as BoundServices<T>[keyof T];\n }\n }\n\n return bound;\n}\n"],"mappings":";;;AAgBA,SAAgB,sBACd,UACkB;CAClB,MAAM,QAAQ,EAAE;AAEhB,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,SAAS,CACjD,KAAI,OAAO,UAAU,WAEnB,OAAM,OAAkB,MAAM,KAAK,eAAe;UACzC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,MAAM,CAEpE,OAAM,OAAkB,sBACtB,MACD;KAED,OAAM,OAAkB;AAI5B,QAAO"}
@@ -1,173 +0,0 @@
1
- import { AnySchema } from "./schema/create.js";
2
- import { IUnitOfWorkBase, UnitOfWorkSchemaView } from "./query/unit-of-work.js";
3
- import { AbstractQuery } from "./query/query.js";
4
- import { DatabaseAdapter } from "./adapters/adapters.js";
5
- import { BoundServices, bindServicesToContext } from "./bind-services.js";
6
- import { AsyncLocalStorage } from "async_hooks";
7
- import { RequestThisContext } from "@fragno-dev/core/api";
8
- import { FragmentDefinition, FragnoPublicConfig, RequestInputContext, RequestOutputContext } from "@fragno-dev/core";
9
-
10
- //#region src/fragment.d.ts
11
- declare const uowStorage: AsyncLocalStorage<IUnitOfWorkBase>;
12
- /**
13
- * Service context for database fragments, providing access to the Unit of Work.
14
- */
15
- interface DatabaseRequestThisContext extends RequestThisContext {
16
- /**
17
- * Get the Unit of Work from the current context.
18
- * @param schema - Optional schema to get a typed view. If not provided, returns the base UOW.
19
- * @returns IUnitOfWorkBase if no schema provided, or typed UnitOfWorkSchemaView if schema provided.
20
- */
21
- getUnitOfWork(): IUnitOfWorkBase;
22
- getUnitOfWork<TSchema extends AnySchema>(schema: TSchema): UnitOfWorkSchemaView<TSchema, [], any>;
23
- }
24
- declare const serviceContext: DatabaseRequestThisContext;
25
- declare function withUnitOfWork<T>(uow: IUnitOfWorkBase, callback: () => T): Promise<T>;
26
- /**
27
- * Type helper that enforces DatabaseRequestThisContext on all functions in a service object
28
- */
29
- type WithDatabaseThis<T> = { [K in keyof T]: T[K] extends ((...args: infer A) => infer R) ? (this: DatabaseRequestThisContext, ...args: A) => R : T[K] extends Record<string, unknown> ? WithDatabaseThis<T[K]> : T[K] };
30
- /**
31
- * Route handler type for database fragments with access to Unit of Work.
32
- */
33
- type DatabaseRouteHandler = (this: DatabaseRequestThisContext, inputContext: RequestInputContext, outputContext: RequestOutputContext) => Promise<Response>;
34
- /**
35
- * Extended FragnoPublicConfig that includes a database adapter.
36
- * Use this type when creating fragments with database support.
37
- */
38
- type FragnoPublicConfigWithDatabase = FragnoPublicConfig & {
39
- databaseAdapter: DatabaseAdapter<any>;
40
- };
41
- /**
42
- * Additional context provided to database fragments containing the database adapter and ORM instance.
43
- */
44
- type DatabaseFragmentContext<TSchema extends AnySchema> = {
45
- databaseAdapter: DatabaseAdapter<any>;
46
- orm: AbstractQuery<TSchema>;
47
- };
48
- declare class DatabaseFragmentBuilder<const TSchema extends AnySchema, const TConfig, const TDeps = {}, const TServices = {}, const TUsedServices = {}, const TProvidedServices = {}> {
49
- #private;
50
- readonly $types: {
51
- schema: TSchema;
52
- config: TConfig;
53
- deps: TDeps;
54
- services: TServices;
55
- usedServices: TUsedServices;
56
- providedServices: TProvidedServices;
57
- };
58
- constructor(options: {
59
- name: string;
60
- schema?: TSchema;
61
- namespace?: string;
62
- dependencies?: (context: {
63
- config: TConfig;
64
- fragnoConfig: FragnoPublicConfig;
65
- } & DatabaseFragmentContext<TSchema>) => TDeps;
66
- services?: (context: {
67
- config: TConfig;
68
- fragnoConfig: FragnoPublicConfig;
69
- deps: TDeps & TUsedServices;
70
- defineService: <T extends Record<string, unknown>>(services: WithDatabaseThis<T>) => WithDatabaseThis<T>;
71
- } & DatabaseFragmentContext<TSchema>) => TServices;
72
- usedServices?: Record<string, {
73
- name: string;
74
- required: boolean;
75
- }>;
76
- providedServices?: Record<string, unknown>;
77
- });
78
- get $requiredOptions(): FragnoPublicConfigWithDatabase;
79
- get definition(): FragmentDefinition<TConfig, TDeps, BoundServices<TServices>, {
80
- databaseSchema?: TSchema;
81
- databaseNamespace: string;
82
- }, BoundServices<TUsedServices>, BoundServices<TProvidedServices>, DatabaseRequestThisContext>;
83
- withDatabase<TNewSchema extends AnySchema>(schema: TNewSchema, namespace?: string): DatabaseFragmentBuilder<TNewSchema, TConfig, TDeps, TServices, TUsedServices, TProvidedServices>;
84
- withDependencies<TNewDeps>(fn: (context: {
85
- config: TConfig;
86
- fragnoConfig: FragnoPublicConfig;
87
- } & DatabaseFragmentContext<TSchema>) => TNewDeps): DatabaseFragmentBuilder<TSchema, TConfig, TNewDeps, {}, TUsedServices, TProvidedServices>;
88
- /**
89
- * Declare that this fragment uses a service.
90
- * @param serviceName - The name of the service to use
91
- * @param options - Optional configuration: { optional: boolean } (defaults to required)
92
- */
93
- usesService<TServiceName extends string, TService>(serviceName: TServiceName, options?: {
94
- optional?: false;
95
- }): DatabaseFragmentBuilder<TSchema, TConfig, TDeps, TServices, TUsedServices & { [K in TServiceName]: TService }, TProvidedServices>;
96
- usesService<TServiceName extends string, TService>(serviceName: TServiceName, options: {
97
- optional: true;
98
- }): DatabaseFragmentBuilder<TSchema, TConfig, TDeps, TServices, TUsedServices & { [K in TServiceName]: TService | undefined }, TProvidedServices>;
99
- /**
100
- * Define services for this fragment (unnamed).
101
- * Functions in the service will have access to DatabaseRequestThisContext via `this` if using `defineService`.
102
- *
103
- * @example
104
- * With `this` context:
105
- * ```ts
106
- * .providesService(({ defineService }) => defineService({
107
- * createUser: function(name: string) {
108
- * const uow = this.getUnitOfWork(mySchema);
109
- * return uow.create('user', { name });
110
- * }
111
- * }))
112
- * ```
113
- *
114
- * Without `this` context:
115
- * ```ts
116
- * .providesService(({ db }) => ({
117
- * createUser: async (name: string) => {
118
- * return db.create('user', { name });
119
- * }
120
- * }))
121
- * ```
122
- */
123
- providesService<TNewServices>(fn: (context: {
124
- config: TConfig;
125
- fragnoConfig: FragnoPublicConfig;
126
- deps: TDeps & TUsedServices;
127
- db: AbstractQuery<TSchema>;
128
- defineService: <T extends Record<string, unknown>>(services: WithDatabaseThis<T>) => WithDatabaseThis<T>;
129
- }) => TNewServices): DatabaseFragmentBuilder<TSchema, TConfig, TDeps, TNewServices, TUsedServices, TProvidedServices>;
130
- /**
131
- * Provide a named service that other fragments can use.
132
- * Functions in the service will have access to DatabaseRequestThisContext via `this` if using `defineService`.
133
- * You can also pass a service object directly instead of a callback.
134
- *
135
- * @example
136
- * With callback and `this` context:
137
- * ```ts
138
- * .providesService("myService", ({ defineService }) => defineService({
139
- * createUser: function(name: string) {
140
- * const uow = this.getUnitOfWork(mySchema);
141
- * return uow.create('user', { name });
142
- * }
143
- * }))
144
- * ```
145
- *
146
- * With callback, no `this` context:
147
- * ```ts
148
- * .providesService("myService", ({ db }) => ({
149
- * createUser: async (name: string) => {
150
- * return db.create('user', { name });
151
- * }
152
- * }))
153
- * ```
154
- *
155
- * With direct object:
156
- * ```ts
157
- * .providesService("myService", {
158
- * createUser: async (name: string) => { ... }
159
- * })
160
- * ```
161
- */
162
- providesService<TServiceName extends string, TService>(serviceName: TServiceName, fnOrService: ((context: {
163
- config: TConfig;
164
- fragnoConfig: FragnoPublicConfig;
165
- deps: TDeps & TUsedServices;
166
- db: AbstractQuery<TSchema>;
167
- defineService: <T extends Record<string, unknown>>(services: WithDatabaseThis<T>) => WithDatabaseThis<T>;
168
- }) => TService) | TService): DatabaseFragmentBuilder<TSchema, TConfig, TDeps, TServices, TUsedServices, TProvidedServices & { [K in TServiceName]: BoundServices<TService> }>;
169
- }
170
- declare function defineFragmentWithDatabase<TConfig = {}>(name: string): DatabaseFragmentBuilder<never, TConfig, {}, {}, {}, {}>;
171
- //#endregion
172
- export { type BoundServices, DatabaseFragmentBuilder, DatabaseFragmentContext, DatabaseRequestThisContext, DatabaseRouteHandler, FragnoPublicConfigWithDatabase, bindServicesToContext, defineFragmentWithDatabase, serviceContext, uowStorage, withUnitOfWork };
173
- //# sourceMappingURL=fragment.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fragment.d.ts","names":[],"sources":["../src/fragment.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/fragment.js DELETED
@@ -1,191 +0,0 @@
1
- import { bindServicesToContext } from "./bind-services.js";
2
- import { AsyncLocalStorage } from "async_hooks";
3
-
4
- //#region src/fragment.ts
5
- const uowStorage = new AsyncLocalStorage();
6
- const serviceContext = { getUnitOfWork(schema) {
7
- const uow = uowStorage.getStore();
8
- if (!uow) throw new Error("No UnitOfWork in context. Service must be called within a route handler.");
9
- if (schema) return uow.forSchema(schema);
10
- return uow;
11
- } };
12
- function withUnitOfWork(uow, callback) {
13
- return Promise.resolve(uowStorage.run(uow, callback));
14
- }
15
- var DatabaseFragmentBuilder = class DatabaseFragmentBuilder {
16
- $types;
17
- #name;
18
- #schema;
19
- #namespace;
20
- #dependencies;
21
- #services;
22
- #usedServices;
23
- #providedServices;
24
- constructor(options) {
25
- this.#name = options.name;
26
- this.#schema = options.schema;
27
- this.#namespace = options.namespace;
28
- this.#dependencies = options.dependencies;
29
- this.#services = options.services;
30
- this.#usedServices = options.usedServices;
31
- this.#providedServices = options.providedServices;
32
- }
33
- get $requiredOptions() {
34
- throw new Error("Type only method. Do not call.");
35
- }
36
- get definition() {
37
- const schema = this.#schema;
38
- const namespace = this.#namespace ?? "";
39
- const name = this.#name;
40
- const dependencies = this.#dependencies;
41
- const services = this.#services;
42
- const providedServices = this.#providedServices;
43
- return {
44
- name,
45
- dependencies: (config, options) => {
46
- const dbContext = this.#createDatabaseContext(options, schema, namespace, name);
47
- return dependencies?.({
48
- config,
49
- fragnoConfig: options,
50
- ...dbContext
51
- }) ?? {};
52
- },
53
- services: (config, options, deps) => {
54
- const dbContext = this.#createDatabaseContext(options, schema, namespace, name);
55
- const defineService = (services$1) => services$1;
56
- return bindServicesToContext(services?.({
57
- config,
58
- fragnoConfig: options,
59
- deps,
60
- defineService,
61
- ...dbContext
62
- }) ?? {});
63
- },
64
- additionalContext: {
65
- databaseSchema: schema,
66
- databaseNamespace: namespace
67
- },
68
- createHandlerWrapper: schema ? (options) => {
69
- const { orm } = this.#createDatabaseContext(options, schema, namespace, name);
70
- return (handler) => {
71
- return async (inputContext, outputContext) => {
72
- return withUnitOfWork(orm.createUnitOfWork(), async () => {
73
- return handler.bind(serviceContext)(inputContext, outputContext);
74
- });
75
- };
76
- };
77
- } : void 0,
78
- usedServices: this.#usedServices,
79
- providedServices
80
- };
81
- }
82
- #createDatabaseContext(options, schema, namespace, name) {
83
- const databaseAdapter = options.databaseAdapter;
84
- if (!databaseAdapter) throw new Error(`Fragment '${name}' requires a database adapter in options.databaseAdapter`);
85
- if (!schema) throw new Error(`Fragment '${name}' requires a schema. Use withDatabase() to provide one.`);
86
- return {
87
- databaseAdapter,
88
- orm: databaseAdapter.createQueryEngine(schema, namespace)
89
- };
90
- }
91
- withDatabase(schema, namespace) {
92
- return new DatabaseFragmentBuilder({
93
- name: this.#name,
94
- schema,
95
- namespace: namespace ?? this.#name + "-db",
96
- dependencies: this.#dependencies,
97
- services: this.#services,
98
- usedServices: this.#usedServices,
99
- providedServices: this.#providedServices
100
- });
101
- }
102
- withDependencies(fn) {
103
- return new DatabaseFragmentBuilder({
104
- name: this.#name,
105
- schema: this.#schema,
106
- namespace: this.#namespace,
107
- dependencies: fn,
108
- services: void 0,
109
- usedServices: this.#usedServices,
110
- providedServices: this.#providedServices
111
- });
112
- }
113
- usesService(serviceName, options) {
114
- const isOptional = options?.optional ?? false;
115
- return new DatabaseFragmentBuilder({
116
- name: this.#name,
117
- schema: this.#schema,
118
- namespace: this.#namespace,
119
- dependencies: this.#dependencies,
120
- services: this.#services,
121
- usedServices: {
122
- ...this.#usedServices,
123
- [serviceName]: {
124
- name: serviceName,
125
- required: !isOptional
126
- }
127
- },
128
- providedServices: this.#providedServices
129
- });
130
- }
131
- providesService(...args) {
132
- if (args.length === 1) {
133
- const [fn] = args;
134
- const servicesCallback = (context) => {
135
- const defineService = (services) => services;
136
- return fn({
137
- config: context.config,
138
- fragnoConfig: context.fragnoConfig,
139
- deps: context.deps,
140
- db: context.orm,
141
- defineService
142
- });
143
- };
144
- return new DatabaseFragmentBuilder({
145
- name: this.#name,
146
- schema: this.#schema,
147
- namespace: this.#namespace,
148
- dependencies: this.#dependencies,
149
- services: servicesCallback,
150
- usedServices: this.#usedServices,
151
- providedServices: this.#providedServices
152
- });
153
- } else {
154
- const [serviceName, fnOrService] = args;
155
- const createService = (config, options, deps) => {
156
- const dbContext = this.#createDatabaseContext(options, this.#schema, this.#namespace ?? "", this.#name);
157
- let implementation;
158
- if (typeof fnOrService === "function") {
159
- const defineService = (services) => services;
160
- implementation = fnOrService({
161
- config,
162
- fragnoConfig: options,
163
- deps,
164
- db: dbContext.orm,
165
- defineService
166
- });
167
- } else implementation = fnOrService;
168
- return bindServicesToContext(implementation);
169
- };
170
- return new DatabaseFragmentBuilder({
171
- name: this.#name,
172
- schema: this.#schema,
173
- namespace: this.#namespace,
174
- dependencies: this.#dependencies,
175
- services: this.#services,
176
- usedServices: this.#usedServices,
177
- providedServices: {
178
- ...this.#providedServices,
179
- [serviceName]: createService
180
- }
181
- });
182
- }
183
- }
184
- };
185
- function defineFragmentWithDatabase(name) {
186
- return new DatabaseFragmentBuilder({ name });
187
- }
188
-
189
- //#endregion
190
- export { DatabaseFragmentBuilder, bindServicesToContext, defineFragmentWithDatabase, serviceContext, uowStorage, withUnitOfWork };
191
- //# sourceMappingURL=fragment.js.map