@effectuate/cubejs-mongosql-driver 1.0.1 → 1.0.2

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 (3) hide show
  1. package/index.d.ts +160 -0
  2. package/index.js +316 -0
  3. package/package.json +7 -7
package/index.d.ts ADDED
@@ -0,0 +1,160 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ /* auto-generated by NAPI-RS */
5
+
6
+ /**
7
+ * Schema source — Collection mode, File mode, or Atlas SQL mode.
8
+ *
9
+ * Wire shape across napi-rs is a tagged object. `kind` is one of
10
+ * `"collection"`, `"file"`, or `"atlas-sql"`; `path` is required for
11
+ * `"file"`. See `schema.rs` module docs for the per-mode loading
12
+ * strategy.
13
+ */
14
+ export interface SchemaSource {
15
+ /** Discriminant: `"collection"`, `"file"`, or `"atlas-sql"`. */
16
+ kind: string
17
+ /** Path to schema file (file mode only). */
18
+ path?: string
19
+ }
20
+ /**
21
+ * Client configuration object passed across the napi-rs boundary.
22
+ *
23
+ * `Debug` is hand-rolled to **redact the URI** because it may contain
24
+ * credentials (SPEC NFR-4).
25
+ */
26
+ export interface ClientConfig {
27
+ /** MongoDB connection URI. **Sensitive: contains credentials.** */
28
+ uri: string
29
+ /** Database name to query. */
30
+ database: string
31
+ /** Schema source. None defaults to Collection (handled by `with_defaults_applied`). */
32
+ schemaSource?: SchemaSource
33
+ /** Refresh interval in seconds. None defaults to 300. */
34
+ schemaRefreshSec?: number
35
+ /** If true, testConnection succeeds even on initial schema load failure. None defaults to false. */
36
+ schemaFailOpen?: boolean
37
+ /** Per-query timeout in milliseconds. None defaults to 60000. */
38
+ queryTimeoutMs?: number
39
+ /** Max rows returned per query (buffered). None defaults to 100000. */
40
+ maxRows?: number
41
+ }
42
+ /**
43
+ * Public napi-rs entry point. Cube's TypeScript driver instantiates this once
44
+ * per Cube driver instance.
45
+ */
46
+ export declare class MongoSqlClient {
47
+ /**
48
+ * Construct a new client. No I/O is performed.
49
+ *
50
+ * Validation is deferred to [`Self::test_connection`] so the constructor
51
+ * stays infallible — napi-rs 2.16's `#[napi(constructor)]` requires
52
+ * `Self` directly, not `Result<Self>`. A subsequent `query()` before
53
+ * `test_connection()` returns a clear `MONGOSQL_CONFIG_INVALID` error
54
+ * rather than panicking.
55
+ */
56
+ constructor(config: ClientConfig)
57
+ /**
58
+ * Verify cluster connectivity and load initial schema, then spawn the
59
+ * background refresh task. Sequence:
60
+ *
61
+ * 1. `config.validate()` — synchronous shape checks (URI scheme, db name, ...).
62
+ * 2. Build the `mongodb::Client` (lazily; cached for subsequent calls).
63
+ * 3. `db("admin").run_command({ping: 1})` with a bounded timeout.
64
+ * 4. Initial schema load (collection or file mode).
65
+ * 5. Swap into the cache; build the column map.
66
+ * 6. Spawn the refresh task.
67
+ *
68
+ * Each step's failure preserves the SPEC §6 error code. Optional
69
+ * `signal` cancels the in-flight ping/load if the caller (or a
70
+ * concurrent `close()`) fires it; on cancellation we surface
71
+ * [`Error::Cancelled`] with site `"test_connection"`.
72
+ */
73
+ testConnection(signal?: AbortHandle | undefined | null): Promise<void>
74
+ /**
75
+ * Translate `sql` and execute the resulting MQL pipeline. Returns rows
76
+ * as a JSON array.
77
+ *
78
+ * Database-name handling: for file-mode catalogs, `default_db` passed to
79
+ * `translate::translate` is [`FILE_MODE_DB_PLACEHOLDER`]; the resulting
80
+ * `Translation::target_db` is rewritten to `config.database` before the
81
+ * executor runs the aggregate, so the wire-level command targets the
82
+ * real database the user configured.
83
+ *
84
+ * If `signal` is provided, abort propagates to the in-flight cursor:
85
+ * the racing `tokio::select!` short-circuits with [`Error::Cancelled`].
86
+ * `close()` also cancels via the parent [`Self::close_token`].
87
+ * `biased` polling on the cancel branch ensures cancellation has
88
+ * priority if the abort fires before/while the executor schedules.
89
+ */
90
+ query(sql: string, signal?: AbortHandle | undefined | null): Promise<any>
91
+ /**
92
+ * Returns Cube's expected `tablesSchema` payload built from the cached
93
+ * schema. Shape: `{ <db>: { <coll>: [{name, type}, ...] } }`.
94
+ *
95
+ * Only the configured database is exposed (one driver instance = one
96
+ * db). For file-mode catalogs the internal placeholder key is rewritten
97
+ * to the configured database name so consumers see a single coherent
98
+ * database label.
99
+ *
100
+ * Optional `signal` cancels the lock acquisition / map clone if a
101
+ * large `__sql_schemas` is being copied. In practice the body is
102
+ * memory-only, but the guard keeps the API symmetrical with `query()`
103
+ * and lets `close()` short-circuit pending callers.
104
+ */
105
+ tablesSchema(signal?: AbortHandle | undefined | null): Promise<any>
106
+ /**
107
+ * Closes underlying connections and stops background tasks.
108
+ *
109
+ * Idempotent: calling `close()` after a previous `close()` (or before
110
+ * `test_connection()` ever spawned a refresh task) is a no-op rather
111
+ * than an error. The mongodb client itself has no explicit close on
112
+ * v3.x — its connection pool drops when the last `Arc<Client>` goes out
113
+ * of scope.
114
+ *
115
+ * **SIGTERM-during-pre-agg fix.** Before this method existed, `close()`
116
+ * only stopped the schema-refresh task; in-flight queries kept draining
117
+ * their cursors until the server-side `maxTimeMS` fired (default 60s,
118
+ * tunable via `CUBEJS_MONGOSQL_QUERY_TIMEOUT_MS`). That leaks
119
+ * connections and wastes Mongo work when the caller has already
120
+ * signalled "stop everything". We now:
121
+ *
122
+ * 1. Cancel the parent token, which fans out to every per-call child
123
+ * token (created in `query()` / `test_connection()` /
124
+ * `tables_schema()`). Each in-flight async fn breaks out of its
125
+ * `tokio::select!` with `Error::Cancelled`.
126
+ * 2. Wait up to [`CLOSE_DRAIN_TIMEOUT`] for the in-flight counter to
127
+ * reach zero — the upper bound on caller-visible delay.
128
+ * 3. Stop the schema refresh task.
129
+ *
130
+ * The 5s drain budget is conservative; in practice in-flight cursors
131
+ * abandon their `try_next()` within microseconds of the cancel and
132
+ * the counter hits zero in O(milliseconds). We keep the bounded wait
133
+ * as defence-in-depth for slow TCP closes.
134
+ */
135
+ close(): Promise<void>
136
+ }
137
+ /**
138
+ * Public napi-rs handle exposed to JavaScript.
139
+ *
140
+ * JS lifecycle:
141
+ * 1. `const handle = new AbortHandle();`
142
+ * 2. Wire to a `AbortSignal`: `signal.addEventListener('abort', () => handle.abort());`
143
+ * 3. Pass to a cancellable Rust async method.
144
+ *
145
+ * The handle is a thin newtype around `Arc<CancelToken>` so it can be
146
+ * cloned cheaply across the napi boundary if a future API needs to share
147
+ * one signal across several calls.
148
+ */
149
+ export declare class AbortHandle {
150
+ /** Construct a fresh, un-aborted handle. */
151
+ constructor()
152
+ /**
153
+ * Mark this handle aborted. Safe to call from any thread; idempotent.
154
+ * JS-callable; the conventional use is from an `AbortSignal`'s
155
+ * `'abort'` event listener.
156
+ */
157
+ abort(): void
158
+ /** Synchronous probe — true once `abort()` has been called. */
159
+ aborted(): boolean
160
+ }
package/index.js ADDED
@@ -0,0 +1,316 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /* prettier-ignore */
4
+
5
+ /* auto-generated by NAPI-RS */
6
+
7
+ const { existsSync, readFileSync } = require('fs')
8
+ const { join } = require('path')
9
+
10
+ const { platform, arch } = process
11
+
12
+ let nativeBinding = null
13
+ let localFileExisted = false
14
+ let loadError = null
15
+
16
+ function isMusl() {
17
+ // For Node 10
18
+ if (!process.report || typeof process.report.getReport !== 'function') {
19
+ try {
20
+ const lddPath = require('child_process').execSync('which ldd').toString().trim()
21
+ return readFileSync(lddPath, 'utf8').includes('musl')
22
+ } catch (e) {
23
+ return true
24
+ }
25
+ } else {
26
+ const { glibcVersionRuntime } = process.report.getReport().header
27
+ return !glibcVersionRuntime
28
+ }
29
+ }
30
+
31
+ switch (platform) {
32
+ case 'android':
33
+ switch (arch) {
34
+ case 'arm64':
35
+ localFileExisted = existsSync(join(__dirname, 'cubejs-mongosql-driver-native.android-arm64.node'))
36
+ try {
37
+ if (localFileExisted) {
38
+ nativeBinding = require('./cubejs-mongosql-driver-native.android-arm64.node')
39
+ } else {
40
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-android-arm64')
41
+ }
42
+ } catch (e) {
43
+ loadError = e
44
+ }
45
+ break
46
+ case 'arm':
47
+ localFileExisted = existsSync(join(__dirname, 'cubejs-mongosql-driver-native.android-arm-eabi.node'))
48
+ try {
49
+ if (localFileExisted) {
50
+ nativeBinding = require('./cubejs-mongosql-driver-native.android-arm-eabi.node')
51
+ } else {
52
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-android-arm-eabi')
53
+ }
54
+ } catch (e) {
55
+ loadError = e
56
+ }
57
+ break
58
+ default:
59
+ throw new Error(`Unsupported architecture on Android ${arch}`)
60
+ }
61
+ break
62
+ case 'win32':
63
+ switch (arch) {
64
+ case 'x64':
65
+ localFileExisted = existsSync(
66
+ join(__dirname, 'cubejs-mongosql-driver-native.win32-x64-msvc.node')
67
+ )
68
+ try {
69
+ if (localFileExisted) {
70
+ nativeBinding = require('./cubejs-mongosql-driver-native.win32-x64-msvc.node')
71
+ } else {
72
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-win32-x64-msvc')
73
+ }
74
+ } catch (e) {
75
+ loadError = e
76
+ }
77
+ break
78
+ case 'ia32':
79
+ localFileExisted = existsSync(
80
+ join(__dirname, 'cubejs-mongosql-driver-native.win32-ia32-msvc.node')
81
+ )
82
+ try {
83
+ if (localFileExisted) {
84
+ nativeBinding = require('./cubejs-mongosql-driver-native.win32-ia32-msvc.node')
85
+ } else {
86
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-win32-ia32-msvc')
87
+ }
88
+ } catch (e) {
89
+ loadError = e
90
+ }
91
+ break
92
+ case 'arm64':
93
+ localFileExisted = existsSync(
94
+ join(__dirname, 'cubejs-mongosql-driver-native.win32-arm64-msvc.node')
95
+ )
96
+ try {
97
+ if (localFileExisted) {
98
+ nativeBinding = require('./cubejs-mongosql-driver-native.win32-arm64-msvc.node')
99
+ } else {
100
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-win32-arm64-msvc')
101
+ }
102
+ } catch (e) {
103
+ loadError = e
104
+ }
105
+ break
106
+ default:
107
+ throw new Error(`Unsupported architecture on Windows: ${arch}`)
108
+ }
109
+ break
110
+ case 'darwin':
111
+ localFileExisted = existsSync(join(__dirname, 'cubejs-mongosql-driver-native.darwin-universal.node'))
112
+ try {
113
+ if (localFileExisted) {
114
+ nativeBinding = require('./cubejs-mongosql-driver-native.darwin-universal.node')
115
+ } else {
116
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-darwin-universal')
117
+ }
118
+ break
119
+ } catch {}
120
+ switch (arch) {
121
+ case 'x64':
122
+ localFileExisted = existsSync(join(__dirname, 'cubejs-mongosql-driver-native.darwin-x64.node'))
123
+ try {
124
+ if (localFileExisted) {
125
+ nativeBinding = require('./cubejs-mongosql-driver-native.darwin-x64.node')
126
+ } else {
127
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-darwin-x64')
128
+ }
129
+ } catch (e) {
130
+ loadError = e
131
+ }
132
+ break
133
+ case 'arm64':
134
+ localFileExisted = existsSync(
135
+ join(__dirname, 'cubejs-mongosql-driver-native.darwin-arm64.node')
136
+ )
137
+ try {
138
+ if (localFileExisted) {
139
+ nativeBinding = require('./cubejs-mongosql-driver-native.darwin-arm64.node')
140
+ } else {
141
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-darwin-arm64')
142
+ }
143
+ } catch (e) {
144
+ loadError = e
145
+ }
146
+ break
147
+ default:
148
+ throw new Error(`Unsupported architecture on macOS: ${arch}`)
149
+ }
150
+ break
151
+ case 'freebsd':
152
+ if (arch !== 'x64') {
153
+ throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
154
+ }
155
+ localFileExisted = existsSync(join(__dirname, 'cubejs-mongosql-driver-native.freebsd-x64.node'))
156
+ try {
157
+ if (localFileExisted) {
158
+ nativeBinding = require('./cubejs-mongosql-driver-native.freebsd-x64.node')
159
+ } else {
160
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-freebsd-x64')
161
+ }
162
+ } catch (e) {
163
+ loadError = e
164
+ }
165
+ break
166
+ case 'linux':
167
+ switch (arch) {
168
+ case 'x64':
169
+ if (isMusl()) {
170
+ localFileExisted = existsSync(
171
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-x64-musl.node')
172
+ )
173
+ try {
174
+ if (localFileExisted) {
175
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-x64-musl.node')
176
+ } else {
177
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-x64-musl')
178
+ }
179
+ } catch (e) {
180
+ loadError = e
181
+ }
182
+ } else {
183
+ localFileExisted = existsSync(
184
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-x64-gnu.node')
185
+ )
186
+ try {
187
+ if (localFileExisted) {
188
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-x64-gnu.node')
189
+ } else {
190
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-x64-gnu')
191
+ }
192
+ } catch (e) {
193
+ loadError = e
194
+ }
195
+ }
196
+ break
197
+ case 'arm64':
198
+ if (isMusl()) {
199
+ localFileExisted = existsSync(
200
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-arm64-musl.node')
201
+ )
202
+ try {
203
+ if (localFileExisted) {
204
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-arm64-musl.node')
205
+ } else {
206
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-arm64-musl')
207
+ }
208
+ } catch (e) {
209
+ loadError = e
210
+ }
211
+ } else {
212
+ localFileExisted = existsSync(
213
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-arm64-gnu.node')
214
+ )
215
+ try {
216
+ if (localFileExisted) {
217
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-arm64-gnu.node')
218
+ } else {
219
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-arm64-gnu')
220
+ }
221
+ } catch (e) {
222
+ loadError = e
223
+ }
224
+ }
225
+ break
226
+ case 'arm':
227
+ if (isMusl()) {
228
+ localFileExisted = existsSync(
229
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-arm-musleabihf.node')
230
+ )
231
+ try {
232
+ if (localFileExisted) {
233
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-arm-musleabihf.node')
234
+ } else {
235
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-arm-musleabihf')
236
+ }
237
+ } catch (e) {
238
+ loadError = e
239
+ }
240
+ } else {
241
+ localFileExisted = existsSync(
242
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-arm-gnueabihf.node')
243
+ )
244
+ try {
245
+ if (localFileExisted) {
246
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-arm-gnueabihf.node')
247
+ } else {
248
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-arm-gnueabihf')
249
+ }
250
+ } catch (e) {
251
+ loadError = e
252
+ }
253
+ }
254
+ break
255
+ case 'riscv64':
256
+ if (isMusl()) {
257
+ localFileExisted = existsSync(
258
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-riscv64-musl.node')
259
+ )
260
+ try {
261
+ if (localFileExisted) {
262
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-riscv64-musl.node')
263
+ } else {
264
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-riscv64-musl')
265
+ }
266
+ } catch (e) {
267
+ loadError = e
268
+ }
269
+ } else {
270
+ localFileExisted = existsSync(
271
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-riscv64-gnu.node')
272
+ )
273
+ try {
274
+ if (localFileExisted) {
275
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-riscv64-gnu.node')
276
+ } else {
277
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-riscv64-gnu')
278
+ }
279
+ } catch (e) {
280
+ loadError = e
281
+ }
282
+ }
283
+ break
284
+ case 's390x':
285
+ localFileExisted = existsSync(
286
+ join(__dirname, 'cubejs-mongosql-driver-native.linux-s390x-gnu.node')
287
+ )
288
+ try {
289
+ if (localFileExisted) {
290
+ nativeBinding = require('./cubejs-mongosql-driver-native.linux-s390x-gnu.node')
291
+ } else {
292
+ nativeBinding = require('@effectuate/cubejs-mongosql-driver-linux-s390x-gnu')
293
+ }
294
+ } catch (e) {
295
+ loadError = e
296
+ }
297
+ break
298
+ default:
299
+ throw new Error(`Unsupported architecture on Linux: ${arch}`)
300
+ }
301
+ break
302
+ default:
303
+ throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
304
+ }
305
+
306
+ if (!nativeBinding) {
307
+ if (loadError) {
308
+ throw loadError
309
+ }
310
+ throw new Error(`Failed to load native binding`)
311
+ }
312
+
313
+ const { MongoSqlClient, AbortHandle } = nativeBinding
314
+
315
+ module.exports.MongoSqlClient = MongoSqlClient
316
+ module.exports.AbortHandle = AbortHandle
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effectuate/cubejs-mongosql-driver",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Cube.js native data source driver for MongoDB via the MongoSQL translator (Rust + napi-rs). Replacement for the EOL'd BI Connector path.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -85,12 +85,12 @@
85
85
  "@cubejs-backend/schema-compiler": "^1.6.0"
86
86
  },
87
87
  "optionalDependencies": {
88
- "@effectuate/cubejs-mongosql-driver-linux-x64-gnu": "1.0.1",
89
- "@effectuate/cubejs-mongosql-driver-linux-arm64-gnu": "1.0.1",
90
- "@effectuate/cubejs-mongosql-driver-linux-x64-musl": "1.0.1",
91
- "@effectuate/cubejs-mongosql-driver-linux-arm64-musl": "1.0.1",
92
- "@effectuate/cubejs-mongosql-driver-darwin-x64": "1.0.1",
93
- "@effectuate/cubejs-mongosql-driver-darwin-arm64": "1.0.1"
88
+ "@effectuate/cubejs-mongosql-driver-linux-x64-gnu": "1.0.2",
89
+ "@effectuate/cubejs-mongosql-driver-linux-arm64-gnu": "1.0.2",
90
+ "@effectuate/cubejs-mongosql-driver-linux-x64-musl": "1.0.2",
91
+ "@effectuate/cubejs-mongosql-driver-linux-arm64-musl": "1.0.2",
92
+ "@effectuate/cubejs-mongosql-driver-darwin-x64": "1.0.2",
93
+ "@effectuate/cubejs-mongosql-driver-darwin-arm64": "1.0.2"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@biomejs/biome": "^2.4.15",