@rc312/effect-snowflake 0.0.0-stage → 0.2.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 (69) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +174 -2
  4. package/dist/adbc-driver.d.ts +49 -0
  5. package/dist/adbc-driver.d.ts.map +1 -0
  6. package/dist/adbc-driver.js +29 -0
  7. package/dist/adbc-driver.js.map +1 -0
  8. package/dist/index.d.ts +96 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +89 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/internal/client.d.ts +6 -0
  13. package/dist/internal/client.d.ts.map +1 -0
  14. package/dist/internal/client.js +29 -0
  15. package/dist/internal/client.js.map +1 -0
  16. package/dist/internal/configuration.d.ts +4 -0
  17. package/dist/internal/configuration.d.ts.map +1 -0
  18. package/dist/internal/configuration.js +51 -0
  19. package/dist/internal/configuration.js.map +1 -0
  20. package/dist/internal/connection.d.ts +25 -0
  21. package/dist/internal/connection.d.ts.map +1 -0
  22. package/dist/internal/connection.js +39 -0
  23. package/dist/internal/connection.js.map +1 -0
  24. package/dist/internal/lifecycle.d.ts +9 -0
  25. package/dist/internal/lifecycle.d.ts.map +1 -0
  26. package/dist/internal/lifecycle.js +81 -0
  27. package/dist/internal/lifecycle.js.map +1 -0
  28. package/dist/internal/native.d.ts +4 -0
  29. package/dist/internal/native.d.ts.map +1 -0
  30. package/dist/internal/native.js +5 -0
  31. package/dist/internal/native.js.map +1 -0
  32. package/dist/internal/session.d.ts +6 -0
  33. package/dist/internal/session.d.ts.map +1 -0
  34. package/dist/internal/session.js +46 -0
  35. package/dist/internal/session.js.map +1 -0
  36. package/dist/internal/transaction.d.ts +6 -0
  37. package/dist/internal/transaction.d.ts.map +1 -0
  38. package/dist/internal/transaction.js +38 -0
  39. package/dist/internal/transaction.js.map +1 -0
  40. package/dist/models.d.ts +99 -0
  41. package/dist/models.d.ts.map +1 -0
  42. package/dist/models.js +2 -0
  43. package/dist/models.js.map +1 -0
  44. package/dist/snowflake-error.d.ts +19 -0
  45. package/dist/snowflake-error.d.ts.map +1 -0
  46. package/dist/snowflake-error.js +13 -0
  47. package/dist/snowflake-error.js.map +1 -0
  48. package/examples/.env.example +16 -0
  49. package/examples/README.md +73 -0
  50. package/examples/check.ts +12 -0
  51. package/examples/composition.ts +24 -0
  52. package/examples/options.ts +80 -0
  53. package/examples/query.ts +4 -0
  54. package/examples/run.ts +30 -0
  55. package/examples/scenarios.ts +114 -0
  56. package/examples/stream.ts +4 -0
  57. package/examples/transaction.ts +4 -0
  58. package/package.json +59 -4
  59. package/src/adbc-driver.ts +83 -0
  60. package/src/index.ts +151 -0
  61. package/src/internal/client.ts +69 -0
  62. package/src/internal/configuration.ts +63 -0
  63. package/src/internal/connection.ts +83 -0
  64. package/src/internal/lifecycle.ts +186 -0
  65. package/src/internal/native.ts +9 -0
  66. package/src/internal/session.ts +111 -0
  67. package/src/internal/transaction.ts +88 -0
  68. package/src/models.ts +126 -0
  69. package/src/snowflake-error.ts +17 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # @rc312/effect-snowflake
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Upgrade Effect support to 4.1.2 and require Node.js 22.19 or newer to match Effect's runtime requirements.
8
+
9
+ Effect 4.1 promotes typed failures to defects when combined with cleanup defects. Snowflake transaction failures retain both the original error and the cleanup error in the combined Cause.
10
+
11
+ ## 0.1.0
12
+
13
+ ### Minor Changes
14
+
15
+ - fc1d925: Add an Effect 4 Snowflake client using Apache Arrow ADBC, with scoped resources, Arrow parameter binding, batch streaming, serialized operations, and transactions.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ryan Callahan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,175 @@
1
- # Temporary Holding Version
1
+ # @rc312/effect-snowflake
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An Effect 4 client for Snowflake through Apache Arrow ADBC. Queries return Arrow `Table`s, streams emit Arrow `RecordBatch`es, and parameters are Arrow tables. The adapter preserves Arrow values without coercing decimals, timestamps, binary values, or 64-bit integers into JavaScript numbers or JSON.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ bun add @rc312/effect-snowflake effect apache-arrow@^21.1.0
9
+ ```
10
+
11
+ Use Node.js 22.19 or newer. This is a server-only package with a native dependency. The package includes the JavaScript ADBC driver manager; install the Snowflake shared-library driver separately:
12
+
13
+ ```sh
14
+ npm install -g @columnar-tech/dbc
15
+ dbc install snowflake
16
+ ```
17
+
18
+ `make` defaults to the driver name `snowflake`. Set `driver` to an absolute path to a driver library or manifest when needed, or supply `manifestSearchPaths`. Importing this package does not load the native addon; acquisition loads it and reports loading failures as `SnowflakeError`.
19
+
20
+ See the [ADBC JavaScript guide](https://arrow.apache.org/adbc/current/javascript/quickstart.html) and [Snowflake ADBC driver documentation](https://adbc-drivers.org/drivers/snowflake/) for driver installation, platform support, and native options. The implementation targets driver manager 0.24.x and Arrow 21.x. Native Snowflake driver installation and account access are application deployment requirements.
21
+
22
+ ## Services, Layers, and composition
23
+
24
+ Provide the native driver at the application boundary and share one client Layer across repositories:
25
+
26
+ ```ts
27
+ import * as Snowflake from "@rc312/effect-snowflake";
28
+ import * as AdbcDriver from "@rc312/effect-snowflake/adbc-driver";
29
+ import { Config, Effect, Layer } from "effect";
30
+
31
+ const DatabaseLive = Snowflake.layerConfig({
32
+ account: Config.String("SNOWFLAKE_ACCOUNT"),
33
+ username: Config.String("SNOWFLAKE_USERNAME"),
34
+ password: Config.Redacted("SNOWFLAKE_PASSWORD"),
35
+ warehouse: Config.String("SNOWFLAKE_WAREHOUSE"),
36
+ }).pipe(Layer.provide(AdbcDriver.layer));
37
+
38
+ const program = Snowflake.query("select current_version() as VERSION").pipe(
39
+ Snowflake.withTransaction,
40
+ Effect.provide(DatabaseLive)
41
+ );
42
+ ```
43
+
44
+ `layer(options)` requires `AdbcDriver`; `layerConfig(config)` reads a `Config` or a record of `Config` fields at acquisition. `layerFrom(acquire)` adapts an application-owned acquisition Effect and preserves its errors and dependencies. The Layer supplies Scope and owns the connection until the consuming program finishes. Reuse the same Layer value when several repository Layers should share one connection. Tests can provide another `AdbcDriver` or `Layer.succeed(Snowflake.Snowflake, client)`.
45
+
46
+ Use `yield* Snowflake.Snowflake` to capture the client in a repository, or compose the module's `query`, `execute`, and `stream` accessors directly. Client methods have no service requirements; accessors require `Snowflake.Snowflake`. `flow` is useful for a reusable input-to-Effect workflow; `pipe` attaches decoding, transaction scope, and provisioning to a particular Effect. See the [complete composition example](examples/composition.ts).
47
+
48
+ `Snowflake.withTransaction(effect)` uses the provided service. `client.withTransaction(effect)` uses that particular captured client. Both preserve the Effect's success, errors, and service requirements. A client resolves its current transaction session through a private fiber-local service, so repositories that captured it before the transaction still participate. Different clients and independently started fibers keep their own connection routing. Child fibers started within a transaction inherit its session and must finish before it exits. Nested transactions fail with `operation: "transaction.nested"`; Snowflake does not provide savepoints.
49
+
50
+ The implementation follows the constructor/Layer separation in [Effect's PostgreSQL adapter](https://github.com/Effect-TS/effect/blob/main/packages/sql/pg/src/PgClient.ts) and the per-client transaction service in [Effect SQL](https://github.com/Effect-TS/effect/blob/main/packages/effect/src/sql/SqlClient.ts). Its transport contract remains Arrow tables and record batches; the core `SqlClient` interface uses row results and SQL-dialect compilation. Native acquisition, session execution, transaction handling, and scope ownership are separate modules here. Session operations compose acquisition, native execution, and ownership with `flow`; transaction handling composes a scoped callback with commit, rollback, and autocommit finalizers. The ownership bracket uses named acquisition, joining, and release operations to keep shutdown ordering explicit. The existing `make` and `makeWithDriver` factories remain available for callers that own scopes directly.
51
+
52
+ ## Query and execute
53
+
54
+ ```ts
55
+ import * as Snowflake from "@rc312/effect-snowflake";
56
+ import { tableFromArrays } from "apache-arrow";
57
+ import { Config, Effect } from "effect";
58
+
59
+ const program = Effect.scoped(
60
+ Effect.gen(function* () {
61
+ const db = yield* Snowflake.make({
62
+ account: yield* Config.String("SNOWFLAKE_ACCOUNT"),
63
+ username: yield* Config.String("SNOWFLAKE_USERNAME"),
64
+ authenticator: "auth_jwt",
65
+ privateKey: yield* Config.Redacted("SNOWFLAKE_PRIVATE_KEY"),
66
+ warehouse: yield* Config.String("SNOWFLAKE_WAREHOUSE"),
67
+ });
68
+
69
+ const params = tableFromArrays({
70
+ id: new BigInt64Array([9007199254740993n]),
71
+ });
72
+ const table = yield* db.query("select ?::number(38, 0) as ID", params);
73
+ return table;
74
+ })
75
+ );
76
+ ```
77
+
78
+ Run `program` at your application's existing Effect runtime boundary. `make` is lazy until executed, and its enclosing Scope owns the connection and database. Use `Layer.effect` with an application service tag to share a scoped client. The adapter does not create an application runtime or retry queries.
79
+
80
+ `query(sql, parameters?)` collects the result into an Arrow table, including the schema of an empty result. `execute(sql, parameters?)` runs DDL/DML and returns the affected row count (`-1` means unknown). Each operation creates and closes a fresh statement. SQL is passed directly to the driver: use `?` placeholders and an Arrow table with columns in placeholder order. Values are never interpolated into SQL. Provide explicit Arrow types when inference would be ambiguous.
81
+
82
+ ADBC authentication names differ from the Snowflake JavaScript SDK: `auth_snowflake`, `auth_jwt`, `auth_oauth`, `auth_ext_browser`, `auth_okta`, `auth_mfa`, `auth_pat`, and `auth_wif`. Set `password`, `token`, `privateKey`, and `privateKeyPass` with `Redacted` values or `Config.Redacted`. `privateKey` is an inline PKCS#8 PEM; `privateKeyPath` is a plain filesystem path.
83
+
84
+ Pass additional native options through `databaseOptions`; every value must be `Redacted`, including credential-bearing connection URIs. Explicit named fields override entries in `databaseOptions`. For example:
85
+
86
+ ```ts
87
+ import { Redacted } from "effect";
88
+
89
+ const databaseOptions = {
90
+ "adbc.snowflake.sql.client_option.login_timeout": Redacted.make("30s"),
91
+ "adbc.snowflake.sql.client_option.request_timeout": Redacted.make("60s"),
92
+ "adbc.snowflake.sql.client_option.client_timeout": Redacted.make("30s"),
93
+ };
94
+ ```
95
+
96
+ ## Streaming
97
+
98
+ ```ts
99
+ import { Stream } from "effect";
100
+
101
+ // Inside the Scope that owns db:
102
+ const firstBatch = db
103
+ .stream("select * from EVENTS")
104
+ .pipe(Stream.take(1), Stream.runCollect);
105
+ ```
106
+
107
+ Streams acquire resources only when consumed. Batches are pulled on demand; there is no adapter-owned prefetch buffer. Native driver prefetch settings still apply. Early termination, errors, and interruption release the Arrow reader before closing its statement. A stream reserves the connection until its consumer releases it. Finish consuming it before starting another operation on the same connection from within that consumer.
108
+
109
+ Connection operations are serialized, including streamed queries. Use separately scoped clients when parallel connections are required.
110
+
111
+ ## Transactions
112
+
113
+ ```ts
114
+ // Inside the Scope that owns db:
115
+ const insert = db.transaction((tx) =>
116
+ Effect.gen(function* () {
117
+ yield* tx.execute(
118
+ "insert into EVENTS (ID) values (?)",
119
+ tableFromArrays({ id: [1] })
120
+ );
121
+ yield* tx.execute(
122
+ "insert into EVENTS (ID) values (?)",
123
+ tableFromArrays({ id: [2] })
124
+ );
125
+ })
126
+ );
127
+ ```
128
+
129
+ Transactions reserve the connection, disable autocommit, and serialize work on the supplied session. Use `tx` inside the callback and await its work. Returning from the callback closes its child scope and expires the session before commit. Typed failures, defects, and interruption trigger rollback. Failed commits also attempt rollback. Successful completion or rollback restores autocommit.
130
+
131
+ Failed reader/statement cleanup, rollback, or autocommit restoration invalidates the client; no further operation is accepted. Recovering a cleanup defect within the callback still prevents commit: the transaction fails with operation `transaction.invalidated` and attempts rollback. Autocommit is never re-enabled after a failed rollback, because doing so could commit pending changes. Cleanup failures are preserved as defects alongside the original failure. In Effect 4.1, a cleanup defect also promotes the original typed failure to a defect in the combined Cause. Acquire a new client after invalidation.
132
+
133
+ Only the callback is interruptible. Once commit starts, the adapter finishes commit and autocommit restoration before releasing the connection. Interruption during a successful commit does not trigger a subsequent rollback; the caller may still observe interruption after the commit completes.
134
+
135
+ Captured client methods automatically use the active transaction session on the current fiber. Transactions do not nest; nesting fails with operation `transaction.nested`. Snowflake DDL implicitly commits: use the transaction helper for DML/query work and create tables before the transaction. A transport failure during commit can leave its remote outcome ambiguous; the adapter does not retry it.
136
+
137
+ ## Lifetime, interruption, and errors
138
+
139
+ The database, connection, statements, and readers have explicit scoped ownership. The client owns a private sequential scope even when its parent scope finalizes in parallel. Scope closure interrupts and joins active acquisition and operations before closing the connection and database, including a connection returned after shutdown begins. Failed acquisition closes and detaches its child scope immediately. Client and transaction-session reuse after closure fails.
140
+
141
+ ADBC JavaScript 0.24 has no cancellation method or `AbortSignal` support. Native acquisition, execution, and batch reads are therefore awaited uninterruptibly before their resources can be released. An Effect interruption or timeout can wait for an in-flight native call to settle. Configure driver login, request, and network timeouts to bound those waits. The adapter cannot guarantee an immediate remote cancellation or a bounded shutdown if native calls never settle.
142
+
143
+ `SnowflakeError` exposes a safe `operation` and generic `message`. Raw driver messages, SQL, binds, connection options, and native error causes are excluded. Public operations have tracing spans without sensitive query attributes. Driver logging is configured by the application and is outside this adapter's error sanitization.
144
+
145
+ For a custom loader or deterministic test, use `makeWithDriver` with the `AdbcDriver` service from `@rc312/effect-snowflake/adbc-driver`. This structural boundary replaces only native resources; Arrow processing and Effect ownership remain real. `make` supplies the default native loader automatically.
146
+
147
+ ## Runnable examples and live E2E tests
148
+
149
+ The [examples guide](examples/README.md) includes environment setup and complete Node entrypoints for Arrow parameter binding, full and early stream consumption, and transactions. The live suite imports those same scenarios and additionally checks empty-result schemas and closed-client reuse.
150
+
151
+ ```sh
152
+ bun run --cwd packages/effect-snowflake example:check
153
+ bun run --cwd packages/effect-snowflake example:query
154
+ bun run --cwd packages/effect-snowflake example:stream
155
+ bun run --cwd packages/effect-snowflake example:transaction
156
+ bun run --cwd packages/effect-snowflake example:composition
157
+ # After configuring credentials and setting SNOWFLAKE_E2E=1:
158
+ bun run --cwd packages/effect-snowflake test:e2e
159
+ ```
160
+
161
+ The examples read the package-local `.env` at the Node entrypoint. The configuration check validates settings without connecting. Live tests are skipped unless explicitly enabled; they use independent sessions and a temporary table, and require a reachable Snowflake account, a warehouse, and appropriate schema privileges.
162
+
163
+ ## Development
164
+
165
+ From the workspace root:
166
+
167
+ ```sh
168
+ bun run --cwd packages/effect-snowflake build
169
+ bun run --cwd packages/effect-snowflake typecheck
170
+ bun run --cwd packages/effect-snowflake test
171
+ bun run --cwd packages/effect-snowflake test:coverage
172
+ bun run lint
173
+ ```
174
+
175
+ Unit tests use real Arrow IPC and controlled native resources for precision, acquisition and reader failures, serialized work, combined cleanup causes, transaction interruption, scope retirement, and tracing redaction. The examples and E2E sources are included in typechecking. Coverage reports are written under the package's ignored `coverage/` directory; the live suite runs separately from ordinary unit tests.
@@ -0,0 +1,49 @@
1
+ import type { AdbcConnection, AdbcStatement, AdbcDatabase, ConnectOptions } from "@apache-arrow/adbc-driver-manager";
2
+ import { Context, Effect, Layer } from "effect";
3
+ import type { SnowflakeError } from "./snowflake-error.ts";
4
+ /**
5
+ * Minimal native database resource owned by a scoped client.
6
+ * Implementations must await acquisition/cleanup rather than detach native work.
7
+ * @since 0.1.0
8
+ */
9
+ export interface Database {
10
+ /** Open a connection; the adapter owns it after this Promise resolves. */
11
+ readonly connect: () => Promise<Connection>;
12
+ /** Release database resources after all owned connections have closed. */
13
+ readonly close: AdbcDatabase["close"];
14
+ }
15
+ /**
16
+ * Native statement operations used by the adapter. Each query receives a fresh
17
+ * instance. A returned reader is released before `close` is invoked.
18
+ * @since 0.1.0
19
+ */
20
+ export type Statement = Pick<AdbcStatement, "setSqlQuery" | "bind" | "executeQuery" | "executeUpdate" | "close">;
21
+ /**
22
+ * Native connection boundary. Methods are called under an exclusive permit;
23
+ * `createStatement` must return a fresh statement for each call.
24
+ * @since 0.1.0
25
+ */
26
+ export type Connection = Pick<AdbcConnection, "setAutoCommit" | "commit" | "rollback" | "close"> & {
27
+ readonly createStatement: () => Promise<Statement>;
28
+ };
29
+ declare const AdbcDriver_base: Context.ServiceClass<AdbcDriver, "@rc312/effect-snowflake/AdbcDriver", {
30
+ /** Construct the database; the client owns and closes a successful result. */
31
+ readonly open: (options: ConnectOptions) => Effect.Effect<Database, SnowflakeError>;
32
+ }>;
33
+ /**
34
+ * Loader service required by `makeWithDriver` for alternate native loading or
35
+ * controlled tests. `open` must map native failures to sanitized Snowflake errors.
36
+ * Use {@link layer} for the standard Apache Arrow implementation.
37
+ * @since 0.1.0
38
+ */
39
+ export declare class AdbcDriver extends AdbcDriver_base {
40
+ }
41
+ /**
42
+ * Standard loader layer. Importing it does not load the native addon; `open` does.
43
+ * Addon import failures use operation `driver.load`; database construction failures
44
+ * use `database.open`. Raw native messages and causes are excluded from both.
45
+ * @since 0.1.0
46
+ */
47
+ export declare const layer: Layer.Layer<AdbcDriver, never, never>;
48
+ export {};
49
+ //# sourceMappingURL=adbc-driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adbc-driver.d.ts","sourceRoot":"","sources":["../src/adbc-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,YAAY,EACZ,cAAc,EACf,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5C,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,IAAI,CAC1B,aAAa,EACb,aAAa,GAAG,MAAM,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,CACpE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,CAC3B,cAAc,EACd,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAClD,GAAG;IAAE,QAAQ,CAAC,eAAe,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC;;IAWvD,8EAA8E;mBAC/D,CACb,OAAO,EAAE,cAAc,KACpB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC;;AAZhD;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,eAQS;CAAG;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,KAAK,uCAiBjB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { failure } from "./snowflake-error.js";
3
+ /**
4
+ * Loader service required by `makeWithDriver` for alternate native loading or
5
+ * controlled tests. `open` must map native failures to sanitized Snowflake errors.
6
+ * Use {@link layer} for the standard Apache Arrow implementation.
7
+ * @since 0.1.0
8
+ */
9
+ export class AdbcDriver extends Context.Service()("@rc312/effect-snowflake/AdbcDriver") {
10
+ }
11
+ /**
12
+ * Standard loader layer. Importing it does not load the native addon; `open` does.
13
+ * Addon import failures use operation `driver.load`; database construction failures
14
+ * use `database.open`. Raw native messages and causes are excluded from both.
15
+ * @since 0.1.0
16
+ */
17
+ export const layer = Layer.succeed(AdbcDriver, AdbcDriver.of({
18
+ open: Effect.fn("Snowflake.AdbcDriver.open")(function* openDatabase(options) {
19
+ const { AdbcDatabase } = yield* Effect.tryPromise({
20
+ catch: failure("driver.load"),
21
+ try: () => import("@apache-arrow/adbc-driver-manager"),
22
+ });
23
+ return yield* Effect.try({
24
+ catch: failure("database.open"),
25
+ try: () => new AdbcDatabase(options),
26
+ });
27
+ }),
28
+ }));
29
+ //# sourceMappingURL=adbc-driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adbc-driver.js","sourceRoot":"","sources":["../src/adbc-driver.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAmC/C;;;;;GAKG;AACH,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAQ5C,CAAC,oCAAoC,CAAC;CAAG;AAE5C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAChC,UAAU,EACV,UAAU,CAAC,EAAE,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAC1C,QAAQ,CAAC,CAAC,YAAY,CAAC,OAAO;QAC5B,MAAM,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;YAChD,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC;YAC7B,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mCAAmC,CAAC;SACvD,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YACvB,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC;YAC/B,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC;SACrC,CAAC,CAAC;IACL,CAAC,CACF;CACF,CAAC,CACH,CAAC"}
@@ -0,0 +1,96 @@
1
+ import type { RecordBatch, Table } from "apache-arrow";
2
+ import { Config, Context, Effect, Layer, Stream } from "effect";
3
+ import type { SnowflakeClient, SnowflakeOptions, SnowflakeSession } from "./models.ts";
4
+ import type { SnowflakeError } from "./snowflake-error.ts";
5
+ export type { SnowflakeClient, SnowflakeOptions, SnowflakeSession, } from "./models.ts";
6
+ export { SnowflakeError } from "./snowflake-error.ts";
7
+ declare const Snowflake_base: Context.ServiceClass<Snowflake, "@rc312/effect-snowflake/Snowflake", {
8
+ readonly query: SnowflakeSession["query"];
9
+ readonly execute: SnowflakeSession["execute"];
10
+ readonly stream: SnowflakeSession["stream"];
11
+ readonly transaction: SnowflakeClient["transaction"];
12
+ readonly withTransaction: SnowflakeClient["withTransaction"];
13
+ }>;
14
+ /**
15
+ * Injected client service. Its layer owns one connection and captures its driver.
16
+ * Reuse the same layer value when repositories should share that connection.
17
+ * @since 0.1.0
18
+ */
19
+ export declare class Snowflake extends Snowflake_base {
20
+ }
21
+ /**
22
+ * Acquire a connected client through an injected `AdbcDriver` service.
23
+ *
24
+ * @param options Native Snowflake settings; construction performs no I/O.
25
+ * @returns An Effect requiring `Scope` and `AdbcDriver`. The scope joins active
26
+ * operations before closing connection and database, even under parallel teardown.
27
+ * Failed acquisition immediately releases its partial resources and child scope.
28
+ *
29
+ * Custom loaders must normalize native errors to sanitized `SnowflakeError`s.
30
+ * Native calls have no cancellation API: configure driver network/login timeouts
31
+ * to bound shutdown. Prefer {@link make} when using the standard native manager.
32
+ * @since 0.1.0
33
+ */
34
+ export declare const makeWithDriver: (options: SnowflakeOptions) => Effect.Effect<SnowflakeClient, SnowflakeError, import("./adbc-driver.ts").AdbcDriver | import("effect/Scope").Scope>;
35
+ /**
36
+ * Acquire a server-only Snowflake connection through the Apache Arrow ADBC manager.
37
+ *
38
+ * @param options Connection settings. The Snowflake shared-library driver must be
39
+ * installed separately; `driver` defaults to `snowflake`.
40
+ * @returns A lazy Effect requiring `Scope`. Its scope owns connection and database.
41
+ * Driver loading and connection errors are sanitized `SnowflakeError`s. Native
42
+ * calls settle before interruption releases resources; queries are never retried.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * import { make } from "@rc312/effect-snowflake";
47
+ * import { Config, Effect } from "effect";
48
+ *
49
+ * const program = Effect.scoped(Effect.gen(function* () {
50
+ * const db = yield* make({
51
+ * account: yield* Config.String("SNOWFLAKE_ACCOUNT"),
52
+ * username: yield* Config.String("SNOWFLAKE_USERNAME"),
53
+ * password: yield* Config.Redacted("SNOWFLAKE_PASSWORD"),
54
+ * });
55
+ * return yield* db.query("select current_version() as VERSION");
56
+ * }));
57
+ * ```
58
+ * @since 0.1.0
59
+ */
60
+ export declare const make: (options: SnowflakeOptions) => Effect.Effect<SnowflakeClient, SnowflakeError, import("effect/Scope").Scope>;
61
+ /**
62
+ * Provide the service from an existing acquisition Effect, retaining its errors
63
+ * and dependencies. The Layer owns any Scope required by the acquisition.
64
+ * Useful for application-owned configuration, instrumentation, and test clients.
65
+ * @since 0.1.0
66
+ */
67
+ export declare const layerFrom: <E, R>(acquire: Effect.Effect<SnowflakeClient, E, R>) => Layer.Layer<Snowflake, E, Exclude<R, import("effect/Scope").Scope>>;
68
+ /**
69
+ * Provide a scoped Snowflake service using an injected AdbcDriver.
70
+ * Compose with `Layer.provide(AdbcDriver.layer)` at the application boundary.
71
+ * @since 0.1.0
72
+ */
73
+ export declare const layer: (options: SnowflakeOptions) => Layer.Layer<Snowflake, SnowflakeError, import("./adbc-driver.ts").AdbcDriver>;
74
+ /**
75
+ * Read Config values when the layer is built, then acquire its scoped client.
76
+ * Accepts one Config or a record of Config fields; ConfigProvider stays caller-owned.
77
+ * Requires the same explicit AdbcDriver dependency as {@link layer}.
78
+ * @since 0.1.0
79
+ */
80
+ export declare const layerConfig: (options: Config.Wrap<SnowflakeOptions>) => Layer.Layer<Snowflake, Config.ConfigError | SnowflakeError, import("./adbc-driver.ts").AdbcDriver>;
81
+ /** Query the injected client, or the active transaction's scoped session. @since 0.1.0 */
82
+ export declare const query: (sql: string, parameters?: Table) => Effect.Effect<Table<any>, SnowflakeError, Snowflake>;
83
+ /** Execute DML/DDL on the injected client. @since 0.1.0 */
84
+ export declare const execute: (sql: string, parameters?: Table) => Effect.Effect<number, SnowflakeError, Snowflake>;
85
+ /** Lazily stream batches from the injected client; the consumer owns its permit. @since 0.1.0 */
86
+ export declare const stream: (sql: string, parameters?: Table) => Stream.Stream<RecordBatch, SnowflakeError, Snowflake>;
87
+ /**
88
+ * Run an Effect in a transaction using the injected client. Pipe it around a
89
+ * composed workflow; accessors and `yield* Snowflake` both resolve its session.
90
+ * Nested transactions fail with operation `transaction.nested` (Snowflake has no
91
+ * savepoints). Callback errors, defects, service requirements, and interruption
92
+ * are preserved by the underlying transaction implementation.
93
+ * @since 0.1.0
94
+ */
95
+ export declare const withTransaction: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E | SnowflakeError, R | Snowflake>;
96
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAc,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAM5E,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;;oBAUlC,gBAAgB,CAAC,OAAO,CAAC;sBACvB,gBAAgB,CAAC,SAAS,CAAC;qBAC5B,gBAAgB,CAAC,QAAQ,CAAC;0BACrB,eAAe,CAAC,aAAa,CAAC;8BAC1B,eAAe,CAAC,iBAAiB,CAAC;;AAZhE;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,cASS;CAAG;AAE3C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,qJAE1B,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,IAAI,6GAGhB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,WACnB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,EAAE,CAAC,CAAC,wEACV,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,KAAK,YAAa,gBAAgB,kFACX,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,WAAW,YAAa,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,uGACJ,CAAC;AAE/D,0FAA0F;AAC1F,eAAO,MAAM,KAAK,QAAS,MAAM,eAAe,KAAK,yDAIlD,CAAC;AAEJ,2DAA2D;AAC3D,eAAO,MAAM,OAAO,QAAS,MAAM,eAAe,KAAK,qDAIpD,CAAC;AAEJ,iGAAiG;AACjG,eAAO,MAAM,MAAM,QACZ,MAAM,eACE,KAAK,KACjB,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,EAAE,SAAS,CAMpD,CAAC;AAEJ;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,wDAIlE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,89 @@
1
+ import { Config, Context, Effect, flow, pipe, Layer, Stream } from "effect";
2
+ import { layer as driverLayer } from "./adbc-driver.js";
3
+ import * as Client from "./internal/client.js";
4
+ import * as Connection from "./internal/connection.js";
5
+ import { acquireOwner } from "./internal/lifecycle.js";
6
+ export { SnowflakeError } from "./snowflake-error.js";
7
+ /**
8
+ * Injected client service. Its layer owns one connection and captures its driver.
9
+ * Reuse the same layer value when repositories should share that connection.
10
+ * @since 0.1.0
11
+ */
12
+ export class Snowflake extends Context.Service()("@rc312/effect-snowflake/Snowflake") {
13
+ }
14
+ /**
15
+ * Acquire a connected client through an injected `AdbcDriver` service.
16
+ *
17
+ * @param options Native Snowflake settings; construction performs no I/O.
18
+ * @returns An Effect requiring `Scope` and `AdbcDriver`. The scope joins active
19
+ * operations before closing connection and database, even under parallel teardown.
20
+ * Failed acquisition immediately releases its partial resources and child scope.
21
+ *
22
+ * Custom loaders must normalize native errors to sanitized `SnowflakeError`s.
23
+ * Native calls have no cancellation API: configure driver network/login timeouts
24
+ * to bound shutdown. Prefer {@link make} when using the standard native manager.
25
+ * @since 0.1.0
26
+ */
27
+ export const makeWithDriver = Effect.fn("Snowflake.make")(flow(Connection.make, Effect.flatMap(Client.make), acquireOwner));
28
+ /**
29
+ * Acquire a server-only Snowflake connection through the Apache Arrow ADBC manager.
30
+ *
31
+ * @param options Connection settings. The Snowflake shared-library driver must be
32
+ * installed separately; `driver` defaults to `snowflake`.
33
+ * @returns A lazy Effect requiring `Scope`. Its scope owns connection and database.
34
+ * Driver loading and connection errors are sanitized `SnowflakeError`s. Native
35
+ * calls settle before interruption releases resources; queries are never retried.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { make } from "@rc312/effect-snowflake";
40
+ * import { Config, Effect } from "effect";
41
+ *
42
+ * const program = Effect.scoped(Effect.gen(function* () {
43
+ * const db = yield* make({
44
+ * account: yield* Config.String("SNOWFLAKE_ACCOUNT"),
45
+ * username: yield* Config.String("SNOWFLAKE_USERNAME"),
46
+ * password: yield* Config.Redacted("SNOWFLAKE_PASSWORD"),
47
+ * });
48
+ * return yield* db.query("select current_version() as VERSION");
49
+ * }));
50
+ * ```
51
+ * @since 0.1.0
52
+ */
53
+ export const make = Effect.fn("Snowflake.makeDefault")((options) => makeWithDriver(options).pipe(Effect.provide(driverLayer)));
54
+ /**
55
+ * Provide the service from an existing acquisition Effect, retaining its errors
56
+ * and dependencies. The Layer owns any Scope required by the acquisition.
57
+ * Useful for application-owned configuration, instrumentation, and test clients.
58
+ * @since 0.1.0
59
+ */
60
+ export const layerFrom = (acquire) => Layer.effect(Snowflake, acquire);
61
+ /**
62
+ * Provide a scoped Snowflake service using an injected AdbcDriver.
63
+ * Compose with `Layer.provide(AdbcDriver.layer)` at the application boundary.
64
+ * @since 0.1.0
65
+ */
66
+ export const layer = (options) => layerFrom(makeWithDriver(options));
67
+ /**
68
+ * Read Config values when the layer is built, then acquire its scoped client.
69
+ * Accepts one Config or a record of Config fields; ConfigProvider stays caller-owned.
70
+ * Requires the same explicit AdbcDriver dependency as {@link layer}.
71
+ * @since 0.1.0
72
+ */
73
+ export const layerConfig = (options) => Layer.unwrap(Config.unwrap(options).pipe(Effect.map(layer)));
74
+ /** Query the injected client, or the active transaction's scoped session. @since 0.1.0 */
75
+ export const query = (sql, parameters) => pipe(Snowflake, Effect.flatMap((client) => client.query(sql, parameters)));
76
+ /** Execute DML/DDL on the injected client. @since 0.1.0 */
77
+ export const execute = (sql, parameters) => pipe(Snowflake, Effect.flatMap((client) => client.execute(sql, parameters)));
78
+ /** Lazily stream batches from the injected client; the consumer owns its permit. @since 0.1.0 */
79
+ export const stream = (sql, parameters) => Stream.unwrap(pipe(Snowflake, Effect.map((client) => client.stream(sql, parameters))));
80
+ /**
81
+ * Run an Effect in a transaction using the injected client. Pipe it around a
82
+ * composed workflow; accessors and `yield* Snowflake` both resolve its session.
83
+ * Nested transactions fail with operation `transaction.nested` (Snowflake has no
84
+ * savepoints). Callback errors, defects, service requirements, and interruption
85
+ * are preserved by the underlying transaction implementation.
86
+ * @since 0.1.0
87
+ */
88
+ export const withTransaction = (self) => pipe(Snowflake, Effect.flatMap((client) => client.withTransaction(self)));
89
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Effect } from "effect";
2
+ import type { SnowflakeClient } from "../models.ts";
3
+ import type { Connection } from "./connection.ts";
4
+ /** Capture the connection; client methods have no dependency requirements. */
5
+ export declare const make: (connection: Connection) => Effect.Effect<SnowflakeClient, never, never>;
6
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/internal/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,MAAM,EAA6B,MAAM,QAAQ,CAAC;AAEpE,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,cAAc,CAAC;AAEtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAQlD,8EAA8E;AAC9E,eAAO,MAAM,IAAI,0EAuDf,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { Context, Effect, Option, Semaphore, Stream } from "effect";
2
+ import { failure } from "../snowflake-error.js";
3
+ import * as Session from "./session.js";
4
+ import * as Transaction from "./transaction.js";
5
+ // Each client needs its own fiber-local session key, as in Effect SqlClient.
6
+ // A transaction on one client must never route another client's queries.
7
+ let nextClientId = 0;
8
+ /** Capture the connection; client methods have no dependency requirements. */
9
+ export const make = Effect.fnUntraced(function* makeClient(connection) {
10
+ const lock = yield* Semaphore.make(1);
11
+ const direct = Session.make(connection, connection.owner, lock, connection.isOpen);
12
+ const transactionSession = Context.Service(`@rc312/effect-snowflake/Transaction/${(nextClientId += 1)}`);
13
+ const currentSession = Effect.serviceOption(transactionSession).pipe(Effect.map(Option.getOrElse(() => direct)));
14
+ const runTransaction = Transaction.make(connection, lock);
15
+ const transaction = (use) => Effect.serviceOption(transactionSession).pipe(Effect.flatMap((current) => {
16
+ if (Option.isSome(current)) {
17
+ return Effect.fail(failure("transaction.nested")());
18
+ }
19
+ return runTransaction((session) => Effect.provideService(use(session), transactionSession, session));
20
+ }));
21
+ return {
22
+ execute: (sql, parameters) => currentSession.pipe(Effect.flatMap((session) => session.execute(sql, parameters))),
23
+ query: (sql, parameters) => currentSession.pipe(Effect.flatMap((session) => session.query(sql, parameters))),
24
+ stream: (sql, parameters) => Stream.unwrap(currentSession.pipe(Effect.map((session) => session.stream(sql, parameters)))),
25
+ transaction,
26
+ withTransaction: (self) => transaction(() => self),
27
+ };
28
+ });
29
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/internal/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGpE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAEhD,6EAA6E;AAC7E,yEAAyE;AACzE,IAAI,YAAY,GAAG,CAAC,CAAC;AAErB,8EAA8E;AAC9E,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,UAAU,CACxD,UAAsB;IAEtB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CACzB,UAAU,EACV,UAAU,CAAC,KAAK,EAChB,IAAI,EACJ,UAAU,CAAC,MAAM,CAClB,CAAC;IAEF,MAAM,kBAAkB,GAAG,OAAO,CAAC,OAAO,CACxC,uCAAuC,CAAC,YAAY,IAAI,CAAC,CAAC,EAAE,CAC7D,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAClE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAC3C,CAAC;IAEF,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAE1D,MAAM,WAAW,GAAmC,CAClD,GAA0D,EAC1D,EAAE,CACF,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACzB,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE,CAChC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,kBAAkB,EAAE,OAAO,CAAC,CACjE,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;IAEJ,OAAO;QACL,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,CAC3B,cAAc,CAAC,IAAI,CACjB,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAC9D;QACH,KAAK,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,CACzB,cAAc,CAAC,IAAI,CACjB,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAC5D;QACH,MAAM,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,EAAE,CAC1B,MAAM,CAAC,MAAM,CACX,cAAc,CAAC,IAAI,CACjB,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CACzD,CACF;QACH,WAAW;QACX,eAAe,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;KACnD,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ConnectOptions } from "@apache-arrow/adbc-driver-manager";
2
+ import type { SnowflakeOptions } from "../models.ts";
3
+ export declare const configuration: (options: SnowflakeOptions) => ConnectOptions;
4
+ //# sourceMappingURL=configuration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configuration.d.ts","sourceRoot":"","sources":["../../src/internal/configuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAGxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,eAAO,MAAM,aAAa,YAAa,gBAAgB,KAAG,cAyDzD,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { Redacted } from "effect";
2
+ export const configuration = (options) => {
3
+ const databaseOptions = Object.fromEntries(Object.entries(options.databaseOptions ?? {}).map(([key, value]) => [
4
+ key,
5
+ Redacted.value(value),
6
+ ]));
7
+ const values = [
8
+ ["adbc.snowflake.sql.account", options.account],
9
+ ["username", options.username],
10
+ ["adbc.snowflake.sql.db", options.database],
11
+ ["adbc.snowflake.sql.schema", options.schema],
12
+ ["adbc.snowflake.sql.warehouse", options.warehouse],
13
+ ["adbc.snowflake.sql.role", options.role],
14
+ ["adbc.snowflake.sql.auth_type", options.authenticator],
15
+ [
16
+ "adbc.snowflake.sql.client_option.jwt_private_key",
17
+ options.privateKeyPath,
18
+ ],
19
+ ];
20
+ for (const [key, value] of values) {
21
+ if (value !== undefined) {
22
+ databaseOptions[key] = value;
23
+ }
24
+ }
25
+ const secrets = [
26
+ ["password", options.password],
27
+ ["adbc.snowflake.sql.client_option.auth_token", options.token],
28
+ [
29
+ "adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_value",
30
+ options.privateKey,
31
+ ],
32
+ [
33
+ "adbc.snowflake.sql.client_option.jwt_private_key_pkcs8_password",
34
+ options.privateKeyPass,
35
+ ],
36
+ ];
37
+ for (const [key, value] of secrets) {
38
+ if (value !== undefined) {
39
+ databaseOptions[key] = Redacted.value(value);
40
+ }
41
+ }
42
+ const config = {
43
+ databaseOptions,
44
+ driver: options.driver ?? "snowflake",
45
+ };
46
+ if (options.manifestSearchPaths !== undefined) {
47
+ config.manifestSearchPaths = [...options.manifestSearchPaths];
48
+ }
49
+ return config;
50
+ };
51
+ //# sourceMappingURL=configuration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/internal/configuration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIlC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAyB,EAAkB,EAAE;IACzE,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,CACxC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;QAClE,GAAG;QACH,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;KACtB,CAAC,CACH,CAAC;IAEF,MAAM,MAAM,GAAG;QACb,CAAC,4BAA4B,EAAE,OAAO,CAAC,OAAO,CAAC;QAC/C,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC;QAC9B,CAAC,uBAAuB,EAAE,OAAO,CAAC,QAAQ,CAAC;QAC3C,CAAC,2BAA2B,EAAE,OAAO,CAAC,MAAM,CAAC;QAC7C,CAAC,8BAA8B,EAAE,OAAO,CAAC,SAAS,CAAC;QACnD,CAAC,yBAAyB,EAAE,OAAO,CAAC,IAAI,CAAC;QACzC,CAAC,8BAA8B,EAAE,OAAO,CAAC,aAAa,CAAC;QACvD;YACE,kDAAkD;YAClD,OAAO,CAAC,cAAc;SACvB;KACO,CAAC;IAEX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,eAAe,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG;QACd,CAAC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC;QAC9B,CAAC,6CAA6C,EAAE,OAAO,CAAC,KAAK,CAAC;QAC9D;YACE,8DAA8D;YAC9D,OAAO,CAAC,UAAU;SACnB;QACD;YACE,iEAAiE;YACjE,OAAO,CAAC,cAAc;SACvB;KACO,CAAC;IAEX,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,eAAe,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAmB;QAC7B,eAAe;QACf,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,WAAW;KACtC,CAAC;IAEF,IAAI,OAAO,CAAC,mBAAmB,KAAK,SAAS,EAAE,CAAC;QAC9C,MAAM,CAAC,mBAAmB,GAAG,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}