@malloy-publisher/server 0.0.241 → 0.0.243
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 +13 -7
- package/dist/server.mjs +123 -44
- package/package.json +1 -1
package/dist/app/api-doc.yaml
CHANGED
|
@@ -4141,25 +4141,31 @@ components:
|
|
|
4141
4141
|
type: string
|
|
4142
4142
|
description: Snowflake username for authentication
|
|
4143
4143
|
password:
|
|
4144
|
-
type: string
|
|
4144
|
+
type: ["string", "null"]
|
|
4145
4145
|
description: Snowflake password for authentication
|
|
4146
4146
|
privateKey:
|
|
4147
4147
|
type: string
|
|
4148
4148
|
description: Snowflake private key for authentication
|
|
4149
4149
|
privateKeyPass:
|
|
4150
|
-
type: string
|
|
4150
|
+
type: ["string", "null"]
|
|
4151
4151
|
description: Passphrase for the Snowflake private key
|
|
4152
4152
|
warehouse:
|
|
4153
4153
|
type: string
|
|
4154
4154
|
description: Snowflake warehouse name
|
|
4155
4155
|
database:
|
|
4156
|
-
type: string
|
|
4157
|
-
description:
|
|
4156
|
+
type: ["string", "null"]
|
|
4157
|
+
description:
|
|
4158
|
+
Snowflake database name. Omitted or null connects with no current
|
|
4159
|
+
database, so names must be fully qualified as
|
|
4160
|
+
DATABASE.SCHEMA.TABLE and schema discovery spans the account.
|
|
4158
4161
|
schema:
|
|
4159
|
-
type: string
|
|
4160
|
-
description:
|
|
4162
|
+
type: ["string", "null"]
|
|
4163
|
+
description:
|
|
4164
|
+
Snowflake schema name. Sets the session default schema and forms part
|
|
4165
|
+
of the connection's identity, so it determines what a materialization
|
|
4166
|
+
build runs as. It does not restrict which schemas are discoverable.
|
|
4161
4167
|
role:
|
|
4162
|
-
type: string
|
|
4168
|
+
type: ["string", "null"]
|
|
4163
4169
|
description: Snowflake role name
|
|
4164
4170
|
responseTimeoutMilliseconds:
|
|
4165
4171
|
type: integer
|
package/dist/server.mjs
CHANGED
|
@@ -265609,6 +265609,9 @@ var PROXIED_SSLMODES = [
|
|
|
265609
265609
|
"verify-full"
|
|
265610
265610
|
];
|
|
265611
265611
|
var PUBLISHER_DUCKDB_API_FIELDS = new Set(["attachedDatabases"]);
|
|
265612
|
+
function nullToUndefined(value) {
|
|
265613
|
+
return value ?? undefined;
|
|
265614
|
+
}
|
|
265612
265615
|
function normalizeSnowflakePrivateKey(privateKey) {
|
|
265613
265616
|
let privateKeyContent = privateKey.trim();
|
|
265614
265617
|
if (!privateKeyContent.includes(`
|
|
@@ -266129,13 +266132,13 @@ function assembleEnvironmentConnections(connections = [], environmentPath = "")
|
|
|
266129
266132
|
is: "snowflake",
|
|
266130
266133
|
account: connection.snowflakeConnection?.account,
|
|
266131
266134
|
username: connection.snowflakeConnection?.username,
|
|
266132
|
-
password: connection.snowflakeConnection?.password,
|
|
266135
|
+
password: nullToUndefined(connection.snowflakeConnection?.password),
|
|
266133
266136
|
privateKey: connection.snowflakeConnection?.privateKey ? normalizeSnowflakePrivateKey(connection.snowflakeConnection.privateKey) : undefined,
|
|
266134
|
-
privateKeyPass: connection.snowflakeConnection?.privateKeyPass,
|
|
266137
|
+
privateKeyPass: nullToUndefined(connection.snowflakeConnection?.privateKeyPass),
|
|
266135
266138
|
warehouse: connection.snowflakeConnection?.warehouse,
|
|
266136
|
-
database: connection.snowflakeConnection?.database,
|
|
266137
|
-
schema: connection.snowflakeConnection?.schema,
|
|
266138
|
-
role: connection.snowflakeConnection?.role,
|
|
266139
|
+
database: nullToUndefined(connection.snowflakeConnection?.database),
|
|
266140
|
+
schema: nullToUndefined(connection.snowflakeConnection?.schema),
|
|
266141
|
+
role: nullToUndefined(connection.snowflakeConnection?.role),
|
|
266139
266142
|
timeoutMs: connection.snowflakeConnection?.responseTimeoutMilliseconds,
|
|
266140
266143
|
poolMin: 1,
|
|
266141
266144
|
poolMax: 20
|
|
@@ -266657,32 +266660,44 @@ async function federateSnowflake(connection, config) {
|
|
|
266657
266660
|
if (!sf) {
|
|
266658
266661
|
throw new Error(`Snowflake connection configuration missing for: ${config.name}`);
|
|
266659
266662
|
}
|
|
266660
|
-
const
|
|
266663
|
+
for (const [field, value] of Object.entries({
|
|
266661
266664
|
account: sf.account,
|
|
266662
|
-
username: sf.username
|
|
266663
|
-
|
|
266664
|
-
};
|
|
266665
|
-
for (const [field, value] of Object.entries(required)) {
|
|
266665
|
+
username: sf.username
|
|
266666
|
+
})) {
|
|
266666
266667
|
if (!value) {
|
|
266667
266668
|
throw new Error(`Snowflake ${field} is required for: ${config.name}`);
|
|
266668
266669
|
}
|
|
266669
266670
|
}
|
|
266671
|
+
const usesKeyPair = !!sf.privateKey;
|
|
266672
|
+
if (!usesKeyPair && !sf.password) {
|
|
266673
|
+
throw new Error(`Snowflake privateKey or password is required for: ${config.name}`);
|
|
266674
|
+
}
|
|
266670
266675
|
await installAndLoadExtension(connection, "snowflake", true);
|
|
266671
266676
|
const params = {
|
|
266672
266677
|
account: escapeSQL(sf.account || ""),
|
|
266673
266678
|
user: escapeSQL(sf.username || ""),
|
|
266674
|
-
password: escapeSQL(sf.password
|
|
266679
|
+
password: sf.password ? escapeSQL(sf.password) : undefined,
|
|
266680
|
+
privateKey: sf.privateKey ? escapeSQL(normalizeSnowflakePrivateKey(sf.privateKey)) : undefined,
|
|
266681
|
+
privateKeyPass: sf.privateKeyPass ? escapeSQL(sf.privateKeyPass) : undefined,
|
|
266675
266682
|
database: sf.database ? escapeSQL(sf.database) : undefined,
|
|
266676
|
-
warehouse: sf.warehouse ? escapeSQL(sf.warehouse) : undefined
|
|
266683
|
+
warehouse: sf.warehouse ? escapeSQL(sf.warehouse) : undefined,
|
|
266684
|
+
schema: sf.schema ? escapeSQL(sf.schema) : undefined,
|
|
266685
|
+
role: sf.role ? escapeSQL(sf.role) : undefined
|
|
266677
266686
|
};
|
|
266678
266687
|
const secretName = sanitizeSecretName(`snowflake_${config.name}`);
|
|
266679
266688
|
const secretLines = [
|
|
266680
266689
|
` TYPE snowflake`,
|
|
266681
266690
|
` ACCOUNT '${params.account}'`,
|
|
266682
266691
|
` USER '${params.user}'`,
|
|
266683
|
-
|
|
266692
|
+
...usesKeyPair ? [
|
|
266693
|
+
` AUTH_TYPE 'key_pair'`,
|
|
266694
|
+
` PRIVATE_KEY '${params.privateKey}'`,
|
|
266695
|
+
...params.privateKeyPass ? [` PRIVATE_KEY_PASSWORD '${params.privateKeyPass}'`] : []
|
|
266696
|
+
] : [` PASSWORD '${params.password}'`],
|
|
266684
266697
|
...params.database ? [` DATABASE '${params.database}'`] : [],
|
|
266685
|
-
...params.warehouse ? [` WAREHOUSE '${params.warehouse}'`] : []
|
|
266698
|
+
...params.warehouse ? [` WAREHOUSE '${params.warehouse}'`] : [],
|
|
266699
|
+
...params.schema ? [` SCHEMA '${params.schema}'`] : [],
|
|
266700
|
+
...params.role ? [` ROLE '${params.role}'`] : []
|
|
266686
266701
|
];
|
|
266687
266702
|
await connection.runSQL(`CREATE OR REPLACE SECRET ${secretName} (
|
|
266688
266703
|
${secretLines.join(`,
|
|
@@ -267004,7 +267019,7 @@ function entryToDuckDBOptions(name, entry, workingDirectory) {
|
|
|
267004
267019
|
return { ...removeUndefined(rest), name };
|
|
267005
267020
|
}
|
|
267006
267021
|
function removeUndefined(value) {
|
|
267007
|
-
return Object.fromEntries(Object.entries(value).filter(([, fieldValue]) => fieldValue !== undefined));
|
|
267022
|
+
return Object.fromEntries(Object.entries(value).filter(([, fieldValue]) => fieldValue !== undefined && fieldValue !== null));
|
|
267008
267023
|
}
|
|
267009
267024
|
function buildSnowflakePrivateKeyConnection(metadata) {
|
|
267010
267025
|
const name = metadata.apiConnection.name;
|
|
@@ -267905,6 +267920,52 @@ async function getSchemasForMySQL(connection) {
|
|
|
267905
267920
|
}
|
|
267906
267921
|
];
|
|
267907
267922
|
}
|
|
267923
|
+
var SNOWFLAKE_SYSTEM_DATABASES = new Set([
|
|
267924
|
+
"SNOWFLAKE",
|
|
267925
|
+
"SNOWFLAKE_SAMPLE_DATA"
|
|
267926
|
+
]);
|
|
267927
|
+
async function listSnowflakeSchemasInDatabase(connection, malloyConnection, database, schema) {
|
|
267928
|
+
const filters = [
|
|
267929
|
+
`CATALOG_NAME = '${sqlLiteral(database, connection.type)}'`
|
|
267930
|
+
];
|
|
267931
|
+
if (schema) {
|
|
267932
|
+
filters.push(`SCHEMA_NAME = '${sqlLiteral(schema, connection.type)}'`);
|
|
267933
|
+
}
|
|
267934
|
+
assertSafeSqlIdentifier(database, "database name");
|
|
267935
|
+
const result = await runIntrospectionSQL(malloyConnection, `SELECT CATALOG_NAME, SCHEMA_NAME, SCHEMA_OWNER FROM ${database}.INFORMATION_SCHEMA.SCHEMATA WHERE ${filters.join(" AND ")} ORDER BY SCHEMA_NAME`);
|
|
267936
|
+
return standardizeRunSQLResult2(result).map((row) => {
|
|
267937
|
+
const r = row;
|
|
267938
|
+
return {
|
|
267939
|
+
catalogName: String(r.CATALOG_NAME ?? r.catalog_name ?? ""),
|
|
267940
|
+
schemaName: String(r.SCHEMA_NAME ?? r.schema_name ?? ""),
|
|
267941
|
+
owner: String(r.SCHEMA_OWNER ?? r.schema_owner ?? "")
|
|
267942
|
+
};
|
|
267943
|
+
});
|
|
267944
|
+
}
|
|
267945
|
+
var SNOWFLAKE_SHOW_ROW_LIMIT = 1e4;
|
|
267946
|
+
async function listSnowflakeSchemasInAccount(malloyConnection) {
|
|
267947
|
+
const result = await runIntrospectionSQL(malloyConnection, `SHOW SCHEMAS IN ACCOUNT LIMIT ${SNOWFLAKE_SHOW_ROW_LIMIT}`);
|
|
267948
|
+
const returnedRows = standardizeRunSQLResult2(result);
|
|
267949
|
+
if (returnedRows.length >= SNOWFLAKE_SHOW_ROW_LIMIT) {
|
|
267950
|
+
logger.warn("Snowflake account-wide schema listing hit the SHOW row limit; the schema list is incomplete and some tables will not be discoverable", {
|
|
267951
|
+
rowLimit: SNOWFLAKE_SHOW_ROW_LIMIT,
|
|
267952
|
+
returnedRows: returnedRows.length
|
|
267953
|
+
});
|
|
267954
|
+
}
|
|
267955
|
+
const parsed = returnedRows.map((row) => {
|
|
267956
|
+
const r = row;
|
|
267957
|
+
return {
|
|
267958
|
+
catalogName: String(r.database_name ?? r.DATABASE_NAME ?? ""),
|
|
267959
|
+
schemaName: String(r.name ?? r.NAME ?? ""),
|
|
267960
|
+
owner: String(r.owner ?? r.OWNER ?? "")
|
|
267961
|
+
};
|
|
267962
|
+
});
|
|
267963
|
+
const usable = parsed.filter((r) => r.catalogName && r.schemaName);
|
|
267964
|
+
if (usable.length < parsed.length) {
|
|
267965
|
+
logger.warn("Dropped Snowflake schema rows missing a database or schema name; the schema list is incomplete", { dropped: parsed.length - usable.length, returned: parsed.length });
|
|
267966
|
+
}
|
|
267967
|
+
return usable.sort((a, b) => a.catalogName.localeCompare(b.catalogName) || a.schemaName.localeCompare(b.schemaName));
|
|
267968
|
+
}
|
|
267908
267969
|
async function getSchemasForSnowflake(connection, malloyConnection) {
|
|
267909
267970
|
if (!connection.snowflakeConnection) {
|
|
267910
267971
|
throw new Error("Snowflake connection is required");
|
|
@@ -267912,28 +267973,15 @@ async function getSchemasForSnowflake(connection, malloyConnection) {
|
|
|
267912
267973
|
try {
|
|
267913
267974
|
const database = connection.snowflakeConnection.database;
|
|
267914
267975
|
const schema = connection.snowflakeConnection.schema;
|
|
267915
|
-
const
|
|
267916
|
-
|
|
267917
|
-
|
|
267918
|
-
|
|
267919
|
-
|
|
267920
|
-
|
|
267921
|
-
}
|
|
267922
|
-
const whereClause = filters.length > 0 ? `WHERE ${filters.join(" AND ")}` : "";
|
|
267923
|
-
const result = await runIntrospectionSQL(malloyConnection, `SELECT CATALOG_NAME, SCHEMA_NAME, SCHEMA_OWNER FROM ${database ? `${database}.` : ""}INFORMATION_SCHEMA.SCHEMATA ${whereClause} ORDER BY SCHEMA_NAME`);
|
|
267924
|
-
const rows = standardizeRunSQLResult2(result);
|
|
267925
|
-
return rows.map((row) => {
|
|
267926
|
-
const typedRow = row;
|
|
267927
|
-
const catalogName = String(typedRow.CATALOG_NAME ?? typedRow.catalog_name ?? "");
|
|
267928
|
-
const schemaName = String(typedRow.SCHEMA_NAME ?? typedRow.schema_name ?? "");
|
|
267929
|
-
const owner = String(typedRow.SCHEMA_OWNER ?? typedRow.schema_owner ?? "");
|
|
267930
|
-
return {
|
|
267931
|
-
name: `${catalogName}.${schemaName}`,
|
|
267932
|
-
isHidden: ["SNOWFLAKE", ""].includes(owner) || schemaName === "INFORMATION_SCHEMA",
|
|
267933
|
-
isDefault: schema ? schemaName === schema : false
|
|
267934
|
-
};
|
|
267935
|
-
});
|
|
267976
|
+
const rows = database ? await listSnowflakeSchemasInDatabase(connection, malloyConnection, database, schema) : await listSnowflakeSchemasInAccount(malloyConnection);
|
|
267977
|
+
return rows.map(({ catalogName, schemaName, owner }) => ({
|
|
267978
|
+
name: `${catalogName}.${schemaName}`,
|
|
267979
|
+
isHidden: owner === "SNOWFLAKE" || Boolean(database) && owner === "" || schemaName === "INFORMATION_SCHEMA" || !database && SNOWFLAKE_SYSTEM_DATABASES.has(catalogName),
|
|
267980
|
+
isDefault: Boolean(database) && Boolean(schema) && schemaName === schema
|
|
267981
|
+
}));
|
|
267936
267982
|
} catch (error) {
|
|
267983
|
+
if (error instanceof BadRequestError)
|
|
267984
|
+
throw error;
|
|
267937
267985
|
logger.error(`Error getting schemas for Snowflake connection ${connection.name}`, { error });
|
|
267938
267986
|
throw new Error(`Failed to get schemas for Snowflake connection ${connection.name}: ${error.message}`);
|
|
267939
267987
|
}
|
|
@@ -269317,7 +269365,7 @@ class QueryController {
|
|
|
269317
269365
|
constructor(environmentStore) {
|
|
269318
269366
|
this.environmentStore = environmentStore;
|
|
269319
269367
|
}
|
|
269320
|
-
async getQuery(environmentName, packageName, modelPath, sourceName, queryName, query, compactJson = false, filterParams, bypassFilters, givens, metadata) {
|
|
269368
|
+
async getQuery(environmentName, packageName, modelPath, sourceName, queryName, query, compactJson = false, filterParams, bypassFilters, givens, metadata, bypassAuthorize) {
|
|
269321
269369
|
let requestMetadata;
|
|
269322
269370
|
let queryClass;
|
|
269323
269371
|
try {
|
|
@@ -269357,7 +269405,7 @@ class QueryController {
|
|
|
269357
269405
|
return null;
|
|
269358
269406
|
}
|
|
269359
269407
|
}
|
|
269360
|
-
}, compactJson ? "compact" : "full"), getQueryTimeoutMs());
|
|
269408
|
+
}, compactJson ? "compact" : "full", bypassAuthorize), getQueryTimeoutMs());
|
|
269361
269409
|
const renderLogs = import_render_validator.validateRenderTags(result);
|
|
269362
269410
|
return {
|
|
269363
269411
|
result: serializedResult,
|
|
@@ -277169,12 +277217,19 @@ function unwrapQuotedExpression(body) {
|
|
|
277169
277217
|
|
|
277170
277218
|
// src/authorize_metrics.ts
|
|
277171
277219
|
var guardRejectionCounter = null;
|
|
277220
|
+
var bypassCounter = null;
|
|
277172
277221
|
function recordAuthorizeGuardRejection(field) {
|
|
277173
277222
|
guardRejectionCounter ??= publisherMeter().createCounter("publisher_authorize_guard_rejected_total", {
|
|
277174
277223
|
description: "Requests rejected with 400 for declaring an `#(authorize)` annotation in caller-submitted Malloy text. Label: field ('query'|'source_name'|'query_name'|'compile_source')."
|
|
277175
277224
|
});
|
|
277176
277225
|
guardRejectionCounter.add(1, { field });
|
|
277177
277226
|
}
|
|
277227
|
+
function recordAuthorizeBypass(entryPoint) {
|
|
277228
|
+
bypassCounter ??= publisherMeter().createCounter("publisher_authorize_bypass_total", {
|
|
277229
|
+
description: "Gate evaluations skipped because the request carried an authorize bypass (private data-management path). Label: entry_point ('source'|'runnable'). Any nonzero value on a path that should not use the bypass is a finding — see the paired `authorize bypass` audit log line for org/package/model/source."
|
|
277230
|
+
});
|
|
277231
|
+
bypassCounter.add(1, { entry_point: entryPoint });
|
|
277232
|
+
}
|
|
277178
277233
|
|
|
277179
277234
|
// src/service/environment.ts
|
|
277180
277235
|
init_logger();
|
|
@@ -278733,7 +278788,11 @@ class Model {
|
|
|
278733
278788
|
}
|
|
278734
278789
|
return this.fileLevelAuthorize;
|
|
278735
278790
|
}
|
|
278736
|
-
async assertAuthorized(sourceName, givens) {
|
|
278791
|
+
async assertAuthorized(sourceName, givens, bypassAuthorize = false) {
|
|
278792
|
+
if (bypassAuthorize) {
|
|
278793
|
+
this.noteAuthorizeBypass("source", sourceName);
|
|
278794
|
+
return;
|
|
278795
|
+
}
|
|
278737
278796
|
const gates = sourceName ? this.entryPointGatesBySource.get(sourceName) : undefined;
|
|
278738
278797
|
if (gates) {
|
|
278739
278798
|
for (const { label, exprs, selfContained, ambientPrefix } of gates) {
|
|
@@ -278743,6 +278802,15 @@ class Model {
|
|
|
278743
278802
|
}
|
|
278744
278803
|
await this.assertAuthorizedExprs(sourceName ?? "(query)", this.effectiveAuthorizeFor(sourceName), givens);
|
|
278745
278804
|
}
|
|
278805
|
+
noteAuthorizeBypass(entryPoint, sourceName) {
|
|
278806
|
+
recordAuthorizeBypass(entryPoint);
|
|
278807
|
+
logger.info("authorize bypass", {
|
|
278808
|
+
entryPoint,
|
|
278809
|
+
sourceName: sourceName ?? "(query)",
|
|
278810
|
+
modelPath: this.modelPath,
|
|
278811
|
+
packageName: this.packageName
|
|
278812
|
+
});
|
|
278813
|
+
}
|
|
278746
278814
|
async assertAuthorizedExprs(label, exprs, givens, selfContainedFirst = false, ambientPrefix = 0) {
|
|
278747
278815
|
if (exprs.length === 0)
|
|
278748
278816
|
return;
|
|
@@ -278765,7 +278833,11 @@ class Model {
|
|
|
278765
278833
|
if (!passed)
|
|
278766
278834
|
deny();
|
|
278767
278835
|
}
|
|
278768
|
-
async assertAuthorizedForAllSources(runnable, givens) {
|
|
278836
|
+
async assertAuthorizedForAllSources(runnable, givens, bypassAuthorize = false) {
|
|
278837
|
+
if (bypassAuthorize) {
|
|
278838
|
+
this.noteAuthorizeBypass("runnable", await this.resolveAuthorizeSourceFromRunnable(runnable));
|
|
278839
|
+
return;
|
|
278840
|
+
}
|
|
278769
278841
|
const ownSourceName = await this.resolveAuthorizeSourceFromRunnable(runnable);
|
|
278770
278842
|
await this.assertAuthorized(ownSourceName, givens);
|
|
278771
278843
|
const { struct, modelDef, compositeResolvedSourceDef } = await this.resolveRunTargetStruct(runnable);
|
|
@@ -279342,7 +279414,7 @@ class Model {
|
|
|
279342
279414
|
return { ...b, schema, refinements };
|
|
279343
279415
|
}).filter((b) => b.schema.length > 0);
|
|
279344
279416
|
}
|
|
279345
|
-
async getQueryResults(sourceName, queryName, query, filterParams, bypassFilters, givens, abortSignal, queryMetadataInput, responseShape = "full") {
|
|
279417
|
+
async getQueryResults(sourceName, queryName, query, filterParams, bypassFilters, givens, abortSignal, queryMetadataInput, responseShape = "full", bypassAuthorize = false) {
|
|
279346
279418
|
const startTime = performance.now();
|
|
279347
279419
|
if (this.compilationError) {
|
|
279348
279420
|
if (this.compilationError instanceof MalloyError2 || this.compilationError instanceof ModelCompilationError) {
|
|
@@ -279361,7 +279433,7 @@ class Model {
|
|
|
279361
279433
|
const surfaceName = extractRunTargetSourceName(query);
|
|
279362
279434
|
const earlySource = sourceName || (queryName ? this.queries?.find((q) => q.name === queryName)?.sourceName : undefined) || (surfaceName && !this.sources?.some((s) => s.name === surfaceName) ? this.queries?.find((q) => q.name === surfaceName)?.sourceName : undefined) || surfaceName;
|
|
279363
279435
|
if (earlySource) {
|
|
279364
|
-
await this.assertAuthorized(earlySource, givens ?? {});
|
|
279436
|
+
await this.assertAuthorized(earlySource, givens ?? {}, bypassAuthorize);
|
|
279365
279437
|
}
|
|
279366
279438
|
try {
|
|
279367
279439
|
for (const [field, callerText] of [
|
|
@@ -279456,7 +279528,7 @@ run: ${sourceName ? `${quoteMalloyIdentifier(sourceName)} -> ` : ""}${quoteMallo
|
|
|
279456
279528
|
if (boundary === "deferred") {
|
|
279457
279529
|
this.assertQueryBoundaryCompiled(compiledSource, query);
|
|
279458
279530
|
}
|
|
279459
|
-
await this.assertAuthorizedForAllSources(runnable, givens ?? {});
|
|
279531
|
+
await this.assertAuthorizedForAllSources(runnable, givens ?? {}, bypassAuthorize);
|
|
279460
279532
|
const maxRows = getMaxQueryRows();
|
|
279461
279533
|
const maxBytes = getMaxResponseBytes();
|
|
279462
279534
|
const buildManifest = this.resolveFreshBuildManifest();
|
|
@@ -284408,6 +284480,13 @@ class WatchModeController {
|
|
|
284408
284480
|
init_errors();
|
|
284409
284481
|
init_logger();
|
|
284410
284482
|
|
|
284483
|
+
// src/authorize_bypass_header.ts
|
|
284484
|
+
var BYPASS_AUTHORIZE_HEADER = "x-publisher-bypass-authorize";
|
|
284485
|
+
var readBypassAuthorize = (req) => {
|
|
284486
|
+
const raw = req.headers[BYPASS_AUTHORIZE_HEADER];
|
|
284487
|
+
return typeof raw === "string" && raw.trim().toLowerCase() === "true" ? true : undefined;
|
|
284488
|
+
};
|
|
284489
|
+
|
|
284411
284490
|
// src/filter_deprecation.ts
|
|
284412
284491
|
var setFilterDeprecationHeaders = (res, options) => {
|
|
284413
284492
|
const hasFilterParams = options.filterParams !== undefined && options.filterParams !== null && !(typeof options.filterParams === "object" && !Array.isArray(options.filterParams) && Object.keys(options.filterParams).length === 0);
|
|
@@ -295580,7 +295659,7 @@ app.post(`${API_PREFIX2}/environments/:environmentName/packages/:packageName/mod
|
|
|
295580
295659
|
queryMetadata: req.body?.queryMetadata,
|
|
295581
295660
|
queryClass: req.body?.queryClass,
|
|
295582
295661
|
versionId: req.body?.versionId
|
|
295583
|
-
});
|
|
295662
|
+
}, readBypassAuthorize(req));
|
|
295584
295663
|
setFilterDeprecationHeaders(res, {
|
|
295585
295664
|
filterParams: req.body.filterParams ?? req.body.sourceFilters,
|
|
295586
295665
|
bypassFilters: req.body.bypassFilters === true ? true : undefined
|