@objectstack/service-datasource 10.0.0 → 10.3.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.
- package/.turbo/turbo-build.log +28 -16
- package/CHANGELOG.md +100 -0
- package/dist/chunk-76HQ74MX.cjs +82 -0
- package/dist/chunk-76HQ74MX.cjs.map +1 -0
- package/dist/chunk-BI2SYWLC.cjs +9 -0
- package/dist/chunk-BI2SYWLC.cjs.map +1 -0
- package/dist/chunk-JRBGOCRJ.js +82 -0
- package/dist/chunk-JRBGOCRJ.js.map +1 -0
- package/dist/chunk-XLS4RP7B.js +9 -0
- package/dist/chunk-XLS4RP7B.js.map +1 -0
- package/dist/contracts/index.cjs +7 -1
- package/dist/contracts/index.cjs.map +1 -1
- package/dist/contracts/index.d.cts +59 -1
- package/dist/contracts/index.d.ts +59 -1
- package/dist/contracts/index.js +6 -0
- package/dist/index.cjs +284 -106
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +270 -5
- package/dist/index.d.ts +270 -5
- package/dist/index.js +216 -38
- package/dist/index.js.map +1 -1
- package/dist/sqlite-driver-fallback-BPFQYLX7.js +11 -0
- package/dist/sqlite-driver-fallback-BPFQYLX7.js.map +1 -0
- package/dist/sqlite-driver-fallback-JX4XOICD.cjs +11 -0
- package/dist/sqlite-driver-fallback-JX4XOICD.cjs.map +1 -0
- package/package.json +8 -7
- package/src/__tests__/datasource-connection-service.test.ts +294 -0
- package/src/contracts/connect-policy.ts +69 -0
- package/src/contracts/index.ts +11 -0
- package/src/datasource-admin-plugin.ts +37 -40
- package/src/datasource-admin-service.ts +2 -0
- package/src/datasource-connection-service.ts +364 -0
- package/src/default-datasource-driver-factory.ts +26 -9
- package/src/index.ts +29 -0
- package/src/logger.ts +2 -0
- package/src/sqlite-driver-fallback.test.ts +184 -0
- package/src/sqlite-driver-fallback.ts +195 -0
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
var _chunkBI2SYWLCcjs = require('./chunk-BI2SYWLC.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunk76HQ74MXcjs = require('./chunk-76HQ74MX.cjs');
|
|
9
|
+
|
|
10
|
+
// src/external-datasource-service.ts
|
|
2
11
|
|
|
3
12
|
|
|
4
13
|
|
|
@@ -368,6 +377,179 @@ function safeGetService(ctx, name) {
|
|
|
368
377
|
}
|
|
369
378
|
}
|
|
370
379
|
|
|
380
|
+
// src/datasource-connection-service.ts
|
|
381
|
+
function isDatasourceAddressed(ds, ctx) {
|
|
382
|
+
if (ds.schemaMode && ds.schemaMode !== "managed") return true;
|
|
383
|
+
if (ds.autoConnect === true) return true;
|
|
384
|
+
if (_optionalChain([ctx, 'access', _38 => _38.objects, 'optionalAccess', _39 => _39.some, 'call', _40 => _40((o) => _optionalChain([o, 'optionalAccess', _41 => _41.datasource]) === ds.name)])) return true;
|
|
385
|
+
return false;
|
|
386
|
+
}
|
|
387
|
+
var DatasourceConnectionService = class {
|
|
388
|
+
constructor(cfg) {
|
|
389
|
+
this.cfg = cfg;
|
|
390
|
+
this.policy = _nullishCoalesce(cfg.policy, () => ( _chunkBI2SYWLCcjs.allowAllConnectPolicy));
|
|
391
|
+
this.logger = cfg.logger;
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Auto-connect the declared (code-defined) datasources that pass the D2 gate.
|
|
395
|
+
* Called from `AppPlugin.start()` with the app bundle's datasources + objects.
|
|
396
|
+
* Each connected external datasource also has its bound objects' read metadata
|
|
397
|
+
* synced so they are immediately queryable with zero app code.
|
|
398
|
+
*/
|
|
399
|
+
async connectDeclared(input) {
|
|
400
|
+
const objects = _nullishCoalesce(input.objects, () => ( []));
|
|
401
|
+
const results = [];
|
|
402
|
+
for (const ds of input.datasources) {
|
|
403
|
+
if (!_optionalChain([ds, 'optionalAccess', _42 => _42.name])) continue;
|
|
404
|
+
if (ds.active === false) continue;
|
|
405
|
+
if (!isDatasourceAddressed(ds, { objects })) continue;
|
|
406
|
+
const bound = objects.filter((o) => _optionalChain([o, 'optionalAccess', _43 => _43.datasource]) === ds.name && typeof _optionalChain([o, 'optionalAccess', _44 => _44.name]) === "string").map((o) => o.name);
|
|
407
|
+
results.push(
|
|
408
|
+
await this.connect(ds, { objects: bound, context: { origin: _nullishCoalesce(ds.origin, () => ( "code")), trigger: "declared-auto" } })
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
return results;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Build + connect + register a single datasource's live driver. The shared
|
|
415
|
+
* core used by both auto-connect and the runtime-admin pool registration.
|
|
416
|
+
*
|
|
417
|
+
* Failure policy (ADR-0062 D5): an `external` datasource with
|
|
418
|
+
* `validation.onMismatch: 'fail'` fails fast (re-throws, bricking boot as
|
|
419
|
+
* intended); everything else degrades with a warning so an optional replica's
|
|
420
|
+
* connectivity blip never bricks boot.
|
|
421
|
+
*/
|
|
422
|
+
async connect(record, opts = {}) {
|
|
423
|
+
const name = record.name;
|
|
424
|
+
const engine = this.cfg.engine();
|
|
425
|
+
const factory = this.cfg.factory();
|
|
426
|
+
if (_optionalChain([engine, 'optionalAccess', _45 => _45.getDriverByName, 'optionalCall', _46 => _46(name)])) {
|
|
427
|
+
return { name, status: "already-registered" };
|
|
428
|
+
}
|
|
429
|
+
let decision;
|
|
430
|
+
try {
|
|
431
|
+
decision = await this.policy.canConnect(
|
|
432
|
+
{ name, driver: record.driver, schemaMode: record.schemaMode, external: record.external },
|
|
433
|
+
opts.context
|
|
434
|
+
);
|
|
435
|
+
} catch (err) {
|
|
436
|
+
decision = { allow: false, reason: `connect policy threw: ${errMsg(err)}` };
|
|
437
|
+
}
|
|
438
|
+
if (!decision.allow) {
|
|
439
|
+
_optionalChain([this, 'access', _47 => _47.logger, 'optionalAccess', _48 => _48.info, 'optionalCall', _49 => _49(`datasource '${name}': connect denied by policy${decision.reason ? ` (${decision.reason})` : ""}`)]);
|
|
440
|
+
return { name, status: "skipped-policy", reason: decision.reason };
|
|
441
|
+
}
|
|
442
|
+
if (!factory || !_optionalChain([engine, 'optionalAccess', _50 => _50.registerDriver])) {
|
|
443
|
+
_optionalChain([this, 'access', _51 => _51.logger, 'optionalAccess', _52 => _52.debug, 'optionalCall', _53 => _53(`datasource '${name}': no driver factory / engine \u2014 left metadata-only`)]);
|
|
444
|
+
return { name, status: "skipped-no-infra" };
|
|
445
|
+
}
|
|
446
|
+
if (!factory.supports(record.driver)) {
|
|
447
|
+
return this.handleFailure(
|
|
448
|
+
record,
|
|
449
|
+
"skipped-unsupported",
|
|
450
|
+
`no driver factory supports driver '${record.driver}'`,
|
|
451
|
+
opts.context
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
let secret;
|
|
455
|
+
const credentialsRef = _optionalChain([record, 'access', _54 => _54.external, 'optionalAccess', _55 => _55.credentialsRef]);
|
|
456
|
+
if (credentialsRef) {
|
|
457
|
+
const resolver = _optionalChain([this, 'access', _56 => _56.cfg, 'access', _57 => _57.secrets, 'optionalAccess', _58 => _58.resolve]);
|
|
458
|
+
if (!resolver) {
|
|
459
|
+
return this.handleFailure(
|
|
460
|
+
record,
|
|
461
|
+
"failed-credentials",
|
|
462
|
+
`requires credential '${credentialsRef}' but no secret store (SecretBinder/ICryptoProvider) is configured`,
|
|
463
|
+
opts.context
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
try {
|
|
467
|
+
secret = await resolver(credentialsRef);
|
|
468
|
+
} catch (err) {
|
|
469
|
+
return this.handleFailure(record, "failed-credentials", `resolving credential '${credentialsRef}' threw: ${errMsg(err)}`, opts.context);
|
|
470
|
+
}
|
|
471
|
+
if (secret == null || secret === "") {
|
|
472
|
+
return this.handleFailure(
|
|
473
|
+
record,
|
|
474
|
+
"failed-credentials",
|
|
475
|
+
`credential '${credentialsRef}' could not be resolved or decrypted (missing sys_secret row, or the encryption key changed)`,
|
|
476
|
+
opts.context
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
try {
|
|
481
|
+
const handle = await factory.create({ ...toSpec(record), ...secret ? { secret } : {} });
|
|
482
|
+
if (typeof _optionalChain([handle, 'optionalAccess', _59 => _59.connect]) === "function") await handle.connect();
|
|
483
|
+
const engineDriver = _nullishCoalesce(handle.driver, () => ( handle));
|
|
484
|
+
try {
|
|
485
|
+
engineDriver.name = name;
|
|
486
|
+
} catch (e2) {
|
|
487
|
+
}
|
|
488
|
+
engine.registerDriver(engineDriver);
|
|
489
|
+
_optionalChain([engine, 'access', _60 => _60.registerDatasourceDef, 'optionalCall', _61 => _61({
|
|
490
|
+
name,
|
|
491
|
+
schemaMode: record.schemaMode,
|
|
492
|
+
external: record.external
|
|
493
|
+
})]);
|
|
494
|
+
for (const objectName of _nullishCoalesce(opts.objects, () => ( []))) {
|
|
495
|
+
try {
|
|
496
|
+
await _optionalChain([engine, 'access', _62 => _62.syncObjectSchema, 'optionalCall', _63 => _63(objectName)]);
|
|
497
|
+
} catch (err) {
|
|
498
|
+
_optionalChain([this, 'access', _64 => _64.logger, 'optionalAccess', _65 => _65.warn, 'optionalCall', _66 => _66(`datasource '${name}': syncObjectSchema('${objectName}') failed: ${errMsg(err)}`)]);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
_optionalChain([this, 'access', _67 => _67.logger, 'optionalAccess', _68 => _68.info, 'optionalCall', _69 => _69(`datasource '${name}': connected (driver=${record.driver}, schemaMode=${_nullishCoalesce(record.schemaMode, () => ( "managed"))})`)]);
|
|
502
|
+
return { name, status: "connected" };
|
|
503
|
+
} catch (err) {
|
|
504
|
+
return this.handleFailure(record, "failed-degraded", errMsg(err), opts.context);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/** Gracefully disconnect a previously-registered datasource pool. */
|
|
508
|
+
async disconnect(name) {
|
|
509
|
+
const driver = _optionalChain([this, 'access', _70 => _70.cfg, 'access', _71 => _71.engine, 'call', _72 => _72(), 'optionalAccess', _73 => _73.getDriverByName, 'optionalCall', _74 => _74(name)]);
|
|
510
|
+
if (typeof _optionalChain([driver, 'optionalAccess', _75 => _75.disconnect]) === "function") {
|
|
511
|
+
try {
|
|
512
|
+
await driver.disconnect();
|
|
513
|
+
} catch (err) {
|
|
514
|
+
_optionalChain([this, 'access', _76 => _76.logger, 'optionalAccess', _77 => _77.warn, 'optionalCall', _78 => _78(`datasource '${name}': disconnect failed: ${errMsg(err)}`)]);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Apply the D5 connect-failure policy (also covers D3 credential failures). A
|
|
520
|
+
* code-defined `external` datasource with `onMismatch:'fail'` auto-connected at
|
|
521
|
+
* boot re-throws (fail-fast, bricking boot as intended). Runtime-admin
|
|
522
|
+
* create/update + boot rehydration always degrade-with-warning — a UI action
|
|
523
|
+
* or a replica blip must never brick the running server (preserves the
|
|
524
|
+
* pre-ADR-0062 admin behavior). Either way the datasource is left unconnected
|
|
525
|
+
* with a clear message — never a silent skip.
|
|
526
|
+
*/
|
|
527
|
+
handleFailure(record, status, reason, context) {
|
|
528
|
+
const isExternal = record.schemaMode && record.schemaMode !== "managed";
|
|
529
|
+
const failFast = _optionalChain([context, 'optionalAccess', _79 => _79.trigger]) === "declared-auto" && isExternal && _optionalChain([record, 'access', _80 => _80.external, 'optionalAccess', _81 => _81.validation, 'optionalAccess', _82 => _82.onMismatch]) === "fail";
|
|
530
|
+
const msg = `datasource '${record.name}': connect failed \u2014 ${reason}`;
|
|
531
|
+
if (failFast) {
|
|
532
|
+
throw new Error(
|
|
533
|
+
`${msg}. (schemaMode=${record.schemaMode}, validation.onMismatch='fail' \u21D2 fail-fast per ADR-0062 D5)`
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
_optionalChain([this, 'access', _83 => _83.logger, 'optionalAccess', _84 => _84.warn, 'optionalCall', _85 => _85(`${msg} \u2014 degrading (datasource left unconnected)`)]);
|
|
537
|
+
return { name: record.name, status, reason };
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
function toSpec(record) {
|
|
541
|
+
return {
|
|
542
|
+
name: record.name,
|
|
543
|
+
driver: record.driver,
|
|
544
|
+
config: _nullishCoalesce(record.config, () => ( {})),
|
|
545
|
+
external: record.external,
|
|
546
|
+
pool: record.pool
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
function errMsg(err) {
|
|
550
|
+
return err instanceof Error ? err.message : String(err);
|
|
551
|
+
}
|
|
552
|
+
|
|
371
553
|
// src/datasource-admin-service.ts
|
|
372
554
|
var NAME_RE = /^[a-z_][a-z0-9_]*$/;
|
|
373
555
|
var DatasourceAdminService = class {
|
|
@@ -398,7 +580,7 @@ var DatasourceAdminService = class {
|
|
|
398
580
|
origin: slot.code ? "code" : "runtime",
|
|
399
581
|
active: _nullishCoalesce(effective.active, () => ( true)),
|
|
400
582
|
status: "unvalidated",
|
|
401
|
-
..._optionalChain([slot, 'access',
|
|
583
|
+
..._optionalChain([slot, 'access', _86 => _86.code, 'optionalAccess', _87 => _87.definedIn]) ? { definedIn: slot.code.definedIn } : {},
|
|
402
584
|
...slot.code && slot.runtime ? { conflictsWithCode: true } : {}
|
|
403
585
|
});
|
|
404
586
|
}
|
|
@@ -414,7 +596,7 @@ var DatasourceAdminService = class {
|
|
|
414
596
|
async getDatasource(name) {
|
|
415
597
|
const rec = await this.config.getDatasourceRecord(name);
|
|
416
598
|
if (!rec) return void 0;
|
|
417
|
-
const hasSecret = Boolean(_optionalChain([rec, 'access',
|
|
599
|
+
const hasSecret = Boolean(_optionalChain([rec, 'access', _88 => _88.external, 'optionalAccess', _89 => _89.credentialsRef]));
|
|
418
600
|
return {
|
|
419
601
|
name: rec.name,
|
|
420
602
|
label: rec.label,
|
|
@@ -428,15 +610,15 @@ var DatasourceAdminService = class {
|
|
|
428
610
|
};
|
|
429
611
|
}
|
|
430
612
|
async testConnection(input, secret) {
|
|
431
|
-
if (!_optionalChain([input, 'optionalAccess',
|
|
613
|
+
if (!_optionalChain([input, 'optionalAccess', _90 => _90.driver])) {
|
|
432
614
|
return { ok: false, error: "A driver is required to test a connection." };
|
|
433
615
|
}
|
|
434
|
-
const queryTimeoutMs = _optionalChain([input, 'access',
|
|
616
|
+
const queryTimeoutMs = _optionalChain([input, 'access', _91 => _91.external, 'optionalAccess', _92 => _92.queryTimeoutMs]);
|
|
435
617
|
try {
|
|
436
618
|
return await this.config.probe({
|
|
437
619
|
driver: input.driver,
|
|
438
620
|
config: _nullishCoalesce(input.config, () => ( {})),
|
|
439
|
-
secret: _optionalChain([secret, 'optionalAccess',
|
|
621
|
+
secret: _optionalChain([secret, 'optionalAccess', _93 => _93.value]),
|
|
440
622
|
external: input.external,
|
|
441
623
|
...typeof queryTimeoutMs === "number" ? { timeoutMs: queryTimeoutMs } : {}
|
|
442
624
|
});
|
|
@@ -445,7 +627,7 @@ var DatasourceAdminService = class {
|
|
|
445
627
|
}
|
|
446
628
|
}
|
|
447
629
|
async createDatasource(input, secret) {
|
|
448
|
-
this.assertValidName(_optionalChain([input, 'optionalAccess',
|
|
630
|
+
this.assertValidName(_optionalChain([input, 'optionalAccess', _94 => _94.name]));
|
|
449
631
|
if (!input.driver) throw new Error("A driver is required to create a datasource.");
|
|
450
632
|
const existing = await this.config.getDatasourceRecord(input.name);
|
|
451
633
|
if (existing) {
|
|
@@ -486,10 +668,10 @@ var DatasourceAdminService = class {
|
|
|
486
668
|
origin: "runtime"
|
|
487
669
|
};
|
|
488
670
|
if (patch.external !== void 0) {
|
|
489
|
-
merged.external = { ...patch.external, credentialsRef: _optionalChain([existing, 'access',
|
|
671
|
+
merged.external = { ...patch.external, credentialsRef: _optionalChain([existing, 'access', _95 => _95.external, 'optionalAccess', _96 => _96.credentialsRef]) };
|
|
490
672
|
}
|
|
491
673
|
if (secret) {
|
|
492
|
-
const prevRef = _optionalChain([existing, 'access',
|
|
674
|
+
const prevRef = _optionalChain([existing, 'access', _97 => _97.external, 'optionalAccess', _98 => _98.credentialsRef]);
|
|
493
675
|
const credentialsRef = await this.config.writeSecret(secret, { name });
|
|
494
676
|
merged.external = { ..._nullishCoalesce(merged.external, () => ( {})), credentialsRef };
|
|
495
677
|
if (prevRef && prevRef !== credentialsRef) await this.tryRemoveSecret(prevRef);
|
|
@@ -511,7 +693,7 @@ var DatasourceAdminService = class {
|
|
|
511
693
|
);
|
|
512
694
|
}
|
|
513
695
|
await this.config.deleteDatasourceRecord(name);
|
|
514
|
-
if (_optionalChain([existing, 'access',
|
|
696
|
+
if (_optionalChain([existing, 'access', _99 => _99.external, 'optionalAccess', _100 => _100.credentialsRef])) await this.tryRemoveSecret(existing.external.credentialsRef);
|
|
515
697
|
await this.tryUnregisterPool(name);
|
|
516
698
|
}
|
|
517
699
|
// --- internals -----------------------------------------------------------
|
|
@@ -547,23 +729,23 @@ var DatasourceAdminService = class {
|
|
|
547
729
|
}
|
|
548
730
|
async tryRegisterPool(record) {
|
|
549
731
|
try {
|
|
550
|
-
await _optionalChain([this, 'access',
|
|
732
|
+
await _optionalChain([this, 'access', _101 => _101.config, 'access', _102 => _102.registerPool, 'optionalCall', _103 => _103(record)]);
|
|
551
733
|
} catch (err) {
|
|
552
|
-
_optionalChain([this, 'access',
|
|
734
|
+
_optionalChain([this, 'access', _104 => _104.logger, 'optionalAccess', _105 => _105.warn, 'call', _106 => _106(`registerPool('${record.name}') failed`, err)]);
|
|
553
735
|
}
|
|
554
736
|
}
|
|
555
737
|
async tryUnregisterPool(name) {
|
|
556
738
|
try {
|
|
557
|
-
await _optionalChain([this, 'access',
|
|
739
|
+
await _optionalChain([this, 'access', _107 => _107.config, 'access', _108 => _108.unregisterPool, 'optionalCall', _109 => _109(name)]);
|
|
558
740
|
} catch (err) {
|
|
559
|
-
_optionalChain([this, 'access',
|
|
741
|
+
_optionalChain([this, 'access', _110 => _110.logger, 'optionalAccess', _111 => _111.warn, 'call', _112 => _112(`unregisterPool('${name}') failed`, err)]);
|
|
560
742
|
}
|
|
561
743
|
}
|
|
562
744
|
async tryRemoveSecret(credentialsRef) {
|
|
563
745
|
try {
|
|
564
|
-
await _optionalChain([this, 'access',
|
|
746
|
+
await _optionalChain([this, 'access', _113 => _113.config, 'access', _114 => _114.removeSecret, 'optionalCall', _115 => _115(credentialsRef)]);
|
|
565
747
|
} catch (err) {
|
|
566
|
-
_optionalChain([this, 'access',
|
|
748
|
+
_optionalChain([this, 'access', _116 => _116.logger, 'optionalAccess', _117 => _117.warn, 'call', _118 => _118(`removeSecret('${credentialsRef}') failed`, err)]);
|
|
567
749
|
}
|
|
568
750
|
}
|
|
569
751
|
};
|
|
@@ -576,13 +758,13 @@ function newMetaId() {
|
|
|
576
758
|
return typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `meta_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
577
759
|
}
|
|
578
760
|
async function persistDatasourceRow(engine, record) {
|
|
579
|
-
if (!_optionalChain([engine, 'optionalAccess',
|
|
761
|
+
if (!_optionalChain([engine, 'optionalAccess', _119 => _119.insert]) || !engine.findOne) return;
|
|
580
762
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
581
763
|
const existing = await engine.findOne(SYS_METADATA, {
|
|
582
764
|
where: { type: DS_META_TYPE, name: record.name, state: "active" }
|
|
583
765
|
});
|
|
584
766
|
if (existing) {
|
|
585
|
-
await _optionalChain([engine, 'access',
|
|
767
|
+
await _optionalChain([engine, 'access', _120 => _120.update, 'optionalCall', _121 => _121(
|
|
586
768
|
SYS_METADATA,
|
|
587
769
|
{ metadata: JSON.stringify(record), updated_at: now, version: (existing.version || 0) + 1, state: "active" },
|
|
588
770
|
{ where: { id: existing.id } }
|
|
@@ -602,21 +784,21 @@ async function persistDatasourceRow(engine, record) {
|
|
|
602
784
|
}
|
|
603
785
|
}
|
|
604
786
|
async function deleteDatasourceRow(engine, name) {
|
|
605
|
-
if (!_optionalChain([engine, 'optionalAccess',
|
|
787
|
+
if (!_optionalChain([engine, 'optionalAccess', _122 => _122.findOne])) return;
|
|
606
788
|
const existing = await engine.findOne(SYS_METADATA, { where: { type: DS_META_TYPE, name, state: "active" } });
|
|
607
789
|
if (!existing) return;
|
|
608
790
|
if (engine.delete) await engine.delete(SYS_METADATA, { where: { id: existing.id } });
|
|
609
|
-
else await _optionalChain([engine, 'access',
|
|
791
|
+
else await _optionalChain([engine, 'access', _123 => _123.update, 'optionalCall', _124 => _124(SYS_METADATA, { state: "inactive" }, { where: { id: existing.id } })]);
|
|
610
792
|
}
|
|
611
793
|
async function loadDatasourceRows(engine) {
|
|
612
|
-
if (!_optionalChain([engine, 'optionalAccess',
|
|
794
|
+
if (!_optionalChain([engine, 'optionalAccess', _125 => _125.find])) return [];
|
|
613
795
|
const rows = await engine.find(SYS_METADATA, { where: { type: DS_META_TYPE, state: "active" } });
|
|
614
796
|
const out = [];
|
|
615
797
|
for (const r of _nullishCoalesce(rows, () => ( []))) {
|
|
616
798
|
const raw = r.metadata;
|
|
617
799
|
try {
|
|
618
800
|
out.push(typeof raw === "string" ? JSON.parse(raw) : raw);
|
|
619
|
-
} catch (
|
|
801
|
+
} catch (e3) {
|
|
620
802
|
}
|
|
621
803
|
}
|
|
622
804
|
return out;
|
|
@@ -647,19 +829,27 @@ var DatasourceAdminServicePlugin = class {
|
|
|
647
829
|
const metadataOf = () => safeGetService2(ctx, "metadata");
|
|
648
830
|
const engineOf = () => safeGetService2(ctx, "data");
|
|
649
831
|
const factory = () => _nullishCoalesce(this.options.driverFactory, () => ( safeGetService2(ctx, "datasource-driver-factory")));
|
|
832
|
+
this.connection = new DatasourceConnectionService({
|
|
833
|
+
factory,
|
|
834
|
+
engine: () => engineOf(),
|
|
835
|
+
secrets: { resolve: (ref) => _nullishCoalesce(_optionalChain([this, 'access', _126 => _126.options, 'access', _127 => _127.secrets, 'optionalAccess', _128 => _128.resolve, 'optionalCall', _129 => _129(ref)]), () => ( Promise.resolve(void 0))) },
|
|
836
|
+
policy: this.options.connectPolicy,
|
|
837
|
+
logger: this.options.logger
|
|
838
|
+
});
|
|
839
|
+
ctx.registerService("datasource-connection", this.connection);
|
|
650
840
|
const config = {
|
|
651
841
|
probe: (input) => this.probe(factory(), input),
|
|
652
842
|
listDatasourceRecords: async () => {
|
|
653
|
-
const rows = await _asyncNullishCoalesce(await _optionalChain([metadataOf, 'call',
|
|
843
|
+
const rows = await _asyncNullishCoalesce(await _optionalChain([metadataOf, 'call', _130 => _130(), 'optionalAccess', _131 => _131.list, 'call', _132 => _132("datasource")]), async () => ( []));
|
|
654
844
|
return rows.map((r) => ({ ...r, origin: _nullishCoalesce(r.origin, () => ( "code")) }));
|
|
655
845
|
},
|
|
656
846
|
getDatasourceRecord: async (name) => {
|
|
657
|
-
const row = await _optionalChain([metadataOf, 'call',
|
|
847
|
+
const row = await _optionalChain([metadataOf, 'call', _133 => _133(), 'optionalAccess', _134 => _134.get, 'call', _135 => _135("datasource", name)]);
|
|
658
848
|
return row ? { ...row, origin: _nullishCoalesce(row.origin, () => ( "code")) } : void 0;
|
|
659
849
|
},
|
|
660
850
|
putDatasourceRecord: async (record) => {
|
|
661
851
|
const metadata = metadataOf();
|
|
662
|
-
if (!_optionalChain([metadata, 'optionalAccess',
|
|
852
|
+
if (!_optionalChain([metadata, 'optionalAccess', _136 => _136.register])) {
|
|
663
853
|
throw new Error("Metadata service is unavailable; cannot persist datasource.");
|
|
664
854
|
}
|
|
665
855
|
await metadata.register("datasource", record.name, record);
|
|
@@ -667,7 +857,7 @@ var DatasourceAdminServicePlugin = class {
|
|
|
667
857
|
},
|
|
668
858
|
deleteDatasourceRecord: async (name) => {
|
|
669
859
|
const metadata = metadataOf();
|
|
670
|
-
if (!_optionalChain([metadata, 'optionalAccess',
|
|
860
|
+
if (!_optionalChain([metadata, 'optionalAccess', _137 => _137.unregister])) {
|
|
671
861
|
throw new Error("Metadata service is unavailable; cannot remove datasource.");
|
|
672
862
|
}
|
|
673
863
|
await metadata.unregister("datasource", name);
|
|
@@ -675,7 +865,7 @@ var DatasourceAdminServicePlugin = class {
|
|
|
675
865
|
},
|
|
676
866
|
writeSecret: async (input, hint) => {
|
|
677
867
|
const binder = this.options.secrets;
|
|
678
|
-
if (!_optionalChain([binder, 'optionalAccess',
|
|
868
|
+
if (!_optionalChain([binder, 'optionalAccess', _138 => _138.bind])) {
|
|
679
869
|
throw new Error(
|
|
680
870
|
"No secret store configured: refusing to persist a datasource credential in cleartext. Wire a SecretBinder (CryptoProvider + sys_secret) into DatasourceAdminServicePlugin."
|
|
681
871
|
);
|
|
@@ -683,36 +873,27 @@ var DatasourceAdminServicePlugin = class {
|
|
|
683
873
|
return binder.bind(input, hint);
|
|
684
874
|
},
|
|
685
875
|
removeSecret: async (ref) => {
|
|
686
|
-
await _optionalChain([this, 'access',
|
|
876
|
+
await _optionalChain([this, 'access', _139 => _139.options, 'access', _140 => _140.secrets, 'optionalAccess', _141 => _141.unbind, 'optionalCall', _142 => _142(ref)]);
|
|
687
877
|
},
|
|
688
878
|
countBoundObjects: async (datasource) => {
|
|
689
879
|
const metadata = metadataOf();
|
|
690
|
-
const objects = await _asyncNullishCoalesce(await _asyncNullishCoalesce(await _optionalChain([metadata, 'optionalAccess',
|
|
691
|
-
return objects.filter((o) => _optionalChain([o, 'optionalAccess',
|
|
880
|
+
const objects = await _asyncNullishCoalesce(await _asyncNullishCoalesce(await _optionalChain([metadata, 'optionalAccess', _143 => _143.listObjects, 'optionalCall', _144 => _144()]), async () => ( await _optionalChain([metadata, 'optionalAccess', _145 => _145.list, 'call', _146 => _146("object")]))), async () => ( []));
|
|
881
|
+
return objects.filter((o) => _optionalChain([o, 'optionalAccess', _147 => _147.datasource]) === datasource).length;
|
|
692
882
|
},
|
|
883
|
+
// Hot pool (de)registration converges on the shared
|
|
884
|
+
// DatasourceConnectionService (ADR-0062 D1) — one connect path for code-
|
|
885
|
+
// and runtime-origin datasources. `connect()` builds the driver via the
|
|
886
|
+
// factory, dereferences `external.credentialsRef` through the SecretBinder,
|
|
887
|
+
// opens the connection, and registers the live driver + datasource def.
|
|
888
|
+
// Runtime-admin connects always degrade-with-warning on failure (never
|
|
889
|
+
// fail-fast), preserving the pre-ADR-0062 admin behavior.
|
|
693
890
|
registerPool: async (record) => {
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
if (!f || !_optionalChain([engine, 'optionalAccess', _96 => _96.registerDriver]) || !f.supports(record.driver)) return;
|
|
697
|
-
const credentialsRef = _optionalChain([record, 'access', _97 => _97.external, 'optionalAccess', _98 => _98.credentialsRef]);
|
|
698
|
-
const secret = credentialsRef ? await _optionalChain([this, 'access', _99 => _99.options, 'access', _100 => _100.secrets, 'optionalAccess', _101 => _101.resolve, 'optionalCall', _102 => _102(credentialsRef)]) : void 0;
|
|
699
|
-
const handle = await f.create({ ...this.toSpec(record), ...secret ? { secret } : {} });
|
|
700
|
-
if (typeof _optionalChain([handle, 'optionalAccess', _103 => _103.connect]) === "function") await handle.connect();
|
|
701
|
-
const engineDriver = _nullishCoalesce(handle.driver, () => ( handle));
|
|
702
|
-
try {
|
|
703
|
-
engineDriver.name = record.name;
|
|
704
|
-
} catch (e3) {
|
|
705
|
-
}
|
|
706
|
-
engine.registerDriver(engineDriver);
|
|
707
|
-
_optionalChain([engine, 'access', _104 => _104.registerDatasourceDef, 'optionalCall', _105 => _105({
|
|
708
|
-
name: record.name,
|
|
709
|
-
schemaMode: record.schemaMode,
|
|
710
|
-
external: record.external
|
|
891
|
+
await _optionalChain([this, 'access', _148 => _148.connection, 'optionalAccess', _149 => _149.connect, 'call', _150 => _150(record, {
|
|
892
|
+
context: { origin: _nullishCoalesce(record.origin, () => ( "runtime")), trigger: "runtime-admin" }
|
|
711
893
|
})]);
|
|
712
894
|
},
|
|
713
895
|
unregisterPool: async (name) => {
|
|
714
|
-
|
|
715
|
-
if (typeof _optionalChain([driver, 'optionalAccess', _109 => _109.disconnect]) === "function") await driver.disconnect();
|
|
896
|
+
await _optionalChain([this, 'access', _151 => _151.connection, 'optionalAccess', _152 => _152.disconnect, 'call', _153 => _153(name)]);
|
|
716
897
|
},
|
|
717
898
|
logger
|
|
718
899
|
};
|
|
@@ -750,7 +931,7 @@ var DatasourceAdminServicePlugin = class {
|
|
|
750
931
|
});
|
|
751
932
|
}
|
|
752
933
|
} catch (err) {
|
|
753
|
-
_optionalChain([this, 'access',
|
|
934
|
+
_optionalChain([this, 'access', _154 => _154.options, 'access', _155 => _155.logger, 'optionalAccess', _156 => _156.warn, 'optionalCall', _157 => _157("datasource nav contribution skipped", err)]);
|
|
754
935
|
}
|
|
755
936
|
}
|
|
756
937
|
async start(ctx) {
|
|
@@ -762,12 +943,12 @@ var DatasourceAdminServicePlugin = class {
|
|
|
762
943
|
async restoreRuntimeDatasources(ctx) {
|
|
763
944
|
const engine = safeGetService2(ctx, "data");
|
|
764
945
|
const metadata = safeGetService2(ctx, "metadata");
|
|
765
|
-
if (!_optionalChain([engine, 'optionalAccess',
|
|
946
|
+
if (!_optionalChain([engine, 'optionalAccess', _158 => _158.find]) || !_optionalChain([metadata, 'optionalAccess', _159 => _159.register])) return;
|
|
766
947
|
let rows;
|
|
767
948
|
try {
|
|
768
949
|
rows = await loadDatasourceRows(engine);
|
|
769
950
|
} catch (err) {
|
|
770
|
-
_optionalChain([this, 'access',
|
|
951
|
+
_optionalChain([this, 'access', _160 => _160.options, 'access', _161 => _161.logger, 'optionalAccess', _162 => _162.warn, 'optionalCall', _163 => _163("datasource restore: reading sys_metadata failed", err)]);
|
|
771
952
|
return;
|
|
772
953
|
}
|
|
773
954
|
let restored = 0;
|
|
@@ -778,10 +959,10 @@ var DatasourceAdminServicePlugin = class {
|
|
|
778
959
|
await metadata.register("datasource", name, rec);
|
|
779
960
|
restored += 1;
|
|
780
961
|
} catch (err) {
|
|
781
|
-
_optionalChain([this, 'access',
|
|
962
|
+
_optionalChain([this, 'access', _164 => _164.options, 'access', _165 => _165.logger, 'optionalAccess', _166 => _166.warn, 'optionalCall', _167 => _167(`datasource restore: register '${name}' failed`, err)]);
|
|
782
963
|
}
|
|
783
964
|
}
|
|
784
|
-
if (restored > 0) _optionalChain([this, 'access',
|
|
965
|
+
if (restored > 0) _optionalChain([this, 'access', _168 => _168.options, 'access', _169 => _169.logger, 'optionalAccess', _170 => _170.info, 'optionalCall', _171 => _171(`datasource: restored ${restored} runtime record(s) from sys_metadata`)]);
|
|
785
966
|
}
|
|
786
967
|
/**
|
|
787
968
|
* Boot-time rehydration: list persisted runtime datasources and re-register
|
|
@@ -794,12 +975,12 @@ var DatasourceAdminServicePlugin = class {
|
|
|
794
975
|
*/
|
|
795
976
|
async rehydratePools() {
|
|
796
977
|
const cfg = this.config;
|
|
797
|
-
if (!_optionalChain([cfg, 'optionalAccess',
|
|
978
|
+
if (!_optionalChain([cfg, 'optionalAccess', _172 => _172.registerPool]) || !cfg.listDatasourceRecords) return;
|
|
798
979
|
let records;
|
|
799
980
|
try {
|
|
800
981
|
records = await cfg.listDatasourceRecords();
|
|
801
982
|
} catch (err) {
|
|
802
|
-
_optionalChain([this, 'access',
|
|
983
|
+
_optionalChain([this, 'access', _173 => _173.options, 'access', _174 => _174.logger, 'optionalAccess', _175 => _175.warn, 'optionalCall', _176 => _176("datasource rehydrate: listing records failed", err)]);
|
|
803
984
|
return;
|
|
804
985
|
}
|
|
805
986
|
const runtime = records.filter((r) => r.origin === "runtime" && (_nullishCoalesce(r.active, () => ( true))));
|
|
@@ -810,10 +991,10 @@ var DatasourceAdminServicePlugin = class {
|
|
|
810
991
|
await cfg.registerPool(record);
|
|
811
992
|
registered++;
|
|
812
993
|
} catch (err) {
|
|
813
|
-
_optionalChain([this, 'access',
|
|
994
|
+
_optionalChain([this, 'access', _177 => _177.options, 'access', _178 => _178.logger, 'optionalAccess', _179 => _179.warn, 'optionalCall', _180 => _180(`datasource rehydrate: pool '${record.name}' failed`, err)]);
|
|
814
995
|
}
|
|
815
996
|
}
|
|
816
|
-
_optionalChain([this, 'access',
|
|
997
|
+
_optionalChain([this, 'access', _181 => _181.options, 'access', _182 => _182.logger, 'optionalAccess', _183 => _183.info, 'optionalCall', _184 => _184(
|
|
817
998
|
`Rehydrated ${registered}/${runtime.length} runtime datasource pool(s) on boot`
|
|
818
999
|
)]);
|
|
819
1000
|
}
|
|
@@ -821,15 +1002,6 @@ var DatasourceAdminServicePlugin = class {
|
|
|
821
1002
|
this.service = void 0;
|
|
822
1003
|
}
|
|
823
1004
|
// --- internals -----------------------------------------------------------
|
|
824
|
-
toSpec(record) {
|
|
825
|
-
return {
|
|
826
|
-
name: record.name,
|
|
827
|
-
driver: record.driver,
|
|
828
|
-
config: _nullishCoalesce(record.config, () => ( {})),
|
|
829
|
-
external: record.external,
|
|
830
|
-
pool: record.pool
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
1005
|
/** Probe a connection via the driver factory: build → connect → ping → close. */
|
|
834
1006
|
async probe(factory, input) {
|
|
835
1007
|
if (!factory) {
|
|
@@ -847,26 +1019,26 @@ var DatasourceAdminServicePlugin = class {
|
|
|
847
1019
|
external: input.external
|
|
848
1020
|
});
|
|
849
1021
|
} catch (err) {
|
|
850
|
-
return { ok: false, error: `Failed to build driver: ${
|
|
1022
|
+
return { ok: false, error: `Failed to build driver: ${errMsg2(err)}` };
|
|
851
1023
|
}
|
|
852
1024
|
const startedAt = monotonicNow();
|
|
853
1025
|
try {
|
|
854
|
-
if (typeof _optionalChain([driver, 'optionalAccess',
|
|
855
|
-
if (typeof _optionalChain([driver, 'optionalAccess',
|
|
856
|
-
else if (typeof _optionalChain([driver, 'optionalAccess',
|
|
857
|
-
else if (typeof _optionalChain([driver, 'optionalAccess',
|
|
1026
|
+
if (typeof _optionalChain([driver, 'optionalAccess', _185 => _185.connect]) === "function") await driver.connect();
|
|
1027
|
+
if (typeof _optionalChain([driver, 'optionalAccess', _186 => _186.ping]) === "function") await driver.ping();
|
|
1028
|
+
else if (typeof _optionalChain([driver, 'optionalAccess', _187 => _187.checkHealth]) === "function") await driver.checkHealth();
|
|
1029
|
+
else if (typeof _optionalChain([driver, 'optionalAccess', _188 => _188.introspectSchema]) === "function") await driver.introspectSchema();
|
|
858
1030
|
const latencyMs = elapsedSince(startedAt);
|
|
859
1031
|
let serverVersion;
|
|
860
1032
|
try {
|
|
861
|
-
serverVersion = typeof _optionalChain([driver, 'optionalAccess',
|
|
1033
|
+
serverVersion = typeof _optionalChain([driver, 'optionalAccess', _189 => _189.serverVersion]) === "function" ? await driver.serverVersion() : void 0;
|
|
862
1034
|
} catch (e4) {
|
|
863
1035
|
}
|
|
864
1036
|
return { ok: true, latencyMs, ...serverVersion ? { serverVersion } : {} };
|
|
865
1037
|
} catch (err) {
|
|
866
|
-
return { ok: false, error:
|
|
1038
|
+
return { ok: false, error: errMsg2(err) };
|
|
867
1039
|
} finally {
|
|
868
1040
|
try {
|
|
869
|
-
if (typeof _optionalChain([driver, 'optionalAccess',
|
|
1041
|
+
if (typeof _optionalChain([driver, 'optionalAccess', _190 => _190.disconnect]) === "function") await driver.disconnect();
|
|
870
1042
|
} catch (e5) {
|
|
871
1043
|
}
|
|
872
1044
|
}
|
|
@@ -879,12 +1051,12 @@ function safeGetService2(ctx, name) {
|
|
|
879
1051
|
return void 0;
|
|
880
1052
|
}
|
|
881
1053
|
}
|
|
882
|
-
function
|
|
1054
|
+
function errMsg2(err) {
|
|
883
1055
|
return err instanceof Error ? err.message : String(err);
|
|
884
1056
|
}
|
|
885
1057
|
function monotonicNow() {
|
|
886
1058
|
const perf = globalThis.performance;
|
|
887
|
-
return typeof _optionalChain([perf, 'optionalAccess',
|
|
1059
|
+
return typeof _optionalChain([perf, 'optionalAccess', _191 => _191.now]) === "function" ? perf.now() : 0;
|
|
888
1060
|
}
|
|
889
1061
|
function elapsedSince(startedAt) {
|
|
890
1062
|
return Math.max(0, Math.round(monotonicNow() - startedAt));
|
|
@@ -909,10 +1081,10 @@ function resolveKind(driverId) {
|
|
|
909
1081
|
}
|
|
910
1082
|
function toHandle(driver, serverVersion) {
|
|
911
1083
|
return {
|
|
912
|
-
connect: typeof _optionalChain([driver, 'optionalAccess',
|
|
913
|
-
disconnect: typeof _optionalChain([driver, 'optionalAccess',
|
|
914
|
-
checkHealth: typeof _optionalChain([driver, 'optionalAccess',
|
|
915
|
-
ping: typeof _optionalChain([driver, 'optionalAccess',
|
|
1084
|
+
connect: typeof _optionalChain([driver, 'optionalAccess', _192 => _192.connect]) === "function" ? () => driver.connect() : void 0,
|
|
1085
|
+
disconnect: typeof _optionalChain([driver, 'optionalAccess', _193 => _193.disconnect]) === "function" ? () => driver.disconnect() : void 0,
|
|
1086
|
+
checkHealth: typeof _optionalChain([driver, 'optionalAccess', _194 => _194.checkHealth]) === "function" ? () => driver.checkHealth() : void 0,
|
|
1087
|
+
ping: typeof _optionalChain([driver, 'optionalAccess', _195 => _195.checkHealth]) === "function" ? () => driver.checkHealth() : void 0,
|
|
916
1088
|
...serverVersion ? { serverVersion } : {},
|
|
917
1089
|
driver
|
|
918
1090
|
};
|
|
@@ -947,7 +1119,7 @@ function buildMongoUrl(spec) {
|
|
|
947
1119
|
const auth = user ? `${encodeURIComponent(user)}:${encodeURIComponent(_nullishCoalesce(spec.secret, () => ( "")))}@` : "";
|
|
948
1120
|
return `mongodb://${auth}${host}:${port}/${db}`;
|
|
949
1121
|
}
|
|
950
|
-
function createDefaultDatasourceDriverFactory() {
|
|
1122
|
+
function createDefaultDatasourceDriverFactory(options = {}) {
|
|
951
1123
|
return {
|
|
952
1124
|
supports(driverId) {
|
|
953
1125
|
return resolveKind(driverId) !== void 0;
|
|
@@ -957,7 +1129,7 @@ function createDefaultDatasourceDriverFactory() {
|
|
|
957
1129
|
if (!kind) {
|
|
958
1130
|
throw new Error(`Unsupported driver id '${spec.driver}'.`);
|
|
959
1131
|
}
|
|
960
|
-
const schemaMode = _nullishCoalesce(_optionalChain([spec, 'access',
|
|
1132
|
+
const schemaMode = _nullishCoalesce(_optionalChain([spec, 'access', _196 => _196.external, 'optionalAccess', _197 => _197.schemaMode]), () => ( _optionalChain([spec, 'access', _198 => _198.config, 'optionalAccess', _199 => _199.schemaMode])));
|
|
961
1133
|
if (kind === "postgres") {
|
|
962
1134
|
const { SqlDriver } = await Promise.resolve().then(() => _interopRequireWildcard(require("@objectstack/driver-sql")));
|
|
963
1135
|
const driver = new SqlDriver({
|
|
@@ -969,14 +1141,14 @@ function createDefaultDatasourceDriverFactory() {
|
|
|
969
1141
|
return toHandle(driver, () => sqlServerVersion(driver, "pg"));
|
|
970
1142
|
}
|
|
971
1143
|
if (kind === "sqlite") {
|
|
972
|
-
const
|
|
973
|
-
const
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1144
|
+
const conn = buildSqlConnection(spec, "better-sqlite3");
|
|
1145
|
+
const { resolveSqliteDriver: resolveSqliteDriver2 } = await Promise.resolve().then(() => _interopRequireWildcard(require("./sqlite-driver-fallback-JX4XOICD.cjs")));
|
|
1146
|
+
const resolved = await resolveSqliteDriver2({
|
|
1147
|
+
filename: _nullishCoalesce(conn.filename, () => ( ":memory:")),
|
|
1148
|
+
dev: options.dev,
|
|
977
1149
|
...schemaMode ? { schemaMode } : {}
|
|
978
1150
|
});
|
|
979
|
-
return toHandle(driver, () => sqlServerVersion(driver, "sqlite"));
|
|
1151
|
+
return toHandle(resolved.driver, () => sqlServerVersion(resolved.driver, "sqlite"));
|
|
980
1152
|
}
|
|
981
1153
|
if (kind === "mongodb") {
|
|
982
1154
|
let MongoDBDriver;
|
|
@@ -984,7 +1156,7 @@ function createDefaultDatasourceDriverFactory() {
|
|
|
984
1156
|
({ MongoDBDriver } = await Promise.resolve().then(() => _interopRequireWildcard(require("@objectstack/driver-mongodb"))));
|
|
985
1157
|
} catch (err) {
|
|
986
1158
|
throw new Error(
|
|
987
|
-
`mongodb driver requested but @objectstack/driver-mongodb is not installed (${_nullishCoalesce(_optionalChain([err, 'optionalAccess',
|
|
1159
|
+
`mongodb driver requested but @objectstack/driver-mongodb is not installed (${_nullishCoalesce(_optionalChain([err, 'optionalAccess', _200 => _200.message]), () => ( err))}).`
|
|
988
1160
|
);
|
|
989
1161
|
}
|
|
990
1162
|
const driver = new MongoDBDriver({ url: buildMongoUrl(spec) });
|
|
@@ -996,12 +1168,12 @@ function createDefaultDatasourceDriverFactory() {
|
|
|
996
1168
|
};
|
|
997
1169
|
}
|
|
998
1170
|
async function sqlServerVersion(driver, client) {
|
|
999
|
-
if (typeof _optionalChain([driver, 'optionalAccess',
|
|
1171
|
+
if (typeof _optionalChain([driver, 'optionalAccess', _201 => _201.execute]) !== "function") return void 0;
|
|
1000
1172
|
try {
|
|
1001
1173
|
const sql = client === "pg" ? "SELECT version() AS v" : "SELECT sqlite_version() AS v";
|
|
1002
1174
|
const rows = await driver.execute(sql);
|
|
1003
|
-
const first = Array.isArray(rows) ? rows[0] : Array.isArray(_optionalChain([rows, 'optionalAccess',
|
|
1004
|
-
const v = _nullishCoalesce(_nullishCoalesce(_optionalChain([first, 'optionalAccess',
|
|
1175
|
+
const first = Array.isArray(rows) ? rows[0] : Array.isArray(_optionalChain([rows, 'optionalAccess', _202 => _202.rows])) ? rows.rows[0] : rows;
|
|
1176
|
+
const v = _nullishCoalesce(_nullishCoalesce(_optionalChain([first, 'optionalAccess', _203 => _203.v]), () => ( _optionalChain([first, 'optionalAccess', _204 => _204.version]))), () => ( _optionalChain([first, 'optionalAccess', _205 => _205["sqlite_version()"]])));
|
|
1005
1177
|
return typeof v === "string" ? v : void 0;
|
|
1006
1178
|
} catch (e7) {
|
|
1007
1179
|
return void 0;
|
|
@@ -1014,7 +1186,7 @@ function toCredentialsRef(handleId) {
|
|
|
1014
1186
|
return `${REF_PREFIX}${handleId}`;
|
|
1015
1187
|
}
|
|
1016
1188
|
function parseCredentialsRef(ref) {
|
|
1017
|
-
return _optionalChain([ref, 'optionalAccess',
|
|
1189
|
+
return _optionalChain([ref, 'optionalAccess', _206 => _206.startsWith, 'call', _207 => _207(REF_PREFIX)]) ? ref.slice(REF_PREFIX.length) : void 0;
|
|
1018
1190
|
}
|
|
1019
1191
|
function createDatasourceSecretBinder(deps) {
|
|
1020
1192
|
const { engine, cryptoProvider } = deps;
|
|
@@ -1051,9 +1223,9 @@ function createDatasourceSecretBinder(deps) {
|
|
|
1051
1223
|
// skip the tenant-audit warning (mirrors SettingsService's store).
|
|
1052
1224
|
bypassTenantAudit: true
|
|
1053
1225
|
});
|
|
1054
|
-
const rows = _nullishCoalesce((Array.isArray(result) ? result : _optionalChain([result, 'optionalAccess',
|
|
1226
|
+
const rows = _nullishCoalesce((Array.isArray(result) ? result : _optionalChain([result, 'optionalAccess', _208 => _208.data])), () => ( []));
|
|
1055
1227
|
const row = rows[0];
|
|
1056
|
-
if (!_optionalChain([row, 'optionalAccess',
|
|
1228
|
+
if (!_optionalChain([row, 'optionalAccess', _209 => _209.ciphertext])) return void 0;
|
|
1057
1229
|
return await cryptoProvider.decrypt(
|
|
1058
1230
|
{
|
|
1059
1231
|
id: row.id,
|
|
@@ -1183,7 +1355,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1183
1355
|
};
|
|
1184
1356
|
server.get(root, async (_req, res) => {
|
|
1185
1357
|
const svc = adminService();
|
|
1186
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1358
|
+
if (!_optionalChain([svc, 'optionalAccess', _210 => _210.listDatasources])) return unavailable(res);
|
|
1187
1359
|
const datasources = await svc.listDatasources();
|
|
1188
1360
|
res.json({ datasources });
|
|
1189
1361
|
});
|
|
@@ -1192,7 +1364,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1192
1364
|
});
|
|
1193
1365
|
server.get(`${root}/:name/remote-tables`, async (req, res) => {
|
|
1194
1366
|
const svc = externalService();
|
|
1195
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1367
|
+
if (!_optionalChain([svc, 'optionalAccess', _211 => _211.listRemoteTables])) return unavailable(res);
|
|
1196
1368
|
try {
|
|
1197
1369
|
const tables = await svc.listRemoteTables(req.params.name);
|
|
1198
1370
|
res.json({ tables });
|
|
@@ -1202,7 +1374,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1202
1374
|
});
|
|
1203
1375
|
server.get(`${root}/:name`, async (req, res) => {
|
|
1204
1376
|
const svc = adminService();
|
|
1205
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1377
|
+
if (!_optionalChain([svc, 'optionalAccess', _212 => _212.getDatasource])) return unavailable(res);
|
|
1206
1378
|
try {
|
|
1207
1379
|
const datasource = await svc.getDatasource(req.params.name);
|
|
1208
1380
|
if (!datasource) return res.status(404).json({ error: "not_found" });
|
|
@@ -1213,7 +1385,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1213
1385
|
});
|
|
1214
1386
|
server.post(`${root}/:name/test`, async (req, res) => {
|
|
1215
1387
|
const svc = externalService();
|
|
1216
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1388
|
+
if (!_optionalChain([svc, 'optionalAccess', _213 => _213.testConnection])) return unavailable(res);
|
|
1217
1389
|
try {
|
|
1218
1390
|
const result = await svc.testConnection(req.params.name);
|
|
1219
1391
|
res.json(result);
|
|
@@ -1223,7 +1395,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1223
1395
|
});
|
|
1224
1396
|
server.post(`${root}/:name/object-draft`, async (req, res) => {
|
|
1225
1397
|
const svc = externalService();
|
|
1226
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1398
|
+
if (!_optionalChain([svc, 'optionalAccess', _214 => _214.generateObjectDraft])) return unavailable(res);
|
|
1227
1399
|
const { table, ...opts } = _nullishCoalesce(req.body, () => ( {}));
|
|
1228
1400
|
if (!table) return badRequest(res, new Error('Body field "table" is required.'));
|
|
1229
1401
|
try {
|
|
@@ -1235,7 +1407,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1235
1407
|
});
|
|
1236
1408
|
server.post(`${root}/test`, async (req, res) => {
|
|
1237
1409
|
const svc = adminService();
|
|
1238
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1410
|
+
if (!_optionalChain([svc, 'optionalAccess', _215 => _215.testConnection])) return unavailable(res);
|
|
1239
1411
|
const { draft, secret } = splitSecret(req.body);
|
|
1240
1412
|
try {
|
|
1241
1413
|
const result = await svc.testConnection(draft, secret);
|
|
@@ -1246,7 +1418,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1246
1418
|
});
|
|
1247
1419
|
server.post(root, async (req, res) => {
|
|
1248
1420
|
const svc = adminService();
|
|
1249
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1421
|
+
if (!_optionalChain([svc, 'optionalAccess', _216 => _216.createDatasource])) return unavailable(res);
|
|
1250
1422
|
const { draft, secret } = splitSecret(req.body);
|
|
1251
1423
|
try {
|
|
1252
1424
|
const datasource = await svc.createDatasource(draft, secret);
|
|
@@ -1257,7 +1429,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1257
1429
|
});
|
|
1258
1430
|
server.patch(`${root}/:name`, async (req, res) => {
|
|
1259
1431
|
const svc = adminService();
|
|
1260
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1432
|
+
if (!_optionalChain([svc, 'optionalAccess', _217 => _217.updateDatasource])) return unavailable(res);
|
|
1261
1433
|
const { draft, secret } = splitSecret(req.body);
|
|
1262
1434
|
try {
|
|
1263
1435
|
const datasource = await svc.updateDatasource(req.params.name, draft, secret);
|
|
@@ -1268,7 +1440,7 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1268
1440
|
});
|
|
1269
1441
|
server.delete(`${root}/:name`, async (req, res) => {
|
|
1270
1442
|
const svc = adminService();
|
|
1271
|
-
if (!_optionalChain([svc, 'optionalAccess',
|
|
1443
|
+
if (!_optionalChain([svc, 'optionalAccess', _218 => _218.removeDatasource])) return unavailable(res);
|
|
1272
1444
|
try {
|
|
1273
1445
|
await svc.removeDatasource(req.params.name);
|
|
1274
1446
|
res.status(204).end();
|
|
@@ -1287,5 +1459,11 @@ function registerDatasourceAdminRoutes(server, ctx, basePath = "/api/v1") {
|
|
|
1287
1459
|
|
|
1288
1460
|
|
|
1289
1461
|
|
|
1290
|
-
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
|
|
1468
|
+
exports.DatasourceAdminService = DatasourceAdminService; exports.DatasourceAdminServicePlugin = DatasourceAdminServicePlugin; exports.DatasourceConnectionService = DatasourceConnectionService; exports.ExternalDatasourceService = ExternalDatasourceService; exports.ExternalDatasourceServicePlugin = ExternalDatasourceServicePlugin; exports.NATIVE_SQLITE_MEMORY_FALLBACK_WARNING = _chunk76HQ74MXcjs.NATIVE_SQLITE_MEMORY_FALLBACK_WARNING; exports.NATIVE_SQLITE_WASM_FALLBACK_WARNING = _chunk76HQ74MXcjs.NATIVE_SQLITE_WASM_FALLBACK_WARNING; exports.allowAllConnectPolicy = _chunkBI2SYWLCcjs.allowAllConnectPolicy; exports.createDatasourceSecretBinder = createDatasourceSecretBinder; exports.createDefaultDatasourceDriverFactory = createDefaultDatasourceDriverFactory; exports.isDatasourceAddressed = isDatasourceAddressed; exports.parseCredentialsRef = parseCredentialsRef; exports.registerDatasourceAdminRoutes = registerDatasourceAdminRoutes; exports.resolveSqliteDriver = _chunk76HQ74MXcjs.resolveSqliteDriver; exports.toCredentialsRef = toCredentialsRef;
|
|
1291
1469
|
//# sourceMappingURL=index.cjs.map
|