@malloydata/malloy 0.0.348 → 0.0.350

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.
@@ -13,12 +13,19 @@ export interface MalloyProjectConfig {
13
13
  * In-memory manifest store. Reads, updates, and serializes manifest data.
14
14
  *
15
15
  * Always valid — starts empty, call load() to populate from a file.
16
- * The internal BuildManifest object is stable: load() and update() mutate
17
- * the same object, so any reference obtained via `buildManifest` stays current.
16
+ * The BuildManifest object returned by `buildManifest` is stable: load()
17
+ * and update() mutate the same entries object, so any reference obtained
18
+ * via `buildManifest` stays current without re-assignment.
19
+ *
20
+ * The `strict` flag controls what happens when a persist source's BuildID
21
+ * is not found in the manifest. When strict, the compiler throws an error
22
+ * instead of falling through to inline SQL. The flag is loaded from the
23
+ * manifest file and can be overridden by the application before creating
24
+ * a Runtime.
18
25
  */
19
26
  export declare class Manifest {
20
27
  private readonly _urlReader?;
21
- private readonly _data;
28
+ private readonly _manifest;
22
29
  private readonly _touched;
23
30
  constructor(urlReader?: URLReader);
24
31
  /**
@@ -36,9 +43,15 @@ export declare class Manifest {
36
43
  /**
37
44
  * The live BuildManifest. This is a stable reference — load() and update()
38
45
  * mutate the same object, so passing this to a Runtime means the Runtime
39
- * always sees current data.
46
+ * always sees current data including the strict flag.
40
47
  */
41
48
  get buildManifest(): BuildManifest;
49
+ /**
50
+ * Whether missing manifest entries should cause errors.
51
+ * Loaded from the manifest file; can be overridden by the application.
52
+ */
53
+ get strict(): boolean;
54
+ set strict(value: boolean);
42
55
  /**
43
56
  * Add or replace a manifest entry. Also marks it as touched.
44
57
  */
@@ -49,11 +62,13 @@ export declare class Manifest {
49
62
  */
50
63
  touch(buildId: BuildID): void;
51
64
  /**
52
- * Returns only entries that were update()d or touch()ed.
53
- * This is the manifest a builder should write — it reflects
54
- * exactly what the current build references.
65
+ * Returns a BuildManifest with only entries that were update()d or touch()ed.
66
+ * This is the manifest a builder should write — it reflects exactly what the
67
+ * current build references. Preserves the strict flag.
55
68
  */
56
69
  get activeEntries(): BuildManifest;
70
+ private _clearEntries;
71
+ private _loadParsed;
57
72
  }
58
73
  /**
59
74
  * Loads and holds a Malloy project configuration (connections + manifest).
@@ -12,12 +12,19 @@ const MANIFEST_FILENAME = 'malloy-manifest.json';
12
12
  * In-memory manifest store. Reads, updates, and serializes manifest data.
13
13
  *
14
14
  * Always valid — starts empty, call load() to populate from a file.
15
- * The internal BuildManifest object is stable: load() and update() mutate
16
- * the same object, so any reference obtained via `buildManifest` stays current.
15
+ * The BuildManifest object returned by `buildManifest` is stable: load()
16
+ * and update() mutate the same entries object, so any reference obtained
17
+ * via `buildManifest` stays current without re-assignment.
18
+ *
19
+ * The `strict` flag controls what happens when a persist source's BuildID
20
+ * is not found in the manifest. When strict, the compiler throws an error
21
+ * instead of falling through to inline SQL. The flag is loaded from the
22
+ * manifest file and can be overridden by the application before creating
23
+ * a Runtime.
17
24
  */
18
25
  class Manifest {
19
26
  constructor(urlReader) {
20
- this._data = {};
27
+ this._manifest = { entries: {}, strict: false };
21
28
  this._touched = new Set();
22
29
  this._urlReader = urlReader;
23
30
  }
@@ -28,11 +35,9 @@ class Manifest {
28
35
  * is available, clears to empty.
29
36
  */
30
37
  async load(manifestRoot) {
31
- // Clear existing entries and touched set
32
- for (const key of Object.keys(this._data)) {
33
- delete this._data[key];
34
- }
38
+ this._clearEntries();
35
39
  this._touched.clear();
40
+ this._manifest.strict = false;
36
41
  if (!this._urlReader)
37
42
  return;
38
43
  const dir = manifestRoot.toString().endsWith('/')
@@ -48,34 +53,42 @@ class Manifest {
48
53
  // No manifest file — stay empty
49
54
  return;
50
55
  }
51
- const loaded = JSON.parse(contents);
52
- Object.assign(this._data, loaded);
56
+ this._loadParsed(JSON.parse(contents));
53
57
  }
54
58
  /**
55
59
  * Load manifest data from a JSON string.
56
60
  * Replaces any existing data.
57
61
  */
58
62
  loadText(jsonText) {
59
- for (const key of Object.keys(this._data)) {
60
- delete this._data[key];
61
- }
63
+ this._clearEntries();
62
64
  this._touched.clear();
63
- const loaded = JSON.parse(jsonText);
64
- Object.assign(this._data, loaded);
65
+ this._manifest.strict = false;
66
+ this._loadParsed(JSON.parse(jsonText));
65
67
  }
66
68
  /**
67
69
  * The live BuildManifest. This is a stable reference — load() and update()
68
70
  * mutate the same object, so passing this to a Runtime means the Runtime
69
- * always sees current data.
71
+ * always sees current data including the strict flag.
70
72
  */
71
73
  get buildManifest() {
72
- return this._data;
74
+ return this._manifest;
75
+ }
76
+ /**
77
+ * Whether missing manifest entries should cause errors.
78
+ * Loaded from the manifest file; can be overridden by the application.
79
+ */
80
+ get strict() {
81
+ var _a;
82
+ return (_a = this._manifest.strict) !== null && _a !== void 0 ? _a : false;
83
+ }
84
+ set strict(value) {
85
+ this._manifest.strict = value;
73
86
  }
74
87
  /**
75
88
  * Add or replace a manifest entry. Also marks it as touched.
76
89
  */
77
90
  update(buildId, entry) {
78
- this._data[buildId] = entry;
91
+ this._manifest.entries[buildId] = entry;
79
92
  this._touched.add(buildId);
80
93
  }
81
94
  /**
@@ -86,18 +99,47 @@ class Manifest {
86
99
  this._touched.add(buildId);
87
100
  }
88
101
  /**
89
- * Returns only entries that were update()d or touch()ed.
90
- * This is the manifest a builder should write — it reflects
91
- * exactly what the current build references.
102
+ * Returns a BuildManifest with only entries that were update()d or touch()ed.
103
+ * This is the manifest a builder should write — it reflects exactly what the
104
+ * current build references. Preserves the strict flag.
92
105
  */
93
106
  get activeEntries() {
94
- const result = {};
107
+ const entries = {};
95
108
  for (const id of this._touched) {
96
- if (this._data[id]) {
97
- result[id] = this._data[id];
109
+ if (this._manifest.entries[id]) {
110
+ entries[id] = this._manifest.entries[id];
111
+ }
112
+ }
113
+ return { entries, strict: this._manifest.strict };
114
+ }
115
+ _clearEntries() {
116
+ for (const key of Object.keys(this._manifest.entries)) {
117
+ delete this._manifest.entries[key];
118
+ }
119
+ }
120
+ _loadParsed(parsed) {
121
+ if (typeof parsed['strict'] === 'boolean') {
122
+ this._manifest.strict = parsed['strict'];
123
+ }
124
+ // New format: {entries: {...}, strict?: boolean}
125
+ // Old format: {buildId: {tableName}, ...} (flat record, no "entries" key)
126
+ let entries;
127
+ if (parsed['entries'] && typeof parsed['entries'] === 'object') {
128
+ entries = parsed['entries'];
129
+ }
130
+ else {
131
+ // Treat as old flat-record format: every key with a tableName is an entry
132
+ entries = {};
133
+ for (const [key, val] of Object.entries(parsed)) {
134
+ if (key !== 'strict' &&
135
+ val &&
136
+ typeof val === 'object' &&
137
+ 'tableName' in val) {
138
+ entries[key] = val;
139
+ }
98
140
  }
99
141
  }
100
- return result;
142
+ Object.assign(this._manifest.entries, entries);
101
143
  }
102
144
  }
103
145
  exports.Manifest = Manifest;
@@ -1,4 +1,5 @@
1
1
  export type { Taggable, Loggable, ParseOptions, CompileOptions, CompileQueryOptions, BuildNode, BuildGraph, } from './types';
2
+ export { EMPTY_BUILD_MANIFEST } from './types';
2
3
  export { EmptyURLReader, InMemoryURLReader, FixedConnectionMap, hashForInvalidationKey, isInternalURL, readURL, getInvalidationKey, } from './readers';
3
4
  export type { ModelCache, CachedModel } from './cache';
4
5
  export { CacheManager, InMemoryModelCache } from './cache';
@@ -4,8 +4,10 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Manifest = exports.ExploreMaterializer = exports.PreparedResultMaterializer = exports.QueryMaterializer = exports.ModelMaterializer = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.Runtime = exports.CSVWriter = exports.JSONWriter = exports.DataWriter = exports.DataRecord = exports.DataArray = exports.Result = exports.PreparedResult = exports.PreparedQuery = exports.PersistSource = exports.Model = exports.QueryField = exports.Query = exports.StringField = exports.UnsupportedField = exports.JSONField = exports.BooleanField = exports.NumberField = exports.TimestampField = exports.DateField = exports.AtomicField = exports.ExploreField = exports.Explore = exports.JoinRelationship = exports.TimestampTimeframe = exports.DateTimeframe = exports.AtomicFieldType = exports.SourceRelationship = exports.DocumentCompletion = exports.DocumentSymbol = exports.DocumentPosition = exports.DocumentRange = exports.DocumentTablePath = exports.Parse = exports.InMemoryModelCache = exports.CacheManager = exports.getInvalidationKey = exports.readURL = exports.isInternalURL = exports.hashForInvalidationKey = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = void 0;
8
- exports.MalloyError = exports.Malloy = exports.MalloyConfig = void 0;
7
+ exports.ExploreMaterializer = exports.PreparedResultMaterializer = exports.QueryMaterializer = exports.ModelMaterializer = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.Runtime = exports.CSVWriter = exports.JSONWriter = exports.DataWriter = exports.DataRecord = exports.DataArray = exports.Result = exports.PreparedResult = exports.PreparedQuery = exports.PersistSource = exports.Model = exports.QueryField = exports.Query = exports.StringField = exports.UnsupportedField = exports.JSONField = exports.BooleanField = exports.NumberField = exports.TimestampField = exports.DateField = exports.AtomicField = exports.ExploreField = exports.Explore = exports.JoinRelationship = exports.TimestampTimeframe = exports.DateTimeframe = exports.AtomicFieldType = exports.SourceRelationship = exports.DocumentCompletion = exports.DocumentSymbol = exports.DocumentPosition = exports.DocumentRange = exports.DocumentTablePath = exports.Parse = exports.InMemoryModelCache = exports.CacheManager = exports.getInvalidationKey = exports.readURL = exports.isInternalURL = exports.hashForInvalidationKey = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.EMPTY_BUILD_MANIFEST = void 0;
8
+ exports.MalloyError = exports.Malloy = exports.MalloyConfig = exports.Manifest = void 0;
9
+ var types_1 = require("./types");
10
+ Object.defineProperty(exports, "EMPTY_BUILD_MANIFEST", { enumerable: true, get: function () { return types_1.EMPTY_BUILD_MANIFEST; } });
9
11
  // URL readers and connection helpers
10
12
  var readers_1 = require("./readers");
11
13
  Object.defineProperty(exports, "EmptyURLReader", { enumerable: true, get: function () { return readers_1.EmptyURLReader; } });
@@ -577,18 +577,24 @@ class QueryMaterializer extends FluentState {
577
577
  ...options,
578
578
  };
579
579
  // Use manifest from options if provided, otherwise fall back to Runtime's manifest.
580
- // Pass an empty {} in options to explicitly suppress manifest substitution.
580
+ // Pass EMPTY_BUILD_MANIFEST in options to explicitly suppress manifest substitution.
581
581
  const explicitManifest = mergedOptions.buildManifest !== undefined;
582
582
  let buildManifest = (_a = mergedOptions.buildManifest) !== null && _a !== void 0 ? _a : this.runtime.buildManifest;
583
- // If we have a manifest, compute connectionDigests for manifest lookups
583
+ // If we have a manifest with entries, compute connectionDigests for lookups.
584
584
  // TODO: This is inefficient - we call getBuildPlan just to find connection names.
585
585
  // Consider adding a listConnections() method to LookupConnection, or caching this.
586
586
  let connectionDigests;
587
+ if (buildManifest &&
588
+ Object.keys(buildManifest.entries).length === 0 &&
589
+ !buildManifest.strict) {
590
+ // Empty non-strict manifest — nothing to substitute, skip persistence checks
591
+ buildManifest = undefined;
592
+ }
587
593
  if (buildManifest) {
588
594
  const modelTag = preparedQuery.model.tagParse({ prefix: /^##! / }).tag;
589
595
  if (!modelTag.has('experimental', 'persistence')) {
590
596
  if (explicitManifest) {
591
- // Explicitly passed manifest requires persistence support
597
+ // Explicitly passed non-empty manifest requires persistence support
592
598
  throw new Error('Model must have ##! experimental.persistence to use buildManifest');
593
599
  }
594
600
  // Runtime-level manifest (e.g. from config): silently ignore
@@ -609,7 +615,6 @@ class QueryMaterializer extends FluentState {
609
615
  defaultRowLimit: mergedOptions.defaultRowLimit,
610
616
  buildManifest,
611
617
  connectionDigests,
612
- strictPersist: mergedOptions.strictPersist,
613
618
  };
614
619
  return preparedQuery.getPreparedResult({
615
620
  ...mergedOptions,
@@ -1,5 +1,14 @@
1
1
  import type { EventStream } from '../../runtime_types';
2
2
  import type { BuildManifest } from '../../model';
3
+ /**
4
+ * An empty BuildManifest with no entries and strict mode off.
5
+ * Use this to explicitly suppress manifest substitution in a query:
6
+ *
7
+ * runtime.loadQuery(url, {buildManifest: EMPTY_BUILD_MANIFEST}).getSQL()
8
+ *
9
+ * Frozen to prevent accidental mutation of the shared sentinel.
10
+ */
11
+ export declare const EMPTY_BUILD_MANIFEST: BuildManifest;
3
12
  export type { Taggable } from '../../taggable';
4
13
  export interface Loggable {
5
14
  debug: (message?: any, ...optionalParams: any[]) => void;
@@ -20,12 +29,10 @@ export interface CompileOptions {
20
29
  export interface CompileQueryOptions {
21
30
  eventStream?: EventStream;
22
31
  defaultRowLimit?: number;
23
- /** Manifest of built tables (BuildID → entry) for persist substitution */
32
+ /** Manifest of built tables for persist source substitution */
24
33
  buildManifest?: BuildManifest;
25
34
  /** Map from connectionName to connectionDigest (from Connection.getDigest()) */
26
35
  connectionDigests?: Record<string, string>;
27
- /** If true, throw when a persist source's BuildID is not in the manifest */
28
- strictPersist?: boolean;
29
36
  }
30
37
  /**
31
38
  * A node in the build graph (recursive DAG structure).
@@ -4,4 +4,17 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.EMPTY_BUILD_MANIFEST = void 0;
8
+ /**
9
+ * An empty BuildManifest with no entries and strict mode off.
10
+ * Use this to explicitly suppress manifest substitution in a query:
11
+ *
12
+ * runtime.loadQuery(url, {buildManifest: EMPTY_BUILD_MANIFEST}).getSQL()
13
+ *
14
+ * Frozen to prevent accidental mutation of the shared sentinel.
15
+ */
16
+ exports.EMPTY_BUILD_MANIFEST = Object.freeze({
17
+ entries: Object.freeze({}),
18
+ strict: false,
19
+ });
7
20
  //# sourceMappingURL=types.js.map
package/dist/index.d.ts CHANGED
@@ -18,5 +18,5 @@ export type { SQLSourceRequest } from './lang/translate-response';
18
18
  export { sqlKey } from './model/sql_block';
19
19
  export { annotationToTag, annotationToTaglines } from './annotation';
20
20
  export type { BuildGraph, BuildNode, BuildPlan } from './api/foundation';
21
- export { PersistSource } from './api/foundation';
21
+ export { PersistSource, EMPTY_BUILD_MANIFEST } from './api/foundation';
22
22
  export { makeDigest } from './model';
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = exports.constantExprToSQL = exports.isDateUnit = exports.isTimestampUnit = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isBasicArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isCompoundArrayData = exports.isBasicAtomic = exports.isAtomic = exports.isSourceDef = exports.TinyParser = exports.Dialect = exports.spread = exports.literal = exports.variadicParam = exports.param = exports.makeParam = exports.sql = exports.maxScalar = exports.minAggregate = exports.anyExprType = exports.minScalar = exports.overload = exports.qtz = exports.arg = exports.registerDialect = exports.MySQLDialect = exports.SnowflakeDialect = exports.PostgresDialect = exports.TrinoDialect = exports.StandardSQLDialect = exports.DuckDBDialect = void 0;
37
- exports.makeDigest = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.resolveValue = exports.isValueRef = exports.getRegisteredConnectionTypes = exports.getConnectionTypeDisplayName = exports.getConnectionProperties = exports.registerConnectionType = exports.MalloyConfig = exports.Manifest = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = void 0;
37
+ exports.makeDigest = exports.EMPTY_BUILD_MANIFEST = exports.PersistSource = exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = exports.resolveValue = exports.isValueRef = exports.getRegisteredConnectionTypes = exports.getConnectionTypeDisplayName = exports.getConnectionProperties = exports.registerConnectionType = exports.MalloyConfig = exports.Manifest = exports.CacheManager = exports.InMemoryModelCache = exports.Explore = exports.DataWriter = exports.Parse = exports.JSONWriter = exports.CSVWriter = exports.QueryMaterializer = exports.Result = exports.PreparedResult = exports.TimestampTimeframe = exports.DateTimeframe = exports.SourceRelationship = exports.JoinRelationship = exports.MalloyError = exports.FixedConnectionMap = exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = void 0;
38
38
  /*
39
39
  * Copyright 2023 Google LLC
40
40
  *
@@ -157,6 +157,7 @@ Object.defineProperty(exports, "annotationToTag", { enumerable: true, get: funct
157
157
  Object.defineProperty(exports, "annotationToTaglines", { enumerable: true, get: function () { return annotation_1.annotationToTaglines; } });
158
158
  var foundation_2 = require("./api/foundation");
159
159
  Object.defineProperty(exports, "PersistSource", { enumerable: true, get: function () { return foundation_2.PersistSource; } });
160
+ Object.defineProperty(exports, "EMPTY_BUILD_MANIFEST", { enumerable: true, get: function () { return foundation_2.EMPTY_BUILD_MANIFEST; } });
160
161
  var model_2 = require("./model");
161
162
  Object.defineProperty(exports, "makeDigest", { enumerable: true, get: function () { return model_2.makeDigest; } });
162
163
  //# sourceMappingURL=index.js.map
@@ -1073,12 +1073,10 @@ export interface PrepareResultOptions {
1073
1073
  defaultRowLimit?: number;
1074
1074
  isPartialQuery?: boolean;
1075
1075
  eventStream?: EventStream;
1076
- /** Manifest of built tables (BuildID entry), the build cache */
1076
+ /** Manifest of built tables for persist source substitution */
1077
1077
  buildManifest?: BuildManifest;
1078
1078
  /** Map from connectionName to connectionDigest (from Connection.getDigest()) */
1079
1079
  connectionDigests?: SafeRecord<string>;
1080
- /** If true, throw when a persist query's digest is not in the manifest */
1081
- strictPersist?: boolean;
1082
1080
  }
1083
1081
  type UTD = AtomicTypeDef | TypedDef | FunctionParameterTypeDef | FunctionReturnTypeDef | undefined;
1084
1082
  /**
@@ -1124,9 +1122,15 @@ export interface BuildManifestEntry {
1124
1122
  }
1125
1123
  /**
1126
1124
  * Manifest of persisted build results (the build cache).
1127
- * Maps BuildID → BuildManifestEntry. Used by compileQuery to substitute
1128
- * persist sources with table references. Content-addressable: same SQL +
1129
- * same connection digest = same BuildID regardless of which model produced it.
1125
+ * Used by compileQuery to substitute persist sources with table references.
1126
+ * Content-addressable: same SQL + same connection digest = same BuildID
1127
+ * regardless of which model produced it.
1128
+ *
1129
+ * When `strict` is true, a missing entry for a persist source throws an error
1130
+ * instead of falling through to inline SQL.
1130
1131
  */
1131
- export type BuildManifest = Record<BuildID, BuildManifestEntry>;
1132
+ export interface BuildManifest {
1133
+ entries: Record<BuildID, BuildManifestEntry>;
1134
+ strict?: boolean;
1135
+ }
1132
1136
  export {};
@@ -534,7 +534,7 @@ class QueryQuery extends query_node_1.QueryField {
534
534
  case 'nest_source':
535
535
  return qs.structDef.pipeSQL;
536
536
  case 'query_source': {
537
- const { buildManifest, connectionDigests, strictPersist } = (_b = qs.prepareResultOptions) !== null && _b !== void 0 ? _b : {};
537
+ const { buildManifest, connectionDigests } = (_b = qs.prepareResultOptions) !== null && _b !== void 0 ? _b : {};
538
538
  // Check manifest for this source
539
539
  if (buildManifest && connectionDigests) {
540
540
  const connDigest = (0, malloy_types_1.safeRecordGet)(connectionDigests, qs.structDef.connection);
@@ -542,12 +542,12 @@ class QueryQuery extends query_node_1.QueryField {
542
542
  // Compile with empty opts to get manifest-ignorant SQL for BuildID
543
543
  const fullRet = this.compileQueryToStages(qs.structDef.query, {}, undefined, false);
544
544
  const buildId = (0, source_def_utils_1.mkBuildID)(connDigest, fullRet.sql);
545
- const entry = buildManifest[buildId];
545
+ const entry = buildManifest.entries[buildId];
546
546
  if (entry) {
547
547
  // Found in manifest - use persisted table
548
548
  return this.parent.dialect.quoteTablePath(entry.tableName);
549
549
  }
550
- if (strictPersist) {
550
+ if (buildManifest.strict) {
551
551
  throw new Error(`Persist source '${qs.structDef.sourceID}' not found in manifest (buildId: ${buildId})`);
552
552
  }
553
553
  }
@@ -51,7 +51,7 @@ function expandSegment(segment, opts, quoteTablePath, compileQuery) {
51
51
  * Always returns a subquery form: (SELECT * FROM table) or (inline SQL)
52
52
  */
53
53
  function expandPersistableSource(source, opts, quoteTablePath, compileQuery) {
54
- const { buildManifest, connectionDigests, strictPersist } = opts;
54
+ const { buildManifest, connectionDigests } = opts;
55
55
  // Try manifest lookup if we have the required info
56
56
  if (buildManifest && connectionDigests) {
57
57
  const connDigest = (0, malloy_types_1.safeRecordGet)(connectionDigests, source.connection);
@@ -59,13 +59,13 @@ function expandPersistableSource(source, opts, quoteTablePath, compileQuery) {
59
59
  // Get the SQL for this source to compute BuildID (no opts = full SQL)
60
60
  const sql = getSourceSQL(source, quoteTablePath, compileQuery);
61
61
  const buildId = (0, source_def_utils_1.mkBuildID)(connDigest, sql);
62
- const entry = buildManifest[buildId];
62
+ const entry = buildManifest.entries[buildId];
63
63
  if (entry) {
64
64
  // Found in manifest - substitute with subquery from persisted table
65
65
  return `(SELECT * FROM ${quoteTablePath(entry.tableName)})`;
66
66
  }
67
67
  // Not in manifest
68
- if (strictPersist) {
68
+ if (buildManifest.strict) {
69
69
  throw new Error(`Persist source '${source.sourceID}' not found in manifest (buildId: ${buildId})`);
70
70
  }
71
71
  }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const MALLOY_VERSION = "0.0.348";
1
+ export declare const MALLOY_VERSION = "0.0.350";
package/dist/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MALLOY_VERSION = void 0;
4
4
  // generated with 'generate-version-file' script; do not edit manually
5
- exports.MALLOY_VERSION = '0.0.348';
5
+ exports.MALLOY_VERSION = '0.0.350';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.348",
3
+ "version": "0.0.350",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -45,9 +45,9 @@
45
45
  "generate-version-file": "VERSION=$(npm pkg get version --workspaces=false | tr -d \\\")\necho \"// generated with 'generate-version-file' script; do not edit manually\\nexport const MALLOY_VERSION = '$VERSION';\" > src/version.ts"
46
46
  },
47
47
  "dependencies": {
48
- "@malloydata/malloy-filter": "0.0.348",
49
- "@malloydata/malloy-interfaces": "0.0.348",
50
- "@malloydata/malloy-tag": "0.0.348",
48
+ "@malloydata/malloy-filter": "0.0.350",
49
+ "@malloydata/malloy-interfaces": "0.0.350",
50
+ "@malloydata/malloy-tag": "0.0.350",
51
51
  "@noble/hashes": "^1.8.0",
52
52
  "antlr4ts": "^0.5.0-alpha.4",
53
53
  "assert": "^2.0.0",