t3code-cli 0.5.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/README.md +41 -16
  2. package/dist/Context-DueQ9iMH.js +4916 -0
  3. package/dist/Path-D8WPdPwR.js +11406 -0
  4. package/dist/Schema-DsQxYh6_.js +13581 -0
  5. package/dist/UrlParams-BA6gBvaY.js +205 -0
  6. package/dist/application.js +2 -0
  7. package/dist/auth.js +3 -0
  8. package/dist/base-dir-R12OMDso.js +20 -0
  9. package/dist/bin.js +236 -13526
  10. package/dist/chunk-B5meny8j.js +36 -0
  11. package/dist/cli.js +2 -0
  12. package/dist/config.js +4 -0
  13. package/dist/connection.js +15 -0
  14. package/dist/contracts.js +1 -0
  15. package/dist/error-B2t1bAP9.js +169 -0
  16. package/dist/error-BHRnjLux.js +15 -0
  17. package/dist/error-jwMt3VoW.js +54 -0
  18. package/dist/flags-CM7_iGdA.js +13371 -0
  19. package/dist/index.js +5 -12
  20. package/dist/layer-CfC5qZol.js +1508 -0
  21. package/dist/layer-DHhKS5jd.js +13 -0
  22. package/dist/layer-DUv99vsS.js +72 -0
  23. package/dist/layer-DvHnKBYj.js +29466 -0
  24. package/dist/layer-MqCKkIGD.js +1206 -0
  25. package/dist/layout.js +2 -0
  26. package/dist/orchestration.js +2 -0
  27. package/dist/rpc.js +2 -0
  28. package/dist/runtime.js +3 -0
  29. package/dist/scope-GycYiJ54.js +29 -0
  30. package/dist/scope.js +2 -0
  31. package/dist/service-CLmRO2Dp.js +8 -0
  32. package/dist/service-ybOWV9pL.js +5 -0
  33. package/dist/src/application/index.d.ts +3 -0
  34. package/dist/src/application/layer.d.ts +4 -4
  35. package/dist/src/application/projects.d.ts +1 -1
  36. package/dist/src/application/service.d.ts +1 -1
  37. package/dist/src/application/threads.d.ts +4 -4
  38. package/dist/src/auth/index.d.ts +10 -0
  39. package/dist/src/auth/local-base-dir.d.ts +5 -7
  40. package/dist/src/auth/local-token.d.ts +2 -2
  41. package/dist/src/auth/type.d.ts +1 -0
  42. package/dist/src/cli/flags.d.ts +15 -0
  43. package/dist/src/cli/index.d.ts +1 -0
  44. package/dist/src/cli/output-format.d.ts +9 -0
  45. package/dist/src/config/index.d.ts +5 -0
  46. package/dist/src/config/layer.d.ts +2 -0
  47. package/dist/src/config/service.d.ts +2 -0
  48. package/dist/src/connection/index.d.ts +5 -0
  49. package/dist/src/contracts/index.d.ts +1 -0
  50. package/dist/src/domain/helpers.d.ts +163 -32
  51. package/dist/src/index.d.ts +4 -28
  52. package/dist/src/layout/base-dir.d.ts +12 -0
  53. package/dist/src/layout/index.d.ts +1 -0
  54. package/dist/src/orchestration/index.d.ts +2 -0
  55. package/dist/src/rpc/index.d.ts +1 -0
  56. package/dist/src/runtime/index.d.ts +2 -0
  57. package/dist/src/runtime/layer.d.ts +11 -0
  58. package/dist/src/scope/index.d.ts +1 -0
  59. package/dist/src/scope/resolve.d.ts +19 -0
  60. package/dist/src/t3tools/index.d.ts +1 -0
  61. package/dist/src-KdbHqrex.js +8874 -0
  62. package/dist/t3tools.js +2 -0
  63. package/dist/transport-D3zBdZ1h.js +539 -0
  64. package/dist/url-SlsaG8nY.js +165 -0
  65. package/package.json +54 -2
  66. package/src/application/index.ts +3 -0
  67. package/src/application/service.ts +1 -1
  68. package/src/application/threads.ts +38 -11
  69. package/src/auth/index.ts +28 -0
  70. package/src/auth/layer.ts +13 -6
  71. package/src/auth/local-base-dir.ts +15 -19
  72. package/src/auth/local-origin.ts +4 -1
  73. package/src/auth/local-token.ts +4 -1
  74. package/src/auth/type.ts +1 -0
  75. package/src/bin.ts +1 -1
  76. package/src/cli/app.ts +6 -6
  77. package/src/cli/auth-format.ts +2 -0
  78. package/src/cli/auth.ts +19 -9
  79. package/src/cli/error.ts +7 -0
  80. package/src/cli/flags.ts +51 -0
  81. package/src/cli/index.ts +10 -0
  82. package/src/cli/{models.ts → model.ts} +5 -4
  83. package/src/cli/{projects.ts → project.ts} +8 -7
  84. package/src/cli/require.ts +31 -0
  85. package/src/cli/{threads.ts → thread.ts} +2 -2
  86. package/src/cli/threads/archive.ts +24 -8
  87. package/src/cli/threads/list.ts +12 -5
  88. package/src/cli/threads/messages.ts +20 -5
  89. package/src/cli/threads/send.ts +27 -23
  90. package/src/cli/threads/start.ts +22 -21
  91. package/src/cli/threads/wait.ts +22 -12
  92. package/src/config/index.ts +5 -0
  93. package/src/config/layer.ts +2 -0
  94. package/src/config/service.ts +2 -0
  95. package/src/connection/index.ts +9 -0
  96. package/src/contracts/index.ts +8 -0
  97. package/src/domain/helpers.test.ts +103 -0
  98. package/src/domain/helpers.ts +112 -16
  99. package/src/index.ts +4 -87
  100. package/src/layout/base-dir.ts +35 -0
  101. package/src/layout/index.ts +1 -0
  102. package/src/orchestration/index.ts +7 -0
  103. package/src/rpc/index.ts +1 -0
  104. package/src/runtime/index.ts +12 -0
  105. package/src/{runtime.ts → runtime/layer.ts} +15 -15
  106. package/src/scope/index.ts +6 -0
  107. package/src/scope/resolve.ts +62 -0
  108. package/src/t3tools/index.ts +1 -0
  109. package/dist/runtime-KQVRmRk-.js +0 -71499
  110. package/dist/src/connection.d.ts +0 -5
  111. package/dist/src/runtime.d.ts +0 -10
  112. package/src/connection.ts +0 -9
@@ -0,0 +1,1508 @@
1
+ import { $t as hash, Tn as constUndefined, X as Prototype, a as get, an as hasProperty, bn as isTagged, h as mutate, k as match, kn as flow, n as Service, o as getOption, r as add, t as Reference } from "./Context-DueQ9iMH.js";
2
+ import { $ as mapError, Ar as makeSpanUnsafe, At as tap, Br as ParentSpan, Bt as useSpan, C as context, Ct as serviceOption, D as ensuring, F as fnUntraced, H as fromResult, Jn as TracerTimingEnabled, Kn as provide, O as exit, Ot as suspend, P as fn, Rn as Scope, Rt as uninterruptibleMask, S as clockWith, Tt as succeed, U as gen, Ur as reason, Ut as withFiber, Vn as close, Vt as void_, Wn as make$4, X as map, Y as makeSpanScoped, _r as endSpan, a as badArgument, at as onExit, b as catchTags, dt as provideService, gt as runForkWith, j as flatMap, k as fail, kn as effect, kt as sync, sr as isSuccess, st as orDie, t as Path, ut as provideContext, v as catchFilter, w as contextWith, xt as scoped, y as catchTag, zn as addFinalizer } from "./Path-D8WPdPwR.js";
3
+ import { Bn as Clock, Dn as runIn, Dt as fromQueue, Fn as encodeBase64Url, In as add$1, Ln as formatIso, Rn as now, Sn as offerUnsafe, dt as FileSystem, nn as unwrap, vn as failCauseUnsafe, yn as make$5, zn as toEpochMillis } from "./Schema-DsQxYh6_.js";
4
+ import { r as decodeAuthLocalRuntimeStateFromJson, t as T3AuthTransport } from "./transport-D3zBdZ1h.js";
5
+ import { ou as AuthAdministrativeScopes, zu as AuthSessionId } from "./src-KdbHqrex.js";
6
+ import { n as T3Config, t as Environment } from "./service-CLmRO2Dp.js";
7
+ import { a as mutate$1, i as fromString, t as normalizeHttpBaseUrl } from "./url-SlsaG8nY.js";
8
+ import { a as AuthLocalSigningError, i as AuthLocalSecretError, n as AuthLocalDatabaseError, o as AuthPairingUrlError, r as AuthLocalError, t as AuthConfigError } from "./error-jwMt3VoW.js";
9
+ import { n as resolveT3BaseDir } from "./base-dir-R12OMDso.js";
10
+ //#region node_modules/.pnpm/effect@4.0.0-beta.78/node_modules/effect/dist/Crypto.js
11
+ /**
12
+ * The `Crypto` module provides a platform-agnostic service for cryptographic
13
+ * operations. Runtime packages such as `@effect/platform-node`,
14
+ * `@effect/platform-bun`, and `@effect/platform-browser` provide concrete
15
+ * implementations backed by the host platform's cryptography APIs.
16
+ *
17
+ * Use `Crypto` for cryptographic randomness, UUID generation, random values,
18
+ * and message digests. The base `Random` service is not cryptographically
19
+ * secure unless you replace it with a cryptographically secure implementation.
20
+ *
21
+ * **Example** (Providing a test Crypto service)
22
+ *
23
+ * ```ts
24
+ * import { Console, Crypto, Effect, Layer } from "effect"
25
+ *
26
+ * const TestCrypto = Layer.succeed(
27
+ * Crypto.Crypto,
28
+ * Crypto.make({
29
+ * randomBytes: (size) => new Uint8Array(size),
30
+ * digest: (_algorithm, data) => Effect.succeed(data)
31
+ * })
32
+ * )
33
+ *
34
+ * const program = Effect.gen(function*() {
35
+ * const crypto = yield* Crypto.Crypto
36
+ * const id = yield* crypto.randomUUIDv4
37
+ * yield* Console.log(`Created id: ${id}`)
38
+ * })
39
+ *
40
+ * Effect.runPromise(Effect.provide(program, TestCrypto))
41
+ * ```
42
+ *
43
+ * **Example** (Generating random bytes)
44
+ *
45
+ * ```ts
46
+ * import { Crypto, Effect, Layer } from "effect"
47
+ *
48
+ * const TestCrypto = Layer.succeed(
49
+ * Crypto.Crypto,
50
+ * Crypto.make({
51
+ * randomBytes: (size) => new Uint8Array(size),
52
+ * digest: (_algorithm, data) => Effect.succeed(data)
53
+ * })
54
+ * )
55
+ *
56
+ * const program = Effect.gen(function*() {
57
+ * const crypto = yield* Crypto.Crypto
58
+ * return yield* crypto.randomBytes(32)
59
+ * })
60
+ *
61
+ * Effect.runPromise(Effect.provide(program, TestCrypto))
62
+ * ```
63
+ *
64
+ * @since 4.0.0
65
+ */
66
+ const TypeId$1 = "~effect/platform/Crypto";
67
+ /**
68
+ * Service tag for platform cryptography.
69
+ *
70
+ * **When to use**
71
+ *
72
+ * Use when you need to provide or retrieve the full platform cryptography
73
+ * service from an effect's context.
74
+ *
75
+ * **Details**
76
+ *
77
+ * Providing this service supplies platform-agnostic cryptographic operations
78
+ * such as hashing, UUID generation, and secure random values.
79
+ *
80
+ * @see {@link make} for constructing a Crypto service from primitive operations
81
+ *
82
+ * @category services
83
+ * @since 4.0.0
84
+ */
85
+ const Crypto = /*#__PURE__*/ Service("effect/Crypto");
86
+ /**
87
+ * Creates a `Crypto` service from the primitive implementation, deriving the
88
+ * random generator helpers and UUID generation from those primitives.
89
+ *
90
+ * **When to use**
91
+ *
92
+ * Use to build a Crypto service for a platform integration, test layer, or
93
+ * custom runtime from primitive random-byte and digest operations.
94
+ *
95
+ * **Details**
96
+ *
97
+ * The constructor derives random numbers, booleans, integer ranges, shuffling,
98
+ * and UUID generation from `impl.randomBytes`. Digest operations delegate to
99
+ * `impl.digest`.
100
+ *
101
+ * **Gotchas**
102
+ *
103
+ * `impl.randomBytes` must return cryptographically secure bytes of the
104
+ * requested length. UUID formatting mutates the byte array returned for UUID
105
+ * generation, so the implementation should return a fresh array for each call.
106
+ *
107
+ * **Example** (Creating a Crypto service)
108
+ *
109
+ * ```ts
110
+ * import { Crypto, Effect, Layer } from "effect"
111
+ *
112
+ * const TestCrypto = Layer.succeed(
113
+ * Crypto.Crypto,
114
+ * Crypto.make({
115
+ * randomBytes: (size) => new Uint8Array(size),
116
+ * digest: (_algorithm, data) => Effect.succeed(data)
117
+ * })
118
+ * )
119
+ * ```
120
+ *
121
+ * @category constructors
122
+ * @since 4.0.0
123
+ */
124
+ const make$3 = (impl) => {
125
+ const randomBytesUnsafe = impl.randomBytes;
126
+ const randomBytes = (size) => map(validateSize("randomBytes", size), randomBytesUnsafe);
127
+ const nextDoubleUnsafe = () => {
128
+ const bytes = randomBytesUnsafe(7);
129
+ return ((bytes[0] & 31) * 2 ** 48 + bytes[1] * 2 ** 40 + bytes[2] * 2 ** 32 + bytes[3] * 2 ** 24 + bytes[4] * 2 ** 16 + bytes[5] * 2 ** 8 + bytes[6]) / 2 ** 53;
130
+ };
131
+ const nextIntUnsafe = () => Math.floor(nextDoubleUnsafe() * (Number.MAX_SAFE_INTEGER - Number.MIN_SAFE_INTEGER + 1)) + Number.MIN_SAFE_INTEGER;
132
+ return Crypto.of({
133
+ [TypeId$1]: TypeId$1,
134
+ randomBytes,
135
+ nextDoubleUnsafe,
136
+ nextIntUnsafe,
137
+ digest: impl.digest,
138
+ random: sync(() => nextDoubleUnsafe()),
139
+ randomBoolean: sync(() => nextDoubleUnsafe() > .5),
140
+ randomInt: sync(() => nextIntUnsafe()),
141
+ randomBetween: (min, max) => sync(() => nextDoubleUnsafe() * (max - min) + min),
142
+ randomIntBetween(min, max, options) {
143
+ const extra = options?.halfOpen === true ? 0 : 1;
144
+ return sync(() => {
145
+ const minInt = Math.ceil(min);
146
+ const maxInt = Math.floor(max);
147
+ return Math.floor(nextDoubleUnsafe() * (maxInt - minInt + extra)) + minInt;
148
+ });
149
+ },
150
+ randomShuffle: (elements) => sync(() => {
151
+ const buffer = Array.from(elements);
152
+ for (let i = buffer.length - 1; i >= 1; i = i - 1) {
153
+ const index = Math.min(i, Math.floor(nextDoubleUnsafe() * (i + 1)));
154
+ const value = buffer[i];
155
+ buffer[i] = buffer[index];
156
+ buffer[index] = value;
157
+ }
158
+ return buffer;
159
+ }),
160
+ randomUUIDv4: sync(() => formatUUIDv4(randomBytesUnsafe(16))),
161
+ randomUUIDv7: clockWith((clock) => succeed(formatUUIDv7(clock.currentTimeMillisUnsafe(), randomBytesUnsafe(16))))
162
+ });
163
+ };
164
+ const validateSize = (method, size) => Number.isSafeInteger(size) && size >= 0 ? succeed(size) : fail(badArgument({
165
+ module: "Crypto",
166
+ method,
167
+ description: "size must be a non-negative safe integer"
168
+ }));
169
+ const hex = (byte) => byte.toString(16).padStart(2, "0");
170
+ const formatUUID = (bytes) => {
171
+ return [
172
+ bytes.subarray(0, 4),
173
+ bytes.subarray(4, 6),
174
+ bytes.subarray(6, 8),
175
+ bytes.subarray(8, 10),
176
+ bytes.subarray(10, 16)
177
+ ].map((segment) => Array.from(segment, hex).join("")).join("-");
178
+ };
179
+ const formatUUIDv4 = (bytes) => {
180
+ bytes[6] = bytes[6] & 15 | 64;
181
+ bytes[8] = bytes[8] & 63 | 128;
182
+ return formatUUID(bytes);
183
+ };
184
+ const maxUUIDv7Timestamp = 2 ** 48 - 1;
185
+ const formatUUIDv7 = (timestampMillis, bytes) => {
186
+ const timestamp = Math.min(Math.max(0, Math.trunc(timestampMillis)), maxUUIDv7Timestamp);
187
+ bytes[0] = Math.floor(timestamp / 2 ** 40);
188
+ bytes[1] = Math.floor(timestamp / 2 ** 32) & 255;
189
+ bytes[2] = Math.floor(timestamp / 2 ** 24) & 255;
190
+ bytes[3] = Math.floor(timestamp / 2 ** 16) & 255;
191
+ bytes[4] = Math.floor(timestamp / 2 ** 8) & 255;
192
+ bytes[5] = timestamp & 255;
193
+ bytes[6] = bytes[6] & 15 | 112;
194
+ bytes[8] = bytes[8] & 63 | 128;
195
+ return formatUUID(bytes);
196
+ };
197
+ //#endregion
198
+ //#region src/auth/service.ts
199
+ var T3Auth = class extends Service()("t3cli/T3Auth") {};
200
+ //#endregion
201
+ //#region src/auth/local-base-dir.ts
202
+ const resolveLocalBaseDir = fn("resolveLocalBaseDir")(function* (input) {
203
+ const environment = yield* Environment;
204
+ return yield* resolveT3BaseDir({
205
+ layout: {
206
+ cwd: environment.cwd,
207
+ homeDir: environment.homeDir,
208
+ t3codeHome: environment.env["T3CODE_HOME"]
209
+ },
210
+ baseDir: input.baseDir
211
+ });
212
+ });
213
+ //#endregion
214
+ //#region src/auth/local-origin.ts
215
+ var T3LocalAuthOrigin = class extends Service()("t3cli/T3LocalAuthOrigin") {};
216
+ const makeT3LocalAuthOrigin = fn("makeT3LocalAuthOrigin")(function* () {
217
+ const fs = yield* FileSystem;
218
+ const path = yield* Path;
219
+ const environment = yield* Environment;
220
+ return { resolve: fn("T3LocalAuthOriginLive.resolve")(function* (input) {
221
+ const baseDir = yield* resolveLocalBaseDir({ baseDir: input?.baseDir }).pipe(provideService(Environment, environment), provideService(Path, path));
222
+ if (input?.origin !== void 0) return yield* normalizeLocalOrigin(input.origin);
223
+ const runtimeStatePath = path.join(baseDir, "userdata", "server-runtime.json");
224
+ return yield* normalizeLocalOrigin((yield* decodeAuthLocalRuntimeStateFromJson(yield* fs.readFileString(runtimeStatePath).pipe(mapError((error) => new AuthLocalError({
225
+ message: `local runtime state not found: ${runtimeStatePath}. Make sure T3 Code is running with Network access enabled, or pass --origin manually.`,
226
+ cause: error
227
+ })))).pipe(mapError((error) => new AuthLocalError({
228
+ message: "local runtime state has invalid shape",
229
+ cause: error
230
+ })))).origin);
231
+ }) };
232
+ });
233
+ const T3LocalAuthOriginLive = effect(T3LocalAuthOrigin, makeT3LocalAuthOrigin());
234
+ function normalizeLocalOrigin(origin) {
235
+ return normalizeHttpBaseUrl(origin).pipe(mapError((error) => new AuthLocalError({
236
+ message: error.message,
237
+ cause: error
238
+ })));
239
+ }
240
+ //#endregion
241
+ //#region node_modules/.pnpm/effect@4.0.0-beta.78/node_modules/effect/dist/unstable/reactivity/Reactivity.js
242
+ /**
243
+ * The `Reactivity` module provides process-local invalidation for connecting
244
+ * writes to dependent reads. It does not cache values itself; it tracks keys,
245
+ * registers query handlers, and reruns effects when matching keys are
246
+ * invalidated so queues, streams, UI subscriptions, and read models can stay
247
+ * fresh after successful writes.
248
+ *
249
+ * **Mental model**
250
+ *
251
+ * A query registers one or more keys, runs once immediately, and publishes each
252
+ * result to a queue or stream. Invalidating any registered key schedules the
253
+ * query to rerun. Mutations wrap an effect and invalidate keys only after it
254
+ * succeeds. Keys can be a flat array, or a record whose property names act as
255
+ * broad namespaces and whose ids address individual records.
256
+ *
257
+ * **Common tasks**
258
+ *
259
+ * - Provide the default in-memory service with {@link layer}.
260
+ * - Use {@link query} when callers need a queue of rerun results.
261
+ * - Use {@link stream} when downstream code should consume reruns as a stream.
262
+ * - Wrap writes with {@link mutation}, or call {@link invalidate} directly when
263
+ * invalidation is already part of the workflow.
264
+ * - Use the {@link Reactivity} service directly when many invalidations should
265
+ * be coalesced until a batch exits.
266
+ *
267
+ * **Gotchas**
268
+ *
269
+ * - The default layer is process-local; it does not coordinate invalidations
270
+ * across processes or cluster runners.
271
+ * - Non-primitive keys are matched by their `Hash.hash` value, so prefer stable
272
+ * key values over mutable objects.
273
+ * - If a query fails, its queue or stream fails with the same cause.
274
+ * - Invalidations that arrive while a query is already running coalesce into one
275
+ * follow-up run.
276
+ *
277
+ * **See also**
278
+ *
279
+ * - {@link query}, {@link stream}, {@link mutation}, and {@link invalidate}
280
+ * - {@link layer} and {@link Reactivity}
281
+ *
282
+ * @since 4.0.0
283
+ */
284
+ /**
285
+ * Service for key-based reactive invalidation.
286
+ *
287
+ * **When to use**
288
+ *
289
+ * Use to provide the invalidation service that refreshes queries, streams, and
290
+ * atoms when application keys change.
291
+ *
292
+ * **Details**
293
+ *
294
+ * The service can register handlers for keys, invalidate those keys, wrap
295
+ * mutations so successful effects invalidate keys, and turn query effects into
296
+ * queues or streams that rerun when keys are invalidated.
297
+ *
298
+ * @category services
299
+ * @since 4.0.0
300
+ */
301
+ var Reactivity = class extends Service()("effect/reactivity/Reactivity") {};
302
+ /**
303
+ * Creates an in-memory `Reactivity` service.
304
+ *
305
+ * **Details**
306
+ *
307
+ * The service tracks handlers by hashed keys and runs the registered handlers when
308
+ * matching keys are invalidated.
309
+ *
310
+ * @category constructors
311
+ * @since 4.0.0
312
+ */
313
+ const make$2 = /*#__PURE__*/ sync(() => {
314
+ const handlers = /* @__PURE__ */ new Map();
315
+ const invalidateUnsafe = (keys) => {
316
+ keysToHashes(keys, (hash) => {
317
+ const set = handlers.get(hash);
318
+ if (set === void 0) return;
319
+ set.forEach((run) => run());
320
+ });
321
+ };
322
+ const invalidate = (keys) => contextWith((services) => {
323
+ const pending = services.mapUnsafe.get(PendingInvalidation.key);
324
+ if (pending) keysToHashes(keys, (hash) => {
325
+ pending.add(hash);
326
+ });
327
+ else invalidateUnsafe(keys);
328
+ return void_;
329
+ });
330
+ const mutation = (keys, effect) => tap(effect, invalidate(keys));
331
+ const registerUnsafe = (keys, handler) => {
332
+ const resolvedKeys = [];
333
+ keysToHashes(keys, (hash) => {
334
+ resolvedKeys.push(hash);
335
+ let set = handlers.get(hash);
336
+ if (set === void 0) {
337
+ set = /* @__PURE__ */ new Set();
338
+ handlers.set(hash, set);
339
+ }
340
+ set.add(handler);
341
+ });
342
+ return () => {
343
+ for (let i = 0; i < resolvedKeys.length; i++) {
344
+ const set = handlers.get(resolvedKeys[i]);
345
+ set.delete(handler);
346
+ if (set.size === 0) handlers.delete(resolvedKeys[i]);
347
+ }
348
+ };
349
+ };
350
+ const query = (keys, effect) => gen(function* () {
351
+ const services = yield* context();
352
+ const scope = get(services, Scope);
353
+ const results = yield* make$5();
354
+ const runFork = flow(runForkWith(services), runIn(scope));
355
+ let running = false;
356
+ let pending = false;
357
+ const handleExit = (exit) => {
358
+ if (exit._tag === "Failure") failCauseUnsafe(results, exit.cause);
359
+ else offerUnsafe(results, exit.value);
360
+ if (pending) {
361
+ pending = false;
362
+ runFork(effect).addObserver(handleExit);
363
+ } else running = false;
364
+ };
365
+ function run() {
366
+ if (running) {
367
+ pending = true;
368
+ return;
369
+ }
370
+ running = true;
371
+ runFork(effect).addObserver(handleExit);
372
+ }
373
+ yield* addFinalizer(scope, sync(registerUnsafe(keys, run)));
374
+ run();
375
+ return results;
376
+ });
377
+ const stream = (tables, effect) => query(tables, effect).pipe(map(fromQueue), unwrap);
378
+ const withBatch = (effect) => suspend(() => {
379
+ const pending = /* @__PURE__ */ new Set();
380
+ return effect.pipe(provideService(PendingInvalidation, pending), onExit((_) => sync(() => {
381
+ pending.forEach((hash) => {
382
+ const set = handlers.get(hash);
383
+ if (set === void 0) return;
384
+ set.forEach((run) => run());
385
+ });
386
+ })));
387
+ });
388
+ return Reactivity.of({
389
+ mutation,
390
+ query,
391
+ stream,
392
+ invalidateUnsafe,
393
+ invalidate,
394
+ registerUnsafe,
395
+ withBatch
396
+ });
397
+ });
398
+ var PendingInvalidation = class extends Service()("effect/reactivity/Reactivity/PendingInvalidation") {};
399
+ /**
400
+ * The default layer that provides an in-memory `Reactivity` service.
401
+ *
402
+ * @category layers
403
+ * @since 4.0.0
404
+ */
405
+ const layer = /*#__PURE__*/ effect(Reactivity)(make$2);
406
+ function stringOrHash(u) {
407
+ switch (typeof u) {
408
+ case "string":
409
+ case "number":
410
+ case "bigint":
411
+ case "boolean": return String(u);
412
+ default: return hash(u);
413
+ }
414
+ }
415
+ const keysToHashes = (keys, f) => {
416
+ if (Array.isArray(keys)) {
417
+ for (let i = 0; i < keys.length; i++) f(stringOrHash(keys[i]));
418
+ return;
419
+ }
420
+ for (const key in keys) {
421
+ f(key);
422
+ const ids = keys[key];
423
+ for (let i = 0; i < ids.length; i++) f(`${key}:${stringOrHash(ids[i])}`);
424
+ }
425
+ };
426
+ //#endregion
427
+ //#region node_modules/.pnpm/effect@4.0.0-beta.78/node_modules/effect/dist/unstable/sql/Statement.js
428
+ /**
429
+ * Low-level SQL statement and fragment primitives.
430
+ *
431
+ * This module is the foundation used by SQL clients to build executable,
432
+ * parameterized SQL. It defines the {@link Statement} and {@link Fragment}
433
+ * models, the tagged-template {@link Constructor}, segment constructors for
434
+ * identifiers, parameters, literals, arrays, records, and custom dialect data,
435
+ * plus compilers that render those segments into dialect-specific SQL text and
436
+ * bind parameters.
437
+ *
438
+ * **Mental model**
439
+ *
440
+ * A statement is a sequence of {@link Segment} values. In a tagged template,
441
+ * nested fragments and known segments are spliced into that sequence, while
442
+ * ordinary interpolated values become bound parameters. A {@link Compiler}
443
+ * turns the sequence into SQL for one dialect, escaping identifiers and
444
+ * formatting placeholders for that dialect. Executing a {@link Statement} uses
445
+ * the connection acquirer captured by {@link make} and can return rows, raw
446
+ * results, streams, values, or unprepared execution paths.
447
+ *
448
+ * **Common tasks**
449
+ *
450
+ * - Build statements with a {@link Constructor} tagged template
451
+ * - Use {@link identifier} for table and column names rather than interpolating
452
+ * plain strings
453
+ * - Compose optional clauses with {@link and}, {@link or}, {@link csv}, and
454
+ * {@link join}
455
+ * - Create insert and update fragments with record helpers
456
+ * - Add custom segment handling with {@link custom} and {@link makeCompiler}
457
+ *
458
+ * **Gotchas**
459
+ *
460
+ * Bound parameters protect values, not SQL syntax. Use `literal` and `unsafe`
461
+ * only for trusted SQL text, and use identifiers for names that need escaping.
462
+ * Compiled SQL is dialect-specific and cached on the statement;
463
+ * `withoutTransform` intentionally bypasses identifier or row transforms, so
464
+ * its output can differ from normal execution.
465
+ *
466
+ * @since 4.0.0
467
+ */
468
+ const FragmentTypeId = "~effect/sql/Fragment";
469
+ /**
470
+ * Constructs a SQL `Fragment` from low-level statement segments.
471
+ *
472
+ * @category constructors
473
+ * @since 4.0.0
474
+ */
475
+ const fragment = (segments) => ({
476
+ [FragmentTypeId]: FragmentTypeId,
477
+ segments
478
+ });
479
+ /**
480
+ * Context reference for an optional current SQL statement transformer applied
481
+ * before statement execution.
482
+ *
483
+ * @category transformer
484
+ * @since 4.0.0
485
+ */
486
+ const CurrentTransformer = /*#__PURE__*/ Reference("effect/sql/CurrentTransformer", { defaultValue: constUndefined });
487
+ /**
488
+ * Returns `true` when a value is a SQL `Fragment`.
489
+ *
490
+ * @category guards
491
+ * @since 4.0.0
492
+ */
493
+ const isFragment = (u) => hasProperty(u, FragmentTypeId);
494
+ /**
495
+ * Constructs a raw SQL literal segment. The literal text is not escaped, so use
496
+ * bound parameters for untrusted values.
497
+ *
498
+ * @category constructors
499
+ * @since 4.0.0
500
+ */
501
+ const literal = (value, params) => ({
502
+ _tag: "Literal",
503
+ value,
504
+ params
505
+ });
506
+ /**
507
+ * Constructs a SQL identifier segment that will be escaped by the active
508
+ * compiler.
509
+ *
510
+ * @category constructors
511
+ * @since 4.0.0
512
+ */
513
+ const identifier = (value) => ({
514
+ _tag: "Identifier",
515
+ value
516
+ });
517
+ /**
518
+ * Constructs a bound parameter segment for a statement value.
519
+ *
520
+ * @category constructors
521
+ * @since 4.0.0
522
+ */
523
+ const parameter = (value) => ({
524
+ _tag: "Parameter",
525
+ value
526
+ });
527
+ /**
528
+ * Constructs an `ArrayHelper` segment for an array of values or fragments.
529
+ *
530
+ * @category constructors
531
+ * @since 4.0.0
532
+ */
533
+ const arrayHelper = (value) => ({
534
+ _tag: "ArrayHelper",
535
+ value
536
+ });
537
+ const RecordInsertHelperProto = {
538
+ _tag: "RecordInsertHelper",
539
+ returning(sql) {
540
+ const self = Object.create(Object.getPrototypeOf(this));
541
+ Object.assign(self, this, { returningIdentifier: sql });
542
+ return self;
543
+ }
544
+ };
545
+ /**
546
+ * Constructs a `RecordInsertHelper` from one or more row objects.
547
+ *
548
+ * @category constructors
549
+ * @since 4.0.0
550
+ */
551
+ const recordInsertHelper = (value) => Object.assign(Object.create(RecordInsertHelperProto), {
552
+ value,
553
+ returningIdentifier: void 0
554
+ });
555
+ const RecordUpdateHelperProto = {
556
+ ...RecordInsertHelperProto,
557
+ _tag: "RecordUpdateHelper"
558
+ };
559
+ /**
560
+ * Constructs a `RecordUpdateHelper` for multi-row update compilation using the
561
+ * provided alias.
562
+ *
563
+ * @category constructors
564
+ * @since 4.0.0
565
+ */
566
+ const recordUpdateHelper = (value, alias) => Object.assign(Object.create(RecordUpdateHelperProto), {
567
+ value,
568
+ alias,
569
+ returningIdentifier: void 0
570
+ });
571
+ const RecordUpdateHelperSingleProto = {
572
+ ...RecordInsertHelperProto,
573
+ _tag: "RecordUpdateHelperSingle"
574
+ };
575
+ /**
576
+ * Constructs a `RecordUpdateHelperSingle` from a record and a list of columns
577
+ * to omit from the update.
578
+ *
579
+ * @category constructors
580
+ * @since 4.0.0
581
+ */
582
+ const recordUpdateHelperSingle = (value, omit) => Object.assign(Object.create(RecordUpdateHelperSingleProto), {
583
+ value,
584
+ omit,
585
+ returningIdentifier: void 0
586
+ });
587
+ /**
588
+ * Creates a cached SQL statement constructor from a connection acquirer,
589
+ * compiler, tracing attributes, and optional row transformation function.
590
+ *
591
+ * @category constructors
592
+ * @since 4.0.0
593
+ */
594
+ const make$1 = (acquirer, compiler, spanAttributes, transformRows) => {
595
+ const cache = transformRows === void 0 ? constructorCache.noTransforms : constructorCache.transforms;
596
+ if (cache.has(acquirer)) return cache.get(acquirer);
597
+ const self = Object.assign(function sql(strings, ...args) {
598
+ if (typeof strings === "string") return identifier(strings);
599
+ else if (Array.isArray(strings) && "raw" in strings) return statement(acquirer, compiler, strings, args, spanAttributes, transformRows);
600
+ throw "absurd";
601
+ }, {
602
+ unsafe(sql, params) {
603
+ return makeUnsafe([literal(sql, params)], acquirer, compiler, spanAttributes, transformRows);
604
+ },
605
+ literal(sql) {
606
+ return fragment([literal(sql)]);
607
+ },
608
+ in: in_,
609
+ insert(value) {
610
+ return recordInsertHelper(Array.isArray(value) ? value : [value]);
611
+ },
612
+ update(value, omit) {
613
+ return recordUpdateHelperSingle(value, omit ?? []);
614
+ },
615
+ updateValues(value, alias) {
616
+ return recordUpdateHelper(value, alias);
617
+ },
618
+ and,
619
+ or,
620
+ csv,
621
+ join,
622
+ onDialect(options) {
623
+ return options[compiler.dialect]();
624
+ },
625
+ onDialectOrElse(options) {
626
+ return options[compiler.dialect] !== void 0 ? options[compiler.dialect]() : options.orElse();
627
+ }
628
+ });
629
+ cache.set(acquirer, self);
630
+ return self;
631
+ };
632
+ const constructorCache = {
633
+ transforms: /*#__PURE__*/ new WeakMap(),
634
+ noTransforms: /*#__PURE__*/ new WeakMap()
635
+ };
636
+ /**
637
+ * Builds a `Statement` from template strings and arguments, preserving
638
+ * fragments and helper segments while converting ordinary interpolated values
639
+ * into bound parameters.
640
+ *
641
+ * @category constructors
642
+ * @since 4.0.0
643
+ */
644
+ const statement = (acquirer, compiler, strings, args, spanAttributes, transformRows) => {
645
+ const segments = strings[0].length > 0 ? [literal(strings[0])] : [];
646
+ for (let i = 0; i < args.length; i++) {
647
+ const arg = args[i];
648
+ if (isFragment(arg)) segments.push(...arg.segments);
649
+ else if (isSegment(arg)) segments.push(arg);
650
+ else segments.push(parameter(arg));
651
+ if (strings[i + 1].length > 0) segments.push(literal(strings[i + 1]));
652
+ }
653
+ return makeUnsafe(segments, acquirer, compiler, spanAttributes, transformRows);
654
+ };
655
+ /**
656
+ * Creates a helper that joins SQL clauses with a literal separator, optionally
657
+ * wrapping multiple clauses in parentheses and using a fallback for an empty
658
+ * list.
659
+ *
660
+ * @category constructors
661
+ * @since 4.0.0
662
+ */
663
+ function join(lit, addParens = true, fallback = "") {
664
+ const literalStatement = literal(lit);
665
+ const fallbackFragment = fragment([literal(fallback)]);
666
+ return (clauses) => {
667
+ if (clauses.length === 0) return fallbackFragment;
668
+ else if (clauses.length === 1) return fragment(convertLiteralOrFragment(clauses[0]));
669
+ const segments = [];
670
+ if (addParens) segments.push(literal("("));
671
+ segments.push.apply(segments, convertLiteralOrFragment(clauses[0]));
672
+ for (let i = 1; i < clauses.length; i++) {
673
+ segments.push(literalStatement);
674
+ segments.push.apply(segments, convertLiteralOrFragment(clauses[i]));
675
+ }
676
+ if (addParens) segments.push(literal(")"));
677
+ return fragment(segments);
678
+ };
679
+ }
680
+ /**
681
+ * Combines clauses with `AND`, parenthesizing multiple clauses and returning
682
+ * `1=1` when the list is empty.
683
+ *
684
+ * @category constructors
685
+ * @since 4.0.0
686
+ */
687
+ const and = /*#__PURE__*/ join(" AND ", true, "1=1");
688
+ /**
689
+ * Combines clauses with `OR`, parenthesizing multiple clauses and returning
690
+ * `1=1` when the list is empty.
691
+ *
692
+ * @category constructors
693
+ * @since 4.0.0
694
+ */
695
+ const or = /*#__PURE__*/ join(" OR ", true, "1=1");
696
+ /**
697
+ * Creates a comma-separated SQL fragment from values, optionally adding a
698
+ * prefix, and returns an empty fragment when no values are provided.
699
+ *
700
+ * @category constructors
701
+ * @since 4.0.0
702
+ */
703
+ const csv = function(...args) {
704
+ if (args[args.length - 1].length === 0) return emptyFragment;
705
+ if (args.length === 1) return csvRaw(args[0]);
706
+ return fragment([literal(`${args[0]} `), ...csvRaw(args[1]).segments]);
707
+ };
708
+ const csvRaw = /*#__PURE__*/ join(",", false);
709
+ const emptyFragment = /*#__PURE__*/ fragment([/*#__PURE__*/ literal("")]);
710
+ /**
711
+ * Creates a dialect-specific SQL `Compiler` from rendering callbacks.
712
+ *
713
+ * @category compiler
714
+ * @since 4.0.0
715
+ */
716
+ const makeCompiler = (options) => {
717
+ const self = Object.create(CompilerProto);
718
+ self.options = options;
719
+ self.dialect = options.dialect;
720
+ self.disableTransforms = false;
721
+ return self;
722
+ };
723
+ const statementCacheSymbol = /*#__PURE__*/ Symbol.for("effect/unstable/sql/Statement/statementCache");
724
+ const statementCacheNoTransformSymbol = /*#__PURE__*/ Symbol.for("effect/unstable/sql/Statement/statementCacheNoTransform");
725
+ const CompilerProto = {
726
+ compile(statement, withoutTransform = false, placeholderOverride) {
727
+ const opts = this.options;
728
+ withoutTransform = withoutTransform || this.disableTransforms;
729
+ const cacheSymbol = withoutTransform ? statementCacheNoTransformSymbol : statementCacheSymbol;
730
+ if (cacheSymbol in statement) return statement[cacheSymbol];
731
+ const segments = statement.segments;
732
+ const len = segments.length;
733
+ let sql = "";
734
+ const binds = [];
735
+ let placeholderCount = 0;
736
+ const placeholder = placeholderOverride ?? ((u) => opts.placeholder(++placeholderCount, u));
737
+ const placeholderNoIncrement = (u) => opts.placeholder(placeholderCount, u);
738
+ const placeholders = makePlaceholdersArray(placeholder);
739
+ for (let i = 0; i < len; i++) {
740
+ const segment = segments[i];
741
+ switch (segment._tag) {
742
+ case "Literal":
743
+ sql += segment.value;
744
+ if (segment.params) binds.push.apply(binds, segment.params);
745
+ break;
746
+ case "Identifier":
747
+ sql += opts.onIdentifier(segment.value, withoutTransform);
748
+ break;
749
+ case "Parameter":
750
+ sql += placeholder(segment.value);
751
+ binds.push(segment.value);
752
+ break;
753
+ case "ArrayHelper":
754
+ sql += `(${placeholders(segment.value)})`;
755
+ binds.push.apply(binds, segment.value);
756
+ break;
757
+ case "RecordInsertHelper": {
758
+ const keys = Object.keys(segment.value[0]);
759
+ if (opts.onInsert) {
760
+ const values = new Array(segment.value.length);
761
+ let placeholders = "";
762
+ for (let i = 0; i < segment.value.length; i++) {
763
+ const row = new Array(keys.length);
764
+ values[i] = row;
765
+ placeholders += i === 0 ? "(" : ",(";
766
+ for (let j = 0; j < keys.length; j++) {
767
+ const key = keys[j];
768
+ const value = segment.value[i][key];
769
+ row[j] = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
770
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
771
+ }
772
+ placeholders += ")";
773
+ }
774
+ const [s, b] = opts.onInsert(keys.map((_) => opts.onIdentifier(_, withoutTransform)), placeholders, values, typeof segment.returningIdentifier === "string" ? [segment.returningIdentifier, []] : segment.returningIdentifier ? this.compile(segment.returningIdentifier, withoutTransform, placeholder) : void 0);
775
+ sql += s;
776
+ binds.push.apply(binds, b);
777
+ } else {
778
+ let placeholders = "";
779
+ for (let i = 0; i < segment.value.length; i++) {
780
+ placeholders += i === 0 ? "(" : ",(";
781
+ for (let j = 0; j < keys.length; j++) {
782
+ const value = segment.value[i][keys[j]];
783
+ const primitive = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
784
+ binds.push(primitive);
785
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
786
+ }
787
+ placeholders += ")";
788
+ }
789
+ sql += `${generateColumns(keys, opts.onIdentifier, withoutTransform)} VALUES ${placeholders}`;
790
+ if (typeof segment.returningIdentifier === "string") sql += ` RETURNING ${segment.returningIdentifier}`;
791
+ else if (segment.returningIdentifier) {
792
+ sql += " RETURNING ";
793
+ const [s, b] = this.compile(segment.returningIdentifier, withoutTransform, placeholder);
794
+ sql += s;
795
+ binds.push.apply(binds, b);
796
+ }
797
+ }
798
+ break;
799
+ }
800
+ case "RecordUpdateHelperSingle": {
801
+ let keys = Object.keys(segment.value);
802
+ if (segment.omit.length > 0) keys = keys.filter((key) => !segment.omit.includes(key));
803
+ if (opts.onRecordUpdateSingle) {
804
+ const [s, b] = opts.onRecordUpdateSingle(keys.map((_) => opts.onIdentifier(_, withoutTransform)), keys.map((key) => extractPrimitive(segment.value[key], opts.onCustom, placeholderNoIncrement, withoutTransform)), typeof segment.returningIdentifier === "string" ? [segment.returningIdentifier, []] : segment.returningIdentifier ? this.compile(segment.returningIdentifier, withoutTransform, placeholder) : void 0);
805
+ sql += s;
806
+ binds.push.apply(binds, b);
807
+ } else {
808
+ for (let i = 0, len = keys.length; i < len; i++) {
809
+ const column = opts.onIdentifier(keys[i], withoutTransform);
810
+ if (i === 0) sql += `${column} = ${placeholder(segment.value[keys[i]])}`;
811
+ else sql += `, ${column} = ${placeholder(segment.value[keys[i]])}`;
812
+ binds.push(extractPrimitive(segment.value[keys[i]], opts.onCustom, placeholderNoIncrement, withoutTransform));
813
+ }
814
+ if (typeof segment.returningIdentifier === "string") if (this.dialect === "mssql") sql += ` OUTPUT ${segment.returningIdentifier === "*" ? "INSERTED.*" : segment.returningIdentifier}`;
815
+ else sql += ` RETURNING ${segment.returningIdentifier}`;
816
+ else if (segment.returningIdentifier) {
817
+ sql += this.dialect === "mssql" ? " OUTPUT " : " RETURNING ";
818
+ const [s, b] = this.compile(segment.returningIdentifier, withoutTransform, placeholder);
819
+ sql += s;
820
+ binds.push.apply(binds, b);
821
+ }
822
+ }
823
+ break;
824
+ }
825
+ case "RecordUpdateHelper": {
826
+ const keys = Object.keys(segment.value[0]);
827
+ const values = new Array(segment.value.length);
828
+ let placeholders = "";
829
+ for (let i = 0; i < segment.value.length; i++) {
830
+ const row = new Array(keys.length);
831
+ values[i] = row;
832
+ placeholders += i === 0 ? "(" : ",(";
833
+ for (let j = 0; j < keys.length; j++) {
834
+ const key = keys[j];
835
+ const value = segment.value[i][key];
836
+ row[j] = extractPrimitive(value, opts.onCustom, placeholderNoIncrement, withoutTransform);
837
+ placeholders += j === 0 ? placeholder(value) : `,${placeholder(value)}`;
838
+ }
839
+ placeholders += ")";
840
+ }
841
+ const [s, b] = opts.onRecordUpdate(placeholders, segment.alias, generateColumns(keys, opts.onIdentifier, withoutTransform), values, typeof segment.returningIdentifier === "string" ? [segment.returningIdentifier, []] : segment.returningIdentifier ? this.compile(segment.returningIdentifier, withoutTransform, placeholder) : void 0);
842
+ sql += s;
843
+ binds.push.apply(binds, b);
844
+ break;
845
+ }
846
+ case "Custom": {
847
+ const [s, b] = opts.onCustom(segment, placeholder, withoutTransform);
848
+ sql += s;
849
+ binds.push.apply(binds, b);
850
+ break;
851
+ }
852
+ }
853
+ }
854
+ const result = [sql, binds];
855
+ if (placeholderOverride !== void 0) return result;
856
+ return statement[cacheSymbol] = result;
857
+ },
858
+ get withoutTransform() {
859
+ const self = Object.create(CompilerProto);
860
+ Object.assign(self, this, { disableTransforms: true });
861
+ return self;
862
+ }
863
+ };
864
+ /**
865
+ * Creates a SQLite compiler that uses `?` placeholders and quoted identifiers,
866
+ * optionally transforming identifier names before escaping.
867
+ *
868
+ * @category compiler
869
+ * @since 4.0.0
870
+ */
871
+ const makeCompilerSqlite = (transform) => makeCompiler({
872
+ dialect: "sqlite",
873
+ placeholder(_) {
874
+ return "?";
875
+ },
876
+ onIdentifier: transform ? function(value, withoutTransform) {
877
+ return withoutTransform ? escapeSqlite(value) : escapeSqlite(transform(value));
878
+ } : escapeSqlite,
879
+ onRecordUpdate() {
880
+ return ["", []];
881
+ },
882
+ onCustom() {
883
+ return ["", []];
884
+ }
885
+ });
886
+ /**
887
+ * Creates an identifier escaping function that wraps names in the given
888
+ * delimiter, doubles delimiter characters, and escapes dots between identifier
889
+ * parts.
890
+ *
891
+ * @category constructors
892
+ * @since 4.0.0
893
+ */
894
+ function defaultEscape(c) {
895
+ const re = new RegExp(c, "g");
896
+ const double = c + c;
897
+ const dot = c + "." + c;
898
+ return function(str) {
899
+ return c + str.replace(re, double).replace(/\./g, dot) + c;
900
+ };
901
+ }
902
+ /**
903
+ * Builds value, object, and row-array transformers that rename object keys with
904
+ * the supplied function and optionally recurse into nested object arrays.
905
+ *
906
+ * @category transforming
907
+ * @since 4.0.0
908
+ */
909
+ const defaultTransforms = (transformer, nested = true) => {
910
+ const transformValue = (value) => {
911
+ if (Array.isArray(value)) {
912
+ if (value.length === 0 || value[0].constructor !== Object) return value;
913
+ return array(value);
914
+ } else if (value?.constructor === Object) return transformObject(value);
915
+ return value;
916
+ };
917
+ const transformObject = (obj) => {
918
+ const newObj = {};
919
+ for (const key in obj) newObj[transformer(key)] = transformValue(obj[key]);
920
+ return newObj;
921
+ };
922
+ const transformArrayNested = (rows) => {
923
+ const newRows = new Array(rows.length);
924
+ for (let i = 0, len = rows.length; i < len; i++) {
925
+ const row = rows[i];
926
+ if (Array.isArray(row)) newRows[i] = transformArrayNested(row);
927
+ else {
928
+ const obj = {};
929
+ for (const key in row) obj[transformer(key)] = transformValue(row[key]);
930
+ newRows[i] = obj;
931
+ }
932
+ }
933
+ return newRows;
934
+ };
935
+ const transformArray = (rows) => {
936
+ const newRows = new Array(rows.length);
937
+ for (let i = 0, len = rows.length; i < len; i++) {
938
+ const row = rows[i];
939
+ if (Array.isArray(row)) newRows[i] = transformArray(row);
940
+ else {
941
+ const obj = {};
942
+ for (const key in row) obj[transformer(key)] = row[key];
943
+ newRows[i] = obj;
944
+ }
945
+ }
946
+ return newRows;
947
+ };
948
+ const array = nested ? transformArrayNested : transformArray;
949
+ return {
950
+ value: transformValue,
951
+ object: transformObject,
952
+ array
953
+ };
954
+ };
955
+ const ATTR_DB_OPERATION_NAME = "db.operation.name";
956
+ const ATTR_DB_QUERY_TEXT = "db.query.text";
957
+ const makeUnsafe = (segments, acquirer, compiler, spanAttributes, transformRows) => {
958
+ const self = Object.create(StatementProto);
959
+ self.segments = segments;
960
+ self.acquirer = acquirer;
961
+ self.compiler = compiler;
962
+ self.spanAttributes = spanAttributes;
963
+ self.transformRows = transformRows;
964
+ return self;
965
+ };
966
+ const StatementProto = {
967
+ .../*#__PURE__*/ Prototype({
968
+ label: "Statement",
969
+ evaluate(fiber) {
970
+ const span = makeSpanUnsafe(fiber, "sql.execute", { kind: "client" });
971
+ const clock = fiber.getRef(Clock);
972
+ const timingEnabled = fiber.getRef(TracerTimingEnabled);
973
+ return onExit(this.withConnectionSpan("execute", (connection, sql, params) => connection.execute(sql, params, this.transformRows), false, span), (exit) => endSpan(span, exit, clock, timingEnabled));
974
+ }
975
+ }),
976
+ [FragmentTypeId]: FragmentTypeId,
977
+ withConnection(operation, f, withoutTransform = false) {
978
+ return useSpan("sql.execute", { kind: "client" }, (span) => this.withConnectionSpan(operation, f, withoutTransform, span));
979
+ },
980
+ withConnectionSpan(operation, f, withoutTransform, span) {
981
+ return withStatement(this, span, (statement) => {
982
+ const [sql, params] = statement.compile(withoutTransform);
983
+ for (const [key, value] of this.spanAttributes) span.attribute(key, value);
984
+ span.attribute(ATTR_DB_OPERATION_NAME, operation);
985
+ span.attribute(ATTR_DB_QUERY_TEXT, sql);
986
+ return scoped(flatMap(this.acquirer, (_) => f(_, sql, params)));
987
+ });
988
+ },
989
+ get withoutTransform() {
990
+ return this.withConnection("executeWithoutTransform", (connection, sql, params) => connection.execute(sql, params, void 0), true);
991
+ },
992
+ get raw() {
993
+ return this.withConnection("executeRaw", (connection, sql, params) => connection.executeRaw(sql, params), true);
994
+ },
995
+ get stream() {
996
+ const self = this;
997
+ return unwrap(flatMap(makeSpanScoped("sql.execute", { kind: "client" }), (span) => withStatement(self, span, (statement) => {
998
+ const [sql, params] = statement.compile();
999
+ for (const [key, value] of self.spanAttributes) span.attribute(key, value);
1000
+ span.attribute(ATTR_DB_OPERATION_NAME, "executeStream");
1001
+ span.attribute(ATTR_DB_QUERY_TEXT, sql);
1002
+ return map(self.acquirer, (_) => _.executeStream(sql, params, self.transformRows));
1003
+ })));
1004
+ },
1005
+ get values() {
1006
+ return this.withConnection("executeValues", (connection, sql, params) => connection.executeValues(sql, params));
1007
+ },
1008
+ get unprepared() {
1009
+ const self = this;
1010
+ return self.withConnection("executeUnprepared", (connection, sql, params) => connection.executeUnprepared(sql, params, self.transformRows));
1011
+ },
1012
+ compile(withoutTransform) {
1013
+ return this.compiler.compile(this, withoutTransform ?? false);
1014
+ },
1015
+ toJSON() {
1016
+ const [sql, params] = this.compile();
1017
+ return {
1018
+ _id: "Statement",
1019
+ segments: this.segments,
1020
+ sql,
1021
+ params
1022
+ };
1023
+ }
1024
+ };
1025
+ const withStatement = (self, span, f) => withFiber((fiber) => {
1026
+ const transform = fiber.getRef(CurrentTransformer);
1027
+ if (transform === void 0) return f(self);
1028
+ return flatMap(transform(self, make$1(self.acquirer, self.compiler, self.spanAttributes, self.transformRows), fiber, span), f);
1029
+ });
1030
+ const isSegment = (u) => {
1031
+ if (!hasProperty(u, "_tag")) return false;
1032
+ switch (u._tag) {
1033
+ case "Literal":
1034
+ case "Parameter":
1035
+ case "ArrayHelper":
1036
+ case "RecordInsertHelper":
1037
+ case "RecordUpdateHelper":
1038
+ case "RecordUpdateHelperSingle":
1039
+ case "Identifier":
1040
+ case "Custom": return true;
1041
+ default: return false;
1042
+ }
1043
+ };
1044
+ function convertLiteralOrFragment(clause) {
1045
+ if (typeof clause === "string") return [literal(clause)];
1046
+ return clause.segments;
1047
+ }
1048
+ const makePlaceholdersArray = (evaluate) => (values) => {
1049
+ if (values.length === 0) return "";
1050
+ let result = evaluate(values[0]);
1051
+ for (let i = 1; i < values.length; i++) result += `,${evaluate(values[i])}`;
1052
+ return result;
1053
+ };
1054
+ const generateColumns = (keys, escape, withoutTransform) => {
1055
+ if (keys.length === 0) return "()";
1056
+ let str = `(${escape(keys[0], withoutTransform)}`;
1057
+ for (let i = 1; i < keys.length; i++) str += `,${escape(keys[i], withoutTransform)}`;
1058
+ return str + ")";
1059
+ };
1060
+ const extractPrimitive = (value, onCustom, placeholder, withoutTransform) => {
1061
+ if (value === void 0) return null;
1062
+ else if (isFragment(value)) {
1063
+ const head = value.segments[0];
1064
+ if (head._tag === "Custom") return onCustom(head, placeholder, withoutTransform)[1][0] ?? null;
1065
+ else if (head._tag === "Parameter") return head.value;
1066
+ return null;
1067
+ }
1068
+ return value;
1069
+ };
1070
+ const escapeSqlite = /*#__PURE__*/ defaultEscape("\"");
1071
+ function in_() {
1072
+ if (arguments.length === 1) return arrayHelper(arguments[0]);
1073
+ const column = arguments[0];
1074
+ const values = arguments[1];
1075
+ return values.length === 0 ? neverFragment : fragment([
1076
+ identifier(column),
1077
+ literal(" IN "),
1078
+ arrayHelper(values)
1079
+ ]);
1080
+ }
1081
+ const neverFragment = /*#__PURE__*/ fragment([/*#__PURE__*/ literal("1=0")]);
1082
+ //#endregion
1083
+ //#region node_modules/.pnpm/effect@4.0.0-beta.78/node_modules/effect/dist/unstable/sql/SqlClient.js
1084
+ /**
1085
+ * Defines the `SqlClient` service, the central runtime entry point for Effect's
1086
+ * unstable SQL support.
1087
+ *
1088
+ * A `SqlClient` combines the tagged-template statement constructor with a
1089
+ * scoped connection acquirer, dialect compiler, tracing attributes, optional row
1090
+ * transforms, reactive query helpers, and transaction management. Applications
1091
+ * typically consume it from `Context` to build parameterized queries, stream
1092
+ * rows, run raw driver operations, reserve a connection for lower-level work, or
1093
+ * wrap several query effects in `withTransaction`.
1094
+ *
1095
+ * Transactions are tracked through a per-client context service. Top-level
1096
+ * transactions acquire the configured transaction connection and issue the
1097
+ * dialect's begin/commit/rollback SQL; nested transactions reuse that
1098
+ * connection and rely on dialect-provided savepoint SQL. A query only joins a
1099
+ * transaction when it is run with the same client service, so avoid mixing
1100
+ * clients or manually reserved connections when atomicity matters. Dialect
1101
+ * integrations are also responsible for the compiler and transaction
1102
+ * statements, which means placeholder syntax, identifier escaping, row
1103
+ * transforms, savepoint support, and unprepared/raw statement behavior can
1104
+ * differ by database.
1105
+ *
1106
+ * @since 4.0.0
1107
+ */
1108
+ const TypeId = "~effect/sql/SqlClient";
1109
+ /**
1110
+ * Service tag for the active SQL client service.
1111
+ *
1112
+ * **When to use**
1113
+ *
1114
+ * Use to access or provide the SQL client used to build statements, stream
1115
+ * rows, reserve connections, and run transactions.
1116
+ *
1117
+ * @category services
1118
+ * @since 4.0.0
1119
+ */
1120
+ const SqlClient = /*#__PURE__*/ Service("effect/sql/SqlClient");
1121
+ let clientIdCounter = 0;
1122
+ /**
1123
+ * Constructs a `SqlClient` from connection acquirers, a compiler, transaction
1124
+ * commands, tracing attributes, optional row transforms, and reactive query
1125
+ * integration.
1126
+ *
1127
+ * @category constructors
1128
+ * @since 4.0.0
1129
+ */
1130
+ const make = /*#__PURE__*/ fnUntraced(function* (options) {
1131
+ const transactionService = options.transactionService ?? TransactionConnection(clientIdCounter++);
1132
+ const getConnection = flatMap(serviceOption(transactionService), match({
1133
+ onNone: () => options.acquirer,
1134
+ onSome: ([conn]) => succeed(conn)
1135
+ }));
1136
+ const beginTransaction = options.beginTransaction ?? "BEGIN";
1137
+ const commit = options.commit ?? "COMMIT";
1138
+ const savepoint = options.savepoint ?? ((name) => `SAVEPOINT ${name}`);
1139
+ const rollback = options.rollback ?? "ROLLBACK";
1140
+ const rollbackSavepoint = options.rollbackSavepoint ?? ((name) => `ROLLBACK TO SAVEPOINT ${name}`);
1141
+ const transactionAcquirer = options.transactionAcquirer ?? options.acquirer;
1142
+ const withTransaction = makeWithTransaction({
1143
+ transactionService,
1144
+ spanAttributes: options.spanAttributes,
1145
+ acquireConnection: flatMap(make$4(), (scope) => map(provide(transactionAcquirer, scope), (conn) => [scope, conn])),
1146
+ begin: (conn) => conn.executeUnprepared(beginTransaction, [], void 0),
1147
+ savepoint: (conn, id) => conn.executeUnprepared(savepoint(`effect_sql_${id}`), [], void 0),
1148
+ commit: (conn) => conn.executeUnprepared(commit, [], void 0),
1149
+ rollback: (conn) => conn.executeUnprepared(rollback, [], void 0),
1150
+ rollbackSavepoint: (conn, id) => conn.executeUnprepared(rollbackSavepoint(`effect_sql_${id}`), [], void 0)
1151
+ });
1152
+ const reactivity = yield* Reactivity;
1153
+ const client = Object.assign(make$1(getConnection, options.compiler, options.spanAttributes, options.transformRows), {
1154
+ [TypeId]: TypeId,
1155
+ safe: void 0,
1156
+ withTransaction,
1157
+ transactionService,
1158
+ reserve: transactionAcquirer,
1159
+ withoutTransforms() {
1160
+ if (options.transformRows === void 0) return this;
1161
+ const statement = make$1(getConnection, options.compiler.withoutTransform, options.spanAttributes, void 0);
1162
+ const client = Object.assign(statement, {
1163
+ ...this,
1164
+ ...statement
1165
+ });
1166
+ client.safe = client;
1167
+ client.withoutTransforms = () => client;
1168
+ return client;
1169
+ },
1170
+ reactive: options.reactiveQueue ? (keys, effect) => options.reactiveQueue(keys, effect).pipe(map(fromQueue), unwrap) : reactivity.stream,
1171
+ reactiveMailbox: options.reactiveQueue ?? reactivity.query
1172
+ });
1173
+ client.safe = client;
1174
+ return client;
1175
+ });
1176
+ /**
1177
+ * Builds a transaction wrapper that begins top-level transactions, uses
1178
+ * savepoints for nested transactions, commits on success, and rolls back on
1179
+ * failure or interruption.
1180
+ *
1181
+ * @category transactions
1182
+ * @since 4.0.0
1183
+ */
1184
+ const makeWithTransaction = (options) => (effect) => {
1185
+ return uninterruptibleMask((restore) => useSpan("sql.transaction", { kind: "client" }, (span) => withFiber((fiber) => {
1186
+ for (const [key, value] of options.spanAttributes) span.attribute(key, value);
1187
+ const services = fiber.context;
1188
+ const clock = fiber.getRef(Clock);
1189
+ const connOption = getOption(services, options.transactionService);
1190
+ const conn = connOption._tag === "Some" ? succeed([void 0, connOption.value[0]]) : options.acquireConnection;
1191
+ const id = connOption._tag === "Some" ? connOption.value[1] + 1 : 0;
1192
+ return flatMap(conn, ([scope, conn]) => (id === 0 ? options.begin(conn) : options.savepoint(conn, id)).pipe(flatMap(() => provideContext(restore(effect), mutate(services, (services) => services.pipe(add(options.transactionService, [conn, id]), add(ParentSpan, span))))), exit, flatMap((exit) => {
1193
+ let effect;
1194
+ if (isSuccess(exit)) if (id === 0) {
1195
+ span.event("db.transaction.commit", clock.currentTimeNanosUnsafe());
1196
+ effect = orDie(options.commit(conn));
1197
+ } else {
1198
+ span.event("db.transaction.savepoint", clock.currentTimeNanosUnsafe());
1199
+ effect = void_;
1200
+ }
1201
+ else {
1202
+ span.event("db.transaction.rollback", clock.currentTimeNanosUnsafe());
1203
+ effect = orDie(id > 0 ? options.rollbackSavepoint(conn, id) : options.rollback(conn));
1204
+ }
1205
+ return flatMap(scope !== void 0 ? ensuring(effect, close(scope, exit)) : effect, () => exit);
1206
+ })));
1207
+ })));
1208
+ };
1209
+ /**
1210
+ * Creates a unique context service tag for the active transaction connection of
1211
+ * a specific SQL client.
1212
+ *
1213
+ * @category services
1214
+ * @since 4.0.0
1215
+ */
1216
+ const TransactionConnection = (clientId) => Service(`effect/sql/SqlClient/TransactionConnection/${clientId}`);
1217
+ //#endregion
1218
+ //#region src/sql/service.ts
1219
+ var SqlClientFactory = class extends Service()("t3cli/SqlClientFactory") {};
1220
+ //#endregion
1221
+ //#region src/auth/local-token.ts
1222
+ var T3LocalAuthToken = class extends Service()("t3cli/T3LocalAuthToken") {};
1223
+ const makeT3LocalAuthToken = fn("makeT3LocalAuthToken")(function* () {
1224
+ const fs = yield* FileSystem;
1225
+ const path = yield* Path;
1226
+ const environment = yield* Environment;
1227
+ const crypto = yield* Crypto;
1228
+ const sqlClientFactory = yield* SqlClientFactory;
1229
+ function readSigningSecret(secretPath) {
1230
+ return fs.readFile(secretPath).pipe(map((bytes) => Uint8Array.from(bytes)), catchFilter(reason("PlatformError", "NotFound"), () => succeed(void 0)), mapError((error) => new AuthLocalSecretError({
1231
+ message: `failed to read signing secret: ${secretPath}`,
1232
+ cause: error
1233
+ })));
1234
+ }
1235
+ const readRequiredSigningSecret = fn("readRequiredSigningSecret")(function* (secretsDir) {
1236
+ const secretPath = path.join(secretsDir, `${signingSecretName}.bin`);
1237
+ const secret = yield* readSigningSecret(secretPath);
1238
+ if (secret === void 0) return yield* fail(new AuthLocalSecretError({ message: `local signing secret not found: ${secretPath}` }));
1239
+ return secret;
1240
+ });
1241
+ const hmacSha256 = (secret, payload) => gen(function* () {
1242
+ const key = secret.byteLength > sha256BlockSize ? yield* crypto.digest("SHA-256", secret) : secret;
1243
+ const block = new Uint8Array(sha256BlockSize);
1244
+ block.set(key);
1245
+ const outerPad = block.map((byte) => byte ^ 92);
1246
+ const innerPad = block.map((byte) => byte ^ 54);
1247
+ const innerHash = yield* crypto.digest("SHA-256", concatBytes(innerPad, payload));
1248
+ return yield* crypto.digest("SHA-256", concatBytes(outerPad, innerHash));
1249
+ });
1250
+ const signPayload = (payload, secret) => hmacSha256(secret, new TextEncoder().encode(payload)).pipe(map(encodeBase64Url), mapError((error) => new AuthLocalSigningError({
1251
+ operation: "sign",
1252
+ message: "failed to sign local auth payload",
1253
+ cause: error
1254
+ })));
1255
+ function openAuthDatabase(dbPath) {
1256
+ return sqlClientFactory.sqliteClient({ filename: dbPath }).pipe(catchTag("SqlError", (error) => fail(new AuthLocalDatabaseError({
1257
+ operation: "connect",
1258
+ message: error.message
1259
+ }))));
1260
+ }
1261
+ const provideAuthDatabase = (dbPath) => (effect) => gen(function* () {
1262
+ const sql = yield* openAuthDatabase(dbPath);
1263
+ return yield* effect.pipe(provideService(SqlClient, sql));
1264
+ }).pipe(scoped);
1265
+ const issueLocalDatabaseSession = fn("issueLocalDatabaseSession")(function* (input) {
1266
+ const secret = yield* readRequiredSigningSecret(input.secretsDir);
1267
+ const issuedAt = yield* now;
1268
+ const expiresAt = add$1(issuedAt, { milliseconds: defaultSessionTtlMs });
1269
+ const sessionId = yield* crypto.randomUUIDv4.pipe(map((id) => AuthSessionId.make(id)), mapError((error) => new AuthLocalSecretError({
1270
+ message: "failed to generate auth session id",
1271
+ cause: error
1272
+ })));
1273
+ const scopes = [...AuthAdministrativeScopes];
1274
+ const claims = {
1275
+ v: 1,
1276
+ kind: "session",
1277
+ sid: sessionId,
1278
+ sub: input.subject,
1279
+ scopes,
1280
+ method: "bearer-access-token",
1281
+ iat: toEpochMillis(issuedAt),
1282
+ exp: toEpochMillis(expiresAt)
1283
+ };
1284
+ const encodedPayload = encodeBase64Url(JSON.stringify(claims));
1285
+ const token = `${encodedPayload}.${yield* signPayload(encodedPayload, secret)}`;
1286
+ yield* insertAuthSession({
1287
+ sessionId,
1288
+ subject: input.subject,
1289
+ scopes,
1290
+ label: input.label,
1291
+ issuedAt: formatIso(issuedAt),
1292
+ expiresAt: formatIso(expiresAt)
1293
+ }).pipe(provideAuthDatabase(input.dbPath), catchTag("SqlError", (error) => fail(new AuthLocalDatabaseError({
1294
+ operation: isTagged(error.reason, "ConnectionError") ? "connect" : "query",
1295
+ message: error.message
1296
+ }))));
1297
+ return {
1298
+ token,
1299
+ role: input.role,
1300
+ expiresAt: formatIso(expiresAt)
1301
+ };
1302
+ });
1303
+ return { create: fn("T3LocalAuthTokenLive.create")(function* (input) {
1304
+ if (input.label.length === 0) return yield* fail(new AuthLocalError({ message: "local auth label cannot be empty" }));
1305
+ if (input.subject.length === 0) return yield* fail(new AuthLocalError({ message: "local auth subject cannot be empty" }));
1306
+ const baseDir = yield* resolveLocalBaseDir({ baseDir: input.baseDir }).pipe(provideService(Environment, environment), provideService(Path, path));
1307
+ const session = yield* issueLocalDatabaseSession({
1308
+ dbPath: path.join(baseDir, "userdata", "state.sqlite"),
1309
+ secretsDir: path.join(baseDir, "userdata", "secrets"),
1310
+ role: input.role,
1311
+ label: input.label,
1312
+ subject: input.subject
1313
+ }).pipe(mapError((error) => new AuthLocalError({
1314
+ message: `local auth failed: ${error.message}`,
1315
+ cause: error
1316
+ })));
1317
+ return {
1318
+ token: session.token,
1319
+ role: session.role,
1320
+ expiresAt: session.expiresAt,
1321
+ source: "local",
1322
+ baseDir
1323
+ };
1324
+ }) };
1325
+ });
1326
+ const T3LocalAuthTokenLive = effect(T3LocalAuthToken, makeT3LocalAuthToken());
1327
+ function insertAuthSession(input) {
1328
+ return gen(function* () {
1329
+ const sql = yield* SqlClient;
1330
+ yield* sql`PRAGMA busy_timeout = 5000;`;
1331
+ yield* sql`PRAGMA foreign_keys = ON;`;
1332
+ if (!(yield* sql`PRAGMA table_info(auth_sessions)`).some((column) => column.name === "scopes")) return yield* fail(new AuthLocalDatabaseError({
1333
+ operation: "schema",
1334
+ message: "local auth database is missing scoped auth_sessions schema"
1335
+ }));
1336
+ yield* sql`
1337
+ INSERT INTO auth_sessions (
1338
+ session_id,
1339
+ subject,
1340
+ scopes,
1341
+ method,
1342
+ client_label,
1343
+ client_ip_address,
1344
+ client_user_agent,
1345
+ client_device_type,
1346
+ client_os,
1347
+ client_browser,
1348
+ issued_at,
1349
+ expires_at,
1350
+ revoked_at
1351
+ )
1352
+ VALUES (
1353
+ ${input.sessionId},
1354
+ ${input.subject},
1355
+ ${JSON.stringify(input.scopes)},
1356
+ ${"bearer-access-token"},
1357
+ ${input.label},
1358
+ NULL,
1359
+ NULL,
1360
+ ${"bot"},
1361
+ NULL,
1362
+ NULL,
1363
+ ${input.issuedAt},
1364
+ ${input.expiresAt},
1365
+ NULL
1366
+ )
1367
+ `;
1368
+ });
1369
+ }
1370
+ const defaultSessionTtlMs = 720 * 60 * 60 * 1e3;
1371
+ const signingSecretName = "server-signing-key";
1372
+ const sha256BlockSize = 64;
1373
+ function concatBytes(first, second) {
1374
+ const bytes = new Uint8Array(first.byteLength + second.byteLength);
1375
+ bytes.set(first);
1376
+ bytes.set(second, first.byteLength);
1377
+ return bytes;
1378
+ }
1379
+ //#endregion
1380
+ //#region src/auth/local.ts
1381
+ var T3LocalAuth = class extends Service()("t3cli/T3LocalAuth") {};
1382
+ const makeT3LocalAuth = fn("makeT3LocalAuth")(function* () {
1383
+ const origin = yield* T3LocalAuthOrigin;
1384
+ const token = yield* T3LocalAuthToken;
1385
+ return { local: fn("T3LocalAuthLive.local")(function* (input) {
1386
+ const created = yield* token.create(input);
1387
+ return {
1388
+ url: yield* origin.resolve({
1389
+ baseDir: created.baseDir,
1390
+ ...input.origin !== void 0 ? { origin: input.origin } : {}
1391
+ }),
1392
+ token: created.token,
1393
+ role: created.role,
1394
+ expiresAt: created.expiresAt,
1395
+ source: "local",
1396
+ baseDir: created.baseDir
1397
+ };
1398
+ }) };
1399
+ });
1400
+ const T3LocalAuthLive = effect(T3LocalAuth, makeT3LocalAuth());
1401
+ //#endregion
1402
+ //#region src/auth/pairing.ts
1403
+ var T3AuthPairing = class extends Service()("t3cli/T3AuthPairing") {};
1404
+ const makeT3AuthPairing = fn("makeT3AuthPairing")(function* () {
1405
+ const transport = yield* T3AuthTransport;
1406
+ return { pair: fn("T3AuthPairingLive.pair")(function* (pairingUrl) {
1407
+ const parsed = yield* parsePairingUrl(pairingUrl);
1408
+ const result = yield* transport.bootstrapBearer(parsed);
1409
+ return {
1410
+ url: parsed.baseUrl,
1411
+ token: result.sessionToken,
1412
+ role: result.role,
1413
+ expiresAt: result.expiresAt
1414
+ };
1415
+ }) };
1416
+ });
1417
+ const T3AuthPairingLive = effect(T3AuthPairing, makeT3AuthPairing());
1418
+ function parsePairingUrl(value) {
1419
+ return gen(function* () {
1420
+ const url = yield* parseUrl(value);
1421
+ const token = yield* readPairingToken(url);
1422
+ if (token.length === 0) return yield* fail(new AuthPairingUrlError({ message: "pairing url missing token" }));
1423
+ const hostedHost = url.searchParams.get("host")?.trim();
1424
+ return {
1425
+ baseUrl: normalizeBaseUrl(yield* parseUrl(hostedHost !== void 0 && hostedHost.length > 0 ? hostedHost : new URL(".", url).toString())),
1426
+ credential: token
1427
+ };
1428
+ });
1429
+ }
1430
+ function parseUrl(value) {
1431
+ return fromResult(fromString(value)).pipe(catchTags({ IllegalArgumentError: (error) => fail(new AuthPairingUrlError({
1432
+ message: "invalid pairing url",
1433
+ cause: error
1434
+ })) }));
1435
+ }
1436
+ function normalizeBaseUrl(url) {
1437
+ return mutate$1(url, (current) => {
1438
+ current.hash = "";
1439
+ current.search = "";
1440
+ current.pathname = current.pathname === "/" ? "" : current.pathname.replace(/\/+$/u, "");
1441
+ }).toString().replace(/\/$/, "");
1442
+ }
1443
+ function readPairingToken(url) {
1444
+ return gen(function* () {
1445
+ const hashToken = (yield* parseUrl(`http://t3.local/?${url.hash.startsWith("#") ? url.hash.slice(1) : url.hash}`)).searchParams.get("token")?.trim();
1446
+ const token = url.searchParams.get("token")?.trim();
1447
+ return hashToken !== void 0 && hashToken.length > 0 ? hashToken : token !== void 0 && token.length > 0 ? token : "";
1448
+ });
1449
+ }
1450
+ //#endregion
1451
+ //#region src/auth/layer.ts
1452
+ const makeT3Auth = fn("makeT3Auth")(function* () {
1453
+ const config = yield* T3Config;
1454
+ const transport = yield* T3AuthTransport;
1455
+ const localAuth = yield* T3LocalAuth;
1456
+ const pairing = yield* T3AuthPairing;
1457
+ const status = fn("T3AuthLive.status")(function* () {
1458
+ const resolved = yield* config.resolve().pipe(catchTags({
1459
+ ConfigError: (error) => fail(new AuthConfigError({
1460
+ message: "auth config failed",
1461
+ cause: error
1462
+ })),
1463
+ UrlError: (error) => fail(new AuthConfigError({
1464
+ message: "auth config failed",
1465
+ cause: error
1466
+ }))
1467
+ }));
1468
+ return yield* transport.getSession(resolved);
1469
+ });
1470
+ const issueWebSocketTicket = fn("T3AuthLive.issueWebSocketTicket")(function* () {
1471
+ const resolved = yield* config.resolve().pipe(catchTags({
1472
+ ConfigError: (error) => fail(new AuthConfigError({
1473
+ message: "auth config failed",
1474
+ cause: error
1475
+ })),
1476
+ UrlError: (error) => fail(new AuthConfigError({
1477
+ message: "auth config failed",
1478
+ cause: error
1479
+ }))
1480
+ }));
1481
+ return yield* transport.issueWebSocketTicket(resolved);
1482
+ });
1483
+ const writeConfig = fn("T3AuthLive.writeConfig")(function* (input) {
1484
+ const existing = yield* config.readStored().pipe(catchTags({ ConfigError: (error) => fail(new AuthConfigError({
1485
+ message: "auth config failed",
1486
+ cause: error
1487
+ })) }));
1488
+ yield* config.writeStored({
1489
+ ...existing,
1490
+ url: input.url,
1491
+ token: input.token,
1492
+ ...input.local !== void 0 ? { local: input.local } : {}
1493
+ }).pipe(catchTags({ ConfigError: (error) => fail(new AuthConfigError({
1494
+ message: "auth config failed",
1495
+ cause: error
1496
+ })) }));
1497
+ });
1498
+ return {
1499
+ pair: pairing.pair,
1500
+ local: localAuth.local,
1501
+ writeConfig,
1502
+ status,
1503
+ issueWebSocketTicket
1504
+ };
1505
+ });
1506
+ const T3AuthLive = effect(T3Auth, makeT3Auth());
1507
+ //#endregion
1508
+ export { make$3 as C, Crypto as S, layer as _, makeT3AuthPairing as a, makeT3LocalAuthOrigin as b, T3LocalAuthLive as c, T3LocalAuthTokenLive as d, makeT3LocalAuthToken as f, makeCompilerSqlite as g, defaultTransforms as h, T3AuthPairingLive as i, makeT3LocalAuth as l, make as m, makeT3Auth as n, parsePairingUrl as o, SqlClientFactory as p, T3AuthPairing as r, T3LocalAuth as s, T3AuthLive as t, T3LocalAuthToken as u, T3LocalAuthOrigin as v, T3Auth as x, T3LocalAuthOriginLive as y };