@malloy-publisher/server 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/api-doc.yaml +140 -44
- package/dist/app/assets/{EnvironmentPage-D6kQraU3.js → EnvironmentPage-BnxD6uzV.js} +1 -1
- package/dist/app/assets/{HomePage-BZbuE5jv.js → HomePage-D_srvBnZ.js} +1 -1
- package/dist/app/assets/{LightMode-BxZdPcNr.js → LightMode-DCsTKw61.js} +1 -1
- package/dist/app/assets/MainPage-CzHkstrF.js +2 -0
- package/dist/app/assets/ModelPage-CoQ07DHX.js +2 -0
- package/dist/app/assets/PackagePage-CUeUHOnm.js +1 -0
- package/dist/app/assets/RenderedResult-BnPzJ9Jf.es-Dme58kt1.js +116 -0
- package/dist/app/assets/RouteError-gRAhsKGi.js +1 -0
- package/dist/app/assets/ThemeEditorPage-C2gOJTU1.js +1 -0
- package/dist/app/assets/ToggleButtonGroup-CoIPitu6.js +1 -0
- package/dist/app/assets/index-BhkeAzTe.js +453 -0
- package/dist/app/assets/index-BswZnpqD.js +1322 -0
- package/dist/app/assets/index-CRAwrhYM.js +2 -0
- package/dist/app/assets/index-DKvKsj6c.js +442 -0
- package/dist/app/assets/{index-By-g8wiC.js → index-DTfS9vNi.js} +1 -1
- package/dist/app/assets/index-hVLQwLRj.js +1 -0
- package/dist/app/assets/index.es-D0L4_L8o.js +106 -0
- package/dist/app/index.html +1 -1
- package/dist/package_load_worker.mjs +20 -1
- package/dist/server.mjs +1033 -683
- package/package.json +3 -3
- package/dist/app/assets/MainPage-DrczCw4J.js +0 -2
- package/dist/app/assets/MaterializationsPage-BFLHLEuk.js +0 -1
- package/dist/app/assets/ModelPage-CFnfQ6BL.js +0 -1
- package/dist/app/assets/PackagePage-DHsVf_mP.js +0 -1
- package/dist/app/assets/RouteError-CHq8ubhy.js +0 -1
- package/dist/app/assets/ThemeEditorPage-B2y8Y64Y.js +0 -1
- package/dist/app/assets/index-BVv6KQ93.js +0 -557
- package/dist/app/assets/index-Bqrhk3ff.js +0 -2
- package/dist/app/assets/index-CawCwLK3.js +0 -1774
package/dist/server.mjs
CHANGED
|
@@ -176443,6 +176443,11 @@ function internalErrorToHttpError(error) {
|
|
|
176443
176443
|
return httpError(409, error.message);
|
|
176444
176444
|
} else if (error instanceof InvalidStateTransitionError) {
|
|
176445
176445
|
return httpError(409, error.message);
|
|
176446
|
+
} else if (error instanceof WriteConflictError) {
|
|
176447
|
+
return httpError(409, error.message);
|
|
176448
|
+
} else if (error instanceof WriteRolledBackError) {
|
|
176449
|
+
logInternalFailure("Dashboard write rolled back", error, "warn");
|
|
176450
|
+
return httpError(500, error.message);
|
|
176446
176451
|
} else if (error instanceof ServiceUnavailableError) {
|
|
176447
176452
|
return httpError(503, error.message);
|
|
176448
176453
|
} else if (error instanceof PayloadTooLargeError) {
|
|
@@ -176466,7 +176471,7 @@ function httpError(code, message, reason) {
|
|
|
176466
176471
|
}
|
|
176467
176472
|
};
|
|
176468
176473
|
}
|
|
176469
|
-
var GENERIC_INTERNAL_MESSAGE = "Internal server error.", GENERIC_UPSTREAM_MESSAGE = "Upstream connection error.", MAX_LOGGED_DETAIL_CHARS = 2000, NotImplementedError, BadRequestError, InvalidArgumentError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, TableNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, MaterializationEligibilityError, PublisherConfigError, FrozenConfigError, AccessDeniedError, NotQueryableError, MaterializationNotFoundError, MaterializationConflictError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
|
|
176474
|
+
var GENERIC_INTERNAL_MESSAGE = "Internal server error.", GENERIC_UPSTREAM_MESSAGE = "Upstream connection error.", MAX_LOGGED_DETAIL_CHARS = 2000, NotImplementedError, BadRequestError, InvalidArgumentError, CompileRefusedError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, TableNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, MaterializationEligibilityError, PublisherConfigError, FrozenConfigError, AccessDeniedError, NotQueryableError, MaterializationNotFoundError, MaterializationConflictError, WriteConflictError, WriteRolledBackError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
|
|
176470
176475
|
var init_errors = __esm(() => {
|
|
176471
176476
|
init_constants();
|
|
176472
176477
|
init_logger();
|
|
@@ -176482,6 +176487,8 @@ var init_errors = __esm(() => {
|
|
|
176482
176487
|
};
|
|
176483
176488
|
InvalidArgumentError = class InvalidArgumentError extends BadRequestError {
|
|
176484
176489
|
};
|
|
176490
|
+
CompileRefusedError = class CompileRefusedError extends BadRequestError {
|
|
176491
|
+
};
|
|
176485
176492
|
EnvironmentNotFoundError = class EnvironmentNotFoundError extends Error {
|
|
176486
176493
|
constructor(message) {
|
|
176487
176494
|
super(message);
|
|
@@ -176581,6 +176588,18 @@ var init_errors = __esm(() => {
|
|
|
176581
176588
|
super(message);
|
|
176582
176589
|
}
|
|
176583
176590
|
};
|
|
176591
|
+
WriteConflictError = class WriteConflictError extends Error {
|
|
176592
|
+
constructor(message) {
|
|
176593
|
+
super(message);
|
|
176594
|
+
this.name = "WriteConflictError";
|
|
176595
|
+
}
|
|
176596
|
+
};
|
|
176597
|
+
WriteRolledBackError = class WriteRolledBackError extends Error {
|
|
176598
|
+
constructor(message) {
|
|
176599
|
+
super(message);
|
|
176600
|
+
this.name = "WriteRolledBackError";
|
|
176601
|
+
}
|
|
176602
|
+
};
|
|
176584
176603
|
InvalidStateTransitionError = class InvalidStateTransitionError extends Error {
|
|
176585
176604
|
constructor(message) {
|
|
176586
176605
|
super(message);
|
|
@@ -176654,6 +176673,65 @@ var init_query_cap_metrics = __esm(() => {
|
|
|
176654
176673
|
init_config();
|
|
176655
176674
|
});
|
|
176656
176675
|
|
|
176676
|
+
// src/path_safety.ts
|
|
176677
|
+
import * as path2 from "path";
|
|
176678
|
+
function assertSafePackageName(packageName) {
|
|
176679
|
+
if (typeof packageName !== "string" || !SAFE_NAME_RE.test(packageName)) {
|
|
176680
|
+
throw new BadRequestError(`Invalid package name: must be 1-255 characters of letters, digits, "-", "_", or "." and must not start with "."`);
|
|
176681
|
+
}
|
|
176682
|
+
}
|
|
176683
|
+
function assertSafeRelativeModelPath(modelPath) {
|
|
176684
|
+
if (typeof modelPath !== "string" || modelPath.length === 0 || modelPath.length > MAX_MODEL_PATH_LEN || modelPath.includes("\x00") || modelPath.includes("\\") || path2.isAbsolute(modelPath) || modelPath.startsWith("/")) {
|
|
176685
|
+
throw new BadRequestError(`Invalid model path`);
|
|
176686
|
+
}
|
|
176687
|
+
const segments = modelPath.split("/");
|
|
176688
|
+
for (const segment of segments) {
|
|
176689
|
+
if (segment === "" || segment === "." || segment === "..") {
|
|
176690
|
+
throw new BadRequestError(`Invalid model path`);
|
|
176691
|
+
}
|
|
176692
|
+
if (segment.startsWith(".")) {
|
|
176693
|
+
throw new BadRequestError(`Invalid model path`);
|
|
176694
|
+
}
|
|
176695
|
+
}
|
|
176696
|
+
}
|
|
176697
|
+
function assertSafeEnvironmentPath(environmentPath) {
|
|
176698
|
+
if (typeof environmentPath !== "string") {
|
|
176699
|
+
throw new BadRequestError(`Invalid environment path: must be a string`);
|
|
176700
|
+
}
|
|
176701
|
+
if (environmentPath.length === 0 || environmentPath.length > MAX_ENVIRONMENT_PATH_LEN) {
|
|
176702
|
+
throw new BadRequestError(`Invalid environment path: bad length`);
|
|
176703
|
+
}
|
|
176704
|
+
if (environmentPath.indexOf("\x00") !== -1) {
|
|
176705
|
+
throw new BadRequestError(`Invalid environment path: contains NUL byte`);
|
|
176706
|
+
}
|
|
176707
|
+
if (environmentPath.indexOf("..") !== -1) {
|
|
176708
|
+
throw new BadRequestError(`Invalid environment path: contains ".." traversal segment`);
|
|
176709
|
+
}
|
|
176710
|
+
if (!SAFE_ENVIRONMENT_PATH_RE.test(environmentPath)) {
|
|
176711
|
+
throw new BadRequestError(`Invalid environment path: must be an absolute path of printable ASCII characters`);
|
|
176712
|
+
}
|
|
176713
|
+
}
|
|
176714
|
+
function safeJoinUnderRoot(root, ...segments) {
|
|
176715
|
+
const resolvedRoot = path2.resolve(root);
|
|
176716
|
+
const joined = path2.resolve(resolvedRoot, ...segments);
|
|
176717
|
+
const rootWithSep = resolvedRoot.endsWith(path2.sep) ? resolvedRoot : resolvedRoot + path2.sep;
|
|
176718
|
+
if (joined !== resolvedRoot && !joined.startsWith(rootWithSep)) {
|
|
176719
|
+
throw new BadRequestError(`Resolved path is outside of root`);
|
|
176720
|
+
}
|
|
176721
|
+
return joined;
|
|
176722
|
+
}
|
|
176723
|
+
var SAFE_NAME_RE, MAX_MODEL_PATH_LEN = 1024, SAFE_ENVIRONMENT_PATH_RE, MAX_ENVIRONMENT_PATH_LEN = 4096;
|
|
176724
|
+
var init_path_safety = __esm(() => {
|
|
176725
|
+
init_errors();
|
|
176726
|
+
SAFE_NAME_RE = /^(?!\.\.?$)(?!\.)[A-Za-z0-9._-]{1,255}$/;
|
|
176727
|
+
SAFE_ENVIRONMENT_PATH_RE = /^(?:\/|[A-Za-z]:[\\/])[\x20-\x7E]*$/;
|
|
176728
|
+
});
|
|
176729
|
+
|
|
176730
|
+
// src/pg_helpers.ts
|
|
176731
|
+
function redactPgSecrets(s) {
|
|
176732
|
+
return s.replace(/([a-z][a-z0-9+.-]*:\/\/[^:/?#\s]*):([^/\s]+)@/gi, "$1:***@").replace(/((?:postgres|postgresql):\/\/[^:/?#\s]*):([^@\s]+)@/gi, "$1:***@").replace(/password=('(?:\\.|[^'\\])*'|"[^"]*"|\S+)/gi, "password=***");
|
|
176733
|
+
}
|
|
176734
|
+
|
|
176657
176735
|
// ../../node_modules/delayed-stream/lib/delayed_stream.js
|
|
176658
176736
|
var require_delayed_stream = __commonJS((exports, module) => {
|
|
176659
176737
|
var Stream = __require("stream").Stream;
|
|
@@ -185494,11 +185572,11 @@ var require_mime_types3 = __commonJS((exports) => {
|
|
|
185494
185572
|
}
|
|
185495
185573
|
return exts[0];
|
|
185496
185574
|
}
|
|
185497
|
-
function lookup(
|
|
185498
|
-
if (!
|
|
185575
|
+
function lookup(path3) {
|
|
185576
|
+
if (!path3 || typeof path3 !== "string") {
|
|
185499
185577
|
return false;
|
|
185500
185578
|
}
|
|
185501
|
-
var extension2 = extname("x." +
|
|
185579
|
+
var extension2 = extname("x." + path3).toLowerCase().substr(1);
|
|
185502
185580
|
if (!extension2) {
|
|
185503
185581
|
return false;
|
|
185504
185582
|
}
|
|
@@ -185768,7 +185846,7 @@ var require_populate = __commonJS((exports, module) => {
|
|
|
185768
185846
|
var require_form_data = __commonJS((exports, module) => {
|
|
185769
185847
|
var CombinedStream = require_combined_stream();
|
|
185770
185848
|
var util3 = __require("util");
|
|
185771
|
-
var
|
|
185849
|
+
var path3 = __require("path");
|
|
185772
185850
|
var http = __require("http");
|
|
185773
185851
|
var https = __require("https");
|
|
185774
185852
|
var parseUrl = __require("url").parse;
|
|
@@ -185895,11 +185973,11 @@ var require_form_data = __commonJS((exports, module) => {
|
|
|
185895
185973
|
FormData2.prototype._getContentDisposition = function(value, options) {
|
|
185896
185974
|
var filename;
|
|
185897
185975
|
if (typeof options.filepath === "string") {
|
|
185898
|
-
filename =
|
|
185976
|
+
filename = path3.normalize(options.filepath).replace(/\\/g, "/");
|
|
185899
185977
|
} else if (options.filename || value && (value.name || value.path)) {
|
|
185900
|
-
filename =
|
|
185978
|
+
filename = path3.basename(options.filename || value && (value.name || value.path));
|
|
185901
185979
|
} else if (value && value.readable && hasOwn(value, "httpVersion")) {
|
|
185902
|
-
filename =
|
|
185980
|
+
filename = path3.basename(value.client._httpMessage.path || "");
|
|
185903
185981
|
}
|
|
185904
185982
|
if (filename) {
|
|
185905
185983
|
return 'filename="' + filename + '"';
|
|
@@ -186635,10 +186713,10 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186635
186713
|
function removeBrackets(key) {
|
|
186636
186714
|
return utils$1.endsWith(key, "[]") ? key.slice(0, -2) : key;
|
|
186637
186715
|
}
|
|
186638
|
-
function renderKey(
|
|
186639
|
-
if (!
|
|
186716
|
+
function renderKey(path3, key, dots) {
|
|
186717
|
+
if (!path3)
|
|
186640
186718
|
return key;
|
|
186641
|
-
return
|
|
186719
|
+
return path3.concat(key).map(function each(token, i) {
|
|
186642
186720
|
token = removeBrackets(token);
|
|
186643
186721
|
return !dots && i ? "[" + token + "]" : token;
|
|
186644
186722
|
}).join(dots ? "." : "");
|
|
@@ -186687,9 +186765,9 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186687
186765
|
}
|
|
186688
186766
|
return value;
|
|
186689
186767
|
}
|
|
186690
|
-
function defaultVisitor(value, key,
|
|
186768
|
+
function defaultVisitor(value, key, path3) {
|
|
186691
186769
|
let arr = value;
|
|
186692
|
-
if (value && !
|
|
186770
|
+
if (value && !path3 && typeof value === "object") {
|
|
186693
186771
|
if (utils$1.endsWith(key, "{}")) {
|
|
186694
186772
|
key = metaTokens ? key : key.slice(0, -2);
|
|
186695
186773
|
value = JSON.stringify(value);
|
|
@@ -186704,7 +186782,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186704
186782
|
if (isVisitable(value)) {
|
|
186705
186783
|
return true;
|
|
186706
186784
|
}
|
|
186707
|
-
formData.append(renderKey(
|
|
186785
|
+
formData.append(renderKey(path3, key, dots), convertValue(value));
|
|
186708
186786
|
return false;
|
|
186709
186787
|
}
|
|
186710
186788
|
const stack = [];
|
|
@@ -186713,17 +186791,17 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186713
186791
|
convertValue,
|
|
186714
186792
|
isVisitable
|
|
186715
186793
|
});
|
|
186716
|
-
function build(value,
|
|
186794
|
+
function build(value, path3) {
|
|
186717
186795
|
if (utils$1.isUndefined(value))
|
|
186718
186796
|
return;
|
|
186719
186797
|
if (stack.indexOf(value) !== -1) {
|
|
186720
|
-
throw Error("Circular reference detected in " +
|
|
186798
|
+
throw Error("Circular reference detected in " + path3.join("."));
|
|
186721
186799
|
}
|
|
186722
186800
|
stack.push(value);
|
|
186723
186801
|
utils$1.forEach(value, function each(el, key) {
|
|
186724
|
-
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key,
|
|
186802
|
+
const result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path3, exposedHelpers);
|
|
186725
186803
|
if (result === true) {
|
|
186726
|
-
build(el,
|
|
186804
|
+
build(el, path3 ? path3.concat(key) : [key]);
|
|
186727
186805
|
}
|
|
186728
186806
|
});
|
|
186729
186807
|
stack.pop();
|
|
@@ -186881,7 +186959,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186881
186959
|
};
|
|
186882
186960
|
function toURLEncodedForm(data, options) {
|
|
186883
186961
|
return toFormData(data, new platform.classes.URLSearchParams, {
|
|
186884
|
-
visitor: function(value, key,
|
|
186962
|
+
visitor: function(value, key, path3, helpers) {
|
|
186885
186963
|
if (platform.isNode && utils$1.isBuffer(value)) {
|
|
186886
186964
|
this.append(key, value.toString("base64"));
|
|
186887
186965
|
return false;
|
|
@@ -186909,12 +186987,12 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186909
186987
|
return obj;
|
|
186910
186988
|
}
|
|
186911
186989
|
function formDataToJSON(formData) {
|
|
186912
|
-
function buildPath(
|
|
186913
|
-
let name =
|
|
186990
|
+
function buildPath(path3, value, target, index) {
|
|
186991
|
+
let name = path3[index++];
|
|
186914
186992
|
if (name === "__proto__")
|
|
186915
186993
|
return true;
|
|
186916
186994
|
const isNumericKey = Number.isFinite(+name);
|
|
186917
|
-
const isLast = index >=
|
|
186995
|
+
const isLast = index >= path3.length;
|
|
186918
186996
|
name = !name && utils$1.isArray(target) ? target.length : name;
|
|
186919
186997
|
if (isLast) {
|
|
186920
186998
|
if (utils$1.hasOwnProp(target, name)) {
|
|
@@ -186927,7 +187005,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
186927
187005
|
if (!target[name] || !utils$1.isObject(target[name])) {
|
|
186928
187006
|
target[name] = [];
|
|
186929
187007
|
}
|
|
186930
|
-
const result = buildPath(
|
|
187008
|
+
const result = buildPath(path3, value, target[name], index);
|
|
186931
187009
|
if (result && utils$1.isArray(target[name])) {
|
|
186932
187010
|
target[name] = arrayToObject(target[name]);
|
|
186933
187011
|
}
|
|
@@ -187336,10 +187414,10 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
187336
187414
|
utils$1.inherits(CanceledError, AxiosError, {
|
|
187337
187415
|
__CANCEL__: true
|
|
187338
187416
|
});
|
|
187339
|
-
function settle(
|
|
187417
|
+
function settle(resolve2, reject, response) {
|
|
187340
187418
|
const validateStatus = response.config.validateStatus;
|
|
187341
187419
|
if (!response.status || !validateStatus || validateStatus(response.status)) {
|
|
187342
|
-
|
|
187420
|
+
resolve2(response);
|
|
187343
187421
|
} else {
|
|
187344
187422
|
reject(new AxiosError("Request failed with status code " + response.status, [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, response.request, response));
|
|
187345
187423
|
}
|
|
@@ -187836,7 +187914,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
187836
187914
|
}
|
|
187837
187915
|
var isHttpAdapterSupported = typeof process !== "undefined" && utils$1.kindOf(process) === "process";
|
|
187838
187916
|
var wrapAsync = (asyncExecutor) => {
|
|
187839
|
-
return new Promise((
|
|
187917
|
+
return new Promise((resolve2, reject) => {
|
|
187840
187918
|
let onDone;
|
|
187841
187919
|
let isDone;
|
|
187842
187920
|
const done = (value, isRejected) => {
|
|
@@ -187847,7 +187925,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
187847
187925
|
};
|
|
187848
187926
|
const _resolve = (value) => {
|
|
187849
187927
|
done(value);
|
|
187850
|
-
|
|
187928
|
+
resolve2(value);
|
|
187851
187929
|
};
|
|
187852
187930
|
const _reject = (reason) => {
|
|
187853
187931
|
done(reason, true);
|
|
@@ -187867,7 +187945,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
187867
187945
|
};
|
|
187868
187946
|
var buildAddressEntry = (address, family) => resolveFamily(utils$1.isObject(address) ? address : { address, family });
|
|
187869
187947
|
var httpAdapter = isHttpAdapterSupported && function httpAdapter2(config) {
|
|
187870
|
-
return wrapAsync(async function dispatchHttpRequest(
|
|
187948
|
+
return wrapAsync(async function dispatchHttpRequest(resolve2, reject, onDone) {
|
|
187871
187949
|
let { data, lookup, family } = config;
|
|
187872
187950
|
const { responseType, responseEncoding } = config;
|
|
187873
187951
|
const method = config.method.toUpperCase();
|
|
@@ -187926,7 +188004,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
187926
188004
|
}
|
|
187927
188005
|
let convertedData;
|
|
187928
188006
|
if (method !== "GET") {
|
|
187929
|
-
return settle(
|
|
188007
|
+
return settle(resolve2, reject, {
|
|
187930
188008
|
status: 405,
|
|
187931
188009
|
statusText: "method not allowed",
|
|
187932
188010
|
headers: {},
|
|
@@ -187948,7 +188026,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
187948
188026
|
} else if (responseType === "stream") {
|
|
187949
188027
|
convertedData = stream__default["default"].Readable.from(convertedData);
|
|
187950
188028
|
}
|
|
187951
|
-
return settle(
|
|
188029
|
+
return settle(resolve2, reject, {
|
|
187952
188030
|
data: convertedData,
|
|
187953
188031
|
status: 200,
|
|
187954
188032
|
statusText: "OK",
|
|
@@ -188028,9 +188106,9 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188028
188106
|
auth = urlUsername + ":" + urlPassword;
|
|
188029
188107
|
}
|
|
188030
188108
|
auth && headers.delete("authorization");
|
|
188031
|
-
let
|
|
188109
|
+
let path3;
|
|
188032
188110
|
try {
|
|
188033
|
-
|
|
188111
|
+
path3 = buildURL(parsed.pathname + parsed.search, config.params, config.paramsSerializer).replace(/^\?/, "");
|
|
188034
188112
|
} catch (err) {
|
|
188035
188113
|
const customErr = new Error(err.message);
|
|
188036
188114
|
customErr.config = config;
|
|
@@ -188040,7 +188118,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188040
188118
|
}
|
|
188041
188119
|
headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false);
|
|
188042
188120
|
const options = {
|
|
188043
|
-
path:
|
|
188121
|
+
path: path3,
|
|
188044
188122
|
method,
|
|
188045
188123
|
headers: headers.toJSON(),
|
|
188046
188124
|
agents: { http: config.httpAgent, https: config.httpsAgent },
|
|
@@ -188134,7 +188212,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188134
188212
|
};
|
|
188135
188213
|
if (responseType === "stream") {
|
|
188136
188214
|
response.data = responseStream;
|
|
188137
|
-
settle(
|
|
188215
|
+
settle(resolve2, reject, response);
|
|
188138
188216
|
} else {
|
|
188139
188217
|
const responseBuffer = [];
|
|
188140
188218
|
let totalResponseBytes = 0;
|
|
@@ -188173,7 +188251,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188173
188251
|
} catch (err) {
|
|
188174
188252
|
return reject(AxiosError.from(err, null, config, response.request, response));
|
|
188175
188253
|
}
|
|
188176
|
-
settle(
|
|
188254
|
+
settle(resolve2, reject, response);
|
|
188177
188255
|
});
|
|
188178
188256
|
}
|
|
188179
188257
|
emitter.once("abort", (err) => {
|
|
@@ -188237,10 +188315,10 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188237
188315
|
return origin2.protocol === url2.protocol && origin2.host === url2.host && (isMSIE || origin2.port === url2.port);
|
|
188238
188316
|
})(new URL(platform.origin), platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)) : () => true;
|
|
188239
188317
|
var cookies = platform.hasStandardBrowserEnv ? {
|
|
188240
|
-
write(name, value, expires,
|
|
188318
|
+
write(name, value, expires, path3, domain, secure) {
|
|
188241
188319
|
const cookie = [name + "=" + encodeURIComponent(value)];
|
|
188242
188320
|
utils$1.isNumber(expires) && cookie.push("expires=" + new Date(expires).toGMTString());
|
|
188243
|
-
utils$1.isString(
|
|
188321
|
+
utils$1.isString(path3) && cookie.push("path=" + path3);
|
|
188244
188322
|
utils$1.isString(domain) && cookie.push("domain=" + domain);
|
|
188245
188323
|
secure === true && cookie.push("secure");
|
|
188246
188324
|
document.cookie = cookie.join("; ");
|
|
@@ -188371,7 +188449,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188371
188449
|
};
|
|
188372
188450
|
var isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
|
|
188373
188451
|
var xhrAdapter = isXHRAdapterSupported && function(config) {
|
|
188374
|
-
return new Promise(function dispatchXhrRequest(
|
|
188452
|
+
return new Promise(function dispatchXhrRequest(resolve2, reject) {
|
|
188375
188453
|
const _config = resolveConfig(config);
|
|
188376
188454
|
let requestData = _config.data;
|
|
188377
188455
|
const requestHeaders = AxiosHeaders$1.from(_config.headers).normalize();
|
|
@@ -188403,7 +188481,7 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188403
188481
|
request
|
|
188404
188482
|
};
|
|
188405
188483
|
settle(function _resolve(value) {
|
|
188406
|
-
|
|
188484
|
+
resolve2(value);
|
|
188407
188485
|
done();
|
|
188408
188486
|
}, function _reject(err) {
|
|
188409
188487
|
reject(err);
|
|
@@ -188754,8 +188832,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
188754
188832
|
responseType = responseType || "text";
|
|
188755
188833
|
let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || "text"](response, config);
|
|
188756
188834
|
!isStreamResponse && unsubscribe && unsubscribe();
|
|
188757
|
-
return await new Promise((
|
|
188758
|
-
settle(
|
|
188835
|
+
return await new Promise((resolve2, reject) => {
|
|
188836
|
+
settle(resolve2, reject, {
|
|
188759
188837
|
data: responseData,
|
|
188760
188838
|
headers: AxiosHeaders$1.from(response.headers),
|
|
188761
188839
|
status: response.status,
|
|
@@ -189095,8 +189173,8 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
189095
189173
|
throw new TypeError("executor must be a function.");
|
|
189096
189174
|
}
|
|
189097
189175
|
let resolvePromise;
|
|
189098
|
-
this.promise = new Promise(function promiseExecutor(
|
|
189099
|
-
resolvePromise =
|
|
189176
|
+
this.promise = new Promise(function promiseExecutor(resolve2) {
|
|
189177
|
+
resolvePromise = resolve2;
|
|
189100
189178
|
});
|
|
189101
189179
|
const token = this;
|
|
189102
189180
|
this.promise.then((cancel) => {
|
|
@@ -189110,9 +189188,9 @@ var require_axios = __commonJS((exports, module) => {
|
|
|
189110
189188
|
});
|
|
189111
189189
|
this.promise.then = (onfulfilled) => {
|
|
189112
189190
|
let _resolve;
|
|
189113
|
-
const promise = new Promise((
|
|
189114
|
-
token.subscribe(
|
|
189115
|
-
_resolve =
|
|
189191
|
+
const promise = new Promise((resolve2) => {
|
|
189192
|
+
token.subscribe(resolve2);
|
|
189193
|
+
_resolve = resolve2;
|
|
189116
189194
|
}).then(onfulfilled);
|
|
189117
189195
|
promise.cancel = function reject() {
|
|
189118
189196
|
token.unsubscribe(_resolve);
|
|
@@ -190420,12 +190498,12 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190420
190498
|
};
|
|
190421
190499
|
var ModelsApiAxiosParamCreator = function(configuration) {
|
|
190422
190500
|
return {
|
|
190423
|
-
compileModelSource: async (projectName, packageName,
|
|
190501
|
+
compileModelSource: async (projectName, packageName, path3, compileRequest, options = {}) => {
|
|
190424
190502
|
(0, common_1.assertParamExists)("compileModelSource", "projectName", projectName);
|
|
190425
190503
|
(0, common_1.assertParamExists)("compileModelSource", "packageName", packageName);
|
|
190426
|
-
(0, common_1.assertParamExists)("compileModelSource", "path",
|
|
190504
|
+
(0, common_1.assertParamExists)("compileModelSource", "path", path3);
|
|
190427
190505
|
(0, common_1.assertParamExists)("compileModelSource", "compileRequest", compileRequest);
|
|
190428
|
-
const localVarPath = `/projects/{projectName}/packages/{packageName}/models/{path}/compile`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
190506
|
+
const localVarPath = `/projects/{projectName}/packages/{packageName}/models/{path}/compile`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(path3)));
|
|
190429
190507
|
const localVarUrlObj = new URL(localVarPath, common_1.DUMMY_BASE_URL);
|
|
190430
190508
|
let baseOptions;
|
|
190431
190509
|
if (configuration) {
|
|
@@ -190444,12 +190522,12 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190444
190522
|
options: localVarRequestOptions
|
|
190445
190523
|
};
|
|
190446
190524
|
},
|
|
190447
|
-
executeQueryModel: async (projectName, packageName,
|
|
190525
|
+
executeQueryModel: async (projectName, packageName, path3, queryRequest, options = {}) => {
|
|
190448
190526
|
(0, common_1.assertParamExists)("executeQueryModel", "projectName", projectName);
|
|
190449
190527
|
(0, common_1.assertParamExists)("executeQueryModel", "packageName", packageName);
|
|
190450
|
-
(0, common_1.assertParamExists)("executeQueryModel", "path",
|
|
190528
|
+
(0, common_1.assertParamExists)("executeQueryModel", "path", path3);
|
|
190451
190529
|
(0, common_1.assertParamExists)("executeQueryModel", "queryRequest", queryRequest);
|
|
190452
|
-
const localVarPath = `/projects/{projectName}/packages/{packageName}/models/{path}/query`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
190530
|
+
const localVarPath = `/projects/{projectName}/packages/{packageName}/models/{path}/query`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(path3)));
|
|
190453
190531
|
const localVarUrlObj = new URL(localVarPath, common_1.DUMMY_BASE_URL);
|
|
190454
190532
|
let baseOptions;
|
|
190455
190533
|
if (configuration) {
|
|
@@ -190468,11 +190546,11 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190468
190546
|
options: localVarRequestOptions
|
|
190469
190547
|
};
|
|
190470
190548
|
},
|
|
190471
|
-
getModel: async (projectName, packageName,
|
|
190549
|
+
getModel: async (projectName, packageName, path3, versionId, options = {}) => {
|
|
190472
190550
|
(0, common_1.assertParamExists)("getModel", "projectName", projectName);
|
|
190473
190551
|
(0, common_1.assertParamExists)("getModel", "packageName", packageName);
|
|
190474
|
-
(0, common_1.assertParamExists)("getModel", "path",
|
|
190475
|
-
const localVarPath = `/projects/{projectName}/packages/{packageName}/models/{path}`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
190552
|
+
(0, common_1.assertParamExists)("getModel", "path", path3);
|
|
190553
|
+
const localVarPath = `/projects/{projectName}/packages/{packageName}/models/{path}`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(path3)));
|
|
190476
190554
|
const localVarUrlObj = new URL(localVarPath, common_1.DUMMY_BASE_URL);
|
|
190477
190555
|
let baseOptions;
|
|
190478
190556
|
if (configuration) {
|
|
@@ -190521,23 +190599,23 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190521
190599
|
var ModelsApiFp = function(configuration) {
|
|
190522
190600
|
const localVarAxiosParamCreator = (0, exports.ModelsApiAxiosParamCreator)(configuration);
|
|
190523
190601
|
return {
|
|
190524
|
-
async compileModelSource(projectName, packageName,
|
|
190602
|
+
async compileModelSource(projectName, packageName, path3, compileRequest, options) {
|
|
190525
190603
|
var _a, _b, _c;
|
|
190526
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.compileModelSource(projectName, packageName,
|
|
190604
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.compileModelSource(projectName, packageName, path3, compileRequest, options);
|
|
190527
190605
|
const localVarOperationServerIndex = (_a = configuration === null || configuration === undefined ? undefined : configuration.serverIndex) !== null && _a !== undefined ? _a : 0;
|
|
190528
190606
|
const localVarOperationServerBasePath = (_c = (_b = base_1.operationServerMap["ModelsApi.compileModelSource"]) === null || _b === undefined ? undefined : _b[localVarOperationServerIndex]) === null || _c === undefined ? undefined : _c.url;
|
|
190529
190607
|
return (axios, basePath) => (0, common_1.createRequestFunction)(localVarAxiosArgs, axios_1.default, base_1.BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
|
190530
190608
|
},
|
|
190531
|
-
async executeQueryModel(projectName, packageName,
|
|
190609
|
+
async executeQueryModel(projectName, packageName, path3, queryRequest, options) {
|
|
190532
190610
|
var _a, _b, _c;
|
|
190533
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.executeQueryModel(projectName, packageName,
|
|
190611
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.executeQueryModel(projectName, packageName, path3, queryRequest, options);
|
|
190534
190612
|
const localVarOperationServerIndex = (_a = configuration === null || configuration === undefined ? undefined : configuration.serverIndex) !== null && _a !== undefined ? _a : 0;
|
|
190535
190613
|
const localVarOperationServerBasePath = (_c = (_b = base_1.operationServerMap["ModelsApi.executeQueryModel"]) === null || _b === undefined ? undefined : _b[localVarOperationServerIndex]) === null || _c === undefined ? undefined : _c.url;
|
|
190536
190614
|
return (axios, basePath) => (0, common_1.createRequestFunction)(localVarAxiosArgs, axios_1.default, base_1.BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
|
190537
190615
|
},
|
|
190538
|
-
async getModel(projectName, packageName,
|
|
190616
|
+
async getModel(projectName, packageName, path3, versionId, options) {
|
|
190539
190617
|
var _a, _b, _c;
|
|
190540
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.getModel(projectName, packageName,
|
|
190618
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.getModel(projectName, packageName, path3, versionId, options);
|
|
190541
190619
|
const localVarOperationServerIndex = (_a = configuration === null || configuration === undefined ? undefined : configuration.serverIndex) !== null && _a !== undefined ? _a : 0;
|
|
190542
190620
|
const localVarOperationServerBasePath = (_c = (_b = base_1.operationServerMap["ModelsApi.getModel"]) === null || _b === undefined ? undefined : _b[localVarOperationServerIndex]) === null || _c === undefined ? undefined : _c.url;
|
|
190543
190621
|
return (axios, basePath) => (0, common_1.createRequestFunction)(localVarAxiosArgs, axios_1.default, base_1.BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
|
@@ -190555,14 +190633,14 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190555
190633
|
var ModelsApiFactory = function(configuration, basePath, axios) {
|
|
190556
190634
|
const localVarFp = (0, exports.ModelsApiFp)(configuration);
|
|
190557
190635
|
return {
|
|
190558
|
-
compileModelSource(projectName, packageName,
|
|
190559
|
-
return localVarFp.compileModelSource(projectName, packageName,
|
|
190636
|
+
compileModelSource(projectName, packageName, path3, compileRequest, options) {
|
|
190637
|
+
return localVarFp.compileModelSource(projectName, packageName, path3, compileRequest, options).then((request) => request(axios, basePath));
|
|
190560
190638
|
},
|
|
190561
|
-
executeQueryModel(projectName, packageName,
|
|
190562
|
-
return localVarFp.executeQueryModel(projectName, packageName,
|
|
190639
|
+
executeQueryModel(projectName, packageName, path3, queryRequest, options) {
|
|
190640
|
+
return localVarFp.executeQueryModel(projectName, packageName, path3, queryRequest, options).then((request) => request(axios, basePath));
|
|
190563
190641
|
},
|
|
190564
|
-
getModel(projectName, packageName,
|
|
190565
|
-
return localVarFp.getModel(projectName, packageName,
|
|
190642
|
+
getModel(projectName, packageName, path3, versionId, options) {
|
|
190643
|
+
return localVarFp.getModel(projectName, packageName, path3, versionId, options).then((request) => request(axios, basePath));
|
|
190566
190644
|
},
|
|
190567
190645
|
listModels(projectName, packageName, versionId, options) {
|
|
190568
190646
|
return localVarFp.listModels(projectName, packageName, versionId, options).then((request) => request(axios, basePath));
|
|
@@ -190572,14 +190650,14 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190572
190650
|
exports.ModelsApiFactory = ModelsApiFactory;
|
|
190573
190651
|
|
|
190574
190652
|
class ModelsApi extends base_1.BaseAPI {
|
|
190575
|
-
compileModelSource(projectName, packageName,
|
|
190576
|
-
return (0, exports.ModelsApiFp)(this.configuration).compileModelSource(projectName, packageName,
|
|
190653
|
+
compileModelSource(projectName, packageName, path3, compileRequest, options) {
|
|
190654
|
+
return (0, exports.ModelsApiFp)(this.configuration).compileModelSource(projectName, packageName, path3, compileRequest, options).then((request) => request(this.axios, this.basePath));
|
|
190577
190655
|
}
|
|
190578
|
-
executeQueryModel(projectName, packageName,
|
|
190579
|
-
return (0, exports.ModelsApiFp)(this.configuration).executeQueryModel(projectName, packageName,
|
|
190656
|
+
executeQueryModel(projectName, packageName, path3, queryRequest, options) {
|
|
190657
|
+
return (0, exports.ModelsApiFp)(this.configuration).executeQueryModel(projectName, packageName, path3, queryRequest, options).then((request) => request(this.axios, this.basePath));
|
|
190580
190658
|
}
|
|
190581
|
-
getModel(projectName, packageName,
|
|
190582
|
-
return (0, exports.ModelsApiFp)(this.configuration).getModel(projectName, packageName,
|
|
190659
|
+
getModel(projectName, packageName, path3, versionId, options) {
|
|
190660
|
+
return (0, exports.ModelsApiFp)(this.configuration).getModel(projectName, packageName, path3, versionId, options).then((request) => request(this.axios, this.basePath));
|
|
190583
190661
|
}
|
|
190584
190662
|
listModels(projectName, packageName, versionId, options) {
|
|
190585
190663
|
return (0, exports.ModelsApiFp)(this.configuration).listModels(projectName, packageName, versionId, options).then((request) => request(this.axios, this.basePath));
|
|
@@ -190588,12 +190666,12 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190588
190666
|
exports.ModelsApi = ModelsApi;
|
|
190589
190667
|
var NotebooksApiAxiosParamCreator = function(configuration) {
|
|
190590
190668
|
return {
|
|
190591
|
-
executeNotebookCell: async (projectName, packageName,
|
|
190669
|
+
executeNotebookCell: async (projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options = {}) => {
|
|
190592
190670
|
(0, common_1.assertParamExists)("executeNotebookCell", "projectName", projectName);
|
|
190593
190671
|
(0, common_1.assertParamExists)("executeNotebookCell", "packageName", packageName);
|
|
190594
|
-
(0, common_1.assertParamExists)("executeNotebookCell", "path",
|
|
190672
|
+
(0, common_1.assertParamExists)("executeNotebookCell", "path", path3);
|
|
190595
190673
|
(0, common_1.assertParamExists)("executeNotebookCell", "cellIndex", cellIndex);
|
|
190596
|
-
const localVarPath = `/projects/{projectName}/packages/{packageName}/notebooks/{path}/cells/{cellIndex}`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
190674
|
+
const localVarPath = `/projects/{projectName}/packages/{packageName}/notebooks/{path}/cells/{cellIndex}`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(path3))).replace(`{${"cellIndex"}}`, encodeURIComponent(String(cellIndex)));
|
|
190597
190675
|
const localVarUrlObj = new URL(localVarPath, common_1.DUMMY_BASE_URL);
|
|
190598
190676
|
let baseOptions;
|
|
190599
190677
|
if (configuration) {
|
|
@@ -190619,11 +190697,11 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190619
190697
|
options: localVarRequestOptions
|
|
190620
190698
|
};
|
|
190621
190699
|
},
|
|
190622
|
-
getNotebook: async (projectName, packageName,
|
|
190700
|
+
getNotebook: async (projectName, packageName, path3, versionId, options = {}) => {
|
|
190623
190701
|
(0, common_1.assertParamExists)("getNotebook", "projectName", projectName);
|
|
190624
190702
|
(0, common_1.assertParamExists)("getNotebook", "packageName", packageName);
|
|
190625
|
-
(0, common_1.assertParamExists)("getNotebook", "path",
|
|
190626
|
-
const localVarPath = `/projects/{projectName}/packages/{packageName}/notebooks/{path}`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(
|
|
190703
|
+
(0, common_1.assertParamExists)("getNotebook", "path", path3);
|
|
190704
|
+
const localVarPath = `/projects/{projectName}/packages/{packageName}/notebooks/{path}`.replace(`{${"projectName"}}`, encodeURIComponent(String(projectName))).replace(`{${"packageName"}}`, encodeURIComponent(String(packageName))).replace(`{${"path"}}`, encodeURIComponent(String(path3)));
|
|
190627
190705
|
const localVarUrlObj = new URL(localVarPath, common_1.DUMMY_BASE_URL);
|
|
190628
190706
|
let baseOptions;
|
|
190629
190707
|
if (configuration) {
|
|
@@ -190672,16 +190750,16 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190672
190750
|
var NotebooksApiFp = function(configuration) {
|
|
190673
190751
|
const localVarAxiosParamCreator = (0, exports.NotebooksApiAxiosParamCreator)(configuration);
|
|
190674
190752
|
return {
|
|
190675
|
-
async executeNotebookCell(projectName, packageName,
|
|
190753
|
+
async executeNotebookCell(projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options) {
|
|
190676
190754
|
var _a, _b, _c;
|
|
190677
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.executeNotebookCell(projectName, packageName,
|
|
190755
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.executeNotebookCell(projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options);
|
|
190678
190756
|
const localVarOperationServerIndex = (_a = configuration === null || configuration === undefined ? undefined : configuration.serverIndex) !== null && _a !== undefined ? _a : 0;
|
|
190679
190757
|
const localVarOperationServerBasePath = (_c = (_b = base_1.operationServerMap["NotebooksApi.executeNotebookCell"]) === null || _b === undefined ? undefined : _b[localVarOperationServerIndex]) === null || _c === undefined ? undefined : _c.url;
|
|
190680
190758
|
return (axios, basePath) => (0, common_1.createRequestFunction)(localVarAxiosArgs, axios_1.default, base_1.BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
|
190681
190759
|
},
|
|
190682
|
-
async getNotebook(projectName, packageName,
|
|
190760
|
+
async getNotebook(projectName, packageName, path3, versionId, options) {
|
|
190683
190761
|
var _a, _b, _c;
|
|
190684
|
-
const localVarAxiosArgs = await localVarAxiosParamCreator.getNotebook(projectName, packageName,
|
|
190762
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.getNotebook(projectName, packageName, path3, versionId, options);
|
|
190685
190763
|
const localVarOperationServerIndex = (_a = configuration === null || configuration === undefined ? undefined : configuration.serverIndex) !== null && _a !== undefined ? _a : 0;
|
|
190686
190764
|
const localVarOperationServerBasePath = (_c = (_b = base_1.operationServerMap["NotebooksApi.getNotebook"]) === null || _b === undefined ? undefined : _b[localVarOperationServerIndex]) === null || _c === undefined ? undefined : _c.url;
|
|
190687
190765
|
return (axios, basePath) => (0, common_1.createRequestFunction)(localVarAxiosArgs, axios_1.default, base_1.BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
|
|
@@ -190699,11 +190777,11 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190699
190777
|
var NotebooksApiFactory = function(configuration, basePath, axios) {
|
|
190700
190778
|
const localVarFp = (0, exports.NotebooksApiFp)(configuration);
|
|
190701
190779
|
return {
|
|
190702
|
-
executeNotebookCell(projectName, packageName,
|
|
190703
|
-
return localVarFp.executeNotebookCell(projectName, packageName,
|
|
190780
|
+
executeNotebookCell(projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options) {
|
|
190781
|
+
return localVarFp.executeNotebookCell(projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options).then((request) => request(axios, basePath));
|
|
190704
190782
|
},
|
|
190705
|
-
getNotebook(projectName, packageName,
|
|
190706
|
-
return localVarFp.getNotebook(projectName, packageName,
|
|
190783
|
+
getNotebook(projectName, packageName, path3, versionId, options) {
|
|
190784
|
+
return localVarFp.getNotebook(projectName, packageName, path3, versionId, options).then((request) => request(axios, basePath));
|
|
190707
190785
|
},
|
|
190708
190786
|
listNotebooks(projectName, packageName, versionId, options) {
|
|
190709
190787
|
return localVarFp.listNotebooks(projectName, packageName, versionId, options).then((request) => request(axios, basePath));
|
|
@@ -190713,11 +190791,11 @@ var require_api2 = __commonJS((exports) => {
|
|
|
190713
190791
|
exports.NotebooksApiFactory = NotebooksApiFactory;
|
|
190714
190792
|
|
|
190715
190793
|
class NotebooksApi extends base_1.BaseAPI {
|
|
190716
|
-
executeNotebookCell(projectName, packageName,
|
|
190717
|
-
return (0, exports.NotebooksApiFp)(this.configuration).executeNotebookCell(projectName, packageName,
|
|
190794
|
+
executeNotebookCell(projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options) {
|
|
190795
|
+
return (0, exports.NotebooksApiFp)(this.configuration).executeNotebookCell(projectName, packageName, path3, cellIndex, versionId, filterParams, bypassFilters, options).then((request) => request(this.axios, this.basePath));
|
|
190718
190796
|
}
|
|
190719
|
-
getNotebook(projectName, packageName,
|
|
190720
|
-
return (0, exports.NotebooksApiFp)(this.configuration).getNotebook(projectName, packageName,
|
|
190797
|
+
getNotebook(projectName, packageName, path3, versionId, options) {
|
|
190798
|
+
return (0, exports.NotebooksApiFp)(this.configuration).getNotebook(projectName, packageName, path3, versionId, options).then((request) => request(this.axios, this.basePath));
|
|
190721
190799
|
}
|
|
190722
190800
|
listNotebooks(projectName, packageName, versionId, options) {
|
|
190723
190801
|
return (0, exports.NotebooksApiFp)(this.configuration).listNotebooks(projectName, packageName, versionId, options).then((request) => request(this.axios, this.basePath));
|
|
@@ -192019,10 +192097,10 @@ function isVisitable(thing) {
|
|
|
192019
192097
|
function removeBrackets(key) {
|
|
192020
192098
|
return utils_default.endsWith(key, "[]") ? key.slice(0, -2) : key;
|
|
192021
192099
|
}
|
|
192022
|
-
function renderKey(
|
|
192023
|
-
if (!
|
|
192100
|
+
function renderKey(path3, key, dots) {
|
|
192101
|
+
if (!path3)
|
|
192024
192102
|
return key;
|
|
192025
|
-
return
|
|
192103
|
+
return path3.concat(key).map(function each(token, i) {
|
|
192026
192104
|
token = removeBrackets(token);
|
|
192027
192105
|
return !dots && i ? "[" + token + "]" : token;
|
|
192028
192106
|
}).join(dots ? "." : "");
|
|
@@ -192068,9 +192146,9 @@ function toFormData(obj, formData, options) {
|
|
|
192068
192146
|
}
|
|
192069
192147
|
return value;
|
|
192070
192148
|
}
|
|
192071
|
-
function defaultVisitor(value, key,
|
|
192149
|
+
function defaultVisitor(value, key, path3) {
|
|
192072
192150
|
let arr = value;
|
|
192073
|
-
if (value && !
|
|
192151
|
+
if (value && !path3 && typeof value === "object") {
|
|
192074
192152
|
if (utils_default.endsWith(key, "{}")) {
|
|
192075
192153
|
key = metaTokens ? key : key.slice(0, -2);
|
|
192076
192154
|
value = JSON.stringify(value);
|
|
@@ -192085,7 +192163,7 @@ function toFormData(obj, formData, options) {
|
|
|
192085
192163
|
if (isVisitable(value)) {
|
|
192086
192164
|
return true;
|
|
192087
192165
|
}
|
|
192088
|
-
formData.append(renderKey(
|
|
192166
|
+
formData.append(renderKey(path3, key, dots), convertValue(value));
|
|
192089
192167
|
return false;
|
|
192090
192168
|
}
|
|
192091
192169
|
const stack = [];
|
|
@@ -192094,17 +192172,17 @@ function toFormData(obj, formData, options) {
|
|
|
192094
192172
|
convertValue,
|
|
192095
192173
|
isVisitable
|
|
192096
192174
|
});
|
|
192097
|
-
function build(value,
|
|
192175
|
+
function build(value, path3) {
|
|
192098
192176
|
if (utils_default.isUndefined(value))
|
|
192099
192177
|
return;
|
|
192100
192178
|
if (stack.indexOf(value) !== -1) {
|
|
192101
|
-
throw Error("Circular reference detected in " +
|
|
192179
|
+
throw Error("Circular reference detected in " + path3.join("."));
|
|
192102
192180
|
}
|
|
192103
192181
|
stack.push(value);
|
|
192104
192182
|
utils_default.forEach(value, function each(el, key) {
|
|
192105
|
-
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key,
|
|
192183
|
+
const result = !(utils_default.isUndefined(el) || el === null) && visitor.call(formData, el, utils_default.isString(key) ? key.trim() : key, path3, exposedHelpers);
|
|
192106
192184
|
if (result === true) {
|
|
192107
|
-
build(el,
|
|
192185
|
+
build(el, path3 ? path3.concat(key) : [key]);
|
|
192108
192186
|
}
|
|
192109
192187
|
});
|
|
192110
192188
|
stack.pop();
|
|
@@ -192320,7 +192398,7 @@ var init_platform = __esm(() => {
|
|
|
192320
192398
|
// ../../node_modules/axios/lib/helpers/toURLEncodedForm.js
|
|
192321
192399
|
function toURLEncodedForm(data, options) {
|
|
192322
192400
|
return toFormData_default(data, new platform_default.classes.URLSearchParams, {
|
|
192323
|
-
visitor: function(value, key,
|
|
192401
|
+
visitor: function(value, key, path3, helpers) {
|
|
192324
192402
|
if (platform_default.isNode && utils_default.isBuffer(value)) {
|
|
192325
192403
|
this.append(key, value.toString("base64"));
|
|
192326
192404
|
return false;
|
|
@@ -192355,12 +192433,12 @@ function arrayToObject(arr) {
|
|
|
192355
192433
|
return obj;
|
|
192356
192434
|
}
|
|
192357
192435
|
function formDataToJSON(formData) {
|
|
192358
|
-
function buildPath(
|
|
192359
|
-
let name =
|
|
192436
|
+
function buildPath(path3, value, target, index) {
|
|
192437
|
+
let name = path3[index++];
|
|
192360
192438
|
if (name === "__proto__")
|
|
192361
192439
|
return true;
|
|
192362
192440
|
const isNumericKey = Number.isFinite(+name);
|
|
192363
|
-
const isLast = index >=
|
|
192441
|
+
const isLast = index >= path3.length;
|
|
192364
192442
|
name = !name && utils_default.isArray(target) ? target.length : name;
|
|
192365
192443
|
if (isLast) {
|
|
192366
192444
|
if (utils_default.hasOwnProp(target, name)) {
|
|
@@ -192373,7 +192451,7 @@ function formDataToJSON(formData) {
|
|
|
192373
192451
|
if (!target[name] || !utils_default.isObject(target[name])) {
|
|
192374
192452
|
target[name] = [];
|
|
192375
192453
|
}
|
|
192376
|
-
const result = buildPath(
|
|
192454
|
+
const result = buildPath(path3, value, target[name], index);
|
|
192377
192455
|
if (result && utils_default.isArray(target[name])) {
|
|
192378
192456
|
target[name] = arrayToObject(target[name]);
|
|
192379
192457
|
}
|
|
@@ -192828,10 +192906,10 @@ var init_CanceledError = __esm(() => {
|
|
|
192828
192906
|
});
|
|
192829
192907
|
|
|
192830
192908
|
// ../../node_modules/axios/lib/core/settle.js
|
|
192831
|
-
function settle(
|
|
192909
|
+
function settle(resolve2, reject, response) {
|
|
192832
192910
|
const validateStatus2 = response.config.validateStatus;
|
|
192833
192911
|
if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
|
|
192834
|
-
|
|
192912
|
+
resolve2(response);
|
|
192835
192913
|
} else {
|
|
192836
192914
|
reject(new AxiosError_default("Request failed with status code " + response.status, [AxiosError_default.ERR_BAD_REQUEST, AxiosError_default.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, response.request, response));
|
|
192837
192915
|
}
|
|
@@ -193387,7 +193465,7 @@ var import_proxy_from_env, import_follow_redirects, zlibOptions, brotliOptions,
|
|
|
193387
193465
|
stream4.on("end", flush).on("error", flush);
|
|
193388
193466
|
return throttled;
|
|
193389
193467
|
}, isHttpAdapterSupported, wrapAsync = (asyncExecutor) => {
|
|
193390
|
-
return new Promise((
|
|
193468
|
+
return new Promise((resolve2, reject) => {
|
|
193391
193469
|
let onDone;
|
|
193392
193470
|
let isDone;
|
|
193393
193471
|
const done = (value, isRejected) => {
|
|
@@ -193398,7 +193476,7 @@ var import_proxy_from_env, import_follow_redirects, zlibOptions, brotliOptions,
|
|
|
193398
193476
|
};
|
|
193399
193477
|
const _resolve = (value) => {
|
|
193400
193478
|
done(value);
|
|
193401
|
-
|
|
193479
|
+
resolve2(value);
|
|
193402
193480
|
};
|
|
193403
193481
|
const _reject = (reason) => {
|
|
193404
193482
|
done(reason, true);
|
|
@@ -193450,7 +193528,7 @@ var init_http = __esm(() => {
|
|
|
193450
193528
|
});
|
|
193451
193529
|
isHttpAdapterSupported = typeof process !== "undefined" && utils_default.kindOf(process) === "process";
|
|
193452
193530
|
http_default = isHttpAdapterSupported && function httpAdapter(config) {
|
|
193453
|
-
return wrapAsync(async function dispatchHttpRequest(
|
|
193531
|
+
return wrapAsync(async function dispatchHttpRequest(resolve2, reject, onDone) {
|
|
193454
193532
|
let { data, lookup, family } = config;
|
|
193455
193533
|
const { responseType, responseEncoding } = config;
|
|
193456
193534
|
const method = config.method.toUpperCase();
|
|
@@ -193509,7 +193587,7 @@ var init_http = __esm(() => {
|
|
|
193509
193587
|
}
|
|
193510
193588
|
let convertedData;
|
|
193511
193589
|
if (method !== "GET") {
|
|
193512
|
-
return settle(
|
|
193590
|
+
return settle(resolve2, reject, {
|
|
193513
193591
|
status: 405,
|
|
193514
193592
|
statusText: "method not allowed",
|
|
193515
193593
|
headers: {},
|
|
@@ -193531,7 +193609,7 @@ var init_http = __esm(() => {
|
|
|
193531
193609
|
} else if (responseType === "stream") {
|
|
193532
193610
|
convertedData = stream3.Readable.from(convertedData);
|
|
193533
193611
|
}
|
|
193534
|
-
return settle(
|
|
193612
|
+
return settle(resolve2, reject, {
|
|
193535
193613
|
data: convertedData,
|
|
193536
193614
|
status: 200,
|
|
193537
193615
|
statusText: "OK",
|
|
@@ -193609,9 +193687,9 @@ var init_http = __esm(() => {
|
|
|
193609
193687
|
auth = urlUsername + ":" + urlPassword;
|
|
193610
193688
|
}
|
|
193611
193689
|
auth && headers.delete("authorization");
|
|
193612
|
-
let
|
|
193690
|
+
let path3;
|
|
193613
193691
|
try {
|
|
193614
|
-
|
|
193692
|
+
path3 = buildURL(parsed.pathname + parsed.search, config.params, config.paramsSerializer).replace(/^\?/, "");
|
|
193615
193693
|
} catch (err) {
|
|
193616
193694
|
const customErr = new Error(err.message);
|
|
193617
193695
|
customErr.config = config;
|
|
@@ -193621,7 +193699,7 @@ var init_http = __esm(() => {
|
|
|
193621
193699
|
}
|
|
193622
193700
|
headers.set("Accept-Encoding", "gzip, compress, deflate" + (isBrotliSupported ? ", br" : ""), false);
|
|
193623
193701
|
const options = {
|
|
193624
|
-
path:
|
|
193702
|
+
path: path3,
|
|
193625
193703
|
method,
|
|
193626
193704
|
headers: headers.toJSON(),
|
|
193627
193705
|
agents: { http: config.httpAgent, https: config.httpsAgent },
|
|
@@ -193715,7 +193793,7 @@ var init_http = __esm(() => {
|
|
|
193715
193793
|
};
|
|
193716
193794
|
if (responseType === "stream") {
|
|
193717
193795
|
response.data = responseStream;
|
|
193718
|
-
settle(
|
|
193796
|
+
settle(resolve2, reject, response);
|
|
193719
193797
|
} else {
|
|
193720
193798
|
const responseBuffer = [];
|
|
193721
193799
|
let totalResponseBytes = 0;
|
|
@@ -193754,7 +193832,7 @@ var init_http = __esm(() => {
|
|
|
193754
193832
|
} catch (err) {
|
|
193755
193833
|
return reject(AxiosError_default.from(err, null, config, response.request, response));
|
|
193756
193834
|
}
|
|
193757
|
-
settle(
|
|
193835
|
+
settle(resolve2, reject, response);
|
|
193758
193836
|
});
|
|
193759
193837
|
}
|
|
193760
193838
|
emitter.once("abort", (err) => {
|
|
@@ -193831,10 +193909,10 @@ var init_cookies = __esm(() => {
|
|
|
193831
193909
|
init_utils();
|
|
193832
193910
|
init_platform();
|
|
193833
193911
|
cookies_default = platform_default.hasStandardBrowserEnv ? {
|
|
193834
|
-
write(name, value, expires,
|
|
193912
|
+
write(name, value, expires, path3, domain, secure) {
|
|
193835
193913
|
const cookie = [name + "=" + encodeURIComponent(value)];
|
|
193836
193914
|
utils_default.isNumber(expires) && cookie.push("expires=" + new Date(expires).toGMTString());
|
|
193837
|
-
utils_default.isString(
|
|
193915
|
+
utils_default.isString(path3) && cookie.push("path=" + path3);
|
|
193838
193916
|
utils_default.isString(domain) && cookie.push("domain=" + domain);
|
|
193839
193917
|
secure === true && cookie.push("secure");
|
|
193840
193918
|
document.cookie = cookie.join("; ");
|
|
@@ -193997,7 +194075,7 @@ var init_xhr = __esm(() => {
|
|
|
193997
194075
|
init_resolveConfig();
|
|
193998
194076
|
isXHRAdapterSupported = typeof XMLHttpRequest !== "undefined";
|
|
193999
194077
|
xhr_default = isXHRAdapterSupported && function(config) {
|
|
194000
|
-
return new Promise(function dispatchXhrRequest(
|
|
194078
|
+
return new Promise(function dispatchXhrRequest(resolve2, reject) {
|
|
194001
194079
|
const _config = resolveConfig_default(config);
|
|
194002
194080
|
let requestData = _config.data;
|
|
194003
194081
|
const requestHeaders = AxiosHeaders_default.from(_config.headers).normalize();
|
|
@@ -194029,7 +194107,7 @@ var init_xhr = __esm(() => {
|
|
|
194029
194107
|
request
|
|
194030
194108
|
};
|
|
194031
194109
|
settle(function _resolve(value) {
|
|
194032
|
-
|
|
194110
|
+
resolve2(value);
|
|
194033
194111
|
done();
|
|
194034
194112
|
}, function _reject(err) {
|
|
194035
194113
|
reject(err);
|
|
@@ -194378,8 +194456,8 @@ var DEFAULT_CHUNK_SIZE, isFunction2, globalFetchAPI, ReadableStream2, TextEncode
|
|
|
194378
194456
|
responseType = responseType || "text";
|
|
194379
194457
|
let responseData = await resolvers[utils_default.findKey(resolvers, responseType) || "text"](response, config);
|
|
194380
194458
|
!isStreamResponse && unsubscribe && unsubscribe();
|
|
194381
|
-
return await new Promise((
|
|
194382
|
-
settle(
|
|
194459
|
+
return await new Promise((resolve2, reject) => {
|
|
194460
|
+
settle(resolve2, reject, {
|
|
194383
194461
|
data: responseData,
|
|
194384
194462
|
headers: AxiosHeaders_default.from(response.headers),
|
|
194385
194463
|
status: response.status,
|
|
@@ -194772,8 +194850,8 @@ class CancelToken {
|
|
|
194772
194850
|
throw new TypeError("executor must be a function.");
|
|
194773
194851
|
}
|
|
194774
194852
|
let resolvePromise;
|
|
194775
|
-
this.promise = new Promise(function promiseExecutor(
|
|
194776
|
-
resolvePromise =
|
|
194853
|
+
this.promise = new Promise(function promiseExecutor(resolve2) {
|
|
194854
|
+
resolvePromise = resolve2;
|
|
194777
194855
|
});
|
|
194778
194856
|
const token = this;
|
|
194779
194857
|
this.promise.then((cancel) => {
|
|
@@ -194787,9 +194865,9 @@ class CancelToken {
|
|
|
194787
194865
|
});
|
|
194788
194866
|
this.promise.then = (onfulfilled) => {
|
|
194789
194867
|
let _resolve;
|
|
194790
|
-
const promise = new Promise((
|
|
194791
|
-
token.subscribe(
|
|
194792
|
-
_resolve =
|
|
194868
|
+
const promise = new Promise((resolve2) => {
|
|
194869
|
+
token.subscribe(resolve2);
|
|
194870
|
+
_resolve = resolve2;
|
|
194793
194871
|
}).then(onfulfilled);
|
|
194794
194872
|
promise.cancel = function reject() {
|
|
194795
194873
|
token.unsubscribe(_resolve);
|
|
@@ -195075,65 +195153,6 @@ var init_ducklake_version = __esm(() => {
|
|
|
195075
195153
|
CATALOG_FORMAT_RE = /^(\d+)\.(\d+)(?:-([0-9A-Za-z.]+))?$/;
|
|
195076
195154
|
});
|
|
195077
195155
|
|
|
195078
|
-
// src/pg_helpers.ts
|
|
195079
|
-
function redactPgSecrets(s) {
|
|
195080
|
-
return s.replace(/([a-z][a-z0-9+.-]*:\/\/[^:/?#\s]*):([^/\s]+)@/gi, "$1:***@").replace(/((?:postgres|postgresql):\/\/[^:/?#\s]*):([^@\s]+)@/gi, "$1:***@").replace(/password=('[^']*'|"[^"]*"|\S+)/gi, "password=***");
|
|
195081
|
-
}
|
|
195082
|
-
|
|
195083
|
-
// src/path_safety.ts
|
|
195084
|
-
import * as path2 from "path";
|
|
195085
|
-
function assertSafePackageName(packageName) {
|
|
195086
|
-
if (typeof packageName !== "string" || !SAFE_NAME_RE.test(packageName)) {
|
|
195087
|
-
throw new BadRequestError(`Invalid package name: must be 1-255 characters of letters, digits, "-", "_", or "." and must not start with "."`);
|
|
195088
|
-
}
|
|
195089
|
-
}
|
|
195090
|
-
function assertSafeRelativeModelPath(modelPath) {
|
|
195091
|
-
if (typeof modelPath !== "string" || modelPath.length === 0 || modelPath.length > MAX_MODEL_PATH_LEN || modelPath.includes("\x00") || modelPath.includes("\\") || path2.isAbsolute(modelPath) || modelPath.startsWith("/")) {
|
|
195092
|
-
throw new BadRequestError(`Invalid model path`);
|
|
195093
|
-
}
|
|
195094
|
-
const segments = modelPath.split("/");
|
|
195095
|
-
for (const segment of segments) {
|
|
195096
|
-
if (segment === "" || segment === "." || segment === "..") {
|
|
195097
|
-
throw new BadRequestError(`Invalid model path`);
|
|
195098
|
-
}
|
|
195099
|
-
if (segment.startsWith(".")) {
|
|
195100
|
-
throw new BadRequestError(`Invalid model path`);
|
|
195101
|
-
}
|
|
195102
|
-
}
|
|
195103
|
-
}
|
|
195104
|
-
function assertSafeEnvironmentPath(environmentPath) {
|
|
195105
|
-
if (typeof environmentPath !== "string") {
|
|
195106
|
-
throw new BadRequestError(`Invalid environment path: must be a string`);
|
|
195107
|
-
}
|
|
195108
|
-
if (environmentPath.length === 0 || environmentPath.length > MAX_ENVIRONMENT_PATH_LEN) {
|
|
195109
|
-
throw new BadRequestError(`Invalid environment path: bad length`);
|
|
195110
|
-
}
|
|
195111
|
-
if (environmentPath.indexOf("\x00") !== -1) {
|
|
195112
|
-
throw new BadRequestError(`Invalid environment path: contains NUL byte`);
|
|
195113
|
-
}
|
|
195114
|
-
if (environmentPath.indexOf("..") !== -1) {
|
|
195115
|
-
throw new BadRequestError(`Invalid environment path: contains ".." traversal segment`);
|
|
195116
|
-
}
|
|
195117
|
-
if (!SAFE_ENVIRONMENT_PATH_RE.test(environmentPath)) {
|
|
195118
|
-
throw new BadRequestError(`Invalid environment path: must be an absolute path of printable ASCII characters`);
|
|
195119
|
-
}
|
|
195120
|
-
}
|
|
195121
|
-
function safeJoinUnderRoot(root, ...segments) {
|
|
195122
|
-
const resolvedRoot = path2.resolve(root);
|
|
195123
|
-
const joined = path2.resolve(resolvedRoot, ...segments);
|
|
195124
|
-
const rootWithSep = resolvedRoot.endsWith(path2.sep) ? resolvedRoot : resolvedRoot + path2.sep;
|
|
195125
|
-
if (joined !== resolvedRoot && !joined.startsWith(rootWithSep)) {
|
|
195126
|
-
throw new BadRequestError(`Resolved path is outside of root`);
|
|
195127
|
-
}
|
|
195128
|
-
return joined;
|
|
195129
|
-
}
|
|
195130
|
-
var SAFE_NAME_RE, MAX_MODEL_PATH_LEN = 1024, SAFE_ENVIRONMENT_PATH_RE, MAX_ENVIRONMENT_PATH_LEN = 4096;
|
|
195131
|
-
var init_path_safety = __esm(() => {
|
|
195132
|
-
init_errors();
|
|
195133
|
-
SAFE_NAME_RE = /^(?!\.\.?$)(?!\.)[A-Za-z0-9._-]{1,255}$/;
|
|
195134
|
-
SAFE_ENVIRONMENT_PATH_RE = /^(?:\/|[A-Za-z]:[\\/])[\x20-\x7E]*$/;
|
|
195135
|
-
});
|
|
195136
|
-
|
|
195137
195156
|
// ../../node_modules/@smithy/types/dist-cjs/index.js
|
|
195138
195157
|
var require_dist_cjs = __commonJS((exports) => {
|
|
195139
195158
|
exports.HttpAuthLocation = undefined;
|
|
@@ -253350,7 +253369,12 @@ import {
|
|
|
253350
253369
|
contextOverlay,
|
|
253351
253370
|
MalloyConfig
|
|
253352
253371
|
} from "@malloydata/malloy";
|
|
253372
|
+
import { createHash } from "crypto";
|
|
253373
|
+
import { mkdtempSync, readFileSync, writeFileSync } from "fs";
|
|
253353
253374
|
import fs3 from "fs/promises";
|
|
253375
|
+
import os2 from "os";
|
|
253376
|
+
import path4 from "path";
|
|
253377
|
+
import tls from "tls";
|
|
253354
253378
|
async function applyDuckLakeRowGroupBound(connection, dbName) {
|
|
253355
253379
|
const bytes = getDuckLakeRowGroupSizeBytes();
|
|
253356
253380
|
if (bytes === undefined) {
|
|
@@ -253358,7 +253382,7 @@ async function applyDuckLakeRowGroupBound(connection, dbName) {
|
|
|
253358
253382
|
}
|
|
253359
253383
|
try {
|
|
253360
253384
|
await connection.runSQL("SET preserve_insertion_order=false");
|
|
253361
|
-
await connection.runSQL(`CALL ${dbName}.set_option('parquet_row_group_size_bytes', '${escapeSQL(bytes)}')`);
|
|
253385
|
+
await connection.runSQL(`CALL ${quoteIdentifier(dbName, "duckdb")}.set_option('parquet_row_group_size_bytes', '${escapeSQL(bytes)}')`);
|
|
253362
253386
|
logger.info(`DuckLake row group bound applied to ${dbName}: ${bytes}`);
|
|
253363
253387
|
} catch (error) {
|
|
253364
253388
|
logger.warn(`Could not set the DuckLake row group bound on ${dbName}; the lake keeps ` + `its existing value: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -253370,7 +253394,7 @@ async function applyDuckLakeTargetFileSize(connection, dbName) {
|
|
|
253370
253394
|
return;
|
|
253371
253395
|
}
|
|
253372
253396
|
try {
|
|
253373
|
-
await connection.runSQL(`CALL ${dbName}.set_option('target_file_size', '${escapeSQL(bytes)}')`);
|
|
253397
|
+
await connection.runSQL(`CALL ${quoteIdentifier(dbName, "duckdb")}.set_option('target_file_size', '${escapeSQL(bytes)}')`);
|
|
253374
253398
|
logger.info(`DuckLake target file size applied to ${dbName}: ${bytes}`);
|
|
253375
253399
|
} catch (error) {
|
|
253376
253400
|
logger.warn(`Could not set the DuckLake target file size on ${dbName}; the lake keeps ` + `its existing value: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -253459,7 +253483,9 @@ async function isDatabaseAttached(connection, dbName) {
|
|
|
253459
253483
|
});
|
|
253460
253484
|
return rows.some((row) => Object.values(row).some((value) => typeof value === "string" && value === dbName));
|
|
253461
253485
|
} catch (error) {
|
|
253462
|
-
logger.warn(
|
|
253486
|
+
logger.warn("Failed to check existing databases", {
|
|
253487
|
+
error: redactPgSecrets(error instanceof Error ? error.message : String(error))
|
|
253488
|
+
});
|
|
253463
253489
|
return false;
|
|
253464
253490
|
}
|
|
253465
253491
|
}
|
|
@@ -253613,10 +253639,13 @@ async function attachPostgres(connection, attachedDb) {
|
|
|
253613
253639
|
if (!attachedDb.postgresConnection) {
|
|
253614
253640
|
throw new Error(`PostgreSQL connection configuration missing for: ${attachedDb.name}`);
|
|
253615
253641
|
}
|
|
253642
|
+
if (!attachedDb.name) {
|
|
253643
|
+
throw new Error("Attached database name is required");
|
|
253644
|
+
}
|
|
253616
253645
|
await installAndLoadExtension(connection, "postgres");
|
|
253617
253646
|
const config = attachedDb.postgresConnection;
|
|
253618
253647
|
const attachString = buildPgConnectionString(config);
|
|
253619
|
-
const attachCommand = `ATTACH '${escapeSQL(attachString)}' AS ${attachedDb.name} (TYPE postgres, READ_ONLY);`;
|
|
253648
|
+
const attachCommand = `ATTACH '${escapeSQL(attachString)}' AS ${quoteIdentifier(attachedDb.name, "duckdb")} (TYPE postgres, READ_ONLY);`;
|
|
253620
253649
|
await connection.runSQL(attachCommand);
|
|
253621
253650
|
logger.info(`Successfully attached PostgreSQL database: ${attachedDb.name}`);
|
|
253622
253651
|
}
|
|
@@ -253628,10 +253657,11 @@ function runSQLRows(result) {
|
|
|
253628
253657
|
}
|
|
253629
253658
|
async function preflightDuckLakeCatalogFormat(connection, dbName, pgConnString, metadataSchema) {
|
|
253630
253659
|
const tempDb = `${dbName}_fmt_preflight_${++ducklakePreflightSeq}`;
|
|
253631
|
-
const
|
|
253660
|
+
const tempDbRef = quoteIdentifier(tempDb, "duckdb");
|
|
253661
|
+
const metadataRef = metadataSchema ? `${tempDbRef}."${metadataSchema}".ducklake_metadata` : `${tempDbRef}.ducklake_metadata`;
|
|
253632
253662
|
let catalogFormat;
|
|
253633
253663
|
try {
|
|
253634
|
-
await connection.runSQL(`ATTACH '${escapeSQL(pgConnString)}' AS ${
|
|
253664
|
+
await connection.runSQL(`ATTACH '${escapeSQL(pgConnString)}' AS ${tempDbRef} (TYPE postgres, READ_ONLY);`);
|
|
253635
253665
|
const result = await connection.runSQL(`SELECT value FROM ${metadataRef} WHERE key = 'version' LIMIT 1;`);
|
|
253636
253666
|
const value = runSQLRows(result)[0]?.value;
|
|
253637
253667
|
catalogFormat = typeof value === "string" ? value : undefined;
|
|
@@ -253645,7 +253675,7 @@ async function preflightDuckLakeCatalogFormat(connection, dbName, pgConnString,
|
|
|
253645
253675
|
return;
|
|
253646
253676
|
} finally {
|
|
253647
253677
|
try {
|
|
253648
|
-
await connection.runSQL(`DETACH ${
|
|
253678
|
+
await connection.runSQL(`DETACH ${tempDbRef};`);
|
|
253649
253679
|
} catch {}
|
|
253650
253680
|
}
|
|
253651
253681
|
if (!catalogFormat) {
|
|
@@ -253719,7 +253749,7 @@ async function attachDuckLakeWithMode(connection, dbName, ducklakeConfig, option
|
|
|
253719
253749
|
await preflightDuckLakeCatalogFormat(connection, dbName, pgConnString, metadataSchema);
|
|
253720
253750
|
const readOnlyClause = options.readOnly ? ", READ_ONLY true" : "";
|
|
253721
253751
|
const metadataSchemaClause = metadataSchema ? `, METADATA_SCHEMA '${escapeSQL(metadataSchema)}'` : "";
|
|
253722
|
-
const attachCommand = `ATTACH OR REPLACE 'ducklake:postgres:${escapedPgConnString}' AS ${dbName} (DATA_PATH '${escapedBucketUrl}', OVERRIDE_DATA_PATH true${readOnlyClause}${metadataSchemaClause});`;
|
|
253752
|
+
const attachCommand = `ATTACH OR REPLACE 'ducklake:postgres:${escapedPgConnString}' AS ${quoteIdentifier(dbName, "duckdb")} (DATA_PATH '${escapedBucketUrl}', OVERRIDE_DATA_PATH true${readOnlyClause}${metadataSchemaClause});`;
|
|
253723
253753
|
logger.debug(`Attaching DuckLake database using command: ${redactPgSecrets(attachCommand)}`);
|
|
253724
253754
|
try {
|
|
253725
253755
|
await connection.runSQL(attachCommand);
|
|
@@ -253746,14 +253776,14 @@ async function attachDuckLakeReadWrite(connection, dbName, ducklakeConfig) {
|
|
|
253746
253776
|
readOnly: false
|
|
253747
253777
|
});
|
|
253748
253778
|
}
|
|
253749
|
-
async function federateSourceForPassthrough(connection, sourceType, config) {
|
|
253779
|
+
async function federateSourceForPassthrough(connection, sourceType, config, deps = {}) {
|
|
253750
253780
|
switch (sourceType) {
|
|
253751
253781
|
case "bigquery":
|
|
253752
253782
|
return federateBigQuery(connection, config);
|
|
253753
253783
|
case "snowflake":
|
|
253754
253784
|
return federateSnowflake(connection, config);
|
|
253755
253785
|
case "postgres":
|
|
253756
|
-
return federatePostgres(connection, config);
|
|
253786
|
+
return federatePostgres(connection, config, deps);
|
|
253757
253787
|
default: {
|
|
253758
253788
|
const exhaustive = sourceType;
|
|
253759
253789
|
throw new Error(`No native query-passthrough for source type '${String(exhaustive)}'`);
|
|
@@ -253856,17 +253886,113 @@ ${secretLines.join(`,
|
|
|
253856
253886
|
logger.info(`Federated Snowflake source for passthrough: ${secretName}`);
|
|
253857
253887
|
return { handle: secretName, sourceType: "snowflake" };
|
|
253858
253888
|
}
|
|
253859
|
-
async function federatePostgres(connection, config) {
|
|
253889
|
+
async function federatePostgres(connection, config, deps = {}) {
|
|
253860
253890
|
const pg = config.postgresConnection;
|
|
253861
253891
|
if (!pg) {
|
|
253862
253892
|
throw new Error(`PostgreSQL connection configuration missing for: ${config.name}`);
|
|
253863
253893
|
}
|
|
253864
253894
|
await installAndLoadExtension(connection, "postgres");
|
|
253865
|
-
const attachString = buildPgConnectionString(pg);
|
|
253866
253895
|
const alias = config.name;
|
|
253867
|
-
|
|
253868
|
-
|
|
253869
|
-
|
|
253896
|
+
let endpoint;
|
|
253897
|
+
try {
|
|
253898
|
+
let attachString;
|
|
253899
|
+
if (config.proxy) {
|
|
253900
|
+
if (!pg.host || !pg.port) {
|
|
253901
|
+
throw new Error(`Connection proxy on '${config.name}' requires explicit host and port on the postgres connection.`);
|
|
253902
|
+
}
|
|
253903
|
+
endpoint = await (deps.openProxy ?? openProxy)(config.proxy, {
|
|
253904
|
+
host: pg.host,
|
|
253905
|
+
port: pg.port
|
|
253906
|
+
});
|
|
253907
|
+
attachString = buildProxiedPgAttachString(config.name, pg, endpoint);
|
|
253908
|
+
} else {
|
|
253909
|
+
attachString = buildPgConnectionString(pg);
|
|
253910
|
+
}
|
|
253911
|
+
logger.info(`Federating Postgres source for passthrough as alias '${alias}'${endpoint ? " through its SSH proxy" : ""}: ${redactPgSecrets(attachString)}`);
|
|
253912
|
+
await connection.runSQL(`ATTACH OR REPLACE '${escapeSQL(attachString)}' AS ${quoteIdentifier(alias, "duckdb")} (TYPE postgres, READ_ONLY);`);
|
|
253913
|
+
} catch (e) {
|
|
253914
|
+
await endpoint?.close().catch((closeErr) => logger.warn(`Failed to close the SSH proxy opened for Postgres source '${config.name}' after its federation failed: ${String(closeErr)}`));
|
|
253915
|
+
throw e;
|
|
253916
|
+
}
|
|
253917
|
+
return {
|
|
253918
|
+
handle: alias,
|
|
253919
|
+
sourceType: "postgres",
|
|
253920
|
+
...endpoint ? { close: () => endpoint.close() } : {}
|
|
253921
|
+
};
|
|
253922
|
+
}
|
|
253923
|
+
function pgConninfoPair(key, value) {
|
|
253924
|
+
if (value !== "" && !/[\s'\\]/.test(value))
|
|
253925
|
+
return `${key}=${value}`;
|
|
253926
|
+
return `${key}='${value.replace(/([\\'])/g, "\\$1")}'`;
|
|
253927
|
+
}
|
|
253928
|
+
function defaultProxiedAttachTrust() {
|
|
253929
|
+
return {
|
|
253930
|
+
caBundle: process.env.NODE_EXTRA_CA_CERTS || undefined,
|
|
253931
|
+
ambientBundle: ambientTrustBundlePath
|
|
253932
|
+
};
|
|
253933
|
+
}
|
|
253934
|
+
function ambientTrustBundlePath() {
|
|
253935
|
+
const extra = process.env.NODE_EXTRA_CA_CERTS || undefined;
|
|
253936
|
+
const cached = ambientTrustBundles.get(extra);
|
|
253937
|
+
if (cached)
|
|
253938
|
+
return cached;
|
|
253939
|
+
let extraPem;
|
|
253940
|
+
if (extra) {
|
|
253941
|
+
try {
|
|
253942
|
+
extraPem = readFileSync(extra, "utf8").trim();
|
|
253943
|
+
} catch (err) {
|
|
253944
|
+
logger.warn(`Ignoring NODE_EXTRA_CA_CERTS for the storage build's trust bundle: ${extra} could not be read (${err instanceof Error ? err.message : String(err)}).`);
|
|
253945
|
+
}
|
|
253946
|
+
}
|
|
253947
|
+
const pem = [...tls.rootCertificates, ...extraPem ? [extraPem] : []].join(`
|
|
253948
|
+
`) + `
|
|
253949
|
+
`;
|
|
253950
|
+
const digest = createHash("sha256").update(pem).digest("hex").slice(0, 16);
|
|
253951
|
+
ambientTrustDir ??= mkdtempSync(path4.join(os2.tmpdir(), "publisher-ambient-ca-"));
|
|
253952
|
+
const file = path4.join(ambientTrustDir, `${digest}.pem`);
|
|
253953
|
+
writeFileSync(file, pem, { mode: 384 });
|
|
253954
|
+
ambientTrustBundles.set(extra, file);
|
|
253955
|
+
return file;
|
|
253956
|
+
}
|
|
253957
|
+
function buildProxiedPgAttachString(name, pg, endpoint, trust = defaultProxiedAttachTrust()) {
|
|
253958
|
+
if (!pg.host) {
|
|
253959
|
+
throw new Error(`Connection proxy on '${name}' requires an explicit host on the postgres connection.`);
|
|
253960
|
+
}
|
|
253961
|
+
const parts = [
|
|
253962
|
+
pgConninfoPair("host", pg.host),
|
|
253963
|
+
pgConninfoPair("hostaddr", endpoint.host),
|
|
253964
|
+
pgConninfoPair("port", String(endpoint.port))
|
|
253965
|
+
];
|
|
253966
|
+
if (pg.databaseName)
|
|
253967
|
+
parts.push(pgConninfoPair("dbname", pg.databaseName));
|
|
253968
|
+
if (pg.userName)
|
|
253969
|
+
parts.push(pgConninfoPair("user", pg.userName));
|
|
253970
|
+
if (pg.password)
|
|
253971
|
+
parts.push(pgConninfoPair("password", pg.password));
|
|
253972
|
+
const mode = pg.sslmode ?? "no-verify";
|
|
253973
|
+
switch (mode) {
|
|
253974
|
+
case "disable":
|
|
253975
|
+
parts.push("sslmode=disable");
|
|
253976
|
+
break;
|
|
253977
|
+
case "no-verify":
|
|
253978
|
+
parts.push("sslmode=require");
|
|
253979
|
+
break;
|
|
253980
|
+
case "verify-ca": {
|
|
253981
|
+
if (!trust.caBundle) {
|
|
253982
|
+
throw new Error(`Connection proxy on '${name}' uses sslmode 'verify-ca' but no trusted CA bundle is available (NODE_EXTRA_CA_CERTS is unset).`);
|
|
253983
|
+
}
|
|
253984
|
+
parts.push("sslmode=verify-ca", pgConninfoPair("sslrootcert", trust.caBundle));
|
|
253985
|
+
break;
|
|
253986
|
+
}
|
|
253987
|
+
case "verify-full":
|
|
253988
|
+
parts.push("sslmode=verify-full", pgConninfoPair("sslrootcert", trust.ambientBundle()));
|
|
253989
|
+
break;
|
|
253990
|
+
default: {
|
|
253991
|
+
const unhandled = mode;
|
|
253992
|
+
throw new Error(`Connection proxy on '${name}' has unsupported sslmode '${String(unhandled)}' (expected ${PROXIED_SSLMODES.join(" | ")}).`);
|
|
253993
|
+
}
|
|
253994
|
+
}
|
|
253995
|
+
return parts.join(" ");
|
|
253870
253996
|
}
|
|
253871
253997
|
function shouldRenewStorageSecret(opts) {
|
|
253872
253998
|
return opts.hasRenewer && !opts.alreadyRenewing && isExpiredCredentialError(opts.error);
|
|
@@ -254051,7 +254177,9 @@ async function attachDatabasesToDuckDB(duckdbConnection, attachedDatabases) {
|
|
|
254051
254177
|
handleAlreadyAttachedError(attachError, attachedDb.name || "");
|
|
254052
254178
|
}
|
|
254053
254179
|
} catch (error) {
|
|
254054
|
-
logger.error(`Failed to attach database ${attachedDb.name}
|
|
254180
|
+
logger.error(`Failed to attach database ${attachedDb.name}`, {
|
|
254181
|
+
error: redactPgSecrets(error instanceof Error ? error.message : String(error))
|
|
254182
|
+
});
|
|
254055
254183
|
throw new Error(`Failed to attach database ${attachedDb.name}: ${error.message}`);
|
|
254056
254184
|
}
|
|
254057
254185
|
}
|
|
@@ -254423,7 +254551,7 @@ async function testDuckDBConnection(duckdbConnection, connectionConfig) {
|
|
|
254423
254551
|
}
|
|
254424
254552
|
} catch (error) {
|
|
254425
254553
|
const errorMessage = `Attached database '${attachedDb.name}' (${attachedDb.type}) test failed: ${error.message}`;
|
|
254426
|
-
logger.error(errorMessage);
|
|
254554
|
+
logger.error(redactPgSecrets(errorMessage));
|
|
254427
254555
|
failedAttachments.push(errorMessage);
|
|
254428
254556
|
}
|
|
254429
254557
|
}
|
|
@@ -254435,11 +254563,16 @@ ${failedAttachments.join(`
|
|
|
254435
254563
|
}
|
|
254436
254564
|
async function testConnectionConfig(connectionConfig) {
|
|
254437
254565
|
let environmentConfig = null;
|
|
254566
|
+
let testRoot = null;
|
|
254438
254567
|
try {
|
|
254439
254568
|
if (!connectionConfig.name) {
|
|
254440
254569
|
throw new Error("Connection name is required");
|
|
254441
254570
|
}
|
|
254442
|
-
|
|
254571
|
+
if (connectionConfig.type === "duckdb" || connectionConfig.type === "ducklake") {
|
|
254572
|
+
assertSafePackageName(connectionConfig.name);
|
|
254573
|
+
}
|
|
254574
|
+
testRoot = await fs3.mkdtemp(path4.join(os2.tmpdir(), "publisher-conn-test-"));
|
|
254575
|
+
environmentConfig = buildEnvironmentMalloyConfig([connectionConfig], testRoot);
|
|
254443
254576
|
const connection = await environmentConfig.malloyConfig.connections.lookupConnection(connectionConfig.name);
|
|
254444
254577
|
if (connectionConfig.type === "duckdb") {
|
|
254445
254578
|
await testDuckDBConnection(connection, connectionConfig);
|
|
@@ -254462,11 +254595,13 @@ async function testConnectionConfig(connectionConfig) {
|
|
|
254462
254595
|
if (error instanceof AxiosError2) {
|
|
254463
254596
|
logAxiosError(error);
|
|
254464
254597
|
} else {
|
|
254465
|
-
logger.error(
|
|
254598
|
+
logger.error("Connection test failed", {
|
|
254599
|
+
error: redactPgSecrets(error instanceof Error ? error.stack ?? error.message : String(error))
|
|
254600
|
+
});
|
|
254466
254601
|
}
|
|
254467
254602
|
return {
|
|
254468
254603
|
status: "failed",
|
|
254469
|
-
errorMessage: error.message
|
|
254604
|
+
errorMessage: redactPgSecrets(error instanceof Error ? error.message : String(error))
|
|
254470
254605
|
};
|
|
254471
254606
|
} finally {
|
|
254472
254607
|
if (environmentConfig) {
|
|
@@ -254478,12 +254613,18 @@ async function testConnectionConfig(connectionConfig) {
|
|
|
254478
254613
|
});
|
|
254479
254614
|
}
|
|
254480
254615
|
}
|
|
254481
|
-
if (
|
|
254482
|
-
|
|
254616
|
+
if (testRoot) {
|
|
254617
|
+
try {
|
|
254618
|
+
await fs3.rm(testRoot, { recursive: true, force: true });
|
|
254619
|
+
} catch (cleanupError) {
|
|
254620
|
+
logger.warn("Error cleaning up connection test directory", {
|
|
254621
|
+
error: cleanupError instanceof Error ? cleanupError.message : String(cleanupError)
|
|
254622
|
+
});
|
|
254623
|
+
}
|
|
254483
254624
|
}
|
|
254484
254625
|
}
|
|
254485
254626
|
}
|
|
254486
|
-
var import_db_publisher, extensionSessionPinned, sessionLimitsApplied, ducklakePreflightSeq = 0, AzureDuckDBConnection, DuckLakeConnection;
|
|
254627
|
+
var import_db_publisher, extensionSessionPinned, sessionLimitsApplied, ducklakePreflightSeq = 0, ambientTrustBundles, ambientTrustDir, AzureDuckDBConnection, DuckLakeConnection;
|
|
254487
254628
|
var init_connection = __esm(() => {
|
|
254488
254629
|
init_axios2();
|
|
254489
254630
|
init_config();
|
|
@@ -254499,6 +254640,7 @@ var init_connection = __esm(() => {
|
|
|
254499
254640
|
import_db_publisher = __toESM(require_dist5(), 1);
|
|
254500
254641
|
extensionSessionPinned = new WeakSet;
|
|
254501
254642
|
sessionLimitsApplied = new WeakMap;
|
|
254643
|
+
ambientTrustBundles = new Map;
|
|
254502
254644
|
AzureDuckDBConnection = class AzureDuckDBConnection extends DuckDBConnection {
|
|
254503
254645
|
azureDatabases;
|
|
254504
254646
|
constructor(options, azureDatabases) {
|
|
@@ -262429,7 +262571,7 @@ var require_table = __commonJS((exports) => {
|
|
|
262429
262571
|
var events_1 = __require("events");
|
|
262430
262572
|
var fs4 = __require("fs");
|
|
262431
262573
|
var is = require_is();
|
|
262432
|
-
var
|
|
262574
|
+
var path5 = __require("path");
|
|
262433
262575
|
var streamEvents = require_stream_events();
|
|
262434
262576
|
var uuid = require_dist10();
|
|
262435
262577
|
var _1 = require_src139();
|
|
@@ -262675,7 +262817,7 @@ var require_table = __commonJS((exports) => {
|
|
|
262675
262817
|
if (!common_1.util.isCustomType(dest, "storage/file")) {
|
|
262676
262818
|
throw new Error("Destination must be a File object.");
|
|
262677
262819
|
}
|
|
262678
|
-
const format =
|
|
262820
|
+
const format = path5.extname(dest.name).substr(1).toLowerCase();
|
|
262679
262821
|
if (!options.destinationFormat && !options.format && FORMATS[format]) {
|
|
262680
262822
|
options.destinationFormat = FORMATS[format];
|
|
262681
262823
|
}
|
|
@@ -262733,7 +262875,7 @@ var require_table = __commonJS((exports) => {
|
|
|
262733
262875
|
metadata.location = this.location;
|
|
262734
262876
|
}
|
|
262735
262877
|
if (typeof source === "string") {
|
|
262736
|
-
const detectedFormat = FORMATS[
|
|
262878
|
+
const detectedFormat = FORMATS[path5.extname(source).substr(1).toLowerCase()];
|
|
262737
262879
|
if (!metadata.sourceFormat && detectedFormat) {
|
|
262738
262880
|
metadata.sourceFormat = detectedFormat;
|
|
262739
262881
|
}
|
|
@@ -262769,7 +262911,7 @@ var require_table = __commonJS((exports) => {
|
|
|
262769
262911
|
if (!common_1.util.isCustomType(src, "storage/file")) {
|
|
262770
262912
|
throw new Error("Source must be a File object.");
|
|
262771
262913
|
}
|
|
262772
|
-
const format = FORMATS[
|
|
262914
|
+
const format = FORMATS[path5.extname(src.name).substr(1).toLowerCase()];
|
|
262773
262915
|
if (!metadata.sourceFormat && format) {
|
|
262774
262916
|
body.configuration.load.sourceFormat = format;
|
|
262775
262917
|
}
|
|
@@ -267522,16 +267664,16 @@ function parseMotly(texts) {
|
|
|
267522
267664
|
const after = parseGuarded(rescued);
|
|
267523
267665
|
return { tag: after.tag, errors: [...envErrors, ...after.messages] };
|
|
267524
267666
|
}
|
|
267525
|
-
function tagText(tag, ...
|
|
267667
|
+
function tagText(tag, ...path6) {
|
|
267526
267668
|
try {
|
|
267527
|
-
return tag?.text(...
|
|
267669
|
+
return tag?.text(...path6);
|
|
267528
267670
|
} catch {
|
|
267529
267671
|
return;
|
|
267530
267672
|
}
|
|
267531
267673
|
}
|
|
267532
|
-
function tagNumeric(tag, ...
|
|
267674
|
+
function tagNumeric(tag, ...path6) {
|
|
267533
267675
|
try {
|
|
267534
|
-
const raw = tagText(tag, ...
|
|
267676
|
+
const raw = tagText(tag, ...path6);
|
|
267535
267677
|
if (raw === undefined)
|
|
267536
267678
|
return;
|
|
267537
267679
|
const DECIMAL = /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$/;
|
|
@@ -267595,8 +267737,8 @@ var init_motly = __esm(() => {
|
|
|
267595
267737
|
import {
|
|
267596
267738
|
isSourceDef
|
|
267597
267739
|
} from "@malloydata/malloy";
|
|
267598
|
-
function presentText(tag, ...
|
|
267599
|
-
const raw = tagText(tag, ...
|
|
267740
|
+
function presentText(tag, ...path6) {
|
|
267741
|
+
const raw = tagText(tag, ...path6);
|
|
267600
267742
|
return raw !== undefined && raw.trim() !== "" ? raw : undefined;
|
|
267601
267743
|
}
|
|
267602
267744
|
function readGivenControlSpec(annotationTexts2) {
|
|
@@ -267877,8 +268019,8 @@ function readDrillTag(annotations) {
|
|
|
267877
268019
|
function isString2(value) {
|
|
267878
268020
|
return value !== undefined;
|
|
267879
268021
|
}
|
|
267880
|
-
function tagTextArray(tag, ...
|
|
267881
|
-
const items = tag?.array(...
|
|
268022
|
+
function tagTextArray(tag, ...path6) {
|
|
268023
|
+
const items = tag?.array(...path6);
|
|
267882
268024
|
return items?.map((item) => tagText(item)).filter(isString2);
|
|
267883
268025
|
}
|
|
267884
268026
|
function resolveTileGivens(tile, facts) {
|
|
@@ -269057,7 +269199,7 @@ var require_yauzl = __commonJS((exports) => {
|
|
|
269057
269199
|
exports.ZipFile = ZipFile;
|
|
269058
269200
|
exports.Entry = Entry;
|
|
269059
269201
|
exports.RandomAccessReader = RandomAccessReader;
|
|
269060
|
-
function open2(
|
|
269202
|
+
function open2(path6, options, callback) {
|
|
269061
269203
|
if (typeof options === "function") {
|
|
269062
269204
|
callback = options;
|
|
269063
269205
|
options = null;
|
|
@@ -269076,7 +269218,7 @@ var require_yauzl = __commonJS((exports) => {
|
|
|
269076
269218
|
options.strictFileNames = false;
|
|
269077
269219
|
if (callback == null)
|
|
269078
269220
|
callback = defaultCallback;
|
|
269079
|
-
fs4.open(
|
|
269221
|
+
fs4.open(path6, "r", function(err, fd) {
|
|
269080
269222
|
if (err)
|
|
269081
269223
|
return callback(err);
|
|
269082
269224
|
fromFd(fd, options, function(err2, zipfile) {
|
|
@@ -269740,7 +269882,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
269740
269882
|
var debug = require_src5()("extract-zip");
|
|
269741
269883
|
var { createWriteStream, promises: fs4 } = __require("fs");
|
|
269742
269884
|
var getStream = require_get_stream();
|
|
269743
|
-
var
|
|
269885
|
+
var path6 = __require("path");
|
|
269744
269886
|
var { promisify } = __require("util");
|
|
269745
269887
|
var stream4 = __require("stream");
|
|
269746
269888
|
var yauzl = require_yauzl();
|
|
@@ -269778,12 +269920,12 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
269778
269920
|
this.zipfile.readEntry();
|
|
269779
269921
|
return;
|
|
269780
269922
|
}
|
|
269781
|
-
const destDir =
|
|
269923
|
+
const destDir = path6.dirname(path6.join(this.opts.dir, entry.fileName));
|
|
269782
269924
|
try {
|
|
269783
269925
|
await fs4.mkdir(destDir, { recursive: true });
|
|
269784
269926
|
const canonicalDestDir = await fs4.realpath(destDir);
|
|
269785
|
-
const relativeDestDir =
|
|
269786
|
-
if (relativeDestDir.split(
|
|
269927
|
+
const relativeDestDir = path6.relative(this.opts.dir, canonicalDestDir);
|
|
269928
|
+
if (relativeDestDir.split(path6.sep).includes("..")) {
|
|
269787
269929
|
throw new Error(`Out of bound path "${canonicalDestDir}" found while processing file ${entry.fileName}`);
|
|
269788
269930
|
}
|
|
269789
269931
|
await this.extractEntry(entry);
|
|
@@ -269805,7 +269947,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
269805
269947
|
if (this.opts.onEntry) {
|
|
269806
269948
|
this.opts.onEntry(entry, this.zipfile);
|
|
269807
269949
|
}
|
|
269808
|
-
const dest =
|
|
269950
|
+
const dest = path6.join(this.opts.dir, entry.fileName);
|
|
269809
269951
|
const mode = entry.externalFileAttributes >> 16 & 65535;
|
|
269810
269952
|
const IFMT = 61440;
|
|
269811
269953
|
const IFDIR = 16384;
|
|
@@ -269820,7 +269962,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
269820
269962
|
isDir = madeBy === 0 && entry.externalFileAttributes === 16;
|
|
269821
269963
|
debug("extracting entry", { filename: entry.fileName, isDir, isSymlink: symlink });
|
|
269822
269964
|
const procMode = this.getExtractedMode(mode, isDir) & 511;
|
|
269823
|
-
const destDir = isDir ? dest :
|
|
269965
|
+
const destDir = isDir ? dest : path6.dirname(dest);
|
|
269824
269966
|
const mkdirOptions = { recursive: true };
|
|
269825
269967
|
if (isDir) {
|
|
269826
269968
|
mkdirOptions.mode = procMode;
|
|
@@ -269863,7 +270005,7 @@ var require_extract_zip = __commonJS((exports, module) => {
|
|
|
269863
270005
|
}
|
|
269864
270006
|
module.exports = async function(zipPath, opts) {
|
|
269865
270007
|
debug("creating target directory", opts.dir);
|
|
269866
|
-
if (!
|
|
270008
|
+
if (!path6.isAbsolute(opts.dir)) {
|
|
269867
270009
|
throw new Error("Target directory is expected to be absolute");
|
|
269868
270010
|
}
|
|
269869
270011
|
await fs4.mkdir(opts.dir, { recursive: true });
|
|
@@ -269881,10 +270023,10 @@ var require_src140 = __commonJS((exports) => {
|
|
|
269881
270023
|
var fs_1 = __require("fs");
|
|
269882
270024
|
var debug_1 = __importDefault(require_src5());
|
|
269883
270025
|
var log = debug_1.default("@kwsites/file-exists");
|
|
269884
|
-
function check(
|
|
269885
|
-
log(`checking %s`,
|
|
270026
|
+
function check(path6, isFile2, isDirectory) {
|
|
270027
|
+
log(`checking %s`, path6);
|
|
269886
270028
|
try {
|
|
269887
|
-
const stat4 = fs_1.statSync(
|
|
270029
|
+
const stat4 = fs_1.statSync(path6);
|
|
269888
270030
|
if (stat4.isFile() && isFile2) {
|
|
269889
270031
|
log(`[OK] path represents a file`);
|
|
269890
270032
|
return true;
|
|
@@ -269904,8 +270046,8 @@ var require_src140 = __commonJS((exports) => {
|
|
|
269904
270046
|
throw e;
|
|
269905
270047
|
}
|
|
269906
270048
|
}
|
|
269907
|
-
function exists(
|
|
269908
|
-
return check(
|
|
270049
|
+
function exists(path6, type = exports.READABLE) {
|
|
270050
|
+
return check(path6, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
269909
270051
|
}
|
|
269910
270052
|
exports.exists = exists;
|
|
269911
270053
|
exports.FILE = 1;
|
|
@@ -270494,14 +270636,14 @@ var init_authorize_metrics = __esm(() => {
|
|
|
270494
270636
|
});
|
|
270495
270637
|
|
|
270496
270638
|
// src/materialization_metrics.ts
|
|
270497
|
-
function
|
|
270639
|
+
function lazyCounter3(name, description) {
|
|
270498
270640
|
let instrument2 = null;
|
|
270499
|
-
|
|
270641
|
+
resetHooks3.push(() => instrument2 = null);
|
|
270500
270642
|
return () => instrument2 ??= publisherMeter().createCounter(name, { description });
|
|
270501
270643
|
}
|
|
270502
|
-
function
|
|
270644
|
+
function lazyHistogram2(name, description, unit) {
|
|
270503
270645
|
let instrument2 = null;
|
|
270504
|
-
|
|
270646
|
+
resetHooks3.push(() => instrument2 = null);
|
|
270505
270647
|
return () => instrument2 ??= publisherMeter().createHistogram(name, {
|
|
270506
270648
|
description,
|
|
270507
270649
|
unit
|
|
@@ -270585,43 +270727,43 @@ function recordChainedStorageBuild(outcome) {
|
|
|
270585
270727
|
function recordColocatedBindDropped(reason) {
|
|
270586
270728
|
colocatedBindDroppedCounter().add(1, { reason });
|
|
270587
270729
|
}
|
|
270588
|
-
var
|
|
270730
|
+
var resetHooks3, runCounter, runDuration, sourcesCounter, incrementalStepCounter, buildPlanComputeDuration, buildPlanComputeFailedCounter, autoLoadCounter, connectionDigestSkipCounter, manifestBindCounter, manifestBindDegradedCounter, duplicateTargetSkipCounter, sharedAddressInstructionCounter, tableCollisionCounter, sourceBuildDuration, dropTablesCounter, scheduledFireCounter, storageServeRoutingCounter, storageTableRetainedCounter, storageBuildFailureCounter, attributionSkippedCounter, eligibilityRefusedCounter, serveShapeTierDropCounter, serveShapeTypeFallbackCounter, chainedStorageBuildCounter, colocatedBindDroppedCounter;
|
|
270589
270731
|
var init_materialization_metrics = __esm(() => {
|
|
270590
270732
|
init_telemetry();
|
|
270591
|
-
|
|
270592
|
-
runCounter =
|
|
270593
|
-
runDuration =
|
|
270594
|
-
sourcesCounter =
|
|
270595
|
-
incrementalStepCounter =
|
|
270596
|
-
buildPlanComputeDuration =
|
|
270597
|
-
buildPlanComputeFailedCounter =
|
|
270598
|
-
autoLoadCounter =
|
|
270599
|
-
connectionDigestSkipCounter =
|
|
270600
|
-
manifestBindCounter =
|
|
270601
|
-
manifestBindDegradedCounter =
|
|
270602
|
-
duplicateTargetSkipCounter =
|
|
270603
|
-
sharedAddressInstructionCounter =
|
|
270604
|
-
tableCollisionCounter =
|
|
270605
|
-
sourceBuildDuration =
|
|
270606
|
-
dropTablesCounter =
|
|
270607
|
-
scheduledFireCounter =
|
|
270608
|
-
storageServeRoutingCounter =
|
|
270609
|
-
storageTableRetainedCounter =
|
|
270610
|
-
storageBuildFailureCounter =
|
|
270611
|
-
attributionSkippedCounter =
|
|
270612
|
-
eligibilityRefusedCounter =
|
|
270613
|
-
serveShapeTierDropCounter =
|
|
270614
|
-
serveShapeTypeFallbackCounter =
|
|
270615
|
-
chainedStorageBuildCounter =
|
|
270616
|
-
colocatedBindDroppedCounter =
|
|
270733
|
+
resetHooks3 = [];
|
|
270734
|
+
runCounter = lazyCounter3("publisher_materialization_runs_total", "Materialization builds completed. Labels: mode ('auto'|'orchestrated'), outcome ('success'|'partial'|'failed'|'cancelled').");
|
|
270735
|
+
runDuration = lazyHistogram2("publisher_materialization_run_duration_ms", "Wall-clock duration of a materialization build. Label: mode ('auto'|'orchestrated').", "ms");
|
|
270736
|
+
sourcesCounter = lazyCounter3("publisher_materialization_sources_total", "Persist sources processed by a materialization run. Label: outcome ('built'|'reused'|'failed').");
|
|
270737
|
+
incrementalStepCounter = lazyCounter3("publisher_materialization_incremental_step_total", 'Refreshes of a source declared refresh="incremental". Labels: step ' + "('delta'|'seed'|'skip'), and for seed/skip a bounded reason code " + "(IncrementalStepReasonCode). A 'seed' is a full rebuild the delta path " + "declined, so a rising seed rate means the feature is not engaging — and " + "the reason label says why without a log dive.");
|
|
270738
|
+
buildPlanComputeDuration = lazyHistogram2("publisher_materialization_build_plan_compute_duration_ms", "Wall-clock duration of compiling a package's build plan (Package.buildPlan).", "ms");
|
|
270739
|
+
buildPlanComputeFailedCounter = lazyCounter3("publisher_materialization_build_plan_compute_failed_total", "Package loads whose build plan failed to compute. The ROOT-CAUSE signal for " + "colocated_bind_dropped{reason='build_plan_unavailable'}, which fires only " + "per dropped entry per load -- a package that loads once and is never " + "reloaded ticks that counter once and then sits with its colocated tier " + "off and a flat total, indistinguishable from healthy.");
|
|
270740
|
+
autoLoadCounter = lazyCounter3("publisher_materialization_auto_load_total", "Auto-run manifest auto-load attempts. Label: outcome ('success'|'failure').");
|
|
270741
|
+
connectionDigestSkipCounter = lazyCounter3("publisher_materialization_connection_digest_skipped_total", "Connection digests skipped during build-plan compile because the connection did not resolve.");
|
|
270742
|
+
manifestBindCounter = lazyCounter3("publisher_materialization_manifest_bind_total", "Manifest bind attempts. Label: outcome ('success'|'failure'|'timeout').");
|
|
270743
|
+
manifestBindDegradedCounter = lazyCounter3("publisher_materialization_manifest_bind_degraded_total", "Manifest entries bound with an UNQUOTED table path because their connection " + "could not be resolved (serve-side bind) or is absent from the build " + "(build-side seed). A misconfiguration that breaks the source on a " + "case-folding engine (Snowflake); alertable.");
|
|
270744
|
+
duplicateTargetSkipCounter = lazyCounter3("publisher_materialization_duplicate_target_skipped_total", "Sources skipped because the physical table they name was already built in " + "this run. Ordinary for a package that extends a persisted source; a " + "rising count against a package with no extension means the plan is " + "enumerating one table under more names than expected.");
|
|
270745
|
+
sharedAddressInstructionCounter = lazyCounter3("publisher_materialization_shared_address_instructions_total", "Content addresses that arrived with more than one instruction naming a " + "DIFFERENT physical table. The host minted a table per source where " + "several sources share one artifact. With a sourceID on each instruction " + "every table is built and only one is recorded, so the rest are orphaned; " + "without one the last instruction wins and the earlier names are never " + "built. Wasteful, not wrong — the table's CONTENT is the same either way.");
|
|
270746
|
+
tableCollisionCounter = lazyCounter3("publisher_materialization_table_collision_total", "Two definitions with DIFFERENT content addresses materializing into ONE " + "physical table. Each build overwrites the other's rows while both " + "addresses resolve to the table at serve time, so a query is answered " + "from another source's data. A wrong answer, not wasted work — page on " + "this one. Refused instead of counted-and-continued when " + "PERSIST_COLLISION_ENFORCE is set, so a non-zero rate here is also the " + "measure of what flipping that flag would start refusing.");
|
|
270747
|
+
sourceBuildDuration = lazyHistogram2("publisher_materialization_source_build_duration_ms", "Wall-clock duration of building a single persist source.", "ms");
|
|
270748
|
+
dropTablesCounter = lazyCounter3("publisher_materialization_drop_tables_total", "Physical tables dropped on delete. Label: outcome ('success'|'failure').");
|
|
270749
|
+
scheduledFireCounter = lazyCounter3("publisher_materialization_scheduled_fires_total", "Standalone-scheduler attempts to fire a package's materialization.schedule. " + "Label: outcome ('fired'|'conflict'|'error').");
|
|
270750
|
+
storageServeRoutingCounter = lazyCounter3("publisher_storage_serve_routing_total", "storage= serve routing decisions. Label: outcome ('storage'|'live_fallback'|" + "'runtime_live_fallback'|'blocked_by_row_level_gate'). Covers the storage= " + "tier only; a colocated #@ persist hit is in neither the numerator nor the " + "denominator. NOTE 'live_fallback' here means the transform was INELIGIBLE, " + "which QueryResult.servedFrom reports as null - that field's " + "'live_fallback' is this counter's 'runtime_live_fallback'.");
|
|
270751
|
+
storageTableRetainedCounter = lazyCounter3("publisher_storage_tables_retained_total", "Tables a FAILED run left in a storage= destination and deliberately did not " + "reclaim, because the source is refreshed incrementally and the name may be " + "the one it serves from. Label: destination. Not all of these are orphans — " + "a rebuild at a fresh generational name is, a seed on the live serving name " + "is not, and the manifest entry cannot separate them — so read this as an " + "upper bound on what is accumulating rather than a leak count. It is the " + "only accounting there is until reclaiming a destination exists, which is " + "why it is a counter and not just a log line: the question is a rate, not " + "whether it ever happened.");
|
|
270752
|
+
storageBuildFailureCounter = lazyCounter3("publisher_storage_build_failures_total", "storage= build failures (federation/passthrough/attach/CTAS), distinct from " + "in-warehouse build failures. Labels: destination (connection name), " + "reason ('build_failed'|'billed_read_not_captured'). The second is the " + "expensive one: the warehouse read ran and was charged, and the rows could " + "not be captured — so a re-drive pays for it again. Worth alerting on " + "separately from a failure that costs only a retry.");
|
|
270753
|
+
attributionSkippedCounter = lazyCounter3("publisher_storage_build_attribution_skipped_total", "storage= builds whose warehouse read went out UNATTRIBUTED while tagging was " + "on. Label: reason ('job_listing_unavailable'|'tag_failed'|" + "'read_row_not_found'|'read_row_ambiguous'|'cost_query_failed'). " + "The read still ran and the " + "build still succeeded — what was lost is the label in the customer's own " + "query history, and the cost on this side. Without this an operator who " + "turns tagging on and sees nothing has a single log line to go on.");
|
|
270754
|
+
eligibilityRefusedCounter = lazyCounter3("publisher_materialization_eligibility_refused_total", "storage= materialization-eligibility refusals. Label: reason " + "('free_parameter'|'given'|'authorize'|'not_duckdb_portable'|" + "'public_surface_unknown').");
|
|
270755
|
+
serveShapeTierDropCounter = lazyCounter3("publisher_storage_serve_shape_tier_drop_total", "storage serve-shape compile escalations: a refinement tier failed to " + "compile and the riskiest category was dropped. Label: tier (the failed " + "tier index, 0=full).");
|
|
270756
|
+
serveShapeTypeFallbackCounter = lazyCounter3("publisher_storage_serve_shape_type_fallback_total", "Captured DuckDB column types mapped to json in the serve shape (type " + "fidelity loss). Label: kind ('array'|'unrecognized').");
|
|
270757
|
+
chainedStorageBuildCounter = lazyCounter3("publisher_storage_chained_build_total", "Chained storage= source builds (a source reading a storage-materialized " + "upstream). Label: outcome ('parent_reuse'|'inline_fallback'|" + "'strict_refused'). The parent_reuse share is the headline signal for how " + "far the stack-on-the-parent path gets us vs recompute-from-raw.");
|
|
270758
|
+
colocatedBindDroppedCounter = lazyCounter3("publisher_materialization_colocated_bind_dropped_total", "Colocated serve-manifest entries dropped by bindColocatedServeManifest. " + "Label: reason ('build_plan_unavailable' when the package's build plan " + "failed to compute, so no source was examined at all; 'refused' when the " + "source itself was examined and found ineligible). 'build_plan_unavailable' " + "is a whole-package regression -- colocated is the default tier and is NOT " + "gated by PERSIST_STORAGE_MODE, so every colocated binding for the package " + "reverts to live recompute until a load succeeds.");
|
|
270617
270759
|
});
|
|
270618
270760
|
|
|
270619
270761
|
// src/utils.ts
|
|
270620
270762
|
import * as fs4 from "fs";
|
|
270621
|
-
import * as
|
|
270763
|
+
import * as path7 from "path";
|
|
270622
270764
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
270623
270765
|
function ignoreDotfiles(file) {
|
|
270624
|
-
return
|
|
270766
|
+
return path7.basename(file).startsWith(".");
|
|
270625
270767
|
}
|
|
270626
270768
|
function errMessage(err) {
|
|
270627
270769
|
return err instanceof Error ? err.message : String(err);
|
|
@@ -270630,11 +270772,11 @@ var URL_READER;
|
|
|
270630
270772
|
var init_utils4 = __esm(() => {
|
|
270631
270773
|
URL_READER = {
|
|
270632
270774
|
readURL: (url2) => {
|
|
270633
|
-
let
|
|
270775
|
+
let path8 = url2.toString();
|
|
270634
270776
|
if (url2.protocol == "file:") {
|
|
270635
|
-
|
|
270777
|
+
path8 = fileURLToPath3(url2);
|
|
270636
270778
|
}
|
|
270637
|
-
return fs4.promises.readFile(
|
|
270779
|
+
return fs4.promises.readFile(path8, "utf8");
|
|
270638
270780
|
}
|
|
270639
270781
|
};
|
|
270640
270782
|
});
|
|
@@ -270906,9 +271048,9 @@ var init_preaggregation_classifier = __esm(() => {
|
|
|
270906
271048
|
|
|
270907
271049
|
// src/service/preaggregation_synthesis.ts
|
|
270908
271050
|
import { Annotations as Annotations3 } from "@malloydata/malloy";
|
|
270909
|
-
import { createHash as
|
|
271051
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
270910
271052
|
function grainDigest(grainDimensions) {
|
|
270911
|
-
return
|
|
271053
|
+
return createHash4("sha256").update(grainDimensions.join("\x00")).digest("hex").slice(0, 8);
|
|
270912
271054
|
}
|
|
270913
271055
|
function rollupSourceName(baseSourceName, grainDimensions) {
|
|
270914
271056
|
const slug = grainDimensions.join("_").replace(/\./g, "_").slice(0, NAME_SLUG_LIMIT);
|
|
@@ -271265,6 +271407,10 @@ function serveShapeFragment(binding) {
|
|
|
271265
271407
|
lines.push(` ${r.kind}: ${r.name} is ${r.code}`);
|
|
271266
271408
|
}
|
|
271267
271409
|
}
|
|
271410
|
+
for (const r of refinements) {
|
|
271411
|
+
if (r.kind === "filter")
|
|
271412
|
+
lines.push(` where: ${r.code}`);
|
|
271413
|
+
}
|
|
271268
271414
|
for (const r of refinements) {
|
|
271269
271415
|
if (r.kind === "view")
|
|
271270
271416
|
lines.push(` view: ${r.text}`);
|
|
@@ -271303,6 +271449,22 @@ ${fragments}
|
|
|
271303
271449
|
`
|
|
271304
271450
|
};
|
|
271305
271451
|
}
|
|
271452
|
+
function buildServeShapeTiers(rollupGroups) {
|
|
271453
|
+
const always = [...NEVER_THINNED];
|
|
271454
|
+
const keepKinds = [
|
|
271455
|
+
new Set([...always, "join", "dimension", "measure", "view"]),
|
|
271456
|
+
new Set([...always, "join", "dimension", "measure"]),
|
|
271457
|
+
new Set([...always, "dimension", "measure"]),
|
|
271458
|
+
new Set(always)
|
|
271459
|
+
];
|
|
271460
|
+
const hasGroups = rollupGroups.length > 0;
|
|
271461
|
+
return [
|
|
271462
|
+
{ keep: keepKinds[0], groups: rollupGroups },
|
|
271463
|
+
...hasGroups ? [{ keep: keepKinds[0], groups: [] }] : [],
|
|
271464
|
+
...keepKinds.slice(1).map((keep) => ({ keep, groups: rollupGroups })),
|
|
271465
|
+
...hasGroups ? [{ keep: new Set(always), groups: [] }] : []
|
|
271466
|
+
];
|
|
271467
|
+
}
|
|
271306
271468
|
function rollupServeShapeFragment(group) {
|
|
271307
271469
|
const members = group.members.map(serveShapeFragment).join(`
|
|
271308
271470
|
`);
|
|
@@ -271405,6 +271567,17 @@ function narrowSchemaToPublic(schema, fields) {
|
|
|
271405
271567
|
}
|
|
271406
271568
|
return out;
|
|
271407
271569
|
}
|
|
271570
|
+
function extractSourceFilters(filterList) {
|
|
271571
|
+
const out = [];
|
|
271572
|
+
for (const entry of filterList ?? []) {
|
|
271573
|
+
const code = entry?.code;
|
|
271574
|
+
out.push({
|
|
271575
|
+
kind: "filter",
|
|
271576
|
+
code: typeof code === "string" ? code : UNREPRODUCIBLE_FILTER
|
|
271577
|
+
});
|
|
271578
|
+
}
|
|
271579
|
+
return out;
|
|
271580
|
+
}
|
|
271408
271581
|
function extractRefinements(fields) {
|
|
271409
271582
|
const out = [];
|
|
271410
271583
|
for (const field of fields ?? []) {
|
|
@@ -271517,13 +271690,14 @@ async function assertServesInDuckDB(sourceName, binding, connections) {
|
|
|
271517
271690
|
});
|
|
271518
271691
|
}
|
|
271519
271692
|
}
|
|
271520
|
-
var BARE_IDENTIFIER;
|
|
271693
|
+
var BARE_IDENTIFIER, NEVER_THINNED, UNREPRODUCIBLE_FILTER = "__unreproducible_filter__";
|
|
271521
271694
|
var init_materialization_serve_transform = __esm(() => {
|
|
271522
271695
|
init_errors();
|
|
271523
271696
|
init_logger();
|
|
271524
271697
|
init_materialization_metrics();
|
|
271525
271698
|
init_quoting();
|
|
271526
271699
|
BARE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
271700
|
+
NEVER_THINNED = ["filter"];
|
|
271527
271701
|
});
|
|
271528
271702
|
|
|
271529
271703
|
// src/service/freshness.ts
|
|
@@ -271571,16 +271745,16 @@ import {
|
|
|
271571
271745
|
isJoined,
|
|
271572
271746
|
isSourceDef as isSourceDef3
|
|
271573
271747
|
} from "@malloydata/malloy";
|
|
271574
|
-
function resolveFieldUsagePath(struct,
|
|
271748
|
+
function resolveFieldUsagePath(struct, path8) {
|
|
271575
271749
|
let current = struct;
|
|
271576
|
-
for (let i = 0;i <
|
|
271577
|
-
const seg =
|
|
271750
|
+
for (let i = 0;i < path8.length - 1; i++) {
|
|
271751
|
+
const seg = path8[i];
|
|
271578
271752
|
const joinField = (current.fields ?? []).find((f) => (f.as || f.name) === seg && isJoined(f) && (isSourceDef3(f) || f.type === "record" || f.type === "array"));
|
|
271579
271753
|
if (!joinField)
|
|
271580
271754
|
return;
|
|
271581
271755
|
current = joinField;
|
|
271582
271756
|
}
|
|
271583
|
-
const leaf =
|
|
271757
|
+
const leaf = path8[path8.length - 1];
|
|
271584
271758
|
const field = (current.fields ?? []).find((f) => (f.as || f.name) === leaf);
|
|
271585
271759
|
return field ? { struct: current, field } : undefined;
|
|
271586
271760
|
}
|
|
@@ -272677,15 +272851,15 @@ __export(exports_preaggregation_compile, {
|
|
|
272677
272851
|
synthesizedModelURL: () => synthesizedModelURL,
|
|
272678
272852
|
compileSynthesizedPreaggregation: () => compileSynthesizedPreaggregation
|
|
272679
272853
|
});
|
|
272680
|
-
import * as
|
|
272854
|
+
import * as path8 from "path";
|
|
272681
272855
|
function synthesizedModelURL(packagePath, modelPath) {
|
|
272682
|
-
return new URL(`file://${
|
|
272856
|
+
return new URL(`file://${path8.join(packagePath, modelPath)}${SYNTHESIZED_SUFFIX}`);
|
|
272683
272857
|
}
|
|
272684
272858
|
async function compileSynthesizedPreaggregation(args) {
|
|
272685
272859
|
const plans = planModelPreaggregation(args.contents);
|
|
272686
272860
|
if (plans.length === 0)
|
|
272687
272861
|
return;
|
|
272688
|
-
const text = synthesizePreaggregationModel(plans,
|
|
272862
|
+
const text = synthesizePreaggregationModel(plans, path8.basename(args.modelPath));
|
|
272689
272863
|
if (!text)
|
|
272690
272864
|
return;
|
|
272691
272865
|
const synthesizedURL = synthesizedModelURL(args.packagePath, args.modelPath);
|
|
@@ -274020,9 +274194,9 @@ import {
|
|
|
274020
274194
|
MalloySQLStatementType
|
|
274021
274195
|
} from "@malloydata/malloy-sql";
|
|
274022
274196
|
import * as fs6 from "fs/promises";
|
|
274023
|
-
import { readFileSync } from "fs";
|
|
274197
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
274024
274198
|
import { createRequire as createRequire2 } from "module";
|
|
274025
|
-
import * as
|
|
274199
|
+
import * as path9 from "path";
|
|
274026
274200
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
274027
274201
|
function quoteMalloyIdentifier2(name) {
|
|
274028
274202
|
return "`" + (name ?? "").replace(/\\/g, "\\\\").replace(/`/g, "\\`") + "`";
|
|
@@ -275293,22 +275467,11 @@ var init_model = __esm(() => {
|
|
|
275293
275467
|
const rollupPaths = [
|
|
275294
275468
|
...buildVirtualMap(groups.flatMap((g) => g.members))
|
|
275295
275469
|
].flatMap(([, byHandle]) => [...byHandle.values()]);
|
|
275296
|
-
const origin2 = rollupPaths.some((
|
|
275470
|
+
const origin2 = rollupPaths.some((path10) => probeSQL.includes(path10)) ? "preaggregate" : "persist";
|
|
275297
275471
|
return { runnable, virtualMap, bindings: freshBindings, origin: origin2 };
|
|
275298
275472
|
}
|
|
275299
|
-
async compileServeShape(enriched, rollupGroups = []) {
|
|
275300
|
-
const
|
|
275301
|
-
new Set(["join", "dimension", "measure", "view"]),
|
|
275302
|
-
new Set(["join", "dimension", "measure"]),
|
|
275303
|
-
new Set(["dimension", "measure"]),
|
|
275304
|
-
new Set
|
|
275305
|
-
];
|
|
275306
|
-
const tiers = [
|
|
275307
|
-
{ keep: keepKinds[0], groups: rollupGroups },
|
|
275308
|
-
...rollupGroups.length > 0 ? [{ keep: keepKinds[0], groups: [] }] : [],
|
|
275309
|
-
...keepKinds.slice(1).map((keep) => ({ keep, groups: rollupGroups })),
|
|
275310
|
-
...rollupGroups.length > 0 ? [{ keep: new Set, groups: [] }] : []
|
|
275311
|
-
];
|
|
275473
|
+
async compileServeShape(enriched, rollupGroups = [], isRetry = false) {
|
|
275474
|
+
const tiers = buildServeShapeTiers(rollupGroups);
|
|
275312
275475
|
const nothingToEscalate = rollupGroups.length === 0 && !enriched.some((b) => (b.refinements ?? []).length > 0);
|
|
275313
275476
|
const lastTier = tiers.length - 1;
|
|
275314
275477
|
for (let tier = 0;tier <= lastTier; tier++) {
|
|
@@ -275318,7 +275481,32 @@ var init_model = __esm(() => {
|
|
|
275318
275481
|
refinements: b.refinements.filter((r) => keep.has(r.kind))
|
|
275319
275482
|
} : b);
|
|
275320
275483
|
const materializer = this.buildServeShapeMaterializer(shaped, groups);
|
|
275321
|
-
if (tier === lastTier
|
|
275484
|
+
if (tier === lastTier) {
|
|
275485
|
+
try {
|
|
275486
|
+
await materializer.getModel();
|
|
275487
|
+
return materializer;
|
|
275488
|
+
} catch (err) {
|
|
275489
|
+
if (isRetry)
|
|
275490
|
+
return materializer;
|
|
275491
|
+
const servable = await this.bindingsWhoseFiltersCompile(enriched, keep);
|
|
275492
|
+
const withheld = enriched.filter((b) => !servable.includes(b)).map((b) => b.sourceName);
|
|
275493
|
+
if (servable.length === 0 || withheld.length === 0) {
|
|
275494
|
+
logger.warn("Storage serve shape failed at its floor and no binding could be isolated; serving live", {
|
|
275495
|
+
model: this.modelPath,
|
|
275496
|
+
error: err instanceof Error ? err.message : String(err)
|
|
275497
|
+
});
|
|
275498
|
+
return materializer;
|
|
275499
|
+
}
|
|
275500
|
+
logger.warn("Withheld storage serve bindings whose filters cannot be reproduced; those sources serve live", {
|
|
275501
|
+
model: this.modelPath,
|
|
275502
|
+
withheld,
|
|
275503
|
+
stillServed: servable.map((b) => b.sourceName),
|
|
275504
|
+
error: err instanceof Error ? err.message : String(err)
|
|
275505
|
+
});
|
|
275506
|
+
return await this.compileServeShape(servable, rollupGroups, true);
|
|
275507
|
+
}
|
|
275508
|
+
}
|
|
275509
|
+
if (tier === 0 && nothingToEscalate) {
|
|
275322
275510
|
return materializer;
|
|
275323
275511
|
}
|
|
275324
275512
|
try {
|
|
@@ -275333,7 +275521,25 @@ var init_model = __esm(() => {
|
|
|
275333
275521
|
});
|
|
275334
275522
|
}
|
|
275335
275523
|
}
|
|
275336
|
-
|
|
275524
|
+
const floor = tiers[tiers.length - 1].keep;
|
|
275525
|
+
return this.buildServeShapeMaterializer(enriched.map((b) => ({
|
|
275526
|
+
...b,
|
|
275527
|
+
refinements: (b.refinements ?? []).filter((r) => floor.has(r.kind))
|
|
275528
|
+
})), []);
|
|
275529
|
+
}
|
|
275530
|
+
async bindingsWhoseFiltersCompile(enriched, floorKeep) {
|
|
275531
|
+
const servable = [];
|
|
275532
|
+
for (const binding of enriched) {
|
|
275533
|
+
const floored = {
|
|
275534
|
+
...binding,
|
|
275535
|
+
refinements: (binding.refinements ?? []).filter((r) => floorKeep.has(r.kind))
|
|
275536
|
+
};
|
|
275537
|
+
try {
|
|
275538
|
+
await this.buildServeShapeMaterializer([floored], []).getModel();
|
|
275539
|
+
servable.push(binding);
|
|
275540
|
+
} catch {}
|
|
275541
|
+
}
|
|
275542
|
+
return servable;
|
|
275337
275543
|
}
|
|
275338
275544
|
buildServeShapeMaterializer(bindings, rollupGroups = []) {
|
|
275339
275545
|
const { modelText } = buildServeShapeModelForBindings(bindings, rollupGroups);
|
|
@@ -275365,7 +275571,7 @@ var init_model = __esm(() => {
|
|
|
275365
275571
|
return;
|
|
275366
275572
|
if (!fileCache.has(location.url)) {
|
|
275367
275573
|
try {
|
|
275368
|
-
fileCache.set(location.url,
|
|
275574
|
+
fileCache.set(location.url, readFileSync2(fileURLToPath5(location.url), "utf8"));
|
|
275369
275575
|
} catch {
|
|
275370
275576
|
fileCache.set(location.url, null);
|
|
275371
275577
|
}
|
|
@@ -275383,6 +275589,7 @@ var init_model = __esm(() => {
|
|
|
275383
275589
|
liftText
|
|
275384
275590
|
}),
|
|
275385
275591
|
...extractRefinements(fields),
|
|
275592
|
+
...extractSourceFilters(contents?.[b.sourceName]?.filterList),
|
|
275386
275593
|
...extractViews(fields, liftText)
|
|
275387
275594
|
];
|
|
275388
275595
|
return { ...b, schema, refinements };
|
|
@@ -276107,7 +276314,7 @@ run: ${sourceName ? `${quoteMalloyIdentifier2(sourceName)} -> ` : ""}${quoteMall
|
|
|
276107
276314
|
return this.modelType;
|
|
276108
276315
|
}
|
|
276109
276316
|
async getFileText(packagePath) {
|
|
276110
|
-
const fullPath =
|
|
276317
|
+
const fullPath = path9.join(packagePath, this.modelPath);
|
|
276111
276318
|
try {
|
|
276112
276319
|
return await fs6.readFile(fullPath, "utf8");
|
|
276113
276320
|
} catch {
|
|
@@ -276339,14 +276546,14 @@ var require_brace_expansion = __commonJS((exports, module) => {
|
|
|
276339
276546
|
var require_minimatch = __commonJS((exports, module) => {
|
|
276340
276547
|
module.exports = minimatch;
|
|
276341
276548
|
minimatch.Minimatch = Minimatch;
|
|
276342
|
-
var
|
|
276549
|
+
var path10 = function() {
|
|
276343
276550
|
try {
|
|
276344
276551
|
return __require("path");
|
|
276345
276552
|
} catch (e) {}
|
|
276346
276553
|
}() || {
|
|
276347
276554
|
sep: "/"
|
|
276348
276555
|
};
|
|
276349
|
-
minimatch.sep =
|
|
276556
|
+
minimatch.sep = path10.sep;
|
|
276350
276557
|
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {};
|
|
276351
276558
|
var expand = require_brace_expansion();
|
|
276352
276559
|
var plTypes = {
|
|
@@ -276437,8 +276644,8 @@ var require_minimatch = __commonJS((exports, module) => {
|
|
|
276437
276644
|
if (!options)
|
|
276438
276645
|
options = {};
|
|
276439
276646
|
pattern = pattern.trim();
|
|
276440
|
-
if (!options.allowWindowsEscape &&
|
|
276441
|
-
pattern = pattern.split(
|
|
276647
|
+
if (!options.allowWindowsEscape && path10.sep !== "/") {
|
|
276648
|
+
pattern = pattern.split(path10.sep).join("/");
|
|
276442
276649
|
}
|
|
276443
276650
|
this.options = options;
|
|
276444
276651
|
this.set = [];
|
|
@@ -276815,8 +277022,8 @@ var require_minimatch = __commonJS((exports, module) => {
|
|
|
276815
277022
|
if (f === "/" && partial)
|
|
276816
277023
|
return true;
|
|
276817
277024
|
var options = this.options;
|
|
276818
|
-
if (
|
|
276819
|
-
f = f.split(
|
|
277025
|
+
if (path10.sep !== "/") {
|
|
277026
|
+
f = f.split(path10.sep).join("/");
|
|
276820
277027
|
}
|
|
276821
277028
|
f = f.split(slashSplit);
|
|
276822
277029
|
this.debug(this.pattern, "split", f);
|
|
@@ -276927,9 +277134,9 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
276927
277134
|
var p = __require("path");
|
|
276928
277135
|
var minimatch = require_minimatch();
|
|
276929
277136
|
function patternMatcher(pattern) {
|
|
276930
|
-
return function(
|
|
277137
|
+
return function(path10, stats) {
|
|
276931
277138
|
var minimatcher = new minimatch.Minimatch(pattern, { matchBase: true });
|
|
276932
|
-
return (!minimatcher.negate || stats.isFile()) && minimatcher.match(
|
|
277139
|
+
return (!minimatcher.negate || stats.isFile()) && minimatcher.match(path10);
|
|
276933
277140
|
};
|
|
276934
277141
|
}
|
|
276935
277142
|
function toMatcherFunction(ignoreEntry) {
|
|
@@ -276939,14 +277146,14 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
276939
277146
|
return patternMatcher(ignoreEntry);
|
|
276940
277147
|
}
|
|
276941
277148
|
}
|
|
276942
|
-
function readdir3(
|
|
277149
|
+
function readdir3(path10, ignores, callback) {
|
|
276943
277150
|
if (typeof ignores == "function") {
|
|
276944
277151
|
callback = ignores;
|
|
276945
277152
|
ignores = [];
|
|
276946
277153
|
}
|
|
276947
277154
|
if (!callback) {
|
|
276948
277155
|
return new Promise(function(resolve4, reject2) {
|
|
276949
|
-
readdir3(
|
|
277156
|
+
readdir3(path10, ignores || [], function(err, data) {
|
|
276950
277157
|
if (err) {
|
|
276951
277158
|
reject2(err);
|
|
276952
277159
|
} else {
|
|
@@ -276957,7 +277164,7 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
276957
277164
|
}
|
|
276958
277165
|
ignores = ignores.map(toMatcherFunction);
|
|
276959
277166
|
var list = [];
|
|
276960
|
-
fs7.readdir(
|
|
277167
|
+
fs7.readdir(path10, function(err, files) {
|
|
276961
277168
|
if (err) {
|
|
276962
277169
|
return callback(err);
|
|
276963
277170
|
}
|
|
@@ -276966,7 +277173,7 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
276966
277173
|
return callback(null, list);
|
|
276967
277174
|
}
|
|
276968
277175
|
files.forEach(function(file) {
|
|
276969
|
-
var filePath = p.join(
|
|
277176
|
+
var filePath = p.join(path10, file);
|
|
276970
277177
|
fs7.stat(filePath, function(_err, stats) {
|
|
276971
277178
|
if (_err) {
|
|
276972
277179
|
return callback(_err);
|
|
@@ -283385,8 +283592,8 @@ var require_CronFileParser = __commonJS((exports) => {
|
|
|
283385
283592
|
return CronFileParser.#parseContent(data);
|
|
283386
283593
|
}
|
|
283387
283594
|
static parseFileSync(filePath) {
|
|
283388
|
-
const { readFileSync:
|
|
283389
|
-
const data =
|
|
283595
|
+
const { readFileSync: readFileSync3 } = __require("fs");
|
|
283596
|
+
const data = readFileSync3(filePath, "utf8");
|
|
283390
283597
|
return CronFileParser.#parseContent(data);
|
|
283391
283598
|
}
|
|
283392
283599
|
static #parseContent(data) {
|
|
@@ -284284,8 +284491,8 @@ var require_uri_all = __commonJS((exports, module) => {
|
|
|
284284
284491
|
wsComponents.secure = undefined;
|
|
284285
284492
|
}
|
|
284286
284493
|
if (wsComponents.resourceName) {
|
|
284287
|
-
var _wsComponents$resourc = wsComponents.resourceName.split("?"), _wsComponents$resourc2 = slicedToArray(_wsComponents$resourc, 2),
|
|
284288
|
-
wsComponents.path =
|
|
284494
|
+
var _wsComponents$resourc = wsComponents.resourceName.split("?"), _wsComponents$resourc2 = slicedToArray(_wsComponents$resourc, 2), path14 = _wsComponents$resourc2[0], query = _wsComponents$resourc2[1];
|
|
284495
|
+
wsComponents.path = path14 && path14 !== "/" ? path14 : undefined;
|
|
284289
284496
|
wsComponents.query = query;
|
|
284290
284497
|
wsComponents.resourceName = undefined;
|
|
284291
284498
|
}
|
|
@@ -284678,12 +284885,12 @@ var require_util12 = __commonJS((exports, module) => {
|
|
|
284678
284885
|
return "'" + escapeQuotes(str) + "'";
|
|
284679
284886
|
}
|
|
284680
284887
|
function getPathExpr(currentPath, expr, jsonPointers, isNumber2) {
|
|
284681
|
-
var
|
|
284682
|
-
return joinPaths(currentPath,
|
|
284888
|
+
var path14 = jsonPointers ? "'/' + " + expr + (isNumber2 ? "" : ".replace(/~/g, '~0').replace(/\\//g, '~1')") : isNumber2 ? "'[' + " + expr + " + ']'" : "'[\\'' + " + expr + " + '\\']'";
|
|
284889
|
+
return joinPaths(currentPath, path14);
|
|
284683
284890
|
}
|
|
284684
284891
|
function getPath(currentPath, prop, jsonPointers) {
|
|
284685
|
-
var
|
|
284686
|
-
return joinPaths(currentPath,
|
|
284892
|
+
var path14 = jsonPointers ? toQuotedString("/" + escapeJsonPointer(prop)) : toQuotedString(getProperty(prop));
|
|
284893
|
+
return joinPaths(currentPath, path14);
|
|
284687
284894
|
}
|
|
284688
284895
|
var JSON_POINTER = /^\/(?:[^~]|~0|~1)*$/;
|
|
284689
284896
|
var RELATIVE_JSON_POINTER = /^([0-9]+)(#|\/(?:[^~]|~0|~1)*)?$/;
|
|
@@ -296286,7 +296493,7 @@ var import_cors = __toESM(require_lib6(), 1);
|
|
|
296286
296493
|
var import_express = __toESM(require_express(), 1);
|
|
296287
296494
|
var import_http_proxy_middleware = __toESM(require_dist4(), 1);
|
|
296288
296495
|
import * as http2 from "http";
|
|
296289
|
-
import * as
|
|
296496
|
+
import * as path16 from "path";
|
|
296290
296497
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
296291
296498
|
|
|
296292
296499
|
// src/controller/compile.controller.ts
|
|
@@ -296312,6 +296519,7 @@ init_config();
|
|
|
296312
296519
|
init_errors();
|
|
296313
296520
|
init_query_cap_metrics();
|
|
296314
296521
|
init_logger();
|
|
296522
|
+
init_path_safety();
|
|
296315
296523
|
|
|
296316
296524
|
// src/query_timeout.ts
|
|
296317
296525
|
init_telemetry();
|
|
@@ -296571,19 +296779,19 @@ function withoutWithheldFields(value) {
|
|
|
296571
296779
|
}
|
|
296572
296780
|
function flattenWithheld(hidden, prefix, out) {
|
|
296573
296781
|
for (const [key, value] of Object.entries(hidden)) {
|
|
296574
|
-
const
|
|
296782
|
+
const path5 = prefix ? `${prefix}.${key}` : key;
|
|
296575
296783
|
if (Array.isArray(value)) {
|
|
296576
296784
|
for (const item of value) {
|
|
296577
296785
|
if (!isPlainObject2(item))
|
|
296578
296786
|
continue;
|
|
296579
296787
|
const { name, ...rest } = item;
|
|
296580
|
-
const label = typeof name === "string" ? `${
|
|
296788
|
+
const label = typeof name === "string" ? `${path5}.${name}` : path5;
|
|
296581
296789
|
flattenWithheld(rest, label, out);
|
|
296582
296790
|
}
|
|
296583
296791
|
} else if (isPlainObject2(value)) {
|
|
296584
|
-
flattenWithheld(value,
|
|
296792
|
+
flattenWithheld(value, path5, out);
|
|
296585
296793
|
} else if (value !== undefined && value !== null && value !== "") {
|
|
296586
|
-
out.push(
|
|
296794
|
+
out.push(path5);
|
|
296587
296795
|
}
|
|
296588
296796
|
}
|
|
296589
296797
|
}
|
|
@@ -296684,22 +296892,22 @@ function isSupplied(value) {
|
|
|
296684
296892
|
return Object.keys(value).length > 0;
|
|
296685
296893
|
return true;
|
|
296686
296894
|
}
|
|
296687
|
-
function suppliedAt(patch,
|
|
296688
|
-
const dot =
|
|
296895
|
+
function suppliedAt(patch, path5) {
|
|
296896
|
+
const dot = path5.indexOf(".");
|
|
296689
296897
|
if (dot === -1) {
|
|
296690
|
-
return Object.hasOwn(patch,
|
|
296898
|
+
return Object.hasOwn(patch, path5) && isSupplied(patch[path5]);
|
|
296691
296899
|
}
|
|
296692
|
-
const parent = patch[
|
|
296900
|
+
const parent = patch[path5.slice(0, dot)];
|
|
296693
296901
|
if (!isPlainObject2(parent))
|
|
296694
296902
|
return false;
|
|
296695
|
-
const leaf =
|
|
296903
|
+
const leaf = path5.slice(dot + 1);
|
|
296696
296904
|
return Object.hasOwn(parent, leaf) && isSupplied(parent[leaf]);
|
|
296697
296905
|
}
|
|
296698
296906
|
function exclusionsFor(patch) {
|
|
296699
296907
|
const skip = new Set;
|
|
296700
296908
|
for (const slots of EXCLUSIVE_SLOTS) {
|
|
296701
296909
|
const declared = slots.filter((slot) => slot.fields.some((field) => isPlainObject2(patch[field])));
|
|
296702
|
-
const selected = declared.length === 1 ? declared : slots.filter((slot) => slot.selects.some((
|
|
296910
|
+
const selected = declared.length === 1 ? declared : slots.filter((slot) => slot.selects.some((path5) => suppliedAt(patch, path5)));
|
|
296703
296911
|
if (selected.length !== 1)
|
|
296704
296912
|
continue;
|
|
296705
296913
|
for (const slot of slots) {
|
|
@@ -298227,12 +298435,15 @@ class ConnectionController {
|
|
|
298227
298435
|
if (!connectionConfig.type || typeof connectionConfig.type !== "string") {
|
|
298228
298436
|
throw new BadRequestError("Connection type is required and must be a string");
|
|
298229
298437
|
}
|
|
298438
|
+
if ((connectionConfig.type === "duckdb" || connectionConfig.type === "ducklake") && connectionConfig.name) {
|
|
298439
|
+
assertSafePackageName(connectionConfig.name);
|
|
298440
|
+
}
|
|
298230
298441
|
try {
|
|
298231
298442
|
return await testConnectionConfig(connectionConfig);
|
|
298232
298443
|
} catch (error) {
|
|
298233
298444
|
return {
|
|
298234
298445
|
status: "failed",
|
|
298235
|
-
errorMessage: `Connection test failed: ${error.message}`
|
|
298446
|
+
errorMessage: redactPgSecrets(`Connection test failed: ${error instanceof Error ? error.message : String(error)}`)
|
|
298236
298447
|
};
|
|
298237
298448
|
}
|
|
298238
298449
|
}
|
|
@@ -298277,6 +298488,48 @@ class ConnectionController {
|
|
|
298277
298488
|
|
|
298278
298489
|
// src/controller/dashboard.controller.ts
|
|
298279
298490
|
init_errors();
|
|
298491
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
298492
|
+
|
|
298493
|
+
// src/dashboard_write_metrics.ts
|
|
298494
|
+
init_telemetry();
|
|
298495
|
+
var resetHooks2 = [];
|
|
298496
|
+
function lazyCounter2(name, description) {
|
|
298497
|
+
let instrument2 = null;
|
|
298498
|
+
resetHooks2.push(() => instrument2 = null);
|
|
298499
|
+
return () => instrument2 ??= publisherMeter().createCounter(name, { description });
|
|
298500
|
+
}
|
|
298501
|
+
function lazyHistogram(name, description, unit) {
|
|
298502
|
+
let instrument2 = null;
|
|
298503
|
+
resetHooks2.push(() => instrument2 = null);
|
|
298504
|
+
return () => instrument2 ??= publisherMeter().createHistogram(name, {
|
|
298505
|
+
description,
|
|
298506
|
+
unit
|
|
298507
|
+
});
|
|
298508
|
+
}
|
|
298509
|
+
var writeCounter = lazyCounter2("publisher_dashboard_writes_total", "Dashboard write attempts. Label: outcome ('created'|'replaced'|'conflict'|'compile_failed'|'refused'|'rolled_back').");
|
|
298510
|
+
var writeDuration = lazyHistogram("publisher_dashboard_write_duration_ms", "Wall-clock duration of a dashboard write, compile and package reload included. Label: outcome.", "ms");
|
|
298511
|
+
function recordDashboardWrite(outcome, durationMs) {
|
|
298512
|
+
writeCounter().add(1, { outcome });
|
|
298513
|
+
writeDuration().record(durationMs, { outcome });
|
|
298514
|
+
}
|
|
298515
|
+
|
|
298516
|
+
// src/controller/dashboard.controller.ts
|
|
298517
|
+
init_path_safety();
|
|
298518
|
+
function outcomeOf(error) {
|
|
298519
|
+
if (error instanceof WriteConflictError)
|
|
298520
|
+
return "conflict";
|
|
298521
|
+
if (error instanceof CompileRefusedError)
|
|
298522
|
+
return "compile_failed";
|
|
298523
|
+
if (error instanceof WriteRolledBackError)
|
|
298524
|
+
return "rolled_back";
|
|
298525
|
+
return "refused";
|
|
298526
|
+
}
|
|
298527
|
+
var DASHBOARD_FILE = /^dashboards\/[^/]+\.malloy$/;
|
|
298528
|
+
var describeProblem = (problem) => {
|
|
298529
|
+
const start = problem.at?.range?.start;
|
|
298530
|
+
return start?.line === undefined ? problem.message : `line ${start.line + 1}:${(start.character ?? 0) + 1} ${problem.message}`;
|
|
298531
|
+
};
|
|
298532
|
+
var contentHashOf = (text) => createHash2("sha256").update(text, "utf8").digest("hex");
|
|
298280
298533
|
|
|
298281
298534
|
class DashboardController {
|
|
298282
298535
|
environmentStore;
|
|
@@ -298297,6 +298550,57 @@ class DashboardController {
|
|
|
298297
298550
|
}
|
|
298298
298551
|
return dashboard;
|
|
298299
298552
|
}
|
|
298553
|
+
async putDashboardSource(environmentName, packageName, modelPath, body) {
|
|
298554
|
+
const startedAt = Date.now();
|
|
298555
|
+
try {
|
|
298556
|
+
const result = await this.writeDashboardSource(environmentName, packageName, modelPath, body);
|
|
298557
|
+
recordDashboardWrite(result.created ? "created" : "replaced", Date.now() - startedAt);
|
|
298558
|
+
return result;
|
|
298559
|
+
} catch (error) {
|
|
298560
|
+
recordDashboardWrite(outcomeOf(error), Date.now() - startedAt);
|
|
298561
|
+
throw error;
|
|
298562
|
+
}
|
|
298563
|
+
}
|
|
298564
|
+
async writeDashboardSource(environmentName, packageName, modelPath, body) {
|
|
298565
|
+
if (this.environmentStore.publisherConfigIsFrozen) {
|
|
298566
|
+
throw new FrozenConfigError('Cannot write a dashboard: publisher.config.json has "frozenConfig": true.');
|
|
298567
|
+
}
|
|
298568
|
+
assertSafeRelativeModelPath(modelPath);
|
|
298569
|
+
if (!DASHBOARD_FILE.test(modelPath)) {
|
|
298570
|
+
throw new BadRequestError(`Only a dashboard file can be written here: \`dashboards/<slug>.malloy\`, ` + `not \`${modelPath}\`.`);
|
|
298571
|
+
}
|
|
298572
|
+
if (typeof body?.source !== "string") {
|
|
298573
|
+
throw new BadRequestError("The request body needs a `source`: the whole file's Malloy text.");
|
|
298574
|
+
}
|
|
298575
|
+
const environment = await this.environmentStore.getEnvironment(environmentName, false);
|
|
298576
|
+
await environment.getPackage(packageName, false);
|
|
298577
|
+
const { problems } = await environment.compileSource(packageName, modelPath, body.source, false, undefined, "file");
|
|
298578
|
+
const errors2 = problems.filter((problem) => problem.severity === "error");
|
|
298579
|
+
if (errors2.length > 0) {
|
|
298580
|
+
throw new CompileRefusedError(`The dashboard does not compile, so it was not written: ` + errors2.map(describeProblem).join("; "));
|
|
298581
|
+
}
|
|
298582
|
+
const { previous } = await environment.writeModelFileTransactional(packageName, modelPath, body.source, (current) => {
|
|
298583
|
+
if (body.expectedHash === undefined) {
|
|
298584
|
+
if (current !== undefined)
|
|
298585
|
+
throw new WriteConflictError(`\`${modelPath}\` already exists in the package. Send the ` + `\`expectedHash\` of the text you opened to replace it.`);
|
|
298586
|
+
return;
|
|
298587
|
+
}
|
|
298588
|
+
const currentHash = current === undefined ? undefined : contentHashOf(current);
|
|
298589
|
+
if (currentHash !== body.expectedHash)
|
|
298590
|
+
throw new WriteConflictError(current === undefined ? `\`${modelPath}\` no longer exists in the package, so the text you ` + `opened cannot be updated. Re-open it before saving.` : `\`${modelPath}\` changed in the package since you opened it. ` + `Re-open it and reapply your change; nothing was written.`);
|
|
298591
|
+
}, async (reloaded) => {
|
|
298592
|
+
const written = reloaded.getModel(modelPath);
|
|
298593
|
+
if (!written)
|
|
298594
|
+
throw new Error(`\`${modelPath}\` is not in the reloaded package`);
|
|
298595
|
+
await written.getModel();
|
|
298596
|
+
});
|
|
298597
|
+
return {
|
|
298598
|
+
resource: `/api/v0/environments/${environmentName}/packages/${packageName}/models/${modelPath}`,
|
|
298599
|
+
path: modelPath,
|
|
298600
|
+
contentHash: contentHashOf(body.source),
|
|
298601
|
+
created: previous === undefined
|
|
298602
|
+
};
|
|
298603
|
+
}
|
|
298300
298604
|
}
|
|
298301
298605
|
|
|
298302
298606
|
// src/controller/database.controller.ts
|
|
@@ -298408,7 +298712,7 @@ class ModelController {
|
|
|
298408
298712
|
init_constants();
|
|
298409
298713
|
init_errors();
|
|
298410
298714
|
init_logger();
|
|
298411
|
-
import * as
|
|
298715
|
+
import * as path5 from "path";
|
|
298412
298716
|
|
|
298413
298717
|
// src/mcp/tools/get_context_tool.ts
|
|
298414
298718
|
var import_lunr = __toESM(require_lunr(), 1);
|
|
@@ -298743,22 +299047,22 @@ async function getModelForQuery(environmentStore, environmentName, packageName,
|
|
|
298743
299047
|
}
|
|
298744
299048
|
}
|
|
298745
299049
|
function buildMalloyUri(components, fragment) {
|
|
298746
|
-
let
|
|
299050
|
+
let path5 = "/environment/";
|
|
298747
299051
|
if (components.environment) {
|
|
298748
|
-
|
|
299052
|
+
path5 += encodeURIComponent(components.environment);
|
|
298749
299053
|
} else {
|
|
298750
|
-
|
|
299054
|
+
path5 += "home";
|
|
298751
299055
|
}
|
|
298752
299056
|
if (components.package) {
|
|
298753
|
-
|
|
299057
|
+
path5 += "/package/" + encodeURIComponent(components.package);
|
|
298754
299058
|
}
|
|
298755
299059
|
if (components.resourceType) {
|
|
298756
|
-
|
|
299060
|
+
path5 += "/" + components.resourceType;
|
|
298757
299061
|
if (components.resourceName) {
|
|
298758
|
-
|
|
299062
|
+
path5 += "/" + encodeURIComponent(components.resourceName);
|
|
298759
299063
|
}
|
|
298760
299064
|
}
|
|
298761
|
-
let uriString = "malloy:/" +
|
|
299065
|
+
let uriString = "malloy:/" + path5;
|
|
298762
299066
|
if (fragment) {
|
|
298763
299067
|
uriString += "#" + fragment;
|
|
298764
299068
|
}
|
|
@@ -298809,7 +299113,7 @@ function jsonToolError(uri, details, extraPayload) {
|
|
|
298809
299113
|
init_logger();
|
|
298810
299114
|
|
|
298811
299115
|
// src/mcp/tools/embedding_index.ts
|
|
298812
|
-
import { createHash } from "crypto";
|
|
299116
|
+
import { createHash as createHash3 } from "crypto";
|
|
298813
299117
|
|
|
298814
299118
|
// ../../node_modules/async-mutex/index.mjs
|
|
298815
299119
|
var E_TIMEOUT = new Error("timeout while waiting for mutex to become available");
|
|
@@ -299216,7 +299520,7 @@ function splitToFit(text, max) {
|
|
|
299216
299520
|
return pieces;
|
|
299217
299521
|
}
|
|
299218
299522
|
function contentHash(text) {
|
|
299219
|
-
return
|
|
299523
|
+
return createHash3("sha256").update(text).digest("hex");
|
|
299220
299524
|
}
|
|
299221
299525
|
function sourceColumn(source) {
|
|
299222
299526
|
return source ?? "";
|
|
@@ -300800,7 +301104,7 @@ class PackageController {
|
|
|
300800
301104
|
} else if (packageLocation.startsWith("s3://")) {
|
|
300801
301105
|
await this.environmentStore.downloadS3Directory(packageLocation, environmentName, targetPath, isCompressedFile);
|
|
300802
301106
|
}
|
|
300803
|
-
if (packageLocation.startsWith("/") ||
|
|
301107
|
+
if (packageLocation.startsWith("/") || path5.isAbsolute(packageLocation)) {
|
|
300804
301108
|
await this.environmentStore.mountLocalDirectory(packageLocation, targetPath, environmentName, packageName);
|
|
300805
301109
|
}
|
|
300806
301110
|
}
|
|
@@ -300958,7 +301262,7 @@ class ReaddirpStream extends Readable2 {
|
|
|
300958
301262
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
300959
301263
|
const statMethod = opts.lstat ? lstat : stat;
|
|
300960
301264
|
if (wantBigintFsStats) {
|
|
300961
|
-
this._stat = (
|
|
301265
|
+
this._stat = (path6) => statMethod(path6, { bigint: true });
|
|
300962
301266
|
} else {
|
|
300963
301267
|
this._stat = statMethod;
|
|
300964
301268
|
}
|
|
@@ -300983,8 +301287,8 @@ class ReaddirpStream extends Readable2 {
|
|
|
300983
301287
|
const par = this.parent;
|
|
300984
301288
|
const fil = par && par.files;
|
|
300985
301289
|
if (fil && fil.length > 0) {
|
|
300986
|
-
const { path:
|
|
300987
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
301290
|
+
const { path: path6, depth } = par;
|
|
301291
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path6));
|
|
300988
301292
|
const awaited = await Promise.all(slice);
|
|
300989
301293
|
for (const entry of awaited) {
|
|
300990
301294
|
if (!entry)
|
|
@@ -301024,20 +301328,20 @@ class ReaddirpStream extends Readable2 {
|
|
|
301024
301328
|
this.reading = false;
|
|
301025
301329
|
}
|
|
301026
301330
|
}
|
|
301027
|
-
async _exploreDir(
|
|
301331
|
+
async _exploreDir(path6, depth) {
|
|
301028
301332
|
let files;
|
|
301029
301333
|
try {
|
|
301030
|
-
files = await readdir(
|
|
301334
|
+
files = await readdir(path6, this._rdOptions);
|
|
301031
301335
|
} catch (error) {
|
|
301032
301336
|
this._onError(error);
|
|
301033
301337
|
}
|
|
301034
|
-
return { files, depth, path:
|
|
301338
|
+
return { files, depth, path: path6 };
|
|
301035
301339
|
}
|
|
301036
|
-
async _formatEntry(dirent,
|
|
301340
|
+
async _formatEntry(dirent, path6) {
|
|
301037
301341
|
let entry;
|
|
301038
301342
|
const basename = this._isDirent ? dirent.name : dirent;
|
|
301039
301343
|
try {
|
|
301040
|
-
const fullPath = presolve(pjoin(
|
|
301344
|
+
const fullPath = presolve(pjoin(path6, basename));
|
|
301041
301345
|
entry = { path: prelative(this._root, fullPath), fullPath, basename };
|
|
301042
301346
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
301043
301347
|
} catch (err) {
|
|
@@ -301436,16 +301740,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
301436
301740
|
};
|
|
301437
301741
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
301438
301742
|
var FsWatchInstances = new Map;
|
|
301439
|
-
function createFsWatchInstance(
|
|
301743
|
+
function createFsWatchInstance(path6, options, listener, errHandler, emitRaw) {
|
|
301440
301744
|
const handleEvent = (rawEvent, evPath) => {
|
|
301441
|
-
listener(
|
|
301442
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
301443
|
-
if (evPath &&
|
|
301444
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
301745
|
+
listener(path6);
|
|
301746
|
+
emitRaw(rawEvent, evPath, { watchedPath: path6 });
|
|
301747
|
+
if (evPath && path6 !== evPath) {
|
|
301748
|
+
fsWatchBroadcast(sysPath.resolve(path6, evPath), KEY_LISTENERS, sysPath.join(path6, evPath));
|
|
301445
301749
|
}
|
|
301446
301750
|
};
|
|
301447
301751
|
try {
|
|
301448
|
-
return fs_watch(
|
|
301752
|
+
return fs_watch(path6, {
|
|
301449
301753
|
persistent: options.persistent
|
|
301450
301754
|
}, handleEvent);
|
|
301451
301755
|
} catch (error) {
|
|
@@ -301461,12 +301765,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
301461
301765
|
listener(val1, val2, val3);
|
|
301462
301766
|
});
|
|
301463
301767
|
};
|
|
301464
|
-
var setFsWatchListener = (
|
|
301768
|
+
var setFsWatchListener = (path6, fullPath, options, handlers) => {
|
|
301465
301769
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
301466
301770
|
let cont = FsWatchInstances.get(fullPath);
|
|
301467
301771
|
let watcher;
|
|
301468
301772
|
if (!options.persistent) {
|
|
301469
|
-
watcher = createFsWatchInstance(
|
|
301773
|
+
watcher = createFsWatchInstance(path6, options, listener, errHandler, rawEmitter);
|
|
301470
301774
|
if (!watcher)
|
|
301471
301775
|
return;
|
|
301472
301776
|
return watcher.close.bind(watcher);
|
|
@@ -301476,7 +301780,7 @@ var setFsWatchListener = (path5, fullPath, options, handlers) => {
|
|
|
301476
301780
|
addAndConvert(cont, KEY_ERR, errHandler);
|
|
301477
301781
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
301478
301782
|
} else {
|
|
301479
|
-
watcher = createFsWatchInstance(
|
|
301783
|
+
watcher = createFsWatchInstance(path6, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
301480
301784
|
if (!watcher)
|
|
301481
301785
|
return;
|
|
301482
301786
|
watcher.on(EV.ERROR, async (error) => {
|
|
@@ -301485,7 +301789,7 @@ var setFsWatchListener = (path5, fullPath, options, handlers) => {
|
|
|
301485
301789
|
cont.watcherUnusable = true;
|
|
301486
301790
|
if (isWindows && error.code === "EPERM") {
|
|
301487
301791
|
try {
|
|
301488
|
-
const fd = await open(
|
|
301792
|
+
const fd = await open(path6, "r");
|
|
301489
301793
|
await fd.close();
|
|
301490
301794
|
broadcastErr(error);
|
|
301491
301795
|
} catch (err) {}
|
|
@@ -301515,7 +301819,7 @@ var setFsWatchListener = (path5, fullPath, options, handlers) => {
|
|
|
301515
301819
|
};
|
|
301516
301820
|
};
|
|
301517
301821
|
var FsWatchFileInstances = new Map;
|
|
301518
|
-
var setFsWatchFileListener = (
|
|
301822
|
+
var setFsWatchFileListener = (path6, fullPath, options, handlers) => {
|
|
301519
301823
|
const { listener, rawEmitter } = handlers;
|
|
301520
301824
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
301521
301825
|
const copts = cont && cont.options;
|
|
@@ -301537,7 +301841,7 @@ var setFsWatchFileListener = (path5, fullPath, options, handlers) => {
|
|
|
301537
301841
|
});
|
|
301538
301842
|
const currmtime = curr.mtimeMs;
|
|
301539
301843
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
301540
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
301844
|
+
foreach(cont.listeners, (listener2) => listener2(path6, curr));
|
|
301541
301845
|
}
|
|
301542
301846
|
})
|
|
301543
301847
|
};
|
|
@@ -301560,13 +301864,13 @@ class NodeFsHandler {
|
|
|
301560
301864
|
this.fsw = fsW;
|
|
301561
301865
|
this._boundHandleError = (error) => fsW._handleError(error);
|
|
301562
301866
|
}
|
|
301563
|
-
_watchWithNodeFs(
|
|
301867
|
+
_watchWithNodeFs(path6, listener) {
|
|
301564
301868
|
const opts = this.fsw.options;
|
|
301565
|
-
const directory = sysPath.dirname(
|
|
301566
|
-
const basename2 = sysPath.basename(
|
|
301869
|
+
const directory = sysPath.dirname(path6);
|
|
301870
|
+
const basename2 = sysPath.basename(path6);
|
|
301567
301871
|
const parent = this.fsw._getWatchedDir(directory);
|
|
301568
301872
|
parent.add(basename2);
|
|
301569
|
-
const absolutePath = sysPath.resolve(
|
|
301873
|
+
const absolutePath = sysPath.resolve(path6);
|
|
301570
301874
|
const options = {
|
|
301571
301875
|
persistent: opts.persistent
|
|
301572
301876
|
};
|
|
@@ -301576,12 +301880,12 @@ class NodeFsHandler {
|
|
|
301576
301880
|
if (opts.usePolling) {
|
|
301577
301881
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
301578
301882
|
options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
|
|
301579
|
-
closer = setFsWatchFileListener(
|
|
301883
|
+
closer = setFsWatchFileListener(path6, absolutePath, options, {
|
|
301580
301884
|
listener,
|
|
301581
301885
|
rawEmitter: this.fsw._emitRaw
|
|
301582
301886
|
});
|
|
301583
301887
|
} else {
|
|
301584
|
-
closer = setFsWatchListener(
|
|
301888
|
+
closer = setFsWatchListener(path6, absolutePath, options, {
|
|
301585
301889
|
listener,
|
|
301586
301890
|
errHandler: this._boundHandleError,
|
|
301587
301891
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -301599,7 +301903,7 @@ class NodeFsHandler {
|
|
|
301599
301903
|
let prevStats = stats;
|
|
301600
301904
|
if (parent.has(basename2))
|
|
301601
301905
|
return;
|
|
301602
|
-
const listener = async (
|
|
301906
|
+
const listener = async (path6, newStats) => {
|
|
301603
301907
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
301604
301908
|
return;
|
|
301605
301909
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -301613,11 +301917,11 @@ class NodeFsHandler {
|
|
|
301613
301917
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
301614
301918
|
}
|
|
301615
301919
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
301616
|
-
this.fsw._closeFile(
|
|
301920
|
+
this.fsw._closeFile(path6);
|
|
301617
301921
|
prevStats = newStats2;
|
|
301618
301922
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
301619
301923
|
if (closer2)
|
|
301620
|
-
this.fsw._addPathCloser(
|
|
301924
|
+
this.fsw._addPathCloser(path6, closer2);
|
|
301621
301925
|
} else {
|
|
301622
301926
|
prevStats = newStats2;
|
|
301623
301927
|
}
|
|
@@ -301641,7 +301945,7 @@ class NodeFsHandler {
|
|
|
301641
301945
|
}
|
|
301642
301946
|
return closer;
|
|
301643
301947
|
}
|
|
301644
|
-
async _handleSymlink(entry, directory,
|
|
301948
|
+
async _handleSymlink(entry, directory, path6, item) {
|
|
301645
301949
|
if (this.fsw.closed) {
|
|
301646
301950
|
return;
|
|
301647
301951
|
}
|
|
@@ -301651,7 +301955,7 @@ class NodeFsHandler {
|
|
|
301651
301955
|
this.fsw._incrReadyCount();
|
|
301652
301956
|
let linkPath;
|
|
301653
301957
|
try {
|
|
301654
|
-
linkPath = await fsrealpath(
|
|
301958
|
+
linkPath = await fsrealpath(path6);
|
|
301655
301959
|
} catch (e) {
|
|
301656
301960
|
this.fsw._emitReady();
|
|
301657
301961
|
return true;
|
|
@@ -301661,12 +301965,12 @@ class NodeFsHandler {
|
|
|
301661
301965
|
if (dir.has(item)) {
|
|
301662
301966
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
301663
301967
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
301664
|
-
this.fsw._emit(EV.CHANGE,
|
|
301968
|
+
this.fsw._emit(EV.CHANGE, path6, entry.stats);
|
|
301665
301969
|
}
|
|
301666
301970
|
} else {
|
|
301667
301971
|
dir.add(item);
|
|
301668
301972
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
301669
|
-
this.fsw._emit(EV.ADD,
|
|
301973
|
+
this.fsw._emit(EV.ADD, path6, entry.stats);
|
|
301670
301974
|
}
|
|
301671
301975
|
this.fsw._emitReady();
|
|
301672
301976
|
return true;
|
|
@@ -301695,9 +301999,9 @@ class NodeFsHandler {
|
|
|
301695
301999
|
return;
|
|
301696
302000
|
}
|
|
301697
302001
|
const item = entry.path;
|
|
301698
|
-
let
|
|
302002
|
+
let path6 = sysPath.join(directory, item);
|
|
301699
302003
|
current.add(item);
|
|
301700
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
302004
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path6, item)) {
|
|
301701
302005
|
return;
|
|
301702
302006
|
}
|
|
301703
302007
|
if (this.fsw.closed) {
|
|
@@ -301706,8 +302010,8 @@ class NodeFsHandler {
|
|
|
301706
302010
|
}
|
|
301707
302011
|
if (item === target || !target && !previous.has(item)) {
|
|
301708
302012
|
this.fsw._incrReadyCount();
|
|
301709
|
-
|
|
301710
|
-
this._addToNodeFs(
|
|
302013
|
+
path6 = sysPath.join(dir, sysPath.relative(dir, path6));
|
|
302014
|
+
this._addToNodeFs(path6, initialAdd, wh, depth + 1);
|
|
301711
302015
|
}
|
|
301712
302016
|
}).on(EV.ERROR, this._boundHandleError);
|
|
301713
302017
|
return new Promise((resolve3, reject) => {
|
|
@@ -301756,13 +302060,13 @@ class NodeFsHandler {
|
|
|
301756
302060
|
}
|
|
301757
302061
|
return closer;
|
|
301758
302062
|
}
|
|
301759
|
-
async _addToNodeFs(
|
|
302063
|
+
async _addToNodeFs(path6, initialAdd, priorWh, depth, target) {
|
|
301760
302064
|
const ready = this.fsw._emitReady;
|
|
301761
|
-
if (this.fsw._isIgnored(
|
|
302065
|
+
if (this.fsw._isIgnored(path6) || this.fsw.closed) {
|
|
301762
302066
|
ready();
|
|
301763
302067
|
return false;
|
|
301764
302068
|
}
|
|
301765
|
-
const wh = this.fsw._getWatchHelpers(
|
|
302069
|
+
const wh = this.fsw._getWatchHelpers(path6);
|
|
301766
302070
|
if (priorWh) {
|
|
301767
302071
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
301768
302072
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -301778,8 +302082,8 @@ class NodeFsHandler {
|
|
|
301778
302082
|
const follow = this.fsw.options.followSymlinks;
|
|
301779
302083
|
let closer;
|
|
301780
302084
|
if (stats.isDirectory()) {
|
|
301781
|
-
const absPath = sysPath.resolve(
|
|
301782
|
-
const targetPath = follow ? await fsrealpath(
|
|
302085
|
+
const absPath = sysPath.resolve(path6);
|
|
302086
|
+
const targetPath = follow ? await fsrealpath(path6) : path6;
|
|
301783
302087
|
if (this.fsw.closed)
|
|
301784
302088
|
return;
|
|
301785
302089
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -301789,29 +302093,29 @@ class NodeFsHandler {
|
|
|
301789
302093
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
301790
302094
|
}
|
|
301791
302095
|
} else if (stats.isSymbolicLink()) {
|
|
301792
|
-
const targetPath = follow ? await fsrealpath(
|
|
302096
|
+
const targetPath = follow ? await fsrealpath(path6) : path6;
|
|
301793
302097
|
if (this.fsw.closed)
|
|
301794
302098
|
return;
|
|
301795
302099
|
const parent = sysPath.dirname(wh.watchPath);
|
|
301796
302100
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
301797
302101
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
301798
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
302102
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path6, wh, targetPath);
|
|
301799
302103
|
if (this.fsw.closed)
|
|
301800
302104
|
return;
|
|
301801
302105
|
if (targetPath !== undefined) {
|
|
301802
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
302106
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path6), targetPath);
|
|
301803
302107
|
}
|
|
301804
302108
|
} else {
|
|
301805
302109
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
301806
302110
|
}
|
|
301807
302111
|
ready();
|
|
301808
302112
|
if (closer)
|
|
301809
|
-
this.fsw._addPathCloser(
|
|
302113
|
+
this.fsw._addPathCloser(path6, closer);
|
|
301810
302114
|
return false;
|
|
301811
302115
|
} catch (error) {
|
|
301812
302116
|
if (this.fsw._handleError(error)) {
|
|
301813
302117
|
ready();
|
|
301814
|
-
return
|
|
302118
|
+
return path6;
|
|
301815
302119
|
}
|
|
301816
302120
|
}
|
|
301817
302121
|
}
|
|
@@ -301855,26 +302159,26 @@ function createPattern(matcher) {
|
|
|
301855
302159
|
}
|
|
301856
302160
|
return () => false;
|
|
301857
302161
|
}
|
|
301858
|
-
function normalizePath(
|
|
301859
|
-
if (typeof
|
|
302162
|
+
function normalizePath(path6) {
|
|
302163
|
+
if (typeof path6 !== "string")
|
|
301860
302164
|
throw new Error("string expected");
|
|
301861
|
-
|
|
301862
|
-
|
|
302165
|
+
path6 = sysPath2.normalize(path6);
|
|
302166
|
+
path6 = path6.replace(/\\/g, "/");
|
|
301863
302167
|
let prepend = false;
|
|
301864
|
-
if (
|
|
302168
|
+
if (path6.startsWith("//"))
|
|
301865
302169
|
prepend = true;
|
|
301866
302170
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
301867
|
-
while (
|
|
301868
|
-
|
|
302171
|
+
while (path6.match(DOUBLE_SLASH_RE2))
|
|
302172
|
+
path6 = path6.replace(DOUBLE_SLASH_RE2, "/");
|
|
301869
302173
|
if (prepend)
|
|
301870
|
-
|
|
301871
|
-
return
|
|
302174
|
+
path6 = "/" + path6;
|
|
302175
|
+
return path6;
|
|
301872
302176
|
}
|
|
301873
302177
|
function matchPatterns(patterns, testString, stats) {
|
|
301874
|
-
const
|
|
302178
|
+
const path6 = normalizePath(testString);
|
|
301875
302179
|
for (let index = 0;index < patterns.length; index++) {
|
|
301876
302180
|
const pattern = patterns[index];
|
|
301877
|
-
if (pattern(
|
|
302181
|
+
if (pattern(path6, stats)) {
|
|
301878
302182
|
return true;
|
|
301879
302183
|
}
|
|
301880
302184
|
}
|
|
@@ -301914,19 +302218,19 @@ var toUnix = (string) => {
|
|
|
301914
302218
|
}
|
|
301915
302219
|
return str;
|
|
301916
302220
|
};
|
|
301917
|
-
var normalizePathToUnix = (
|
|
301918
|
-
var normalizeIgnored = (cwd = "") => (
|
|
301919
|
-
if (typeof
|
|
301920
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
302221
|
+
var normalizePathToUnix = (path6) => toUnix(sysPath2.normalize(toUnix(path6)));
|
|
302222
|
+
var normalizeIgnored = (cwd = "") => (path6) => {
|
|
302223
|
+
if (typeof path6 === "string") {
|
|
302224
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path6) ? path6 : sysPath2.join(cwd, path6));
|
|
301921
302225
|
} else {
|
|
301922
|
-
return
|
|
302226
|
+
return path6;
|
|
301923
302227
|
}
|
|
301924
302228
|
};
|
|
301925
|
-
var getAbsolutePath = (
|
|
301926
|
-
if (sysPath2.isAbsolute(
|
|
301927
|
-
return
|
|
302229
|
+
var getAbsolutePath = (path6, cwd) => {
|
|
302230
|
+
if (sysPath2.isAbsolute(path6)) {
|
|
302231
|
+
return path6;
|
|
301928
302232
|
}
|
|
301929
|
-
return sysPath2.join(cwd,
|
|
302233
|
+
return sysPath2.join(cwd, path6);
|
|
301930
302234
|
};
|
|
301931
302235
|
var EMPTY_SET = Object.freeze(new Set);
|
|
301932
302236
|
|
|
@@ -301983,10 +302287,10 @@ var STAT_METHOD_F = "stat";
|
|
|
301983
302287
|
var STAT_METHOD_L = "lstat";
|
|
301984
302288
|
|
|
301985
302289
|
class WatchHelper {
|
|
301986
|
-
constructor(
|
|
302290
|
+
constructor(path6, follow, fsw) {
|
|
301987
302291
|
this.fsw = fsw;
|
|
301988
|
-
const watchPath =
|
|
301989
|
-
this.path =
|
|
302292
|
+
const watchPath = path6;
|
|
302293
|
+
this.path = path6 = path6.replace(REPLACER_RE, "");
|
|
301990
302294
|
this.watchPath = watchPath;
|
|
301991
302295
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
301992
302296
|
this.dirParts = [];
|
|
@@ -302099,20 +302403,20 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302099
302403
|
this._closePromise = undefined;
|
|
302100
302404
|
let paths = unifyPaths(paths_);
|
|
302101
302405
|
if (cwd) {
|
|
302102
|
-
paths = paths.map((
|
|
302103
|
-
const absPath = getAbsolutePath(
|
|
302406
|
+
paths = paths.map((path6) => {
|
|
302407
|
+
const absPath = getAbsolutePath(path6, cwd);
|
|
302104
302408
|
return absPath;
|
|
302105
302409
|
});
|
|
302106
302410
|
}
|
|
302107
|
-
paths.forEach((
|
|
302108
|
-
this._removeIgnoredPath(
|
|
302411
|
+
paths.forEach((path6) => {
|
|
302412
|
+
this._removeIgnoredPath(path6);
|
|
302109
302413
|
});
|
|
302110
302414
|
this._userIgnored = undefined;
|
|
302111
302415
|
if (!this._readyCount)
|
|
302112
302416
|
this._readyCount = 0;
|
|
302113
302417
|
this._readyCount += paths.length;
|
|
302114
|
-
Promise.all(paths.map(async (
|
|
302115
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
302418
|
+
Promise.all(paths.map(async (path6) => {
|
|
302419
|
+
const res = await this._nodeFsHandler._addToNodeFs(path6, !_internal, undefined, 0, _origAdd);
|
|
302116
302420
|
if (res)
|
|
302117
302421
|
this._emitReady();
|
|
302118
302422
|
return res;
|
|
@@ -302131,17 +302435,17 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302131
302435
|
return this;
|
|
302132
302436
|
const paths = unifyPaths(paths_);
|
|
302133
302437
|
const { cwd } = this.options;
|
|
302134
|
-
paths.forEach((
|
|
302135
|
-
if (!sysPath2.isAbsolute(
|
|
302438
|
+
paths.forEach((path6) => {
|
|
302439
|
+
if (!sysPath2.isAbsolute(path6) && !this._closers.has(path6)) {
|
|
302136
302440
|
if (cwd)
|
|
302137
|
-
|
|
302138
|
-
|
|
302441
|
+
path6 = sysPath2.join(cwd, path6);
|
|
302442
|
+
path6 = sysPath2.resolve(path6);
|
|
302139
302443
|
}
|
|
302140
|
-
this._closePath(
|
|
302141
|
-
this._addIgnoredPath(
|
|
302142
|
-
if (this._watched.has(
|
|
302444
|
+
this._closePath(path6);
|
|
302445
|
+
this._addIgnoredPath(path6);
|
|
302446
|
+
if (this._watched.has(path6)) {
|
|
302143
302447
|
this._addIgnoredPath({
|
|
302144
|
-
path:
|
|
302448
|
+
path: path6,
|
|
302145
302449
|
recursive: true
|
|
302146
302450
|
});
|
|
302147
302451
|
}
|
|
@@ -302190,38 +302494,38 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302190
302494
|
if (event !== EVENTS.ERROR)
|
|
302191
302495
|
this.emit(EVENTS.ALL, event, ...args);
|
|
302192
302496
|
}
|
|
302193
|
-
async _emit(event,
|
|
302497
|
+
async _emit(event, path6, stats) {
|
|
302194
302498
|
if (this.closed)
|
|
302195
302499
|
return;
|
|
302196
302500
|
const opts = this.options;
|
|
302197
302501
|
if (isWindows)
|
|
302198
|
-
|
|
302502
|
+
path6 = sysPath2.normalize(path6);
|
|
302199
302503
|
if (opts.cwd)
|
|
302200
|
-
|
|
302201
|
-
const args = [
|
|
302504
|
+
path6 = sysPath2.relative(opts.cwd, path6);
|
|
302505
|
+
const args = [path6];
|
|
302202
302506
|
if (stats != null)
|
|
302203
302507
|
args.push(stats);
|
|
302204
302508
|
const awf = opts.awaitWriteFinish;
|
|
302205
302509
|
let pw;
|
|
302206
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
302510
|
+
if (awf && (pw = this._pendingWrites.get(path6))) {
|
|
302207
302511
|
pw.lastChange = new Date;
|
|
302208
302512
|
return this;
|
|
302209
302513
|
}
|
|
302210
302514
|
if (opts.atomic) {
|
|
302211
302515
|
if (event === EVENTS.UNLINK) {
|
|
302212
|
-
this._pendingUnlinks.set(
|
|
302516
|
+
this._pendingUnlinks.set(path6, [event, ...args]);
|
|
302213
302517
|
setTimeout(() => {
|
|
302214
|
-
this._pendingUnlinks.forEach((entry,
|
|
302518
|
+
this._pendingUnlinks.forEach((entry, path7) => {
|
|
302215
302519
|
this.emit(...entry);
|
|
302216
302520
|
this.emit(EVENTS.ALL, ...entry);
|
|
302217
|
-
this._pendingUnlinks.delete(
|
|
302521
|
+
this._pendingUnlinks.delete(path7);
|
|
302218
302522
|
});
|
|
302219
302523
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
302220
302524
|
return this;
|
|
302221
302525
|
}
|
|
302222
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
302526
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path6)) {
|
|
302223
302527
|
event = EVENTS.CHANGE;
|
|
302224
|
-
this._pendingUnlinks.delete(
|
|
302528
|
+
this._pendingUnlinks.delete(path6);
|
|
302225
302529
|
}
|
|
302226
302530
|
}
|
|
302227
302531
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -302239,16 +302543,16 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302239
302543
|
this.emitWithAll(event, args);
|
|
302240
302544
|
}
|
|
302241
302545
|
};
|
|
302242
|
-
this._awaitWriteFinish(
|
|
302546
|
+
this._awaitWriteFinish(path6, awf.stabilityThreshold, event, awfEmit);
|
|
302243
302547
|
return this;
|
|
302244
302548
|
}
|
|
302245
302549
|
if (event === EVENTS.CHANGE) {
|
|
302246
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
302550
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path6, 50);
|
|
302247
302551
|
if (isThrottled)
|
|
302248
302552
|
return this;
|
|
302249
302553
|
}
|
|
302250
302554
|
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
302251
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
302555
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path6) : path6;
|
|
302252
302556
|
let stats2;
|
|
302253
302557
|
try {
|
|
302254
302558
|
stats2 = await stat3(fullPath);
|
|
@@ -302267,23 +302571,23 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302267
302571
|
}
|
|
302268
302572
|
return error || this.closed;
|
|
302269
302573
|
}
|
|
302270
|
-
_throttle(actionType,
|
|
302574
|
+
_throttle(actionType, path6, timeout) {
|
|
302271
302575
|
if (!this._throttled.has(actionType)) {
|
|
302272
302576
|
this._throttled.set(actionType, new Map);
|
|
302273
302577
|
}
|
|
302274
302578
|
const action = this._throttled.get(actionType);
|
|
302275
302579
|
if (!action)
|
|
302276
302580
|
throw new Error("invalid throttle");
|
|
302277
|
-
const actionPath = action.get(
|
|
302581
|
+
const actionPath = action.get(path6);
|
|
302278
302582
|
if (actionPath) {
|
|
302279
302583
|
actionPath.count++;
|
|
302280
302584
|
return false;
|
|
302281
302585
|
}
|
|
302282
302586
|
let timeoutObject;
|
|
302283
302587
|
const clear = () => {
|
|
302284
|
-
const item = action.get(
|
|
302588
|
+
const item = action.get(path6);
|
|
302285
302589
|
const count = item ? item.count : 0;
|
|
302286
|
-
action.delete(
|
|
302590
|
+
action.delete(path6);
|
|
302287
302591
|
clearTimeout(timeoutObject);
|
|
302288
302592
|
if (item)
|
|
302289
302593
|
clearTimeout(item.timeoutObject);
|
|
@@ -302291,50 +302595,50 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302291
302595
|
};
|
|
302292
302596
|
timeoutObject = setTimeout(clear, timeout);
|
|
302293
302597
|
const thr = { timeoutObject, clear, count: 0 };
|
|
302294
|
-
action.set(
|
|
302598
|
+
action.set(path6, thr);
|
|
302295
302599
|
return thr;
|
|
302296
302600
|
}
|
|
302297
302601
|
_incrReadyCount() {
|
|
302298
302602
|
return this._readyCount++;
|
|
302299
302603
|
}
|
|
302300
|
-
_awaitWriteFinish(
|
|
302604
|
+
_awaitWriteFinish(path6, threshold, event, awfEmit) {
|
|
302301
302605
|
const awf = this.options.awaitWriteFinish;
|
|
302302
302606
|
if (typeof awf !== "object")
|
|
302303
302607
|
return;
|
|
302304
302608
|
const pollInterval = awf.pollInterval;
|
|
302305
302609
|
let timeoutHandler;
|
|
302306
|
-
let fullPath =
|
|
302307
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
302308
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
302610
|
+
let fullPath = path6;
|
|
302611
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path6)) {
|
|
302612
|
+
fullPath = sysPath2.join(this.options.cwd, path6);
|
|
302309
302613
|
}
|
|
302310
302614
|
const now = new Date;
|
|
302311
302615
|
const writes = this._pendingWrites;
|
|
302312
302616
|
function awaitWriteFinishFn(prevStat) {
|
|
302313
302617
|
statcb(fullPath, (err, curStat) => {
|
|
302314
|
-
if (err || !writes.has(
|
|
302618
|
+
if (err || !writes.has(path6)) {
|
|
302315
302619
|
if (err && err.code !== "ENOENT")
|
|
302316
302620
|
awfEmit(err);
|
|
302317
302621
|
return;
|
|
302318
302622
|
}
|
|
302319
302623
|
const now2 = Number(new Date);
|
|
302320
302624
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
302321
|
-
writes.get(
|
|
302625
|
+
writes.get(path6).lastChange = now2;
|
|
302322
302626
|
}
|
|
302323
|
-
const pw = writes.get(
|
|
302627
|
+
const pw = writes.get(path6);
|
|
302324
302628
|
const df = now2 - pw.lastChange;
|
|
302325
302629
|
if (df >= threshold) {
|
|
302326
|
-
writes.delete(
|
|
302630
|
+
writes.delete(path6);
|
|
302327
302631
|
awfEmit(undefined, curStat);
|
|
302328
302632
|
} else {
|
|
302329
302633
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
302330
302634
|
}
|
|
302331
302635
|
});
|
|
302332
302636
|
}
|
|
302333
|
-
if (!writes.has(
|
|
302334
|
-
writes.set(
|
|
302637
|
+
if (!writes.has(path6)) {
|
|
302638
|
+
writes.set(path6, {
|
|
302335
302639
|
lastChange: now,
|
|
302336
302640
|
cancelWait: () => {
|
|
302337
|
-
writes.delete(
|
|
302641
|
+
writes.delete(path6);
|
|
302338
302642
|
clearTimeout(timeoutHandler);
|
|
302339
302643
|
return event;
|
|
302340
302644
|
}
|
|
@@ -302342,8 +302646,8 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302342
302646
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
302343
302647
|
}
|
|
302344
302648
|
}
|
|
302345
|
-
_isIgnored(
|
|
302346
|
-
if (this.options.atomic && DOT_RE.test(
|
|
302649
|
+
_isIgnored(path6, stats) {
|
|
302650
|
+
if (this.options.atomic && DOT_RE.test(path6))
|
|
302347
302651
|
return true;
|
|
302348
302652
|
if (!this._userIgnored) {
|
|
302349
302653
|
const { cwd } = this.options;
|
|
@@ -302353,13 +302657,13 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302353
302657
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
302354
302658
|
this._userIgnored = anymatch(list, undefined);
|
|
302355
302659
|
}
|
|
302356
|
-
return this._userIgnored(
|
|
302660
|
+
return this._userIgnored(path6, stats);
|
|
302357
302661
|
}
|
|
302358
|
-
_isntIgnored(
|
|
302359
|
-
return !this._isIgnored(
|
|
302662
|
+
_isntIgnored(path6, stat4) {
|
|
302663
|
+
return !this._isIgnored(path6, stat4);
|
|
302360
302664
|
}
|
|
302361
|
-
_getWatchHelpers(
|
|
302362
|
-
return new WatchHelper(
|
|
302665
|
+
_getWatchHelpers(path6) {
|
|
302666
|
+
return new WatchHelper(path6, this.options.followSymlinks, this);
|
|
302363
302667
|
}
|
|
302364
302668
|
_getWatchedDir(directory) {
|
|
302365
302669
|
const dir = sysPath2.resolve(directory);
|
|
@@ -302373,57 +302677,57 @@ class FSWatcher extends EventEmitter2 {
|
|
|
302373
302677
|
return Boolean(Number(stats.mode) & 256);
|
|
302374
302678
|
}
|
|
302375
302679
|
_remove(directory, item, isDirectory) {
|
|
302376
|
-
const
|
|
302377
|
-
const fullPath = sysPath2.resolve(
|
|
302378
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
302379
|
-
if (!this._throttle("remove",
|
|
302680
|
+
const path6 = sysPath2.join(directory, item);
|
|
302681
|
+
const fullPath = sysPath2.resolve(path6);
|
|
302682
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path6) || this._watched.has(fullPath);
|
|
302683
|
+
if (!this._throttle("remove", path6, 100))
|
|
302380
302684
|
return;
|
|
302381
302685
|
if (!isDirectory && this._watched.size === 1) {
|
|
302382
302686
|
this.add(directory, item, true);
|
|
302383
302687
|
}
|
|
302384
|
-
const wp = this._getWatchedDir(
|
|
302688
|
+
const wp = this._getWatchedDir(path6);
|
|
302385
302689
|
const nestedDirectoryChildren = wp.getChildren();
|
|
302386
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
302690
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path6, nested));
|
|
302387
302691
|
const parent = this._getWatchedDir(directory);
|
|
302388
302692
|
const wasTracked = parent.has(item);
|
|
302389
302693
|
parent.remove(item);
|
|
302390
302694
|
if (this._symlinkPaths.has(fullPath)) {
|
|
302391
302695
|
this._symlinkPaths.delete(fullPath);
|
|
302392
302696
|
}
|
|
302393
|
-
let relPath =
|
|
302697
|
+
let relPath = path6;
|
|
302394
302698
|
if (this.options.cwd)
|
|
302395
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
302699
|
+
relPath = sysPath2.relative(this.options.cwd, path6);
|
|
302396
302700
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
302397
302701
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
302398
302702
|
if (event === EVENTS.ADD)
|
|
302399
302703
|
return;
|
|
302400
302704
|
}
|
|
302401
|
-
this._watched.delete(
|
|
302705
|
+
this._watched.delete(path6);
|
|
302402
302706
|
this._watched.delete(fullPath);
|
|
302403
302707
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
302404
|
-
if (wasTracked && !this._isIgnored(
|
|
302405
|
-
this._emit(eventName,
|
|
302406
|
-
this._closePath(
|
|
302708
|
+
if (wasTracked && !this._isIgnored(path6))
|
|
302709
|
+
this._emit(eventName, path6);
|
|
302710
|
+
this._closePath(path6);
|
|
302407
302711
|
}
|
|
302408
|
-
_closePath(
|
|
302409
|
-
this._closeFile(
|
|
302410
|
-
const dir = sysPath2.dirname(
|
|
302411
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
302712
|
+
_closePath(path6) {
|
|
302713
|
+
this._closeFile(path6);
|
|
302714
|
+
const dir = sysPath2.dirname(path6);
|
|
302715
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path6));
|
|
302412
302716
|
}
|
|
302413
|
-
_closeFile(
|
|
302414
|
-
const closers = this._closers.get(
|
|
302717
|
+
_closeFile(path6) {
|
|
302718
|
+
const closers = this._closers.get(path6);
|
|
302415
302719
|
if (!closers)
|
|
302416
302720
|
return;
|
|
302417
302721
|
closers.forEach((closer) => closer());
|
|
302418
|
-
this._closers.delete(
|
|
302722
|
+
this._closers.delete(path6);
|
|
302419
302723
|
}
|
|
302420
|
-
_addPathCloser(
|
|
302724
|
+
_addPathCloser(path6, closer) {
|
|
302421
302725
|
if (!closer)
|
|
302422
302726
|
return;
|
|
302423
|
-
let list = this._closers.get(
|
|
302727
|
+
let list = this._closers.get(path6);
|
|
302424
302728
|
if (!list) {
|
|
302425
302729
|
list = [];
|
|
302426
|
-
this._closers.set(
|
|
302730
|
+
this._closers.set(path6, list);
|
|
302427
302731
|
}
|
|
302428
302732
|
list.push(closer);
|
|
302429
302733
|
}
|
|
@@ -302457,7 +302761,7 @@ init_errors();
|
|
|
302457
302761
|
init_logger();
|
|
302458
302762
|
init_path_safety();
|
|
302459
302763
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
302460
|
-
import
|
|
302764
|
+
import path13 from "path";
|
|
302461
302765
|
|
|
302462
302766
|
// src/service/environment_store.ts
|
|
302463
302767
|
var import_client_s33 = __toESM(require_dist_cjs75(), 1);
|
|
@@ -302465,8 +302769,8 @@ import { Storage as Storage2 } from "@google-cloud/storage";
|
|
|
302465
302769
|
var import_extract_zip = __toESM(require_extract_zip(), 1);
|
|
302466
302770
|
import crypto5 from "crypto";
|
|
302467
302771
|
import * as fs9 from "fs";
|
|
302468
|
-
import * as
|
|
302469
|
-
import * as
|
|
302772
|
+
import * as os3 from "os";
|
|
302773
|
+
import * as path12 from "path";
|
|
302470
302774
|
|
|
302471
302775
|
// ../../node_modules/simple-git/dist/esm/index.js
|
|
302472
302776
|
var import_file_exists = __toESM(require_dist12(), 1);
|
|
@@ -302504,8 +302808,8 @@ function pathspec(...paths) {
|
|
|
302504
302808
|
cache.set(key, paths);
|
|
302505
302809
|
return key;
|
|
302506
302810
|
}
|
|
302507
|
-
function isPathSpec(
|
|
302508
|
-
return
|
|
302811
|
+
function isPathSpec(path6) {
|
|
302812
|
+
return path6 instanceof String && cache.has(path6);
|
|
302509
302813
|
}
|
|
302510
302814
|
function toPaths(pathSpec) {
|
|
302511
302815
|
return cache.get(pathSpec) || [];
|
|
@@ -302591,8 +302895,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = `
|
|
|
302591
302895
|
function forEachLineWithContent(input, callback) {
|
|
302592
302896
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
302593
302897
|
}
|
|
302594
|
-
function folderExists(
|
|
302595
|
-
return import_file_exists.exists(
|
|
302898
|
+
function folderExists(path6) {
|
|
302899
|
+
return import_file_exists.exists(path6, import_file_exists.FOLDER);
|
|
302596
302900
|
}
|
|
302597
302901
|
function append2(target, item) {
|
|
302598
302902
|
if (Array.isArray(target)) {
|
|
@@ -302973,8 +303277,8 @@ function checkIsRepoRootTask() {
|
|
|
302973
303277
|
commands,
|
|
302974
303278
|
format: "utf-8",
|
|
302975
303279
|
onError,
|
|
302976
|
-
parser(
|
|
302977
|
-
return /^\.(git)?$/.test(
|
|
303280
|
+
parser(path6) {
|
|
303281
|
+
return /^\.(git)?$/.test(path6.trim());
|
|
302978
303282
|
}
|
|
302979
303283
|
};
|
|
302980
303284
|
}
|
|
@@ -303385,11 +303689,11 @@ function parseGrep(grep) {
|
|
|
303385
303689
|
const paths = /* @__PURE__ */ new Set;
|
|
303386
303690
|
const results = {};
|
|
303387
303691
|
forEachLineWithContent(grep, (input) => {
|
|
303388
|
-
const [
|
|
303389
|
-
paths.add(
|
|
303390
|
-
(results[
|
|
303692
|
+
const [path6, line, preview] = input.split(NULL);
|
|
303693
|
+
paths.add(path6);
|
|
303694
|
+
(results[path6] = results[path6] || []).push({
|
|
303391
303695
|
line: asNumber(line),
|
|
303392
|
-
path:
|
|
303696
|
+
path: path6,
|
|
303393
303697
|
preview
|
|
303394
303698
|
});
|
|
303395
303699
|
});
|
|
@@ -304051,14 +304355,14 @@ var init_hash_object = __esm2({
|
|
|
304051
304355
|
init_task();
|
|
304052
304356
|
}
|
|
304053
304357
|
});
|
|
304054
|
-
function parseInit(bare,
|
|
304358
|
+
function parseInit(bare, path6, text) {
|
|
304055
304359
|
const response = String(text).trim();
|
|
304056
304360
|
let result;
|
|
304057
304361
|
if (result = initResponseRegex.exec(response)) {
|
|
304058
|
-
return new InitSummary(bare,
|
|
304362
|
+
return new InitSummary(bare, path6, false, result[1]);
|
|
304059
304363
|
}
|
|
304060
304364
|
if (result = reInitResponseRegex.exec(response)) {
|
|
304061
|
-
return new InitSummary(bare,
|
|
304365
|
+
return new InitSummary(bare, path6, true, result[1]);
|
|
304062
304366
|
}
|
|
304063
304367
|
let gitDir = "";
|
|
304064
304368
|
const tokens = response.split(" ");
|
|
@@ -304069,7 +304373,7 @@ function parseInit(bare, path5, text) {
|
|
|
304069
304373
|
break;
|
|
304070
304374
|
}
|
|
304071
304375
|
}
|
|
304072
|
-
return new InitSummary(bare,
|
|
304376
|
+
return new InitSummary(bare, path6, /^re/i.test(response), gitDir);
|
|
304073
304377
|
}
|
|
304074
304378
|
var InitSummary;
|
|
304075
304379
|
var initResponseRegex;
|
|
@@ -304077,9 +304381,9 @@ var reInitResponseRegex;
|
|
|
304077
304381
|
var init_InitSummary = __esm2({
|
|
304078
304382
|
"src/lib/responses/InitSummary.ts"() {
|
|
304079
304383
|
InitSummary = class {
|
|
304080
|
-
constructor(bare,
|
|
304384
|
+
constructor(bare, path6, existing, gitDir) {
|
|
304081
304385
|
this.bare = bare;
|
|
304082
|
-
this.path =
|
|
304386
|
+
this.path = path6;
|
|
304083
304387
|
this.existing = existing;
|
|
304084
304388
|
this.gitDir = gitDir;
|
|
304085
304389
|
}
|
|
@@ -304091,7 +304395,7 @@ var init_InitSummary = __esm2({
|
|
|
304091
304395
|
function hasBareCommand(command) {
|
|
304092
304396
|
return command.includes(bareCommand);
|
|
304093
304397
|
}
|
|
304094
|
-
function initTask(bare = false,
|
|
304398
|
+
function initTask(bare = false, path6, customArgs) {
|
|
304095
304399
|
const commands = ["init", ...customArgs];
|
|
304096
304400
|
if (bare && !hasBareCommand(commands)) {
|
|
304097
304401
|
commands.splice(1, 0, bareCommand);
|
|
@@ -304100,7 +304404,7 @@ function initTask(bare = false, path5, customArgs) {
|
|
|
304100
304404
|
commands,
|
|
304101
304405
|
format: "utf-8",
|
|
304102
304406
|
parser(text) {
|
|
304103
|
-
return parseInit(commands.includes("--bare"),
|
|
304407
|
+
return parseInit(commands.includes("--bare"), path6, text);
|
|
304104
304408
|
}
|
|
304105
304409
|
};
|
|
304106
304410
|
}
|
|
@@ -304815,12 +305119,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
304815
305119
|
"src/lib/responses/FileStatusSummary.ts"() {
|
|
304816
305120
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
304817
305121
|
FileStatusSummary = class {
|
|
304818
|
-
constructor(
|
|
304819
|
-
this.path =
|
|
305122
|
+
constructor(path6, index, working_dir) {
|
|
305123
|
+
this.path = path6;
|
|
304820
305124
|
this.index = index;
|
|
304821
305125
|
this.working_dir = working_dir;
|
|
304822
305126
|
if (index === "R" || working_dir === "R") {
|
|
304823
|
-
const detail = fromPathRegex.exec(
|
|
305127
|
+
const detail = fromPathRegex.exec(path6) || [null, path6, path6];
|
|
304824
305128
|
this.from = detail[2] || "";
|
|
304825
305129
|
this.path = detail[1] || "";
|
|
304826
305130
|
}
|
|
@@ -304851,14 +305155,14 @@ function splitLine(result, lineStr) {
|
|
|
304851
305155
|
default:
|
|
304852
305156
|
return;
|
|
304853
305157
|
}
|
|
304854
|
-
function data(index, workingDir,
|
|
305158
|
+
function data(index, workingDir, path6) {
|
|
304855
305159
|
const raw = `${index}${workingDir}`;
|
|
304856
305160
|
const handler = parsers6.get(raw);
|
|
304857
305161
|
if (handler) {
|
|
304858
|
-
handler(result,
|
|
305162
|
+
handler(result, path6);
|
|
304859
305163
|
}
|
|
304860
305164
|
if (raw !== "##" && raw !== "!!") {
|
|
304861
|
-
result.files.push(new FileStatusSummary(
|
|
305165
|
+
result.files.push(new FileStatusSummary(path6, index, workingDir));
|
|
304862
305166
|
}
|
|
304863
305167
|
}
|
|
304864
305168
|
}
|
|
@@ -305089,8 +305393,8 @@ var init_simple_git_api = __esm2({
|
|
|
305089
305393
|
}
|
|
305090
305394
|
return this._runTask(configurationErrorTask("Git.cwd: workingDirectory must be supplied as a string"), next);
|
|
305091
305395
|
}
|
|
305092
|
-
hashObject(
|
|
305093
|
-
return this._runTask(hashObjectTask(
|
|
305396
|
+
hashObject(path6, write) {
|
|
305397
|
+
return this._runTask(hashObjectTask(path6, write === true), trailingFunctionArgument(arguments));
|
|
305094
305398
|
}
|
|
305095
305399
|
init(bare) {
|
|
305096
305400
|
return this._runTask(initTask(bare === true, this._executor.cwd, getTrailingOptions(arguments)), trailingFunctionArgument(arguments));
|
|
@@ -305667,8 +305971,8 @@ __export2(sub_module_exports, {
|
|
|
305667
305971
|
subModuleTask: () => subModuleTask,
|
|
305668
305972
|
updateSubModuleTask: () => updateSubModuleTask
|
|
305669
305973
|
});
|
|
305670
|
-
function addSubModuleTask(repo,
|
|
305671
|
-
return subModuleTask(["add", repo,
|
|
305974
|
+
function addSubModuleTask(repo, path6) {
|
|
305975
|
+
return subModuleTask(["add", repo, path6]);
|
|
305672
305976
|
}
|
|
305673
305977
|
function initSubModuleTask(customArgs) {
|
|
305674
305978
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -305936,8 +306240,8 @@ var require_git = __commonJS2({
|
|
|
305936
306240
|
}
|
|
305937
306241
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
305938
306242
|
};
|
|
305939
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
305940
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
306243
|
+
Git2.prototype.submoduleAdd = function(repo, path6, then) {
|
|
306244
|
+
return this._runTask(addSubModuleTask2(repo, path6), trailingFunctionArgument2(arguments));
|
|
305941
306245
|
};
|
|
305942
306246
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
305943
306247
|
return this._runTask(updateSubModuleTask2(getTrailingOptions2(arguments, true)), trailingFunctionArgument2(arguments));
|
|
@@ -306570,7 +306874,7 @@ init_config();
|
|
|
306570
306874
|
import {
|
|
306571
306875
|
DuckDBInstance
|
|
306572
306876
|
} from "@duckdb/node-api";
|
|
306573
|
-
import * as
|
|
306877
|
+
import * as path6 from "path";
|
|
306574
306878
|
function duckDBInstanceResourceOptions() {
|
|
306575
306879
|
const options = {};
|
|
306576
306880
|
const memoryLimit = getDuckDBMemoryLimit();
|
|
@@ -306590,7 +306894,7 @@ class DuckDBConnection2 {
|
|
|
306590
306894
|
dbPath;
|
|
306591
306895
|
mutex = new Mutex;
|
|
306592
306896
|
constructor(dbPath) {
|
|
306593
|
-
this.dbPath = dbPath ||
|
|
306897
|
+
this.dbPath = dbPath || path6.join(process.cwd(), "publisher.db");
|
|
306594
306898
|
}
|
|
306595
306899
|
async initialize() {
|
|
306596
306900
|
try {
|
|
@@ -307051,7 +307355,6 @@ var ACTIVE_STATUSES = [
|
|
|
307051
307355
|
function activeKeyFor(environmentId, packageName) {
|
|
307052
307356
|
return `${environmentId}|${packageName}`;
|
|
307053
307357
|
}
|
|
307054
|
-
var DEFAULT_ENVIRONMENT_LIST_LIMIT = 500;
|
|
307055
307358
|
|
|
307056
307359
|
class DuplicateActiveMaterializationError extends Error {
|
|
307057
307360
|
constructor(environmentId, packageName) {
|
|
@@ -307084,18 +307387,6 @@ class MaterializationRepository {
|
|
|
307084
307387
|
const rows = await this.db.all(sql, params);
|
|
307085
307388
|
return rows.map(this.mapRow);
|
|
307086
307389
|
}
|
|
307087
|
-
async listByEnvironment(environmentId, options) {
|
|
307088
|
-
let sql = "SELECT * FROM materializations WHERE environment_id = ? ORDER BY created_at DESC";
|
|
307089
|
-
const params = [environmentId];
|
|
307090
|
-
sql += " LIMIT ?";
|
|
307091
|
-
params.push(options?.limit ?? DEFAULT_ENVIRONMENT_LIST_LIMIT);
|
|
307092
|
-
if (options?.offset !== undefined) {
|
|
307093
|
-
sql += " OFFSET ?";
|
|
307094
|
-
params.push(options.offset);
|
|
307095
|
-
}
|
|
307096
|
-
const rows = await this.db.all(sql, params);
|
|
307097
|
-
return rows.map(this.mapRow);
|
|
307098
|
-
}
|
|
307099
307390
|
async getLatestScheduledFireAt(environmentId, packageName) {
|
|
307100
307391
|
const row = await this.db.get(`SELECT created_at FROM materializations
|
|
307101
307392
|
WHERE environment_id = ? AND package_name = ?
|
|
@@ -307426,9 +307717,6 @@ class DuckDBRepository {
|
|
|
307426
307717
|
async listMaterializations(environmentId, packageName, options) {
|
|
307427
307718
|
return this.materializationRepo.list(environmentId, packageName, options);
|
|
307428
307719
|
}
|
|
307429
|
-
async listMaterializationsByEnvironment(environmentId, options) {
|
|
307430
|
-
return this.materializationRepo.listByEnvironment(environmentId, options);
|
|
307431
|
-
}
|
|
307432
307720
|
async getLatestScheduledFireAt(environmentId, packageName) {
|
|
307433
307721
|
return this.materializationRepo.getLatestScheduledFireAt(environmentId, packageName);
|
|
307434
307722
|
}
|
|
@@ -307899,7 +308187,7 @@ init_config();
|
|
|
307899
308187
|
init_logger();
|
|
307900
308188
|
import crypto4 from "crypto";
|
|
307901
308189
|
import * as fs8 from "fs";
|
|
307902
|
-
import * as
|
|
308190
|
+
import * as path11 from "path";
|
|
307903
308191
|
import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL2 } from "url";
|
|
307904
308192
|
init_materialization_metrics();
|
|
307905
308193
|
init_path_safety();
|
|
@@ -308009,7 +308297,7 @@ init_logger();
|
|
|
308009
308297
|
init_materialization_metrics();
|
|
308010
308298
|
var import_recursive_readdir = __toESM(require_recursive_readdir(), 1);
|
|
308011
308299
|
import * as fs7 from "fs/promises";
|
|
308012
|
-
import * as
|
|
308300
|
+
import * as path10 from "path";
|
|
308013
308301
|
import"@malloydata/db-duckdb/native";
|
|
308014
308302
|
import { DuckDBConnection as DuckDBConnection3 } from "@malloydata/db-duckdb";
|
|
308015
308303
|
import {
|
|
@@ -309123,7 +309411,7 @@ class Package {
|
|
|
309123
309411
|
});
|
|
309124
309412
|
}
|
|
309125
309413
|
if (sm.modelPath.endsWith(MODEL_FILE_SUFFIX)) {
|
|
309126
|
-
const modelSource = await fs7.readFile(
|
|
309414
|
+
const modelSource = await fs7.readFile(path10.join(packagePath, sm.modelPath), "utf-8");
|
|
309127
309415
|
assertPersistNamesQuoted(modelSource, sm.modelPath);
|
|
309128
309416
|
}
|
|
309129
309417
|
models.set(sm.modelPath, model);
|
|
@@ -310128,16 +310416,16 @@ class Package {
|
|
|
310128
310416
|
static async getDatabasePaths(packagePath) {
|
|
310129
310417
|
const files = await import_recursive_readdir.default(packagePath, [ignoreDotfiles]);
|
|
310130
310418
|
return files.map((fullPath) => {
|
|
310131
|
-
return
|
|
310419
|
+
return path10.relative(packagePath, fullPath).replace(/\\/g, "/");
|
|
310132
310420
|
}).filter((modelPath) => {
|
|
310133
|
-
if (
|
|
310421
|
+
if (path10.basename(modelPath).startsWith("~$")) {
|
|
310134
310422
|
return false;
|
|
310135
310423
|
}
|
|
310136
310424
|
return modelPath.endsWith(".parquet") || modelPath.endsWith(".csv") || modelPath.endsWith(".xlsx");
|
|
310137
310425
|
});
|
|
310138
310426
|
}
|
|
310139
310427
|
static async getDatabaseInfo(packagePath, databasePath, conn) {
|
|
310140
|
-
const fullPath =
|
|
310428
|
+
const fullPath = path10.join(packagePath, databasePath);
|
|
310141
310429
|
const runtime = new ConnectionRuntime({
|
|
310142
310430
|
urlReader: new EmptyURLReader,
|
|
310143
310431
|
connections: [conn]
|
|
@@ -310251,7 +310539,7 @@ class Environment {
|
|
|
310251
310539
|
async writeEnvironmentReadme(readme) {
|
|
310252
310540
|
if (readme === undefined)
|
|
310253
310541
|
return;
|
|
310254
|
-
const readmePath =
|
|
310542
|
+
const readmePath = path11.join(this.environmentPath, "README.md");
|
|
310255
310543
|
try {
|
|
310256
310544
|
await fs8.promises.writeFile(readmePath, readme, "utf-8");
|
|
310257
310545
|
logger.info(`Updated README.md for environment ${this.environmentName}`);
|
|
@@ -310345,8 +310633,8 @@ class Environment {
|
|
|
310345
310633
|
return this.withPackageLock(packageName, async () => {
|
|
310346
310634
|
const modelPath = safeJoinUnderRoot(this.environmentPath, packageName, modelName);
|
|
310347
310635
|
const packagePath = safeJoinUnderRoot(this.environmentPath, packageName);
|
|
310348
|
-
const modelDir =
|
|
310349
|
-
const virtualUrl = scope === "append" ? pathToFileURL2(
|
|
310636
|
+
const modelDir = path11.dirname(modelPath);
|
|
310637
|
+
const virtualUrl = scope === "append" ? pathToFileURL2(path11.join(modelDir, "__compile_check.malloy")) : pathToFileURL2(modelPath);
|
|
310350
310638
|
const virtualUri = virtualUrl.toString();
|
|
310351
310639
|
let fullSource = source ?? "";
|
|
310352
310640
|
if (scope === "append") {
|
|
@@ -310395,8 +310683,8 @@ ${source}` : source ?? "";
|
|
|
310395
310683
|
let model;
|
|
310396
310684
|
if (url2 && url2.startsWith("file:")) {
|
|
310397
310685
|
try {
|
|
310398
|
-
const rel =
|
|
310399
|
-
if (!rel.startsWith("..") && !
|
|
310686
|
+
const rel = path11.relative(packagePath, fileURLToPath6(url2));
|
|
310687
|
+
if (!rel.startsWith("..") && !path11.isAbsolute(rel)) {
|
|
310400
310688
|
model = rel;
|
|
310401
310689
|
}
|
|
310402
310690
|
} catch {}
|
|
@@ -310683,6 +310971,49 @@ ${source}` : source ?? "";
|
|
|
310683
310971
|
assertSafePackageName(packageName);
|
|
310684
310972
|
return this.getOrCreatePackageMutex(packageName).runExclusive(fn);
|
|
310685
310973
|
}
|
|
310974
|
+
async _readModelFileLocked(target) {
|
|
310975
|
+
try {
|
|
310976
|
+
return await fs8.promises.readFile(target, "utf8");
|
|
310977
|
+
} catch (error) {
|
|
310978
|
+
if (error.code !== "ENOENT")
|
|
310979
|
+
throw error;
|
|
310980
|
+
return;
|
|
310981
|
+
}
|
|
310982
|
+
}
|
|
310983
|
+
async _writeModelFileLocked(target, source) {
|
|
310984
|
+
await fs8.promises.mkdir(path11.dirname(target), { recursive: true });
|
|
310985
|
+
const temporary = `${target}.${crypto4.randomUUID()}.tmp`;
|
|
310986
|
+
await fs8.promises.writeFile(temporary, source, "utf8");
|
|
310987
|
+
await fs8.promises.rename(temporary, target);
|
|
310988
|
+
}
|
|
310989
|
+
async writeModelFileTransactional(packageName, modelPath, source, check, verify) {
|
|
310990
|
+
assertSafePackageName(packageName);
|
|
310991
|
+
assertSafeRelativeModelPath(modelPath);
|
|
310992
|
+
return this.withPackageLock(packageName, async () => {
|
|
310993
|
+
const target = safeJoinUnderRoot(this.environmentPath, packageName, modelPath);
|
|
310994
|
+
const previous = await this._readModelFileLocked(target);
|
|
310995
|
+
check(previous);
|
|
310996
|
+
await this._writeModelFileLocked(target, source);
|
|
310997
|
+
try {
|
|
310998
|
+
const reloaded = await this._loadOrGetPackageLocked(packageName, true);
|
|
310999
|
+
return { previous, verified: await verify(reloaded) };
|
|
311000
|
+
} catch (error) {
|
|
311001
|
+
if (previous !== undefined)
|
|
311002
|
+
await this._writeModelFileLocked(target, previous);
|
|
311003
|
+
else
|
|
311004
|
+
await fs8.promises.rm(target, { force: true });
|
|
311005
|
+
await this._loadOrGetPackageLocked(packageName, true).catch(() => {
|
|
311006
|
+
return;
|
|
311007
|
+
});
|
|
311008
|
+
logger.warn("Dashboard write rolled back", {
|
|
311009
|
+
packageName,
|
|
311010
|
+
modelPath,
|
|
311011
|
+
error
|
|
311012
|
+
});
|
|
311013
|
+
throw new WriteRolledBackError(`The package did not reload with the new \`${modelPath}\`, so ` + `the previous text was put back and nothing changed.`);
|
|
311014
|
+
}
|
|
311015
|
+
});
|
|
311016
|
+
}
|
|
310686
311017
|
allocateStagingPath(packageName) {
|
|
310687
311018
|
return safeJoinUnderRoot(this.environmentPath, STAGING_DIR_NAME, `${packageName}-${crypto4.randomUUID()}`);
|
|
310688
311019
|
}
|
|
@@ -310695,7 +311026,7 @@ ${source}` : source ?? "";
|
|
|
310695
311026
|
const dir = safeJoinUnderRoot(environmentPath, dirName);
|
|
310696
311027
|
if (dir.indexOf("..") !== -1)
|
|
310697
311028
|
continue;
|
|
310698
|
-
if (
|
|
311029
|
+
if (path11.basename(dir) !== dirName)
|
|
310699
311030
|
continue;
|
|
310700
311031
|
try {
|
|
310701
311032
|
await fs8.promises.rm(dir, { recursive: true, force: true });
|
|
@@ -310835,7 +311166,7 @@ ${source}` : source ?? "";
|
|
|
310835
311166
|
async installPackage(packageName, downloader, validate) {
|
|
310836
311167
|
assertSafePackageName(packageName);
|
|
310837
311168
|
const stagingPath = this.allocateStagingPath(packageName);
|
|
310838
|
-
await fs8.promises.mkdir(
|
|
311169
|
+
await fs8.promises.mkdir(path11.dirname(stagingPath), { recursive: true });
|
|
310839
311170
|
logger.debug("install.phase1.download.started", {
|
|
310840
311171
|
environmentName: this.environmentName,
|
|
310841
311172
|
packageName,
|
|
@@ -310864,7 +311195,7 @@ ${source}` : source ?? "";
|
|
|
310864
311195
|
const oldExistsOnDisk = await fs8.promises.access(canonicalPath).then(() => true).catch(() => false);
|
|
310865
311196
|
if (oldExistsOnDisk) {
|
|
310866
311197
|
retiredPath = this.allocateRetiredPath(packageName);
|
|
310867
|
-
await fs8.promises.mkdir(
|
|
311198
|
+
await fs8.promises.mkdir(path11.dirname(retiredPath), {
|
|
310868
311199
|
recursive: true
|
|
310869
311200
|
});
|
|
310870
311201
|
await fs8.promises.rename(canonicalPath, retiredPath);
|
|
@@ -311229,7 +311560,7 @@ ${source}` : source ?? "";
|
|
|
311229
311560
|
const retiredPath = this.allocateRetiredPath(packageName);
|
|
311230
311561
|
let renamed = false;
|
|
311231
311562
|
try {
|
|
311232
|
-
await fs8.promises.mkdir(
|
|
311563
|
+
await fs8.promises.mkdir(path11.dirname(retiredPath), {
|
|
311233
311564
|
recursive: true
|
|
311234
311565
|
});
|
|
311235
311566
|
await fs8.promises.rename(canonicalPath, retiredPath);
|
|
@@ -311329,7 +311660,7 @@ ${source}` : source ?? "";
|
|
|
311329
311660
|
};
|
|
311330
311661
|
}
|
|
311331
311662
|
async deleteDuckDBConnection(connectionName) {
|
|
311332
|
-
const duckdbPath =
|
|
311663
|
+
const duckdbPath = path11.join(this.environmentPath, `${connectionName}.duckdb`);
|
|
311333
311664
|
try {
|
|
311334
311665
|
await fs8.promises.rm(duckdbPath, { force: true });
|
|
311335
311666
|
logger.info(`Removed DuckDB connection file ${connectionName} from environment ${this.environmentName}`);
|
|
@@ -311403,13 +311734,13 @@ async function clearMountTarget(targetPath) {
|
|
|
311403
311734
|
function resolvePackageLocation(location, anchorDir, homeDir) {
|
|
311404
311735
|
let expanded = location;
|
|
311405
311736
|
if (location.startsWith("~/")) {
|
|
311406
|
-
const home = homeDir ??
|
|
311737
|
+
const home = homeDir ?? os3.homedir();
|
|
311407
311738
|
if (!home) {
|
|
311408
311739
|
throw new Error(`Cannot expand "~" in location "${location}": home directory is not set`);
|
|
311409
311740
|
}
|
|
311410
|
-
expanded =
|
|
311741
|
+
expanded = path12.join(home, location.slice(2));
|
|
311411
311742
|
}
|
|
311412
|
-
return
|
|
311743
|
+
return path12.isAbsolute(expanded) ? expanded : path12.join(anchorDir, expanded);
|
|
311413
311744
|
}
|
|
311414
311745
|
var GIT_CLONE_OPTIONS = {
|
|
311415
311746
|
"--depth": 1,
|
|
@@ -311587,7 +311918,7 @@ class EnvironmentStore {
|
|
|
311587
311918
|
const storageConfig = {
|
|
311588
311919
|
type: "duckdb",
|
|
311589
311920
|
duckdb: {
|
|
311590
|
-
path:
|
|
311921
|
+
path: path12.join(serverRootPath, "publisher.db")
|
|
311591
311922
|
}
|
|
311592
311923
|
};
|
|
311593
311924
|
this.storageManager = new StorageManager(storageConfig);
|
|
@@ -312002,7 +312333,7 @@ class EnvironmentStore {
|
|
|
312002
312333
|
const reInit = process.env.INITIALIZE_STORAGE === "true";
|
|
312003
312334
|
await fs9.promises.mkdir(this.serverRootPath, { recursive: true });
|
|
312004
312335
|
if (reInit) {
|
|
312005
|
-
const uploadDocsPath2 =
|
|
312336
|
+
const uploadDocsPath2 = path12.join(this.serverRootPath, PUBLISHER_DATA_DIR);
|
|
312006
312337
|
logger.info(`Reinitialization mode: Cleaning up upload documents path ${uploadDocsPath2}`);
|
|
312007
312338
|
try {
|
|
312008
312339
|
await fs9.promises.rm(uploadDocsPath2, {
|
|
@@ -312019,7 +312350,7 @@ class EnvironmentStore {
|
|
|
312019
312350
|
} else {
|
|
312020
312351
|
logger.info(`Using existing publisher path`);
|
|
312021
312352
|
}
|
|
312022
|
-
const uploadDocsPath =
|
|
312353
|
+
const uploadDocsPath = path12.join(this.serverRootPath, PUBLISHER_DATA_DIR);
|
|
312023
312354
|
await fs9.promises.mkdir(uploadDocsPath, { recursive: true });
|
|
312024
312355
|
}
|
|
312025
312356
|
async listEnvironments(skipInitializationCheck = false) {
|
|
@@ -312197,9 +312528,9 @@ class EnvironmentStore {
|
|
|
312197
312528
|
assertSafeEnvironmentPath(absoluteEnvironmentPath);
|
|
312198
312529
|
const startedAt = Date.now();
|
|
312199
312530
|
logger.info(`Detected zip file at "${absoluteEnvironmentPath}". Unzipping...`);
|
|
312200
|
-
const archiveDir =
|
|
312201
|
-
const unzippedEnvironmentPath =
|
|
312202
|
-
if (!unzippedEnvironmentPath.startsWith(archiveDir +
|
|
312531
|
+
const archiveDir = path12.resolve(path12.dirname(absoluteEnvironmentPath));
|
|
312532
|
+
const unzippedEnvironmentPath = path12.resolve(archiveDir, path12.basename(absoluteEnvironmentPath, ".zip"));
|
|
312533
|
+
if (!unzippedEnvironmentPath.startsWith(archiveDir + path12.sep)) {
|
|
312203
312534
|
throw new BadRequestError(`Refusing to unzip "${absoluteEnvironmentPath}": target escapes its directory`);
|
|
312204
312535
|
}
|
|
312205
312536
|
await fs9.promises.rm(unzippedEnvironmentPath, {
|
|
@@ -312210,7 +312541,7 @@ class EnvironmentStore {
|
|
|
312210
312541
|
let entryCount = 0;
|
|
312211
312542
|
let totalUncompressedBytes = 0;
|
|
312212
312543
|
await import_extract_zip.default(absoluteEnvironmentPath, {
|
|
312213
|
-
dir:
|
|
312544
|
+
dir: path12.resolve(unzippedEnvironmentPath),
|
|
312214
312545
|
onEntry: (entry) => {
|
|
312215
312546
|
entryCount += 1;
|
|
312216
312547
|
totalUncompressedBytes += entry.uncompressedSize ?? 0;
|
|
@@ -312317,7 +312648,7 @@ class EnvironmentStore {
|
|
|
312317
312648
|
return absoluteEnvironmentPath;
|
|
312318
312649
|
}
|
|
312319
312650
|
isLocalPath(location) {
|
|
312320
|
-
return location.startsWith("./") || location.startsWith("../") || location.startsWith("~/") || location.startsWith("/") ||
|
|
312651
|
+
return location.startsWith("./") || location.startsWith("../") || location.startsWith("~/") || location.startsWith("/") || path12.isAbsolute(location);
|
|
312321
312652
|
}
|
|
312322
312653
|
resolveLocalPath(location) {
|
|
312323
312654
|
return resolvePackageLocation(location, getPublisherConfigDir(this.serverRootPath) ?? this.serverRootPath);
|
|
@@ -312414,7 +312745,7 @@ class EnvironmentStore {
|
|
|
312414
312745
|
const isInPlace = this.inPlaceEnvs.has(environmentName) && this.isLocalPath(_package.location);
|
|
312415
312746
|
if (isInPlace) {
|
|
312416
312747
|
await clearMountTarget(absolutePackagePath);
|
|
312417
|
-
const absoluteSourcePath =
|
|
312748
|
+
const absoluteSourcePath = path12.resolve(sourcePath);
|
|
312418
312749
|
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
312419
312750
|
try {
|
|
312420
312751
|
await fs9.promises.symlink(absoluteSourcePath, absolutePackagePath, linkType);
|
|
@@ -312573,7 +312904,7 @@ class EnvironmentStore {
|
|
|
312573
312904
|
if (file.name.endsWith("/")) {
|
|
312574
312905
|
return;
|
|
312575
312906
|
}
|
|
312576
|
-
await fs9.promises.mkdir(
|
|
312907
|
+
await fs9.promises.mkdir(path12.dirname(absoluteFilePath), {
|
|
312577
312908
|
recursive: true
|
|
312578
312909
|
});
|
|
312579
312910
|
return fs9.promises.writeFile(absoluteFilePath, await file.download());
|
|
@@ -312590,7 +312921,7 @@ class EnvironmentStore {
|
|
|
312590
312921
|
const prefix = prefixParts.join("/");
|
|
312591
312922
|
if (isCompressedFile) {
|
|
312592
312923
|
const zipFilePath = `${absoluteDirPath}.zip`;
|
|
312593
|
-
await fs9.promises.mkdir(
|
|
312924
|
+
await fs9.promises.mkdir(path12.dirname(zipFilePath), {
|
|
312594
312925
|
recursive: true
|
|
312595
312926
|
});
|
|
312596
312927
|
const command = new import_client_s33.GetObjectCommand({
|
|
@@ -312630,7 +312961,7 @@ class EnvironmentStore {
|
|
|
312630
312961
|
return;
|
|
312631
312962
|
}
|
|
312632
312963
|
const absoluteFilePath = safeJoinUnderRoot(absoluteDirPath, relativeFilePath);
|
|
312633
|
-
await fs9.promises.mkdir(
|
|
312964
|
+
await fs9.promises.mkdir(path12.dirname(absoluteFilePath), {
|
|
312634
312965
|
recursive: true
|
|
312635
312966
|
});
|
|
312636
312967
|
const command = new import_client_s33.GetObjectCommand({
|
|
@@ -312784,7 +313115,7 @@ class WatchModeController {
|
|
|
312784
313115
|
ignored: (filePath, stats) => {
|
|
312785
313116
|
if (!stats?.isFile())
|
|
312786
313117
|
return false;
|
|
312787
|
-
const ext =
|
|
313118
|
+
const ext = path13.extname(filePath).toLowerCase();
|
|
312788
313119
|
return !MODEL_EXTS.has(ext) && !ASSET_EXTS.has(ext);
|
|
312789
313120
|
},
|
|
312790
313121
|
ignoreInitial: true
|
|
@@ -312802,12 +313133,12 @@ class WatchModeController {
|
|
|
312802
313133
|
};
|
|
312803
313134
|
const onEvent = (kind) => async (filePath) => {
|
|
312804
313135
|
logger.info(`Watch ${kind}: ${filePath}; environment=${watchName}`);
|
|
312805
|
-
const rel =
|
|
312806
|
-
const segments = rel.split(
|
|
313136
|
+
const rel = path13.relative(this.watchingPath ?? "", filePath);
|
|
313137
|
+
const segments = rel.split(path13.sep);
|
|
312807
313138
|
const pkgName = segments.length > 1 && segments[0] && !segments[0].startsWith("..") ? segments[0] : null;
|
|
312808
313139
|
if (!pkgName)
|
|
312809
313140
|
return;
|
|
312810
|
-
const ext =
|
|
313141
|
+
const ext = path13.extname(filePath).toLowerCase();
|
|
312811
313142
|
if (MODEL_EXTS.has(ext)) {
|
|
312812
313143
|
const recompiled = await reloadPackage(pkgName);
|
|
312813
313144
|
if (!recompiled)
|
|
@@ -313207,9 +313538,6 @@ class MaterializationController {
|
|
|
313207
313538
|
async listMaterializations(environmentName, packageName, options) {
|
|
313208
313539
|
return this.materializationService.listMaterializations(environmentName, packageName, options);
|
|
313209
313540
|
}
|
|
313210
|
-
async listEnvironmentMaterializations(environmentName, options) {
|
|
313211
|
-
return this.materializationService.listEnvironmentMaterializations(environmentName, options);
|
|
313212
|
-
}
|
|
313213
313541
|
async getMaterialization(environmentName, packageName, materializationId) {
|
|
313214
313542
|
return this.materializationService.getMaterialization(environmentName, packageName, materializationId);
|
|
313215
313543
|
}
|
|
@@ -316104,7 +316432,7 @@ init_logger();
|
|
|
316104
316432
|
// src/mcp/tools/schema_index.ts
|
|
316105
316433
|
init_logger();
|
|
316106
316434
|
var import_lunr3 = __toESM(require_lunr(), 1);
|
|
316107
|
-
import { createHash as
|
|
316435
|
+
import { createHash as createHash5 } from "crypto";
|
|
316108
316436
|
var MAX_INDEXED_TABLES = 5000;
|
|
316109
316437
|
var MAX_COLUMNS_IN_INDEX_TEXT = 60;
|
|
316110
316438
|
var MAX_CACHED_SCHEMAS = 8;
|
|
@@ -316119,7 +316447,7 @@ function tableIndexText(entity) {
|
|
|
316119
316447
|
}
|
|
316120
316448
|
function schemaFingerprint(tables) {
|
|
316121
316449
|
const canonical = tables.map((t) => `${t.resource}\x00${t.columns.map((c) => `${c.name}:${c.type ?? ""}`).join(",")}`).sort().join("\x01");
|
|
316122
|
-
return
|
|
316450
|
+
return createHash5("sha256").update(canonical).digest("hex");
|
|
316123
316451
|
}
|
|
316124
316452
|
function sanitizeQuery(query) {
|
|
316125
316453
|
return query.replace(/[~^:*+\-"]/g, " ").trim();
|
|
@@ -320380,14 +320708,18 @@ Scanned at a glance is a dashboard; read top to bottom is a notebook.
|
|
|
320380
320708
|
2. **PICK THE VIEWS TO SHOW.** A dashboard is \`## artifact { tiles=[…] }\` naming existing views, so
|
|
320381
320709
|
this is the design step: which views, how wide each sits, what each is called. There is one form,
|
|
320382
320710
|
so there is no form to choose.
|
|
320383
|
-
3. **DECLARE THE GIVENS** the dashboard will filter by, in the
|
|
320384
|
-
|
|
320385
|
-
|
|
320711
|
+
3. **DECLARE THE GIVENS** the dashboard will filter by, in the dashboard file itself, with their
|
|
320712
|
+
control tags: see "Filter controls" below for the syntax and what each tag renders as. That is
|
|
320713
|
+
the convention because the dashboard builder edits the dashboard file and nothing else, so a
|
|
320714
|
+
filter it can add, change or remove is a declaration in that file. Bind them on the tiles (step
|
|
320715
|
+
4). Reuse the package's \`givens.malloy\` only for a control several surfaces genuinely share, and
|
|
320716
|
+
then import it whole, knowing the builder can bind those givens but not edit them.
|
|
320386
320717
|
4. **COMPOSE THE FILE** for \`dashboards/\`, following the template below, but do not save it yet.
|
|
320387
|
-
|
|
320388
|
-
|
|
320389
|
-
|
|
320390
|
-
|
|
320718
|
+
Name the sources you need: \`import { order_items, products } from '../storefront.malloy'\`.
|
|
320719
|
+
Each tile binds its controls with a refinement, \`view: t is v + { where: category ~ $CATEGORY }\`,
|
|
320720
|
+
one clause per given it answers to; a \`filter<...>\` binds with \`~\`, a plain \`date\` or \`number\`
|
|
320721
|
+
given is a value and binds with \`>=\`, \`<=\` or \`=\`. Only the givens some tile references become
|
|
320722
|
+
controls, so a declaration nothing binds shows nothing. Then import every
|
|
320391
320723
|
source or query any referenced given names in a \`suggest\`. Both are per-file, and getting the
|
|
320392
320724
|
suggest wrong does not error: the control still looks like a picker but has no options, and says
|
|
320393
320725
|
so underneath, "Could not load the options for this control". The package warnings name it too. **A \`suggest\` naming a \`query=\` needs that
|
|
@@ -320422,33 +320754,31 @@ out by Publisher into the grid \`# dashboard { columns=N }\` names.
|
|
|
320422
320754
|
\`\`\`malloy
|
|
320423
320755
|
##! experimental.givens
|
|
320424
320756
|
## artifact { title="Storefront overview" tiles=["overview -> kpis", "overview -> revenue_trend", "overview -> revenue_by_state"] } dashboard { columns=12 }
|
|
320425
|
-
import {
|
|
320426
|
-
|
|
320427
|
-
|
|
320757
|
+
import { order_items, products } from '../storefront.malloy'
|
|
320758
|
+
|
|
320759
|
+
// The controls, declared here: the tags are each one's control contract.
|
|
320760
|
+
# label="Category" control=select suggest { source=products dimension=category }
|
|
320761
|
+
given: CATEGORY :: filter<string> is f''
|
|
320762
|
+
# label="Ordered since"
|
|
320763
|
+
given: SINCE :: date is @2023-01-01
|
|
320428
320764
|
|
|
320429
320765
|
// Layout goes on the VIEW, and a thin re-declaration is the place to put it: the
|
|
320430
|
-
// modelled view keeps its chart tag,
|
|
320431
|
-
|
|
320766
|
+
// modelled view keeps its chart tag, this decides how wide it sits here, and the
|
|
320767
|
+
// \`+ { where: ... }\` says which controls the tile answers to.
|
|
320768
|
+
source: overview is order_items extend {
|
|
320432
320769
|
# colspan=12
|
|
320433
320770
|
# label="Key figures"
|
|
320434
320771
|
# big_value
|
|
320435
|
-
view: kpis is {
|
|
320436
|
-
aggregate:
|
|
320437
|
-
# label="Revenue"
|
|
320438
|
-
# currency
|
|
320439
|
-
total_sales
|
|
320440
|
-
# label="Orders"
|
|
320441
|
-
order_count
|
|
320442
|
-
}
|
|
320772
|
+
view: kpis is key_figures + { where: category ~ $CATEGORY, where: created_at >= $SINCE }
|
|
320443
320773
|
|
|
320444
320774
|
# colspan=8
|
|
320445
320775
|
# break
|
|
320446
320776
|
# label="Revenue by month"
|
|
320447
|
-
view: revenue_trend is sales_by_month
|
|
320777
|
+
view: revenue_trend is sales_by_month + { where: category ~ $CATEGORY, where: created_at >= $SINCE }
|
|
320448
320778
|
|
|
320449
320779
|
# colspan=4
|
|
320450
320780
|
# label="Revenue by state"
|
|
320451
|
-
view: revenue_by_state is sales_by_state
|
|
320781
|
+
view: revenue_by_state is sales_by_state + { where: category ~ $CATEGORY, where: created_at >= $SINCE }
|
|
320452
320782
|
}
|
|
320453
320783
|
\`\`\`
|
|
320454
320784
|
|
|
@@ -320461,8 +320791,8 @@ Three things the form costs, so you are not surprised by them:
|
|
|
320461
320791
|
- **A tile expression is a string in an annotation, so the compiler never checks it.** Rename a view
|
|
320462
320792
|
and the file still compiles; the tile fails at package load. Read the lint (step 6).
|
|
320463
320793
|
- **No per-parent-row grouping.** There is no parent query to repeat a grid over.
|
|
320464
|
-
- **Filtering lives
|
|
320465
|
-
|
|
320794
|
+
- **Filtering lives on the tiles**, not on the page: each view's \`+ { where: ... }\` names the
|
|
320795
|
+
controls it answers to. Below is why, and the one thing that does not work.
|
|
320466
320796
|
|
|
320467
320797
|
### Also served: \`# artifact\` on a \`query:\`
|
|
320468
320798
|
|
|
@@ -320522,23 +320852,24 @@ object", so a dashboard has no description as a result.
|
|
|
320522
320852
|
|
|
320523
320853
|
### Where the filtering goes
|
|
320524
320854
|
|
|
320525
|
-
A dashboard has no query, so
|
|
320526
|
-
|
|
320527
|
-
|
|
320528
|
-
|
|
320529
|
-
|
|
320530
|
-
|
|
320531
|
-
|
|
320532
|
-
|
|
320533
|
-
|
|
320534
|
-
|
|
320535
|
-
|
|
320536
|
-
|
|
320537
|
-
|
|
320538
|
-
|
|
320539
|
-
|
|
320540
|
-
|
|
320541
|
-
|
|
320855
|
+
A dashboard has no query, so its filtering lives on the views it names: a \`+ { where: field ~ $GIVEN }\`
|
|
320856
|
+
refinement on each tile, one clause per control the tile answers to. A tile without the clause does
|
|
320857
|
+
not move when the control does, which is how a page keeps one tile fixed while the rest filter. The
|
|
320858
|
+
givens those clauses read are declared in the same file (step 3).
|
|
320859
|
+
|
|
320860
|
+
**Binding is per declaration, not per name.** Measured: a dashboard declaring its own \`CATEGORY\`
|
|
320861
|
+
over a source whose model-level \`where:\` reads the model's \`CATEGORY\` compiles, shows the control,
|
|
320862
|
+
and filters nothing when it moves, because the two declarations only share a name. So do not mix
|
|
320863
|
+
the two designs on one given. The other design still works on its own: a source with the givens
|
|
320864
|
+
already applied in an untagged \`dashboards/_shared.malloy\`, reading \`import '../givens.malloy'\`,
|
|
320865
|
+
which discovery treats as a shared include rather than a dashboard. Then the dashboard imports both
|
|
320866
|
+
and the controls render for the givens its tiles reach. A given the dashboard imports but nothing
|
|
320867
|
+
references gets no control, silently, at reload 200 with no warning. Save the include before you
|
|
320868
|
+
compile the dashboard that imports it, since an importer compiled against a sibling that is not on
|
|
320869
|
+
disk fails with an \`import-error\`. The builder can bind such a control but not add, change or
|
|
320870
|
+
remove it, since it never edits imports or model files.
|
|
320871
|
+
|
|
320872
|
+
Note \`SINCE\` is a \`date\` rather than a \`filter<>\`, so it compares with \`>=\` rather than \`~\`.
|
|
320542
320873
|
|
|
320543
320874
|
**\`# dashboard { columns=N }\` is the one spelling of the grid width**, on both forms, beside the
|
|
320544
320875
|
artifact tag. Anything else inside the artifact tag is a package warning naming it, which is what you
|
|
@@ -320620,9 +320951,10 @@ rows.
|
|
|
320620
320951
|
- **The filename is the dashboard's name:** its URL slug, its listing name, and its \`# drill\`
|
|
320621
320952
|
target. The query inside can be called anything, and sometimes must be (a query named \`regions\`
|
|
320622
320953
|
collides with an imported \`regions\` source).
|
|
320623
|
-
- **
|
|
320624
|
-
|
|
320625
|
-
|
|
320954
|
+
- **A given has to be in the dashboard file's scope to be bindable**: declared there (the
|
|
320955
|
+
convention) or imported. Malloy's given namespace is per-file. A given the file cannot see gets
|
|
320956
|
+
no control and cannot be sent to it, even when a \`where:\` that references it lives up an import
|
|
320957
|
+
chain. And a given declared here does not drive a \`where:\` in the model: bind on the tiles.
|
|
320626
320958
|
- **A suggest's source or query has to resolve in the dashboard file too.** \`suggest { source=products … }\`
|
|
320627
320959
|
means the dashboard imports \`products\`.
|
|
320628
320960
|
- **A model-level \`##\` tag must be on one line.** Wrapping one always breaks it, but how you find
|
|
@@ -320641,9 +320973,10 @@ choosing them.
|
|
|
320641
320973
|
|
|
320642
320974
|
## Filter controls
|
|
320643
320975
|
|
|
320644
|
-
Controls come from the \`given:\` declarations the
|
|
320645
|
-
|
|
320646
|
-
|
|
320976
|
+
Controls come from the \`given:\` declarations the tiles reference. Declare them in the dashboard
|
|
320977
|
+
file, which is what the builder edits; a package \`givens.malloy\` is for controls the data app and
|
|
320978
|
+
notebooks share, and a dashboard importing it whole gets the same controls but cannot edit them.
|
|
320979
|
+
The tags on the declaration are the control contract:
|
|
320647
320980
|
|
|
320648
320981
|
\`\`\`malloy
|
|
320649
320982
|
##! experimental.givens
|
|
@@ -322177,7 +322510,7 @@ Present coverage in this order:
|
|
|
322177
322510
|
{
|
|
322178
322511
|
name: "malloy-materialization-tuning",
|
|
322179
322512
|
description: "Optimize a package's Malloy Persistence materializations for cost and performance using the malloy-pub CLI and the materialization history. Recommend what to persist, what to stop persisting, and how to schedule/scope it. Use when the user asks to make a package cheaper or faster, tune persistence, decide what to materialize, or review persist/schedule choices.",
|
|
322180
|
-
body: "# Tuning materializations for cost and performance\n\nThis skill turns the signals the open-source Publisher already records (the materialization history, per-run timings, and which sources were built vs reused) into concrete, **recommendations-only** advice: which sources to persist, which to stop persisting, and how to schedule and scope them. It is the local counterpart to the platform's usage-driven optimization: the Publisher has the raw signals, and you read them with the `malloy-pub` CLI.\n\n> **Recommendations only. Never change a model, schedule, or scope without the user's explicit go-ahead.** Present the findings and the proposed edits, then apply them only when asked. Persisting the wrong source wastes storage and rebuild time; unpersisting a hot one makes queries slow. Let the user decide.\n\nAssumes the `malloy-pub` CLI is on PATH and points at the server (`--url` or `MALLOY_PUBLISHER_URL`, default `http://localhost:4000`). Substitute the real environment and package for `<env>` / `<pkg>`.\n\n## Step 1: Take inventory\n\nEstablish what the package persists today and how it is governed.\n\n- **Persist sources:** the sources annotated `#@ persist name=\"…\"` in the package's `.malloy` files. Read the models (or `get_context` the package) to list them.\n- **Schedule + scope:**\n\n ```bash\n malloy-pub schedule view --environment <env> --package <pkg>\n ```\n\n This prints the cron (or `none`, meaning publish / on-demand only), the persist **scope** (`package` = artifacts reused across versions; `version` = per published version), and whether a freshness policy is set. A control-plane-managed package (manifestLocation set) is refreshed by the control plane, not the standalone scheduler, so leave its cadence alone.\n\n## Step 2: Read the materialization history\n\nThe history is where cost lives. Each run records its trigger, timing, and how many sources were built vs reused.\n\n- **
|
|
322513
|
+
body: "# Tuning materializations for cost and performance\n\nThis skill turns the signals the open-source Publisher already records (the materialization history, per-run timings, and which sources were built vs reused) into concrete, **recommendations-only** advice: which sources to persist, which to stop persisting, and how to schedule and scope them. It is the local counterpart to the platform's usage-driven optimization: the Publisher has the raw signals, and you read them with the `malloy-pub` CLI.\n\n> **Recommendations only. Never change a model, schedule, or scope without the user's explicit go-ahead.** Present the findings and the proposed edits, then apply them only when asked. Persisting the wrong source wastes storage and rebuild time; unpersisting a hot one makes queries slow. Let the user decide.\n\nAssumes the `malloy-pub` CLI is on PATH and points at the server (`--url` or `MALLOY_PUBLISHER_URL`, default `http://localhost:4000`). Substitute the real environment and package for `<env>` / `<pkg>`.\n\n## Step 1: Take inventory\n\nEstablish what the package persists today and how it is governed.\n\n- **Persist sources:** the sources annotated `#@ persist name=\"…\"` in the package's `.malloy` files. Read the models (or `get_context` the package) to list them.\n- **Schedule + scope:**\n\n ```bash\n malloy-pub schedule view --environment <env> --package <pkg>\n ```\n\n This prints the cron (or `none`, meaning publish / on-demand only), the persist **scope** (`package` = artifacts reused across versions; `version` = per published version), and whether a freshness policy is set. A control-plane-managed package (manifestLocation set) is refreshed by the control plane, not the standalone scheduler, so leave its cadence alone.\n\n## Step 2: Read the materialization history\n\nThe history is where cost lives. Each run records its trigger, timing, and how many sources were built vs reused.\n\n- **For one package** (newest first). A materialization is a run of one package's persist sources, so this is the listing; to review a whole environment, read each package in turn (`malloy-pub list package --environment <env>` names them):\n\n ```bash\n malloy-pub list materialization --environment <env> --package <pkg>\n ```\n\n Columns: ID, Status, **Trigger** (`SCHEDULER` vs `ON_DEMAND`), Started, Completed, Error.\n\n- **A single run's detail** (the cost signals):\n\n ```bash\n malloy-pub get materialization <id> --environment <env> --package <pkg>\n ```\n\n In the JSON, read:\n - `metadata.durationMs`: how long the build took.\n - `metadata.sourcesBuilt` vs `metadata.sourcesReused`: how much work each run actually did. A run that is nearly all _reused_ is cheap; one that is nearly all _built_ every time is where cost accumulates.\n - `metadata.trigger`: `SCHEDULER` (a cron fired it) or `ON_DEMAND`.\n - `manifest.entries[*]`: the persisted sources: `sourceName`, `physicalTableName`, `realization`.\n\nLook across several runs, not one: the pattern over the recent history (how often it rebuilds, how much it reuses, how long it takes) is the signal.\n\n## Step 3: Analyze and recommend\n\nWeigh rebuild cost against query benefit. Common findings:\n\n- **Persist candidate:** an expensive, frequently-queried source that is _not_ persisted (recomputed on every query). Recommend adding `#@ persist name=\"…\"`. Strongest when the source is a heavy aggregate/join reused by many queries and its inputs change slowly. If the source carries an `#(authorize)` gate, check which case it is first. A gate reached only through a `join_*`, or inherited from a base it cannot be attributed to, makes the colocated persist **refuse with a 422** - so do not recommend persisting it at all. Where the gate is provably the source's own row filter the persist is admitted, and then only recommend it alongside a freshness window (`freshness.fallback=\"live\"`): the gating column freezes at build time, so without one a revoked row can be served under its old access decision indefinitely (see `skill:malloy-materialization`, which also covers where that window does and does not bind).\n- **Removal candidate:** a persisted source that is cheap to compute, rarely queried, or rebuilt far more often than it is read. Recommend dropping the `#@ persist` annotation (and its table): the storage + rebuild cost is not buying anything.\n- **Cadence mismatch:** a `SCHEDULER` cadence out of step with how fast the data changes or how long a build takes. If most scheduled runs are all-reused (nothing changed), the cron is too frequent, so loosen it. If queries routinely read stale data, tighten it. If the build's `durationMs` approaches the interval, the cadence is too aggressive.\n- **Scope mismatch:** `scope: version` re-materializes per published version (right when versions must be isolated, e.g. a schedule); `scope: package` reuses one lineage across versions (cheaper when versions can share). A schedule _requires_ `version`. If a package carries a schedule it does not need, clearing the schedule frees it to use the cheaper package scope.\n\nFrame each recommendation with the evidence from Step 2 (the run IDs, timings, built/reused counts) so the user can judge it.\n\n## Step 4: Apply (only once approved)\n\n- **Add a persist source:** add the `#@ persist` annotation in the `.malloy` file (use the modeling workflow to validate and reload), then rebuild so it is materialized:\n\n ```bash\n malloy-pub materialize --environment <env> --package <pkg> --wait\n ```\n\n- **Remove a persist source:** delete the `#@ persist` annotation, then drop the old run's tables **before** rebuilding what remains:\n\n ```bash\n malloy-pub delete materialization <id> --environment <env> --package <pkg> --drop-tables\n malloy-pub materialize --environment <env> --package <pkg> --wait\n ```\n\n > `--drop-tables` drops **every** physical table in that run's manifest, not just the removed source's: auto-run assigns stable table names and carries unchanged sources forward, so an old run's manifest names tables a newer manifest still serves. Do the drop **first, then rebuild**: `materialize --wait` re-creates every source that is still persisted, ending in the desired state. Dropping a run whose tables the current serving manifest depends on, without an immediate rebuild, breaks queries (`Table ... does not exist`).\n\n- **Change the schedule / cadence:**\n\n ```bash\n malloy-pub schedule set \"0 6 * * *\" --environment <env> --package <pkg> # 5-field UTC cron\n malloy-pub schedule clear --environment <env> --package <pkg>\n ```\n\n `set` also sets `scope: version` (a schedule requires it); the server rejects an invalid cron or an illegal scope/freshness combination, so a rejection means the change was unsafe.\n\n- **Change the scope:** `scope` is declared in the package's `publisher.json` under `materialization` (`\"scope\": \"package\"` or `\"version\"`; the root-level form is deprecated but still read). Edit it there, then reload/republish the package. Remember a schedule pins scope to `version`, so clear the schedule first if moving to `package`.\n\nAfter applying, re-run Step 2 on the next few builds to confirm the change did what you predicted (more reuse, shorter builds, or a table that is actually read).\n\n## What this skill does not do\n\n- It does not decide for the user or apply changes silently; every edit needs an explicit go-ahead.\n- It cannot see per-query read counts (the open-source Publisher records build history, not query-level table usage), so \"rarely queried\" is a judgment from the model and the user's knowledge, not a measured metric. Say so when it matters."
|
|
322181
322514
|
},
|
|
322182
322515
|
{
|
|
322183
322516
|
name: "malloy-model",
|
|
@@ -324296,8 +324629,8 @@ function initializeMcpServer(environmentStore) {
|
|
|
324296
324629
|
init_config();
|
|
324297
324630
|
init_logger();
|
|
324298
324631
|
import * as fs10 from "fs";
|
|
324299
|
-
import * as
|
|
324300
|
-
import * as
|
|
324632
|
+
import * as os4 from "os";
|
|
324633
|
+
import * as path14 from "path";
|
|
324301
324634
|
var MCP_CONFIG_FILENAME = ".mcp.json";
|
|
324302
324635
|
function malloyServer(endpoint) {
|
|
324303
324636
|
return { type: "http", url: endpoint };
|
|
@@ -324321,11 +324654,11 @@ function mcpEndpoint(host, port) {
|
|
|
324321
324654
|
return `http://${host}:${port}/mcp`;
|
|
324322
324655
|
}
|
|
324323
324656
|
function findGitWorkTreeRoot(dir) {
|
|
324324
|
-
let current =
|
|
324657
|
+
let current = path14.resolve(dir);
|
|
324325
324658
|
for (;; ) {
|
|
324326
|
-
if (fs10.existsSync(
|
|
324659
|
+
if (fs10.existsSync(path14.join(current, ".git")))
|
|
324327
324660
|
return current;
|
|
324328
|
-
const parent =
|
|
324661
|
+
const parent = path14.dirname(current);
|
|
324329
324662
|
if (parent === current)
|
|
324330
324663
|
return;
|
|
324331
324664
|
current = parent;
|
|
@@ -324348,7 +324681,7 @@ function mcpConfigEnabled() {
|
|
|
324348
324681
|
}
|
|
324349
324682
|
function ensureMcpConfig(options) {
|
|
324350
324683
|
const { dir, endpoint, requestedPort, boundPort, homeDir } = options;
|
|
324351
|
-
const file =
|
|
324684
|
+
const file = path14.join(dir, MCP_CONFIG_FILENAME);
|
|
324352
324685
|
try {
|
|
324353
324686
|
const existing = (() => {
|
|
324354
324687
|
try {
|
|
@@ -324375,18 +324708,18 @@ function ensureMcpConfig(options) {
|
|
|
324375
324708
|
try {
|
|
324376
324709
|
return fs10.realpathSync(p);
|
|
324377
324710
|
} catch {
|
|
324378
|
-
return
|
|
324711
|
+
return path14.resolve(p);
|
|
324379
324712
|
}
|
|
324380
324713
|
};
|
|
324381
|
-
if (realish(dir) === realish(homeDir ??
|
|
324714
|
+
if (realish(dir) === realish(homeDir ?? os4.homedir())) {
|
|
324382
324715
|
return { action: "skipped-home", dir, endpoint, staleConfig };
|
|
324383
324716
|
}
|
|
324384
|
-
if (
|
|
324717
|
+
if (path14.resolve(dir) === path14.parse(path14.resolve(dir)).root) {
|
|
324385
324718
|
return { action: "skipped-root", dir, endpoint, staleConfig };
|
|
324386
324719
|
}
|
|
324387
324720
|
const gitRoot = findGitWorkTreeRoot(dir);
|
|
324388
324721
|
if (gitRoot !== undefined) {
|
|
324389
|
-
const rootCandidate =
|
|
324722
|
+
const rootCandidate = path14.join(gitRoot, MCP_CONFIG_FILENAME);
|
|
324390
324723
|
return {
|
|
324391
324724
|
action: "skipped-git",
|
|
324392
324725
|
dir,
|
|
@@ -325427,9 +325760,9 @@ import {
|
|
|
325427
325760
|
InMemoryURLReader as InMemoryURLReader3,
|
|
325428
325761
|
Runtime as Runtime4
|
|
325429
325762
|
} from "@malloydata/malloy";
|
|
325430
|
-
import { mkdirSync as mkdirSync3, mkdtempSync, rmSync } from "node:fs";
|
|
325431
|
-
import
|
|
325432
|
-
import
|
|
325763
|
+
import { mkdirSync as mkdirSync3, mkdtempSync as mkdtempSync2, rmSync } from "node:fs";
|
|
325764
|
+
import os5 from "node:os";
|
|
325765
|
+
import path15 from "node:path";
|
|
325433
325766
|
|
|
325434
325767
|
// src/service/build_query_tag.ts
|
|
325435
325768
|
var MAX_QUERY_TAG_LENGTH = 2000;
|
|
@@ -325671,14 +326004,14 @@ ${buildSQL};`;
|
|
|
325671
326004
|
}
|
|
325672
326005
|
return row;
|
|
325673
326006
|
}, parentJobId);
|
|
325674
|
-
const
|
|
326007
|
+
const path16 = [
|
|
325675
326008
|
str2(located.project) ?? handle,
|
|
325676
326009
|
str2(located.dataset),
|
|
325677
326010
|
str2(located.table)
|
|
325678
326011
|
].join(".");
|
|
325679
326012
|
const jobId = str2(located.job_id);
|
|
325680
326013
|
return {
|
|
325681
|
-
selectSQL: `SELECT * FROM bigquery_scan('${escapeSQL(
|
|
326014
|
+
selectSQL: `SELECT * FROM bigquery_scan('${escapeSQL(path16)}')`,
|
|
325682
326015
|
jobId,
|
|
325683
326016
|
cost: bigQueryReadCost(located, jobId, parentJobId)
|
|
325684
326017
|
};
|
|
@@ -325741,7 +326074,7 @@ function passthroughSourceType(sourceConnection) {
|
|
|
325741
326074
|
throw new BadRequestError(`Cannot materialize a '${type}' source into a storage destination: the ` + `native query-passthrough build supports source connections of type ` + `${PASSTHROUGH_SOURCE_TYPES.join(", ")} only.`);
|
|
325742
326075
|
}
|
|
325743
326076
|
function createIsolatedBuildSession(sessionName) {
|
|
325744
|
-
const workDir =
|
|
326077
|
+
const workDir = mkdtempSync2(path15.join(os5.tmpdir(), "malloy-build-"));
|
|
325745
326078
|
let session;
|
|
325746
326079
|
try {
|
|
325747
326080
|
session = new DuckDBConnection4(sessionName, ":memory:", workDir, {
|
|
@@ -325794,10 +326127,13 @@ async function buildSourceIntoStorage(params) {
|
|
|
325794
326127
|
environmentPath,
|
|
325795
326128
|
queryMetadata
|
|
325796
326129
|
} = params;
|
|
326130
|
+
const federate = params.deps?.federate ?? federateSourceForPassthrough;
|
|
326131
|
+
const read = params.deps?.read ?? issuePassthroughRead;
|
|
325797
326132
|
assertSupportedDestination(destinationName, destinationConnection);
|
|
325798
326133
|
const sourceType = passthroughSourceType(sourceConnection);
|
|
325799
326134
|
const { session, dispose, workDir } = createIsolatedBuildSession(`build_${destinationName}`);
|
|
325800
326135
|
let federatedHandle;
|
|
326136
|
+
let federatedClose;
|
|
325801
326137
|
try {
|
|
325802
326138
|
await applySessionResourceLimits(session, { tempDirectory: workDir });
|
|
325803
326139
|
await attachDestinationReadWrite(session, destinationName, destinationConnection, environmentPath);
|
|
@@ -325805,7 +326141,8 @@ async function buildSourceIntoStorage(params) {
|
|
|
325805
326141
|
await session.runSQL("SET ducklake_default_data_inlining_row_limit=0");
|
|
325806
326142
|
}
|
|
325807
326143
|
await pinSessionToUTC(session);
|
|
325808
|
-
const federated = await
|
|
326144
|
+
const federated = await federate(session, sourceType, sourceFederationConfig(sourceConnection));
|
|
326145
|
+
federatedClose = federated.close;
|
|
325809
326146
|
await tagSnowflakeSession(session, sourceType, federated.handle, queryMetadata);
|
|
325810
326147
|
const target = quoteManifestTablePath(`${destinationName}.${physicalTableName}`, STORAGE_TARGET_DIALECT);
|
|
325811
326148
|
if (params.incremental) {
|
|
@@ -325824,8 +326161,8 @@ async function buildSourceIntoStorage(params) {
|
|
|
325824
326161
|
};
|
|
325825
326162
|
}
|
|
325826
326163
|
}
|
|
325827
|
-
const
|
|
325828
|
-
const schema = await createTableAndDescribe(session, target,
|
|
326164
|
+
const passthrough = await read(session, sourceType, federated.handle, buildSQL, queryMetadata);
|
|
326165
|
+
const schema = await createTableAndDescribe(session, target, passthrough.selectSQL);
|
|
325829
326166
|
const seededThrough = await params.incremental?.afterSeed({
|
|
325830
326167
|
session,
|
|
325831
326168
|
quotedTablePath: target
|
|
@@ -325834,11 +326171,14 @@ async function buildSourceIntoStorage(params) {
|
|
|
325834
326171
|
seededThrough,
|
|
325835
326172
|
storageDestinationName: destinationName,
|
|
325836
326173
|
schema,
|
|
325837
|
-
readCost:
|
|
326174
|
+
readCost: passthrough.cost ?? await snowflakeReadCostAfterBuild(session, sourceType, federated.handle, buildSQL, queryMetadata, sourceConnection.snowflakeConnection?.database)
|
|
325838
326175
|
};
|
|
325839
326176
|
} finally {
|
|
325840
326177
|
await clearSnowflakeSessionTag(session, sourceType, federatedHandle);
|
|
325841
326178
|
await dispose();
|
|
326179
|
+
if (federatedClose) {
|
|
326180
|
+
await federatedClose().catch((e) => logger.warn(`Failed to close the SSH proxy a storage build federated through: ${String(e)}`));
|
|
326181
|
+
}
|
|
325842
326182
|
}
|
|
325843
326183
|
}
|
|
325844
326184
|
async function buildDownstreamIntoStorage(params) {
|
|
@@ -325943,7 +326283,7 @@ async function attachDestinationReadWrite(session, destinationName, destinationC
|
|
|
325943
326283
|
}
|
|
325944
326284
|
const destinationRoot = storageDestinationRoot(environmentPath);
|
|
325945
326285
|
mkdirSync3(destinationRoot, { recursive: true });
|
|
325946
|
-
const dbPath =
|
|
326286
|
+
const dbPath = path15.join(destinationRoot, `${destinationName}.duckdb`);
|
|
325947
326287
|
await session.runSQL(`ATTACH '${escapeSQL(dbPath)}' AS ${quoteIdentifier(destinationName, STORAGE_TARGET_DIALECT)}`);
|
|
325948
326288
|
}
|
|
325949
326289
|
function assertSupportedDestination(destinationName, destinationConnection) {
|
|
@@ -325957,7 +326297,8 @@ function sourceFederationConfig(sourceConnection) {
|
|
|
325957
326297
|
name: sourceConnection.name ?? "src",
|
|
325958
326298
|
bigqueryConnection: sourceConnection.bigqueryConnection,
|
|
325959
326299
|
snowflakeConnection: sourceConnection.snowflakeConnection,
|
|
325960
|
-
postgresConnection: sourceConnection.postgresConnection
|
|
326300
|
+
postgresConnection: sourceConnection.postgresConnection,
|
|
326301
|
+
proxy: sourceConnection.proxy
|
|
325961
326302
|
};
|
|
325962
326303
|
}
|
|
325963
326304
|
async function createTableAndDescribe(session, quotedTablePath, selectSQL) {
|
|
@@ -326053,7 +326394,7 @@ function storageDeltaTarget(params) {
|
|
|
326053
326394
|
init_connection();
|
|
326054
326395
|
init_materialization_serve_transform();
|
|
326055
326396
|
init_quoting();
|
|
326056
|
-
import { readFileSync as
|
|
326397
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
326057
326398
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
326058
326399
|
|
|
326059
326400
|
// src/service/resolve_environment.ts
|
|
@@ -326246,10 +326587,6 @@ class MaterializationService {
|
|
|
326246
326587
|
const environmentId = await this.resolveEnvironmentId(environmentName);
|
|
326247
326588
|
return this.repository.listMaterializations(environmentId, packageName, options);
|
|
326248
326589
|
}
|
|
326249
|
-
async listEnvironmentMaterializations(environmentName, options) {
|
|
326250
|
-
const environmentId = await this.resolveEnvironmentId(environmentName);
|
|
326251
|
-
return this.repository.listMaterializationsByEnvironment(environmentId, options);
|
|
326252
|
-
}
|
|
326253
326590
|
async getLatestScheduledFireAt(environmentName, packageName) {
|
|
326254
326591
|
const environmentId = await this.resolveEnvironmentId(environmentName);
|
|
326255
326592
|
return this.repository.getLatestScheduledFireAt(environmentId, packageName);
|
|
@@ -327352,7 +327689,7 @@ class MaterializationService {
|
|
|
327352
327689
|
return;
|
|
327353
327690
|
let text;
|
|
327354
327691
|
try {
|
|
327355
|
-
text =
|
|
327692
|
+
text = readFileSync4(fileURLToPath7(location.url), "utf8");
|
|
327356
327693
|
} catch {
|
|
327357
327694
|
return;
|
|
327358
327695
|
}
|
|
@@ -327869,7 +328206,7 @@ var import_debug2 = __toESM(require_src5(), 1);
|
|
|
327869
328206
|
import { isIPv6 } from "node:net";
|
|
327870
328207
|
import { isIPv6 as isIPv62 } from "node:net";
|
|
327871
328208
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
327872
|
-
import { createHash as
|
|
328209
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
327873
328210
|
import { isIP } from "node:net";
|
|
327874
328211
|
var ipv4CompatibleSubnet = new import_ip_address.Address6("::/96");
|
|
327875
328212
|
function ipKeyGenerator(ip, ipv6Subnet = 56) {
|
|
@@ -327978,7 +328315,7 @@ var getResetSeconds = (windowMs, resetTime) => {
|
|
|
327978
328315
|
return resetSeconds;
|
|
327979
328316
|
};
|
|
327980
328317
|
var getPartitionKey = (key) => {
|
|
327981
|
-
const hash =
|
|
328318
|
+
const hash = createHash6("sha256");
|
|
327982
328319
|
hash.update(key);
|
|
327983
328320
|
const partitionKey = hash.digest("hex").slice(0, 12);
|
|
327984
328321
|
return Buffer3.from(partitionKey).toString("base64");
|
|
@@ -328660,8 +328997,8 @@ var MCP_ENDPOINT = "/mcp";
|
|
|
328660
328997
|
var SHUTDOWN_DRAIN_DURATION_SECONDS = Number(process.env.SHUTDOWN_DRAIN_DURATION_SECONDS || 0);
|
|
328661
328998
|
var SHUTDOWN_GRACEFUL_CLOSE_TIMEOUT_SECONDS = Number(process.env.SHUTDOWN_GRACEFUL_CLOSE_TIMEOUT_SECONDS || 0);
|
|
328662
328999
|
var __filename_esm = fileURLToPath8(import.meta.url);
|
|
328663
|
-
var ROOT =
|
|
328664
|
-
var SERVER_ROOT =
|
|
329000
|
+
var ROOT = path16.join(path16.dirname(__filename_esm), "app");
|
|
329001
|
+
var SERVER_ROOT = path16.resolve(process.cwd(), process.env.SERVER_ROOT || ".");
|
|
328665
329002
|
var API_PREFIX2 = "/api/v0";
|
|
328666
329003
|
var isDevelopment = process.env["NODE_ENV"] === "development";
|
|
328667
329004
|
var app = import_express.default();
|
|
@@ -328768,7 +329105,7 @@ mcpApp.all(MCP_ENDPOINT, async (req, res) => {
|
|
|
328768
329105
|
}
|
|
328769
329106
|
}
|
|
328770
329107
|
});
|
|
328771
|
-
var PUBLISHER_RUNTIME_PATH =
|
|
329108
|
+
var PUBLISHER_RUNTIME_PATH = path16.join(path16.dirname(__filename_esm), "runtime", "publisher.js");
|
|
328772
329109
|
app.get("/sdk/publisher.js", (_req, res) => {
|
|
328773
329110
|
res.type("application/javascript");
|
|
328774
329111
|
res.setHeader("cache-control", "public, max-age=60");
|
|
@@ -328797,7 +329134,7 @@ async function serveFromPackage(req, res) {
|
|
|
328797
329134
|
try {
|
|
328798
329135
|
const environment = await environmentStore.getEnvironment(req.params.environmentName, false);
|
|
328799
329136
|
const pkg = await environment.getPackage(req.params.packageName, false);
|
|
328800
|
-
const publicRoot =
|
|
329137
|
+
const publicRoot = path16.join(pkg.getPackagePath(), "public");
|
|
328801
329138
|
let subPath = subPathRaw;
|
|
328802
329139
|
if (subPath === "" || subPath.endsWith("/")) {
|
|
328803
329140
|
subPath = subPath + "index.html";
|
|
@@ -328815,12 +329152,12 @@ async function serveFromPackage(req, res) {
|
|
|
328815
329152
|
}
|
|
328816
329153
|
return;
|
|
328817
329154
|
}
|
|
328818
|
-
const rel =
|
|
328819
|
-
if (rel.startsWith("..") ||
|
|
329155
|
+
const rel = path16.relative(realPublicRoot, realFullPath);
|
|
329156
|
+
if (rel.startsWith("..") || path16.isAbsolute(rel)) {
|
|
328820
329157
|
res.status(403).end();
|
|
328821
329158
|
return;
|
|
328822
329159
|
}
|
|
328823
|
-
const ext =
|
|
329160
|
+
const ext = path16.extname(realFullPath).toLowerCase();
|
|
328824
329161
|
if (ext === ".html" || ext === ".htm") {
|
|
328825
329162
|
const frameAncestors = process.env.PUBLISHER_FRAME_ANCESTORS || "*";
|
|
328826
329163
|
res.setHeader("Content-Security-Policy", `frame-ancestors ${frameAncestors}`);
|
|
@@ -328886,20 +329223,20 @@ async function listPackageDataApps(environmentName, packageName, publicRoot) {
|
|
|
328886
329223
|
for (const entry of entries) {
|
|
328887
329224
|
if (entry.name.startsWith(".") || entry.name === "node_modules")
|
|
328888
329225
|
continue;
|
|
328889
|
-
const full =
|
|
329226
|
+
const full = path16.join(dir, entry.name);
|
|
328890
329227
|
let realFull;
|
|
328891
329228
|
try {
|
|
328892
329229
|
realFull = await fs11.realpath(full);
|
|
328893
329230
|
} catch {
|
|
328894
329231
|
continue;
|
|
328895
329232
|
}
|
|
328896
|
-
const contained =
|
|
328897
|
-
if (contained.startsWith("..") ||
|
|
329233
|
+
const contained = path16.relative(realPublicRoot, realFull);
|
|
329234
|
+
if (contained.startsWith("..") || path16.isAbsolute(contained))
|
|
328898
329235
|
continue;
|
|
328899
329236
|
if (entry.isDirectory()) {
|
|
328900
329237
|
await walk2(full, depth + 1);
|
|
328901
329238
|
} else if (entry.isFile() && (entry.name.endsWith(".html") || entry.name.endsWith(".htm"))) {
|
|
328902
|
-
const rel =
|
|
329239
|
+
const rel = path16.relative(publicRoot, full).replace(/\\/g, "/");
|
|
328903
329240
|
let title = rel;
|
|
328904
329241
|
let fit;
|
|
328905
329242
|
try {
|
|
@@ -328944,14 +329281,14 @@ async function listPackageDataApps(environmentName, packageName, publicRoot) {
|
|
|
328944
329281
|
}
|
|
328945
329282
|
if (!isDevelopment) {
|
|
328946
329283
|
app.use("/", import_express.default.static(ROOT));
|
|
328947
|
-
app.use("/api-doc.html", import_express.default.static(
|
|
329284
|
+
app.use("/api-doc.html", import_express.default.static(path16.join(ROOT, "api-doc.html")));
|
|
328948
329285
|
} else {
|
|
328949
329286
|
app.use(`${API_PREFIX2}`, loggerMiddleware);
|
|
328950
329287
|
app.use(import_http_proxy_middleware.createProxyMiddleware({
|
|
328951
329288
|
target: "http://localhost:5173",
|
|
328952
329289
|
changeOrigin: true,
|
|
328953
329290
|
ws: true,
|
|
328954
|
-
pathFilter: (
|
|
329291
|
+
pathFilter: (path17) => !path17.startsWith("/api/") && !path17.startsWith("/metrics") && !path17.startsWith("/health")
|
|
328955
329292
|
}));
|
|
328956
329293
|
}
|
|
328957
329294
|
var setVersionIdError2 = (res) => {
|
|
@@ -328976,7 +329313,7 @@ app.get(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/data
|
|
|
328976
329313
|
try {
|
|
328977
329314
|
const environment = await environmentStore.getEnvironment(req.params.environmentName, false);
|
|
328978
329315
|
const pkg = await environment.getPackage(req.params.packageName, false);
|
|
328979
|
-
const dataApps = await listPackageDataApps(req.params.environmentName, req.params.packageName,
|
|
329316
|
+
const dataApps = await listPackageDataApps(req.params.environmentName, req.params.packageName, path16.join(pkg.getPackagePath(), "public"));
|
|
328980
329317
|
res.json(dataApps);
|
|
328981
329318
|
} catch (error) {
|
|
328982
329319
|
logger.error("Failed to list package data apps", { error });
|
|
@@ -329349,17 +329686,6 @@ app.post(`${API_PREFIX2}/environments/:environmentName/packages`, async (req, re
|
|
|
329349
329686
|
res.status(status).json(json);
|
|
329350
329687
|
}
|
|
329351
329688
|
});
|
|
329352
|
-
app.get(`${API_PREFIX2}/environments/:environmentName/packages/materializations`, async (req, res) => {
|
|
329353
|
-
try {
|
|
329354
|
-
const limit = parseNonNegativeIntParam(req.query.limit);
|
|
329355
|
-
const offset = parseNonNegativeIntParam(req.query.offset);
|
|
329356
|
-
const builds = await materializationController.listEnvironmentMaterializations(req.params.environmentName, { limit, offset });
|
|
329357
|
-
res.status(200).json(builds);
|
|
329358
|
-
} catch (error) {
|
|
329359
|
-
const { json, status } = internalErrorToHttpError(error);
|
|
329360
|
-
res.status(status).json(json);
|
|
329361
|
-
}
|
|
329362
|
-
});
|
|
329363
329689
|
app.get(`${API_PREFIX2}/environments/:environmentName/packages/:packageName`, async (req, res) => {
|
|
329364
329690
|
if (req.query.versionId) {
|
|
329365
329691
|
setVersionIdError2(res);
|
|
@@ -329422,6 +329748,30 @@ app.get(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/mode
|
|
|
329422
329748
|
res.status(status).json(json);
|
|
329423
329749
|
}
|
|
329424
329750
|
});
|
|
329751
|
+
app.put(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/models/*?`, async (req, res) => {
|
|
329752
|
+
if (req.query.versionId) {
|
|
329753
|
+
setVersionIdError2(res);
|
|
329754
|
+
return;
|
|
329755
|
+
}
|
|
329756
|
+
try {
|
|
329757
|
+
const result = await dashboardController.putDashboardSource(req.params.environmentName, req.params.packageName, req.params["0"], req.body);
|
|
329758
|
+
res.status(result.created ? 201 : 200).json(result);
|
|
329759
|
+
} catch (error) {
|
|
329760
|
+
const { json, status } = internalErrorToHttpError(error);
|
|
329761
|
+
const detail = {
|
|
329762
|
+
environmentName: req.params.environmentName,
|
|
329763
|
+
packageName: req.params.packageName,
|
|
329764
|
+
modelPath: req.params["0"],
|
|
329765
|
+
status,
|
|
329766
|
+
error
|
|
329767
|
+
};
|
|
329768
|
+
if (status >= 500)
|
|
329769
|
+
logger.error("Dashboard write failed", detail);
|
|
329770
|
+
else
|
|
329771
|
+
logger.warn("Dashboard write refused", detail);
|
|
329772
|
+
res.status(status).json(json);
|
|
329773
|
+
}
|
|
329774
|
+
});
|
|
329425
329775
|
app.get(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/dashboards`, async (req, res) => {
|
|
329426
329776
|
if (req.query.versionId) {
|
|
329427
329777
|
setVersionIdError2(res);
|
|
@@ -329641,7 +329991,7 @@ registerLegacyRoutes(app, {
|
|
|
329641
329991
|
materializationController
|
|
329642
329992
|
});
|
|
329643
329993
|
if (!isDevelopment) {
|
|
329644
|
-
const SPA_INDEX =
|
|
329994
|
+
const SPA_INDEX = path16.resolve(ROOT, "index.html");
|
|
329645
329995
|
const escapeHtml = (value) => value.replace(/[<>&]/g, (c) => ({ "<": "<", ">": ">", "&": "&" })[c] ?? c);
|
|
329646
329996
|
const decodeSegment = (segment) => {
|
|
329647
329997
|
if (segment === undefined)
|