@malloy-publisher/server 0.0.192 → 0.0.193
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/dist/app/api-doc.yaml +522 -1
- package/dist/app/assets/{HomePage-H1OH-VW5.js → HomePage-Di9MU3lS.js} +1 -1
- package/dist/app/assets/{MainPage-GL06aMke.js → MainPage-yZQo2HSL.js} +1 -1
- package/dist/app/assets/{ModelPage-Crau5hgZ.js → ModelPage-Dx2mHWeT.js} +1 -1
- package/dist/app/assets/{PackagePage-CbubRhgE.js → PackagePage-Q386Py9t.js} +1 -1
- package/dist/app/assets/{ProjectPage-DUlJkYJ4.js → ProjectPage-WR7wPQB-.js} +1 -1
- package/dist/app/assets/{RouteError-DrNXNihc.js → RouteError-stRGU4aW.js} +1 -1
- package/dist/app/assets/{WorkbookPage-CBBv7n5U.js → WorkbookPage-D3iX0djH.js} +1 -1
- package/dist/app/assets/{core-Dzx75uJR.es-DwnFZnyO.js → core-QH4HZQVz.es-CqlQLZdl.js} +1 -1
- package/dist/app/assets/{index-d5rvmoZ7.js → index-CVHzPJwN.js} +119 -119
- package/dist/app/assets/{index-CzjyS9cx.js → index-DavAceYD.js} +50 -50
- package/dist/app/assets/{index-HHdhLUpv.js → index-Y3Y-VRna.js} +1 -1
- package/dist/app/assets/{index.umd-CetYIBQY.js → index.umd-Bp8OIhfV.js} +46 -46
- package/dist/app/index.html +1 -1
- package/dist/server.mjs +1389 -984
- package/package.json +10 -10
- package/src/controller/connection.controller.ts +102 -27
- package/src/dto/connection.dto.spec.ts +4 -0
- package/src/dto/connection.dto.ts +46 -2
- package/src/server.ts +201 -2
- package/src/service/connection.spec.ts +250 -4
- package/src/service/connection.ts +326 -473
- package/src/service/connection_config.ts +514 -0
- package/src/service/connection_service.spec.ts +50 -0
- package/src/service/connection_service.ts +125 -32
- package/src/service/materialization_service.spec.ts +18 -12
- package/src/service/materialization_service.ts +54 -7
- package/src/service/model.ts +24 -27
- package/src/service/package.spec.ts +125 -1
- package/src/service/package.ts +86 -44
- package/src/service/project.ts +172 -94
- package/src/service/project_store.spec.ts +72 -0
- package/src/service/project_store.ts +98 -81
- package/tests/unit/duckdb/attached_databases.test.ts +1 -19
package/dist/server.mjs
CHANGED
|
@@ -150546,7 +150546,7 @@ var require_src113 = __commonJS((exports) => {
|
|
|
150546
150546
|
var fs2 = __require("fs");
|
|
150547
150547
|
var gaxios_1 = require_src53();
|
|
150548
150548
|
var jws = require_jws();
|
|
150549
|
-
var
|
|
150549
|
+
var path3 = __require("path");
|
|
150550
150550
|
var util_1 = __require("util");
|
|
150551
150551
|
var readFile = fs2.readFile ? (0, util_1.promisify)(fs2.readFile) : async () => {
|
|
150552
150552
|
throw new ErrorWithCode("use key rather than keyFile.", "MISSING_CREDENTIALS");
|
|
@@ -150616,7 +150616,7 @@ var require_src113 = __commonJS((exports) => {
|
|
|
150616
150616
|
return __classPrivateFieldGet(this, _GoogleToken_instances, "m", _GoogleToken_getTokenAsync).call(this, opts);
|
|
150617
150617
|
}
|
|
150618
150618
|
async getCredentials(keyFile) {
|
|
150619
|
-
const ext =
|
|
150619
|
+
const ext = path3.extname(keyFile);
|
|
150620
150620
|
switch (ext) {
|
|
150621
150621
|
case ".json": {
|
|
150622
150622
|
const key = await readFile(keyFile, "utf8");
|
|
@@ -152721,7 +152721,7 @@ var require_googleauth = __commonJS((exports) => {
|
|
|
152721
152721
|
var fs2 = __require("fs");
|
|
152722
152722
|
var gcpMetadata = require_src55();
|
|
152723
152723
|
var os2 = __require("os");
|
|
152724
|
-
var
|
|
152724
|
+
var path3 = __require("path");
|
|
152725
152725
|
var crypto_1 = require_crypto3();
|
|
152726
152726
|
var transporters_1 = require_transporters();
|
|
152727
152727
|
var computeclient_1 = require_computeclient();
|
|
@@ -152917,11 +152917,11 @@ var require_googleauth = __commonJS((exports) => {
|
|
|
152917
152917
|
} else {
|
|
152918
152918
|
const home = process.env["HOME"];
|
|
152919
152919
|
if (home) {
|
|
152920
|
-
location =
|
|
152920
|
+
location = path3.join(home, ".config");
|
|
152921
152921
|
}
|
|
152922
152922
|
}
|
|
152923
152923
|
if (location) {
|
|
152924
|
-
location =
|
|
152924
|
+
location = path3.join(location, "gcloud", "application_default_credentials.json");
|
|
152925
152925
|
if (!fs2.existsSync(location)) {
|
|
152926
152926
|
location = null;
|
|
152927
152927
|
}
|
|
@@ -153238,7 +153238,7 @@ var require_googleauth = __commonJS((exports) => {
|
|
|
153238
153238
|
if (this.jsonContent) {
|
|
153239
153239
|
return this._cacheClientFromJSON(this.jsonContent, this.clientOptions);
|
|
153240
153240
|
} else if (this.keyFilename) {
|
|
153241
|
-
const filePath =
|
|
153241
|
+
const filePath = path3.resolve(this.keyFilename);
|
|
153242
153242
|
const stream4 = fs2.createReadStream(filePath);
|
|
153243
153243
|
return await this.fromStreamAsync(stream4, this.clientOptions);
|
|
153244
153244
|
} else if (this.apiKey) {
|
|
@@ -153729,19 +153729,19 @@ var require_rng2 = __commonJS((exports) => {
|
|
|
153729
153729
|
Object.defineProperty(exports, "__esModule", {
|
|
153730
153730
|
value: true
|
|
153731
153731
|
});
|
|
153732
|
-
exports.default =
|
|
153732
|
+
exports.default = rng;
|
|
153733
153733
|
var _crypto = _interopRequireDefault(__require("crypto"));
|
|
153734
153734
|
function _interopRequireDefault(obj) {
|
|
153735
153735
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
153736
153736
|
}
|
|
153737
|
-
var
|
|
153738
|
-
var
|
|
153739
|
-
function
|
|
153740
|
-
if (
|
|
153741
|
-
_crypto.default.randomFillSync(
|
|
153742
|
-
|
|
153737
|
+
var rnds8Pool = new Uint8Array(256);
|
|
153738
|
+
var poolPtr = rnds8Pool.length;
|
|
153739
|
+
function rng() {
|
|
153740
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
153741
|
+
_crypto.default.randomFillSync(rnds8Pool);
|
|
153742
|
+
poolPtr = 0;
|
|
153743
153743
|
}
|
|
153744
|
-
return
|
|
153744
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
153745
153745
|
}
|
|
153746
153746
|
});
|
|
153747
153747
|
|
|
@@ -153778,20 +153778,20 @@ var require_stringify5 = __commonJS((exports) => {
|
|
|
153778
153778
|
value: true
|
|
153779
153779
|
});
|
|
153780
153780
|
exports.default = undefined;
|
|
153781
|
-
exports.unsafeStringify =
|
|
153781
|
+
exports.unsafeStringify = unsafeStringify;
|
|
153782
153782
|
var _validate = _interopRequireDefault(require_validate2());
|
|
153783
153783
|
function _interopRequireDefault(obj) {
|
|
153784
153784
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
153785
153785
|
}
|
|
153786
|
-
var
|
|
153786
|
+
var byteToHex = [];
|
|
153787
153787
|
for (let i = 0;i < 256; ++i) {
|
|
153788
|
-
|
|
153788
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
153789
153789
|
}
|
|
153790
|
-
function
|
|
153791
|
-
return
|
|
153790
|
+
function unsafeStringify(arr, offset = 0) {
|
|
153791
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
153792
153792
|
}
|
|
153793
153793
|
function stringify(arr, offset = 0) {
|
|
153794
|
-
const uuid =
|
|
153794
|
+
const uuid = unsafeStringify(arr, offset);
|
|
153795
153795
|
if (!(0, _validate.default)(uuid)) {
|
|
153796
153796
|
throw TypeError("Stringified UUID is invalid");
|
|
153797
153797
|
}
|
|
@@ -154032,7 +154032,7 @@ var require_v42 = __commonJS((exports) => {
|
|
|
154032
154032
|
function _interopRequireDefault(obj) {
|
|
154033
154033
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
154034
154034
|
}
|
|
154035
|
-
function
|
|
154035
|
+
function v4(options, buf, offset) {
|
|
154036
154036
|
if (_native.default.randomUUID && !buf && !options) {
|
|
154037
154037
|
return _native.default.randomUUID();
|
|
154038
154038
|
}
|
|
@@ -154049,7 +154049,7 @@ var require_v42 = __commonJS((exports) => {
|
|
|
154049
154049
|
}
|
|
154050
154050
|
return (0, _stringify.unsafeStringify)(rnds);
|
|
154051
154051
|
}
|
|
154052
|
-
var _default =
|
|
154052
|
+
var _default = v4;
|
|
154053
154053
|
exports.default = _default;
|
|
154054
154054
|
});
|
|
154055
154055
|
|
|
@@ -160310,19 +160310,19 @@ var require_rng3 = __commonJS((exports) => {
|
|
|
160310
160310
|
Object.defineProperty(exports, "__esModule", {
|
|
160311
160311
|
value: true
|
|
160312
160312
|
});
|
|
160313
|
-
exports.default =
|
|
160313
|
+
exports.default = rng;
|
|
160314
160314
|
var _crypto = _interopRequireDefault(__require("crypto"));
|
|
160315
160315
|
function _interopRequireDefault(obj) {
|
|
160316
160316
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
160317
160317
|
}
|
|
160318
|
-
var
|
|
160319
|
-
var
|
|
160320
|
-
function
|
|
160321
|
-
if (
|
|
160322
|
-
_crypto.default.randomFillSync(
|
|
160323
|
-
|
|
160318
|
+
var rnds8Pool = new Uint8Array(256);
|
|
160319
|
+
var poolPtr = rnds8Pool.length;
|
|
160320
|
+
function rng() {
|
|
160321
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
160322
|
+
_crypto.default.randomFillSync(rnds8Pool);
|
|
160323
|
+
poolPtr = 0;
|
|
160324
160324
|
}
|
|
160325
|
-
return
|
|
160325
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
160326
160326
|
}
|
|
160327
160327
|
});
|
|
160328
160328
|
|
|
@@ -160359,20 +160359,20 @@ var require_stringify6 = __commonJS((exports) => {
|
|
|
160359
160359
|
value: true
|
|
160360
160360
|
});
|
|
160361
160361
|
exports.default = undefined;
|
|
160362
|
-
exports.unsafeStringify =
|
|
160362
|
+
exports.unsafeStringify = unsafeStringify;
|
|
160363
160363
|
var _validate = _interopRequireDefault(require_validate3());
|
|
160364
160364
|
function _interopRequireDefault(obj) {
|
|
160365
160365
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
160366
160366
|
}
|
|
160367
|
-
var
|
|
160367
|
+
var byteToHex = [];
|
|
160368
160368
|
for (let i = 0;i < 256; ++i) {
|
|
160369
|
-
|
|
160369
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
160370
160370
|
}
|
|
160371
|
-
function
|
|
160372
|
-
return
|
|
160371
|
+
function unsafeStringify(arr, offset = 0) {
|
|
160372
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
160373
160373
|
}
|
|
160374
160374
|
function stringify(arr, offset = 0) {
|
|
160375
|
-
const uuid =
|
|
160375
|
+
const uuid = unsafeStringify(arr, offset);
|
|
160376
160376
|
if (!(0, _validate.default)(uuid)) {
|
|
160377
160377
|
throw TypeError("Stringified UUID is invalid");
|
|
160378
160378
|
}
|
|
@@ -160613,7 +160613,7 @@ var require_v43 = __commonJS((exports) => {
|
|
|
160613
160613
|
function _interopRequireDefault(obj) {
|
|
160614
160614
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
160615
160615
|
}
|
|
160616
|
-
function
|
|
160616
|
+
function v4(options, buf, offset) {
|
|
160617
160617
|
if (_native.default.randomUUID && !buf && !options) {
|
|
160618
160618
|
return _native.default.randomUUID();
|
|
160619
160619
|
}
|
|
@@ -160630,7 +160630,7 @@ var require_v43 = __commonJS((exports) => {
|
|
|
160630
160630
|
}
|
|
160631
160631
|
return (0, _stringify.unsafeStringify)(rnds);
|
|
160632
160632
|
}
|
|
160633
|
-
var _default =
|
|
160633
|
+
var _default = v4;
|
|
160634
160634
|
exports.default = _default;
|
|
160635
160635
|
});
|
|
160636
160636
|
|
|
@@ -160995,7 +160995,7 @@ var require_table = __commonJS((exports) => {
|
|
|
160995
160995
|
var events_1 = __require("events");
|
|
160996
160996
|
var fs2 = __require("fs");
|
|
160997
160997
|
var is = require_is();
|
|
160998
|
-
var
|
|
160998
|
+
var path3 = __require("path");
|
|
160999
160999
|
var streamEvents = require_stream_events();
|
|
161000
161000
|
var uuid = require_dist9();
|
|
161001
161001
|
var _1 = require_src121();
|
|
@@ -161241,7 +161241,7 @@ var require_table = __commonJS((exports) => {
|
|
|
161241
161241
|
if (!common_1.util.isCustomType(dest, "storage/file")) {
|
|
161242
161242
|
throw new Error("Destination must be a File object.");
|
|
161243
161243
|
}
|
|
161244
|
-
const format =
|
|
161244
|
+
const format = path3.extname(dest.name).substr(1).toLowerCase();
|
|
161245
161245
|
if (!options.destinationFormat && !options.format && FORMATS[format]) {
|
|
161246
161246
|
options.destinationFormat = FORMATS[format];
|
|
161247
161247
|
}
|
|
@@ -161299,7 +161299,7 @@ var require_table = __commonJS((exports) => {
|
|
|
161299
161299
|
metadata.location = this.location;
|
|
161300
161300
|
}
|
|
161301
161301
|
if (typeof source === "string") {
|
|
161302
|
-
const detectedFormat = FORMATS[
|
|
161302
|
+
const detectedFormat = FORMATS[path3.extname(source).substr(1).toLowerCase()];
|
|
161303
161303
|
if (!metadata.sourceFormat && detectedFormat) {
|
|
161304
161304
|
metadata.sourceFormat = detectedFormat;
|
|
161305
161305
|
}
|
|
@@ -161335,7 +161335,7 @@ var require_table = __commonJS((exports) => {
|
|
|
161335
161335
|
if (!common_1.util.isCustomType(src, "storage/file")) {
|
|
161336
161336
|
throw new Error("Source must be a File object.");
|
|
161337
161337
|
}
|
|
161338
|
-
const format = FORMATS[
|
|
161338
|
+
const format = FORMATS[path3.extname(src.name).substr(1).toLowerCase()];
|
|
161339
161339
|
if (!metadata.sourceFormat && format) {
|
|
161340
161340
|
body.configuration.load.sourceFormat = format;
|
|
161341
161341
|
}
|
|
@@ -164969,12 +164969,12 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
164969
164969
|
const password = request.password ?? "";
|
|
164970
164970
|
auth = `${username}:${password}`;
|
|
164971
164971
|
}
|
|
164972
|
-
let
|
|
164972
|
+
let path3 = request.path;
|
|
164973
164973
|
if (queryString) {
|
|
164974
|
-
|
|
164974
|
+
path3 += `?${queryString}`;
|
|
164975
164975
|
}
|
|
164976
164976
|
if (request.fragment) {
|
|
164977
|
-
|
|
164977
|
+
path3 += `#${request.fragment}`;
|
|
164978
164978
|
}
|
|
164979
164979
|
let hostname = request.hostname ?? "";
|
|
164980
164980
|
if (hostname[0] === "[" && hostname.endsWith("]")) {
|
|
@@ -164986,7 +164986,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
164986
164986
|
headers: request.headers,
|
|
164987
164987
|
host: hostname,
|
|
164988
164988
|
method: request.method,
|
|
164989
|
-
path:
|
|
164989
|
+
path: path3,
|
|
164990
164990
|
port: request.port,
|
|
164991
164991
|
agent,
|
|
164992
164992
|
auth
|
|
@@ -165244,16 +165244,16 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
165244
165244
|
reject(err);
|
|
165245
165245
|
};
|
|
165246
165246
|
const queryString = querystringBuilder.buildQueryString(query || {});
|
|
165247
|
-
let
|
|
165247
|
+
let path3 = request.path;
|
|
165248
165248
|
if (queryString) {
|
|
165249
|
-
|
|
165249
|
+
path3 += `?${queryString}`;
|
|
165250
165250
|
}
|
|
165251
165251
|
if (request.fragment) {
|
|
165252
|
-
|
|
165252
|
+
path3 += `#${request.fragment}`;
|
|
165253
165253
|
}
|
|
165254
165254
|
const req = session.request({
|
|
165255
165255
|
...request.headers,
|
|
165256
|
-
[http22.constants.HTTP2_HEADER_PATH]:
|
|
165256
|
+
[http22.constants.HTTP2_HEADER_PATH]: path3,
|
|
165257
165257
|
[http22.constants.HTTP2_HEADER_METHOD]: method
|
|
165258
165258
|
});
|
|
165259
165259
|
session.ref();
|
|
@@ -165440,13 +165440,13 @@ var require_dist_cjs13 = __commonJS((exports) => {
|
|
|
165440
165440
|
abortError.name = "AbortError";
|
|
165441
165441
|
return Promise.reject(abortError);
|
|
165442
165442
|
}
|
|
165443
|
-
let
|
|
165443
|
+
let path3 = request.path;
|
|
165444
165444
|
const queryString = querystringBuilder.buildQueryString(request.query || {});
|
|
165445
165445
|
if (queryString) {
|
|
165446
|
-
|
|
165446
|
+
path3 += `?${queryString}`;
|
|
165447
165447
|
}
|
|
165448
165448
|
if (request.fragment) {
|
|
165449
|
-
|
|
165449
|
+
path3 += `#${request.fragment}`;
|
|
165450
165450
|
}
|
|
165451
165451
|
let auth = "";
|
|
165452
165452
|
if (request.username != null || request.password != null) {
|
|
@@ -165455,7 +165455,7 @@ var require_dist_cjs13 = __commonJS((exports) => {
|
|
|
165455
165455
|
auth = `${username}:${password}@`;
|
|
165456
165456
|
}
|
|
165457
165457
|
const { port, method } = request;
|
|
165458
|
-
const url2 = `${request.protocol}//${auth}${request.hostname}${port ? `:${port}` : ""}${
|
|
165458
|
+
const url2 = `${request.protocol}//${auth}${request.hostname}${port ? `:${port}` : ""}${path3}`;
|
|
165459
165459
|
const body = method === "GET" || method === "HEAD" ? undefined : request.body;
|
|
165460
165460
|
const requestOptions = {
|
|
165461
165461
|
body,
|
|
@@ -167049,13 +167049,13 @@ var require_tslib = __commonJS((exports, module) => {
|
|
|
167049
167049
|
}
|
|
167050
167050
|
return next();
|
|
167051
167051
|
};
|
|
167052
|
-
__rewriteRelativeImportExtension = function(
|
|
167053
|
-
if (typeof
|
|
167054
|
-
return
|
|
167052
|
+
__rewriteRelativeImportExtension = function(path3, preserveJsx) {
|
|
167053
|
+
if (typeof path3 === "string" && /^\.\.?\//.test(path3)) {
|
|
167054
|
+
return path3.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
|
|
167055
167055
|
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : d + ext + "." + cm.toLowerCase() + "js";
|
|
167056
167056
|
});
|
|
167057
167057
|
}
|
|
167058
|
-
return
|
|
167058
|
+
return path3;
|
|
167059
167059
|
};
|
|
167060
167060
|
exporter("__extends", __extends);
|
|
167061
167061
|
exporter("__assign", __assign);
|
|
@@ -167103,11 +167103,11 @@ var require_randomUUID = __commonJS((exports) => {
|
|
|
167103
167103
|
|
|
167104
167104
|
// ../../node_modules/@smithy/uuid/dist-cjs/index.js
|
|
167105
167105
|
var require_dist_cjs16 = __commonJS((exports) => {
|
|
167106
|
-
var
|
|
167106
|
+
var randomUUID2 = require_randomUUID();
|
|
167107
167107
|
var decimalToHex = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
167108
|
-
var
|
|
167109
|
-
if (
|
|
167110
|
-
return
|
|
167108
|
+
var v4 = () => {
|
|
167109
|
+
if (randomUUID2.randomUUID) {
|
|
167110
|
+
return randomUUID2.randomUUID();
|
|
167111
167111
|
}
|
|
167112
167112
|
const rnds = new Uint8Array(16);
|
|
167113
167113
|
crypto.getRandomValues(rnds);
|
|
@@ -167115,7 +167115,7 @@ var require_dist_cjs16 = __commonJS((exports) => {
|
|
|
167115
167115
|
rnds[8] = rnds[8] & 63 | 128;
|
|
167116
167116
|
return decimalToHex[rnds[0]] + decimalToHex[rnds[1]] + decimalToHex[rnds[2]] + decimalToHex[rnds[3]] + "-" + decimalToHex[rnds[4]] + decimalToHex[rnds[5]] + "-" + decimalToHex[rnds[6]] + decimalToHex[rnds[7]] + "-" + decimalToHex[rnds[8]] + decimalToHex[rnds[9]] + "-" + decimalToHex[rnds[10]] + decimalToHex[rnds[11]] + decimalToHex[rnds[12]] + decimalToHex[rnds[13]] + decimalToHex[rnds[14]] + decimalToHex[rnds[15]];
|
|
167117
167117
|
};
|
|
167118
|
-
exports.v4 =
|
|
167118
|
+
exports.v4 = v4;
|
|
167119
167119
|
});
|
|
167120
167120
|
|
|
167121
167121
|
// ../../node_modules/@smithy/core/dist-cjs/submodules/serde/index.js
|
|
@@ -168203,11 +168203,11 @@ var require_protocols = __commonJS((exports) => {
|
|
|
168203
168203
|
const opTraits = schema.translateTraits(operationSchema.traits);
|
|
168204
168204
|
if (opTraits.http) {
|
|
168205
168205
|
request.method = opTraits.http[0];
|
|
168206
|
-
const [
|
|
168206
|
+
const [path3, search] = opTraits.http[1].split("?");
|
|
168207
168207
|
if (request.path == "/") {
|
|
168208
|
-
request.path =
|
|
168208
|
+
request.path = path3;
|
|
168209
168209
|
} else {
|
|
168210
|
-
request.path +=
|
|
168210
|
+
request.path += path3;
|
|
168211
168211
|
}
|
|
168212
168212
|
const traitSearchParams = new URLSearchParams(search ?? "");
|
|
168213
168213
|
Object.assign(query, Object.fromEntries(traitSearchParams));
|
|
@@ -168559,8 +168559,8 @@ var require_protocols = __commonJS((exports) => {
|
|
|
168559
168559
|
return this;
|
|
168560
168560
|
}
|
|
168561
168561
|
p(memberName, labelValueProvider, uriLabel, isGreedyLabel) {
|
|
168562
|
-
this.resolvePathStack.push((
|
|
168563
|
-
this.path = resolvedPath(
|
|
168562
|
+
this.resolvePathStack.push((path3) => {
|
|
168563
|
+
this.path = resolvedPath(path3, this.input, memberName, labelValueProvider, uriLabel, isGreedyLabel);
|
|
168564
168564
|
});
|
|
168565
168565
|
return this;
|
|
168566
168566
|
}
|
|
@@ -168995,9 +168995,9 @@ var require_dist_cjs17 = __commonJS((exports) => {
|
|
|
168995
168995
|
return;
|
|
168996
168996
|
};
|
|
168997
168997
|
}
|
|
168998
|
-
var get = (fromObject,
|
|
168998
|
+
var get = (fromObject, path3) => {
|
|
168999
168999
|
let cursor = fromObject;
|
|
169000
|
-
const pathComponents =
|
|
169000
|
+
const pathComponents = path3.split(".");
|
|
169001
169001
|
for (const step of pathComponents) {
|
|
169002
169002
|
if (!cursor || typeof cursor !== "object") {
|
|
169003
169003
|
return;
|
|
@@ -169641,10 +169641,10 @@ ${longDate}
|
|
|
169641
169641
|
${credentialScope}
|
|
169642
169642
|
${utilHexEncoding.toHex(hashedRequest)}`;
|
|
169643
169643
|
}
|
|
169644
|
-
getCanonicalPath({ path:
|
|
169644
|
+
getCanonicalPath({ path: path3 }) {
|
|
169645
169645
|
if (this.uriEscapePath) {
|
|
169646
169646
|
const normalizedPathSegments = [];
|
|
169647
|
-
for (const pathSegment of
|
|
169647
|
+
for (const pathSegment of path3.split("/")) {
|
|
169648
169648
|
if (pathSegment?.length === 0)
|
|
169649
169649
|
continue;
|
|
169650
169650
|
if (pathSegment === ".")
|
|
@@ -169655,11 +169655,11 @@ ${utilHexEncoding.toHex(hashedRequest)}`;
|
|
|
169655
169655
|
normalizedPathSegments.push(pathSegment);
|
|
169656
169656
|
}
|
|
169657
169657
|
}
|
|
169658
|
-
const normalizedPath = `${
|
|
169658
|
+
const normalizedPath = `${path3?.startsWith("/") ? "/" : ""}${normalizedPathSegments.join("/")}${normalizedPathSegments.length > 0 && path3?.endsWith("/") ? "/" : ""}`;
|
|
169659
169659
|
const doubleEncoded = utilUriEscape.escapeUri(normalizedPath);
|
|
169660
169660
|
return doubleEncoded.replace(/%2F/g, "/");
|
|
169661
169661
|
}
|
|
169662
|
-
return
|
|
169662
|
+
return path3;
|
|
169663
169663
|
}
|
|
169664
169664
|
validateResolvedCredentials(credentials) {
|
|
169665
169665
|
if (typeof credentials !== "object" || typeof credentials.accessKeyId !== "string" || typeof credentials.secretAccessKey !== "string") {
|
|
@@ -170571,14 +170571,14 @@ var require_cbor = __commonJS((exports) => {
|
|
|
170571
170571
|
throw new Error("Malformed RPCv2 CBOR response, status: " + response.statusCode);
|
|
170572
170572
|
}
|
|
170573
170573
|
};
|
|
170574
|
-
var buildHttpRpcRequest = async (context, headers,
|
|
170574
|
+
var buildHttpRpcRequest = async (context, headers, path3, resolvedHostname, body) => {
|
|
170575
170575
|
const { hostname, protocol = "https", port, path: basePath } = await context.endpoint();
|
|
170576
170576
|
const contents = {
|
|
170577
170577
|
protocol,
|
|
170578
170578
|
hostname,
|
|
170579
170579
|
port,
|
|
170580
170580
|
method: "POST",
|
|
170581
|
-
path: basePath.endsWith("/") ? basePath.slice(0, -1) +
|
|
170581
|
+
path: basePath.endsWith("/") ? basePath.slice(0, -1) + path3 : basePath + path3,
|
|
170582
170582
|
headers: {
|
|
170583
170583
|
...headers
|
|
170584
170584
|
}
|
|
@@ -170806,11 +170806,11 @@ var require_cbor = __commonJS((exports) => {
|
|
|
170806
170806
|
} catch (e) {}
|
|
170807
170807
|
}
|
|
170808
170808
|
const { service, operation } = utilMiddleware.getSmithyContext(context);
|
|
170809
|
-
const
|
|
170809
|
+
const path3 = `/service/${service}/operation/${operation}`;
|
|
170810
170810
|
if (request.path.endsWith("/")) {
|
|
170811
|
-
request.path +=
|
|
170811
|
+
request.path += path3.slice(1);
|
|
170812
170812
|
} else {
|
|
170813
|
-
request.path +=
|
|
170813
|
+
request.path += path3;
|
|
170814
170814
|
}
|
|
170815
170815
|
return request;
|
|
170816
170816
|
}
|
|
@@ -177273,18 +177273,18 @@ var require_dist_cjs36 = __commonJS((exports) => {
|
|
|
177273
177273
|
}
|
|
177274
177274
|
}
|
|
177275
177275
|
var booleanEquals = (value1, value2) => value1 === value2;
|
|
177276
|
-
var getAttrPathList = (
|
|
177277
|
-
const parts =
|
|
177276
|
+
var getAttrPathList = (path3) => {
|
|
177277
|
+
const parts = path3.split(".");
|
|
177278
177278
|
const pathList = [];
|
|
177279
177279
|
for (const part of parts) {
|
|
177280
177280
|
const squareBracketIndex = part.indexOf("[");
|
|
177281
177281
|
if (squareBracketIndex !== -1) {
|
|
177282
177282
|
if (part.indexOf("]") !== part.length - 1) {
|
|
177283
|
-
throw new EndpointError(`Path: '${
|
|
177283
|
+
throw new EndpointError(`Path: '${path3}' does not end with ']'`);
|
|
177284
177284
|
}
|
|
177285
177285
|
const arrayIndex = part.slice(squareBracketIndex + 1, -1);
|
|
177286
177286
|
if (Number.isNaN(parseInt(arrayIndex))) {
|
|
177287
|
-
throw new EndpointError(`Invalid array index: '${arrayIndex}' in path: '${
|
|
177287
|
+
throw new EndpointError(`Invalid array index: '${arrayIndex}' in path: '${path3}'`);
|
|
177288
177288
|
}
|
|
177289
177289
|
if (squareBracketIndex !== 0) {
|
|
177290
177290
|
pathList.push(part.slice(0, squareBracketIndex));
|
|
@@ -177296,9 +177296,9 @@ var require_dist_cjs36 = __commonJS((exports) => {
|
|
|
177296
177296
|
}
|
|
177297
177297
|
return pathList;
|
|
177298
177298
|
};
|
|
177299
|
-
var getAttr = (value,
|
|
177299
|
+
var getAttr = (value, path3) => getAttrPathList(path3).reduce((acc, index) => {
|
|
177300
177300
|
if (typeof acc !== "object") {
|
|
177301
|
-
throw new EndpointError(`Index '${index}' in '${
|
|
177301
|
+
throw new EndpointError(`Index '${index}' in '${path3}' not found in '${JSON.stringify(value)}'`);
|
|
177302
177302
|
} else if (Array.isArray(acc)) {
|
|
177303
177303
|
return acc[parseInt(index)];
|
|
177304
177304
|
}
|
|
@@ -177317,8 +177317,8 @@ var require_dist_cjs36 = __commonJS((exports) => {
|
|
|
177317
177317
|
return value;
|
|
177318
177318
|
}
|
|
177319
177319
|
if (typeof value === "object" && "hostname" in value) {
|
|
177320
|
-
const { hostname: hostname2, port, protocol: protocol2 = "", path:
|
|
177321
|
-
const url2 = new URL(`${protocol2}//${hostname2}${port ? `:${port}` : ""}${
|
|
177320
|
+
const { hostname: hostname2, port, protocol: protocol2 = "", path: path3 = "", query = {} } = value;
|
|
177321
|
+
const url2 = new URL(`${protocol2}//${hostname2}${port ? `:${port}` : ""}${path3}`);
|
|
177322
177322
|
url2.search = Object.entries(query).map(([k, v]) => `${k}=${v}`).join("&");
|
|
177323
177323
|
return url2;
|
|
177324
177324
|
}
|
|
@@ -178526,14 +178526,14 @@ var require_readFile = __commonJS((exports) => {
|
|
|
178526
178526
|
var promises_1 = __require("node:fs/promises");
|
|
178527
178527
|
exports.filePromises = {};
|
|
178528
178528
|
exports.fileIntercept = {};
|
|
178529
|
-
var readFile = (
|
|
178530
|
-
if (exports.fileIntercept[
|
|
178531
|
-
return exports.fileIntercept[
|
|
178529
|
+
var readFile = (path3, options) => {
|
|
178530
|
+
if (exports.fileIntercept[path3] !== undefined) {
|
|
178531
|
+
return exports.fileIntercept[path3];
|
|
178532
178532
|
}
|
|
178533
|
-
if (!exports.filePromises[
|
|
178534
|
-
exports.filePromises[
|
|
178533
|
+
if (!exports.filePromises[path3] || options?.ignoreCache) {
|
|
178534
|
+
exports.filePromises[path3] = (0, promises_1.readFile)(path3, "utf8");
|
|
178535
178535
|
}
|
|
178536
|
-
return exports.filePromises[
|
|
178536
|
+
return exports.filePromises[path3];
|
|
178537
178537
|
};
|
|
178538
178538
|
exports.readFile = readFile;
|
|
178539
178539
|
});
|
|
@@ -178543,7 +178543,7 @@ var require_dist_cjs44 = __commonJS((exports) => {
|
|
|
178543
178543
|
var getHomeDir = require_getHomeDir();
|
|
178544
178544
|
var getSSOTokenFilepath = require_getSSOTokenFilepath();
|
|
178545
178545
|
var getSSOTokenFromFile = require_getSSOTokenFromFile();
|
|
178546
|
-
var
|
|
178546
|
+
var path3 = __require("path");
|
|
178547
178547
|
var types2 = require_dist_cjs();
|
|
178548
178548
|
var readFile = require_readFile();
|
|
178549
178549
|
var ENV_PROFILE = "AWS_PROFILE";
|
|
@@ -178565,9 +178565,9 @@ var require_dist_cjs44 = __commonJS((exports) => {
|
|
|
178565
178565
|
...data.default && { default: data.default }
|
|
178566
178566
|
});
|
|
178567
178567
|
var ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
|
|
178568
|
-
var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] ||
|
|
178568
|
+
var getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || path3.join(getHomeDir.getHomeDir(), ".aws", "config");
|
|
178569
178569
|
var ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
|
|
178570
|
-
var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] ||
|
|
178570
|
+
var getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || path3.join(getHomeDir.getHomeDir(), ".aws", "credentials");
|
|
178571
178571
|
var prefixKeyRegex = /^([\w-]+)\s(["'])?([\w-@\+\.%:/]+)\2$/;
|
|
178572
178572
|
var profileNameBlockList = ["__proto__", "profile __proto__"];
|
|
178573
178573
|
var parseIni = (iniData) => {
|
|
@@ -178622,11 +178622,11 @@ var require_dist_cjs44 = __commonJS((exports) => {
|
|
|
178622
178622
|
const relativeHomeDirPrefix = "~/";
|
|
178623
178623
|
let resolvedFilepath = filepath;
|
|
178624
178624
|
if (filepath.startsWith(relativeHomeDirPrefix)) {
|
|
178625
|
-
resolvedFilepath =
|
|
178625
|
+
resolvedFilepath = path3.join(homeDir, filepath.slice(2));
|
|
178626
178626
|
}
|
|
178627
178627
|
let resolvedConfigFilepath = configFilepath;
|
|
178628
178628
|
if (configFilepath.startsWith(relativeHomeDirPrefix)) {
|
|
178629
|
-
resolvedConfigFilepath =
|
|
178629
|
+
resolvedConfigFilepath = path3.join(homeDir, configFilepath.slice(2));
|
|
178630
178630
|
}
|
|
178631
178631
|
const parsedFiles = await Promise.all([
|
|
178632
178632
|
readFile.readFile(resolvedConfigFilepath, {
|
|
@@ -178665,8 +178665,8 @@ var require_dist_cjs44 = __commonJS((exports) => {
|
|
|
178665
178665
|
getFileRecord() {
|
|
178666
178666
|
return readFile.fileIntercept;
|
|
178667
178667
|
},
|
|
178668
|
-
interceptFile(
|
|
178669
|
-
readFile.fileIntercept[
|
|
178668
|
+
interceptFile(path4, contents) {
|
|
178669
|
+
readFile.fileIntercept[path4] = Promise.resolve(contents);
|
|
178670
178670
|
},
|
|
178671
178671
|
getTokenRecord() {
|
|
178672
178672
|
return getSSOTokenFromFile.tokenIntercept;
|
|
@@ -178894,8 +178894,8 @@ var require_dist_cjs46 = __commonJS((exports) => {
|
|
|
178894
178894
|
return endpoint.url.href;
|
|
178895
178895
|
}
|
|
178896
178896
|
if ("hostname" in endpoint) {
|
|
178897
|
-
const { protocol, hostname, port, path:
|
|
178898
|
-
return `${protocol}//${hostname}${port ? ":" + port : ""}${
|
|
178897
|
+
const { protocol, hostname, port, path: path3 } = endpoint;
|
|
178898
|
+
return `${protocol}//${hostname}${port ? ":" + port : ""}${path3}`;
|
|
178899
178899
|
}
|
|
178900
178900
|
}
|
|
178901
178901
|
return endpoint;
|
|
@@ -196989,26 +196989,26 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
196989
196989
|
}
|
|
196990
196990
|
mkdirSync(folder);
|
|
196991
196991
|
};
|
|
196992
|
-
Utils.prototype.writeFileTo = function(
|
|
196992
|
+
Utils.prototype.writeFileTo = function(path4, content, overwrite, attr) {
|
|
196993
196993
|
const self2 = this;
|
|
196994
|
-
if (self2.fs.existsSync(
|
|
196994
|
+
if (self2.fs.existsSync(path4)) {
|
|
196995
196995
|
if (!overwrite)
|
|
196996
196996
|
return false;
|
|
196997
|
-
var stat4 = self2.fs.statSync(
|
|
196997
|
+
var stat4 = self2.fs.statSync(path4);
|
|
196998
196998
|
if (stat4.isDirectory()) {
|
|
196999
196999
|
return false;
|
|
197000
197000
|
}
|
|
197001
197001
|
}
|
|
197002
|
-
var folder = pth.dirname(
|
|
197002
|
+
var folder = pth.dirname(path4);
|
|
197003
197003
|
if (!self2.fs.existsSync(folder)) {
|
|
197004
197004
|
self2.makeDir(folder);
|
|
197005
197005
|
}
|
|
197006
197006
|
var fd;
|
|
197007
197007
|
try {
|
|
197008
|
-
fd = self2.fs.openSync(
|
|
197008
|
+
fd = self2.fs.openSync(path4, "w", 438);
|
|
197009
197009
|
} catch (e) {
|
|
197010
|
-
self2.fs.chmodSync(
|
|
197011
|
-
fd = self2.fs.openSync(
|
|
197010
|
+
self2.fs.chmodSync(path4, 438);
|
|
197011
|
+
fd = self2.fs.openSync(path4, "w", 438);
|
|
197012
197012
|
}
|
|
197013
197013
|
if (fd) {
|
|
197014
197014
|
try {
|
|
@@ -197017,33 +197017,33 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197017
197017
|
self2.fs.closeSync(fd);
|
|
197018
197018
|
}
|
|
197019
197019
|
}
|
|
197020
|
-
self2.fs.chmodSync(
|
|
197020
|
+
self2.fs.chmodSync(path4, attr || 438);
|
|
197021
197021
|
return true;
|
|
197022
197022
|
};
|
|
197023
|
-
Utils.prototype.writeFileToAsync = function(
|
|
197023
|
+
Utils.prototype.writeFileToAsync = function(path4, content, overwrite, attr, callback) {
|
|
197024
197024
|
if (typeof attr === "function") {
|
|
197025
197025
|
callback = attr;
|
|
197026
197026
|
attr = undefined;
|
|
197027
197027
|
}
|
|
197028
197028
|
const self2 = this;
|
|
197029
|
-
self2.fs.exists(
|
|
197029
|
+
self2.fs.exists(path4, function(exist) {
|
|
197030
197030
|
if (exist && !overwrite)
|
|
197031
197031
|
return callback(false);
|
|
197032
|
-
self2.fs.stat(
|
|
197032
|
+
self2.fs.stat(path4, function(err, stat4) {
|
|
197033
197033
|
if (exist && stat4.isDirectory()) {
|
|
197034
197034
|
return callback(false);
|
|
197035
197035
|
}
|
|
197036
|
-
var folder = pth.dirname(
|
|
197036
|
+
var folder = pth.dirname(path4);
|
|
197037
197037
|
self2.fs.exists(folder, function(exists) {
|
|
197038
197038
|
if (!exists)
|
|
197039
197039
|
self2.makeDir(folder);
|
|
197040
|
-
self2.fs.open(
|
|
197040
|
+
self2.fs.open(path4, "w", 438, function(err2, fd) {
|
|
197041
197041
|
if (err2) {
|
|
197042
|
-
self2.fs.chmod(
|
|
197043
|
-
self2.fs.open(
|
|
197042
|
+
self2.fs.chmod(path4, 438, function() {
|
|
197043
|
+
self2.fs.open(path4, "w", 438, function(err3, fd2) {
|
|
197044
197044
|
self2.fs.write(fd2, content, 0, content.length, 0, function() {
|
|
197045
197045
|
self2.fs.close(fd2, function() {
|
|
197046
|
-
self2.fs.chmod(
|
|
197046
|
+
self2.fs.chmod(path4, attr || 438, function() {
|
|
197047
197047
|
callback(true);
|
|
197048
197048
|
});
|
|
197049
197049
|
});
|
|
@@ -197053,13 +197053,13 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197053
197053
|
} else if (fd) {
|
|
197054
197054
|
self2.fs.write(fd, content, 0, content.length, 0, function() {
|
|
197055
197055
|
self2.fs.close(fd, function() {
|
|
197056
|
-
self2.fs.chmod(
|
|
197056
|
+
self2.fs.chmod(path4, attr || 438, function() {
|
|
197057
197057
|
callback(true);
|
|
197058
197058
|
});
|
|
197059
197059
|
});
|
|
197060
197060
|
});
|
|
197061
197061
|
} else {
|
|
197062
|
-
self2.fs.chmod(
|
|
197062
|
+
self2.fs.chmod(path4, attr || 438, function() {
|
|
197063
197063
|
callback(true);
|
|
197064
197064
|
});
|
|
197065
197065
|
}
|
|
@@ -197068,7 +197068,7 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197068
197068
|
});
|
|
197069
197069
|
});
|
|
197070
197070
|
};
|
|
197071
|
-
Utils.prototype.findFiles = function(
|
|
197071
|
+
Utils.prototype.findFiles = function(path4) {
|
|
197072
197072
|
const self2 = this;
|
|
197073
197073
|
function findSync(dir, pattern, recursive) {
|
|
197074
197074
|
if (typeof pattern === "boolean") {
|
|
@@ -197077,17 +197077,17 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197077
197077
|
}
|
|
197078
197078
|
let files = [];
|
|
197079
197079
|
self2.fs.readdirSync(dir).forEach(function(file) {
|
|
197080
|
-
const
|
|
197081
|
-
const stat4 = self2.fs.statSync(
|
|
197082
|
-
if (!pattern || pattern.test(
|
|
197083
|
-
files.push(pth.normalize(
|
|
197080
|
+
const path5 = pth.join(dir, file);
|
|
197081
|
+
const stat4 = self2.fs.statSync(path5);
|
|
197082
|
+
if (!pattern || pattern.test(path5)) {
|
|
197083
|
+
files.push(pth.normalize(path5) + (stat4.isDirectory() ? self2.sep : ""));
|
|
197084
197084
|
}
|
|
197085
197085
|
if (stat4.isDirectory() && recursive)
|
|
197086
|
-
files = files.concat(findSync(
|
|
197086
|
+
files = files.concat(findSync(path5, pattern, recursive));
|
|
197087
197087
|
});
|
|
197088
197088
|
return files;
|
|
197089
197089
|
}
|
|
197090
|
-
return findSync(
|
|
197090
|
+
return findSync(path4, undefined, true);
|
|
197091
197091
|
};
|
|
197092
197092
|
Utils.prototype.findFilesAsync = function(dir, cb) {
|
|
197093
197093
|
const self2 = this;
|
|
@@ -197147,16 +197147,16 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197147
197147
|
return "UNSUPPORTED (" + method + ")";
|
|
197148
197148
|
}
|
|
197149
197149
|
};
|
|
197150
|
-
Utils.canonical = function(
|
|
197151
|
-
if (!
|
|
197150
|
+
Utils.canonical = function(path4) {
|
|
197151
|
+
if (!path4)
|
|
197152
197152
|
return "";
|
|
197153
|
-
const safeSuffix = pth.posix.normalize("/" +
|
|
197153
|
+
const safeSuffix = pth.posix.normalize("/" + path4.split("\\").join("/"));
|
|
197154
197154
|
return pth.join(".", safeSuffix);
|
|
197155
197155
|
};
|
|
197156
|
-
Utils.zipnamefix = function(
|
|
197157
|
-
if (!
|
|
197156
|
+
Utils.zipnamefix = function(path4) {
|
|
197157
|
+
if (!path4)
|
|
197158
197158
|
return "";
|
|
197159
|
-
const safeSuffix = pth.posix.normalize("/" +
|
|
197159
|
+
const safeSuffix = pth.posix.normalize("/" + path4.split("\\").join("/"));
|
|
197160
197160
|
return pth.posix.join(".", safeSuffix);
|
|
197161
197161
|
};
|
|
197162
197162
|
Utils.findLast = function(arr, callback) {
|
|
@@ -197174,9 +197174,9 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197174
197174
|
prefix = pth.resolve(pth.normalize(prefix));
|
|
197175
197175
|
var parts = name.split("/");
|
|
197176
197176
|
for (var i = 0, l = parts.length;i < l; i++) {
|
|
197177
|
-
var
|
|
197178
|
-
if (
|
|
197179
|
-
return
|
|
197177
|
+
var path4 = pth.normalize(pth.join(prefix, parts.slice(i, l).join(pth.sep)));
|
|
197178
|
+
if (path4.indexOf(prefix) === 0) {
|
|
197179
|
+
return path4;
|
|
197180
197180
|
}
|
|
197181
197181
|
}
|
|
197182
197182
|
return pth.normalize(pth.join(prefix, pth.basename(name)));
|
|
@@ -197214,8 +197214,8 @@ var require_utils74 = __commonJS((exports, module) => {
|
|
|
197214
197214
|
// ../../node_modules/adm-zip/util/fattr.js
|
|
197215
197215
|
var require_fattr = __commonJS((exports, module) => {
|
|
197216
197216
|
var pth = __require("path");
|
|
197217
|
-
module.exports = function(
|
|
197218
|
-
var _path =
|
|
197217
|
+
module.exports = function(path4, { fs: fs2 }) {
|
|
197218
|
+
var _path = path4 || "", _obj = newAttr(), _stat = null;
|
|
197219
197219
|
function newAttr() {
|
|
197220
197220
|
return {
|
|
197221
197221
|
directory: false,
|
|
@@ -197722,7 +197722,7 @@ var require_inflater = __commonJS((exports, module) => {
|
|
|
197722
197722
|
|
|
197723
197723
|
// ../../node_modules/adm-zip/methods/zipcrypto.js
|
|
197724
197724
|
var require_zipcrypto = __commonJS((exports, module) => {
|
|
197725
|
-
var { randomFillSync
|
|
197725
|
+
var { randomFillSync } = __require("crypto");
|
|
197726
197726
|
var Errors = require_errors6();
|
|
197727
197727
|
var crctable = new Uint32Array(256).map((t, crc) => {
|
|
197728
197728
|
for (let j = 0;j < 8; j++) {
|
|
@@ -197739,8 +197739,8 @@ var require_zipcrypto = __commonJS((exports, module) => {
|
|
|
197739
197739
|
return crctable[(pCrc32 ^ bval) & 255] ^ pCrc32 >>> 8;
|
|
197740
197740
|
};
|
|
197741
197741
|
var genSalt = () => {
|
|
197742
|
-
if (typeof
|
|
197743
|
-
return
|
|
197742
|
+
if (typeof randomFillSync === "function") {
|
|
197743
|
+
return randomFillSync(Buffer.alloc(12));
|
|
197744
197744
|
} else {
|
|
197745
197745
|
return genSalt.node();
|
|
197746
197746
|
}
|
|
@@ -199074,10 +199074,10 @@ var require_src122 = __commonJS((exports) => {
|
|
|
199074
199074
|
var fs_1 = __require("fs");
|
|
199075
199075
|
var debug_1 = __importDefault(require_src5());
|
|
199076
199076
|
var log = debug_1.default("@kwsites/file-exists");
|
|
199077
|
-
function check(
|
|
199078
|
-
log(`checking %s`,
|
|
199077
|
+
function check(path4, isFile2, isDirectory) {
|
|
199078
|
+
log(`checking %s`, path4);
|
|
199079
199079
|
try {
|
|
199080
|
-
const stat4 = fs_1.statSync(
|
|
199080
|
+
const stat4 = fs_1.statSync(path4);
|
|
199081
199081
|
if (stat4.isFile() && isFile2) {
|
|
199082
199082
|
log(`[OK] path represents a file`);
|
|
199083
199083
|
return true;
|
|
@@ -199097,8 +199097,8 @@ var require_src122 = __commonJS((exports) => {
|
|
|
199097
199097
|
throw e;
|
|
199098
199098
|
}
|
|
199099
199099
|
}
|
|
199100
|
-
function exists(
|
|
199101
|
-
return check(
|
|
199100
|
+
function exists(path4, type = exports.READABLE) {
|
|
199101
|
+
return check(path4, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
199102
199102
|
}
|
|
199103
199103
|
exports.exists = exists;
|
|
199104
199104
|
exports.FILE = 1;
|
|
@@ -199378,14 +199378,14 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
199378
199378
|
var require_minimatch = __commonJS((exports, module) => {
|
|
199379
199379
|
module.exports = minimatch;
|
|
199380
199380
|
minimatch.Minimatch = Minimatch;
|
|
199381
|
-
var
|
|
199381
|
+
var path6 = function() {
|
|
199382
199382
|
try {
|
|
199383
199383
|
return __require("path");
|
|
199384
199384
|
} catch (e) {}
|
|
199385
199385
|
}() || {
|
|
199386
199386
|
sep: "/"
|
|
199387
199387
|
};
|
|
199388
|
-
minimatch.sep =
|
|
199388
|
+
minimatch.sep = path6.sep;
|
|
199389
199389
|
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {};
|
|
199390
199390
|
var expand = require_brace_expansion();
|
|
199391
199391
|
var plTypes = {
|
|
@@ -199476,8 +199476,8 @@ var require_minimatch = __commonJS((exports, module) => {
|
|
|
199476
199476
|
if (!options)
|
|
199477
199477
|
options = {};
|
|
199478
199478
|
pattern = pattern.trim();
|
|
199479
|
-
if (!options.allowWindowsEscape &&
|
|
199480
|
-
pattern = pattern.split(
|
|
199479
|
+
if (!options.allowWindowsEscape && path6.sep !== "/") {
|
|
199480
|
+
pattern = pattern.split(path6.sep).join("/");
|
|
199481
199481
|
}
|
|
199482
199482
|
this.options = options;
|
|
199483
199483
|
this.set = [];
|
|
@@ -199854,8 +199854,8 @@ var require_minimatch = __commonJS((exports, module) => {
|
|
|
199854
199854
|
if (f === "/" && partial)
|
|
199855
199855
|
return true;
|
|
199856
199856
|
var options = this.options;
|
|
199857
|
-
if (
|
|
199858
|
-
f = f.split(
|
|
199857
|
+
if (path6.sep !== "/") {
|
|
199858
|
+
f = f.split(path6.sep).join("/");
|
|
199859
199859
|
}
|
|
199860
199860
|
f = f.split(slashSplit);
|
|
199861
199861
|
this.debug(this.pattern, "split", f);
|
|
@@ -199966,9 +199966,9 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
199966
199966
|
var p = __require("path");
|
|
199967
199967
|
var minimatch = require_minimatch();
|
|
199968
199968
|
function patternMatcher(pattern) {
|
|
199969
|
-
return function(
|
|
199969
|
+
return function(path6, stats) {
|
|
199970
199970
|
var minimatcher = new minimatch.Minimatch(pattern, { matchBase: true });
|
|
199971
|
-
return (!minimatcher.negate || stats.isFile()) && minimatcher.match(
|
|
199971
|
+
return (!minimatcher.negate || stats.isFile()) && minimatcher.match(path6);
|
|
199972
199972
|
};
|
|
199973
199973
|
}
|
|
199974
199974
|
function toMatcherFunction(ignoreEntry) {
|
|
@@ -199978,14 +199978,14 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
199978
199978
|
return patternMatcher(ignoreEntry);
|
|
199979
199979
|
}
|
|
199980
199980
|
}
|
|
199981
|
-
function readdir3(
|
|
199981
|
+
function readdir3(path6, ignores, callback) {
|
|
199982
199982
|
if (typeof ignores == "function") {
|
|
199983
199983
|
callback = ignores;
|
|
199984
199984
|
ignores = [];
|
|
199985
199985
|
}
|
|
199986
199986
|
if (!callback) {
|
|
199987
199987
|
return new Promise(function(resolve3, reject) {
|
|
199988
|
-
readdir3(
|
|
199988
|
+
readdir3(path6, ignores || [], function(err, data) {
|
|
199989
199989
|
if (err) {
|
|
199990
199990
|
reject(err);
|
|
199991
199991
|
} else {
|
|
@@ -199996,7 +199996,7 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
199996
199996
|
}
|
|
199997
199997
|
ignores = ignores.map(toMatcherFunction);
|
|
199998
199998
|
var list = [];
|
|
199999
|
-
fs4.readdir(
|
|
199999
|
+
fs4.readdir(path6, function(err, files) {
|
|
200000
200000
|
if (err) {
|
|
200001
200001
|
return callback(err);
|
|
200002
200002
|
}
|
|
@@ -200005,7 +200005,7 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
200005
200005
|
return callback(null, list);
|
|
200006
200006
|
}
|
|
200007
200007
|
files.forEach(function(file) {
|
|
200008
|
-
var filePath = p.join(
|
|
200008
|
+
var filePath = p.join(path6, file);
|
|
200009
200009
|
fs4.stat(filePath, function(_err, stats) {
|
|
200010
200010
|
if (_err) {
|
|
200011
200011
|
return callback(_err);
|
|
@@ -200851,8 +200851,8 @@ var require_uri_all = __commonJS((exports, module) => {
|
|
|
200851
200851
|
wsComponents.secure = undefined;
|
|
200852
200852
|
}
|
|
200853
200853
|
if (wsComponents.resourceName) {
|
|
200854
|
-
var _wsComponents$resourc = wsComponents.resourceName.split("?"), _wsComponents$resourc2 = slicedToArray(_wsComponents$resourc, 2),
|
|
200855
|
-
wsComponents.path =
|
|
200854
|
+
var _wsComponents$resourc = wsComponents.resourceName.split("?"), _wsComponents$resourc2 = slicedToArray(_wsComponents$resourc, 2), path11 = _wsComponents$resourc2[0], query = _wsComponents$resourc2[1];
|
|
200855
|
+
wsComponents.path = path11 && path11 !== "/" ? path11 : undefined;
|
|
200856
200856
|
wsComponents.query = query;
|
|
200857
200857
|
wsComponents.resourceName = undefined;
|
|
200858
200858
|
}
|
|
@@ -201245,12 +201245,12 @@ var require_util13 = __commonJS((exports, module) => {
|
|
|
201245
201245
|
return "'" + escapeQuotes(str) + "'";
|
|
201246
201246
|
}
|
|
201247
201247
|
function getPathExpr(currentPath, expr, jsonPointers, isNumber2) {
|
|
201248
|
-
var
|
|
201249
|
-
return joinPaths(currentPath,
|
|
201248
|
+
var path11 = jsonPointers ? "'/' + " + expr + (isNumber2 ? "" : ".replace(/~/g, '~0').replace(/\\//g, '~1')") : isNumber2 ? "'[' + " + expr + " + ']'" : "'[\\'' + " + expr + " + '\\']'";
|
|
201249
|
+
return joinPaths(currentPath, path11);
|
|
201250
201250
|
}
|
|
201251
201251
|
function getPath(currentPath, prop, jsonPointers) {
|
|
201252
|
-
var
|
|
201253
|
-
return joinPaths(currentPath,
|
|
201252
|
+
var path11 = jsonPointers ? toQuotedString("/" + escapeJsonPointer(prop)) : toQuotedString(getProperty(prop));
|
|
201253
|
+
return joinPaths(currentPath, path11);
|
|
201254
201254
|
}
|
|
201255
201255
|
var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
|
|
201256
201256
|
var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
|
|
@@ -207304,11 +207304,11 @@ var require_ast = __commonJS((exports, module) => {
|
|
|
207304
207304
|
helperExpression: function helperExpression(node) {
|
|
207305
207305
|
return node.type === "SubExpression" || (node.type === "MustacheStatement" || node.type === "BlockStatement") && !!(node.params && node.params.length || node.hash);
|
|
207306
207306
|
},
|
|
207307
|
-
scopedId: function scopedId(
|
|
207308
|
-
return /^\.|this\b/.test(
|
|
207307
|
+
scopedId: function scopedId(path11) {
|
|
207308
|
+
return /^\.|this\b/.test(path11.original);
|
|
207309
207309
|
},
|
|
207310
|
-
simpleId: function simpleId(
|
|
207311
|
-
return
|
|
207310
|
+
simpleId: function simpleId(path11) {
|
|
207311
|
+
return path11.parts.length === 1 && !AST.helpers.scopedId(path11) && !path11.depth;
|
|
207312
207312
|
}
|
|
207313
207313
|
}
|
|
207314
207314
|
};
|
|
@@ -208368,12 +208368,12 @@ var require_helpers3 = __commonJS((exports) => {
|
|
|
208368
208368
|
loc
|
|
208369
208369
|
};
|
|
208370
208370
|
}
|
|
208371
|
-
function prepareMustache(
|
|
208371
|
+
function prepareMustache(path11, params, hash, open2, strip, locInfo) {
|
|
208372
208372
|
var escapeFlag = open2.charAt(3) || open2.charAt(2), escaped = escapeFlag !== "{" && escapeFlag !== "&";
|
|
208373
208373
|
var decorator = /\*/.test(open2);
|
|
208374
208374
|
return {
|
|
208375
208375
|
type: decorator ? "Decorator" : "MustacheStatement",
|
|
208376
|
-
path:
|
|
208376
|
+
path: path11,
|
|
208377
208377
|
params,
|
|
208378
208378
|
hash,
|
|
208379
208379
|
escaped,
|
|
@@ -208637,9 +208637,9 @@ var require_compiler = __commonJS((exports) => {
|
|
|
208637
208637
|
},
|
|
208638
208638
|
DecoratorBlock: function DecoratorBlock(decorator) {
|
|
208639
208639
|
var program = decorator.program && this.compileProgram(decorator.program);
|
|
208640
|
-
var params = this.setupFullMustacheParams(decorator, program, undefined),
|
|
208640
|
+
var params = this.setupFullMustacheParams(decorator, program, undefined), path11 = decorator.path;
|
|
208641
208641
|
this.useDecorators = true;
|
|
208642
|
-
this.opcode("registerDecorator", params.length,
|
|
208642
|
+
this.opcode("registerDecorator", params.length, path11.original);
|
|
208643
208643
|
},
|
|
208644
208644
|
PartialStatement: function PartialStatement(partial) {
|
|
208645
208645
|
this.usePartial = true;
|
|
@@ -208702,46 +208702,46 @@ var require_compiler = __commonJS((exports) => {
|
|
|
208702
208702
|
}
|
|
208703
208703
|
},
|
|
208704
208704
|
ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) {
|
|
208705
|
-
var
|
|
208706
|
-
this.opcode("getContext",
|
|
208705
|
+
var path11 = sexpr.path, name = path11.parts[0], isBlock = program != null || inverse != null;
|
|
208706
|
+
this.opcode("getContext", path11.depth);
|
|
208707
208707
|
this.opcode("pushProgram", program);
|
|
208708
208708
|
this.opcode("pushProgram", inverse);
|
|
208709
|
-
|
|
208710
|
-
this.accept(
|
|
208709
|
+
path11.strict = true;
|
|
208710
|
+
this.accept(path11);
|
|
208711
208711
|
this.opcode("invokeAmbiguous", name, isBlock);
|
|
208712
208712
|
},
|
|
208713
208713
|
simpleSexpr: function simpleSexpr(sexpr) {
|
|
208714
|
-
var
|
|
208715
|
-
|
|
208716
|
-
this.accept(
|
|
208714
|
+
var path11 = sexpr.path;
|
|
208715
|
+
path11.strict = true;
|
|
208716
|
+
this.accept(path11);
|
|
208717
208717
|
this.opcode("resolvePossibleLambda");
|
|
208718
208718
|
},
|
|
208719
208719
|
helperSexpr: function helperSexpr(sexpr, program, inverse) {
|
|
208720
|
-
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
|
208720
|
+
var params = this.setupFullMustacheParams(sexpr, program, inverse), path11 = sexpr.path, name = path11.parts[0];
|
|
208721
208721
|
if (this.options.knownHelpers[name]) {
|
|
208722
208722
|
this.opcode("invokeKnownHelper", params.length, name);
|
|
208723
208723
|
} else if (this.options.knownHelpersOnly) {
|
|
208724
208724
|
throw new _exception2["default"]("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
|
208725
208725
|
} else {
|
|
208726
|
-
|
|
208727
|
-
|
|
208728
|
-
this.accept(
|
|
208729
|
-
this.opcode("invokeHelper", params.length,
|
|
208726
|
+
path11.strict = true;
|
|
208727
|
+
path11.falsy = true;
|
|
208728
|
+
this.accept(path11);
|
|
208729
|
+
this.opcode("invokeHelper", params.length, path11.original, _ast2["default"].helpers.simpleId(path11));
|
|
208730
208730
|
}
|
|
208731
208731
|
},
|
|
208732
|
-
PathExpression: function PathExpression(
|
|
208733
|
-
this.addDepth(
|
|
208734
|
-
this.opcode("getContext",
|
|
208735
|
-
var name =
|
|
208732
|
+
PathExpression: function PathExpression(path11) {
|
|
208733
|
+
this.addDepth(path11.depth);
|
|
208734
|
+
this.opcode("getContext", path11.depth);
|
|
208735
|
+
var name = path11.parts[0], scoped = _ast2["default"].helpers.scopedId(path11), blockParamId = !path11.depth && !scoped && this.blockParamIndex(name);
|
|
208736
208736
|
if (blockParamId) {
|
|
208737
|
-
this.opcode("lookupBlockParam", blockParamId,
|
|
208737
|
+
this.opcode("lookupBlockParam", blockParamId, path11.parts);
|
|
208738
208738
|
} else if (!name) {
|
|
208739
208739
|
this.opcode("pushContext");
|
|
208740
|
-
} else if (
|
|
208740
|
+
} else if (path11.data) {
|
|
208741
208741
|
this.options.data = true;
|
|
208742
|
-
this.opcode("lookupData",
|
|
208742
|
+
this.opcode("lookupData", path11.depth, path11.parts, path11.strict);
|
|
208743
208743
|
} else {
|
|
208744
|
-
this.opcode("lookupOnContext",
|
|
208744
|
+
this.opcode("lookupOnContext", path11.parts, path11.falsy, path11.strict, scoped);
|
|
208745
208745
|
}
|
|
208746
208746
|
},
|
|
208747
208747
|
StringLiteral: function StringLiteral(string2) {
|
|
@@ -209085,16 +209085,16 @@ var require_util14 = __commonJS((exports) => {
|
|
|
209085
209085
|
}
|
|
209086
209086
|
exports.urlGenerate = urlGenerate;
|
|
209087
209087
|
function normalize2(aPath) {
|
|
209088
|
-
var
|
|
209088
|
+
var path11 = aPath;
|
|
209089
209089
|
var url2 = urlParse(aPath);
|
|
209090
209090
|
if (url2) {
|
|
209091
209091
|
if (!url2.path) {
|
|
209092
209092
|
return aPath;
|
|
209093
209093
|
}
|
|
209094
|
-
|
|
209094
|
+
path11 = url2.path;
|
|
209095
209095
|
}
|
|
209096
|
-
var isAbsolute3 = exports.isAbsolute(
|
|
209097
|
-
var parts =
|
|
209096
|
+
var isAbsolute3 = exports.isAbsolute(path11);
|
|
209097
|
+
var parts = path11.split(/\/+/);
|
|
209098
209098
|
for (var part, up = 0, i = parts.length - 1;i >= 0; i--) {
|
|
209099
209099
|
part = parts[i];
|
|
209100
209100
|
if (part === ".") {
|
|
@@ -209111,15 +209111,15 @@ var require_util14 = __commonJS((exports) => {
|
|
|
209111
209111
|
}
|
|
209112
209112
|
}
|
|
209113
209113
|
}
|
|
209114
|
-
|
|
209115
|
-
if (
|
|
209116
|
-
|
|
209114
|
+
path11 = parts.join("/");
|
|
209115
|
+
if (path11 === "") {
|
|
209116
|
+
path11 = isAbsolute3 ? "/" : ".";
|
|
209117
209117
|
}
|
|
209118
209118
|
if (url2) {
|
|
209119
|
-
url2.path =
|
|
209119
|
+
url2.path = path11;
|
|
209120
209120
|
return urlGenerate(url2);
|
|
209121
209121
|
}
|
|
209122
|
-
return
|
|
209122
|
+
return path11;
|
|
209123
209123
|
}
|
|
209124
209124
|
exports.normalize = normalize2;
|
|
209125
209125
|
function join9(aRoot, aPath) {
|
|
@@ -211676,8 +211676,8 @@ var require_printer = __commonJS((exports) => {
|
|
|
211676
211676
|
return this.accept(sexpr.path) + " " + params + hash;
|
|
211677
211677
|
};
|
|
211678
211678
|
PrintVisitor.prototype.PathExpression = function(id) {
|
|
211679
|
-
var
|
|
211680
|
-
return (id.data ? "@" : "") + "PATH:" +
|
|
211679
|
+
var path11 = id.parts.join("/");
|
|
211680
|
+
return (id.data ? "@" : "") + "PATH:" + path11;
|
|
211681
211681
|
};
|
|
211682
211682
|
PrintVisitor.prototype.StringLiteral = function(string2) {
|
|
211683
211683
|
return '"' + string2.value + '"';
|
|
@@ -216946,8 +216946,8 @@ var import_cors = __toESM(require_lib7(), 1);
|
|
|
216946
216946
|
var import_express = __toESM(require_express(), 1);
|
|
216947
216947
|
var import_http_proxy_middleware = __toESM(require_dist4(), 1);
|
|
216948
216948
|
import * as http2 from "http";
|
|
216949
|
-
import * as
|
|
216950
|
-
import { fileURLToPath as
|
|
216949
|
+
import * as path11 from "path";
|
|
216950
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
216951
216951
|
|
|
216952
216952
|
// src/controller/compile.controller.ts
|
|
216953
216953
|
class CompileController {
|
|
@@ -217095,12 +217095,20 @@ class InvalidStateTransitionError extends Error {
|
|
|
217095
217095
|
}
|
|
217096
217096
|
|
|
217097
217097
|
// src/service/connection.ts
|
|
217098
|
-
import
|
|
217098
|
+
import"@malloydata/db-bigquery";
|
|
217099
217099
|
import { DuckDBConnection } from "@malloydata/db-duckdb";
|
|
217100
|
-
import
|
|
217101
|
-
import
|
|
217102
|
-
import
|
|
217103
|
-
import {
|
|
217100
|
+
import"@malloydata/db-duckdb/native";
|
|
217101
|
+
import"@malloydata/db-mysql";
|
|
217102
|
+
import"@malloydata/db-postgres";
|
|
217103
|
+
import {
|
|
217104
|
+
buildPoolOptions,
|
|
217105
|
+
SnowflakeConnection
|
|
217106
|
+
} from "@malloydata/db-snowflake";
|
|
217107
|
+
import"@malloydata/db-trino";
|
|
217108
|
+
import {
|
|
217109
|
+
contextOverlay,
|
|
217110
|
+
MalloyConfig
|
|
217111
|
+
} from "@malloydata/malloy";
|
|
217104
217112
|
|
|
217105
217113
|
// ../../node_modules/axios/lib/helpers/bind.js
|
|
217106
217114
|
function bind(fn, thisArg) {
|
|
@@ -220369,90 +220377,354 @@ var {
|
|
|
220369
220377
|
|
|
220370
220378
|
// src/service/connection.ts
|
|
220371
220379
|
import fs from "fs/promises";
|
|
220372
|
-
import
|
|
220373
|
-
// ../../node_modules/uuid/dist/esm/native.js
|
|
220374
|
-
import { randomUUID as randomUUID2 } from "crypto";
|
|
220375
|
-
var native_default = { randomUUID: randomUUID2 };
|
|
220380
|
+
import path2 from "path";
|
|
220376
220381
|
|
|
220377
|
-
//
|
|
220378
|
-
import
|
|
220379
|
-
var
|
|
220380
|
-
|
|
220381
|
-
|
|
220382
|
-
if (
|
|
220383
|
-
|
|
220384
|
-
|
|
220382
|
+
// src/service/connection_config.ts
|
|
220383
|
+
import path from "path";
|
|
220384
|
+
var PUBLISHER_DUCKDB_API_FIELDS = new Set(["attachedDatabases"]);
|
|
220385
|
+
function normalizeSnowflakePrivateKey(privateKey) {
|
|
220386
|
+
let privateKeyContent = privateKey.trim();
|
|
220387
|
+
if (!privateKeyContent.includes(`
|
|
220388
|
+
`)) {
|
|
220389
|
+
const keyPatterns = [
|
|
220390
|
+
{
|
|
220391
|
+
beginRegex: /-----BEGIN\s+ENCRYPTED\s+PRIVATE\s+KEY-----/i,
|
|
220392
|
+
endRegex: /-----END\s+ENCRYPTED\s+PRIVATE\s+KEY-----/i,
|
|
220393
|
+
beginMarker: "-----BEGIN ENCRYPTED PRIVATE KEY-----",
|
|
220394
|
+
endMarker: "-----END ENCRYPTED PRIVATE KEY-----"
|
|
220395
|
+
},
|
|
220396
|
+
{
|
|
220397
|
+
beginRegex: /-----BEGIN\s+PRIVATE\s+KEY-----/i,
|
|
220398
|
+
endRegex: /-----END\s+PRIVATE\s+KEY-----/i,
|
|
220399
|
+
beginMarker: "-----BEGIN PRIVATE KEY-----",
|
|
220400
|
+
endMarker: "-----END PRIVATE KEY-----"
|
|
220401
|
+
}
|
|
220402
|
+
];
|
|
220403
|
+
for (const pattern of keyPatterns) {
|
|
220404
|
+
const beginMatch = privateKeyContent.match(pattern.beginRegex);
|
|
220405
|
+
const endMatch = privateKeyContent.match(pattern.endRegex);
|
|
220406
|
+
if (beginMatch && endMatch) {
|
|
220407
|
+
const beginPos = beginMatch.index + beginMatch[0].length;
|
|
220408
|
+
const endPos = endMatch.index;
|
|
220409
|
+
const keyData = privateKeyContent.substring(beginPos, endPos).replace(/\s+/g, "");
|
|
220410
|
+
const lines = [];
|
|
220411
|
+
for (let i = 0;i < keyData.length; i += 64) {
|
|
220412
|
+
lines.push(keyData.slice(i, i + 64));
|
|
220413
|
+
}
|
|
220414
|
+
privateKeyContent = `${pattern.beginMarker}
|
|
220415
|
+
${lines.join(`
|
|
220416
|
+
`)}
|
|
220417
|
+
${pattern.endMarker}
|
|
220418
|
+
`;
|
|
220419
|
+
break;
|
|
220420
|
+
}
|
|
220421
|
+
}
|
|
220422
|
+
} else if (!privateKeyContent.endsWith(`
|
|
220423
|
+
`)) {
|
|
220424
|
+
privateKeyContent += `
|
|
220425
|
+
`;
|
|
220385
220426
|
}
|
|
220386
|
-
return
|
|
220427
|
+
return privateKeyContent;
|
|
220387
220428
|
}
|
|
220388
|
-
|
|
220389
|
-
|
|
220390
|
-
|
|
220391
|
-
|
|
220392
|
-
|
|
220429
|
+
function validateDuckdbApiSurface(connection) {
|
|
220430
|
+
if (connection.type !== "duckdb" || !connection.duckdbConnection)
|
|
220431
|
+
return;
|
|
220432
|
+
const unsupportedFields = Object.keys(connection.duckdbConnection).filter((field) => !PUBLISHER_DUCKDB_API_FIELDS.has(field) && connection.duckdbConnection[field] !== undefined);
|
|
220433
|
+
if (unsupportedFields.length > 0) {
|
|
220434
|
+
throw new Error(`Unsupported DuckDB connection field(s): ${unsupportedFields.join(", ")}. Publisher only supports attachedDatabases for project-authored DuckDB connections.`);
|
|
220435
|
+
}
|
|
220393
220436
|
}
|
|
220394
|
-
function
|
|
220395
|
-
return
|
|
220437
|
+
function cloneApiConnection(connection) {
|
|
220438
|
+
return { ...connection };
|
|
220396
220439
|
}
|
|
220397
|
-
|
|
220398
|
-
|
|
220399
|
-
|
|
220400
|
-
|
|
220401
|
-
|
|
220440
|
+
function getStaticConnectionAttributes(type) {
|
|
220441
|
+
switch (type) {
|
|
220442
|
+
case "postgres":
|
|
220443
|
+
return {
|
|
220444
|
+
dialectName: "postgres",
|
|
220445
|
+
isPool: false,
|
|
220446
|
+
canPersist: true,
|
|
220447
|
+
canStream: true
|
|
220448
|
+
};
|
|
220449
|
+
case "bigquery":
|
|
220450
|
+
return {
|
|
220451
|
+
dialectName: "standardsql",
|
|
220452
|
+
isPool: false,
|
|
220453
|
+
canPersist: true,
|
|
220454
|
+
canStream: true
|
|
220455
|
+
};
|
|
220456
|
+
case "snowflake":
|
|
220457
|
+
return {
|
|
220458
|
+
dialectName: "snowflake",
|
|
220459
|
+
isPool: true,
|
|
220460
|
+
canPersist: true,
|
|
220461
|
+
canStream: true
|
|
220462
|
+
};
|
|
220463
|
+
case "trino":
|
|
220464
|
+
return {
|
|
220465
|
+
dialectName: "trino",
|
|
220466
|
+
isPool: false,
|
|
220467
|
+
canPersist: true,
|
|
220468
|
+
canStream: false
|
|
220469
|
+
};
|
|
220470
|
+
case "mysql":
|
|
220471
|
+
return {
|
|
220472
|
+
dialectName: "mysql",
|
|
220473
|
+
isPool: false,
|
|
220474
|
+
canPersist: true,
|
|
220475
|
+
canStream: false
|
|
220476
|
+
};
|
|
220477
|
+
case "duckdb":
|
|
220478
|
+
case "motherduck":
|
|
220479
|
+
case "ducklake":
|
|
220480
|
+
return {
|
|
220481
|
+
dialectName: "duckdb",
|
|
220482
|
+
isPool: false,
|
|
220483
|
+
canPersist: true,
|
|
220484
|
+
canStream: true
|
|
220485
|
+
};
|
|
220486
|
+
default:
|
|
220487
|
+
return;
|
|
220402
220488
|
}
|
|
220403
|
-
|
|
220404
|
-
|
|
220405
|
-
if (
|
|
220406
|
-
|
|
220489
|
+
}
|
|
220490
|
+
function parseServiceAccountKey(json) {
|
|
220491
|
+
if (!json)
|
|
220492
|
+
return;
|
|
220493
|
+
const keyData = JSON.parse(json);
|
|
220494
|
+
const requiredFields = ["type", "project_id", "private_key", "client_email"];
|
|
220495
|
+
for (const field of requiredFields) {
|
|
220496
|
+
if (!keyData[field]) {
|
|
220497
|
+
throw new Error(`Invalid service account key: missing "${field}" field`);
|
|
220498
|
+
}
|
|
220499
|
+
}
|
|
220500
|
+
if (keyData.type !== "service_account") {
|
|
220501
|
+
throw new Error('Invalid service account key: incorrect "type" field');
|
|
220502
|
+
}
|
|
220503
|
+
return keyData;
|
|
220504
|
+
}
|
|
220505
|
+
function buildPostgresConnectionString(config) {
|
|
220506
|
+
if (config.connectionString || !process.env.PGSSLMODE) {
|
|
220507
|
+
return config.connectionString;
|
|
220407
220508
|
}
|
|
220408
|
-
|
|
220409
|
-
|
|
220410
|
-
|
|
220411
|
-
|
|
220412
|
-
|
|
220413
|
-
|
|
220509
|
+
const params = new URLSearchParams;
|
|
220510
|
+
params.set("sslmode", process.env.PGSSLMODE);
|
|
220511
|
+
const auth = config.userName && config.password ? `${encodeURIComponent(config.userName)}:${encodeURIComponent(config.password)}@` : config.userName ? `${encodeURIComponent(config.userName)}@` : "";
|
|
220512
|
+
const host = config.host ?? "localhost";
|
|
220513
|
+
const port = config.port ? `:${config.port}` : "";
|
|
220514
|
+
const database = config.databaseName ? `/${encodeURIComponent(config.databaseName)}` : "";
|
|
220515
|
+
return `postgresql://${auth}${host}${port}${database}?${params.toString()}`;
|
|
220516
|
+
}
|
|
220517
|
+
function buildDuckdbEntry(name, projectPath, databaseFilename = `${name}.duckdb`) {
|
|
220518
|
+
return {
|
|
220519
|
+
is: "duckdb",
|
|
220520
|
+
databasePath: path.join(projectPath, databaseFilename)
|
|
220521
|
+
};
|
|
220522
|
+
}
|
|
220523
|
+
function validateConnectionShape(connection) {
|
|
220524
|
+
switch (connection.type) {
|
|
220525
|
+
case "postgres":
|
|
220526
|
+
case "mysql":
|
|
220527
|
+
case "bigquery":
|
|
220528
|
+
break;
|
|
220529
|
+
case "duckdb":
|
|
220530
|
+
if (!connection.duckdbConnection) {
|
|
220531
|
+
throw new Error("DuckDB connection configuration is missing.");
|
|
220532
|
+
}
|
|
220533
|
+
break;
|
|
220534
|
+
case "motherduck":
|
|
220535
|
+
if (!connection.motherduckConnection) {
|
|
220536
|
+
throw new Error("MotherDuck connection configuration is missing.");
|
|
220537
|
+
}
|
|
220538
|
+
if (!connection.motherduckConnection.accessToken) {
|
|
220539
|
+
throw new Error("MotherDuck access token is required.");
|
|
220540
|
+
}
|
|
220541
|
+
break;
|
|
220542
|
+
case "trino":
|
|
220543
|
+
if (!connection.trinoConnection) {
|
|
220544
|
+
throw new Error("Trino connection configuration is missing.");
|
|
220545
|
+
}
|
|
220546
|
+
break;
|
|
220547
|
+
case "snowflake": {
|
|
220548
|
+
const snowflakeConnection = connection.snowflakeConnection;
|
|
220549
|
+
if (!snowflakeConnection) {
|
|
220550
|
+
throw new Error("Snowflake connection configuration is missing.");
|
|
220551
|
+
}
|
|
220552
|
+
if (!snowflakeConnection.account) {
|
|
220553
|
+
throw new Error("Snowflake account is required.");
|
|
220554
|
+
}
|
|
220555
|
+
if (!snowflakeConnection.username) {
|
|
220556
|
+
throw new Error("Snowflake username is required.");
|
|
220557
|
+
}
|
|
220558
|
+
if (!snowflakeConnection.password && !snowflakeConnection.privateKey) {
|
|
220559
|
+
throw new Error("Snowflake password or private key or private key path is required.");
|
|
220560
|
+
}
|
|
220561
|
+
if (!snowflakeConnection.warehouse) {
|
|
220562
|
+
throw new Error("Snowflake warehouse is required.");
|
|
220563
|
+
}
|
|
220564
|
+
break;
|
|
220414
220565
|
}
|
|
220415
|
-
|
|
220416
|
-
|
|
220566
|
+
}
|
|
220567
|
+
}
|
|
220568
|
+
function assembleProjectConnections(connections = [], projectPath = "") {
|
|
220569
|
+
const pojo = { connections: {} };
|
|
220570
|
+
const metadata = new Map;
|
|
220571
|
+
const apiConnections = [];
|
|
220572
|
+
const processedConnections = new Set;
|
|
220573
|
+
for (const connection of connections) {
|
|
220574
|
+
if (!connection.name) {
|
|
220575
|
+
throw new Error("Invalid connection configuration. No name.");
|
|
220417
220576
|
}
|
|
220418
|
-
|
|
220577
|
+
if (processedConnections.has(connection.name)) {
|
|
220578
|
+
continue;
|
|
220579
|
+
}
|
|
220580
|
+
if (connection.name === "duckdb") {
|
|
220581
|
+
throw new Error("DuckDB connection name cannot be 'duckdb'; it is reserved for Publisher package sandboxes.");
|
|
220582
|
+
}
|
|
220583
|
+
processedConnections.add(connection.name);
|
|
220584
|
+
validateDuckdbApiSurface(connection);
|
|
220585
|
+
validateConnectionShape(connection);
|
|
220586
|
+
const apiConnection = cloneApiConnection(connection);
|
|
220587
|
+
apiConnection.attributes = getStaticConnectionAttributes(connection.type);
|
|
220588
|
+
const attachedDatabases = connection.duckdbConnection?.attachedDatabases ?? [];
|
|
220589
|
+
const isDuckLake = connection.type === "ducklake";
|
|
220590
|
+
const isDuckdb = connection.type === "duckdb";
|
|
220591
|
+
const databasePath = isDuckLake ? path.join(projectPath, `${connection.name}_ducklake.duckdb`) : isDuckdb ? path.join(projectPath, `${connection.name}.duckdb`) : undefined;
|
|
220592
|
+
metadata.set(connection.name, {
|
|
220593
|
+
apiConnection,
|
|
220594
|
+
attachedDatabases,
|
|
220595
|
+
hasAzureAttachment: attachedDatabases.some((database) => database.type === "azure"),
|
|
220596
|
+
hasSnowflakePrivateKey: connection.type === "snowflake" && !!connection.snowflakeConnection?.privateKey,
|
|
220597
|
+
isDuckLake,
|
|
220598
|
+
databasePath,
|
|
220599
|
+
workingDirectory: projectPath
|
|
220600
|
+
});
|
|
220601
|
+
switch (connection.type) {
|
|
220602
|
+
case "postgres": {
|
|
220603
|
+
const postgresConnection = connection.postgresConnection;
|
|
220604
|
+
pojo.connections[connection.name] = {
|
|
220605
|
+
is: "postgres",
|
|
220606
|
+
host: postgresConnection?.host,
|
|
220607
|
+
port: postgresConnection?.port,
|
|
220608
|
+
username: postgresConnection?.userName,
|
|
220609
|
+
password: postgresConnection?.password,
|
|
220610
|
+
databaseName: postgresConnection?.databaseName,
|
|
220611
|
+
connectionString: postgresConnection ? buildPostgresConnectionString(postgresConnection) : undefined
|
|
220612
|
+
};
|
|
220613
|
+
break;
|
|
220614
|
+
}
|
|
220615
|
+
case "mysql": {
|
|
220616
|
+
pojo.connections[connection.name] = {
|
|
220617
|
+
is: "mysql",
|
|
220618
|
+
host: connection.mysqlConnection?.host,
|
|
220619
|
+
port: connection.mysqlConnection?.port,
|
|
220620
|
+
user: connection.mysqlConnection?.user,
|
|
220621
|
+
password: connection.mysqlConnection?.password,
|
|
220622
|
+
database: connection.mysqlConnection?.database
|
|
220623
|
+
};
|
|
220624
|
+
break;
|
|
220625
|
+
}
|
|
220626
|
+
case "bigquery": {
|
|
220627
|
+
const serviceAccountKey = parseServiceAccountKey(connection.bigqueryConnection?.serviceAccountKeyJson);
|
|
220628
|
+
pojo.connections[connection.name] = {
|
|
220629
|
+
is: "bigquery",
|
|
220630
|
+
projectId: connection.bigqueryConnection?.defaultProjectId ?? serviceAccountKey?.project_id,
|
|
220631
|
+
serviceAccountKey,
|
|
220632
|
+
location: connection.bigqueryConnection?.location,
|
|
220633
|
+
maximumBytesBilled: connection.bigqueryConnection?.maximumBytesBilled,
|
|
220634
|
+
timeoutMs: connection.bigqueryConnection?.queryTimeoutMilliseconds,
|
|
220635
|
+
billingProjectId: connection.bigqueryConnection?.billingProjectId
|
|
220636
|
+
};
|
|
220637
|
+
break;
|
|
220638
|
+
}
|
|
220639
|
+
case "snowflake": {
|
|
220640
|
+
pojo.connections[connection.name] = {
|
|
220641
|
+
is: "snowflake",
|
|
220642
|
+
account: connection.snowflakeConnection?.account,
|
|
220643
|
+
username: connection.snowflakeConnection?.username,
|
|
220644
|
+
password: connection.snowflakeConnection?.password,
|
|
220645
|
+
privateKey: connection.snowflakeConnection?.privateKey ? normalizeSnowflakePrivateKey(connection.snowflakeConnection.privateKey) : undefined,
|
|
220646
|
+
privateKeyPass: connection.snowflakeConnection?.privateKeyPass,
|
|
220647
|
+
warehouse: connection.snowflakeConnection?.warehouse,
|
|
220648
|
+
database: connection.snowflakeConnection?.database,
|
|
220649
|
+
schema: connection.snowflakeConnection?.schema,
|
|
220650
|
+
role: connection.snowflakeConnection?.role,
|
|
220651
|
+
timeoutMs: connection.snowflakeConnection?.responseTimeoutMilliseconds,
|
|
220652
|
+
poolMin: 1,
|
|
220653
|
+
poolMax: 20
|
|
220654
|
+
};
|
|
220655
|
+
break;
|
|
220656
|
+
}
|
|
220657
|
+
case "trino": {
|
|
220658
|
+
pojo.connections[connection.name] = {
|
|
220659
|
+
is: "trino",
|
|
220660
|
+
...validateAndBuildTrinoCoreConfig(connection.trinoConnection)
|
|
220661
|
+
};
|
|
220662
|
+
break;
|
|
220663
|
+
}
|
|
220664
|
+
case "duckdb": {
|
|
220665
|
+
if (attachedDatabases.some((database) => database.name === connection.name)) {
|
|
220666
|
+
throw new Error(`DuckDB attached database names cannot conflict with connection name ${connection.name}`);
|
|
220667
|
+
}
|
|
220668
|
+
pojo.connections[connection.name] = buildDuckdbEntry(connection.name, projectPath, `${connection.name}.duckdb`);
|
|
220669
|
+
break;
|
|
220670
|
+
}
|
|
220671
|
+
case "motherduck": {
|
|
220672
|
+
if (!connection.motherduckConnection?.accessToken) {
|
|
220673
|
+
throw new Error("MotherDuck access token is required.");
|
|
220674
|
+
}
|
|
220675
|
+
pojo.connections[connection.name] = {
|
|
220676
|
+
is: "duckdb",
|
|
220677
|
+
databasePath: connection.motherduckConnection.database ? `md:${connection.motherduckConnection.database}?attach_mode=single` : "md:",
|
|
220678
|
+
motherDuckToken: connection.motherduckConnection.accessToken
|
|
220679
|
+
};
|
|
220680
|
+
break;
|
|
220681
|
+
}
|
|
220682
|
+
case "ducklake": {
|
|
220683
|
+
if (!connection.ducklakeConnection) {
|
|
220684
|
+
throw new Error("DuckLake connection configuration is missing.");
|
|
220685
|
+
}
|
|
220686
|
+
if (!connection.ducklakeConnection.catalog?.postgresConnection) {
|
|
220687
|
+
throw new Error(`PostgreSQL connection configuration is required for DuckLake catalog: ${connection.name}`);
|
|
220688
|
+
}
|
|
220689
|
+
pojo.connections[connection.name] = buildDuckdbEntry(connection.name, projectPath, `${connection.name}_ducklake.duckdb`);
|
|
220690
|
+
break;
|
|
220691
|
+
}
|
|
220692
|
+
default: {
|
|
220693
|
+
throw new Error(`Unsupported connection type: ${connection.type}`);
|
|
220694
|
+
}
|
|
220695
|
+
}
|
|
220696
|
+
apiConnections.push(apiConnection);
|
|
220419
220697
|
}
|
|
220420
|
-
return
|
|
220698
|
+
return { pojo, metadata, apiConnections };
|
|
220421
220699
|
}
|
|
220422
|
-
|
|
220423
|
-
|
|
220424
|
-
|
|
220425
|
-
if (!trinoConfig.server?.includes(trinoConfig.port?.toString() || "")) {
|
|
220426
|
-
trinoConfig.server = `${trinoConfig.server}:${trinoConfig.port}`;
|
|
220700
|
+
function validateAndBuildTrinoCoreConfig(trinoConfig) {
|
|
220701
|
+
if (!trinoConfig) {
|
|
220702
|
+
return {};
|
|
220427
220703
|
}
|
|
220704
|
+
const server = trinoConfig.server && trinoConfig.port ? trinoConfig.server.includes(trinoConfig.port.toString()) ? trinoConfig.server : `${trinoConfig.server}:${trinoConfig.port}` : trinoConfig.server;
|
|
220428
220705
|
const baseConfig = {
|
|
220429
|
-
server
|
|
220706
|
+
server,
|
|
220430
220707
|
port: trinoConfig.port,
|
|
220431
220708
|
catalog: trinoConfig.catalog,
|
|
220432
220709
|
schema: trinoConfig.schema,
|
|
220433
220710
|
user: trinoConfig.user
|
|
220434
220711
|
};
|
|
220435
220712
|
if (trinoConfig.peakaKey) {
|
|
220436
|
-
baseConfig.
|
|
220437
|
-
|
|
220438
|
-
peakaKey: trinoConfig.peakaKey
|
|
220439
|
-
}
|
|
220713
|
+
baseConfig.extraCredential = {
|
|
220714
|
+
peakaKey: trinoConfig.peakaKey
|
|
220440
220715
|
};
|
|
220441
|
-
|
|
220442
|
-
|
|
220443
|
-
|
|
220444
|
-
} else if (trinoConfig.server?.startsWith("https://") && trinoConfig.password) {
|
|
220716
|
+
return baseConfig;
|
|
220717
|
+
}
|
|
220718
|
+
if (server?.startsWith("https://") && trinoConfig.password) {
|
|
220445
220719
|
baseConfig.password = trinoConfig.password;
|
|
220446
220720
|
}
|
|
220447
|
-
if (
|
|
220448
|
-
delete baseConfig.password;
|
|
220449
|
-
return baseConfig;
|
|
220450
|
-
} else if (trinoConfig.server?.startsWith("https://")) {
|
|
220721
|
+
if (server?.startsWith("http://") || server?.startsWith("https://")) {
|
|
220451
220722
|
return baseConfig;
|
|
220452
|
-
} else {
|
|
220453
|
-
throw new Error(`Invalid Trino connection: expected "http://server:port" or "https://server:port".`);
|
|
220454
220723
|
}
|
|
220724
|
+
throw new Error(`Invalid Trino connection: expected "http://server:port" or "https://server:port".`);
|
|
220455
220725
|
}
|
|
220726
|
+
|
|
220727
|
+
// src/service/connection.ts
|
|
220456
220728
|
async function installAndLoadExtension(connection, extensionName, fromCommunity = false) {
|
|
220457
220729
|
try {
|
|
220458
220730
|
const installCommand = fromCommunity ? `FORCE INSTALL '${extensionName}' FROM community;` : `INSTALL ${extensionName};`;
|
|
@@ -220488,52 +220760,6 @@ function handleAlreadyAttachedError(error, dbName) {
|
|
|
220488
220760
|
throw error;
|
|
220489
220761
|
}
|
|
220490
220762
|
}
|
|
220491
|
-
function normalizePrivateKey(privateKey) {
|
|
220492
|
-
let privateKeyContent = privateKey.trim();
|
|
220493
|
-
if (!privateKeyContent.includes(`
|
|
220494
|
-
`)) {
|
|
220495
|
-
const keyPatterns = [
|
|
220496
|
-
{
|
|
220497
|
-
beginRegex: /-----BEGIN\s+ENCRYPTED\s+PRIVATE\s+KEY-----/i,
|
|
220498
|
-
endRegex: /-----END\s+ENCRYPTED\s+PRIVATE\s+KEY-----/i,
|
|
220499
|
-
beginMarker: "-----BEGIN ENCRYPTED PRIVATE KEY-----",
|
|
220500
|
-
endMarker: "-----END ENCRYPTED PRIVATE KEY-----"
|
|
220501
|
-
},
|
|
220502
|
-
{
|
|
220503
|
-
beginRegex: /-----BEGIN\s+PRIVATE\s+KEY-----/i,
|
|
220504
|
-
endRegex: /-----END\s+PRIVATE\s+KEY-----/i,
|
|
220505
|
-
beginMarker: "-----BEGIN PRIVATE KEY-----",
|
|
220506
|
-
endMarker: "-----END PRIVATE KEY-----"
|
|
220507
|
-
}
|
|
220508
|
-
];
|
|
220509
|
-
for (const pattern of keyPatterns) {
|
|
220510
|
-
const beginMatch = privateKeyContent.match(pattern.beginRegex);
|
|
220511
|
-
const endMatch = privateKeyContent.match(pattern.endRegex);
|
|
220512
|
-
if (beginMatch && endMatch) {
|
|
220513
|
-
const beginPos = beginMatch.index + beginMatch[0].length;
|
|
220514
|
-
const endPos = endMatch.index;
|
|
220515
|
-
const keyData = privateKeyContent.substring(beginPos, endPos).replace(/\s+/g, "");
|
|
220516
|
-
const lines = [];
|
|
220517
|
-
for (let i = 0;i < keyData.length; i += 64) {
|
|
220518
|
-
lines.push(keyData.slice(i, i + 64));
|
|
220519
|
-
}
|
|
220520
|
-
privateKeyContent = `${pattern.beginMarker}
|
|
220521
|
-
${lines.join(`
|
|
220522
|
-
`)}
|
|
220523
|
-
${pattern.endMarker}
|
|
220524
|
-
`;
|
|
220525
|
-
break;
|
|
220526
|
-
}
|
|
220527
|
-
}
|
|
220528
|
-
} else {
|
|
220529
|
-
if (!privateKeyContent.endsWith(`
|
|
220530
|
-
`)) {
|
|
220531
|
-
privateKeyContent += `
|
|
220532
|
-
`;
|
|
220533
|
-
}
|
|
220534
|
-
}
|
|
220535
|
-
return privateKeyContent;
|
|
220536
|
-
}
|
|
220537
220763
|
async function attachBigQuery(connection, attachedDb) {
|
|
220538
220764
|
if (!attachedDb.bigqueryConnection) {
|
|
220539
220765
|
throw new Error(`BigQuery connection configuration missing for: ${attachedDb.name}`);
|
|
@@ -220926,8 +221152,8 @@ function buildAzureFileUrl(azureConn, blobName) {
|
|
|
220926
221152
|
|
|
220927
221153
|
class AzureDuckDBConnection extends DuckDBConnection {
|
|
220928
221154
|
azureDatabases;
|
|
220929
|
-
constructor(
|
|
220930
|
-
super(
|
|
221155
|
+
constructor(options, azureDatabases) {
|
|
221156
|
+
super(options);
|
|
220931
221157
|
this.azureDatabases = azureDatabases;
|
|
220932
221158
|
}
|
|
220933
221159
|
async fetchTableSchema(tableKey, tablePath) {
|
|
@@ -220959,12 +221185,12 @@ class AzureDuckDBConnection extends DuckDBConnection {
|
|
|
220959
221185
|
|
|
220960
221186
|
class DuckLakeConnection extends DuckDBConnection {
|
|
220961
221187
|
connectionName;
|
|
220962
|
-
constructor(
|
|
220963
|
-
super(
|
|
220964
|
-
if (!databasePath
|
|
220965
|
-
throw new Error(`DuckLakeConnection should only be used for DuckLake connections. ` + `Expected database path ending with '_ducklake.duckdb', got: ${databasePath}`);
|
|
221188
|
+
constructor(options) {
|
|
221189
|
+
super(options);
|
|
221190
|
+
if (!options.databasePath?.endsWith("_ducklake.duckdb")) {
|
|
221191
|
+
throw new Error(`DuckLakeConnection should only be used for DuckLake connections. ` + `Expected database path ending with '_ducklake.duckdb', got: ${options.databasePath}`);
|
|
220966
221192
|
}
|
|
220967
|
-
this.connectionName =
|
|
221193
|
+
this.connectionName = options.name;
|
|
220968
221194
|
}
|
|
220969
221195
|
async fetchTableSchema(tableKey, tablePath) {
|
|
220970
221196
|
const parts = tablePath.split(".");
|
|
@@ -220989,7 +221215,7 @@ class DuckLakeConnection extends DuckDBConnection {
|
|
|
220989
221215
|
}
|
|
220990
221216
|
}
|
|
220991
221217
|
async function deleteDuckLakeConnectionFile(connectionName, projectPath) {
|
|
220992
|
-
const ducklakePath =
|
|
221218
|
+
const ducklakePath = path2.join(projectPath, `${connectionName}_ducklake.duckdb`);
|
|
220993
221219
|
try {
|
|
220994
221220
|
await fs.access(ducklakePath);
|
|
220995
221221
|
await fs.rm(ducklakePath);
|
|
@@ -221002,215 +221228,153 @@ async function deleteDuckLakeConnectionFile(connectionName, projectPath) {
|
|
|
221002
221228
|
}
|
|
221003
221229
|
}
|
|
221004
221230
|
}
|
|
221005
|
-
|
|
221006
|
-
const
|
|
221007
|
-
|
|
221008
|
-
|
|
221009
|
-
|
|
221010
|
-
|
|
221011
|
-
|
|
221012
|
-
|
|
221013
|
-
|
|
221014
|
-
|
|
221015
|
-
|
|
221016
|
-
|
|
221017
|
-
|
|
221231
|
+
function entryToDuckDBOptions(name, entry, workingDirectory) {
|
|
221232
|
+
const { is: _is, ...rest } = entry;
|
|
221233
|
+
if (workingDirectory !== undefined) {
|
|
221234
|
+
rest.workingDirectory = workingDirectory;
|
|
221235
|
+
}
|
|
221236
|
+
return { ...removeUndefined(rest), name };
|
|
221237
|
+
}
|
|
221238
|
+
function removeUndefined(value) {
|
|
221239
|
+
return Object.fromEntries(Object.entries(value).filter(([, fieldValue]) => fieldValue !== undefined));
|
|
221240
|
+
}
|
|
221241
|
+
function buildSnowflakePrivateKeyConnection(metadata) {
|
|
221242
|
+
const name = metadata.apiConnection.name;
|
|
221243
|
+
const snowflake = metadata.apiConnection.snowflakeConnection;
|
|
221244
|
+
if (!snowflake?.privateKey) {
|
|
221245
|
+
throw new Error(`Snowflake private key is required for connection ${name}`);
|
|
221246
|
+
}
|
|
221247
|
+
if (!snowflake.account) {
|
|
221248
|
+
throw new Error(`Snowflake account is required for connection ${name}`);
|
|
221249
|
+
}
|
|
221250
|
+
if (!snowflake.username) {
|
|
221251
|
+
throw new Error(`Snowflake username is required for connection ${name}`);
|
|
221252
|
+
}
|
|
221253
|
+
if (!snowflake.warehouse) {
|
|
221254
|
+
throw new Error(`Snowflake warehouse is required for connection ${name}`);
|
|
221255
|
+
}
|
|
221256
|
+
return new SnowflakeConnection(name, {
|
|
221257
|
+
connOptions: {
|
|
221258
|
+
account: snowflake.account,
|
|
221259
|
+
username: snowflake.username,
|
|
221260
|
+
privateKey: normalizeSnowflakePrivateKey(snowflake.privateKey),
|
|
221261
|
+
authenticator: "SNOWFLAKE_JWT",
|
|
221262
|
+
warehouse: snowflake.warehouse,
|
|
221263
|
+
...removeUndefined({
|
|
221264
|
+
password: snowflake.password,
|
|
221265
|
+
privateKeyPass: snowflake.privateKeyPass,
|
|
221266
|
+
database: snowflake.database,
|
|
221267
|
+
schema: snowflake.schema,
|
|
221268
|
+
role: snowflake.role
|
|
221269
|
+
})
|
|
221270
|
+
},
|
|
221271
|
+
timeoutMs: snowflake.responseTimeoutMilliseconds,
|
|
221272
|
+
poolOptions: buildPoolOptions({ poolMin: 1, poolMax: 20 })
|
|
221273
|
+
});
|
|
221274
|
+
}
|
|
221275
|
+
function buildDuckLakeConnection(metadata, entry) {
|
|
221276
|
+
return new DuckLakeConnection(entryToDuckDBOptions(metadata.apiConnection.name, entry, metadata.workingDirectory));
|
|
221277
|
+
}
|
|
221278
|
+
function buildAzureDuckDBConnection(metadata, entry) {
|
|
221279
|
+
return new AzureDuckDBConnection(entryToDuckDBOptions(metadata.apiConnection.name, entry, metadata.workingDirectory), metadata.attachedDatabases);
|
|
221280
|
+
}
|
|
221281
|
+
function getMetadataForLookup(metadata, name) {
|
|
221282
|
+
return name ? metadata.get(name) : undefined;
|
|
221283
|
+
}
|
|
221284
|
+
function isDuckDBConnection(connection) {
|
|
221285
|
+
return connection instanceof DuckDBConnection;
|
|
221286
|
+
}
|
|
221287
|
+
function buildProjectMalloyConfig(connections = [], projectPath = "", isUpdateConnectionRequest = false) {
|
|
221288
|
+
const assembled = assembleProjectConnections(connections, projectPath);
|
|
221289
|
+
const duckLakeCache = new Map;
|
|
221290
|
+
const snowflakeJwtCache = new Map;
|
|
221291
|
+
const azureDuckDBCache = new Map;
|
|
221292
|
+
const attachPromises = new WeakMap;
|
|
221293
|
+
const malloyConfig = new MalloyConfig(assembled.pojo, {
|
|
221294
|
+
config: contextOverlay({ rootDirectory: projectPath })
|
|
221295
|
+
});
|
|
221296
|
+
async function attachOnce(connection, metadata) {
|
|
221297
|
+
if (metadata.attachedDatabases.length === 0 || !isDuckDBConnection(connection)) {
|
|
221298
|
+
return;
|
|
221018
221299
|
}
|
|
221019
|
-
|
|
221020
|
-
|
|
221021
|
-
|
|
221022
|
-
|
|
221023
|
-
|
|
221024
|
-
|
|
221025
|
-
|
|
221026
|
-
|
|
221027
|
-
|
|
221028
|
-
|
|
221029
|
-
|
|
221030
|
-
|
|
221031
|
-
|
|
221032
|
-
|
|
221033
|
-
|
|
221034
|
-
|
|
221035
|
-
|
|
221036
|
-
|
|
221037
|
-
|
|
221038
|
-
|
|
221039
|
-
|
|
221040
|
-
|
|
221041
|
-
|
|
221042
|
-
|
|
221043
|
-
|
|
221044
|
-
|
|
221045
|
-
|
|
221046
|
-
|
|
221047
|
-
|
|
221048
|
-
|
|
221049
|
-
|
|
221050
|
-
|
|
221051
|
-
|
|
221052
|
-
|
|
221053
|
-
|
|
221054
|
-
|
|
221055
|
-
|
|
221056
|
-
|
|
221057
|
-
|
|
221058
|
-
|
|
221059
|
-
|
|
221060
|
-
|
|
221061
|
-
|
|
221062
|
-
|
|
221063
|
-
|
|
221064
|
-
}
|
|
221065
|
-
const bigqueryConnectionOptions = {
|
|
221066
|
-
projectId: connection.bigqueryConnection.defaultProjectId,
|
|
221067
|
-
serviceAccountKeyPath,
|
|
221068
|
-
location: connection.bigqueryConnection.location,
|
|
221069
|
-
maximumBytesBilled: connection.bigqueryConnection.maximumBytesBilled,
|
|
221070
|
-
timeoutMs: connection.bigqueryConnection.queryTimeoutMilliseconds,
|
|
221071
|
-
billingProjectId: connection.bigqueryConnection.billingProjectId
|
|
221072
|
-
};
|
|
221073
|
-
const bigqueryConnection = new BigQueryConnection(connection.name, () => ({}), bigqueryConnectionOptions);
|
|
221074
|
-
connectionMap.set(connection.name, bigqueryConnection);
|
|
221075
|
-
connection.attributes = getConnectionAttributes(bigqueryConnection);
|
|
221076
|
-
break;
|
|
221077
|
-
}
|
|
221078
|
-
case "snowflake": {
|
|
221079
|
-
if (!connection.snowflakeConnection) {
|
|
221080
|
-
throw new Error("Snowflake connection configuration is missing.");
|
|
221081
|
-
}
|
|
221082
|
-
if (!connection.snowflakeConnection.account) {
|
|
221083
|
-
throw new Error("Snowflake account is required.");
|
|
221084
|
-
}
|
|
221085
|
-
if (!connection.snowflakeConnection.username) {
|
|
221086
|
-
throw new Error("Snowflake username is required.");
|
|
221087
|
-
}
|
|
221088
|
-
if (!connection.snowflakeConnection.password && !connection.snowflakeConnection.privateKey) {
|
|
221089
|
-
throw new Error("Snowflake password or private key or private key path is required.");
|
|
221090
|
-
}
|
|
221091
|
-
if (!connection.snowflakeConnection.warehouse) {
|
|
221092
|
-
throw new Error("Snowflake warehouse is required.");
|
|
221093
|
-
}
|
|
221094
|
-
let privateKeyPath = undefined;
|
|
221095
|
-
if (connection.snowflakeConnection.privateKey) {
|
|
221096
|
-
privateKeyPath = path.join(TEMP_DIR_PATH, `${connection.name}-${v4_default()}-private-key.pem`);
|
|
221097
|
-
const normalizedKey = normalizePrivateKey(connection.snowflakeConnection.privateKey);
|
|
221098
|
-
await fs.writeFile(privateKeyPath, normalizedKey);
|
|
221099
|
-
}
|
|
221100
|
-
const snowflakeConnectionOptions = {
|
|
221101
|
-
connOptions: {
|
|
221102
|
-
account: connection.snowflakeConnection.account,
|
|
221103
|
-
username: connection.snowflakeConnection.username,
|
|
221104
|
-
warehouse: connection.snowflakeConnection.warehouse,
|
|
221105
|
-
database: connection.snowflakeConnection.database,
|
|
221106
|
-
schema: connection.snowflakeConnection.schema,
|
|
221107
|
-
role: connection.snowflakeConnection.role,
|
|
221108
|
-
...connection.snowflakeConnection.privateKey ? {
|
|
221109
|
-
privateKeyPath,
|
|
221110
|
-
authenticator: "SNOWFLAKE_JWT",
|
|
221111
|
-
privateKeyPass: connection.snowflakeConnection.privateKeyPass || undefined
|
|
221112
|
-
} : {
|
|
221113
|
-
password: connection.snowflakeConnection.password || undefined
|
|
221114
|
-
},
|
|
221115
|
-
timeout: connection.snowflakeConnection.responseTimeoutMilliseconds
|
|
221116
|
-
},
|
|
221117
|
-
poolOptions: {
|
|
221118
|
-
min: 1,
|
|
221119
|
-
max: 20
|
|
221120
|
-
}
|
|
221121
|
-
};
|
|
221122
|
-
const snowflakeConnection = new SnowflakeConnection(connection.name, snowflakeConnectionOptions);
|
|
221123
|
-
connectionMap.set(connection.name, snowflakeConnection);
|
|
221124
|
-
connection.attributes = getConnectionAttributes(snowflakeConnection);
|
|
221125
|
-
break;
|
|
221126
|
-
}
|
|
221127
|
-
case "trino": {
|
|
221128
|
-
if (!connection.trinoConnection) {
|
|
221129
|
-
throw new Error("Trino connection configuration is missing.");
|
|
221130
|
-
}
|
|
221131
|
-
const trinoConnectionOptions = validateAndBuildTrinoConfig(connection.trinoConnection);
|
|
221132
|
-
const trinoConnection = new TrinoConnection(connection.name, {}, trinoConnectionOptions);
|
|
221133
|
-
connectionMap.set(connection.name, trinoConnection);
|
|
221134
|
-
connection.attributes = getConnectionAttributes(trinoConnection);
|
|
221135
|
-
break;
|
|
221136
|
-
}
|
|
221137
|
-
case "duckdb": {
|
|
221138
|
-
if (!connection.duckdbConnection) {
|
|
221139
|
-
throw new Error("DuckDB connection configuration is missing.");
|
|
221140
|
-
}
|
|
221141
|
-
if (connection.duckdbConnection.attachedDatabases?.some((database) => database.name === connection.name)) {
|
|
221142
|
-
throw new Error(`DuckDB attached databases names cannot conflict with connection name ${connection.name}`);
|
|
221143
|
-
}
|
|
221144
|
-
if (connection.name === "duckdb") {
|
|
221145
|
-
throw new Error("DuckDB connection name cannot be 'duckdb'");
|
|
221146
|
-
}
|
|
221147
|
-
if (connection.duckdbConnection?.attachedDatabases?.length == 0) {
|
|
221148
|
-
throw new Error("DuckDB connection must have at least one attached database");
|
|
221149
|
-
}
|
|
221150
|
-
const attachedDatabases = connection.duckdbConnection.attachedDatabases ?? [];
|
|
221151
|
-
const hasAzureAttached = attachedDatabases.some((db) => db.type === "azure");
|
|
221152
|
-
const duckdbConnection = hasAzureAttached ? new AzureDuckDBConnection(connection.name, path.join(projectPath, `${connection.name}.duckdb`), projectPath, attachedDatabases) : new DuckDBConnection(connection.name, path.join(projectPath, `${connection.name}.duckdb`), projectPath);
|
|
221153
|
-
if (attachedDatabases.length > 0) {
|
|
221154
|
-
await attachDatabasesToDuckDB(duckdbConnection, attachedDatabases);
|
|
221155
|
-
}
|
|
221156
|
-
connectionMap.set(connection.name, duckdbConnection);
|
|
221157
|
-
connection.attributes = getConnectionAttributes(duckdbConnection);
|
|
221158
|
-
break;
|
|
221300
|
+
let attachPromise = attachPromises.get(connection);
|
|
221301
|
+
if (!attachPromise) {
|
|
221302
|
+
attachPromise = attachDatabasesToDuckDB(connection, metadata.attachedDatabases);
|
|
221303
|
+
attachPromises.set(connection, attachPromise);
|
|
221304
|
+
}
|
|
221305
|
+
await attachPromise;
|
|
221306
|
+
}
|
|
221307
|
+
malloyConfig.wrapConnections((base) => ({
|
|
221308
|
+
lookupConnection: async (name) => {
|
|
221309
|
+
const metadata = getMetadataForLookup(assembled.metadata, name);
|
|
221310
|
+
if (metadata?.isDuckLake) {
|
|
221311
|
+
let connectionPromise = duckLakeCache.get(name);
|
|
221312
|
+
if (!connectionPromise) {
|
|
221313
|
+
const entry = assembled.pojo.connections[name];
|
|
221314
|
+
connectionPromise = Promise.resolve(buildDuckLakeConnection(metadata, entry));
|
|
221315
|
+
duckLakeCache.set(name, connectionPromise);
|
|
221316
|
+
}
|
|
221317
|
+
const connection2 = await connectionPromise;
|
|
221318
|
+
if (isUpdateConnectionRequest || !await isDatabaseAttached(connection2, name)) {
|
|
221319
|
+
await attachDuckLake(connection2, name, metadata.apiConnection.ducklakeConnection);
|
|
221320
|
+
}
|
|
221321
|
+
return connection2;
|
|
221322
|
+
}
|
|
221323
|
+
if (metadata?.hasSnowflakePrivateKey) {
|
|
221324
|
+
let connectionPromise = snowflakeJwtCache.get(name);
|
|
221325
|
+
if (!connectionPromise) {
|
|
221326
|
+
connectionPromise = Promise.resolve(buildSnowflakePrivateKeyConnection(metadata));
|
|
221327
|
+
snowflakeJwtCache.set(name, connectionPromise);
|
|
221328
|
+
}
|
|
221329
|
+
return connectionPromise;
|
|
221330
|
+
}
|
|
221331
|
+
if (metadata?.hasAzureAttachment) {
|
|
221332
|
+
let connectionPromise = azureDuckDBCache.get(name);
|
|
221333
|
+
if (!connectionPromise) {
|
|
221334
|
+
const entry = assembled.pojo.connections[name];
|
|
221335
|
+
connectionPromise = Promise.resolve(buildAzureDuckDBConnection(metadata, entry));
|
|
221336
|
+
azureDuckDBCache.set(name, connectionPromise);
|
|
221337
|
+
}
|
|
221338
|
+
const connection2 = await connectionPromise;
|
|
221339
|
+
await attachOnce(connection2, metadata);
|
|
221340
|
+
return connection2;
|
|
221341
|
+
}
|
|
221342
|
+
const connection = await base.lookupConnection(name);
|
|
221343
|
+
if (metadata) {
|
|
221344
|
+
await attachOnce(connection, metadata);
|
|
221159
221345
|
}
|
|
221160
|
-
|
|
221161
|
-
|
|
221162
|
-
|
|
221163
|
-
|
|
221164
|
-
|
|
221165
|
-
|
|
221166
|
-
|
|
221167
|
-
|
|
221168
|
-
|
|
221169
|
-
|
|
221170
|
-
|
|
221171
|
-
|
|
221172
|
-
|
|
221173
|
-
|
|
221174
|
-
|
|
221175
|
-
|
|
221346
|
+
return connection;
|
|
221347
|
+
}
|
|
221348
|
+
}));
|
|
221349
|
+
return {
|
|
221350
|
+
malloyConfig,
|
|
221351
|
+
apiConnections: assembled.apiConnections,
|
|
221352
|
+
releaseConnections: async () => {
|
|
221353
|
+
const wrapperPromises = [
|
|
221354
|
+
...duckLakeCache.values(),
|
|
221355
|
+
...snowflakeJwtCache.values(),
|
|
221356
|
+
...azureDuckDBCache.values()
|
|
221357
|
+
];
|
|
221358
|
+
const closeResults = await Promise.allSettled([
|
|
221359
|
+
malloyConfig.releaseConnections(),
|
|
221360
|
+
...wrapperPromises.map(async (promise) => {
|
|
221361
|
+
const connection = await promise;
|
|
221362
|
+
await connection.close();
|
|
221363
|
+
})
|
|
221364
|
+
]);
|
|
221365
|
+
duckLakeCache.clear();
|
|
221366
|
+
snowflakeJwtCache.clear();
|
|
221367
|
+
azureDuckDBCache.clear();
|
|
221368
|
+
const failures = closeResults.filter((result) => result.status === "rejected");
|
|
221369
|
+
for (const failure of failures) {
|
|
221370
|
+
logger.error("Failed to release project connection", {
|
|
221371
|
+
error: failure.reason
|
|
221176
221372
|
});
|
|
221177
|
-
connectionMap.set(connection.name, motherduckConnection);
|
|
221178
|
-
connection.attributes = getConnectionAttributes(motherduckConnection);
|
|
221179
|
-
break;
|
|
221180
|
-
}
|
|
221181
|
-
case "ducklake": {
|
|
221182
|
-
if (!connection.ducklakeConnection) {
|
|
221183
|
-
throw new Error("DuckLake connection configuration is missing.");
|
|
221184
|
-
}
|
|
221185
|
-
const ducklakeDuckdbConnection = new DuckLakeConnection(connection.name, path.join(projectPath, `${connection.name}_ducklake.duckdb`), projectPath);
|
|
221186
|
-
if (isUpdateConnectionRequest || !await isDatabaseAttached(ducklakeDuckdbConnection, connection.name)) {
|
|
221187
|
-
await attachDuckLake(ducklakeDuckdbConnection, connection.name, connection.ducklakeConnection);
|
|
221188
|
-
}
|
|
221189
|
-
connectionMap.set(connection.name, ducklakeDuckdbConnection);
|
|
221190
|
-
connection.attributes = getConnectionAttributes(ducklakeDuckdbConnection);
|
|
221191
|
-
break;
|
|
221192
221373
|
}
|
|
221193
|
-
|
|
221194
|
-
throw new
|
|
221374
|
+
if (failures.length > 0) {
|
|
221375
|
+
throw new AggregateError(failures.map((failure) => failure.reason), "Failed to release one or more project connections");
|
|
221195
221376
|
}
|
|
221196
221377
|
}
|
|
221197
|
-
apiConnections.push(connection);
|
|
221198
|
-
}
|
|
221199
|
-
return {
|
|
221200
|
-
malloyConnections: connectionMap,
|
|
221201
|
-
apiConnections
|
|
221202
|
-
};
|
|
221203
|
-
}
|
|
221204
|
-
function getConnectionAttributes(connection) {
|
|
221205
|
-
let canStream = false;
|
|
221206
|
-
try {
|
|
221207
|
-
canStream = connection.canStream();
|
|
221208
|
-
} catch {}
|
|
221209
|
-
return {
|
|
221210
|
-
dialectName: connection.dialectName,
|
|
221211
|
-
isPool: connection.isPool(),
|
|
221212
|
-
canPersist: connection.canPersist(),
|
|
221213
|
-
canStream
|
|
221214
221378
|
};
|
|
221215
221379
|
}
|
|
221216
221380
|
async function testDuckDBConnection(duckdbConnection, connectionConfig) {
|
|
@@ -221286,17 +221450,13 @@ ${failedAttachments.join(`
|
|
|
221286
221450
|
}
|
|
221287
221451
|
}
|
|
221288
221452
|
async function testConnectionConfig(connectionConfig) {
|
|
221289
|
-
let
|
|
221453
|
+
let projectConfig = null;
|
|
221290
221454
|
try {
|
|
221291
221455
|
if (!connectionConfig.name) {
|
|
221292
221456
|
throw new Error("Connection name is required");
|
|
221293
221457
|
}
|
|
221294
|
-
|
|
221295
|
-
|
|
221296
|
-
const connection = malloyConnections.get(connectionConfig.name);
|
|
221297
|
-
if (!connection) {
|
|
221298
|
-
throw new Error(`Failed to create connection: ${connectionConfig.name}`);
|
|
221299
|
-
}
|
|
221458
|
+
projectConfig = buildProjectMalloyConfig([connectionConfig]);
|
|
221459
|
+
const connection = await projectConfig.malloyConfig.connections.lookupConnection(connectionConfig.name);
|
|
221300
221460
|
if (connectionConfig.type === "duckdb") {
|
|
221301
221461
|
await testDuckDBConnection(connection, connectionConfig);
|
|
221302
221462
|
} else if (connectionConfig.type === "ducklake") {
|
|
@@ -221325,25 +221485,41 @@ async function testConnectionConfig(connectionConfig) {
|
|
|
221325
221485
|
errorMessage: error.message
|
|
221326
221486
|
};
|
|
221327
221487
|
} finally {
|
|
221328
|
-
if (
|
|
221329
|
-
|
|
221330
|
-
|
|
221331
|
-
|
|
221332
|
-
|
|
221333
|
-
|
|
221334
|
-
}
|
|
221335
|
-
logger.warn(`Error closing connection ${connName} during test cleanup`, { error: closeError });
|
|
221336
|
-
} finally {
|
|
221337
|
-
if (connectionConfig.type === "ducklake") {
|
|
221338
|
-
await deleteDuckLakeConnectionFile(connName, process.cwd());
|
|
221339
|
-
}
|
|
221340
|
-
}
|
|
221488
|
+
if (projectConfig) {
|
|
221489
|
+
try {
|
|
221490
|
+
await projectConfig.releaseConnections();
|
|
221491
|
+
} catch (closeError) {
|
|
221492
|
+
logger.warn("Error releasing temporary connection test config", {
|
|
221493
|
+
error: closeError
|
|
221494
|
+
});
|
|
221341
221495
|
}
|
|
221342
221496
|
}
|
|
221497
|
+
if (connectionConfig.type === "ducklake" && connectionConfig.name) {
|
|
221498
|
+
await deleteDuckLakeConnectionFile(connectionConfig.name, process.cwd());
|
|
221499
|
+
}
|
|
221343
221500
|
}
|
|
221344
221501
|
}
|
|
221345
221502
|
|
|
221346
221503
|
// src/service/connection_service.ts
|
|
221504
|
+
async function runProjectConnectionUpdate(project, fn) {
|
|
221505
|
+
if (project.runConnectionUpdateExclusive) {
|
|
221506
|
+
return project.runConnectionUpdateExclusive(fn);
|
|
221507
|
+
}
|
|
221508
|
+
return fn();
|
|
221509
|
+
}
|
|
221510
|
+
function updateProjectConnections(project, nextMalloyConfig, afterPreviousRelease) {
|
|
221511
|
+
project.updateConnections?.(nextMalloyConfig, nextMalloyConfig.apiConnections, afterPreviousRelease);
|
|
221512
|
+
}
|
|
221513
|
+
function buildDeletedConnectionCleanup(project, deletedConnection, connectionName) {
|
|
221514
|
+
if (deletedConnection.type === "duckdb" && typeof project.deleteDuckDBConnection === "function") {
|
|
221515
|
+
return () => project.deleteDuckDBConnection(connectionName);
|
|
221516
|
+
}
|
|
221517
|
+
if (deletedConnection.type === "ducklake" && typeof project.deleteDuckLakeConnection === "function") {
|
|
221518
|
+
return () => project.deleteDuckLakeConnection(connectionName);
|
|
221519
|
+
}
|
|
221520
|
+
return;
|
|
221521
|
+
}
|
|
221522
|
+
|
|
221347
221523
|
class ConnectionService {
|
|
221348
221524
|
projectStore;
|
|
221349
221525
|
constructor(projectStore) {
|
|
@@ -221378,10 +221554,12 @@ class ConnectionService {
|
|
|
221378
221554
|
throw new Error(`Connection "${connectionName}" already exists in project "${projectName}".`);
|
|
221379
221555
|
}
|
|
221380
221556
|
const project = await this.projectStore.getProject(projectName, false);
|
|
221381
|
-
|
|
221382
|
-
|
|
221383
|
-
|
|
221384
|
-
|
|
221557
|
+
await runProjectConnectionUpdate(project, async () => {
|
|
221558
|
+
const existingConnections = project.listApiConnections();
|
|
221559
|
+
const nextMalloyConfig = buildProjectMalloyConfig([...existingConnections, connection], project.metadata.location || "");
|
|
221560
|
+
await this.projectStore.addConnection(connection, dbProject.id, repository);
|
|
221561
|
+
updateProjectConnections(project, nextMalloyConfig);
|
|
221562
|
+
});
|
|
221385
221563
|
logger.info(`Successfully added connection "${connection.name}" to project "${projectName}"`);
|
|
221386
221564
|
}
|
|
221387
221565
|
async updateConnection(projectName, connectionName, connection) {
|
|
@@ -221392,16 +221570,18 @@ class ConnectionService {
|
|
|
221392
221570
|
logger.info(`Updating connection "${connectionName}" in project "${projectName}"`);
|
|
221393
221571
|
const { dbProject, dbConnection, repository } = await this.getConnection(projectName, connectionName);
|
|
221394
221572
|
const project = await this.projectStore.getProject(projectName, false);
|
|
221395
|
-
|
|
221396
|
-
|
|
221397
|
-
|
|
221398
|
-
|
|
221399
|
-
|
|
221400
|
-
|
|
221401
|
-
|
|
221402
|
-
|
|
221403
|
-
|
|
221404
|
-
|
|
221573
|
+
await runProjectConnectionUpdate(project, async () => {
|
|
221574
|
+
const existingConnections = project.listApiConnections();
|
|
221575
|
+
const updatedConnection = {
|
|
221576
|
+
...dbConnection.config,
|
|
221577
|
+
...connection,
|
|
221578
|
+
name: connectionName
|
|
221579
|
+
};
|
|
221580
|
+
const updatedConnections = existingConnections.map((conn) => conn.name === connectionName ? updatedConnection : conn);
|
|
221581
|
+
const nextMalloyConfig = buildProjectMalloyConfig(updatedConnections, project.metadata.location || "", true);
|
|
221582
|
+
await this.projectStore.updateConnection(updatedConnection, dbProject.id, repository);
|
|
221583
|
+
updateProjectConnections(project, nextMalloyConfig);
|
|
221584
|
+
});
|
|
221405
221585
|
logger.info(`Successfully updated connection "${connectionName}" in project "${projectName}"`);
|
|
221406
221586
|
}
|
|
221407
221587
|
async deleteConnection(projectName, connectionName) {
|
|
@@ -221412,8 +221592,21 @@ class ConnectionService {
|
|
|
221412
221592
|
logger.info(`Deleting connection "${connectionName}" from project "${projectName}"`);
|
|
221413
221593
|
const { dbConnection, repository } = await this.getConnection(projectName, connectionName);
|
|
221414
221594
|
const project = await this.projectStore.getProject(projectName, false);
|
|
221415
|
-
await project
|
|
221416
|
-
|
|
221595
|
+
await runProjectConnectionUpdate(project, async () => {
|
|
221596
|
+
if (typeof project.listApiConnections !== "function") {
|
|
221597
|
+
if (typeof project.deleteConnection === "function") {
|
|
221598
|
+
await project.deleteConnection(connectionName);
|
|
221599
|
+
}
|
|
221600
|
+
await repository.deleteConnection(dbConnection.id);
|
|
221601
|
+
return;
|
|
221602
|
+
}
|
|
221603
|
+
const deletedConnection = "getApiConnection" in project && typeof project.getApiConnection === "function" ? project.getApiConnection(connectionName) : dbConnection.config;
|
|
221604
|
+
const updatedConnections = project.listApiConnections().filter((connection) => connection.name !== connectionName);
|
|
221605
|
+
const nextMalloyConfig = buildProjectMalloyConfig(updatedConnections, project.metadata.location || "");
|
|
221606
|
+
const deleteConnectionFilesAfterRelease = buildDeletedConnectionCleanup(project, deletedConnection, connectionName);
|
|
221607
|
+
await repository.deleteConnection(dbConnection.id);
|
|
221608
|
+
updateProjectConnections(project, nextMalloyConfig, deleteConnectionFilesAfterRelease);
|
|
221609
|
+
});
|
|
221417
221610
|
logger.info(`Successfully deleted connection "${connectionName}" from project "${projectName}"`);
|
|
221418
221611
|
}
|
|
221419
221612
|
}
|
|
@@ -222426,6 +222619,16 @@ function validateAzureAttachedDatabases(connectionConfig) {
|
|
|
222426
222619
|
}
|
|
222427
222620
|
}
|
|
222428
222621
|
}
|
|
222622
|
+
function validateAdminAuthoredConnection(connectionName, connectionConfig) {
|
|
222623
|
+
if (connectionName === "duckdb" || connectionConfig.name === "duckdb") {
|
|
222624
|
+
throw new BadRequestError("DuckDB connection name cannot be 'duckdb'; it is reserved for Publisher package sandboxes.");
|
|
222625
|
+
}
|
|
222626
|
+
try {
|
|
222627
|
+
validateDuckdbApiSurface(connectionConfig);
|
|
222628
|
+
} catch (error) {
|
|
222629
|
+
throw new BadRequestError(error.message);
|
|
222630
|
+
}
|
|
222631
|
+
}
|
|
222429
222632
|
|
|
222430
222633
|
class ConnectionController {
|
|
222431
222634
|
projectStore;
|
|
@@ -222434,22 +222637,42 @@ class ConnectionController {
|
|
|
222434
222637
|
this.projectStore = projectStore;
|
|
222435
222638
|
this.connectionService = new ConnectionService(projectStore);
|
|
222436
222639
|
}
|
|
222437
|
-
|
|
222640
|
+
getApiConnectionForLookup(project, connectionName) {
|
|
222641
|
+
if (connectionName === "duckdb") {
|
|
222642
|
+
return {
|
|
222643
|
+
name: "duckdb",
|
|
222644
|
+
type: "duckdb",
|
|
222645
|
+
duckdbConnection: { attachedDatabases: [] }
|
|
222646
|
+
};
|
|
222647
|
+
}
|
|
222648
|
+
return project.getApiConnection(connectionName);
|
|
222649
|
+
}
|
|
222650
|
+
async getMalloyConnection(projectName, connectionName, packageName) {
|
|
222438
222651
|
const project = await this.projectStore.getProject(projectName, false);
|
|
222439
|
-
|
|
222440
|
-
if (connection.name === "duckdb" && connection.type === "duckdb") {
|
|
222652
|
+
if (connectionName === "duckdb") {
|
|
222441
222653
|
const packages = await project.listPackages();
|
|
222442
222654
|
if (packages.length === 0) {
|
|
222443
|
-
return project.getMalloyConnection(connectionName);
|
|
222655
|
+
return await project.getMalloyConnection(connectionName);
|
|
222656
|
+
}
|
|
222657
|
+
if (packageName) {
|
|
222658
|
+
const known = packages.some((p) => p.name === packageName);
|
|
222659
|
+
if (!known) {
|
|
222660
|
+
throw new BadRequestError(`Package "${packageName}" not found in project "${projectName}"`);
|
|
222661
|
+
}
|
|
222662
|
+
const pkg = await project.getPackage(packageName);
|
|
222663
|
+
return await pkg.getMalloyConnection(connectionName);
|
|
222444
222664
|
}
|
|
222445
|
-
|
|
222446
|
-
|
|
222447
|
-
|
|
222665
|
+
if (packages.length === 1) {
|
|
222666
|
+
const onlyPackage = packages[0].name;
|
|
222667
|
+
if (!onlyPackage) {
|
|
222668
|
+
throw new ConnectionError("Package name is undefined");
|
|
222669
|
+
}
|
|
222670
|
+
const pkg = await project.getPackage(onlyPackage);
|
|
222671
|
+
return await pkg.getMalloyConnection(connectionName);
|
|
222448
222672
|
}
|
|
222449
|
-
|
|
222450
|
-
return pkg.getMalloyConnection(connectionName);
|
|
222673
|
+
throw new BadRequestError(`Ambiguous "duckdb" connection lookup: project "${projectName}" has multiple packages. ` + `Use /projects/${projectName}/packages/{packageName}/connections/duckdb/... to disambiguate.`);
|
|
222451
222674
|
} else {
|
|
222452
|
-
return project.getMalloyConnection(connectionName);
|
|
222675
|
+
return await project.getMalloyConnection(connectionName);
|
|
222453
222676
|
}
|
|
222454
222677
|
}
|
|
222455
222678
|
async fetchTable(malloyConnection, tableKey, tablePath) {
|
|
@@ -222490,20 +222713,20 @@ class ConnectionController {
|
|
|
222490
222713
|
const project = await this.projectStore.getProject(projectName, false);
|
|
222491
222714
|
return project.listApiConnections();
|
|
222492
222715
|
}
|
|
222493
|
-
async listSchemas(projectName, connectionName) {
|
|
222716
|
+
async listSchemas(projectName, connectionName, packageName) {
|
|
222494
222717
|
const project = await this.projectStore.getProject(projectName, false);
|
|
222495
|
-
const connection =
|
|
222496
|
-
const malloyConnection = await this.getMalloyConnection(projectName, connectionName);
|
|
222718
|
+
const connection = this.getApiConnectionForLookup(project, connectionName);
|
|
222719
|
+
const malloyConnection = await this.getMalloyConnection(projectName, connectionName, packageName);
|
|
222497
222720
|
return getSchemasForConnection(connection, malloyConnection);
|
|
222498
222721
|
}
|
|
222499
|
-
async listTables(projectName, connectionName, schemaName, tableNames) {
|
|
222722
|
+
async listTables(projectName, connectionName, schemaName, tableNames, packageName) {
|
|
222500
222723
|
const project = await this.projectStore.getProject(projectName, false);
|
|
222501
|
-
const connection =
|
|
222502
|
-
const malloyConnection = await this.getMalloyConnection(projectName, connectionName);
|
|
222724
|
+
const connection = this.getApiConnectionForLookup(project, connectionName);
|
|
222725
|
+
const malloyConnection = await this.getMalloyConnection(projectName, connectionName, packageName);
|
|
222503
222726
|
return listTablesForSchema(connection, schemaName, malloyConnection, tableNames);
|
|
222504
222727
|
}
|
|
222505
|
-
async getConnectionSqlSource(projectName, connectionName, sqlStatement) {
|
|
222506
|
-
const malloyConnection = await this.getMalloyConnection(projectName, connectionName);
|
|
222728
|
+
async getConnectionSqlSource(projectName, connectionName, sqlStatement, packageName) {
|
|
222729
|
+
const malloyConnection = await this.getMalloyConnection(projectName, connectionName, packageName);
|
|
222507
222730
|
try {
|
|
222508
222731
|
const schema = await malloyConnection.fetchSelectSchema({
|
|
222509
222732
|
connection: connectionName,
|
|
@@ -222519,10 +222742,10 @@ class ConnectionController {
|
|
|
222519
222742
|
throw new ConnectionError(error.message);
|
|
222520
222743
|
}
|
|
222521
222744
|
}
|
|
222522
|
-
async getTable(projectName, connectionName, schemaName, tablePath) {
|
|
222523
|
-
const malloyConnection = await this.getMalloyConnection(projectName, connectionName);
|
|
222745
|
+
async getTable(projectName, connectionName, schemaName, tablePath, packageName) {
|
|
222746
|
+
const malloyConnection = await this.getMalloyConnection(projectName, connectionName, packageName);
|
|
222524
222747
|
const project = await this.projectStore.getProject(projectName, false);
|
|
222525
|
-
const connection =
|
|
222748
|
+
const connection = this.getApiConnectionForLookup(project, connectionName);
|
|
222526
222749
|
if (connection.type === "ducklake") {
|
|
222527
222750
|
if (tablePath.split(".").length === 1) {
|
|
222528
222751
|
tablePath = `${connectionName}.${schemaName}.${tablePath}`;
|
|
@@ -222554,8 +222777,8 @@ class ConnectionController {
|
|
|
222554
222777
|
}
|
|
222555
222778
|
return this.fetchTable(malloyConnection, tableKey, tablePath);
|
|
222556
222779
|
}
|
|
222557
|
-
async getConnectionQueryData(projectName, connectionName, sqlStatement, options) {
|
|
222558
|
-
const malloyConnection = await this.getMalloyConnection(projectName, connectionName);
|
|
222780
|
+
async getConnectionQueryData(projectName, connectionName, sqlStatement, options, packageName) {
|
|
222781
|
+
const malloyConnection = await this.getMalloyConnection(projectName, connectionName, packageName);
|
|
222559
222782
|
let runSQLOptions = {};
|
|
222560
222783
|
if (options) {
|
|
222561
222784
|
runSQLOptions = JSON.parse(options);
|
|
@@ -222572,8 +222795,8 @@ class ConnectionController {
|
|
|
222572
222795
|
throw new ConnectionError(error.message);
|
|
222573
222796
|
}
|
|
222574
222797
|
}
|
|
222575
|
-
async getConnectionTemporaryTable(projectName, connectionName, sqlStatement) {
|
|
222576
|
-
const malloyConnection = await this.getMalloyConnection(projectName, connectionName);
|
|
222798
|
+
async getConnectionTemporaryTable(projectName, connectionName, sqlStatement, packageName) {
|
|
222799
|
+
const malloyConnection = await this.getMalloyConnection(projectName, connectionName, packageName);
|
|
222577
222800
|
try {
|
|
222578
222801
|
return {
|
|
222579
222802
|
table: JSON.stringify(await malloyConnection.manifestTemporaryTable(sqlStatement))
|
|
@@ -222582,10 +222805,8 @@ class ConnectionController {
|
|
|
222582
222805
|
throw new ConnectionError(error.message);
|
|
222583
222806
|
}
|
|
222584
222807
|
}
|
|
222585
|
-
async testConnectionConfiguration(
|
|
222586
|
-
|
|
222587
|
-
connectionConfig = connectionConfig.config;
|
|
222588
|
-
}
|
|
222808
|
+
async testConnectionConfiguration(input) {
|
|
222809
|
+
const connectionConfig = input.config && typeof input.config === "object" ? input.config : input;
|
|
222589
222810
|
if (!connectionConfig || typeof connectionConfig !== "object" || Object.keys(connectionConfig).length === 0) {
|
|
222590
222811
|
throw new BadRequestError("Connection configuration is required and cannot be empty");
|
|
222591
222812
|
}
|
|
@@ -222612,6 +222833,7 @@ class ConnectionController {
|
|
|
222612
222833
|
throw new BadRequestError("Connection type is required");
|
|
222613
222834
|
}
|
|
222614
222835
|
validateAzureAttachedDatabases(connectionConfig);
|
|
222836
|
+
validateAdminAuthoredConnection(connectionName, connectionConfig);
|
|
222615
222837
|
logger.info(`Creating connection "${connectionName}" in project "${projectName}"`);
|
|
222616
222838
|
await this.connectionService.addConnection(projectName, connectionName, connectionConfig);
|
|
222617
222839
|
return {
|
|
@@ -222623,6 +222845,7 @@ class ConnectionController {
|
|
|
222623
222845
|
throw new BadRequestError("Connection payload is required");
|
|
222624
222846
|
}
|
|
222625
222847
|
validateAzureAttachedDatabases(connection);
|
|
222848
|
+
validateAdminAuthoredConnection(connectionName, connection);
|
|
222626
222849
|
logger.info(`Updating connection "${connectionName}" in project "${projectName}"`);
|
|
222627
222850
|
await this.connectionService.updateConnection(projectName, connectionName, connection);
|
|
222628
222851
|
return {
|
|
@@ -222713,7 +222936,7 @@ class ModelController {
|
|
|
222713
222936
|
}
|
|
222714
222937
|
|
|
222715
222938
|
// src/controller/package.controller.ts
|
|
222716
|
-
import * as
|
|
222939
|
+
import * as path3 from "path";
|
|
222717
222940
|
class PackageController {
|
|
222718
222941
|
projectStore;
|
|
222719
222942
|
manifestService;
|
|
@@ -222797,7 +223020,7 @@ class PackageController {
|
|
|
222797
223020
|
return result;
|
|
222798
223021
|
}
|
|
222799
223022
|
async downloadPackage(projectName, packageName, packageLocation) {
|
|
222800
|
-
const absoluteTargetPath =
|
|
223023
|
+
const absoluteTargetPath = path3.join(this.projectStore.serverRootPath, PUBLISHER_DATA_DIR, projectName, packageName);
|
|
222801
223024
|
const isCompressedFile = packageLocation.endsWith(".zip");
|
|
222802
223025
|
if (packageLocation.startsWith("https://") || packageLocation.startsWith("git@")) {
|
|
222803
223026
|
await this.projectStore.downloadGitHubDirectory(packageLocation, absoluteTargetPath);
|
|
@@ -222921,7 +223144,7 @@ class ReaddirpStream extends Readable2 {
|
|
|
222921
223144
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
222922
223145
|
const statMethod = opts.lstat ? lstat : stat;
|
|
222923
223146
|
if (wantBigintFsStats) {
|
|
222924
|
-
this._stat = (
|
|
223147
|
+
this._stat = (path4) => statMethod(path4, { bigint: true });
|
|
222925
223148
|
} else {
|
|
222926
223149
|
this._stat = statMethod;
|
|
222927
223150
|
}
|
|
@@ -222946,8 +223169,8 @@ class ReaddirpStream extends Readable2 {
|
|
|
222946
223169
|
const par = this.parent;
|
|
222947
223170
|
const fil = par && par.files;
|
|
222948
223171
|
if (fil && fil.length > 0) {
|
|
222949
|
-
const { path:
|
|
222950
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
223172
|
+
const { path: path4, depth } = par;
|
|
223173
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path4));
|
|
222951
223174
|
const awaited = await Promise.all(slice);
|
|
222952
223175
|
for (const entry of awaited) {
|
|
222953
223176
|
if (!entry)
|
|
@@ -222987,20 +223210,20 @@ class ReaddirpStream extends Readable2 {
|
|
|
222987
223210
|
this.reading = false;
|
|
222988
223211
|
}
|
|
222989
223212
|
}
|
|
222990
|
-
async _exploreDir(
|
|
223213
|
+
async _exploreDir(path4, depth) {
|
|
222991
223214
|
let files;
|
|
222992
223215
|
try {
|
|
222993
|
-
files = await readdir(
|
|
223216
|
+
files = await readdir(path4, this._rdOptions);
|
|
222994
223217
|
} catch (error) {
|
|
222995
223218
|
this._onError(error);
|
|
222996
223219
|
}
|
|
222997
|
-
return { files, depth, path:
|
|
223220
|
+
return { files, depth, path: path4 };
|
|
222998
223221
|
}
|
|
222999
|
-
async _formatEntry(dirent,
|
|
223222
|
+
async _formatEntry(dirent, path4) {
|
|
223000
223223
|
let entry;
|
|
223001
223224
|
const basename = this._isDirent ? dirent.name : dirent;
|
|
223002
223225
|
try {
|
|
223003
|
-
const fullPath = presolve(pjoin(
|
|
223226
|
+
const fullPath = presolve(pjoin(path4, basename));
|
|
223004
223227
|
entry = { path: prelative(this._root, fullPath), fullPath, basename };
|
|
223005
223228
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
223006
223229
|
} catch (err) {
|
|
@@ -223399,16 +223622,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
223399
223622
|
};
|
|
223400
223623
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
223401
223624
|
var FsWatchInstances = new Map;
|
|
223402
|
-
function createFsWatchInstance(
|
|
223625
|
+
function createFsWatchInstance(path4, options, listener, errHandler, emitRaw) {
|
|
223403
223626
|
const handleEvent = (rawEvent, evPath) => {
|
|
223404
|
-
listener(
|
|
223405
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
223406
|
-
if (evPath &&
|
|
223407
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
223627
|
+
listener(path4);
|
|
223628
|
+
emitRaw(rawEvent, evPath, { watchedPath: path4 });
|
|
223629
|
+
if (evPath && path4 !== evPath) {
|
|
223630
|
+
fsWatchBroadcast(sysPath.resolve(path4, evPath), KEY_LISTENERS, sysPath.join(path4, evPath));
|
|
223408
223631
|
}
|
|
223409
223632
|
};
|
|
223410
223633
|
try {
|
|
223411
|
-
return fs_watch(
|
|
223634
|
+
return fs_watch(path4, {
|
|
223412
223635
|
persistent: options.persistent
|
|
223413
223636
|
}, handleEvent);
|
|
223414
223637
|
} catch (error) {
|
|
@@ -223424,12 +223647,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
223424
223647
|
listener(val1, val2, val3);
|
|
223425
223648
|
});
|
|
223426
223649
|
};
|
|
223427
|
-
var setFsWatchListener = (
|
|
223650
|
+
var setFsWatchListener = (path4, fullPath, options, handlers) => {
|
|
223428
223651
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
223429
223652
|
let cont = FsWatchInstances.get(fullPath);
|
|
223430
223653
|
let watcher;
|
|
223431
223654
|
if (!options.persistent) {
|
|
223432
|
-
watcher = createFsWatchInstance(
|
|
223655
|
+
watcher = createFsWatchInstance(path4, options, listener, errHandler, rawEmitter);
|
|
223433
223656
|
if (!watcher)
|
|
223434
223657
|
return;
|
|
223435
223658
|
return watcher.close.bind(watcher);
|
|
@@ -223439,7 +223662,7 @@ var setFsWatchListener = (path3, fullPath, options, handlers) => {
|
|
|
223439
223662
|
addAndConvert(cont, KEY_ERR, errHandler);
|
|
223440
223663
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
223441
223664
|
} else {
|
|
223442
|
-
watcher = createFsWatchInstance(
|
|
223665
|
+
watcher = createFsWatchInstance(path4, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
223443
223666
|
if (!watcher)
|
|
223444
223667
|
return;
|
|
223445
223668
|
watcher.on(EV.ERROR, async (error) => {
|
|
@@ -223448,7 +223671,7 @@ var setFsWatchListener = (path3, fullPath, options, handlers) => {
|
|
|
223448
223671
|
cont.watcherUnusable = true;
|
|
223449
223672
|
if (isWindows && error.code === "EPERM") {
|
|
223450
223673
|
try {
|
|
223451
|
-
const fd = await open(
|
|
223674
|
+
const fd = await open(path4, "r");
|
|
223452
223675
|
await fd.close();
|
|
223453
223676
|
broadcastErr(error);
|
|
223454
223677
|
} catch (err) {}
|
|
@@ -223478,7 +223701,7 @@ var setFsWatchListener = (path3, fullPath, options, handlers) => {
|
|
|
223478
223701
|
};
|
|
223479
223702
|
};
|
|
223480
223703
|
var FsWatchFileInstances = new Map;
|
|
223481
|
-
var setFsWatchFileListener = (
|
|
223704
|
+
var setFsWatchFileListener = (path4, fullPath, options, handlers) => {
|
|
223482
223705
|
const { listener, rawEmitter } = handlers;
|
|
223483
223706
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
223484
223707
|
const copts = cont && cont.options;
|
|
@@ -223500,7 +223723,7 @@ var setFsWatchFileListener = (path3, fullPath, options, handlers) => {
|
|
|
223500
223723
|
});
|
|
223501
223724
|
const currmtime = curr.mtimeMs;
|
|
223502
223725
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
223503
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
223726
|
+
foreach(cont.listeners, (listener2) => listener2(path4, curr));
|
|
223504
223727
|
}
|
|
223505
223728
|
})
|
|
223506
223729
|
};
|
|
@@ -223523,13 +223746,13 @@ class NodeFsHandler {
|
|
|
223523
223746
|
this.fsw = fsW;
|
|
223524
223747
|
this._boundHandleError = (error) => fsW._handleError(error);
|
|
223525
223748
|
}
|
|
223526
|
-
_watchWithNodeFs(
|
|
223749
|
+
_watchWithNodeFs(path4, listener) {
|
|
223527
223750
|
const opts = this.fsw.options;
|
|
223528
|
-
const directory = sysPath.dirname(
|
|
223529
|
-
const basename2 = sysPath.basename(
|
|
223751
|
+
const directory = sysPath.dirname(path4);
|
|
223752
|
+
const basename2 = sysPath.basename(path4);
|
|
223530
223753
|
const parent = this.fsw._getWatchedDir(directory);
|
|
223531
223754
|
parent.add(basename2);
|
|
223532
|
-
const absolutePath = sysPath.resolve(
|
|
223755
|
+
const absolutePath = sysPath.resolve(path4);
|
|
223533
223756
|
const options = {
|
|
223534
223757
|
persistent: opts.persistent
|
|
223535
223758
|
};
|
|
@@ -223539,12 +223762,12 @@ class NodeFsHandler {
|
|
|
223539
223762
|
if (opts.usePolling) {
|
|
223540
223763
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
223541
223764
|
options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
|
|
223542
|
-
closer = setFsWatchFileListener(
|
|
223765
|
+
closer = setFsWatchFileListener(path4, absolutePath, options, {
|
|
223543
223766
|
listener,
|
|
223544
223767
|
rawEmitter: this.fsw._emitRaw
|
|
223545
223768
|
});
|
|
223546
223769
|
} else {
|
|
223547
|
-
closer = setFsWatchListener(
|
|
223770
|
+
closer = setFsWatchListener(path4, absolutePath, options, {
|
|
223548
223771
|
listener,
|
|
223549
223772
|
errHandler: this._boundHandleError,
|
|
223550
223773
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -223562,7 +223785,7 @@ class NodeFsHandler {
|
|
|
223562
223785
|
let prevStats = stats;
|
|
223563
223786
|
if (parent.has(basename2))
|
|
223564
223787
|
return;
|
|
223565
|
-
const listener = async (
|
|
223788
|
+
const listener = async (path4, newStats) => {
|
|
223566
223789
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
223567
223790
|
return;
|
|
223568
223791
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -223576,11 +223799,11 @@ class NodeFsHandler {
|
|
|
223576
223799
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
223577
223800
|
}
|
|
223578
223801
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
223579
|
-
this.fsw._closeFile(
|
|
223802
|
+
this.fsw._closeFile(path4);
|
|
223580
223803
|
prevStats = newStats2;
|
|
223581
223804
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
223582
223805
|
if (closer2)
|
|
223583
|
-
this.fsw._addPathCloser(
|
|
223806
|
+
this.fsw._addPathCloser(path4, closer2);
|
|
223584
223807
|
} else {
|
|
223585
223808
|
prevStats = newStats2;
|
|
223586
223809
|
}
|
|
@@ -223604,7 +223827,7 @@ class NodeFsHandler {
|
|
|
223604
223827
|
}
|
|
223605
223828
|
return closer;
|
|
223606
223829
|
}
|
|
223607
|
-
async _handleSymlink(entry, directory,
|
|
223830
|
+
async _handleSymlink(entry, directory, path4, item) {
|
|
223608
223831
|
if (this.fsw.closed) {
|
|
223609
223832
|
return;
|
|
223610
223833
|
}
|
|
@@ -223614,7 +223837,7 @@ class NodeFsHandler {
|
|
|
223614
223837
|
this.fsw._incrReadyCount();
|
|
223615
223838
|
let linkPath;
|
|
223616
223839
|
try {
|
|
223617
|
-
linkPath = await fsrealpath(
|
|
223840
|
+
linkPath = await fsrealpath(path4);
|
|
223618
223841
|
} catch (e) {
|
|
223619
223842
|
this.fsw._emitReady();
|
|
223620
223843
|
return true;
|
|
@@ -223624,12 +223847,12 @@ class NodeFsHandler {
|
|
|
223624
223847
|
if (dir.has(item)) {
|
|
223625
223848
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
223626
223849
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
223627
|
-
this.fsw._emit(EV.CHANGE,
|
|
223850
|
+
this.fsw._emit(EV.CHANGE, path4, entry.stats);
|
|
223628
223851
|
}
|
|
223629
223852
|
} else {
|
|
223630
223853
|
dir.add(item);
|
|
223631
223854
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
223632
|
-
this.fsw._emit(EV.ADD,
|
|
223855
|
+
this.fsw._emit(EV.ADD, path4, entry.stats);
|
|
223633
223856
|
}
|
|
223634
223857
|
this.fsw._emitReady();
|
|
223635
223858
|
return true;
|
|
@@ -223658,9 +223881,9 @@ class NodeFsHandler {
|
|
|
223658
223881
|
return;
|
|
223659
223882
|
}
|
|
223660
223883
|
const item = entry.path;
|
|
223661
|
-
let
|
|
223884
|
+
let path4 = sysPath.join(directory, item);
|
|
223662
223885
|
current.add(item);
|
|
223663
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
223886
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path4, item)) {
|
|
223664
223887
|
return;
|
|
223665
223888
|
}
|
|
223666
223889
|
if (this.fsw.closed) {
|
|
@@ -223669,8 +223892,8 @@ class NodeFsHandler {
|
|
|
223669
223892
|
}
|
|
223670
223893
|
if (item === target || !target && !previous.has(item)) {
|
|
223671
223894
|
this.fsw._incrReadyCount();
|
|
223672
|
-
|
|
223673
|
-
this._addToNodeFs(
|
|
223895
|
+
path4 = sysPath.join(dir, sysPath.relative(dir, path4));
|
|
223896
|
+
this._addToNodeFs(path4, initialAdd, wh, depth + 1);
|
|
223674
223897
|
}
|
|
223675
223898
|
}).on(EV.ERROR, this._boundHandleError);
|
|
223676
223899
|
return new Promise((resolve2, reject) => {
|
|
@@ -223719,13 +223942,13 @@ class NodeFsHandler {
|
|
|
223719
223942
|
}
|
|
223720
223943
|
return closer;
|
|
223721
223944
|
}
|
|
223722
|
-
async _addToNodeFs(
|
|
223945
|
+
async _addToNodeFs(path4, initialAdd, priorWh, depth, target) {
|
|
223723
223946
|
const ready = this.fsw._emitReady;
|
|
223724
|
-
if (this.fsw._isIgnored(
|
|
223947
|
+
if (this.fsw._isIgnored(path4) || this.fsw.closed) {
|
|
223725
223948
|
ready();
|
|
223726
223949
|
return false;
|
|
223727
223950
|
}
|
|
223728
|
-
const wh = this.fsw._getWatchHelpers(
|
|
223951
|
+
const wh = this.fsw._getWatchHelpers(path4);
|
|
223729
223952
|
if (priorWh) {
|
|
223730
223953
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
223731
223954
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -223741,8 +223964,8 @@ class NodeFsHandler {
|
|
|
223741
223964
|
const follow = this.fsw.options.followSymlinks;
|
|
223742
223965
|
let closer;
|
|
223743
223966
|
if (stats.isDirectory()) {
|
|
223744
|
-
const absPath = sysPath.resolve(
|
|
223745
|
-
const targetPath = follow ? await fsrealpath(
|
|
223967
|
+
const absPath = sysPath.resolve(path4);
|
|
223968
|
+
const targetPath = follow ? await fsrealpath(path4) : path4;
|
|
223746
223969
|
if (this.fsw.closed)
|
|
223747
223970
|
return;
|
|
223748
223971
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -223752,29 +223975,29 @@ class NodeFsHandler {
|
|
|
223752
223975
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
223753
223976
|
}
|
|
223754
223977
|
} else if (stats.isSymbolicLink()) {
|
|
223755
|
-
const targetPath = follow ? await fsrealpath(
|
|
223978
|
+
const targetPath = follow ? await fsrealpath(path4) : path4;
|
|
223756
223979
|
if (this.fsw.closed)
|
|
223757
223980
|
return;
|
|
223758
223981
|
const parent = sysPath.dirname(wh.watchPath);
|
|
223759
223982
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
223760
223983
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
223761
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
223984
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path4, wh, targetPath);
|
|
223762
223985
|
if (this.fsw.closed)
|
|
223763
223986
|
return;
|
|
223764
223987
|
if (targetPath !== undefined) {
|
|
223765
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
223988
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path4), targetPath);
|
|
223766
223989
|
}
|
|
223767
223990
|
} else {
|
|
223768
223991
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
223769
223992
|
}
|
|
223770
223993
|
ready();
|
|
223771
223994
|
if (closer)
|
|
223772
|
-
this.fsw._addPathCloser(
|
|
223995
|
+
this.fsw._addPathCloser(path4, closer);
|
|
223773
223996
|
return false;
|
|
223774
223997
|
} catch (error) {
|
|
223775
223998
|
if (this.fsw._handleError(error)) {
|
|
223776
223999
|
ready();
|
|
223777
|
-
return
|
|
224000
|
+
return path4;
|
|
223778
224001
|
}
|
|
223779
224002
|
}
|
|
223780
224003
|
}
|
|
@@ -223818,26 +224041,26 @@ function createPattern(matcher) {
|
|
|
223818
224041
|
}
|
|
223819
224042
|
return () => false;
|
|
223820
224043
|
}
|
|
223821
|
-
function normalizePath(
|
|
223822
|
-
if (typeof
|
|
224044
|
+
function normalizePath(path4) {
|
|
224045
|
+
if (typeof path4 !== "string")
|
|
223823
224046
|
throw new Error("string expected");
|
|
223824
|
-
|
|
223825
|
-
|
|
224047
|
+
path4 = sysPath2.normalize(path4);
|
|
224048
|
+
path4 = path4.replace(/\\/g, "/");
|
|
223826
224049
|
let prepend = false;
|
|
223827
|
-
if (
|
|
224050
|
+
if (path4.startsWith("//"))
|
|
223828
224051
|
prepend = true;
|
|
223829
224052
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
223830
|
-
while (
|
|
223831
|
-
|
|
224053
|
+
while (path4.match(DOUBLE_SLASH_RE2))
|
|
224054
|
+
path4 = path4.replace(DOUBLE_SLASH_RE2, "/");
|
|
223832
224055
|
if (prepend)
|
|
223833
|
-
|
|
223834
|
-
return
|
|
224056
|
+
path4 = "/" + path4;
|
|
224057
|
+
return path4;
|
|
223835
224058
|
}
|
|
223836
224059
|
function matchPatterns(patterns, testString, stats) {
|
|
223837
|
-
const
|
|
224060
|
+
const path4 = normalizePath(testString);
|
|
223838
224061
|
for (let index = 0;index < patterns.length; index++) {
|
|
223839
224062
|
const pattern = patterns[index];
|
|
223840
|
-
if (pattern(
|
|
224063
|
+
if (pattern(path4, stats)) {
|
|
223841
224064
|
return true;
|
|
223842
224065
|
}
|
|
223843
224066
|
}
|
|
@@ -223877,19 +224100,19 @@ var toUnix = (string) => {
|
|
|
223877
224100
|
}
|
|
223878
224101
|
return str;
|
|
223879
224102
|
};
|
|
223880
|
-
var normalizePathToUnix = (
|
|
223881
|
-
var normalizeIgnored = (cwd = "") => (
|
|
223882
|
-
if (typeof
|
|
223883
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
224103
|
+
var normalizePathToUnix = (path4) => toUnix(sysPath2.normalize(toUnix(path4)));
|
|
224104
|
+
var normalizeIgnored = (cwd = "") => (path4) => {
|
|
224105
|
+
if (typeof path4 === "string") {
|
|
224106
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path4) ? path4 : sysPath2.join(cwd, path4));
|
|
223884
224107
|
} else {
|
|
223885
|
-
return
|
|
224108
|
+
return path4;
|
|
223886
224109
|
}
|
|
223887
224110
|
};
|
|
223888
|
-
var getAbsolutePath = (
|
|
223889
|
-
if (sysPath2.isAbsolute(
|
|
223890
|
-
return
|
|
224111
|
+
var getAbsolutePath = (path4, cwd) => {
|
|
224112
|
+
if (sysPath2.isAbsolute(path4)) {
|
|
224113
|
+
return path4;
|
|
223891
224114
|
}
|
|
223892
|
-
return sysPath2.join(cwd,
|
|
224115
|
+
return sysPath2.join(cwd, path4);
|
|
223893
224116
|
};
|
|
223894
224117
|
var EMPTY_SET = Object.freeze(new Set);
|
|
223895
224118
|
|
|
@@ -223946,10 +224169,10 @@ var STAT_METHOD_F = "stat";
|
|
|
223946
224169
|
var STAT_METHOD_L = "lstat";
|
|
223947
224170
|
|
|
223948
224171
|
class WatchHelper {
|
|
223949
|
-
constructor(
|
|
224172
|
+
constructor(path4, follow, fsw) {
|
|
223950
224173
|
this.fsw = fsw;
|
|
223951
|
-
const watchPath =
|
|
223952
|
-
this.path =
|
|
224174
|
+
const watchPath = path4;
|
|
224175
|
+
this.path = path4 = path4.replace(REPLACER_RE, "");
|
|
223953
224176
|
this.watchPath = watchPath;
|
|
223954
224177
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
223955
224178
|
this.dirParts = [];
|
|
@@ -224062,20 +224285,20 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224062
224285
|
this._closePromise = undefined;
|
|
224063
224286
|
let paths = unifyPaths(paths_);
|
|
224064
224287
|
if (cwd) {
|
|
224065
|
-
paths = paths.map((
|
|
224066
|
-
const absPath = getAbsolutePath(
|
|
224288
|
+
paths = paths.map((path4) => {
|
|
224289
|
+
const absPath = getAbsolutePath(path4, cwd);
|
|
224067
224290
|
return absPath;
|
|
224068
224291
|
});
|
|
224069
224292
|
}
|
|
224070
|
-
paths.forEach((
|
|
224071
|
-
this._removeIgnoredPath(
|
|
224293
|
+
paths.forEach((path4) => {
|
|
224294
|
+
this._removeIgnoredPath(path4);
|
|
224072
224295
|
});
|
|
224073
224296
|
this._userIgnored = undefined;
|
|
224074
224297
|
if (!this._readyCount)
|
|
224075
224298
|
this._readyCount = 0;
|
|
224076
224299
|
this._readyCount += paths.length;
|
|
224077
|
-
Promise.all(paths.map(async (
|
|
224078
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
224300
|
+
Promise.all(paths.map(async (path4) => {
|
|
224301
|
+
const res = await this._nodeFsHandler._addToNodeFs(path4, !_internal, undefined, 0, _origAdd);
|
|
224079
224302
|
if (res)
|
|
224080
224303
|
this._emitReady();
|
|
224081
224304
|
return res;
|
|
@@ -224094,17 +224317,17 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224094
224317
|
return this;
|
|
224095
224318
|
const paths = unifyPaths(paths_);
|
|
224096
224319
|
const { cwd } = this.options;
|
|
224097
|
-
paths.forEach((
|
|
224098
|
-
if (!sysPath2.isAbsolute(
|
|
224320
|
+
paths.forEach((path4) => {
|
|
224321
|
+
if (!sysPath2.isAbsolute(path4) && !this._closers.has(path4)) {
|
|
224099
224322
|
if (cwd)
|
|
224100
|
-
|
|
224101
|
-
|
|
224323
|
+
path4 = sysPath2.join(cwd, path4);
|
|
224324
|
+
path4 = sysPath2.resolve(path4);
|
|
224102
224325
|
}
|
|
224103
|
-
this._closePath(
|
|
224104
|
-
this._addIgnoredPath(
|
|
224105
|
-
if (this._watched.has(
|
|
224326
|
+
this._closePath(path4);
|
|
224327
|
+
this._addIgnoredPath(path4);
|
|
224328
|
+
if (this._watched.has(path4)) {
|
|
224106
224329
|
this._addIgnoredPath({
|
|
224107
|
-
path:
|
|
224330
|
+
path: path4,
|
|
224108
224331
|
recursive: true
|
|
224109
224332
|
});
|
|
224110
224333
|
}
|
|
@@ -224153,38 +224376,38 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224153
224376
|
if (event !== EVENTS.ERROR)
|
|
224154
224377
|
this.emit(EVENTS.ALL, event, ...args);
|
|
224155
224378
|
}
|
|
224156
|
-
async _emit(event,
|
|
224379
|
+
async _emit(event, path4, stats) {
|
|
224157
224380
|
if (this.closed)
|
|
224158
224381
|
return;
|
|
224159
224382
|
const opts = this.options;
|
|
224160
224383
|
if (isWindows)
|
|
224161
|
-
|
|
224384
|
+
path4 = sysPath2.normalize(path4);
|
|
224162
224385
|
if (opts.cwd)
|
|
224163
|
-
|
|
224164
|
-
const args = [
|
|
224386
|
+
path4 = sysPath2.relative(opts.cwd, path4);
|
|
224387
|
+
const args = [path4];
|
|
224165
224388
|
if (stats != null)
|
|
224166
224389
|
args.push(stats);
|
|
224167
224390
|
const awf = opts.awaitWriteFinish;
|
|
224168
224391
|
let pw;
|
|
224169
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
224392
|
+
if (awf && (pw = this._pendingWrites.get(path4))) {
|
|
224170
224393
|
pw.lastChange = new Date;
|
|
224171
224394
|
return this;
|
|
224172
224395
|
}
|
|
224173
224396
|
if (opts.atomic) {
|
|
224174
224397
|
if (event === EVENTS.UNLINK) {
|
|
224175
|
-
this._pendingUnlinks.set(
|
|
224398
|
+
this._pendingUnlinks.set(path4, [event, ...args]);
|
|
224176
224399
|
setTimeout(() => {
|
|
224177
|
-
this._pendingUnlinks.forEach((entry,
|
|
224400
|
+
this._pendingUnlinks.forEach((entry, path5) => {
|
|
224178
224401
|
this.emit(...entry);
|
|
224179
224402
|
this.emit(EVENTS.ALL, ...entry);
|
|
224180
|
-
this._pendingUnlinks.delete(
|
|
224403
|
+
this._pendingUnlinks.delete(path5);
|
|
224181
224404
|
});
|
|
224182
224405
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
224183
224406
|
return this;
|
|
224184
224407
|
}
|
|
224185
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
224408
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path4)) {
|
|
224186
224409
|
event = EVENTS.CHANGE;
|
|
224187
|
-
this._pendingUnlinks.delete(
|
|
224410
|
+
this._pendingUnlinks.delete(path4);
|
|
224188
224411
|
}
|
|
224189
224412
|
}
|
|
224190
224413
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -224202,16 +224425,16 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224202
224425
|
this.emitWithAll(event, args);
|
|
224203
224426
|
}
|
|
224204
224427
|
};
|
|
224205
|
-
this._awaitWriteFinish(
|
|
224428
|
+
this._awaitWriteFinish(path4, awf.stabilityThreshold, event, awfEmit);
|
|
224206
224429
|
return this;
|
|
224207
224430
|
}
|
|
224208
224431
|
if (event === EVENTS.CHANGE) {
|
|
224209
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
224432
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path4, 50);
|
|
224210
224433
|
if (isThrottled)
|
|
224211
224434
|
return this;
|
|
224212
224435
|
}
|
|
224213
224436
|
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
224214
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
224437
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path4) : path4;
|
|
224215
224438
|
let stats2;
|
|
224216
224439
|
try {
|
|
224217
224440
|
stats2 = await stat3(fullPath);
|
|
@@ -224230,23 +224453,23 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224230
224453
|
}
|
|
224231
224454
|
return error || this.closed;
|
|
224232
224455
|
}
|
|
224233
|
-
_throttle(actionType,
|
|
224456
|
+
_throttle(actionType, path4, timeout) {
|
|
224234
224457
|
if (!this._throttled.has(actionType)) {
|
|
224235
224458
|
this._throttled.set(actionType, new Map);
|
|
224236
224459
|
}
|
|
224237
224460
|
const action = this._throttled.get(actionType);
|
|
224238
224461
|
if (!action)
|
|
224239
224462
|
throw new Error("invalid throttle");
|
|
224240
|
-
const actionPath = action.get(
|
|
224463
|
+
const actionPath = action.get(path4);
|
|
224241
224464
|
if (actionPath) {
|
|
224242
224465
|
actionPath.count++;
|
|
224243
224466
|
return false;
|
|
224244
224467
|
}
|
|
224245
224468
|
let timeoutObject;
|
|
224246
224469
|
const clear = () => {
|
|
224247
|
-
const item = action.get(
|
|
224470
|
+
const item = action.get(path4);
|
|
224248
224471
|
const count = item ? item.count : 0;
|
|
224249
|
-
action.delete(
|
|
224472
|
+
action.delete(path4);
|
|
224250
224473
|
clearTimeout(timeoutObject);
|
|
224251
224474
|
if (item)
|
|
224252
224475
|
clearTimeout(item.timeoutObject);
|
|
@@ -224254,50 +224477,50 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224254
224477
|
};
|
|
224255
224478
|
timeoutObject = setTimeout(clear, timeout);
|
|
224256
224479
|
const thr = { timeoutObject, clear, count: 0 };
|
|
224257
|
-
action.set(
|
|
224480
|
+
action.set(path4, thr);
|
|
224258
224481
|
return thr;
|
|
224259
224482
|
}
|
|
224260
224483
|
_incrReadyCount() {
|
|
224261
224484
|
return this._readyCount++;
|
|
224262
224485
|
}
|
|
224263
|
-
_awaitWriteFinish(
|
|
224486
|
+
_awaitWriteFinish(path4, threshold, event, awfEmit) {
|
|
224264
224487
|
const awf = this.options.awaitWriteFinish;
|
|
224265
224488
|
if (typeof awf !== "object")
|
|
224266
224489
|
return;
|
|
224267
224490
|
const pollInterval = awf.pollInterval;
|
|
224268
224491
|
let timeoutHandler;
|
|
224269
|
-
let fullPath =
|
|
224270
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
224271
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
224492
|
+
let fullPath = path4;
|
|
224493
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path4)) {
|
|
224494
|
+
fullPath = sysPath2.join(this.options.cwd, path4);
|
|
224272
224495
|
}
|
|
224273
224496
|
const now = new Date;
|
|
224274
224497
|
const writes = this._pendingWrites;
|
|
224275
224498
|
function awaitWriteFinishFn(prevStat) {
|
|
224276
224499
|
statcb(fullPath, (err, curStat) => {
|
|
224277
|
-
if (err || !writes.has(
|
|
224500
|
+
if (err || !writes.has(path4)) {
|
|
224278
224501
|
if (err && err.code !== "ENOENT")
|
|
224279
224502
|
awfEmit(err);
|
|
224280
224503
|
return;
|
|
224281
224504
|
}
|
|
224282
224505
|
const now2 = Number(new Date);
|
|
224283
224506
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
224284
|
-
writes.get(
|
|
224507
|
+
writes.get(path4).lastChange = now2;
|
|
224285
224508
|
}
|
|
224286
|
-
const pw = writes.get(
|
|
224509
|
+
const pw = writes.get(path4);
|
|
224287
224510
|
const df = now2 - pw.lastChange;
|
|
224288
224511
|
if (df >= threshold) {
|
|
224289
|
-
writes.delete(
|
|
224512
|
+
writes.delete(path4);
|
|
224290
224513
|
awfEmit(undefined, curStat);
|
|
224291
224514
|
} else {
|
|
224292
224515
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
224293
224516
|
}
|
|
224294
224517
|
});
|
|
224295
224518
|
}
|
|
224296
|
-
if (!writes.has(
|
|
224297
|
-
writes.set(
|
|
224519
|
+
if (!writes.has(path4)) {
|
|
224520
|
+
writes.set(path4, {
|
|
224298
224521
|
lastChange: now,
|
|
224299
224522
|
cancelWait: () => {
|
|
224300
|
-
writes.delete(
|
|
224523
|
+
writes.delete(path4);
|
|
224301
224524
|
clearTimeout(timeoutHandler);
|
|
224302
224525
|
return event;
|
|
224303
224526
|
}
|
|
@@ -224305,8 +224528,8 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224305
224528
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
224306
224529
|
}
|
|
224307
224530
|
}
|
|
224308
|
-
_isIgnored(
|
|
224309
|
-
if (this.options.atomic && DOT_RE.test(
|
|
224531
|
+
_isIgnored(path4, stats) {
|
|
224532
|
+
if (this.options.atomic && DOT_RE.test(path4))
|
|
224310
224533
|
return true;
|
|
224311
224534
|
if (!this._userIgnored) {
|
|
224312
224535
|
const { cwd } = this.options;
|
|
@@ -224316,13 +224539,13 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224316
224539
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
224317
224540
|
this._userIgnored = anymatch(list, undefined);
|
|
224318
224541
|
}
|
|
224319
|
-
return this._userIgnored(
|
|
224542
|
+
return this._userIgnored(path4, stats);
|
|
224320
224543
|
}
|
|
224321
|
-
_isntIgnored(
|
|
224322
|
-
return !this._isIgnored(
|
|
224544
|
+
_isntIgnored(path4, stat4) {
|
|
224545
|
+
return !this._isIgnored(path4, stat4);
|
|
224323
224546
|
}
|
|
224324
|
-
_getWatchHelpers(
|
|
224325
|
-
return new WatchHelper(
|
|
224547
|
+
_getWatchHelpers(path4) {
|
|
224548
|
+
return new WatchHelper(path4, this.options.followSymlinks, this);
|
|
224326
224549
|
}
|
|
224327
224550
|
_getWatchedDir(directory) {
|
|
224328
224551
|
const dir = sysPath2.resolve(directory);
|
|
@@ -224336,57 +224559,57 @@ class FSWatcher extends EventEmitter2 {
|
|
|
224336
224559
|
return Boolean(Number(stats.mode) & 256);
|
|
224337
224560
|
}
|
|
224338
224561
|
_remove(directory, item, isDirectory) {
|
|
224339
|
-
const
|
|
224340
|
-
const fullPath = sysPath2.resolve(
|
|
224341
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
224342
|
-
if (!this._throttle("remove",
|
|
224562
|
+
const path4 = sysPath2.join(directory, item);
|
|
224563
|
+
const fullPath = sysPath2.resolve(path4);
|
|
224564
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path4) || this._watched.has(fullPath);
|
|
224565
|
+
if (!this._throttle("remove", path4, 100))
|
|
224343
224566
|
return;
|
|
224344
224567
|
if (!isDirectory && this._watched.size === 1) {
|
|
224345
224568
|
this.add(directory, item, true);
|
|
224346
224569
|
}
|
|
224347
|
-
const wp = this._getWatchedDir(
|
|
224570
|
+
const wp = this._getWatchedDir(path4);
|
|
224348
224571
|
const nestedDirectoryChildren = wp.getChildren();
|
|
224349
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
224572
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path4, nested));
|
|
224350
224573
|
const parent = this._getWatchedDir(directory);
|
|
224351
224574
|
const wasTracked = parent.has(item);
|
|
224352
224575
|
parent.remove(item);
|
|
224353
224576
|
if (this._symlinkPaths.has(fullPath)) {
|
|
224354
224577
|
this._symlinkPaths.delete(fullPath);
|
|
224355
224578
|
}
|
|
224356
|
-
let relPath =
|
|
224579
|
+
let relPath = path4;
|
|
224357
224580
|
if (this.options.cwd)
|
|
224358
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
224581
|
+
relPath = sysPath2.relative(this.options.cwd, path4);
|
|
224359
224582
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
224360
224583
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
224361
224584
|
if (event === EVENTS.ADD)
|
|
224362
224585
|
return;
|
|
224363
224586
|
}
|
|
224364
|
-
this._watched.delete(
|
|
224587
|
+
this._watched.delete(path4);
|
|
224365
224588
|
this._watched.delete(fullPath);
|
|
224366
224589
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
224367
|
-
if (wasTracked && !this._isIgnored(
|
|
224368
|
-
this._emit(eventName,
|
|
224369
|
-
this._closePath(
|
|
224590
|
+
if (wasTracked && !this._isIgnored(path4))
|
|
224591
|
+
this._emit(eventName, path4);
|
|
224592
|
+
this._closePath(path4);
|
|
224370
224593
|
}
|
|
224371
|
-
_closePath(
|
|
224372
|
-
this._closeFile(
|
|
224373
|
-
const dir = sysPath2.dirname(
|
|
224374
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
224594
|
+
_closePath(path4) {
|
|
224595
|
+
this._closeFile(path4);
|
|
224596
|
+
const dir = sysPath2.dirname(path4);
|
|
224597
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path4));
|
|
224375
224598
|
}
|
|
224376
|
-
_closeFile(
|
|
224377
|
-
const closers = this._closers.get(
|
|
224599
|
+
_closeFile(path4) {
|
|
224600
|
+
const closers = this._closers.get(path4);
|
|
224378
224601
|
if (!closers)
|
|
224379
224602
|
return;
|
|
224380
224603
|
closers.forEach((closer) => closer());
|
|
224381
|
-
this._closers.delete(
|
|
224604
|
+
this._closers.delete(path4);
|
|
224382
224605
|
}
|
|
224383
|
-
_addPathCloser(
|
|
224606
|
+
_addPathCloser(path4, closer) {
|
|
224384
224607
|
if (!closer)
|
|
224385
224608
|
return;
|
|
224386
|
-
let list = this._closers.get(
|
|
224609
|
+
let list = this._closers.get(path4);
|
|
224387
224610
|
if (!list) {
|
|
224388
224611
|
list = [];
|
|
224389
|
-
this._closers.set(
|
|
224612
|
+
this._closers.set(path4, list);
|
|
224390
224613
|
}
|
|
224391
224614
|
list.push(closer);
|
|
224392
224615
|
}
|
|
@@ -224416,7 +224639,7 @@ function watch(paths, options = {}) {
|
|
|
224416
224639
|
var esm_default = { watch, FSWatcher };
|
|
224417
224640
|
|
|
224418
224641
|
// src/controller/watch-mode.controller.ts
|
|
224419
|
-
import
|
|
224642
|
+
import path10 from "path";
|
|
224420
224643
|
|
|
224421
224644
|
// src/service/project_store.ts
|
|
224422
224645
|
var import_client_s32 = __toESM(require_dist_cjs75(), 1);
|
|
@@ -224634,7 +224857,7 @@ class Mutex {
|
|
|
224634
224857
|
// src/service/project_store.ts
|
|
224635
224858
|
import crypto3 from "crypto";
|
|
224636
224859
|
import * as fs7 from "fs";
|
|
224637
|
-
import * as
|
|
224860
|
+
import * as path9 from "path";
|
|
224638
224861
|
|
|
224639
224862
|
// ../../node_modules/simple-git/dist/esm/index.js
|
|
224640
224863
|
var import_file_exists = __toESM(require_dist11(), 1);
|
|
@@ -224672,8 +224895,8 @@ function pathspec(...paths) {
|
|
|
224672
224895
|
cache.set(key, paths);
|
|
224673
224896
|
return key;
|
|
224674
224897
|
}
|
|
224675
|
-
function isPathSpec(
|
|
224676
|
-
return
|
|
224898
|
+
function isPathSpec(path4) {
|
|
224899
|
+
return path4 instanceof String && cache.has(path4);
|
|
224677
224900
|
}
|
|
224678
224901
|
function toPaths(pathSpec) {
|
|
224679
224902
|
return cache.get(pathSpec) || [];
|
|
@@ -224759,8 +224982,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = `
|
|
|
224759
224982
|
function forEachLineWithContent(input, callback) {
|
|
224760
224983
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
224761
224984
|
}
|
|
224762
|
-
function folderExists(
|
|
224763
|
-
return import_file_exists.exists(
|
|
224985
|
+
function folderExists(path4) {
|
|
224986
|
+
return import_file_exists.exists(path4, import_file_exists.FOLDER);
|
|
224764
224987
|
}
|
|
224765
224988
|
function append2(target, item) {
|
|
224766
224989
|
if (Array.isArray(target)) {
|
|
@@ -225141,8 +225364,8 @@ function checkIsRepoRootTask() {
|
|
|
225141
225364
|
commands,
|
|
225142
225365
|
format: "utf-8",
|
|
225143
225366
|
onError,
|
|
225144
|
-
parser(
|
|
225145
|
-
return /^\.(git)?$/.test(
|
|
225367
|
+
parser(path4) {
|
|
225368
|
+
return /^\.(git)?$/.test(path4.trim());
|
|
225146
225369
|
}
|
|
225147
225370
|
};
|
|
225148
225371
|
}
|
|
@@ -225553,11 +225776,11 @@ function parseGrep(grep) {
|
|
|
225553
225776
|
const paths = /* @__PURE__ */ new Set;
|
|
225554
225777
|
const results = {};
|
|
225555
225778
|
forEachLineWithContent(grep, (input) => {
|
|
225556
|
-
const [
|
|
225557
|
-
paths.add(
|
|
225558
|
-
(results[
|
|
225779
|
+
const [path4, line, preview] = input.split(NULL);
|
|
225780
|
+
paths.add(path4);
|
|
225781
|
+
(results[path4] = results[path4] || []).push({
|
|
225559
225782
|
line: asNumber(line),
|
|
225560
|
-
path:
|
|
225783
|
+
path: path4,
|
|
225561
225784
|
preview
|
|
225562
225785
|
});
|
|
225563
225786
|
});
|
|
@@ -226219,14 +226442,14 @@ var init_hash_object = __esm({
|
|
|
226219
226442
|
init_task();
|
|
226220
226443
|
}
|
|
226221
226444
|
});
|
|
226222
|
-
function parseInit(bare,
|
|
226445
|
+
function parseInit(bare, path4, text) {
|
|
226223
226446
|
const response = String(text).trim();
|
|
226224
226447
|
let result;
|
|
226225
226448
|
if (result = initResponseRegex.exec(response)) {
|
|
226226
|
-
return new InitSummary(bare,
|
|
226449
|
+
return new InitSummary(bare, path4, false, result[1]);
|
|
226227
226450
|
}
|
|
226228
226451
|
if (result = reInitResponseRegex.exec(response)) {
|
|
226229
|
-
return new InitSummary(bare,
|
|
226452
|
+
return new InitSummary(bare, path4, true, result[1]);
|
|
226230
226453
|
}
|
|
226231
226454
|
let gitDir = "";
|
|
226232
226455
|
const tokens = response.split(" ");
|
|
@@ -226237,7 +226460,7 @@ function parseInit(bare, path3, text) {
|
|
|
226237
226460
|
break;
|
|
226238
226461
|
}
|
|
226239
226462
|
}
|
|
226240
|
-
return new InitSummary(bare,
|
|
226463
|
+
return new InitSummary(bare, path4, /^re/i.test(response), gitDir);
|
|
226241
226464
|
}
|
|
226242
226465
|
var InitSummary;
|
|
226243
226466
|
var initResponseRegex;
|
|
@@ -226245,9 +226468,9 @@ var reInitResponseRegex;
|
|
|
226245
226468
|
var init_InitSummary = __esm({
|
|
226246
226469
|
"src/lib/responses/InitSummary.ts"() {
|
|
226247
226470
|
InitSummary = class {
|
|
226248
|
-
constructor(bare,
|
|
226471
|
+
constructor(bare, path4, existing, gitDir) {
|
|
226249
226472
|
this.bare = bare;
|
|
226250
|
-
this.path =
|
|
226473
|
+
this.path = path4;
|
|
226251
226474
|
this.existing = existing;
|
|
226252
226475
|
this.gitDir = gitDir;
|
|
226253
226476
|
}
|
|
@@ -226259,7 +226482,7 @@ var init_InitSummary = __esm({
|
|
|
226259
226482
|
function hasBareCommand(command) {
|
|
226260
226483
|
return command.includes(bareCommand);
|
|
226261
226484
|
}
|
|
226262
|
-
function initTask(bare = false,
|
|
226485
|
+
function initTask(bare = false, path4, customArgs) {
|
|
226263
226486
|
const commands = ["init", ...customArgs];
|
|
226264
226487
|
if (bare && !hasBareCommand(commands)) {
|
|
226265
226488
|
commands.splice(1, 0, bareCommand);
|
|
@@ -226268,7 +226491,7 @@ function initTask(bare = false, path3, customArgs) {
|
|
|
226268
226491
|
commands,
|
|
226269
226492
|
format: "utf-8",
|
|
226270
226493
|
parser(text) {
|
|
226271
|
-
return parseInit(commands.includes("--bare"),
|
|
226494
|
+
return parseInit(commands.includes("--bare"), path4, text);
|
|
226272
226495
|
}
|
|
226273
226496
|
};
|
|
226274
226497
|
}
|
|
@@ -226983,12 +227206,12 @@ var init_FileStatusSummary = __esm({
|
|
|
226983
227206
|
"src/lib/responses/FileStatusSummary.ts"() {
|
|
226984
227207
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
226985
227208
|
FileStatusSummary = class {
|
|
226986
|
-
constructor(
|
|
226987
|
-
this.path =
|
|
227209
|
+
constructor(path4, index, working_dir) {
|
|
227210
|
+
this.path = path4;
|
|
226988
227211
|
this.index = index;
|
|
226989
227212
|
this.working_dir = working_dir;
|
|
226990
227213
|
if (index === "R" || working_dir === "R") {
|
|
226991
|
-
const detail = fromPathRegex.exec(
|
|
227214
|
+
const detail = fromPathRegex.exec(path4) || [null, path4, path4];
|
|
226992
227215
|
this.from = detail[2] || "";
|
|
226993
227216
|
this.path = detail[1] || "";
|
|
226994
227217
|
}
|
|
@@ -227019,14 +227242,14 @@ function splitLine(result, lineStr) {
|
|
|
227019
227242
|
default:
|
|
227020
227243
|
return;
|
|
227021
227244
|
}
|
|
227022
|
-
function data(index, workingDir,
|
|
227245
|
+
function data(index, workingDir, path4) {
|
|
227023
227246
|
const raw = `${index}${workingDir}`;
|
|
227024
227247
|
const handler = parsers6.get(raw);
|
|
227025
227248
|
if (handler) {
|
|
227026
|
-
handler(result,
|
|
227249
|
+
handler(result, path4);
|
|
227027
227250
|
}
|
|
227028
227251
|
if (raw !== "##" && raw !== "!!") {
|
|
227029
|
-
result.files.push(new FileStatusSummary(
|
|
227252
|
+
result.files.push(new FileStatusSummary(path4, index, workingDir));
|
|
227030
227253
|
}
|
|
227031
227254
|
}
|
|
227032
227255
|
}
|
|
@@ -227257,8 +227480,8 @@ var init_simple_git_api = __esm({
|
|
|
227257
227480
|
}
|
|
227258
227481
|
return this._runTask(configurationErrorTask("Git.cwd: workingDirectory must be supplied as a string"), next);
|
|
227259
227482
|
}
|
|
227260
|
-
hashObject(
|
|
227261
|
-
return this._runTask(hashObjectTask(
|
|
227483
|
+
hashObject(path4, write) {
|
|
227484
|
+
return this._runTask(hashObjectTask(path4, write === true), trailingFunctionArgument(arguments));
|
|
227262
227485
|
}
|
|
227263
227486
|
init(bare) {
|
|
227264
227487
|
return this._runTask(initTask(bare === true, this._executor.cwd, getTrailingOptions(arguments)), trailingFunctionArgument(arguments));
|
|
@@ -227835,8 +228058,8 @@ __export2(sub_module_exports, {
|
|
|
227835
228058
|
subModuleTask: () => subModuleTask,
|
|
227836
228059
|
updateSubModuleTask: () => updateSubModuleTask
|
|
227837
228060
|
});
|
|
227838
|
-
function addSubModuleTask(repo,
|
|
227839
|
-
return subModuleTask(["add", repo,
|
|
228061
|
+
function addSubModuleTask(repo, path4) {
|
|
228062
|
+
return subModuleTask(["add", repo, path4]);
|
|
227840
228063
|
}
|
|
227841
228064
|
function initSubModuleTask(customArgs) {
|
|
227842
228065
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -228104,8 +228327,8 @@ var require_git = __commonJS2({
|
|
|
228104
228327
|
}
|
|
228105
228328
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
228106
228329
|
};
|
|
228107
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
228108
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
228330
|
+
Git2.prototype.submoduleAdd = function(repo, path4, then) {
|
|
228331
|
+
return this._runTask(addSubModuleTask2(repo, path4), trailingFunctionArgument2(arguments));
|
|
228109
228332
|
};
|
|
228110
228333
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
228111
228334
|
return this._runTask(updateSubModuleTask2(getTrailingOptions2(arguments, true)), trailingFunctionArgument2(arguments));
|
|
@@ -228621,7 +228844,7 @@ import { Writable } from "stream";
|
|
|
228621
228844
|
|
|
228622
228845
|
// src/config.ts
|
|
228623
228846
|
import fs2 from "fs";
|
|
228624
|
-
import
|
|
228847
|
+
import path4 from "path";
|
|
228625
228848
|
function substituteEnvVars(value) {
|
|
228626
228849
|
const envVarPattern = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
|
|
228627
228850
|
return value.replace(envVarPattern, (_match, varName) => {
|
|
@@ -228649,7 +228872,7 @@ function processConfigValue(value) {
|
|
|
228649
228872
|
return value;
|
|
228650
228873
|
}
|
|
228651
228874
|
var getPublisherConfig = (serverRoot) => {
|
|
228652
|
-
const publisherConfigPath =
|
|
228875
|
+
const publisherConfigPath = path4.join(serverRoot, PUBLISHER_CONFIG_NAME);
|
|
228653
228876
|
if (!fs2.existsSync(publisherConfigPath)) {
|
|
228654
228877
|
return {
|
|
228655
228878
|
frozenConfig: false,
|
|
@@ -228871,7 +229094,7 @@ function registerHealthEndpoints(app) {
|
|
|
228871
229094
|
|
|
228872
229095
|
// src/storage/duckdb/DuckDBConnection.ts
|
|
228873
229096
|
import duckdb from "duckdb";
|
|
228874
|
-
import * as
|
|
229097
|
+
import * as path5 from "path";
|
|
228875
229098
|
|
|
228876
229099
|
class DuckDBConnection2 {
|
|
228877
229100
|
db = null;
|
|
@@ -228879,7 +229102,7 @@ class DuckDBConnection2 {
|
|
|
228879
229102
|
dbPath;
|
|
228880
229103
|
mutex = new Mutex;
|
|
228881
229104
|
constructor(dbPath) {
|
|
228882
|
-
this.dbPath = dbPath ||
|
|
229105
|
+
this.dbPath = dbPath || path5.join(process.cwd(), "publisher.db");
|
|
228883
229106
|
}
|
|
228884
229107
|
async initialize() {
|
|
228885
229108
|
return new Promise((resolve3, reject) => {
|
|
@@ -229970,20 +230193,20 @@ class StorageManager {
|
|
|
229970
230193
|
}
|
|
229971
230194
|
|
|
229972
230195
|
// src/service/project.ts
|
|
229973
|
-
import {
|
|
230196
|
+
import { MalloyError as MalloyError3, Runtime as Runtime2 } from "@malloydata/malloy";
|
|
229974
230197
|
import * as fs6 from "fs";
|
|
229975
|
-
import * as
|
|
230198
|
+
import * as path8 from "path";
|
|
229976
230199
|
|
|
229977
230200
|
// src/utils.ts
|
|
229978
230201
|
import * as fs3 from "fs";
|
|
229979
230202
|
import { fileURLToPath } from "url";
|
|
229980
230203
|
var URL_READER = {
|
|
229981
230204
|
readURL: (url2) => {
|
|
229982
|
-
let
|
|
230205
|
+
let path6 = url2.toString();
|
|
229983
230206
|
if (url2.protocol == "file:") {
|
|
229984
|
-
|
|
230207
|
+
path6 = fileURLToPath(url2);
|
|
229985
230208
|
}
|
|
229986
|
-
return fs3.promises.readFile(
|
|
230209
|
+
return fs3.promises.readFile(path6, "utf8");
|
|
229987
230210
|
}
|
|
229988
230211
|
};
|
|
229989
230212
|
|
|
@@ -229991,11 +230214,15 @@ var URL_READER = {
|
|
|
229991
230214
|
var import_api3 = __toESM(require_src(), 1);
|
|
229992
230215
|
var import_recursive_readdir = __toESM(require_recursive_readdir(), 1);
|
|
229993
230216
|
import * as fs5 from "fs/promises";
|
|
229994
|
-
import * as
|
|
230217
|
+
import * as path7 from "path";
|
|
229995
230218
|
import { DuckDBConnection as DuckDBConnection3 } from "@malloydata/db-duckdb";
|
|
230219
|
+
import"@malloydata/db-duckdb/native";
|
|
229996
230220
|
import {
|
|
229997
230221
|
ConnectionRuntime,
|
|
229998
|
-
EmptyURLReader
|
|
230222
|
+
EmptyURLReader,
|
|
230223
|
+
FixedConnectionMap as FixedConnectionMap2,
|
|
230224
|
+
contextOverlay as contextOverlay2,
|
|
230225
|
+
MalloyConfig as MalloyConfig3
|
|
229999
230226
|
} from "@malloydata/malloy";
|
|
230000
230227
|
|
|
230001
230228
|
// src/service/model.ts
|
|
@@ -230004,6 +230231,7 @@ import {
|
|
|
230004
230231
|
API,
|
|
230005
230232
|
FixedConnectionMap,
|
|
230006
230233
|
isSourceDef,
|
|
230234
|
+
MalloyConfig as MalloyConfig2,
|
|
230007
230235
|
MalloyError as MalloyError2,
|
|
230008
230236
|
modelDefToModelInfo,
|
|
230009
230237
|
Runtime
|
|
@@ -230014,8 +230242,7 @@ import {
|
|
|
230014
230242
|
} from "@malloydata/malloy-sql";
|
|
230015
230243
|
import { createRequire as createRequire2 } from "module";
|
|
230016
230244
|
import * as fs4 from "fs/promises";
|
|
230017
|
-
import * as
|
|
230018
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
230245
|
+
import * as path6 from "path";
|
|
230019
230246
|
|
|
230020
230247
|
// src/data_styles.ts
|
|
230021
230248
|
function compileDataStyles(styles) {
|
|
@@ -230301,8 +230528,8 @@ class Model {
|
|
|
230301
230528
|
const arrowMatch = query.match(/^\s*(\w+)\s*->/m);
|
|
230302
230529
|
return runMatch?.[1] ?? arrowMatch?.[1];
|
|
230303
230530
|
}
|
|
230304
|
-
static async create(packageName, packagePath, modelPath,
|
|
230305
|
-
const { runtime, modelURL, importBaseURL, dataStyles, modelType } = await Model.getModelRuntime(packagePath, modelPath,
|
|
230531
|
+
static async create(packageName, packagePath, modelPath, malloyConfig, options) {
|
|
230532
|
+
const { runtime, modelURL, importBaseURL, dataStyles, modelType } = await Model.getModelRuntime(packagePath, modelPath, malloyConfig, options);
|
|
230306
230533
|
try {
|
|
230307
230534
|
const { modelMaterializer, runnableNotebookCells } = await Model.getModelMaterializer(runtime, importBaseURL, modelURL, modelPath);
|
|
230308
230535
|
let modelDef = undefined;
|
|
@@ -230625,8 +230852,8 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`;
|
|
|
230625
230852
|
newSources: cell.newSources?.map((source) => JSON.stringify(source))
|
|
230626
230853
|
};
|
|
230627
230854
|
}
|
|
230628
|
-
static async getModelRuntime(packagePath, modelPath,
|
|
230629
|
-
const fullModelPath =
|
|
230855
|
+
static async getModelRuntime(packagePath, modelPath, malloyConfig, options) {
|
|
230856
|
+
const fullModelPath = path6.join(packagePath, modelPath);
|
|
230630
230857
|
try {
|
|
230631
230858
|
if (!(await fs4.stat(fullModelPath)).isFile()) {
|
|
230632
230859
|
throw new ModelNotFoundError(`${modelPath} is not a file.`);
|
|
@@ -230644,26 +230871,24 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`;
|
|
|
230644
230871
|
}
|
|
230645
230872
|
const modelURL = new URL(`file://${fullModelPath}`);
|
|
230646
230873
|
const baseUrl = new URL(".", modelURL);
|
|
230647
|
-
const fileUrl = new URL(baseUrl.pathname, "file:");
|
|
230648
|
-
const workingDirectory = fileURLToPath2(fileUrl);
|
|
230649
230874
|
const importBaseURL = new URL(baseUrl.pathname + "/", "file:");
|
|
230650
230875
|
const urlReader = new HackyDataStylesAccumulator(URL_READER);
|
|
230651
|
-
const
|
|
230652
|
-
await duckdbConnection.runSQL(`SET FILE_SEARCH_PATH='${workingDirectory}';`);
|
|
230653
|
-
const runtimeOptions = {
|
|
230876
|
+
const runtime = new Runtime({
|
|
230654
230877
|
urlReader,
|
|
230655
|
-
|
|
230656
|
-
|
|
230657
|
-
|
|
230658
|
-
runtimeOptions.buildManifest = {
|
|
230659
|
-
entries: options.buildManifest,
|
|
230660
|
-
strict: false
|
|
230661
|
-
};
|
|
230662
|
-
}
|
|
230663
|
-
const runtime = new Runtime(runtimeOptions);
|
|
230878
|
+
config: Model.toMalloyConfig(malloyConfig),
|
|
230879
|
+
buildManifest: options?.buildManifest ? { entries: options.buildManifest, strict: false } : undefined
|
|
230880
|
+
});
|
|
230664
230881
|
const dataStyles = urlReader.getHackyAccumulatedDataStyles();
|
|
230665
230882
|
return { runtime, modelURL, importBaseURL, dataStyles, modelType };
|
|
230666
230883
|
}
|
|
230884
|
+
static toMalloyConfig(input) {
|
|
230885
|
+
if (input instanceof MalloyConfig2) {
|
|
230886
|
+
return input;
|
|
230887
|
+
}
|
|
230888
|
+
const malloyConfig = new MalloyConfig2({ connections: {} });
|
|
230889
|
+
malloyConfig.wrapConnections(() => new FixedConnectionMap(input, "duckdb"));
|
|
230890
|
+
return malloyConfig;
|
|
230891
|
+
}
|
|
230667
230892
|
static getQueries(modelPath, modelDef) {
|
|
230668
230893
|
const isNamedQuery = (object) => object.type === "query";
|
|
230669
230894
|
return Object.values(modelDef.contents).filter(isNamedQuery).map((queryObj) => ({
|
|
@@ -230841,7 +231066,7 @@ run: ${sourceName ? sourceName + "->" : ""}${queryName}`;
|
|
|
230841
231066
|
return this.modelType;
|
|
230842
231067
|
}
|
|
230843
231068
|
async getFileText(packagePath) {
|
|
230844
|
-
const fullPath =
|
|
231069
|
+
const fullPath = path6.join(packagePath, this.modelPath);
|
|
230845
231070
|
try {
|
|
230846
231071
|
return await fs4.readFile(fullPath, "utf8");
|
|
230847
231072
|
} catch {
|
|
@@ -230860,22 +231085,22 @@ class Package {
|
|
|
230860
231085
|
databases;
|
|
230861
231086
|
models = new Map;
|
|
230862
231087
|
packagePath;
|
|
230863
|
-
|
|
231088
|
+
malloyConfig;
|
|
230864
231089
|
static meter = import_api3.metrics.getMeter("publisher");
|
|
230865
231090
|
static packageLoadHistogram = this.meter.createHistogram("malloy_package_load_duration", {
|
|
230866
231091
|
description: "Time taken to load a Malloy package",
|
|
230867
231092
|
unit: "ms"
|
|
230868
231093
|
});
|
|
230869
|
-
constructor(projectName, packageName, packagePath, packageMetadata, databases, models,
|
|
231094
|
+
constructor(projectName, packageName, packagePath, packageMetadata, databases, models, malloyConfig = new MalloyConfig3({ connections: {} })) {
|
|
230870
231095
|
this.projectName = projectName;
|
|
230871
231096
|
this.packageName = packageName;
|
|
230872
231097
|
this.packagePath = packagePath;
|
|
230873
231098
|
this.packageMetadata = packageMetadata;
|
|
230874
231099
|
this.databases = databases;
|
|
230875
231100
|
this.models = models;
|
|
230876
|
-
this.
|
|
231101
|
+
this.malloyConfig = malloyConfig;
|
|
230877
231102
|
}
|
|
230878
|
-
static async create(projectName, packageName, packagePath,
|
|
231103
|
+
static async create(projectName, packageName, packagePath, projectMalloyConfig) {
|
|
230879
231104
|
const startTime = performance.now();
|
|
230880
231105
|
await Package.validatePackageManifestExistsOrThrowError(packagePath);
|
|
230881
231106
|
const manifestValidationTime = performance.now();
|
|
@@ -230898,10 +231123,8 @@ class Package {
|
|
|
230898
231123
|
databaseCount: databases.length,
|
|
230899
231124
|
duration: formatDuration(databasesTime - packageConfigTime)
|
|
230900
231125
|
});
|
|
230901
|
-
const
|
|
230902
|
-
const
|
|
230903
|
-
connections.set("duckdb", duckdbConnection);
|
|
230904
|
-
const models = await Package.loadModels(packageName, packagePath, connections);
|
|
231126
|
+
const malloyConfig = Package.buildPackageMalloyConfig(packagePath, typeof projectMalloyConfig === "function" ? projectMalloyConfig : () => Package.toMalloyConfig(projectMalloyConfig));
|
|
231127
|
+
const models = await Package.loadModels(packageName, packagePath, malloyConfig);
|
|
230905
231128
|
const modelsTime = performance.now();
|
|
230906
231129
|
logger.info("Models loaded", {
|
|
230907
231130
|
packageName,
|
|
@@ -230935,7 +231158,7 @@ class Package {
|
|
|
230935
231158
|
packageName,
|
|
230936
231159
|
duration: formatDuration(executionTime)
|
|
230937
231160
|
});
|
|
230938
|
-
return new Package(projectName, packageName, packagePath, packageConfig, databases, models,
|
|
231161
|
+
return new Package(projectName, packageName, packagePath, packageConfig, databases, models, malloyConfig);
|
|
230939
231162
|
} catch (error) {
|
|
230940
231163
|
logger.error(`Error loading package ${packageName}`, { error });
|
|
230941
231164
|
console.error(error);
|
|
@@ -230962,9 +231185,6 @@ class Package {
|
|
|
230962
231185
|
getPackageName() {
|
|
230963
231186
|
return this.packageName;
|
|
230964
231187
|
}
|
|
230965
|
-
getPackagePath() {
|
|
230966
|
-
return this.packagePath;
|
|
230967
|
-
}
|
|
230968
231188
|
getPackageMetadata() {
|
|
230969
231189
|
return this.packageMetadata;
|
|
230970
231190
|
}
|
|
@@ -230974,6 +231194,15 @@ class Package {
|
|
|
230974
231194
|
getModel(modelPath) {
|
|
230975
231195
|
return this.models.get(modelPath);
|
|
230976
231196
|
}
|
|
231197
|
+
async getMalloyConnection(connectionName) {
|
|
231198
|
+
return this.malloyConfig.connections.lookupConnection(connectionName);
|
|
231199
|
+
}
|
|
231200
|
+
getMalloyConfig() {
|
|
231201
|
+
return this.malloyConfig;
|
|
231202
|
+
}
|
|
231203
|
+
getPackagePath() {
|
|
231204
|
+
return this.packagePath;
|
|
231205
|
+
}
|
|
230977
231206
|
getModelPaths() {
|
|
230978
231207
|
return Array.from(this.models.keys());
|
|
230979
231208
|
}
|
|
@@ -230984,23 +231213,13 @@ class Package {
|
|
|
230984
231213
|
modelCount: modelPaths.length,
|
|
230985
231214
|
manifestEntryCount: Object.keys(buildManifest).length
|
|
230986
231215
|
});
|
|
230987
|
-
const reloaded = await Promise.all(modelPaths.map((modelPath) => Model.create(this.packageName, this.packagePath, modelPath, this.
|
|
231216
|
+
const reloaded = await Promise.all(modelPaths.map((modelPath) => Model.create(this.packageName, this.packagePath, modelPath, this.malloyConfig, { buildManifest })));
|
|
230988
231217
|
const nextModels = new Map;
|
|
230989
231218
|
for (const model of reloaded) {
|
|
230990
231219
|
nextModels.set(model.getPath(), model);
|
|
230991
231220
|
}
|
|
230992
231221
|
this.models = nextModels;
|
|
230993
231222
|
}
|
|
230994
|
-
getConnections() {
|
|
230995
|
-
return this.connections;
|
|
230996
|
-
}
|
|
230997
|
-
getMalloyConnection(connectionName) {
|
|
230998
|
-
const connection = this.connections.get(connectionName);
|
|
230999
|
-
if (!connection) {
|
|
231000
|
-
throw new Error(`Connection ${connectionName} not found in package ${this.packageName}`);
|
|
231001
|
-
}
|
|
231002
|
-
return connection;
|
|
231003
|
-
}
|
|
231004
231223
|
async getModelFileText(modelPath) {
|
|
231005
231224
|
const model = this.getModel(modelPath);
|
|
231006
231225
|
if (!model) {
|
|
@@ -231045,11 +231264,40 @@ class Package {
|
|
|
231045
231264
|
};
|
|
231046
231265
|
}));
|
|
231047
231266
|
}
|
|
231048
|
-
static async loadModels(packageName, packagePath,
|
|
231267
|
+
static async loadModels(packageName, packagePath, malloyConfig) {
|
|
231049
231268
|
const modelPaths = await Package.getModelPaths(packagePath);
|
|
231050
|
-
const models = await Promise.all(modelPaths.map((modelPath) => Model.create(packageName, packagePath, modelPath,
|
|
231269
|
+
const models = await Promise.all(modelPaths.map((modelPath) => Model.create(packageName, packagePath, modelPath, malloyConfig)));
|
|
231051
231270
|
return new Map(models.map((model) => [model.getPath(), model]));
|
|
231052
231271
|
}
|
|
231272
|
+
static buildPackageMalloyConfig(packagePath, getProjectMalloyConfig) {
|
|
231273
|
+
const malloyConfig = new MalloyConfig3({
|
|
231274
|
+
connections: {
|
|
231275
|
+
duckdb: {
|
|
231276
|
+
is: "duckdb",
|
|
231277
|
+
databasePath: ":memory:"
|
|
231278
|
+
}
|
|
231279
|
+
}
|
|
231280
|
+
}, {
|
|
231281
|
+
config: contextOverlay2({ rootDirectory: packagePath })
|
|
231282
|
+
});
|
|
231283
|
+
malloyConfig.wrapConnections((base) => ({
|
|
231284
|
+
lookupConnection: async (name) => {
|
|
231285
|
+
if (!name || name === "duckdb") {
|
|
231286
|
+
return base.lookupConnection(name);
|
|
231287
|
+
}
|
|
231288
|
+
return getProjectMalloyConfig().connections.lookupConnection(name);
|
|
231289
|
+
}
|
|
231290
|
+
}));
|
|
231291
|
+
return malloyConfig;
|
|
231292
|
+
}
|
|
231293
|
+
static toMalloyConfig(input) {
|
|
231294
|
+
if (input instanceof MalloyConfig3) {
|
|
231295
|
+
return input;
|
|
231296
|
+
}
|
|
231297
|
+
const malloyConfig = new MalloyConfig3({ connections: {} });
|
|
231298
|
+
malloyConfig.wrapConnections(() => new FixedConnectionMap2(input, "duckdb"));
|
|
231299
|
+
return malloyConfig;
|
|
231300
|
+
}
|
|
231053
231301
|
static async getModelPaths(packagePath) {
|
|
231054
231302
|
let files = undefined;
|
|
231055
231303
|
try {
|
|
@@ -231059,11 +231307,11 @@ class Package {
|
|
|
231059
231307
|
throw new PackageNotFoundError(`Package config for ${packagePath} does not exist.`);
|
|
231060
231308
|
}
|
|
231061
231309
|
return files.map((fullPath) => {
|
|
231062
|
-
return
|
|
231310
|
+
return path7.relative(packagePath, fullPath).replace(/\\/g, "/");
|
|
231063
231311
|
}).filter((modelPath) => modelPath.endsWith(MODEL_FILE_SUFFIX) || modelPath.endsWith(NOTEBOOK_FILE_SUFFIX));
|
|
231064
231312
|
}
|
|
231065
231313
|
static async validatePackageManifestExistsOrThrowError(packagePath) {
|
|
231066
|
-
const packageConfigPath =
|
|
231314
|
+
const packageConfigPath = path7.join(packagePath, PACKAGE_MANIFEST_NAME);
|
|
231067
231315
|
try {
|
|
231068
231316
|
await fs5.stat(packageConfigPath);
|
|
231069
231317
|
} catch {
|
|
@@ -231072,7 +231320,7 @@ class Package {
|
|
|
231072
231320
|
}
|
|
231073
231321
|
}
|
|
231074
231322
|
static async readPackageConfig(packagePath) {
|
|
231075
|
-
const packageConfigPath =
|
|
231323
|
+
const packageConfigPath = path7.join(packagePath, PACKAGE_MANIFEST_NAME);
|
|
231076
231324
|
const packageConfigContents = await fs5.readFile(packageConfigPath);
|
|
231077
231325
|
const packageManifest = JSON.parse(packageConfigContents.toString());
|
|
231078
231326
|
return {
|
|
@@ -231094,11 +231342,11 @@ class Package {
|
|
|
231094
231342
|
let files = undefined;
|
|
231095
231343
|
files = await import_recursive_readdir.default(packagePath);
|
|
231096
231344
|
return files.map((fullPath) => {
|
|
231097
|
-
return
|
|
231345
|
+
return path7.relative(packagePath, fullPath).replace(/\\/g, "/");
|
|
231098
231346
|
}).filter((modelPath) => modelPath.endsWith(".parquet") || modelPath.endsWith(".csv"));
|
|
231099
231347
|
}
|
|
231100
231348
|
static async getDatabaseInfo(packagePath, databasePath) {
|
|
231101
|
-
const fullPath =
|
|
231349
|
+
const fullPath = path7.join(packagePath, databasePath);
|
|
231102
231350
|
const runtime = new ConnectionRuntime({
|
|
231103
231351
|
urlReader: new EmptyURLReader,
|
|
231104
231352
|
connections: [new DuckDBConnection3("duckdb")]
|
|
@@ -231127,19 +231375,23 @@ class Package {
|
|
|
231127
231375
|
}
|
|
231128
231376
|
|
|
231129
231377
|
// src/service/project.ts
|
|
231378
|
+
var RETIRED_CONNECTION_DRAIN_MS = 30000;
|
|
231379
|
+
|
|
231130
231380
|
class Project {
|
|
231131
231381
|
packages = new Map;
|
|
231132
231382
|
packageMutexes = new Map;
|
|
231133
231383
|
packageStatuses = new Map;
|
|
231134
|
-
|
|
231384
|
+
malloyConfig;
|
|
231385
|
+
connectionMutex = new Mutex;
|
|
231386
|
+
retiredConnectionGenerations = new Set;
|
|
231135
231387
|
apiConnections;
|
|
231136
231388
|
projectPath;
|
|
231137
231389
|
projectName;
|
|
231138
231390
|
metadata;
|
|
231139
|
-
constructor(projectName, projectPath,
|
|
231391
|
+
constructor(projectName, projectPath, malloyConfig, apiConnections) {
|
|
231140
231392
|
this.projectName = projectName;
|
|
231141
231393
|
this.projectPath = projectPath;
|
|
231142
|
-
this.
|
|
231394
|
+
this.malloyConfig = malloyConfig;
|
|
231143
231395
|
this.apiConnections = apiConnections;
|
|
231144
231396
|
this.metadata = {
|
|
231145
231397
|
resource: `${API_PREFIX}/projects/${this.projectName}`,
|
|
@@ -231151,7 +231403,7 @@ class Project {
|
|
|
231151
231403
|
async writeProjectReadme(readme) {
|
|
231152
231404
|
if (readme === undefined)
|
|
231153
231405
|
return;
|
|
231154
|
-
const readmePath =
|
|
231406
|
+
const readmePath = path8.join(this.projectPath, "README.md");
|
|
231155
231407
|
try {
|
|
231156
231408
|
await fs6.promises.writeFile(readmePath, readme, "utf-8");
|
|
231157
231409
|
logger.info(`Updated README.md for project ${this.projectName}`);
|
|
@@ -231166,15 +231418,16 @@ class Project {
|
|
|
231166
231418
|
await this.writeProjectReadme(payload.readme);
|
|
231167
231419
|
}
|
|
231168
231420
|
if (payload.connections) {
|
|
231169
|
-
|
|
231170
|
-
|
|
231171
|
-
|
|
231172
|
-
|
|
231173
|
-
|
|
231174
|
-
|
|
231175
|
-
|
|
231176
|
-
|
|
231177
|
-
|
|
231421
|
+
const payloadConnections = payload.connections;
|
|
231422
|
+
await this.runConnectionUpdateExclusive(async () => {
|
|
231423
|
+
logger.info(`Updating ${payloadConnections.length} connections for project ${this.projectName}`);
|
|
231424
|
+
const isUpdateConnectionRequest = true;
|
|
231425
|
+
const nextMalloyConfig = buildProjectMalloyConfig(payloadConnections, this.projectPath, isUpdateConnectionRequest);
|
|
231426
|
+
this.updateConnections(nextMalloyConfig);
|
|
231427
|
+
logger.info(`Successfully updated connections for project ${this.projectName}`, {
|
|
231428
|
+
apiConnections: this.apiConnections.length,
|
|
231429
|
+
internalConnections: this.apiConnections.length
|
|
231430
|
+
});
|
|
231178
231431
|
});
|
|
231179
231432
|
}
|
|
231180
231433
|
return this;
|
|
@@ -231184,18 +231437,17 @@ class Project {
|
|
|
231184
231437
|
throw new ProjectNotFoundError(`Project path ${projectPath} not found`);
|
|
231185
231438
|
}
|
|
231186
231439
|
logger.info(`Creating project with connection configuration`);
|
|
231187
|
-
const
|
|
231188
|
-
logger.info(`Loaded ${
|
|
231189
|
-
|
|
231190
|
-
apiConnections
|
|
231440
|
+
const malloyConfig = buildProjectMalloyConfig(connections, projectPath);
|
|
231441
|
+
logger.info(`Loaded ${malloyConfig.apiConnections.length} connections for project ${projectName}`, {
|
|
231442
|
+
apiConnections: malloyConfig.apiConnections
|
|
231191
231443
|
});
|
|
231192
|
-
const project = new Project(projectName, projectPath,
|
|
231444
|
+
const project = new Project(projectName, projectPath, malloyConfig, malloyConfig.apiConnections);
|
|
231193
231445
|
return project;
|
|
231194
231446
|
}
|
|
231195
231447
|
async reloadProjectMetadata() {
|
|
231196
231448
|
let readme = "";
|
|
231197
231449
|
try {
|
|
231198
|
-
readme = (await fs6.promises.readFile(
|
|
231450
|
+
readme = (await fs6.promises.readFile(path8.join(this.projectPath, README_NAME))).toString();
|
|
231199
231451
|
} catch {}
|
|
231200
231452
|
this.metadata = {
|
|
231201
231453
|
...this.metadata,
|
|
@@ -231206,10 +231458,10 @@ class Project {
|
|
|
231206
231458
|
return this.metadata;
|
|
231207
231459
|
}
|
|
231208
231460
|
async compileSource(packageName, modelName, source, includeSql = false) {
|
|
231209
|
-
const modelDir =
|
|
231210
|
-
const virtualUri = `file://${
|
|
231461
|
+
const modelDir = path8.dirname(path8.join(this.projectPath, packageName, modelName));
|
|
231462
|
+
const virtualUri = `file://${path8.join(modelDir, "__compile_check.malloy")}`;
|
|
231211
231463
|
const virtualUrl = new URL(virtualUri);
|
|
231212
|
-
const modelPath =
|
|
231464
|
+
const modelPath = path8.join(this.projectPath, packageName, modelName);
|
|
231213
231465
|
let modelContent = "";
|
|
231214
231466
|
try {
|
|
231215
231467
|
modelContent = await fs6.promises.readFile(modelPath, "utf8");
|
|
@@ -231224,9 +231476,10 @@ ${source}` : source;
|
|
|
231224
231476
|
return URL_READER.readURL(url2);
|
|
231225
231477
|
}
|
|
231226
231478
|
};
|
|
231479
|
+
const pkg = await this.getPackage(packageName);
|
|
231227
231480
|
const runtime = new Runtime2({
|
|
231228
231481
|
urlReader: interceptingReader,
|
|
231229
|
-
|
|
231482
|
+
config: pkg.getMalloyConfig()
|
|
231230
231483
|
});
|
|
231231
231484
|
try {
|
|
231232
231485
|
const modelMaterializer = runtime.loadModel(virtualUrl);
|
|
@@ -231256,12 +231509,40 @@ ${source}` : source;
|
|
|
231256
231509
|
}
|
|
231257
231510
|
return connection;
|
|
231258
231511
|
}
|
|
231259
|
-
getMalloyConnection(connectionName) {
|
|
231260
|
-
|
|
231261
|
-
|
|
231262
|
-
|
|
231512
|
+
async getMalloyConnection(connectionName) {
|
|
231513
|
+
return this.malloyConfig.malloyConfig.connections.lookupConnection(connectionName);
|
|
231514
|
+
}
|
|
231515
|
+
getProjectMalloyConfig() {
|
|
231516
|
+
return this.malloyConfig.malloyConfig;
|
|
231517
|
+
}
|
|
231518
|
+
async runConnectionUpdateExclusive(fn) {
|
|
231519
|
+
return this.connectionMutex.runExclusive(fn);
|
|
231520
|
+
}
|
|
231521
|
+
retireConnectionGeneration(label, releaseConnections) {
|
|
231522
|
+
const generation = {
|
|
231523
|
+
label,
|
|
231524
|
+
releaseConnections
|
|
231525
|
+
};
|
|
231526
|
+
generation.timer = setTimeout(() => {
|
|
231527
|
+
this.releaseRetiredConnectionGeneration(generation);
|
|
231528
|
+
}, RETIRED_CONNECTION_DRAIN_MS);
|
|
231529
|
+
generation.timer.unref?.();
|
|
231530
|
+
this.retiredConnectionGenerations.add(generation);
|
|
231531
|
+
}
|
|
231532
|
+
async releaseRetiredConnectionGeneration(generation) {
|
|
231533
|
+
if (!this.retiredConnectionGenerations.delete(generation))
|
|
231534
|
+
return;
|
|
231535
|
+
if (generation.timer) {
|
|
231536
|
+
clearTimeout(generation.timer);
|
|
231263
231537
|
}
|
|
231264
|
-
|
|
231538
|
+
try {
|
|
231539
|
+
await generation.releaseConnections();
|
|
231540
|
+
} catch (error) {
|
|
231541
|
+
logger.error(`Error releasing retired connection generation ${generation.label}`, { error });
|
|
231542
|
+
}
|
|
231543
|
+
}
|
|
231544
|
+
async releaseAllRetiredConnectionGenerations() {
|
|
231545
|
+
await Promise.all([...this.retiredConnectionGenerations].map((generation) => this.releaseRetiredConnectionGeneration(generation)));
|
|
231265
231546
|
}
|
|
231266
231547
|
async listPackages() {
|
|
231267
231548
|
logger.debug("Listing packages", { projectPath: this.projectPath });
|
|
@@ -231316,8 +231597,11 @@ ${source}` : source;
|
|
|
231316
231597
|
this.setPackageStatus(packageName, "loading" /* LOADING */);
|
|
231317
231598
|
try {
|
|
231318
231599
|
logger.debug(`Loading package ${packageName}...`);
|
|
231319
|
-
const packagePath =
|
|
231320
|
-
const _package2 = await Package.create(this.projectName, packageName, packagePath, this.
|
|
231600
|
+
const packagePath = path8.join(this.projectPath, packageName);
|
|
231601
|
+
const _package2 = await Package.create(this.projectName, packageName, packagePath, () => this.malloyConfig.malloyConfig);
|
|
231602
|
+
if (existingPackage !== undefined && reload) {
|
|
231603
|
+
this.retireConnectionGeneration(`package ${packageName}`, () => existingPackage.getMalloyConfig().releaseConnections());
|
|
231604
|
+
}
|
|
231321
231605
|
this.packages.set(packageName, _package2);
|
|
231322
231606
|
this.setPackageStatus(packageName, "serving" /* SERVING */);
|
|
231323
231607
|
logger.debug(`Successfully loaded package ${packageName}`);
|
|
@@ -231331,17 +231615,17 @@ ${source}` : source;
|
|
|
231331
231615
|
});
|
|
231332
231616
|
}
|
|
231333
231617
|
async addPackage(packageName) {
|
|
231334
|
-
const packagePath =
|
|
231618
|
+
const packagePath = path8.join(this.projectPath, packageName);
|
|
231335
231619
|
if (!await fs6.promises.access(packagePath).then(() => true).catch(() => false) || !(await fs6.promises.stat(packagePath))?.isDirectory()) {
|
|
231336
231620
|
throw new PackageNotFoundError(`Package ${packageName} not found`);
|
|
231337
231621
|
}
|
|
231338
231622
|
logger.info(`Adding package ${packageName} to project ${this.projectName}`, {
|
|
231339
231623
|
packagePath,
|
|
231340
|
-
|
|
231624
|
+
malloyConfig: this.malloyConfig.malloyConfig
|
|
231341
231625
|
});
|
|
231342
231626
|
this.setPackageStatus(packageName, "loading" /* LOADING */);
|
|
231343
231627
|
try {
|
|
231344
|
-
this.packages.set(packageName, await Package.create(this.projectName, packageName, packagePath, this.
|
|
231628
|
+
this.packages.set(packageName, await Package.create(this.projectName, packageName, packagePath, () => this.malloyConfig.malloyConfig));
|
|
231345
231629
|
} catch (error) {
|
|
231346
231630
|
logger.error("Error adding package", { error });
|
|
231347
231631
|
this.deletePackageStatus(packageName);
|
|
@@ -231351,8 +231635,8 @@ ${source}` : source;
|
|
|
231351
231635
|
return this.packages.get(packageName);
|
|
231352
231636
|
}
|
|
231353
231637
|
async writePackageManifest(packageName, metadata) {
|
|
231354
|
-
const packagePath =
|
|
231355
|
-
const manifestPath =
|
|
231638
|
+
const packagePath = path8.join(this.projectPath, packageName);
|
|
231639
|
+
const manifestPath = path8.join(packagePath, "publisher.json");
|
|
231356
231640
|
try {
|
|
231357
231641
|
let existingManifest = {};
|
|
231358
231642
|
try {
|
|
@@ -231422,8 +231706,9 @@ ${source}` : source;
|
|
|
231422
231706
|
} else if (packageStatus?.status === "serving" /* SERVING */) {
|
|
231423
231707
|
this.setPackageStatus(packageName, "unloading" /* UNLOADING */);
|
|
231424
231708
|
}
|
|
231709
|
+
await _package.getMalloyConfig().releaseConnections();
|
|
231425
231710
|
try {
|
|
231426
|
-
await fs6.promises.rm(
|
|
231711
|
+
await fs6.promises.rm(path8.join(this.projectPath, packageName), {
|
|
231427
231712
|
recursive: true,
|
|
231428
231713
|
force: true
|
|
231429
231714
|
});
|
|
@@ -231433,39 +231718,45 @@ ${source}` : source;
|
|
|
231433
231718
|
this.packages.delete(packageName);
|
|
231434
231719
|
this.packageStatuses.delete(packageName);
|
|
231435
231720
|
}
|
|
231436
|
-
updateConnections(
|
|
231437
|
-
|
|
231438
|
-
this.
|
|
231721
|
+
updateConnections(malloyConfig, _apiConnections, afterPreviousRelease) {
|
|
231722
|
+
const previousMalloyConfig = this.malloyConfig;
|
|
231723
|
+
this.malloyConfig = malloyConfig;
|
|
231724
|
+
this.apiConnections = malloyConfig.apiConnections;
|
|
231725
|
+
if (previousMalloyConfig !== malloyConfig) {
|
|
231726
|
+
this.retireConnectionGeneration(`project ${this.projectName}`, async () => {
|
|
231727
|
+
await previousMalloyConfig.releaseConnections();
|
|
231728
|
+
await afterPreviousRelease?.();
|
|
231729
|
+
});
|
|
231730
|
+
} else {
|
|
231731
|
+
afterPreviousRelease?.();
|
|
231732
|
+
}
|
|
231439
231733
|
}
|
|
231440
231734
|
async deleteConnection(connectionName) {
|
|
231441
|
-
this.malloyConnections.get(connectionName)?.close();
|
|
231442
|
-
const isDeleted = this.malloyConnections.delete(connectionName);
|
|
231443
231735
|
const index = this.apiConnections.findIndex((conn) => conn.name === connectionName);
|
|
231444
|
-
const connectionType = this.apiConnections[index]?.type;
|
|
231445
|
-
if (connectionType === "duckdb") {
|
|
231446
|
-
await this.deleteDuckDBConnection(connectionName);
|
|
231447
|
-
} else if (connectionType === "ducklake") {
|
|
231448
|
-
await this.deleteDuckLakeConnection(connectionName);
|
|
231449
|
-
}
|
|
231450
231736
|
if (index !== -1) {
|
|
231451
231737
|
this.apiConnections.splice(index, 1);
|
|
231452
231738
|
}
|
|
231453
|
-
if (
|
|
231739
|
+
if (index !== -1) {
|
|
231454
231740
|
logger.info(`Removed connection ${connectionName} from project ${this.projectName}`);
|
|
231455
231741
|
} else {
|
|
231456
231742
|
logger.warn(`Connection ${connectionName} not found in project ${this.projectName}`);
|
|
231457
231743
|
}
|
|
231458
231744
|
}
|
|
231459
|
-
closeAllConnections() {
|
|
231460
|
-
|
|
231461
|
-
|
|
231462
|
-
|
|
231463
|
-
logger.
|
|
231464
|
-
} catch (error) {
|
|
231465
|
-
logger.error(`Error closing connection ${connectionName} for project ${this.projectName}`, { error });
|
|
231745
|
+
async closeAllConnections() {
|
|
231746
|
+
const packageReleases = await Promise.allSettled(Array.from(this.packages.values(), (pkg) => pkg.getMalloyConfig().releaseConnections()));
|
|
231747
|
+
for (const result of packageReleases) {
|
|
231748
|
+
if (result.status === "rejected") {
|
|
231749
|
+
logger.error(`Error closing package connections for project ${this.projectName}`, { error: result.reason });
|
|
231466
231750
|
}
|
|
231467
231751
|
}
|
|
231468
|
-
this.
|
|
231752
|
+
this.packages.clear();
|
|
231753
|
+
this.packageStatuses.clear();
|
|
231754
|
+
try {
|
|
231755
|
+
await this.malloyConfig.releaseConnections();
|
|
231756
|
+
} catch (error) {
|
|
231757
|
+
logger.error(`Error closing connections for project ${this.projectName}`, { error });
|
|
231758
|
+
}
|
|
231759
|
+
await this.releaseAllRetiredConnectionGenerations();
|
|
231469
231760
|
this.apiConnections = [];
|
|
231470
231761
|
logger.info(`Closed all connections for project ${this.projectName}`);
|
|
231471
231762
|
}
|
|
@@ -231477,16 +231768,13 @@ ${source}` : source;
|
|
|
231477
231768
|
};
|
|
231478
231769
|
}
|
|
231479
231770
|
async deleteDuckDBConnection(connectionName) {
|
|
231480
|
-
const duckdbPath =
|
|
231481
|
-
|
|
231482
|
-
fs6.promises.rm(duckdbPath
|
|
231483
|
-
|
|
231484
|
-
|
|
231485
|
-
logger.error(`Failed to remove DuckDB connection file ${connectionName} from project ${this.projectName}`, { error });
|
|
231486
|
-
});
|
|
231487
|
-
}).catch((error) => {
|
|
231771
|
+
const duckdbPath = path8.join(this.projectPath, `${connectionName}.duckdb`);
|
|
231772
|
+
try {
|
|
231773
|
+
await fs6.promises.rm(duckdbPath, { force: true });
|
|
231774
|
+
logger.info(`Removed DuckDB connection file ${connectionName} from project ${this.projectName}`);
|
|
231775
|
+
} catch (error) {
|
|
231488
231776
|
logger.error(`Failed to remove DuckDB connection file ${connectionName} from project ${this.projectName}`, { error });
|
|
231489
|
-
}
|
|
231777
|
+
}
|
|
231490
231778
|
}
|
|
231491
231779
|
async deleteDuckLakeConnection(connectionName) {
|
|
231492
231780
|
await deleteDuckLakeConnectionFile(connectionName, this.projectPath);
|
|
@@ -231560,12 +231848,28 @@ class ProjectStore {
|
|
|
231560
231848
|
const storageConfig = {
|
|
231561
231849
|
type: "duckdb",
|
|
231562
231850
|
duckdb: {
|
|
231563
|
-
path:
|
|
231851
|
+
path: path9.join(serverRootPath, "publisher.db")
|
|
231564
231852
|
}
|
|
231565
231853
|
};
|
|
231566
231854
|
this.storageManager = new StorageManager(storageConfig);
|
|
231567
231855
|
this.finishedInitialization = this.initialize();
|
|
231568
231856
|
}
|
|
231857
|
+
async addConfiguredProject(project) {
|
|
231858
|
+
try {
|
|
231859
|
+
await this.addProject({
|
|
231860
|
+
name: project.name,
|
|
231861
|
+
resource: `${API_PREFIX}/projects/${project.name}`,
|
|
231862
|
+
connections: project.connections,
|
|
231863
|
+
packages: project.packages
|
|
231864
|
+
}, true);
|
|
231865
|
+
} catch (error) {
|
|
231866
|
+
this.logProjectInitializationError(project.name, error);
|
|
231867
|
+
}
|
|
231868
|
+
}
|
|
231869
|
+
logProjectInitializationError(projectName, error) {
|
|
231870
|
+
const label = projectName ? ` "${projectName}"` : "";
|
|
231871
|
+
logger.error(`Error initializing project${label}; skipping project`, this.extractErrorDataFromError(error));
|
|
231872
|
+
}
|
|
231569
231873
|
async initialize() {
|
|
231570
231874
|
const reInit = process.env.INITIALIZE_STORAGE === "true";
|
|
231571
231875
|
const initialTime = performance.now();
|
|
@@ -231577,58 +231881,52 @@ class ProjectStore {
|
|
|
231577
231881
|
const repository = this.storageManager.getRepository();
|
|
231578
231882
|
if (reInit) {
|
|
231579
231883
|
await Promise.all(projectManifest.projects.map(async (project) => {
|
|
231580
|
-
await this.
|
|
231581
|
-
name: project.name,
|
|
231582
|
-
resource: `${API_PREFIX}/projects/${project.name}`,
|
|
231583
|
-
connections: project.connections,
|
|
231584
|
-
packages: project.packages
|
|
231585
|
-
}, true);
|
|
231884
|
+
await this.addConfiguredProject(project);
|
|
231586
231885
|
}));
|
|
231587
231886
|
} else {
|
|
231588
231887
|
const existingProjects = await repository.listProjects();
|
|
231589
231888
|
if (existingProjects.length > 0) {
|
|
231590
231889
|
await Promise.all(existingProjects.map(async (dbProject) => {
|
|
231591
|
-
|
|
231592
|
-
|
|
231593
|
-
|
|
231594
|
-
|
|
231595
|
-
|
|
231596
|
-
|
|
231597
|
-
|
|
231598
|
-
|
|
231599
|
-
|
|
231600
|
-
|
|
231601
|
-
|
|
231602
|
-
|
|
231603
|
-
|
|
231604
|
-
|
|
231605
|
-
|
|
231606
|
-
|
|
231607
|
-
|
|
231890
|
+
try {
|
|
231891
|
+
const projectExists = await fs7.promises.access(dbProject.path).then(() => true).catch(() => false);
|
|
231892
|
+
if (!projectExists) {
|
|
231893
|
+
const projectConfig = projectManifest.projects.find((p) => p.name === dbProject.name);
|
|
231894
|
+
if (projectConfig) {
|
|
231895
|
+
const projectInstance2 = await this.addProject({
|
|
231896
|
+
name: projectConfig.name,
|
|
231897
|
+
resource: `${API_PREFIX}/projects/${projectConfig.name}`,
|
|
231898
|
+
connections: projectConfig.connections,
|
|
231899
|
+
packages: projectConfig.packages
|
|
231900
|
+
}, true);
|
|
231901
|
+
await repository.updateProject(dbProject.id, {
|
|
231902
|
+
path: projectInstance2.metadata.location
|
|
231903
|
+
});
|
|
231904
|
+
return projectInstance2.listPackages();
|
|
231905
|
+
} else {
|
|
231906
|
+
logger.error(`Project "${dbProject.name}" not found in config and files missing`);
|
|
231907
|
+
return;
|
|
231908
|
+
}
|
|
231608
231909
|
}
|
|
231910
|
+
const connections = await repository.listConnections(dbProject.id);
|
|
231911
|
+
const projectInstance = await Project.create(dbProject.name, dbProject.path, connections.map((conn) => ({
|
|
231912
|
+
name: conn.name,
|
|
231913
|
+
type: conn.type,
|
|
231914
|
+
resource: `${API_PREFIX}/connections/${conn.name}`,
|
|
231915
|
+
...conn.config
|
|
231916
|
+
})));
|
|
231917
|
+
const packages = await repository.listPackages(dbProject.id);
|
|
231918
|
+
packages.forEach((pkg) => {
|
|
231919
|
+
projectInstance.setPackageStatus(pkg.name, "serving" /* SERVING */);
|
|
231920
|
+
});
|
|
231921
|
+
this.projects.set(dbProject.name, projectInstance);
|
|
231922
|
+
return projectInstance.listPackages();
|
|
231923
|
+
} catch (error) {
|
|
231924
|
+
this.logProjectInitializationError(dbProject.name, error);
|
|
231609
231925
|
}
|
|
231610
|
-
const connections = await repository.listConnections(dbProject.id);
|
|
231611
|
-
const projectInstance = await Project.create(dbProject.name, dbProject.path, connections.map((conn) => ({
|
|
231612
|
-
name: conn.name,
|
|
231613
|
-
type: conn.type,
|
|
231614
|
-
resource: `${API_PREFIX}/connections/${conn.name}`,
|
|
231615
|
-
...conn.config
|
|
231616
|
-
})));
|
|
231617
|
-
this.projects.set(dbProject.name, projectInstance);
|
|
231618
|
-
const packages = await repository.listPackages(dbProject.id);
|
|
231619
|
-
packages.forEach((pkg) => {
|
|
231620
|
-
projectInstance.setPackageStatus(pkg.name, "serving" /* SERVING */);
|
|
231621
|
-
});
|
|
231622
|
-
return projectInstance.listPackages();
|
|
231623
231926
|
}));
|
|
231624
231927
|
} else {
|
|
231625
231928
|
await Promise.all(projectManifest.projects.map(async (project) => {
|
|
231626
|
-
await this.
|
|
231627
|
-
name: project.name,
|
|
231628
|
-
resource: `${API_PREFIX}/projects/${project.name}`,
|
|
231629
|
-
connections: project.connections,
|
|
231630
|
-
packages: project.packages
|
|
231631
|
-
}, true);
|
|
231929
|
+
await this.addConfiguredProject(project);
|
|
231632
231930
|
}));
|
|
231633
231931
|
}
|
|
231634
231932
|
}
|
|
@@ -231640,7 +231938,6 @@ class ProjectStore {
|
|
|
231640
231938
|
markNotReady();
|
|
231641
231939
|
const errorData = this.extractErrorDataFromError(error);
|
|
231642
231940
|
logger.error("Error initializing project store", errorData);
|
|
231643
|
-
process.exit(1);
|
|
231644
231941
|
}
|
|
231645
231942
|
}
|
|
231646
231943
|
async addProjectToDatabase(project) {
|
|
@@ -231838,7 +232135,7 @@ class ProjectStore {
|
|
|
231838
232135
|
const reInit = process.env.INITIALIZE_STORAGE === "true";
|
|
231839
232136
|
await fs7.promises.mkdir(this.serverRootPath, { recursive: true });
|
|
231840
232137
|
if (reInit) {
|
|
231841
|
-
const uploadDocsPath2 =
|
|
232138
|
+
const uploadDocsPath2 = path9.join(this.serverRootPath, PUBLISHER_DATA_DIR);
|
|
231842
232139
|
logger.info(`Reinitialization mode: Cleaning up upload documents path ${uploadDocsPath2}`);
|
|
231843
232140
|
try {
|
|
231844
232141
|
await fs7.promises.rm(uploadDocsPath2, {
|
|
@@ -231855,7 +232152,7 @@ class ProjectStore {
|
|
|
231855
232152
|
} else {
|
|
231856
232153
|
logger.info(`Using existing publisher path`);
|
|
231857
232154
|
}
|
|
231858
|
-
const uploadDocsPath =
|
|
232155
|
+
const uploadDocsPath = path9.join(this.serverRootPath, PUBLISHER_DATA_DIR);
|
|
231859
232156
|
await fs7.promises.mkdir(uploadDocsPath, { recursive: true });
|
|
231860
232157
|
}
|
|
231861
232158
|
async listProjects(skipInitializationCheck = false) {
|
|
@@ -232021,7 +232318,7 @@ class ProjectStore {
|
|
|
232021
232318
|
return;
|
|
232022
232319
|
}
|
|
232023
232320
|
const projectPath = project.metadata?.location;
|
|
232024
|
-
project.closeAllConnections();
|
|
232321
|
+
await project.closeAllConnections();
|
|
232025
232322
|
this.projects.delete(projectName);
|
|
232026
232323
|
await this.deleteProjectFromDatabase(projectName);
|
|
232027
232324
|
if (projectPath) {
|
|
@@ -232079,12 +232376,12 @@ class ProjectStore {
|
|
|
232079
232376
|
const absoluteProjectPath = `${this.serverRootPath}/${PUBLISHER_DATA_DIR}/${projectName}`;
|
|
232080
232377
|
await fs7.promises.mkdir(absoluteProjectPath, { recursive: true });
|
|
232081
232378
|
if (project.readme) {
|
|
232082
|
-
await fs7.promises.writeFile(
|
|
232379
|
+
await fs7.promises.writeFile(path9.join(absoluteProjectPath, "README.md"), project.readme);
|
|
232083
232380
|
}
|
|
232084
232381
|
return absoluteProjectPath;
|
|
232085
232382
|
}
|
|
232086
232383
|
isLocalPath(location) {
|
|
232087
|
-
return location.startsWith("./") || location.startsWith("../") || location.startsWith("~/") || location.startsWith("/") ||
|
|
232384
|
+
return location.startsWith("./") || location.startsWith("../") || location.startsWith("~/") || location.startsWith("/") || path9.isAbsolute(location);
|
|
232088
232385
|
}
|
|
232089
232386
|
isGitHubURL(location) {
|
|
232090
232387
|
return location.startsWith("https://github.com/") || location.startsWith("git@github.com:");
|
|
@@ -232140,7 +232437,7 @@ class ProjectStore {
|
|
|
232140
232437
|
if (githubInfo && githubInfo.packagePath) {
|
|
232141
232438
|
const subPathMatch = _package.location.match(/\/tree\/[^/]+\/(.+)$/);
|
|
232142
232439
|
if (subPathMatch) {
|
|
232143
|
-
sourcePath =
|
|
232440
|
+
sourcePath = path9.join(tempDownloadPath, subPathMatch[1]);
|
|
232144
232441
|
} else {
|
|
232145
232442
|
sourcePath = tempDownloadPath;
|
|
232146
232443
|
}
|
|
@@ -232151,7 +232448,7 @@ class ProjectStore {
|
|
|
232151
232448
|
if (this.isLocalPath(_package.location)) {
|
|
232152
232449
|
sourcePath = _package.location;
|
|
232153
232450
|
} else {
|
|
232154
|
-
sourcePath =
|
|
232451
|
+
sourcePath = path9.join(tempDownloadPath, groupedLocation);
|
|
232155
232452
|
}
|
|
232156
232453
|
}
|
|
232157
232454
|
const sourceExists = await fs7.promises.access(sourcePath).then(() => true).catch(() => false);
|
|
@@ -232227,7 +232524,7 @@ class ProjectStore {
|
|
|
232227
232524
|
}
|
|
232228
232525
|
}
|
|
232229
232526
|
if (this.isLocalPath(location)) {
|
|
232230
|
-
const packagePath =
|
|
232527
|
+
const packagePath = path9.isAbsolute(location) ? location : path9.join(this.serverRootPath, location);
|
|
232231
232528
|
try {
|
|
232232
232529
|
logger.info(`Mounting local directory at "${packagePath}" to "${targetPath}"`);
|
|
232233
232530
|
await this.mountLocalDirectory(packagePath, targetPath, projectName, packageName);
|
|
@@ -232281,11 +232578,11 @@ class ProjectStore {
|
|
|
232281
232578
|
}
|
|
232282
232579
|
await Promise.all(files.map(async (file) => {
|
|
232283
232580
|
const relativeFilePath = file.name.replace(prefix, "");
|
|
232284
|
-
const absoluteFilePath = isCompressedFile ? absoluteDirPath :
|
|
232581
|
+
const absoluteFilePath = isCompressedFile ? absoluteDirPath : path9.join(absoluteDirPath, relativeFilePath);
|
|
232285
232582
|
if (file.name.endsWith("/")) {
|
|
232286
232583
|
return;
|
|
232287
232584
|
}
|
|
232288
|
-
await fs7.promises.mkdir(
|
|
232585
|
+
await fs7.promises.mkdir(path9.dirname(absoluteFilePath), {
|
|
232289
232586
|
recursive: true
|
|
232290
232587
|
});
|
|
232291
232588
|
return fs7.promises.writeFile(absoluteFilePath, await file.download());
|
|
@@ -232301,7 +232598,7 @@ class ProjectStore {
|
|
|
232301
232598
|
const prefix = prefixParts.join("/");
|
|
232302
232599
|
if (isCompressedFile) {
|
|
232303
232600
|
const zipFilePath = `${absoluteDirPath}.zip`;
|
|
232304
|
-
await fs7.promises.mkdir(
|
|
232601
|
+
await fs7.promises.mkdir(path9.dirname(zipFilePath), {
|
|
232305
232602
|
recursive: true
|
|
232306
232603
|
});
|
|
232307
232604
|
const command = new import_client_s32.GetObjectCommand({
|
|
@@ -232340,8 +232637,8 @@ class ProjectStore {
|
|
|
232340
232637
|
if (!relativeFilePath || relativeFilePath.endsWith("/")) {
|
|
232341
232638
|
return;
|
|
232342
232639
|
}
|
|
232343
|
-
const absoluteFilePath =
|
|
232344
|
-
await fs7.promises.mkdir(
|
|
232640
|
+
const absoluteFilePath = path9.join(absoluteDirPath, relativeFilePath);
|
|
232641
|
+
await fs7.promises.mkdir(path9.dirname(absoluteFilePath), {
|
|
232345
232642
|
recursive: true
|
|
232346
232643
|
});
|
|
232347
232644
|
const command = new import_client_s32.GetObjectCommand({
|
|
@@ -232403,7 +232700,7 @@ class ProjectStore {
|
|
|
232403
232700
|
logger.info(`Successfully cloned entire repository to: ${absoluteDirPath}`);
|
|
232404
232701
|
return;
|
|
232405
232702
|
}
|
|
232406
|
-
const packageFullPath =
|
|
232703
|
+
const packageFullPath = path9.join(absoluteDirPath, cleanPackagePath);
|
|
232407
232704
|
const packageExists = await fs7.promises.access(packageFullPath).then(() => true).catch(() => false);
|
|
232408
232705
|
if (!packageExists) {
|
|
232409
232706
|
throw new Error(`Package path "${cleanPackagePath}" does not exist in the cloned repository.`);
|
|
@@ -232411,7 +232708,7 @@ class ProjectStore {
|
|
|
232411
232708
|
const dirContents = await fs7.promises.readdir(absoluteDirPath);
|
|
232412
232709
|
for (const entry of dirContents) {
|
|
232413
232710
|
if (entry !== cleanPackagePath.replace(/^\/+/, "").split("/")[0]) {
|
|
232414
|
-
await fs7.promises.rm(
|
|
232711
|
+
await fs7.promises.rm(path9.join(absoluteDirPath, entry), {
|
|
232415
232712
|
recursive: true,
|
|
232416
232713
|
force: true
|
|
232417
232714
|
});
|
|
@@ -232419,7 +232716,7 @@ class ProjectStore {
|
|
|
232419
232716
|
}
|
|
232420
232717
|
const packageContents = await fs7.promises.readdir(packageFullPath);
|
|
232421
232718
|
for (const entry of packageContents) {
|
|
232422
|
-
await fs7.promises.rename(
|
|
232719
|
+
await fs7.promises.rename(path9.join(packageFullPath, entry), path9.join(absoluteDirPath, entry));
|
|
232423
232720
|
}
|
|
232424
232721
|
await fs7.promises.rm(packageFullPath, { recursive: true, force: true });
|
|
232425
232722
|
}
|
|
@@ -232466,9 +232763,9 @@ class WatchModeController {
|
|
|
232466
232763
|
});
|
|
232467
232764
|
return;
|
|
232468
232765
|
}
|
|
232469
|
-
this.watchingPath =
|
|
232766
|
+
this.watchingPath = path10.join(this.projectStore.serverRootPath, req.body.projectName);
|
|
232470
232767
|
this.watcher = esm_default.watch(this.watchingPath, {
|
|
232471
|
-
ignored: (
|
|
232768
|
+
ignored: (path11, stats) => !!stats?.isFile() && !path11.endsWith(".malloy") && !path11.endsWith(".md"),
|
|
232472
232769
|
ignoreInitial: true
|
|
232473
232770
|
});
|
|
232474
232771
|
const reloadProject = async () => {
|
|
@@ -232476,16 +232773,16 @@ class WatchModeController {
|
|
|
232476
232773
|
await this.projectStore.addProject(project2.metadata);
|
|
232477
232774
|
logger.info(`Reloaded ${req.body.projectName}`);
|
|
232478
232775
|
};
|
|
232479
|
-
this.watcher.on("add", async (
|
|
232480
|
-
logger.info(`Detected new file ${
|
|
232776
|
+
this.watcher.on("add", async (path11) => {
|
|
232777
|
+
logger.info(`Detected new file ${path11}, reloading ${req.body.projectName}`);
|
|
232481
232778
|
await reloadProject();
|
|
232482
232779
|
});
|
|
232483
|
-
this.watcher.on("unlink", async (
|
|
232484
|
-
logger.info(`Detected deletion of ${
|
|
232780
|
+
this.watcher.on("unlink", async (path11) => {
|
|
232781
|
+
logger.info(`Detected deletion of ${path11}, reloading ${req.body.projectName}`);
|
|
232485
232782
|
await reloadProject();
|
|
232486
232783
|
});
|
|
232487
|
-
this.watcher.on("change", async (
|
|
232488
|
-
logger.info(`Detected change on ${
|
|
232784
|
+
this.watcher.on("change", async (path11) => {
|
|
232785
|
+
logger.info(`Detected change on ${path11}, reloading ${req.body.projectName}`);
|
|
232489
232786
|
await reloadProject();
|
|
232490
232787
|
});
|
|
232491
232788
|
res.json();
|
|
@@ -235576,25 +235873,25 @@ async function getModelForQuery(projectStore, projectName, packageName, modelPat
|
|
|
235576
235873
|
}
|
|
235577
235874
|
}
|
|
235578
235875
|
function buildMalloyUri(components, fragment) {
|
|
235579
|
-
let
|
|
235876
|
+
let path11 = "/project/";
|
|
235580
235877
|
if (components.project) {
|
|
235581
|
-
|
|
235878
|
+
path11 += encodeURIComponent(components.project);
|
|
235582
235879
|
} else {
|
|
235583
|
-
|
|
235880
|
+
path11 += "home";
|
|
235584
235881
|
}
|
|
235585
235882
|
if (components.package) {
|
|
235586
|
-
|
|
235883
|
+
path11 += "/package/" + encodeURIComponent(components.package);
|
|
235587
235884
|
}
|
|
235588
235885
|
if (components.resourceType) {
|
|
235589
|
-
|
|
235886
|
+
path11 += "/" + components.resourceType;
|
|
235590
235887
|
if (components.resourceName) {
|
|
235591
|
-
|
|
235888
|
+
path11 += "/" + encodeURIComponent(components.resourceName);
|
|
235592
235889
|
if (components.subResourceType && components.subResourceName) {
|
|
235593
|
-
|
|
235890
|
+
path11 += "/" + components.subResourceType + "/" + encodeURIComponent(components.subResourceName);
|
|
235594
235891
|
}
|
|
235595
235892
|
}
|
|
235596
235893
|
}
|
|
235597
|
-
let uriString = "malloy:/" +
|
|
235894
|
+
let uriString = "malloy:/" + path11;
|
|
235598
235895
|
if (fragment) {
|
|
235599
235896
|
uriString += "#" + fragment;
|
|
235600
235897
|
}
|
|
@@ -236530,8 +236827,8 @@ import {
|
|
|
236530
236827
|
} from "@malloydata/malloy";
|
|
236531
236828
|
|
|
236532
236829
|
// src/service/quoting.ts
|
|
236533
|
-
function quoteTablePath(
|
|
236534
|
-
return
|
|
236830
|
+
function quoteTablePath(path11, dialect) {
|
|
236831
|
+
return path11.split(".").map((seg) => dialect.quoteTablePath(seg)).join(".");
|
|
236535
236832
|
}
|
|
236536
236833
|
function splitTablePath(tableName) {
|
|
236537
236834
|
const lastDot = tableName.lastIndexOf(".");
|
|
@@ -236695,6 +236992,23 @@ var STAGING_BUILD_ID_LEN = 12;
|
|
|
236695
236992
|
function stagingSuffix(buildId) {
|
|
236696
236993
|
return `_${buildId.substring(0, STAGING_BUILD_ID_LEN)}`;
|
|
236697
236994
|
}
|
|
236995
|
+
async function resolvePackageConnections(pkg, names) {
|
|
236996
|
+
const map2 = new Map;
|
|
236997
|
+
const seen = new Set;
|
|
236998
|
+
for (const name of names) {
|
|
236999
|
+
if (!name || seen.has(name))
|
|
237000
|
+
continue;
|
|
237001
|
+
seen.add(name);
|
|
237002
|
+
try {
|
|
237003
|
+
map2.set(name, await pkg.getMalloyConnection(name));
|
|
237004
|
+
} catch (err) {
|
|
237005
|
+
logger.warn(`Failed to resolve connection ${name}`, {
|
|
237006
|
+
error: err instanceof Error ? err.message : String(err)
|
|
237007
|
+
});
|
|
237008
|
+
}
|
|
237009
|
+
}
|
|
237010
|
+
return map2;
|
|
237011
|
+
}
|
|
236698
237012
|
function manifestTableKey(connectionName, tableName) {
|
|
236699
237013
|
return `${connectionName}::${tableName}`;
|
|
236700
237014
|
}
|
|
@@ -236875,8 +237189,8 @@ class MaterializationService {
|
|
|
236875
237189
|
}
|
|
236876
237190
|
const project = await this.projectStore.getProject(projectName, false);
|
|
236877
237191
|
const pkg = await project.getPackage(packageName, false);
|
|
236878
|
-
const connections = pkg.getConnections();
|
|
236879
237192
|
const entries = await this.manifestService.listEntries(projectId, packageName);
|
|
237193
|
+
const connections = await resolvePackageConnections(pkg, entries.map((e) => e.connectionName));
|
|
236880
237194
|
return dropManifestEntries(entries, {
|
|
236881
237195
|
connections,
|
|
236882
237196
|
manifestService: this.manifestService,
|
|
@@ -236897,12 +237211,11 @@ class MaterializationService {
|
|
|
236897
237211
|
manifest.loadText(JSON.stringify(existingManifest));
|
|
236898
237212
|
const existingEntries = await this.manifestService.listEntries(projectId, packageName);
|
|
236899
237213
|
const knownMaterializedTables = new Set(existingEntries.map((e) => manifestTableKey(e.connectionName, e.tableName)));
|
|
236900
|
-
const { graphs, sources, connectionDigests } = await this.compilePackageBuildPlan(pkg, signal);
|
|
237214
|
+
const { graphs, sources, connectionDigests, connections } = await this.compilePackageBuildPlan(pkg, signal);
|
|
236901
237215
|
if (graphs.length === 0) {
|
|
236902
237216
|
logger.info("No persist sources to build");
|
|
236903
237217
|
return { sourcesBuilt: 0, sourcesSkipped: 0 };
|
|
236904
237218
|
}
|
|
236905
|
-
const connections = pkg.getConnections();
|
|
236906
237219
|
let sourcesBuilt = 0;
|
|
236907
237220
|
let sourcesSkipped = 0;
|
|
236908
237221
|
const sourceResults = [];
|
|
@@ -236951,7 +237264,7 @@ class MaterializationService {
|
|
|
236951
237264
|
for (const modelPath of modelPaths) {
|
|
236952
237265
|
if (signal.aborted)
|
|
236953
237266
|
throw new Error("Build cancelled");
|
|
236954
|
-
const { runtime, modelURL, importBaseURL } = await Model.getModelRuntime(pkg.getPackagePath(), modelPath, pkg.
|
|
237267
|
+
const { runtime, modelURL, importBaseURL } = await Model.getModelRuntime(pkg.getPackagePath(), modelPath, pkg.getMalloyConfig());
|
|
236955
237268
|
const modelMaterializer = runtime.loadModel(modelURL, {
|
|
236956
237269
|
importBaseURL
|
|
236957
237270
|
});
|
|
@@ -236994,7 +237307,7 @@ class MaterializationService {
|
|
|
236994
237307
|
}
|
|
236995
237308
|
tableOwners.set(key, sourceID);
|
|
236996
237309
|
}
|
|
236997
|
-
const connections = pkg.
|
|
237310
|
+
const connections = await resolvePackageConnections(pkg, allGraphs.map((g) => g.connectionName));
|
|
236998
237311
|
const connectionDigests = {};
|
|
236999
237312
|
for (const graph of allGraphs) {
|
|
237000
237313
|
const conn = connections.get(graph.connectionName);
|
|
@@ -237002,7 +237315,12 @@ class MaterializationService {
|
|
|
237002
237315
|
connectionDigests[graph.connectionName] = await conn.getDigest();
|
|
237003
237316
|
}
|
|
237004
237317
|
}
|
|
237005
|
-
return {
|
|
237318
|
+
return {
|
|
237319
|
+
graphs: allGraphs,
|
|
237320
|
+
sources: allSources,
|
|
237321
|
+
connectionDigests,
|
|
237322
|
+
connections
|
|
237323
|
+
};
|
|
237006
237324
|
}
|
|
237007
237325
|
async buildOneSource(persistSource, manifest, connection, connectionDigests, forceRefresh, projectId, packageName, knownMaterializedTables) {
|
|
237008
237326
|
const buildIdSQL = persistSource.getSQL();
|
|
@@ -237155,9 +237473,9 @@ var MCP_PORT = Number(process.env.MCP_PORT || 4040);
|
|
|
237155
237473
|
var MCP_ENDPOINT = "/mcp";
|
|
237156
237474
|
var SHUTDOWN_DRAIN_DURATION_SECONDS = Number(process.env.SHUTDOWN_DRAIN_DURATION_SECONDS || 0);
|
|
237157
237475
|
var SHUTDOWN_GRACEFUL_CLOSE_TIMEOUT_SECONDS = Number(process.env.SHUTDOWN_GRACEFUL_CLOSE_TIMEOUT_SECONDS || 0);
|
|
237158
|
-
var __filename_esm =
|
|
237159
|
-
var ROOT =
|
|
237160
|
-
var SERVER_ROOT =
|
|
237476
|
+
var __filename_esm = fileURLToPath2(import.meta.url);
|
|
237477
|
+
var ROOT = path11.join(path11.dirname(__filename_esm), "app");
|
|
237478
|
+
var SERVER_ROOT = path11.resolve(process.cwd(), process.env.SERVER_ROOT || ".");
|
|
237161
237479
|
var API_PREFIX2 = "/api/v0";
|
|
237162
237480
|
var isDevelopment = process.env["NODE_ENV"] === "development";
|
|
237163
237481
|
var app = import_express.default();
|
|
@@ -237238,14 +237556,14 @@ mcpApp.all(MCP_ENDPOINT, async (req, res) => {
|
|
|
237238
237556
|
});
|
|
237239
237557
|
if (!isDevelopment) {
|
|
237240
237558
|
app.use("/", import_express.default.static(ROOT));
|
|
237241
|
-
app.use("/api-doc.html", import_express.default.static(
|
|
237559
|
+
app.use("/api-doc.html", import_express.default.static(path11.join(ROOT, "api-doc.html")));
|
|
237242
237560
|
} else {
|
|
237243
237561
|
app.use(`${API_PREFIX2}`, loggerMiddleware);
|
|
237244
237562
|
app.use(import_http_proxy_middleware.createProxyMiddleware({
|
|
237245
237563
|
target: "http://localhost:5173",
|
|
237246
237564
|
changeOrigin: true,
|
|
237247
237565
|
ws: true,
|
|
237248
|
-
pathFilter: (
|
|
237566
|
+
pathFilter: (path12) => !path12.startsWith("/api/") && !path12.startsWith("/metrics") && !path12.startsWith("/health")
|
|
237249
237567
|
}));
|
|
237250
237568
|
}
|
|
237251
237569
|
var setVersionIdError = (res) => {
|
|
@@ -237418,6 +237736,33 @@ app.get(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/schema
|
|
|
237418
237736
|
res.status(status).json(json);
|
|
237419
237737
|
}
|
|
237420
237738
|
});
|
|
237739
|
+
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/schemas`, async (req, res) => {
|
|
237740
|
+
try {
|
|
237741
|
+
res.status(200).json(await connectionController.listSchemas(req.params.projectName, req.params.connectionName, req.params.packageName));
|
|
237742
|
+
} catch (error) {
|
|
237743
|
+
logger.error(error);
|
|
237744
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237745
|
+
res.status(status).json(json);
|
|
237746
|
+
}
|
|
237747
|
+
});
|
|
237748
|
+
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/schemas/:schemaName/tables`, async (req, res) => {
|
|
237749
|
+
try {
|
|
237750
|
+
res.status(200).json(await connectionController.listTables(req.params.projectName, req.params.connectionName, req.params.schemaName, normalizeQueryArray(req.query.tableNames), req.params.packageName));
|
|
237751
|
+
} catch (error) {
|
|
237752
|
+
logger.error(error);
|
|
237753
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237754
|
+
res.status(status).json(json);
|
|
237755
|
+
}
|
|
237756
|
+
});
|
|
237757
|
+
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/schemas/:schemaName/tables/:tablePath`, async (req, res) => {
|
|
237758
|
+
try {
|
|
237759
|
+
res.status(200).json(await connectionController.getTable(req.params.projectName, req.params.connectionName, req.params.schemaName, req.params.tablePath, req.params.packageName));
|
|
237760
|
+
} catch (error) {
|
|
237761
|
+
logger.error(error);
|
|
237762
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237763
|
+
res.status(status).json(json);
|
|
237764
|
+
}
|
|
237765
|
+
});
|
|
237421
237766
|
app.get(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/sqlSource`, async (req, res) => {
|
|
237422
237767
|
try {
|
|
237423
237768
|
res.status(200).json(await connectionController.getConnectionSqlSource(req.params.projectName, req.params.connectionName, req.query.sqlStatement));
|
|
@@ -237436,6 +237781,24 @@ app.post(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/sqlSo
|
|
|
237436
237781
|
res.status(status).json(json);
|
|
237437
237782
|
}
|
|
237438
237783
|
});
|
|
237784
|
+
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/sqlSource`, async (req, res) => {
|
|
237785
|
+
try {
|
|
237786
|
+
res.status(200).json(await connectionController.getConnectionSqlSource(req.params.projectName, req.params.connectionName, req.query.sqlStatement, req.params.packageName));
|
|
237787
|
+
} catch (error) {
|
|
237788
|
+
logger.error(error);
|
|
237789
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237790
|
+
res.status(status).json(json);
|
|
237791
|
+
}
|
|
237792
|
+
});
|
|
237793
|
+
app.post(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/sqlSource`, async (req, res) => {
|
|
237794
|
+
try {
|
|
237795
|
+
res.status(200).json(await connectionController.getConnectionSqlSource(req.params.projectName, req.params.connectionName, req.body.sqlStatement, req.params.packageName));
|
|
237796
|
+
} catch (error) {
|
|
237797
|
+
logger.error(error);
|
|
237798
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237799
|
+
res.status(status).json(json);
|
|
237800
|
+
}
|
|
237801
|
+
});
|
|
237439
237802
|
app.get(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/queryData`, async (req, res) => {
|
|
237440
237803
|
try {
|
|
237441
237804
|
res.status(200).json(await connectionController.getConnectionQueryData(req.params.projectName, req.params.connectionName, req.query.sqlStatement, req.query.options));
|
|
@@ -237445,6 +237808,15 @@ app.get(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/queryD
|
|
|
237445
237808
|
res.status(status).json(json);
|
|
237446
237809
|
}
|
|
237447
237810
|
});
|
|
237811
|
+
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/queryData`, async (req, res) => {
|
|
237812
|
+
try {
|
|
237813
|
+
res.status(200).json(await connectionController.getConnectionQueryData(req.params.projectName, req.params.connectionName, req.query.sqlStatement, req.query.options, req.params.packageName));
|
|
237814
|
+
} catch (error) {
|
|
237815
|
+
logger.error(error);
|
|
237816
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237817
|
+
res.status(status).json(json);
|
|
237818
|
+
}
|
|
237819
|
+
});
|
|
237448
237820
|
app.post(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/sqlQuery`, async (req, res) => {
|
|
237449
237821
|
try {
|
|
237450
237822
|
let options;
|
|
@@ -237460,6 +237832,21 @@ app.post(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/sqlQu
|
|
|
237460
237832
|
res.status(status).json(json);
|
|
237461
237833
|
}
|
|
237462
237834
|
});
|
|
237835
|
+
app.post(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/sqlQuery`, async (req, res) => {
|
|
237836
|
+
try {
|
|
237837
|
+
let options;
|
|
237838
|
+
if (req.body?.options) {
|
|
237839
|
+
options = req.body.options;
|
|
237840
|
+
} else {
|
|
237841
|
+
options = req.query.options;
|
|
237842
|
+
}
|
|
237843
|
+
res.status(200).json(await connectionController.getConnectionQueryData(req.params.projectName, req.params.connectionName, req.body.sqlStatement, options, req.params.packageName));
|
|
237844
|
+
} catch (error) {
|
|
237845
|
+
logger.error(error);
|
|
237846
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237847
|
+
res.status(status).json(json);
|
|
237848
|
+
}
|
|
237849
|
+
});
|
|
237463
237850
|
app.get(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/temporaryTable`, async (req, res) => {
|
|
237464
237851
|
try {
|
|
237465
237852
|
res.status(200).json(await connectionController.getConnectionTemporaryTable(req.params.projectName, req.params.connectionName, req.query.sqlStatement));
|
|
@@ -237469,6 +237856,15 @@ app.get(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/tempor
|
|
|
237469
237856
|
res.status(status).json(json);
|
|
237470
237857
|
}
|
|
237471
237858
|
});
|
|
237859
|
+
app.get(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/temporaryTable`, async (req, res) => {
|
|
237860
|
+
try {
|
|
237861
|
+
res.status(200).json(await connectionController.getConnectionTemporaryTable(req.params.projectName, req.params.connectionName, req.query.sqlStatement, req.params.packageName));
|
|
237862
|
+
} catch (error) {
|
|
237863
|
+
logger.error(error);
|
|
237864
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237865
|
+
res.status(status).json(json);
|
|
237866
|
+
}
|
|
237867
|
+
});
|
|
237472
237868
|
app.post(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/sqlTemporaryTable`, async (req, res) => {
|
|
237473
237869
|
try {
|
|
237474
237870
|
res.status(200).json(await connectionController.getConnectionTemporaryTable(req.params.projectName, req.params.connectionName, req.body.sqlStatement));
|
|
@@ -237478,6 +237874,15 @@ app.post(`${API_PREFIX2}/projects/:projectName/connections/:connectionName/sqlTe
|
|
|
237478
237874
|
res.status(status).json(json);
|
|
237479
237875
|
}
|
|
237480
237876
|
});
|
|
237877
|
+
app.post(`${API_PREFIX2}/projects/:projectName/packages/:packageName/connections/:connectionName/sqlTemporaryTable`, async (req, res) => {
|
|
237878
|
+
try {
|
|
237879
|
+
res.status(200).json(await connectionController.getConnectionTemporaryTable(req.params.projectName, req.params.connectionName, req.body.sqlStatement, req.params.packageName));
|
|
237880
|
+
} catch (error) {
|
|
237881
|
+
logger.error(error);
|
|
237882
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
237883
|
+
res.status(status).json(json);
|
|
237884
|
+
}
|
|
237885
|
+
});
|
|
237481
237886
|
app.get(`${API_PREFIX2}/projects/:projectName/packages`, async (req, res) => {
|
|
237482
237887
|
if (req.query.versionId) {
|
|
237483
237888
|
setVersionIdError(res);
|
|
@@ -237747,7 +238152,7 @@ app.post(`${API_PREFIX2}/projects/:projectName/packages/:packageName/manifest`,
|
|
|
237747
238152
|
}
|
|
237748
238153
|
});
|
|
237749
238154
|
if (!isDevelopment) {
|
|
237750
|
-
app.get("*", (_req, res) => res.sendFile(
|
|
238155
|
+
app.get("*", (_req, res) => res.sendFile(path11.resolve(ROOT, "index.html")));
|
|
237751
238156
|
}
|
|
237752
238157
|
app.use((err, _req, res, _next) => {
|
|
237753
238158
|
logger.error("Unhandled error:", err);
|