@malloydata/db-duckdb 0.0.376 → 0.0.378

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.
@@ -0,0 +1,375 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ var __importDefault = (this && this.__importDefault) || function (mod) {
40
+ return (mod && mod.__esModule) ? mod : { "default": mod };
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.DuckDBConfigValidationError = void 0;
44
+ exports.normalizeDuckDBConfig = normalizeDuckDBConfig;
45
+ exports.buildDuckDBShareKey = buildDuckDBShareKey;
46
+ exports.sqlStringLiteral = sqlStringLiteral;
47
+ exports.sqlStringListLiteral = sqlStringListLiteral;
48
+ exports.stringifyDuckDBOption = stringifyDuckDBOption;
49
+ const path_1 = __importDefault(require("path"));
50
+ const malloy_1 = require("@malloydata/malloy");
51
+ const pathSecurity = __importStar(require("./path_security"));
52
+ class DuckDBConfigValidationError extends Error {
53
+ constructor(message) {
54
+ super(message);
55
+ this.name = 'DuckDBConfigValidationError';
56
+ }
57
+ }
58
+ exports.DuckDBConfigValidationError = DuckDBConfigValidationError;
59
+ const REQUIRED_BASELINE_EXTENSIONS = ['icu', 'json'];
60
+ const DERIVED_TEMP_DIRECTORY_NAME = '.tmp';
61
+ const DERIVED_SECRET_DIRECTORY_NAME = '.duckdb-secrets';
62
+ function normalizeDuckDBConfig(config) {
63
+ var _a, _b, _c, _d;
64
+ const filesystemPolicy = parsePolicyValue(config['filesystemPolicy'], 'filesystemPolicy', ['open', 'sandboxed']);
65
+ const networkPolicy = parsePolicyValue(config['networkPolicy'], 'networkPolicy', ['open', 'closed']);
66
+ if (filesystemPolicy === 'sandboxed' && !pathSecurity.isPosixHost()) {
67
+ throw new DuckDBConfigValidationError('filesystemPolicy "sandboxed" is only supported on POSIX hosts');
68
+ }
69
+ const rawDatabasePath = (_b = (_a = readOptionalString(config, 'databasePath')) !== null && _a !== void 0 ? _a : readOptionalString(config, 'path')) !== null && _b !== void 0 ? _b : ':memory:';
70
+ const rawWorkingDirectory = readOptionalString(config, 'workingDirectory');
71
+ const rawSetupSQL = normalizeOptionalText(readOptionalString(config, 'setupSQL'));
72
+ const rawMotherDuckToken = normalizeOptionalText(readOptionalString(config, 'motherDuckToken'));
73
+ const readOnly = (_c = readOptionalBoolean(config, 'readOnly')) !== null && _c !== void 0 ? _c : false;
74
+ const additionalExtensions = normalizeExtensions(config['additionalExtensions'], 'additionalExtensions');
75
+ const enableExternalAccess = readOptionalBoolean(config, 'enableExternalAccess');
76
+ const lockConfiguration = readOptionalBoolean(config, 'lockConfiguration');
77
+ const autoloadKnownExtensions = readOptionalBoolean(config, 'autoloadKnownExtensions');
78
+ const autoinstallKnownExtensions = readOptionalBoolean(config, 'autoinstallKnownExtensions');
79
+ const allowCommunityExtensions = readOptionalBoolean(config, 'allowCommunityExtensions');
80
+ const allowUnsignedExtensions = readOptionalBoolean(config, 'allowUnsignedExtensions');
81
+ const tempFileEncryption = readOptionalBoolean(config, 'tempFileEncryption');
82
+ const threads = readOptionalInteger(config, 'threads');
83
+ const memoryLimit = readOptionalString(config, 'memoryLimit');
84
+ const rawTempDirectory = readOptionalString(config, 'tempDirectory');
85
+ const rawExtensionDirectory = readOptionalString(config, 'extensionDirectory');
86
+ const rawAllowedDirectories = readOptionalStringArray(config['allowedDirectories'], 'allowedDirectories');
87
+ const restricted = filesystemPolicy === 'sandboxed' || networkPolicy === 'closed';
88
+ const safetyPolicy = restricted
89
+ ? {
90
+ requiresPosixHost: filesystemPolicy === 'sandboxed',
91
+ requiresLockedConfiguration: true,
92
+ requiresNoSetupSQL: true,
93
+ requiresSandboxedPaths: filesystemPolicy === 'sandboxed',
94
+ requiresTempFileEncryption: true,
95
+ requiresSecretNeutralization: true,
96
+ requiredBaselineExtensions: REQUIRED_BASELINE_EXTENSIONS,
97
+ allowHttpfs: networkPolicy === 'open',
98
+ forbidAdditionalExtensions: true,
99
+ derivedTempDirectoryName: DERIVED_TEMP_DIRECTORY_NAME,
100
+ }
101
+ : undefined;
102
+ if ((safetyPolicy === null || safetyPolicy === void 0 ? void 0 : safetyPolicy.requiresNoSetupSQL) && rawSetupSQL !== undefined) {
103
+ throw new DuckDBConfigValidationError('setupSQL is not allowed when filesystemPolicy or networkPolicy requires a locked DuckDB baseline');
104
+ }
105
+ if ((safetyPolicy === null || safetyPolicy === void 0 ? void 0 : safetyPolicy.forbidAdditionalExtensions) &&
106
+ additionalExtensions.length > 0) {
107
+ throw new DuckDBConfigValidationError('additionalExtensions is not allowed when filesystemPolicy or networkPolicy requires a locked DuckDB baseline');
108
+ }
109
+ if (restricted && lockConfiguration === false) {
110
+ throw new DuckDBConfigValidationError('lockConfiguration cannot be false when filesystemPolicy or networkPolicy requires a locked DuckDB baseline');
111
+ }
112
+ if (restricted && tempFileEncryption === false) {
113
+ throw new DuckDBConfigValidationError('tempFileEncryption cannot be false when filesystemPolicy or networkPolicy requires a locked DuckDB baseline');
114
+ }
115
+ if (networkPolicy === 'closed') {
116
+ rejectConflictingBoolean(enableExternalAccess, 'enableExternalAccess', true, 'networkPolicy "closed"');
117
+ rejectConflictingBoolean(autoloadKnownExtensions, 'autoloadKnownExtensions', true, 'networkPolicy "closed"');
118
+ rejectConflictingBoolean(autoinstallKnownExtensions, 'autoinstallKnownExtensions', true, 'networkPolicy "closed"');
119
+ rejectConflictingBoolean(allowCommunityExtensions, 'allowCommunityExtensions', true, 'networkPolicy "closed"');
120
+ rejectConflictingBoolean(allowUnsignedExtensions, 'allowUnsignedExtensions', true, 'networkPolicy "closed"');
121
+ if (rawMotherDuckToken !== undefined) {
122
+ throw new DuckDBConfigValidationError('motherDuckToken is not allowed when networkPolicy is "closed"');
123
+ }
124
+ }
125
+ let workingDirectory;
126
+ if (rawWorkingDirectory !== undefined) {
127
+ workingDirectory = canonicalizeConfigPath(rawWorkingDirectory, 'workingDirectory', {
128
+ mustExist: filesystemPolicy === 'sandboxed',
129
+ });
130
+ }
131
+ const databasePath = canonicalizeDatabasePath(rawDatabasePath);
132
+ const isMotherDuck = isMotherDuckPath(databasePath);
133
+ if (networkPolicy === 'closed' &&
134
+ !isAllowedClosedNetworkDatabasePath(databasePath)) {
135
+ throw new DuckDBConfigValidationError(`databasePath "${rawDatabasePath}" is not allowed when networkPolicy is "closed"`);
136
+ }
137
+ if (networkPolicy === 'closed' && isMotherDuck) {
138
+ throw new DuckDBConfigValidationError('MotherDuck database paths are not allowed when networkPolicy is "closed"');
139
+ }
140
+ const normalizedAllowedDirectories = rawAllowedDirectories === undefined
141
+ ? undefined
142
+ : canonicalizeConfigPathList(rawAllowedDirectories, 'allowedDirectories');
143
+ let allowedDirectories = normalizedAllowedDirectories;
144
+ if (filesystemPolicy === 'sandboxed') {
145
+ if (allowedDirectories === undefined) {
146
+ if (workingDirectory === undefined) {
147
+ throw new DuckDBConfigValidationError('filesystemPolicy "sandboxed" requires either allowedDirectories or workingDirectory. If you expected workingDirectory to come from config.rootDirectory, verify that overlay is available.');
148
+ }
149
+ allowedDirectories = [workingDirectory];
150
+ }
151
+ if (workingDirectory !== undefined &&
152
+ !allowedDirectories.some(allowed => pathSecurity.isContainedPath(allowed, workingDirectory))) {
153
+ throw new DuckDBConfigValidationError('workingDirectory must be contained within allowedDirectories when filesystemPolicy is "sandboxed"');
154
+ }
155
+ }
156
+ let tempDirectory;
157
+ if (rawTempDirectory !== undefined) {
158
+ tempDirectory = canonicalizeConfigPath(rawTempDirectory, 'tempDirectory');
159
+ }
160
+ else if (filesystemPolicy === 'sandboxed') {
161
+ if (workingDirectory === undefined) {
162
+ throw new DuckDBConfigValidationError('filesystemPolicy "sandboxed" requires tempDirectory or workingDirectory so Malloy can derive a safe temp directory');
163
+ }
164
+ tempDirectory = path_1.default.join(workingDirectory, DERIVED_TEMP_DIRECTORY_NAME);
165
+ }
166
+ if (filesystemPolicy === 'sandboxed') {
167
+ if (allowedDirectories === undefined) {
168
+ throw new DuckDBConfigValidationError('filesystemPolicy "sandboxed" requires allowedDirectories');
169
+ }
170
+ if (tempDirectory === undefined) {
171
+ throw new DuckDBConfigValidationError('filesystemPolicy "sandboxed" requires tempDirectory');
172
+ }
173
+ if (!allowedDirectories.some(allowed => pathSecurity.isContainedPath(allowed, tempDirectory))) {
174
+ throw new DuckDBConfigValidationError('tempDirectory must be contained within allowedDirectories when filesystemPolicy is "sandboxed"');
175
+ }
176
+ }
177
+ const extensionDirectory = rawExtensionDirectory === undefined
178
+ ? undefined
179
+ : canonicalizeConfigPath(rawExtensionDirectory, 'extensionDirectory');
180
+ const secretDirectory = deriveRestrictedSecretDirectory({
181
+ requiresSecretNeutralization: (_d = safetyPolicy === null || safetyPolicy === void 0 ? void 0 : safetyPolicy.requiresSecretNeutralization) !== null && _d !== void 0 ? _d : false,
182
+ tempDirectory,
183
+ workingDirectory,
184
+ });
185
+ return {
186
+ name: config.name,
187
+ databasePath,
188
+ readOnly: databasePath === ':memory:' ? false : readOnly,
189
+ workingDirectory,
190
+ filesystemPolicy,
191
+ networkPolicy,
192
+ safetyPolicy,
193
+ allowedDirectories,
194
+ enableExternalAccess: networkPolicy === 'closed' ? false : enableExternalAccess,
195
+ lockConfiguration: (safetyPolicy === null || safetyPolicy === void 0 ? void 0 : safetyPolicy.requiresLockedConfiguration)
196
+ ? true
197
+ : lockConfiguration,
198
+ autoloadKnownExtensions: networkPolicy === 'closed' ? false : autoloadKnownExtensions,
199
+ autoinstallKnownExtensions: networkPolicy === 'closed' ? false : autoinstallKnownExtensions,
200
+ allowCommunityExtensions: networkPolicy === 'closed' ? false : allowCommunityExtensions,
201
+ allowUnsignedExtensions: networkPolicy === 'closed' ? false : allowUnsignedExtensions,
202
+ tempFileEncryption: (safetyPolicy === null || safetyPolicy === void 0 ? void 0 : safetyPolicy.requiresTempFileEncryption)
203
+ ? true
204
+ : tempFileEncryption,
205
+ threads,
206
+ memoryLimit,
207
+ tempDirectory,
208
+ secretDirectory,
209
+ extensionDirectory,
210
+ motherDuckToken: rawMotherDuckToken,
211
+ additionalExtensions,
212
+ setupSQL: rawSetupSQL,
213
+ };
214
+ }
215
+ function buildDuckDBShareKey(config) {
216
+ var _a, _b, _c, _d, _e, _f, _g;
217
+ // secretDirectory is derived from policy + workingDirectory/tempDirectory,
218
+ // which already participate in the share key.
219
+ return (0, malloy_1.makeDigest)('duckdb-share-key-v1', config.databasePath, String(config.readOnly), config.filesystemPolicy, config.networkPolicy, (_a = config.setupSQL) !== null && _a !== void 0 ? _a : '', ...((_b = config.allowedDirectories) !== null && _b !== void 0 ? _b : []), config.enableExternalAccess === undefined
220
+ ? ''
221
+ : String(config.enableExternalAccess), config.lockConfiguration === undefined
222
+ ? ''
223
+ : String(config.lockConfiguration), config.autoloadKnownExtensions === undefined
224
+ ? ''
225
+ : String(config.autoloadKnownExtensions), config.autoinstallKnownExtensions === undefined
226
+ ? ''
227
+ : String(config.autoinstallKnownExtensions), config.allowCommunityExtensions === undefined
228
+ ? ''
229
+ : String(config.allowCommunityExtensions), config.allowUnsignedExtensions === undefined
230
+ ? ''
231
+ : String(config.allowUnsignedExtensions), config.tempFileEncryption === undefined
232
+ ? ''
233
+ : String(config.tempFileEncryption), config.threads === undefined ? '' : String(config.threads), (_c = config.memoryLimit) !== null && _c !== void 0 ? _c : '', (_d = config.tempDirectory) !== null && _d !== void 0 ? _d : '', (_e = config.workingDirectory) !== null && _e !== void 0 ? _e : '', ...[...config.additionalExtensions].sort(), (_f = config.extensionDirectory) !== null && _f !== void 0 ? _f : '', (_g = config.motherDuckToken) !== null && _g !== void 0 ? _g : '');
234
+ }
235
+ function sqlStringLiteral(value) {
236
+ return `'${value.replace(/'/g, "''")}'`;
237
+ }
238
+ function sqlStringListLiteral(values) {
239
+ return `[${values.map(value => sqlStringLiteral(value)).join(',')}]`;
240
+ }
241
+ function stringifyDuckDBOption(value) {
242
+ return String(value);
243
+ }
244
+ function parsePolicyValue(rawValue, fieldName, allowedValues) {
245
+ if (rawValue === undefined) {
246
+ return 'open';
247
+ }
248
+ if (typeof rawValue !== 'string') {
249
+ throw new DuckDBConfigValidationError(`${fieldName} must be one of ${allowedValues
250
+ .map(v => `"${v}"`)
251
+ .join(' or ')}, got ${typeof rawValue}`);
252
+ }
253
+ if (allowedValues.includes(rawValue)) {
254
+ return rawValue;
255
+ }
256
+ throw new DuckDBConfigValidationError(`${fieldName} must be one of ${allowedValues
257
+ .map(v => `"${v}"`)
258
+ .join(' or ')}, got "${rawValue}"`);
259
+ }
260
+ function readOptionalString(config, fieldName) {
261
+ const rawValue = config[fieldName];
262
+ if (rawValue === undefined) {
263
+ return undefined;
264
+ }
265
+ if (typeof rawValue !== 'string') {
266
+ throw new DuckDBConfigValidationError(`${fieldName} must be a string, got ${typeof rawValue}`);
267
+ }
268
+ return rawValue;
269
+ }
270
+ function readOptionalBoolean(config, fieldName) {
271
+ const rawValue = config[fieldName];
272
+ if (rawValue === undefined) {
273
+ return undefined;
274
+ }
275
+ if (typeof rawValue !== 'boolean') {
276
+ throw new DuckDBConfigValidationError(`${fieldName} must be a boolean, got ${typeof rawValue}`);
277
+ }
278
+ return rawValue;
279
+ }
280
+ function readOptionalInteger(config, fieldName) {
281
+ const rawValue = config[fieldName];
282
+ if (rawValue === undefined) {
283
+ return undefined;
284
+ }
285
+ if (typeof rawValue !== 'number' || !Number.isInteger(rawValue)) {
286
+ throw new DuckDBConfigValidationError(`${fieldName} must be an integer number`);
287
+ }
288
+ return rawValue;
289
+ }
290
+ function readOptionalStringArray(rawValue, fieldName) {
291
+ if (rawValue === undefined) {
292
+ return undefined;
293
+ }
294
+ if (!Array.isArray(rawValue)) {
295
+ throw new DuckDBConfigValidationError(`${fieldName} must be a JSON array of strings`);
296
+ }
297
+ if (!rawValue.every(value => typeof value === 'string')) {
298
+ throw new DuckDBConfigValidationError(`${fieldName} must be a JSON array of strings`);
299
+ }
300
+ return rawValue;
301
+ }
302
+ function normalizeExtensions(rawValue, fieldName) {
303
+ if (rawValue === undefined) {
304
+ return [];
305
+ }
306
+ const parts = (() => {
307
+ if (typeof rawValue === 'string') {
308
+ return rawValue.split(',');
309
+ }
310
+ if (Array.isArray(rawValue) &&
311
+ rawValue.every(value => typeof value === 'string')) {
312
+ return rawValue;
313
+ }
314
+ throw new DuckDBConfigValidationError(`${fieldName} must be a comma-separated string or an array of strings`);
315
+ })();
316
+ const normalized = parts
317
+ .map(value => value.trim())
318
+ .filter(value => value !== '');
319
+ return Array.from(new Set(normalized));
320
+ }
321
+ function normalizeOptionalText(value) {
322
+ if (value === undefined) {
323
+ return undefined;
324
+ }
325
+ const trimmed = value.trim();
326
+ return trimmed === '' ? undefined : value;
327
+ }
328
+ function deriveRestrictedSecretDirectory({ requiresSecretNeutralization, tempDirectory, workingDirectory, }) {
329
+ if (!requiresSecretNeutralization) {
330
+ return undefined;
331
+ }
332
+ if (tempDirectory !== undefined) {
333
+ return path_1.default.join(tempDirectory, DERIVED_SECRET_DIRECTORY_NAME);
334
+ }
335
+ if (workingDirectory !== undefined) {
336
+ return path_1.default.join(workingDirectory, DERIVED_SECRET_DIRECTORY_NAME);
337
+ }
338
+ throw new DuckDBConfigValidationError('restricted DuckDB policies require workingDirectory or tempDirectory so Malloy can isolate persistent DuckDB secrets');
339
+ }
340
+ function canonicalizeDatabasePath(databasePath) {
341
+ if (databasePath === ':memory:' || isLikelyRemoteDatabasePath(databasePath)) {
342
+ return databasePath;
343
+ }
344
+ return canonicalizeConfigPath(databasePath, 'databasePath');
345
+ }
346
+ function canonicalizeConfigPath(input, fieldName, options = {}) {
347
+ try {
348
+ return pathSecurity.canonicalizePath(input, options);
349
+ }
350
+ catch (error) {
351
+ throw new DuckDBConfigValidationError(`${fieldName} is invalid: ${errorMessage(error)}`);
352
+ }
353
+ }
354
+ function canonicalizeConfigPathList(paths, fieldName) {
355
+ return Array.from(new Set(paths.map(p => canonicalizeConfigPath(p, fieldName)).sort()));
356
+ }
357
+ function isAllowedClosedNetworkDatabasePath(databasePath) {
358
+ return (databasePath === ':memory:' || !isLikelyRemoteDatabasePath(databasePath));
359
+ }
360
+ function isLikelyRemoteDatabasePath(databasePath) {
361
+ return (isMotherDuckPath(databasePath) ||
362
+ /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(databasePath));
363
+ }
364
+ function isMotherDuckPath(databasePath) {
365
+ return (databasePath.startsWith('md:') || databasePath.startsWith('motherduck:'));
366
+ }
367
+ function rejectConflictingBoolean(actualValue, fieldName, forbiddenValue, reason) {
368
+ if (actualValue === forbiddenValue) {
369
+ throw new DuckDBConfigValidationError(`${fieldName} cannot be ${forbiddenValue} when ${reason} is enabled`);
370
+ }
371
+ }
372
+ function errorMessage(error) {
373
+ return error instanceof Error ? error.message : String(error);
374
+ }
375
+ //# sourceMappingURL=duckdb_config.js.map
@@ -3,12 +3,26 @@ import { DuckDBInstance } from '@duckdb/node-api';
3
3
  import type { DuckDBConnection as DuckDBNodeConnection } from '@duckdb/node-api';
4
4
  import type { ConnectionConfig, QueryRecord, QueryOptionsReader, RunSQLOptions } from '@malloydata/malloy';
5
5
  export interface DuckDBConnectionOptions extends ConnectionConfig {
6
- additionalExtensions?: string[];
6
+ additionalExtensions?: string[] | string;
7
7
  databasePath?: string;
8
8
  motherDuckToken?: string;
9
9
  workingDirectory?: string;
10
10
  readOnly?: boolean;
11
11
  setupSQL?: string;
12
+ filesystemPolicy?: 'open' | 'sandboxed';
13
+ networkPolicy?: 'open' | 'closed';
14
+ allowedDirectories?: string[];
15
+ enableExternalAccess?: boolean;
16
+ lockConfiguration?: boolean;
17
+ autoloadKnownExtensions?: boolean;
18
+ autoinstallKnownExtensions?: boolean;
19
+ allowCommunityExtensions?: boolean;
20
+ allowUnsignedExtensions?: boolean;
21
+ tempFileEncryption?: boolean;
22
+ threads?: number;
23
+ memoryLimit?: string;
24
+ tempDirectory?: string;
25
+ extensionDirectory?: string;
12
26
  }
13
27
  interface ActiveDB {
14
28
  instance: DuckDBInstance;
@@ -16,10 +30,11 @@ interface ActiveDB {
16
30
  }
17
31
  export declare class DuckDBConnection extends DuckDBCommon {
18
32
  readonly name: string;
19
- private additionalExtensions;
20
- private databasePath;
21
- private workingDirectory;
22
- private readOnly;
33
+ private readonly normalized;
34
+ private readonly shareKey;
35
+ private readonly digestDatabasePath;
36
+ private readonly digestWorkingDirectory?;
37
+ private readonly digestSetupSQL?;
23
38
  connecting: Promise<void>;
24
39
  protected connection: DuckDBNodeConnection | null;
25
40
  protected setupError: Error | undefined;
@@ -29,8 +44,14 @@ export declare class DuckDBConnection extends DuckDBCommon {
29
44
  constructor(name: string, databasePath?: string, workingDirectory?: string, queryOptions?: QueryOptionsReader);
30
45
  getDigest(): string;
31
46
  private init;
32
- loadExtension(ext: string): Promise<void>;
33
47
  protected setup(): Promise<void>;
48
+ private setupOnce;
49
+ private buildInstanceOptions;
50
+ private shouldApplyEnableExternalAccessAtOpenTime;
51
+ private applyFinalBaseline;
52
+ private loadBaselineExtensions;
53
+ private shouldLoadHttpfs;
54
+ private loadExtension;
34
55
  protected runDuckDBQuery(sql: string): Promise<{
35
56
  rows: QueryRecord[];
36
57
  totalRows: number;