@malloy-publisher/server 0.2.4 → 0.2.6
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 +40 -8
- package/dist/app/assets/{EnvironmentPage-CMzxoXwh.js → EnvironmentPage-BAegPFOF.js} +1 -1
- package/dist/app/assets/{HomePage-DGB13NHr.js → HomePage-DpDWLD0m.js} +1 -1
- package/dist/app/assets/{LightMode-drhYHM27.js → LightMode-CAFl4Cvr.js} +1 -1
- package/dist/app/assets/{MainPage-BfFE47Sp.js → MainPage-DBHZF__d.js} +1 -1
- package/dist/app/assets/{MaterializationsPage-C_iwL_3A.js → MaterializationsPage-DS5Wrhkc.js} +1 -1
- package/dist/app/assets/{ModelPage-nls853_3.js → ModelPage-BE19OgP9.js} +1 -1
- package/dist/app/assets/{PackagePage-D_e_fXEW.js → PackagePage-D5gz7Abx.js} +1 -1
- package/dist/app/assets/{RouteError-Bej8W2nX.js → RouteError-BE1pcxrx.js} +1 -1
- package/dist/app/assets/{ThemeEditorPage-BoxpETpC.js → ThemeEditorPage-CiRxkL1D.js} +1 -1
- package/dist/app/assets/{WorkbookPage-DObenCMx.js → WorkbookPage-Czc9IG0b.js} +1 -1
- package/dist/app/assets/{core-CHmvIICy.es-C_LOF_0M.js → core-xdZbLgaF.es-BGrT15Sy.js} +1 -1
- package/dist/app/assets/{index-5p0haSOb.js → index-73xxtSWr.js} +1 -1
- package/dist/app/assets/{index-BmFFAoZx.js → index-BVkVGR63.js} +1 -1
- package/dist/app/assets/{index-QM4T1eJn.js → index-C22pKyUm.js} +1 -1
- package/dist/app/assets/{index-sZHvyEzw.js → index-DcYLvDJ2.js} +4 -4
- package/dist/app/index.html +1 -1
- package/dist/package_load_worker.mjs +671 -180
- package/dist/server.mjs +437 -53
- package/package.json +1 -1
package/dist/server.mjs
CHANGED
|
@@ -156558,6 +156558,8 @@ function internalErrorToHttpError(error) {
|
|
|
156558
156558
|
return httpError(404, error.message);
|
|
156559
156559
|
} else if (error instanceof MalloyError) {
|
|
156560
156560
|
return httpError(400, error.message);
|
|
156561
|
+
} else if (error instanceof TableNotFoundError) {
|
|
156562
|
+
return httpError(404, error.message, "TABLE_NOT_FOUND");
|
|
156561
156563
|
} else if (error instanceof ConnectionNotFoundError) {
|
|
156562
156564
|
return httpError(404, error.message);
|
|
156563
156565
|
} else if (error instanceof DestinationNotFoundError) {
|
|
@@ -156590,16 +156592,17 @@ function internalErrorToHttpError(error) {
|
|
|
156590
156592
|
return httpError(500, error.message);
|
|
156591
156593
|
}
|
|
156592
156594
|
}
|
|
156593
|
-
function httpError(code, message) {
|
|
156595
|
+
function httpError(code, message, reason) {
|
|
156594
156596
|
return {
|
|
156595
156597
|
status: code,
|
|
156596
156598
|
json: {
|
|
156597
156599
|
code,
|
|
156598
|
-
message
|
|
156600
|
+
message,
|
|
156601
|
+
...reason ? { reason } : {}
|
|
156599
156602
|
}
|
|
156600
156603
|
};
|
|
156601
156604
|
}
|
|
156602
|
-
var NotImplementedError, BadRequestError, InvalidArgumentError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, MaterializationEligibilityError, PublisherConfigError, FrozenConfigError, AccessDeniedError, NotQueryableError, MaterializationNotFoundError, MaterializationConflictError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
|
|
156605
|
+
var 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;
|
|
156603
156606
|
var init_errors = __esm(() => {
|
|
156604
156607
|
init_constants();
|
|
156605
156608
|
NotImplementedError = class NotImplementedError extends Error {
|
|
@@ -156639,6 +156642,11 @@ var init_errors = __esm(() => {
|
|
|
156639
156642
|
super(message);
|
|
156640
156643
|
}
|
|
156641
156644
|
};
|
|
156645
|
+
TableNotFoundError = class TableNotFoundError extends Error {
|
|
156646
|
+
constructor(message) {
|
|
156647
|
+
super(message);
|
|
156648
|
+
}
|
|
156649
|
+
};
|
|
156642
156650
|
ConnectionError = class ConnectionError extends Error {
|
|
156643
156651
|
constructor(message) {
|
|
156644
156652
|
super(message);
|
|
@@ -234644,14 +234652,14 @@ var init_connection = __esm(() => {
|
|
|
234644
234652
|
});
|
|
234645
234653
|
const result2 = await super.fetchTableSchema(tableKey, azureUrl);
|
|
234646
234654
|
if (!result2) {
|
|
234647
|
-
throw new
|
|
234655
|
+
throw new TableNotFoundError(`Azure file not found: ${azureUrl}`);
|
|
234648
234656
|
}
|
|
234649
234657
|
return result2;
|
|
234650
234658
|
}
|
|
234651
234659
|
}
|
|
234652
234660
|
const result = await super.fetchTableSchema(tableKey, tablePath);
|
|
234653
234661
|
if (!result) {
|
|
234654
|
-
throw new
|
|
234662
|
+
throw new TableNotFoundError(`Table ${tablePath} not found`);
|
|
234655
234663
|
}
|
|
234656
234664
|
return result;
|
|
234657
234665
|
}
|
|
@@ -234703,13 +234711,13 @@ var init_connection = __esm(() => {
|
|
|
234703
234711
|
});
|
|
234704
234712
|
const result2 = await super.fetchTableSchema(tableKey, prefixedPath);
|
|
234705
234713
|
if (!result2) {
|
|
234706
|
-
throw new
|
|
234714
|
+
throw new TableNotFoundError(`Table ${prefixedPath} not found in connection ${this.connectionName}`);
|
|
234707
234715
|
}
|
|
234708
234716
|
return result2;
|
|
234709
234717
|
}
|
|
234710
234718
|
const result = await super.fetchTableSchema(tableKey, tablePath);
|
|
234711
234719
|
if (!result) {
|
|
234712
|
-
throw new
|
|
234720
|
+
throw new TableNotFoundError(`Table ${tablePath} not found in connection ${this.connectionName}`);
|
|
234713
234721
|
}
|
|
234714
234722
|
return result;
|
|
234715
234723
|
}
|
|
@@ -251802,6 +251810,118 @@ var init_gate_registry_walk = __esm(() => {
|
|
|
251802
251810
|
init_authorize();
|
|
251803
251811
|
});
|
|
251804
251812
|
|
|
251813
|
+
// src/service/partition_annotation.ts
|
|
251814
|
+
import { payloadOf as payloadOf2, routeOf as routeOf2 } from "@malloydata/malloy";
|
|
251815
|
+
function noteRoute2(text) {
|
|
251816
|
+
return routeOf2({ value: text.trimStart() });
|
|
251817
|
+
}
|
|
251818
|
+
function containsPartitionAnnotationTag(texts) {
|
|
251819
|
+
return texts.some((text) => noteRoute2(text) === PARTITION_ROUTE);
|
|
251820
|
+
}
|
|
251821
|
+
function reachesPartitionTagBelow(node, seen = new WeakSet, depth = 0) {
|
|
251822
|
+
if (depth > MAX_PARTITION_IR_WALK_DEPTH) {
|
|
251823
|
+
throw new Error("partition-marker IR walk exceeded max depth");
|
|
251824
|
+
}
|
|
251825
|
+
if (node === null || typeof node !== "object")
|
|
251826
|
+
return false;
|
|
251827
|
+
if (seen.has(node))
|
|
251828
|
+
return false;
|
|
251829
|
+
seen.add(node);
|
|
251830
|
+
if (Array.isArray(node)) {
|
|
251831
|
+
return node.some((item) => reachesPartitionTagBelow(item, seen, depth + 1));
|
|
251832
|
+
}
|
|
251833
|
+
const record = node;
|
|
251834
|
+
if (depth > 0 && record.join !== undefined)
|
|
251835
|
+
return false;
|
|
251836
|
+
if (depth > 0) {
|
|
251837
|
+
for (const key of ["blockNotes", "notes"]) {
|
|
251838
|
+
const arr = record[key];
|
|
251839
|
+
if (!Array.isArray(arr))
|
|
251840
|
+
continue;
|
|
251841
|
+
const texts = arr.map((n) => typeof n === "string" ? n : n && typeof n === "object" && typeof n.text === "string" ? n.text : undefined).filter((text) => text !== undefined);
|
|
251842
|
+
if (containsPartitionAnnotationTag(texts))
|
|
251843
|
+
return true;
|
|
251844
|
+
}
|
|
251845
|
+
}
|
|
251846
|
+
return Object.entries(record).some(([key, value]) => depth === 0 && key === "annotations" ? false : reachesPartitionTagBelow(value, seen, depth + 1));
|
|
251847
|
+
}
|
|
251848
|
+
function notePayload2(text) {
|
|
251849
|
+
return payloadOf2({ value: text.trimStart() }) ?? "";
|
|
251850
|
+
}
|
|
251851
|
+
function rejectionMessage(sourceName, body, detail) {
|
|
251852
|
+
return `Source "${sourceName}" declares \`#(partition) ${body}\`: ${detail} ` + `#(partition) only accepts \`<column> = $GIVEN\`, where <column> is a ` + `single field or a dotted join path.`;
|
|
251853
|
+
}
|
|
251854
|
+
function reject(sourceName, body, cause, detail) {
|
|
251855
|
+
throw new PartitionAnnotationError(cause, rejectionMessage(sourceName, body, detail));
|
|
251856
|
+
}
|
|
251857
|
+
function parsePartitionAnnotation(sourceName, annotationText) {
|
|
251858
|
+
if (noteRoute2(annotationText) !== PARTITION_ROUTE)
|
|
251859
|
+
return null;
|
|
251860
|
+
const body = notePayload2(annotationText).trim();
|
|
251861
|
+
if (body.length === 0) {
|
|
251862
|
+
reject(sourceName, body, "empty_body", "the expression body is empty.");
|
|
251863
|
+
}
|
|
251864
|
+
if (COMPOUND_BOOLEAN_RE.test(body)) {
|
|
251865
|
+
reject(sourceName, body, "compound_boolean", "a compound boolean (`and`/`or`/`not`) is not allowed — declare one " + "`#(partition)` marker per column.");
|
|
251866
|
+
}
|
|
251867
|
+
if (IN_OPERATOR_RE.test(body)) {
|
|
251868
|
+
reject(sourceName, body, "in_operator", "the `in` operator is not allowed.");
|
|
251869
|
+
}
|
|
251870
|
+
if (NEGATED_OPERATOR_RE.test(body)) {
|
|
251871
|
+
reject(sourceName, body, "negated_operator", "`!=` is not allowed.");
|
|
251872
|
+
}
|
|
251873
|
+
if (COMPARISON_OPERATOR_RE.test(body)) {
|
|
251874
|
+
reject(sourceName, body, "comparison_operator", "only `=` is allowed, not `<`/`>`/`<=`/`>=`.");
|
|
251875
|
+
}
|
|
251876
|
+
const eq = body.indexOf("=");
|
|
251877
|
+
if (eq === -1) {
|
|
251878
|
+
reject(sourceName, body, "malformed_body", "no `=` was found.");
|
|
251879
|
+
}
|
|
251880
|
+
const left = body.slice(0, eq).trim();
|
|
251881
|
+
const right = body.slice(eq + 1).trim();
|
|
251882
|
+
if (!FIELD_PATH_RE.test(left)) {
|
|
251883
|
+
reject(sourceName, body, "left_not_field_path", `\`${left}\` is not a field path — the left side must be a single ` + "column or a dotted join path, not an expression.");
|
|
251884
|
+
}
|
|
251885
|
+
const givenMatch = GIVEN_REF_RE.exec(right);
|
|
251886
|
+
if (!givenMatch) {
|
|
251887
|
+
reject(sourceName, body, "missing_given_reference", `\`${right}\` is not a given reference — the right side must be ` + "`$NAME`.");
|
|
251888
|
+
}
|
|
251889
|
+
return { column: left, given: givenMatch[1] };
|
|
251890
|
+
}
|
|
251891
|
+
function collectPartitionPairs(sourceName, annotationTexts2) {
|
|
251892
|
+
const pairs = [];
|
|
251893
|
+
const seenGivens = new Map;
|
|
251894
|
+
for (const text of annotationTexts2) {
|
|
251895
|
+
const pair = parsePartitionAnnotation(sourceName, text);
|
|
251896
|
+
if (pair === null)
|
|
251897
|
+
continue;
|
|
251898
|
+
const priorColumn = seenGivens.get(pair.given);
|
|
251899
|
+
if (priorColumn !== undefined) {
|
|
251900
|
+
throw new PartitionAnnotationError("duplicate_given", `Source "${sourceName}" declares \`#(partition)\` on both ` + `\`${priorColumn}\` and \`${pair.column}\` for the same given ` + `\`$${pair.given}\` — a given can back at most one partition ` + `column per source.`);
|
|
251901
|
+
}
|
|
251902
|
+
seenGivens.set(pair.given, pair.column);
|
|
251903
|
+
pairs.push(pair);
|
|
251904
|
+
}
|
|
251905
|
+
return pairs;
|
|
251906
|
+
}
|
|
251907
|
+
var PARTITION_ROUTE = "partition", MAX_PARTITION_IR_WALK_DEPTH = 200, PartitionAnnotationError, IDENT = "[A-Za-z_][A-Za-z0-9_]*", FIELD_PATH_RE, GIVEN_REF_RE, COMPOUND_BOOLEAN_RE, IN_OPERATOR_RE, NEGATED_OPERATOR_RE, COMPARISON_OPERATOR_RE;
|
|
251908
|
+
var init_partition_annotation = __esm(() => {
|
|
251909
|
+
init_errors();
|
|
251910
|
+
PartitionAnnotationError = class PartitionAnnotationError extends ModelCompilationError {
|
|
251911
|
+
rejectionCause;
|
|
251912
|
+
constructor(rejectionCause, message) {
|
|
251913
|
+
super({ message });
|
|
251914
|
+
this.rejectionCause = rejectionCause;
|
|
251915
|
+
}
|
|
251916
|
+
};
|
|
251917
|
+
FIELD_PATH_RE = new RegExp(`^${IDENT}(?:\\.${IDENT})*$`);
|
|
251918
|
+
GIVEN_REF_RE = new RegExp(`^\\$(${IDENT})$`);
|
|
251919
|
+
COMPOUND_BOOLEAN_RE = /\b(and|or|not)\b/i;
|
|
251920
|
+
IN_OPERATOR_RE = /\bin\b/i;
|
|
251921
|
+
NEGATED_OPERATOR_RE = /!=/;
|
|
251922
|
+
COMPARISON_OPERATOR_RE = /(>=|<=|>|<)/;
|
|
251923
|
+
});
|
|
251924
|
+
|
|
251805
251925
|
// src/service/gate_classification.ts
|
|
251806
251926
|
import {
|
|
251807
251927
|
isSourceDef as isSourceDef4
|
|
@@ -252032,12 +252152,142 @@ function isBareFalseLiteral(expr) {
|
|
|
252032
252152
|
function computeGivenDeclaredTypes(givens) {
|
|
252033
252153
|
return new Map((givens ?? []).filter((g) => g.name != null && g.type != null).map((g) => [g.name, g.type]));
|
|
252034
252154
|
}
|
|
252155
|
+
function resolveEntryPointPartitions(struct, modelDef, seen = new Set) {
|
|
252156
|
+
if (!struct || !modelDef || seen.has(struct))
|
|
252157
|
+
return [];
|
|
252158
|
+
seen.add(struct);
|
|
252159
|
+
const label = struct.as ?? struct.name;
|
|
252160
|
+
const own = collectPartitionPairs(label, ownLevelNotes(struct.annotations).map((note) => note.text));
|
|
252161
|
+
if (own.length > 0)
|
|
252162
|
+
return own;
|
|
252163
|
+
let inherited = struct.annotations?.inherits;
|
|
252164
|
+
for (let depth = 0;inherited && depth < ANCESTOR_WALK_MAX_DEPTH; depth++) {
|
|
252165
|
+
const pairs = collectPartitionPairs(label, ownLevelNoteTexts(inherited));
|
|
252166
|
+
if (pairs.length > 0)
|
|
252167
|
+
return pairs;
|
|
252168
|
+
inherited = inherited.inherits;
|
|
252169
|
+
}
|
|
252170
|
+
if (inherited)
|
|
252171
|
+
throw unresolvableAncestry(label);
|
|
252172
|
+
const declared = resolveDeclaredSource(struct, modelDef);
|
|
252173
|
+
if (declared.kind === "unresolvable")
|
|
252174
|
+
throw unresolvableAncestry(label);
|
|
252175
|
+
if (declared.kind === "resolved") {
|
|
252176
|
+
const pairs = resolveEntryPointPartitions(declared.source, modelDef, seen);
|
|
252177
|
+
if (pairs.length > 0)
|
|
252178
|
+
return pairs;
|
|
252179
|
+
}
|
|
252180
|
+
const queryBase = resolveQuerySourceBase(struct, modelDef);
|
|
252181
|
+
if (queryBase)
|
|
252182
|
+
return resolveEntryPointPartitions(queryBase, modelDef, seen);
|
|
252183
|
+
return [];
|
|
252184
|
+
}
|
|
252185
|
+
function unresolvableAncestry(label) {
|
|
252186
|
+
return new PartitionAnnotationError("ancestry_unresolvable", `Could not resolve whether source "${label}" carries a ` + `\`#(partition)\` marker: the derivation chain it inherits from ` + `could not be read. Denying rather than serving unfiltered.`);
|
|
252187
|
+
}
|
|
252188
|
+
function assertPartitionAnnotationsValid(modelDef) {
|
|
252189
|
+
if (!modelDef)
|
|
252190
|
+
return;
|
|
252191
|
+
for (const [key, obj] of Object.entries(modelDef.contents)) {
|
|
252192
|
+
if (!isSourceDef4(obj))
|
|
252193
|
+
continue;
|
|
252194
|
+
const label = obj.as ?? obj.name ?? key;
|
|
252195
|
+
if (obj.type !== "composite") {
|
|
252196
|
+
let resolved = [];
|
|
252197
|
+
try {
|
|
252198
|
+
resolved = resolveEntryPointPartitions(obj, modelDef);
|
|
252199
|
+
} catch (err) {
|
|
252200
|
+
if (!(err instanceof PartitionAnnotationError) || err.rejectionCause !== "ancestry_unresolvable") {
|
|
252201
|
+
throw err;
|
|
252202
|
+
}
|
|
252203
|
+
continue;
|
|
252204
|
+
}
|
|
252205
|
+
assertNoUnreachableMarker(obj, label, resolved);
|
|
252206
|
+
continue;
|
|
252207
|
+
}
|
|
252208
|
+
if (resolveEntryPointPartitions(obj, modelDef).length > 0) {
|
|
252209
|
+
throw new PartitionAnnotationError("partitioned_composite", `Source "${label}" is a composite source (\`compose(...)\`) and ` + `also declares \`#(partition)\` (on itself or an ancestor it ` + `derives from). A composite run target compiles each query ` + `against one resolved member branch, which a partition filter ` + `cannot attach to — declare \`#(partition)\` on a non-composite ` + `source instead.`);
|
|
252210
|
+
}
|
|
252211
|
+
const marked = partitionedMemberLabel(obj, modelDef);
|
|
252212
|
+
if (marked !== undefined) {
|
|
252213
|
+
throw new PartitionAnnotationError("partitioned_composite", `Source "${label}" is a composite source (\`compose(...)\`) with ` + `member "${marked}", which declares \`#(partition)\`. MEASURED: ` + `querying the composite reads EVERY partition of that member — ` + `the graft lands on the composite's own struct, not the ` + `resolved member branch, so no filter reaches the executed ` + `query. Remove the composite, or drop \`#(partition)\` from ` + `"${marked}" and expose it as its own source.`);
|
|
252214
|
+
}
|
|
252215
|
+
}
|
|
252216
|
+
}
|
|
252217
|
+
function assertNoUnreachableMarker(struct, label, resolved) {
|
|
252218
|
+
if (resolved.length > 0)
|
|
252219
|
+
return;
|
|
252220
|
+
let reachesBelow;
|
|
252221
|
+
try {
|
|
252222
|
+
reachesBelow = reachesPartitionTagBelow(struct);
|
|
252223
|
+
} catch {
|
|
252224
|
+
reachesBelow = true;
|
|
252225
|
+
}
|
|
252226
|
+
if (!reachesBelow)
|
|
252227
|
+
return;
|
|
252228
|
+
throw new PartitionAnnotationError("marker_unreachable", `Source "${label}" carries a \`#(partition)\` marker that is not ` + `declared on the source itself — it sits on a field, a view, or an ` + `inline \`compose(...)\` inside it. Nothing would filter this ` + `source: every caller would read every partition. Move the marker ` + `onto the \`source:\` declaration.`);
|
|
252229
|
+
}
|
|
252230
|
+
function partitionedMemberLabel(composite, modelDef, seen = new Set) {
|
|
252231
|
+
if (seen.has(composite))
|
|
252232
|
+
return;
|
|
252233
|
+
seen.add(composite);
|
|
252234
|
+
for (const member of composite.sources ?? []) {
|
|
252235
|
+
const label = member.as ?? member.name;
|
|
252236
|
+
if (resolveEntryPointPartitions(member, modelDef).length > 0) {
|
|
252237
|
+
return label;
|
|
252238
|
+
}
|
|
252239
|
+
if (member.type === "composite") {
|
|
252240
|
+
const nested = partitionedMemberLabel(member, modelDef, seen);
|
|
252241
|
+
if (nested !== undefined)
|
|
252242
|
+
return nested;
|
|
252243
|
+
}
|
|
252244
|
+
}
|
|
252245
|
+
return;
|
|
252246
|
+
}
|
|
252247
|
+
async function resolvePartitionGraftEntries(struct, originModelDef, graftScope, deps) {
|
|
252248
|
+
if (!struct || !originModelDef)
|
|
252249
|
+
return [];
|
|
252250
|
+
const pairs = resolveEntryPointPartitions(struct, originModelDef);
|
|
252251
|
+
if (pairs.length === 0)
|
|
252252
|
+
return [];
|
|
252253
|
+
const label = struct.as ?? struct.name;
|
|
252254
|
+
if (!graftScope) {
|
|
252255
|
+
logger.debug("Partition filter has no graft scope to attach to; denying", { modelPath: deps.modelPath, label });
|
|
252256
|
+
throw new Error(`partition on "${label}" has no graft scope`);
|
|
252257
|
+
}
|
|
252258
|
+
const graftTarget = resolveGraftTarget(struct, originModelDef, graftScope.modelDef);
|
|
252259
|
+
if (!graftTarget) {
|
|
252260
|
+
logger.debug("Partition filter resolved to no graft target; denying", {
|
|
252261
|
+
modelPath: deps.modelPath,
|
|
252262
|
+
label
|
|
252263
|
+
});
|
|
252264
|
+
throw new Error(`partition on "${label}" resolved to no graft target`);
|
|
252265
|
+
}
|
|
252266
|
+
const entries = [];
|
|
252267
|
+
for (const pair of pairs) {
|
|
252268
|
+
if (!deps.givenDeclaredTypes.has(pair.given)) {
|
|
252269
|
+
logger.warn("Partition references a given off the model surface; denying", { modelPath: deps.modelPath, graftTarget, givenName: pair.given });
|
|
252270
|
+
throw new Error(`partition on "${label}" references \`$${pair.given}\`, which is not on this model's given surface`);
|
|
252271
|
+
}
|
|
252272
|
+
const filterText = `${pair.column} = $${pair.given}`;
|
|
252273
|
+
const condition = await liftGateCondition(graftTarget, filterText, graftScope.materializer);
|
|
252274
|
+
entries.push({
|
|
252275
|
+
label,
|
|
252276
|
+
graftTarget,
|
|
252277
|
+
filterText,
|
|
252278
|
+
condition,
|
|
252279
|
+
givenNames: [pair.given]
|
|
252280
|
+
});
|
|
252281
|
+
}
|
|
252282
|
+
return entries;
|
|
252283
|
+
}
|
|
252035
252284
|
var init_gate_classification = __esm(() => {
|
|
252036
252285
|
init_logger();
|
|
252037
252286
|
init_annotations();
|
|
252038
252287
|
init_authorize();
|
|
252039
252288
|
init_gate_dimension();
|
|
252040
252289
|
init_gate_registry_walk();
|
|
252290
|
+
init_partition_annotation();
|
|
252041
252291
|
});
|
|
252042
252292
|
|
|
252043
252293
|
// src/service/incremental_declaration.ts
|
|
@@ -252234,8 +252484,24 @@ function assertMaterializationEligible(persistSource) {
|
|
|
252234
252484
|
message: `Source '${sourceName}' cannot be materialized into a storage ` + `destination: it is protected by an #(authorize) gate (its own or a ` + `joined source's). An authorize expression is evaluated per request; ` + `a materialized-once table served frozen carries no gate, so it would ` + `be served to everyone, bypassing authorization. This is refused for ` + `safety. Serve this source live (drop 'storage=').`
|
|
252235
252485
|
});
|
|
252236
252486
|
}
|
|
252487
|
+
if (referencesPartition(persistSource)) {
|
|
252488
|
+
recordEligibilityRefused("partition");
|
|
252489
|
+
throw new MaterializationEligibilityError({
|
|
252490
|
+
reason: "partition",
|
|
252491
|
+
message: `Source '${sourceName}' cannot be materialized into a storage ` + `destination: it declares a #(partition) marker. A partition ` + `filter binds a given at query time (the same mechanism as ` + `row-level access control), so a materialized-once table served ` + `frozen would leak every partition's rows to every caller. This ` + `is refused for safety. Serve this source live (drop 'storage=').`
|
|
252492
|
+
});
|
|
252493
|
+
}
|
|
252237
252494
|
}
|
|
252238
252495
|
function assertColocatedPersistNotAuthorizeGated(persistSource, sourceName = persistSource.name, origin2 = "persist", gateOutcome) {
|
|
252496
|
+
if (referencesPartition(persistSource)) {
|
|
252497
|
+
recordEligibilityRefused("partition");
|
|
252498
|
+
const what2 = origin2 === "preaggregate" ? `Pre-aggregation rollup '${sourceName}'` : `Source '${sourceName}'`;
|
|
252499
|
+
const gated2 = origin2 === "preaggregate" ? `the source '${sourceName}' rolls up declares` : `it declares`;
|
|
252500
|
+
throw new MaterializationEligibilityError({
|
|
252501
|
+
reason: "partition",
|
|
252502
|
+
message: `${what2} cannot be materialized (colocated '#@ persist'): ` + `${gated2} a #(partition) marker. A partition filter binds a ` + `given at query time; this pass cannot prove the persisted ` + `artifact's read path still applies it, so this is refused for ` + `safety. Move the marker to a source that is not materialized, ` + `or stop persisting this one.`
|
|
252503
|
+
});
|
|
252504
|
+
}
|
|
252239
252505
|
if (!referencesAuthorize(persistSource))
|
|
252240
252506
|
return;
|
|
252241
252507
|
if (origin2 === "persist" && gateOutcome?.classification === "row_level" && gateOutcome.attributed) {
|
|
@@ -252311,6 +252577,44 @@ function walkForGiven(node, seen, depth) {
|
|
|
252311
252577
|
}
|
|
252312
252578
|
return false;
|
|
252313
252579
|
}
|
|
252580
|
+
function referencesPartition(persistSource) {
|
|
252581
|
+
try {
|
|
252582
|
+
return walkForPartition(persistSource._sourceDef, new WeakSet, 0);
|
|
252583
|
+
} catch {
|
|
252584
|
+
return true;
|
|
252585
|
+
}
|
|
252586
|
+
}
|
|
252587
|
+
function walkForPartition(node, seen, depth) {
|
|
252588
|
+
if (depth > MAX_GIVEN_WALK_DEPTH) {
|
|
252589
|
+
throw new Error("partition-usage walk exceeded max depth");
|
|
252590
|
+
}
|
|
252591
|
+
if (node === null || typeof node !== "object")
|
|
252592
|
+
return false;
|
|
252593
|
+
if (seen.has(node))
|
|
252594
|
+
return false;
|
|
252595
|
+
seen.add(node);
|
|
252596
|
+
if (Array.isArray(node)) {
|
|
252597
|
+
for (const item of node) {
|
|
252598
|
+
if (walkForPartition(item, seen, depth + 1))
|
|
252599
|
+
return true;
|
|
252600
|
+
}
|
|
252601
|
+
return false;
|
|
252602
|
+
}
|
|
252603
|
+
const record = node;
|
|
252604
|
+
for (const key of ["blockNotes", "notes"]) {
|
|
252605
|
+
const arr = record[key];
|
|
252606
|
+
if (!Array.isArray(arr))
|
|
252607
|
+
continue;
|
|
252608
|
+
const texts = arr.map((n) => typeof n === "string" ? n : n && typeof n === "object" && typeof n.text === "string" ? n.text : undefined).filter((text) => text !== undefined);
|
|
252609
|
+
if (containsPartitionAnnotationTag(texts))
|
|
252610
|
+
return true;
|
|
252611
|
+
}
|
|
252612
|
+
for (const value of Object.values(record)) {
|
|
252613
|
+
if (walkForPartition(value, seen, depth + 1))
|
|
252614
|
+
return true;
|
|
252615
|
+
}
|
|
252616
|
+
return false;
|
|
252617
|
+
}
|
|
252314
252618
|
function referencesAuthorize(persistSource) {
|
|
252315
252619
|
try {
|
|
252316
252620
|
return walkForAuthorize(persistSource._sourceDef, new WeakSet, 0);
|
|
@@ -252411,6 +252715,7 @@ var init_materialization_eligibility = __esm(() => {
|
|
|
252411
252715
|
init_errors();
|
|
252412
252716
|
init_materialization_metrics();
|
|
252413
252717
|
init_authorize();
|
|
252718
|
+
init_partition_annotation();
|
|
252414
252719
|
});
|
|
252415
252720
|
|
|
252416
252721
|
// src/service/preaggregation_compile.ts
|
|
@@ -253865,6 +254170,7 @@ var init_model = __esm(() => {
|
|
|
253865
254170
|
init_query_metadata();
|
|
253866
254171
|
init_preaggregation_validation();
|
|
253867
254172
|
init_gate_registry_walk();
|
|
254173
|
+
init_partition_annotation();
|
|
253868
254174
|
init_gate_classification();
|
|
253869
254175
|
init_source_extraction();
|
|
253870
254176
|
init_authorize_metrics();
|
|
@@ -254060,20 +254366,7 @@ var init_model = __esm(() => {
|
|
|
254060
254366
|
if (!modelDef)
|
|
254061
254367
|
return false;
|
|
254062
254368
|
try {
|
|
254063
|
-
const
|
|
254064
|
-
for (const obj of Object.values(modelDef.contents)) {
|
|
254065
|
-
if (isSourceDef6(obj))
|
|
254066
|
-
structs.push(obj);
|
|
254067
|
-
}
|
|
254068
|
-
for (const value of Object.values(modelDef.sourceRegistry ?? {})) {
|
|
254069
|
-
const entry = value.entry;
|
|
254070
|
-
if (entry.type === "source_registry_reference")
|
|
254071
|
-
continue;
|
|
254072
|
-
if (isSourceDef6(entry))
|
|
254073
|
-
structs.push(entry);
|
|
254074
|
-
}
|
|
254075
|
-
structs.push(...derivedStructsReachable(structs, modelDef));
|
|
254076
|
-
for (const struct of structs) {
|
|
254369
|
+
for (const struct of this.reachableStructsForNoteSweep(modelDef)) {
|
|
254077
254370
|
if (containsAuthorizeAnnotationTag(annotationTexts(struct.annotations) ?? [])) {
|
|
254078
254371
|
return true;
|
|
254079
254372
|
}
|
|
@@ -254090,6 +254383,43 @@ var init_model = __esm(() => {
|
|
|
254090
254383
|
})();
|
|
254091
254384
|
return this.anyAuthorizeNote;
|
|
254092
254385
|
}
|
|
254386
|
+
reachableStructsForNoteSweep(modelDef) {
|
|
254387
|
+
const structs = [];
|
|
254388
|
+
for (const obj of Object.values(modelDef.contents)) {
|
|
254389
|
+
if (isSourceDef6(obj))
|
|
254390
|
+
structs.push(obj);
|
|
254391
|
+
}
|
|
254392
|
+
for (const value of Object.values(modelDef.sourceRegistry ?? {})) {
|
|
254393
|
+
const entry = value.entry;
|
|
254394
|
+
if (entry.type === "source_registry_reference")
|
|
254395
|
+
continue;
|
|
254396
|
+
if (isSourceDef6(entry))
|
|
254397
|
+
structs.push(entry);
|
|
254398
|
+
}
|
|
254399
|
+
structs.push(...derivedStructsReachable(structs, modelDef));
|
|
254400
|
+
return structs;
|
|
254401
|
+
}
|
|
254402
|
+
anyPartitionNote;
|
|
254403
|
+
hasAnyPartitionNote() {
|
|
254404
|
+
if (this.anyPartitionNote !== undefined)
|
|
254405
|
+
return this.anyPartitionNote;
|
|
254406
|
+
this.anyPartitionNote = (() => {
|
|
254407
|
+
const modelDef = this.modelDef;
|
|
254408
|
+
if (!modelDef)
|
|
254409
|
+
return false;
|
|
254410
|
+
try {
|
|
254411
|
+
for (const struct of this.reachableStructsForNoteSweep(modelDef)) {
|
|
254412
|
+
if (containsPartitionAnnotationTag(annotationTexts(struct.annotations) ?? [])) {
|
|
254413
|
+
return true;
|
|
254414
|
+
}
|
|
254415
|
+
}
|
|
254416
|
+
return false;
|
|
254417
|
+
} catch {
|
|
254418
|
+
return true;
|
|
254419
|
+
}
|
|
254420
|
+
})();
|
|
254421
|
+
return this.anyPartitionNote;
|
|
254422
|
+
}
|
|
254093
254423
|
async assertAuthorized(sourceName, _givens, bypassAuthorize = false, graftScope = this.defaultGraftScope()) {
|
|
254094
254424
|
if (bypassAuthorize) {
|
|
254095
254425
|
this.noteAuthorizeBypass("source", sourceName);
|
|
@@ -254146,7 +254476,7 @@ var init_model = __esm(() => {
|
|
|
254146
254476
|
entryPointGates = Array.from(byKey.values());
|
|
254147
254477
|
}
|
|
254148
254478
|
}
|
|
254149
|
-
return { entryPointGates, modelDef };
|
|
254479
|
+
return { entryPointGates, modelDef, struct };
|
|
254150
254480
|
}
|
|
254151
254481
|
async assertAuthorizedFromCompiledRunnable(runnable, givens) {
|
|
254152
254482
|
await this.authorizeAndBindRunnable(runnable, givens, {
|
|
@@ -254158,7 +254488,7 @@ var init_model = __esm(() => {
|
|
|
254158
254488
|
return this.rowLevelFilteredRunnables.has(runnable);
|
|
254159
254489
|
}
|
|
254160
254490
|
async probeEntryPointGates(runnable, givens, graftScope, skipOwnSourceGate = false) {
|
|
254161
|
-
const { entryPointGates, modelDef } = await this.collectAuthorizeEntryPointGates(runnable, givens, graftScope, skipOwnSourceGate);
|
|
254491
|
+
const { entryPointGates, modelDef, struct } = await this.collectAuthorizeEntryPointGates(runnable, givens, graftScope, skipOwnSourceGate);
|
|
254162
254492
|
const rowLevel = [];
|
|
254163
254493
|
for (const entry of entryPointGates) {
|
|
254164
254494
|
const resolution = modelDef ? await this.resolveGateShape(entry, modelDef, graftScope) : { shape: "rejected", cause: undefined };
|
|
@@ -254177,6 +254507,16 @@ var init_model = __esm(() => {
|
|
|
254177
254507
|
recordRowLevelGateRejected(resolution.cause);
|
|
254178
254508
|
throw new AccessDeniedError(`Access denied for source "${entry.label}".`);
|
|
254179
254509
|
}
|
|
254510
|
+
try {
|
|
254511
|
+
rowLevel.push(...await resolvePartitionGraftEntries(struct, modelDef, graftScope, this.gateClassificationDeps()));
|
|
254512
|
+
} catch (err) {
|
|
254513
|
+
recordRowLevelGateDecision("denied_by_gate");
|
|
254514
|
+
logger.debug("Partition filter could not be resolved; denying", {
|
|
254515
|
+
modelPath: this.modelPath,
|
|
254516
|
+
error: err instanceof Error ? err.message : String(err)
|
|
254517
|
+
});
|
|
254518
|
+
throw new AccessDeniedError(`Access denied for source "${struct?.as ?? struct?.name ?? "unknown"}".`);
|
|
254519
|
+
}
|
|
254180
254520
|
return rowLevel;
|
|
254181
254521
|
}
|
|
254182
254522
|
async queryEntryPointHasRowLevelGate(runnable) {
|
|
@@ -254189,7 +254529,7 @@ var init_model = __esm(() => {
|
|
|
254189
254529
|
if (compositeResolvedSourceDef) {
|
|
254190
254530
|
gates.push(...this.collectEntryPointGates(compositeResolvedSourceDef, modelDef, seen, true, undefined, struct ? ownLevelNotes(struct.annotations) : []));
|
|
254191
254531
|
}
|
|
254192
|
-
return gates.length > 0;
|
|
254532
|
+
return gates.length > 0 || resolveEntryPointPartitions(struct, modelDef).length > 0;
|
|
254193
254533
|
} catch {
|
|
254194
254534
|
return true;
|
|
254195
254535
|
}
|
|
@@ -254520,6 +254860,7 @@ var init_model = __esm(() => {
|
|
|
254520
254860
|
filterMap = sourceResult.filterMap;
|
|
254521
254861
|
const queryResult = Model.getQueries(modelDef);
|
|
254522
254862
|
queries = queryResult.queries;
|
|
254863
|
+
assertPartitionAnnotationsValid(modelDef);
|
|
254523
254864
|
assertNoMisplacedAuthorizeAnnotations([
|
|
254524
254865
|
...sourceResult.misplacedAuthorize,
|
|
254525
254866
|
...queryResult.misplacedAuthorize
|
|
@@ -255147,7 +255488,7 @@ run: ${sourceName ? `${quoteMalloyIdentifier2(sourceName)} -> ` : ""}${quoteMall
|
|
|
255147
255488
|
liveRunnable = runnable;
|
|
255148
255489
|
const storageRoutingPossible = getPersistStorageMode() === "on" && this.serveBindings.length > 0 && !!this.serveDestinationConfig;
|
|
255149
255490
|
const preaggServeMaterializer = this.preaggregateServeMaterializer;
|
|
255150
|
-
const routingBlockedByRowLevelGate = (storageRoutingPossible || !!preaggServeMaterializer) && !bypassAuthorize && this.hasAnyAuthorizeNote() && await this.queryEntryPointHasRowLevelGate(runnable);
|
|
255491
|
+
const routingBlockedByRowLevelGate = (storageRoutingPossible || !!preaggServeMaterializer) && !bypassAuthorize && (this.hasAnyAuthorizeNote() || this.hasAnyPartitionNote()) && await this.queryEntryPointHasRowLevelGate(runnable);
|
|
255151
255492
|
if (routingBlockedByRowLevelGate) {
|
|
255152
255493
|
recordStorageServeRouting("blocked_by_row_level_gate");
|
|
255153
255494
|
}
|
|
@@ -256631,10 +256972,10 @@ var require_recursive_readdir = __commonJS((exports, module) => {
|
|
|
256631
256972
|
ignores = [];
|
|
256632
256973
|
}
|
|
256633
256974
|
if (!callback) {
|
|
256634
|
-
return new Promise(function(resolve4,
|
|
256975
|
+
return new Promise(function(resolve4, reject2) {
|
|
256635
256976
|
readdir3(path9, ignores || [], function(err, data) {
|
|
256636
256977
|
if (err) {
|
|
256637
|
-
|
|
256978
|
+
reject2(err);
|
|
256638
256979
|
} else {
|
|
256639
256980
|
resolve4(data);
|
|
256640
256981
|
}
|
|
@@ -277216,6 +277557,26 @@ function validateAdminAuthoredConnection(connectionName, connectionConfig) {
|
|
|
277216
277557
|
}
|
|
277217
277558
|
}
|
|
277218
277559
|
}
|
|
277560
|
+
var BIGQUERY_NOT_FOUND = /^Not found: (Table|Dataset)\b/;
|
|
277561
|
+
var BIGQUERY_IMPROPER_PATH = /^Improper table path\b/;
|
|
277562
|
+
var DUCKDB_TABLE_NOT_FOUND = /^Catalog Error: Table with name .+ does not exist/;
|
|
277563
|
+
var DUCKDB_CATALOG_NOT_FOUND = /^Binder Error: Catalog .+ does not exist/;
|
|
277564
|
+
function driverErrorToPublisherError(message) {
|
|
277565
|
+
if (BIGQUERY_NOT_FOUND.test(message) || DUCKDB_TABLE_NOT_FOUND.test(message) || DUCKDB_CATALOG_NOT_FOUND.test(message)) {
|
|
277566
|
+
return new TableNotFoundError(message);
|
|
277567
|
+
}
|
|
277568
|
+
if (BIGQUERY_IMPROPER_PATH.test(message)) {
|
|
277569
|
+
return new InvalidArgumentError(message);
|
|
277570
|
+
}
|
|
277571
|
+
return new ConnectionError(message);
|
|
277572
|
+
}
|
|
277573
|
+
function classifyDriverFailure(error) {
|
|
277574
|
+
if (error instanceof TableNotFoundError || error instanceof InvalidArgumentError) {
|
|
277575
|
+
return error;
|
|
277576
|
+
}
|
|
277577
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error);
|
|
277578
|
+
return driverErrorToPublisherError(message);
|
|
277579
|
+
}
|
|
277219
277580
|
|
|
277220
277581
|
class ConnectionController {
|
|
277221
277582
|
environmentStore;
|
|
@@ -277282,10 +277643,10 @@ class ConnectionController {
|
|
|
277282
277643
|
try {
|
|
277283
277644
|
const source = await malloyConnection.fetchTableSchema(tableKey, tablePath);
|
|
277284
277645
|
if (!source) {
|
|
277285
|
-
throw new
|
|
277646
|
+
throw new TableNotFoundError(`Table ${tablePath} not found`);
|
|
277286
277647
|
}
|
|
277287
277648
|
if (typeof source === "string") {
|
|
277288
|
-
throw
|
|
277649
|
+
throw driverErrorToPublisherError(source);
|
|
277289
277650
|
}
|
|
277290
277651
|
return {
|
|
277291
277652
|
source: JSON.stringify(source),
|
|
@@ -277296,13 +277657,21 @@ class ConnectionController {
|
|
|
277296
277657
|
}))
|
|
277297
277658
|
};
|
|
277298
277659
|
} catch (error) {
|
|
277299
|
-
const
|
|
277660
|
+
const classified = classifyDriverFailure(error);
|
|
277661
|
+
if (!(classified instanceof ConnectionError)) {
|
|
277662
|
+
logger.warn("table not resolvable", {
|
|
277663
|
+
tableKey,
|
|
277664
|
+
tablePath,
|
|
277665
|
+
reason: classified.constructor.name
|
|
277666
|
+
});
|
|
277667
|
+
throw classified;
|
|
277668
|
+
}
|
|
277300
277669
|
logger.error("fetchTableSchema error", {
|
|
277301
277670
|
error,
|
|
277302
277671
|
tableKey,
|
|
277303
277672
|
tablePath
|
|
277304
277673
|
});
|
|
277305
|
-
throw
|
|
277674
|
+
throw classified;
|
|
277306
277675
|
}
|
|
277307
277676
|
}
|
|
277308
277677
|
async getConnection(environmentName, connectionName) {
|
|
@@ -277336,13 +277705,13 @@ class ConnectionController {
|
|
|
277336
277705
|
selectStr: sqlStatement
|
|
277337
277706
|
});
|
|
277338
277707
|
if (typeof schema === "string") {
|
|
277339
|
-
throw
|
|
277708
|
+
throw driverErrorToPublisherError(schema);
|
|
277340
277709
|
}
|
|
277341
277710
|
return {
|
|
277342
277711
|
source: JSON.stringify(schema)
|
|
277343
277712
|
};
|
|
277344
277713
|
} catch (error) {
|
|
277345
|
-
throw
|
|
277714
|
+
throw classifyDriverFailure(error);
|
|
277346
277715
|
}
|
|
277347
277716
|
}
|
|
277348
277717
|
async getTable(environmentName, connectionName, schemaName, tablePath, packageName) {
|
|
@@ -288124,19 +288493,34 @@ init_model();
|
|
|
288124
288493
|
init_errors();
|
|
288125
288494
|
var PERSIST_LINE_PATTERN = /^\s*#@\s+persist\b/;
|
|
288126
288495
|
var UNQUOTED_NAME_PATTERN = /(?<![.\w])name\s*=\s*(?!["'])/;
|
|
288496
|
+
var QUOTED_NAME_VALUE_PATTERN = /(?<![.\w])name\s*=\s*(["'])(.*?)\1/g;
|
|
288497
|
+
var SAFE_NAME_PATH = /^[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)*$/;
|
|
288127
288498
|
function assertPersistNamesQuoted(modelSource, modelPath) {
|
|
288128
|
-
const
|
|
288499
|
+
const unquoted = [];
|
|
288500
|
+
const unsafe = [];
|
|
288129
288501
|
for (const rawLine of modelSource.split(`
|
|
288130
288502
|
`)) {
|
|
288131
288503
|
if (!PERSIST_LINE_PATTERN.test(rawLine))
|
|
288132
288504
|
continue;
|
|
288133
288505
|
if (UNQUOTED_NAME_PATTERN.test(rawLine)) {
|
|
288134
|
-
|
|
288506
|
+
unquoted.push(rawLine.trim());
|
|
288507
|
+
continue;
|
|
288508
|
+
}
|
|
288509
|
+
for (const match of rawLine.matchAll(QUOTED_NAME_VALUE_PATTERN)) {
|
|
288510
|
+
if (!SAFE_NAME_PATH.test(match[2])) {
|
|
288511
|
+
unsafe.push(rawLine.trim());
|
|
288512
|
+
break;
|
|
288513
|
+
}
|
|
288135
288514
|
}
|
|
288136
288515
|
}
|
|
288137
|
-
if (
|
|
288516
|
+
if (unquoted.length > 0) {
|
|
288138
288517
|
throw new ModelCompilationError({
|
|
288139
|
-
message: `${modelPath}: persist annotation name must be quoted. Write a quoted ` + `value like name="engaged_events" (or a dialect table path such as ` + `name="my_dataset.engaged_events"), not a bare value
|
|
288518
|
+
message: `${modelPath}: persist annotation name must be quoted. Write a quoted ` + `value like name="engaged_events" (or a dialect table path such as ` + `name="my_dataset.engaged_events"), not a bare value -- an unquoted ` + `persist name is dropped from the build plan, so the source would ` + `publish but never materialize. Offending annotation(s): ` + `${unquoted.join("; ")}.`
|
|
288519
|
+
});
|
|
288520
|
+
}
|
|
288521
|
+
if (unsafe.length > 0) {
|
|
288522
|
+
throw new ModelCompilationError({
|
|
288523
|
+
message: `${modelPath}: persist annotation name must be a plain identifier path -- ` + `dot-separated segments of letters, digits, underscores, and hyphens ` + `(e.g. name="engaged_events", name="my_dataset.engaged_events", or a ` + `hyphenated container path name="my-proj.mydataset.engaged_events"). ` + `The name is inlined into the materialization table DDL, so a value ` + `containing a quote, backtick, semicolon, or space is rejected. ` + `Offending annotation(s): ${unsafe.join("; ")}.`
|
|
288140
288524
|
});
|
|
288141
288525
|
}
|
|
288142
288526
|
}
|
|
@@ -290288,8 +290672,8 @@ ${source}` : source ?? "";
|
|
|
290288
290672
|
}
|
|
290289
290673
|
async fetchManifestEntriesWithTimeout(manifestLocation) {
|
|
290290
290674
|
let timer;
|
|
290291
|
-
const timeout = new Promise((_,
|
|
290292
|
-
timer = setTimeout(() =>
|
|
290675
|
+
const timeout = new Promise((_, reject2) => {
|
|
290676
|
+
timer = setTimeout(() => reject2(new Error(`Timed out after ${MANIFEST_FETCH_TIMEOUT_MS}ms fetching manifest ${manifestLocation}`)), MANIFEST_FETCH_TIMEOUT_MS);
|
|
290293
290677
|
});
|
|
290294
290678
|
try {
|
|
290295
290679
|
return await Promise.race([
|
|
@@ -291851,8 +292235,8 @@ class EnvironmentStore {
|
|
|
291851
292235
|
}
|
|
291852
292236
|
const file = fs9.createWriteStream(zipFilePath);
|
|
291853
292237
|
item.Body.transformToWebStream().pipeTo(Writable.toWeb(file));
|
|
291854
|
-
await new Promise((resolve5,
|
|
291855
|
-
file.on("error",
|
|
292238
|
+
await new Promise((resolve5, reject2) => {
|
|
292239
|
+
file.on("error", reject2);
|
|
291856
292240
|
file.on("finish", resolve5);
|
|
291857
292241
|
});
|
|
291858
292242
|
await this.unzipEnvironment(zipFilePath);
|
|
@@ -291891,8 +292275,8 @@ class EnvironmentStore {
|
|
|
291891
292275
|
}
|
|
291892
292276
|
const file = fs9.createWriteStream(absoluteFilePath);
|
|
291893
292277
|
item.Body.transformToWebStream().pipeTo(Writable.toWeb(file));
|
|
291894
|
-
await new Promise((resolve5,
|
|
291895
|
-
file.on("error",
|
|
292278
|
+
await new Promise((resolve5, reject2) => {
|
|
292279
|
+
file.on("error", reject2);
|
|
291896
292280
|
file.on("finish", resolve5);
|
|
291897
292281
|
});
|
|
291898
292282
|
}));
|
|
@@ -291913,7 +292297,7 @@ class EnvironmentStore {
|
|
|
291913
292297
|
await fs9.promises.mkdir(absoluteDirPath, { recursive: true });
|
|
291914
292298
|
const repoUrl = `https://github.com/${owner}/${repoName}`;
|
|
291915
292299
|
const reporter = new CloneProgressReporter(cloneProgressLabel(`${owner}/${repoName}`, progressContext));
|
|
291916
|
-
await new Promise((resolve5,
|
|
292300
|
+
await new Promise((resolve5, reject2) => {
|
|
291917
292301
|
esm_default2({
|
|
291918
292302
|
progress: (event) => reporter.onProgress(event)
|
|
291919
292303
|
}).clone(repoUrl, absoluteDirPath, GIT_CLONE_OPTIONS, (err) => {
|
|
@@ -291925,7 +292309,7 @@ class EnvironmentStore {
|
|
|
291925
292309
|
}
|
|
291926
292310
|
const errorData = this.extractErrorDataFromError(err);
|
|
291927
292311
|
logger.error(`Failed to clone GitHub repository "${repoUrl}"`, errorData);
|
|
291928
|
-
|
|
292312
|
+
reject2(err);
|
|
291929
292313
|
return;
|
|
291930
292314
|
}
|
|
291931
292315
|
resolve5();
|
|
@@ -292708,10 +293092,10 @@ class Protocol {
|
|
|
292708
293092
|
}
|
|
292709
293093
|
request(request, resultSchema, options) {
|
|
292710
293094
|
const { relatedRequestId, resumptionToken, onresumptiontoken } = options !== null && options !== undefined ? options : {};
|
|
292711
|
-
return new Promise((resolve5,
|
|
293095
|
+
return new Promise((resolve5, reject2) => {
|
|
292712
293096
|
var _a2, _b, _c, _d, _e, _f;
|
|
292713
293097
|
if (!this._transport) {
|
|
292714
|
-
|
|
293098
|
+
reject2(new Error("Not connected"));
|
|
292715
293099
|
return;
|
|
292716
293100
|
}
|
|
292717
293101
|
if (((_a2 = this._options) === null || _a2 === undefined ? undefined : _a2.enforceStrictCapabilities) === true) {
|
|
@@ -292747,7 +293131,7 @@ class Protocol {
|
|
|
292747
293131
|
reason: String(reason)
|
|
292748
293132
|
}
|
|
292749
293133
|
}, { relatedRequestId, resumptionToken, onresumptiontoken }).catch((error) => this._onerror(new Error(`Failed to send cancellation: ${error}`)));
|
|
292750
|
-
|
|
293134
|
+
reject2(reason);
|
|
292751
293135
|
};
|
|
292752
293136
|
this._responseHandlers.set(messageId, (response) => {
|
|
292753
293137
|
var _a3;
|
|
@@ -292755,13 +293139,13 @@ class Protocol {
|
|
|
292755
293139
|
return;
|
|
292756
293140
|
}
|
|
292757
293141
|
if (response instanceof Error) {
|
|
292758
|
-
return
|
|
293142
|
+
return reject2(response);
|
|
292759
293143
|
}
|
|
292760
293144
|
try {
|
|
292761
293145
|
const result = resultSchema.parse(response.result);
|
|
292762
293146
|
resolve5(result);
|
|
292763
293147
|
} catch (error) {
|
|
292764
|
-
|
|
293148
|
+
reject2(error);
|
|
292765
293149
|
}
|
|
292766
293150
|
});
|
|
292767
293151
|
(_d = options === null || options === undefined ? undefined : options.signal) === null || _d === undefined || _d.addEventListener("abort", () => {
|
|
@@ -292773,7 +293157,7 @@ class Protocol {
|
|
|
292773
293157
|
this._setupTimeout(messageId, timeout, options === null || options === undefined ? undefined : options.maxTotalTimeout, timeoutHandler, (_f = options === null || options === undefined ? undefined : options.resetTimeoutOnProgress) !== null && _f !== undefined ? _f : false);
|
|
292774
293158
|
this._transport.send(jsonrpcRequest, { relatedRequestId, resumptionToken, onresumptiontoken }).catch((error) => {
|
|
292775
293159
|
this._cleanupTimeout(messageId);
|
|
292776
|
-
|
|
293160
|
+
reject2(error);
|
|
292777
293161
|
});
|
|
292778
293162
|
});
|
|
292779
293163
|
}
|
|
@@ -306222,10 +306606,10 @@ var promisifyStore = (passedStore) => {
|
|
|
306222
306606
|
|
|
306223
306607
|
class PromisifiedStore {
|
|
306224
306608
|
async increment(key) {
|
|
306225
|
-
return new Promise((resolve6,
|
|
306609
|
+
return new Promise((resolve6, reject2) => {
|
|
306226
306610
|
legacyStore.incr(key, (error, totalHits, resetTime) => {
|
|
306227
306611
|
if (error)
|
|
306228
|
-
|
|
306612
|
+
reject2(error);
|
|
306229
306613
|
resolve6({ totalHits, resetTime });
|
|
306230
306614
|
});
|
|
306231
306615
|
});
|