@malloy-publisher/server 0.0.246 → 0.0.247
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 +189 -35
- package/dist/app/assets/{EnvironmentPage-EjXlK1AR.js → EnvironmentPage-DrTRtRHz.js} +1 -1
- package/dist/app/assets/{HomePage-BDg82oe3.js → HomePage-X_Wozguy.js} +1 -1
- package/dist/app/assets/{LightMode-CM8J0nPB.js → LightMode-4Y7DEWAD.js} +1 -1
- package/dist/app/assets/{MainPage-CkkdimtC.js → MainPage-DKNR-8Vr.js} +1 -1
- package/dist/app/assets/{MaterializationsPage-DvVS2HMi.js → MaterializationsPage-h3ONDcgJ.js} +1 -1
- package/dist/app/assets/{ModelPage-Bz2je31A.js → ModelPage-B8Qsrbxn.js} +1 -1
- package/dist/app/assets/{PackagePage-BUJU3qB3.js → PackagePage-D8mM4T37.js} +1 -1
- package/dist/app/assets/{RouteError-oqZTfMol.js → RouteError-DzJ0TPOj.js} +1 -1
- package/dist/app/assets/{ThemeEditorPage-W-V8hngE.js → ThemeEditorPage-BYvxc5op.js} +1 -1
- package/dist/app/assets/{WorkbookPage-IQFxsQGR.js → WorkbookPage-CYOpAw7I.js} +1 -1
- package/dist/app/assets/{core-BCwj9ZvB.es-C610H3gu.js → core-BuvlzSIX.es-cZHBIpH6.js} +1 -1
- package/dist/app/assets/{index-Dxotbpnc.js → index-BgAa2J25.js} +1 -1
- package/dist/app/assets/{index-BUhTsFh9.js → index-BgMR5Uuv.js} +1 -1
- package/dist/app/assets/{index-DJ-3RN5W.js → index-BwoU1Ko8.js} +4 -4
- package/dist/app/assets/{index-1xafiaYB.js → index-CuaX7xuf.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/package_load_worker.mjs +90 -20
- package/dist/server.mjs +4975 -4585
- package/package.json +1 -1
- package/dist/sshcrypto-vd2k5hq9.node +0 -0
|
@@ -11887,11 +11887,19 @@ import { Annotations } from "@malloydata/malloy";
|
|
|
11887
11887
|
function isReservedRoute(route) {
|
|
11888
11888
|
return route === "" || !/[\p{L}\p{N}]/u.test(route);
|
|
11889
11889
|
}
|
|
11890
|
+
function ownModelAnnotations(modelDef) {
|
|
11891
|
+
return foldModelAnnotations(modelDef, (id) => id === modelDef.modelID || id.startsWith("internal://"));
|
|
11892
|
+
}
|
|
11890
11893
|
function modelAnnotations(modelDef) {
|
|
11894
|
+
return foldModelAnnotations(modelDef, () => true);
|
|
11895
|
+
}
|
|
11896
|
+
function foldModelAnnotations(modelDef, admits) {
|
|
11891
11897
|
const registry = modelDef.modelAnnotations ?? {};
|
|
11892
11898
|
const visited = new Set;
|
|
11893
11899
|
const order = [];
|
|
11894
11900
|
const visit = (id) => {
|
|
11901
|
+
if (!admits(id))
|
|
11902
|
+
return;
|
|
11895
11903
|
if (visited.has(id))
|
|
11896
11904
|
return;
|
|
11897
11905
|
visited.add(id);
|
|
@@ -12328,6 +12336,48 @@ function resolvePackageScope(rootRaw, materializationRaw) {
|
|
|
12328
12336
|
return { scope: envelopeScope, warnings: [] };
|
|
12329
12337
|
}
|
|
12330
12338
|
var SCOPE_ROOT_DEPRECATION = `"scope" at the manifest root is deprecated: declare it as ` + `"materialization": { "scope": ... } alongside the other build knobs. The ` + `root form still works and will be removed in a future release; until then ` + `the server keeps both homes in sync when it writes the manifest, so an ` + `older publisher still reads the right value.`;
|
|
12339
|
+
function resolvePackageQueryMetadata(rootRaw, materializationRaw) {
|
|
12340
|
+
const envelopeRaw = materializationRaw && typeof materializationRaw === "object" ? materializationRaw.queryMetadata : undefined;
|
|
12341
|
+
const rootDeclared = rootRaw !== undefined && rootRaw !== null;
|
|
12342
|
+
const envelopeDeclared = envelopeRaw !== undefined && envelopeRaw !== null;
|
|
12343
|
+
if (rootDeclared && envelopeDeclared) {
|
|
12344
|
+
if (sameQueryMetadataBag(rootRaw, envelopeRaw)) {
|
|
12345
|
+
return { queryMetadata: rootRaw, home: "root", warnings: [] };
|
|
12346
|
+
}
|
|
12347
|
+
return {
|
|
12348
|
+
queryMetadata: rootRaw,
|
|
12349
|
+
home: "root",
|
|
12350
|
+
warnings: [QUERY_METADATA_CONFLICT]
|
|
12351
|
+
};
|
|
12352
|
+
}
|
|
12353
|
+
if (envelopeDeclared) {
|
|
12354
|
+
return {
|
|
12355
|
+
queryMetadata: envelopeRaw,
|
|
12356
|
+
home: "envelope",
|
|
12357
|
+
warnings: [QUERY_METADATA_ENVELOPE_DEPRECATION]
|
|
12358
|
+
};
|
|
12359
|
+
}
|
|
12360
|
+
return { queryMetadata: rootRaw, home: "root", warnings: [] };
|
|
12361
|
+
}
|
|
12362
|
+
function sameQueryMetadataBag(a, b) {
|
|
12363
|
+
return keySortedJson(a) === keySortedJson(b);
|
|
12364
|
+
}
|
|
12365
|
+
function keySortedJson(value) {
|
|
12366
|
+
if (value === null || typeof value !== "object") {
|
|
12367
|
+
return JSON.stringify(value) ?? "undefined";
|
|
12368
|
+
}
|
|
12369
|
+
if (Array.isArray(value)) {
|
|
12370
|
+
return `[${value.map(keySortedJson).join(",")}]`;
|
|
12371
|
+
}
|
|
12372
|
+
const entries = Object.entries(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
|
|
12373
|
+
return `{${entries.map(([name, nested]) => `${JSON.stringify(name)}:${keySortedJson(nested)}`).join(",")}}`;
|
|
12374
|
+
}
|
|
12375
|
+
var QUERY_METADATA_HOME_LABELS = {
|
|
12376
|
+
root: "queryMetadata",
|
|
12377
|
+
envelope: "materialization.queryMetadata"
|
|
12378
|
+
};
|
|
12379
|
+
var QUERY_METADATA_ENVELOPE_DEPRECATION = `"queryMetadata" inside "materialization" is deprecated: declare it at the ` + `manifest root instead. It is not a build setting — the properties ride ` + `every statement the package's sources issue, including served queries. The ` + `enveloped form still works and will be removed in a future release; until ` + `then the server keeps both homes in sync when it writes the manifest, so an ` + `older publisher still reads the right value.`;
|
|
12380
|
+
var QUERY_METADATA_CONFLICT = `Conflicting "queryMetadata" in publisher.json: the manifest root and ` + `"materialization.queryMetadata" declare different bags, and the root wins. ` + `Delete "materialization": { "queryMetadata": ... } — the server rewrites ` + `both homes on its next manifest write, so an older publisher still reads ` + `the right value.`;
|
|
12331
12381
|
function parseFreshness(raw) {
|
|
12332
12382
|
if (!raw || typeof raw !== "object") {
|
|
12333
12383
|
return null;
|
|
@@ -12342,7 +12392,7 @@ function parseFreshness(raw) {
|
|
|
12342
12392
|
}
|
|
12343
12393
|
return freshness;
|
|
12344
12394
|
}
|
|
12345
|
-
function parseQueryMetadata(raw) {
|
|
12395
|
+
function parseQueryMetadata(raw, label = QUERY_METADATA_HOME_LABELS.envelope) {
|
|
12346
12396
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
12347
12397
|
return { metadata: null, warnings: [] };
|
|
12348
12398
|
}
|
|
@@ -12352,7 +12402,7 @@ function parseQueryMetadata(raw) {
|
|
|
12352
12402
|
if (typeof value === "string") {
|
|
12353
12403
|
out[name] = value;
|
|
12354
12404
|
} else {
|
|
12355
|
-
warnings.push(
|
|
12405
|
+
warnings.push(`${label}: property '${name}' must be a ` + `string (got ${value === null ? "null" : typeof value}); it is ` + `not attached to any statement`);
|
|
12356
12406
|
}
|
|
12357
12407
|
}
|
|
12358
12408
|
return {
|
|
@@ -12371,12 +12421,18 @@ function parsePackageMaterialization(raw) {
|
|
|
12371
12421
|
queryMetadata: parseQueryMetadata(queryMetadata).metadata
|
|
12372
12422
|
};
|
|
12373
12423
|
}
|
|
12374
|
-
function
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12424
|
+
function materializationWithQueryMetadata(parsed, queryMetadataRaw) {
|
|
12425
|
+
const queryMetadata = parseQueryMetadata(queryMetadataRaw).metadata;
|
|
12426
|
+
if (!parsed && !queryMetadata)
|
|
12427
|
+
return null;
|
|
12428
|
+
return {
|
|
12429
|
+
schedule: parsed?.schedule ?? null,
|
|
12430
|
+
freshness: parsed?.freshness ?? null,
|
|
12431
|
+
queryMetadata
|
|
12432
|
+
};
|
|
12433
|
+
}
|
|
12434
|
+
function queryMetadataParseWarnings(raw, home = "root") {
|
|
12435
|
+
return parseQueryMetadata(raw, QUERY_METADATA_HOME_LABELS[home]).warnings;
|
|
12380
12436
|
}
|
|
12381
12437
|
|
|
12382
12438
|
// src/package_load/package_load_worker.ts
|
|
@@ -12438,9 +12494,9 @@ function newRpcId() {
|
|
|
12438
12494
|
}
|
|
12439
12495
|
function callMain(send) {
|
|
12440
12496
|
const requestId = newRpcId();
|
|
12441
|
-
return new Promise((
|
|
12497
|
+
return new Promise((resolve2, reject) => {
|
|
12442
12498
|
pendingRpc.set(requestId, {
|
|
12443
|
-
resolve: (value) =>
|
|
12499
|
+
resolve: (value) => resolve2(value),
|
|
12444
12500
|
reject
|
|
12445
12501
|
});
|
|
12446
12502
|
send(requestId);
|
|
@@ -12555,18 +12611,21 @@ function serializeFetchOptions(options) {
|
|
|
12555
12611
|
}
|
|
12556
12612
|
return out;
|
|
12557
12613
|
}
|
|
12558
|
-
function makeWorkerUrlReader(
|
|
12614
|
+
function makeWorkerUrlReader(job) {
|
|
12559
12615
|
return {
|
|
12560
12616
|
readURL: async (url) => {
|
|
12561
12617
|
if (url.protocol === "file:") {
|
|
12562
12618
|
const filePath = fileURLToPath2(url);
|
|
12619
|
+
if (job.replacement && path2.resolve(filePath) === path2.resolve(job.packagePath, job.replacement.modelPath)) {
|
|
12620
|
+
return job.replacement.source;
|
|
12621
|
+
}
|
|
12563
12622
|
return fs2.promises.readFile(filePath, "utf8");
|
|
12564
12623
|
}
|
|
12565
12624
|
const response = await callMain((requestId) => {
|
|
12566
12625
|
const req = {
|
|
12567
12626
|
type: "read-url",
|
|
12568
12627
|
requestId,
|
|
12569
|
-
jobId,
|
|
12628
|
+
jobId: job.requestId,
|
|
12570
12629
|
url: url.toString()
|
|
12571
12630
|
};
|
|
12572
12631
|
port.postMessage(req);
|
|
@@ -12614,9 +12673,11 @@ async function readPackageMetadata(packagePath) {
|
|
|
12614
12673
|
const contents = await fs2.promises.readFile(manifestPath, "utf8");
|
|
12615
12674
|
const parsed = JSON.parse(contents);
|
|
12616
12675
|
const scope = resolvePackageScope(parsed.scope, parsed.materialization);
|
|
12676
|
+
const queryMetadata = resolvePackageQueryMetadata(parsed.queryMetadata, parsed.materialization);
|
|
12617
12677
|
const manifestWarnings = [
|
|
12618
12678
|
...scope.warnings,
|
|
12619
|
-
...
|
|
12679
|
+
...queryMetadata.warnings,
|
|
12680
|
+
...queryMetadataParseWarnings(queryMetadata.queryMetadata, queryMetadata.home)
|
|
12620
12681
|
];
|
|
12621
12682
|
return {
|
|
12622
12683
|
name: parsed.name,
|
|
@@ -12624,7 +12685,7 @@ async function readPackageMetadata(packagePath) {
|
|
|
12624
12685
|
explores: Array.isArray(parsed.explores) ? parsed.explores.map(normalizeModelPath) : undefined,
|
|
12625
12686
|
queryableSources: parsed.queryableSources === "all" ? "all" : "declared",
|
|
12626
12687
|
manifestLocation: typeof parsed.manifestLocation === "string" ? parsed.manifestLocation : null,
|
|
12627
|
-
materialization: parsePackageMaterialization(parsed.materialization),
|
|
12688
|
+
materialization: materializationWithQueryMetadata(parsePackageMaterialization(parsed.materialization), queryMetadata.queryMetadata),
|
|
12628
12689
|
scope: scope.scope,
|
|
12629
12690
|
manifestWarnings: manifestWarnings.length > 0 ? manifestWarnings : undefined
|
|
12630
12691
|
};
|
|
@@ -12675,8 +12736,8 @@ function extractSources(modelDef, givens) {
|
|
|
12675
12736
|
function extractQueries(modelDef) {
|
|
12676
12737
|
return extractQueriesFromModelDef(modelDef);
|
|
12677
12738
|
}
|
|
12678
|
-
function buildRuntimeForModel(job, malloyConfig
|
|
12679
|
-
const urlReader = new HackyDataStylesAccumulator(makeWorkerUrlReader(
|
|
12739
|
+
function buildRuntimeForModel(job, malloyConfig) {
|
|
12740
|
+
const urlReader = new HackyDataStylesAccumulator(makeWorkerUrlReader(job));
|
|
12680
12741
|
const runtime = new Runtime({
|
|
12681
12742
|
urlReader,
|
|
12682
12743
|
config: malloyConfig,
|
|
@@ -12692,7 +12753,7 @@ async function compileMalloyModel(job, malloyConfig, modelPath) {
|
|
|
12692
12753
|
const fullPath = path2.join(job.packagePath, modelPath);
|
|
12693
12754
|
const modelURL = pathToFileURL(fullPath);
|
|
12694
12755
|
const importBaseURL = new URL(".", modelURL);
|
|
12695
|
-
const { runtime, urlReader } = buildRuntimeForModel(job, malloyConfig
|
|
12756
|
+
const { runtime, urlReader } = buildRuntimeForModel(job, malloyConfig);
|
|
12696
12757
|
const mm = runtime.loadModel(modelURL, { importBaseURL });
|
|
12697
12758
|
const compiled = await mm.getModel();
|
|
12698
12759
|
const modelDef = compiled._modelDef;
|
|
@@ -12714,7 +12775,8 @@ async function compileMalloyModel(job, malloyConfig, modelPath) {
|
|
|
12714
12775
|
filterMap: Array.from(filterMap.entries()),
|
|
12715
12776
|
givens,
|
|
12716
12777
|
dataStyles: urlReader.getHackyAccumulatedDataStyles(),
|
|
12717
|
-
compileDurationMs: performance.now() - compileStart
|
|
12778
|
+
compileDurationMs: performance.now() - compileStart,
|
|
12779
|
+
problems: job.collectProblems ? compiled.problems : undefined
|
|
12718
12780
|
};
|
|
12719
12781
|
}
|
|
12720
12782
|
async function compileNotebookModel(job, malloyConfig, modelPath) {
|
|
@@ -12722,7 +12784,7 @@ async function compileNotebookModel(job, malloyConfig, modelPath) {
|
|
|
12722
12784
|
const fullPath = path2.join(job.packagePath, modelPath);
|
|
12723
12785
|
const modelURL = pathToFileURL(fullPath);
|
|
12724
12786
|
const importBaseURL = new URL(".", modelURL);
|
|
12725
|
-
const { runtime, urlReader } = buildRuntimeForModel(job, malloyConfig
|
|
12787
|
+
const { runtime, urlReader } = buildRuntimeForModel(job, malloyConfig);
|
|
12726
12788
|
const fileContents = await fs2.promises.readFile(modelURL, "utf8");
|
|
12727
12789
|
const parse = MalloySQLParser.parse(fileContents, modelPath);
|
|
12728
12790
|
let mm;
|
|
@@ -12799,8 +12861,10 @@ async function compileNotebookModel(job, malloyConfig, modelPath) {
|
|
|
12799
12861
|
let finalSourceInfos;
|
|
12800
12862
|
let finalFilterMap;
|
|
12801
12863
|
let finalGivens;
|
|
12864
|
+
let finalProblems;
|
|
12802
12865
|
if (mm) {
|
|
12803
12866
|
const compiled = await mm.getModel();
|
|
12867
|
+
finalProblems = compiled.problems;
|
|
12804
12868
|
finalModelDef = compiled._modelDef;
|
|
12805
12869
|
const malloyGivens = Array.from(compiled.givens.values());
|
|
12806
12870
|
finalGivens = malloyGivens.length > 0 ? malloyGivens.map((g) => malloyGivenToApi(g)) : undefined;
|
|
@@ -12825,7 +12889,8 @@ async function compileNotebookModel(job, malloyConfig, modelPath) {
|
|
|
12825
12889
|
givens: finalGivens,
|
|
12826
12890
|
notebookCells,
|
|
12827
12891
|
dataStyles: urlReader.getHackyAccumulatedDataStyles(),
|
|
12828
|
-
compileDurationMs: performance.now() - compileStart
|
|
12892
|
+
compileDurationMs: performance.now() - compileStart,
|
|
12893
|
+
problems: job.collectProblems ? finalProblems : undefined
|
|
12829
12894
|
};
|
|
12830
12895
|
}
|
|
12831
12896
|
async function compileOneModel(job, malloyConfig, modelPath) {
|
|
@@ -12859,6 +12924,10 @@ async function loadPackage(job) {
|
|
|
12859
12924
|
const malloyConfig = buildWorkerMalloyConfig(job);
|
|
12860
12925
|
const allFiles = await listPackageFiles(job.packagePath);
|
|
12861
12926
|
const modelPaths = filterModelPaths(allFiles);
|
|
12927
|
+
const replacementMatchedExisting = job.replacement ? modelPaths.includes(job.replacement.modelPath) : undefined;
|
|
12928
|
+
if (job.replacement && !replacementMatchedExisting) {
|
|
12929
|
+
modelPaths.push(job.replacement.modelPath);
|
|
12930
|
+
}
|
|
12862
12931
|
const compileRegionStart = performance.now();
|
|
12863
12932
|
schemaWait.begin(job.requestId);
|
|
12864
12933
|
const models = await Promise.all(modelPaths.map((modelPath) => compileOneModel(job, malloyConfig, modelPath)));
|
|
@@ -12869,6 +12938,7 @@ async function loadPackage(job) {
|
|
|
12869
12938
|
requestId: job.requestId,
|
|
12870
12939
|
packageMetadata,
|
|
12871
12940
|
models,
|
|
12941
|
+
replacementMatchedExisting,
|
|
12872
12942
|
loadDurationMs: loadEnd - loadStart,
|
|
12873
12943
|
timings: {
|
|
12874
12944
|
compileDurationMs: Math.max(0, loadEnd - compileRegionStart - schemaFetchDurationMs),
|