@malloydata/malloy 0.0.362 → 0.0.364

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.
Files changed (46) hide show
  1. package/dist/api/core.js +21 -3
  2. package/dist/api/foundation/compile.js +20 -0
  3. package/dist/api/foundation/runtime.d.ts +16 -4
  4. package/dist/api/foundation/runtime.js +22 -4
  5. package/dist/api/foundation/types.d.ts +3 -1
  6. package/dist/index.d.ts +1 -1
  7. package/dist/lang/ast/index.d.ts +5 -0
  8. package/dist/lang/ast/index.js +5 -0
  9. package/dist/lang/ast/source-elements/named-source.js +4 -0
  10. package/dist/lang/ast/source-elements/typed-source.d.ts +23 -0
  11. package/dist/lang/ast/source-elements/typed-source.js +133 -0
  12. package/dist/lang/ast/source-elements/virtual-source.d.ts +10 -0
  13. package/dist/lang/ast/source-elements/virtual-source.js +47 -0
  14. package/dist/lang/ast/source-properties/user-type-shape.d.ts +29 -0
  15. package/dist/lang/ast/source-properties/user-type-shape.js +100 -0
  16. package/dist/lang/ast/source-query-elements/sq-reference.js +1 -1
  17. package/dist/lang/ast/source-query-elements/sq-typed-source.d.ts +18 -0
  18. package/dist/lang/ast/source-query-elements/sq-typed-source.js +39 -0
  19. package/dist/lang/ast/statements/define-user-type.d.ts +28 -0
  20. package/dist/lang/ast/statements/define-user-type.js +82 -0
  21. package/dist/lang/ast/types/malloy-element.js +14 -6
  22. package/dist/lang/lib/Malloy/MalloyLexer.d.ts +146 -144
  23. package/dist/lang/lib/Malloy/MalloyLexer.js +1408 -1391
  24. package/dist/lang/lib/Malloy/MalloyParser.d.ts +491 -307
  25. package/dist/lang/lib/Malloy/MalloyParser.js +7907 -6680
  26. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +186 -0
  27. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +117 -0
  28. package/dist/lang/malloy-to-ast.d.ts +17 -0
  29. package/dist/lang/malloy-to-ast.js +118 -0
  30. package/dist/lang/parse-log.d.ts +12 -1
  31. package/dist/lang/parse-malloy.d.ts +6 -1
  32. package/dist/lang/parse-malloy.js +17 -1
  33. package/dist/lang/parse-tree-walkers/find-external-references.d.ts +4 -0
  34. package/dist/lang/parse-tree-walkers/find-external-references.js +10 -0
  35. package/dist/lang/test/test-translator.d.ts +2 -1
  36. package/dist/lang/test/test-translator.js +10 -0
  37. package/dist/lang/translate-response.d.ts +6 -1
  38. package/dist/lang/translate-response.js +3 -1
  39. package/dist/model/malloy_types.d.ts +25 -4
  40. package/dist/model/malloy_types.js +13 -2
  41. package/dist/model/query_model_impl.js +3 -0
  42. package/dist/model/query_node.js +1 -0
  43. package/dist/model/query_query.js +11 -3
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +1 -1
  46. package/package.json +4 -4
package/dist/api/core.js CHANGED
@@ -167,7 +167,8 @@ function getSchemaFields(schema) {
167
167
  return fields;
168
168
  }
169
169
  function compilerNeedsToUpdate(compilerNeeds) {
170
- var _a, _b, _c, _d, _e, _f;
170
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
171
+ var _l;
171
172
  const update = {
172
173
  urls: {},
173
174
  tables: {},
@@ -200,10 +201,22 @@ function compilerNeedsToUpdate(compilerNeeds) {
200
201
  update.translations[translation.url] = modelDef;
201
202
  }
202
203
  }
204
+ for (const connection of (_g = compilerNeeds.connections) !== null && _g !== void 0 ? _g : []) {
205
+ if (connection.dialect) {
206
+ (_h = update.connectionDialects) !== null && _h !== void 0 ? _h : (update.connectionDialects = {});
207
+ update.connectionDialects[connection.name] = connection.dialect;
208
+ }
209
+ else {
210
+ (_j = update.errors) !== null && _j !== void 0 ? _j : (update.errors = {});
211
+ (_k = (_l = update.errors).connectionDialects) !== null && _k !== void 0 ? _k : (_l.connectionDialects = {});
212
+ update.errors.connectionDialects[connection.name] =
213
+ `Connection '${connection.name}' not found`;
214
+ }
215
+ }
203
216
  }
204
217
  return update;
205
218
  }
206
- function convertCompilerNeeds(compileSQL, urls, tables) {
219
+ function convertCompilerNeeds(compileSQL, urls, tables, connectionDialects) {
207
220
  var _a, _b, _c;
208
221
  const compilerNeeds = {};
209
222
  const neededConnections = new Set();
@@ -235,6 +248,11 @@ function convertCompilerNeeds(compileSQL, urls, tables) {
235
248
  neededConnections.add(connectionName);
236
249
  }
237
250
  }
251
+ if (connectionDialects !== undefined) {
252
+ for (const connName in connectionDialects) {
253
+ neededConnections.add(connectionDialects[connName].connectionName);
254
+ }
255
+ }
238
256
  if (neededConnections.size > 0) {
239
257
  compilerNeeds.connections = Array.from(neededConnections).map(c => ({
240
258
  name: c,
@@ -350,7 +368,7 @@ function _statedCompileModel(state) {
350
368
  }
351
369
  }
352
370
  else {
353
- const compilerNeeds = convertCompilerNeeds(result.compileSQL, result.urls, result.tables);
371
+ const compilerNeeds = convertCompilerNeeds(result.compileSQL, result.urls, result.tables, result.connectionDialects);
354
372
  const timingInfo = timer.stop();
355
373
  return { compilerNeeds, logs: result.problems, timingInfo };
356
374
  }
@@ -273,6 +273,26 @@ class Malloy {
273
273
  }
274
274
  }
275
275
  }
276
+ if (result.connectionDialects) {
277
+ for (const connName in result.connectionDialects) {
278
+ const { connectionName } = result.connectionDialects[connName];
279
+ try {
280
+ const connection = await connections.lookupConnection(connectionName);
281
+ translator.update({
282
+ connectionDialects: { [connName]: connection.dialectName },
283
+ });
284
+ }
285
+ catch (error) {
286
+ translator.update({
287
+ errors: {
288
+ connectionDialects: {
289
+ [connName]: error.toString(),
290
+ },
291
+ },
292
+ });
293
+ }
294
+ }
295
+ }
276
296
  if (result.compileSQL) {
277
297
  // Unlike other requests, these do not come in batches
278
298
  const toCompile = result.compileSQL;
@@ -1,6 +1,6 @@
1
1
  import type { Connection, LookupConnection } from '../../connection/types';
2
2
  import type { URLReader, EventStream } from '../../runtime_types';
3
- import type { ModelDef, Query as InternalQuery, SearchIndexResult, SearchValueMapResult, QueryRunStats, BuildManifest } from '../../model';
3
+ import type { ModelDef, Query as InternalQuery, SearchIndexResult, SearchValueMapResult, QueryRunStats, BuildManifest, VirtualMap } from '../../model';
4
4
  import type { Dialect } from '../../dialect';
5
5
  import type { RunSQLOptions } from '../../run_sql_options';
6
6
  import type { CacheManager } from './cache';
@@ -40,11 +40,13 @@ export declare class Runtime {
40
40
  private _eventStream;
41
41
  private _cacheManager;
42
42
  private _buildManifest;
43
- constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, }: {
43
+ private _virtualMap;
44
+ constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, virtualMap, }: {
44
45
  urlReader?: URLReader;
45
46
  eventStream?: EventStream;
46
47
  cacheManager?: CacheManager;
47
48
  buildManifest?: BuildManifest;
49
+ virtualMap?: VirtualMap;
48
50
  } & Connectionable);
49
51
  /**
50
52
  * @return The `CacheManager` for this runtime instance.
@@ -70,6 +72,14 @@ export declare class Runtime {
70
72
  */
71
73
  get buildManifest(): BuildManifest | undefined;
72
74
  set buildManifest(manifest: BuildManifest | undefined);
75
+ /**
76
+ * The virtual map for virtual source resolution.
77
+ * When set, compiled queries automatically resolve virtual sources
78
+ * against this map. Can be overridden per-query via
79
+ * CompileQueryOptions.virtualMap.
80
+ */
81
+ get virtualMap(): VirtualMap | undefined;
82
+ set virtualMap(map: VirtualMap | undefined);
73
83
  /**
74
84
  * Load a Malloy model by URL or contents.
75
85
  *
@@ -142,19 +152,21 @@ export declare class Runtime {
142
152
  }
143
153
  export declare class ConnectionRuntime extends Runtime {
144
154
  readonly rawConnections: Connection[];
145
- constructor({ urlReader, connections, buildManifest, }: {
155
+ constructor({ urlReader, connections, buildManifest, virtualMap, }: {
146
156
  urlReader?: URLReader;
147
157
  connections: Connection[];
148
158
  buildManifest?: BuildManifest;
159
+ virtualMap?: VirtualMap;
149
160
  });
150
161
  }
151
162
  export declare class SingleConnectionRuntime<T extends Connection = Connection> extends Runtime {
152
163
  readonly connection: T;
153
- constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, }: {
164
+ constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, virtualMap, }: {
154
165
  urlReader?: URLReader;
155
166
  eventStream?: EventStream;
156
167
  cacheManager?: CacheManager;
157
168
  buildManifest?: BuildManifest;
169
+ virtualMap?: VirtualMap;
158
170
  connection: T;
159
171
  });
160
172
  get supportsNesting(): boolean;
@@ -46,7 +46,7 @@ class FluentState {
46
46
  * An environment for compiling and running Malloy queries.
47
47
  */
48
48
  class Runtime {
49
- constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, }) {
49
+ constructor({ urlReader, connections, connection, eventStream, cacheManager, buildManifest, virtualMap, }) {
50
50
  this.isTestRuntime = false;
51
51
  if (connections === undefined) {
52
52
  if (connection === undefined) {
@@ -64,6 +64,7 @@ class Runtime {
64
64
  this._eventStream = eventStream;
65
65
  this._cacheManager = cacheManager;
66
66
  this._buildManifest = buildManifest;
67
+ this._virtualMap = virtualMap;
67
68
  }
68
69
  /**
69
70
  * @return The `CacheManager` for this runtime instance.
@@ -101,6 +102,18 @@ class Runtime {
101
102
  set buildManifest(manifest) {
102
103
  this._buildManifest = manifest;
103
104
  }
105
+ /**
106
+ * The virtual map for virtual source resolution.
107
+ * When set, compiled queries automatically resolve virtual sources
108
+ * against this map. Can be overridden per-query via
109
+ * CompileQueryOptions.virtualMap.
110
+ */
111
+ get virtualMap() {
112
+ return this._virtualMap;
113
+ }
114
+ set virtualMap(map) {
115
+ this._virtualMap = map;
116
+ }
104
117
  /**
105
118
  * Load a Malloy model by URL or contents.
106
119
  *
@@ -223,23 +236,25 @@ exports.Runtime = Runtime;
223
236
  // ConnectionRuntime and SingleConnectionRuntime
224
237
  // =============================================================================
225
238
  class ConnectionRuntime extends Runtime {
226
- constructor({ urlReader, connections, buildManifest, }) {
239
+ constructor({ urlReader, connections, buildManifest, virtualMap, }) {
227
240
  super({
228
241
  connections: readers_1.FixedConnectionMap.fromArray(connections),
229
242
  urlReader,
230
243
  buildManifest,
244
+ virtualMap,
231
245
  });
232
246
  this.rawConnections = connections;
233
247
  }
234
248
  }
235
249
  exports.ConnectionRuntime = ConnectionRuntime;
236
250
  class SingleConnectionRuntime extends Runtime {
237
- constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, }) {
251
+ constructor({ urlReader, connection, eventStream, cacheManager, buildManifest, virtualMap, }) {
238
252
  super({
239
253
  urlReader,
240
254
  eventStream,
241
255
  cacheManager,
242
256
  buildManifest,
257
+ virtualMap,
243
258
  connection,
244
259
  });
245
260
  this.connection = connection;
@@ -569,7 +584,7 @@ class QueryMaterializer extends FluentState {
569
584
  */
570
585
  loadPreparedResult(options) {
571
586
  return this.makePreparedResultMaterializer(async () => {
572
- var _a;
587
+ var _a, _b;
573
588
  const preparedQuery = await this.materialize();
574
589
  const mergedOptions = {
575
590
  eventStream: this.eventStream,
@@ -610,11 +625,14 @@ class QueryMaterializer extends FluentState {
610
625
  connectionDigests[connName] = conn.getDigest();
611
626
  }
612
627
  }
628
+ // Use virtualMap from options if provided, otherwise fall back to Runtime's.
629
+ const virtualMap = (_b = mergedOptions.virtualMap) !== null && _b !== void 0 ? _b : this.runtime.virtualMap;
613
630
  // Build PrepareResultOptions from CompileQueryOptions + connectionDigests
614
631
  const prepareResultOptions = {
615
632
  defaultRowLimit: mergedOptions.defaultRowLimit,
616
633
  buildManifest,
617
634
  connectionDigests,
635
+ virtualMap,
618
636
  };
619
637
  return preparedQuery.getPreparedResult({
620
638
  ...mergedOptions,
@@ -1,5 +1,5 @@
1
1
  import type { EventStream } from '../../runtime_types';
2
- import type { BuildManifest } from '../../model';
2
+ import type { BuildManifest, VirtualMap } from '../../model';
3
3
  /**
4
4
  * An empty BuildManifest with no entries and strict mode off.
5
5
  * Use this to explicitly suppress manifest substitution in a query:
@@ -33,6 +33,8 @@ export interface CompileQueryOptions {
33
33
  buildManifest?: BuildManifest;
34
34
  /** Map from connectionName to connectionDigest (from Connection.getDigest()) */
35
35
  connectionDigests?: Record<string, string>;
36
+ /** Map from connectionName → virtualName → tablePath for virtual source resolution */
37
+ virtualMap?: VirtualMap;
36
38
  }
37
39
  /**
38
40
  * A node in the build graph (recursive DAG structure).
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, DatabricksDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, TinyParser, } from './dialect';
2
2
  export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, TinyToken, } from './dialect';
3
- export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildID, BuildManifest, BuildManifestEntry, } from './model';
3
+ export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildID, BuildManifest, BuildManifestEntry, VirtualMap, } from './model';
4
4
  export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
5
5
  export { malloyToQuery, MalloyTranslator, } from './lang';
6
6
  export type { LogMessage, TranslateResponse } from './lang';
@@ -1,5 +1,6 @@
1
1
  export * from './query-properties/nest';
2
2
  export * from './statements/define-source';
3
+ export * from './statements/define-user-type';
3
4
  export * from './statements/define-query';
4
5
  export * from './source-elements/source';
5
6
  export * from './source-elements/refined-source';
@@ -9,6 +10,7 @@ export * from './source-query-elements/sq-refine';
9
10
  export * from './source-query-elements/sq-source';
10
11
  export * from './source-query-elements/sq-reference';
11
12
  export * from './source-query-elements/sq-extend';
13
+ export * from './source-query-elements/sq-typed-source';
12
14
  export * from './source-query-elements/sq-compose';
13
15
  export * from './source-query-elements/include-item';
14
16
  export * from './source-properties/field-list-edit';
@@ -16,6 +18,7 @@ export * from './source-properties/primary-key';
16
18
  export * from './source-properties/renames';
17
19
  export * from './source-properties/views';
18
20
  export * from './source-properties/timezone-statement';
21
+ export * from './source-properties/user-type-shape';
19
22
  export * from './expressions/apply';
20
23
  export * from './expressions/binary-numeric';
21
24
  export * from './expressions/boolean';
@@ -100,6 +103,8 @@ export * from './source-elements/named-source';
100
103
  export * from './source-elements/query-source';
101
104
  export * from './source-elements/sql-source';
102
105
  export * from './source-elements/table-source';
106
+ export * from './source-elements/typed-source';
107
+ export * from './source-elements/virtual-source';
103
108
  export * from './sql-elements/sql-string';
104
109
  export * from './types/annotation-elements';
105
110
  export * from './types/binary_operators';
@@ -38,6 +38,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  __exportStar(require("./query-properties/nest"), exports);
40
40
  __exportStar(require("./statements/define-source"), exports);
41
+ __exportStar(require("./statements/define-user-type"), exports);
41
42
  __exportStar(require("./statements/define-query"), exports);
42
43
  __exportStar(require("./source-elements/source"), exports);
43
44
  __exportStar(require("./source-elements/refined-source"), exports);
@@ -47,6 +48,7 @@ __exportStar(require("./source-query-elements/sq-refine"), exports);
47
48
  __exportStar(require("./source-query-elements/sq-source"), exports);
48
49
  __exportStar(require("./source-query-elements/sq-reference"), exports);
49
50
  __exportStar(require("./source-query-elements/sq-extend"), exports);
51
+ __exportStar(require("./source-query-elements/sq-typed-source"), exports);
50
52
  __exportStar(require("./source-query-elements/sq-compose"), exports);
51
53
  __exportStar(require("./source-query-elements/include-item"), exports);
52
54
  __exportStar(require("./source-properties/field-list-edit"), exports);
@@ -54,6 +56,7 @@ __exportStar(require("./source-properties/primary-key"), exports);
54
56
  __exportStar(require("./source-properties/renames"), exports);
55
57
  __exportStar(require("./source-properties/views"), exports);
56
58
  __exportStar(require("./source-properties/timezone-statement"), exports);
59
+ __exportStar(require("./source-properties/user-type-shape"), exports);
57
60
  __exportStar(require("./expressions/apply"), exports);
58
61
  __exportStar(require("./expressions/binary-numeric"), exports);
59
62
  __exportStar(require("./expressions/boolean"), exports);
@@ -138,6 +141,8 @@ __exportStar(require("./source-elements/named-source"), exports);
138
141
  __exportStar(require("./source-elements/query-source"), exports);
139
142
  __exportStar(require("./source-elements/sql-source"), exports);
140
143
  __exportStar(require("./source-elements/table-source"), exports);
144
+ __exportStar(require("./source-elements/typed-source"), exports);
145
+ __exportStar(require("./source-elements/virtual-source"), exports);
141
146
  __exportStar(require("./sql-elements/sql-string"), exports);
142
147
  __exportStar(require("./types/annotation-elements"), exports);
143
148
  __exportStar(require("./types/binary_operators"), exports);
@@ -99,6 +99,10 @@ class NamedSource extends source_1.Source {
99
99
  this.logError('invalid-source-from-connection', `Cannot construct a source from a connection '${this.refName}'`);
100
100
  return;
101
101
  }
102
+ else if (entry.type === 'userType') {
103
+ this.logError('invalid-source-from-user-type', `Cannot construct a source from a user type '${this.refName}'`);
104
+ return;
105
+ }
102
106
  else {
103
107
  (_a = this.document()) === null || _a === void 0 ? void 0 : _a.checkExperimentalDialect(this, entry.dialect);
104
108
  if ((0, malloy_types_1.isSourceDef)(entry)) {
@@ -0,0 +1,23 @@
1
+ import type { NonDefaultAccessModifierLabel, SourceDef } from '../../../model/malloy_types';
2
+ import { Source } from './source';
3
+ import type { ParameterSpace } from '../field-space/parameter-space';
4
+ import type { ModelEntryReference } from '../types/malloy-element';
5
+ export declare const USER_TYPE_HIDDEN_ACCESS: NonDefaultAccessModifierLabel;
6
+ /**
7
+ * A Source wrapped with user type constraints via the `::` operator.
8
+ * Resolves and merges user types (validating no conflicts), then:
9
+ * - virtual sources: user-type fields not in the source are added
10
+ * - all other sources: user-type fields not in the source are an error
11
+ * - in both cases: source fields not in any user type are marked
12
+ * with USER_TYPE_HIDDEN_ACCESS
13
+ *
14
+ * e.g. `source::MyType` or `source::(A, B)`
15
+ */
16
+ export declare class TypedSource extends Source {
17
+ readonly innerSource: Source;
18
+ readonly userTypes: ModelEntryReference[];
19
+ elementType: string;
20
+ constructor(innerSource: Source, userTypes: ModelEntryReference[]);
21
+ getSourceDef(parameterSpace: ParameterSpace | undefined): SourceDef;
22
+ private nextShape;
23
+ }
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.TypedSource = exports.USER_TYPE_HIDDEN_ACCESS = void 0;
8
+ const malloy_types_1 = require("../../../model/malloy_types");
9
+ const source_1 = require("./source");
10
+ exports.USER_TYPE_HIDDEN_ACCESS = 'internal';
11
+ /**
12
+ * With each field, keep the shape reference it came from, for error reporting
13
+ */
14
+ class Shape extends Map {
15
+ }
16
+ /**
17
+ * A Source wrapped with user type constraints via the `::` operator.
18
+ * Resolves and merges user types (validating no conflicts), then:
19
+ * - virtual sources: user-type fields not in the source are added
20
+ * - all other sources: user-type fields not in the source are an error
21
+ * - in both cases: source fields not in any user type are marked
22
+ * with USER_TYPE_HIDDEN_ACCESS
23
+ *
24
+ * e.g. `source::MyType` or `source::(A, B)`
25
+ */
26
+ class TypedSource extends source_1.Source {
27
+ constructor(innerSource, userTypes) {
28
+ super({ innerSource });
29
+ this.innerSource = innerSource;
30
+ this.userTypes = userTypes;
31
+ this.elementType = 'typedSource';
32
+ this.has({ userTypes });
33
+ }
34
+ getSourceDef(parameterSpace) {
35
+ const sourceDef = this.innerSource.getSourceDef(parameterSpace);
36
+ // Merge user types, while validating no field conflicts
37
+ const [outputShape, ...remainingShapes] = this.nextShape();
38
+ if (outputShape === undefined) {
39
+ return sourceDef;
40
+ }
41
+ for (const mergeShape of remainingShapes) {
42
+ for (const [name, { field, fromShape }] of mergeShape) {
43
+ const existing = outputShape.get(name);
44
+ if (existing && !malloy_types_1.TD.eq(field, existing.field)) {
45
+ fromShape.logError('user-type-field-conflict', `Field '${name}' has conflicting types in user types '${existing.fromShape.name}' and '${fromShape.name}'`);
46
+ }
47
+ else {
48
+ outputShape.set(name, { field, fromShape });
49
+ }
50
+ }
51
+ }
52
+ const isVirtual = sourceDef.type === 'virtual';
53
+ const sourceFields = new Map(sourceDef.fields.map(f => { var _a; return [(_a = f.as) !== null && _a !== void 0 ? _a : f.name, f]; }));
54
+ const fieldsToAdd = [];
55
+ // Validate/Enforce that this source matches the shape
56
+ for (const [name, { field, fromShape }] of outputShape) {
57
+ const sourceField = sourceFields.get(name);
58
+ if (sourceField === undefined) {
59
+ if (isVirtual) {
60
+ fieldsToAdd.push(field);
61
+ }
62
+ else {
63
+ fromShape.logError('user-type-field-missing', `Source is missing field '${field.name}' required by user type '${fromShape.name}'`);
64
+ }
65
+ }
66
+ else if (!isVirtual &&
67
+ (0, malloy_types_1.fieldIsIntrinsic)(sourceField) &&
68
+ !malloy_types_1.TD.eq(field, sourceField)) {
69
+ fromShape.logError('user-type-type-mismatch', `Type mismatch for '${name}': user type '${fromShape.name}' declares ${field.type} but source has ${sourceField.type}`);
70
+ }
71
+ }
72
+ // Intrinsic fields not in any shape: mark as hidden.
73
+ // Matching fields inherit annotations from the shape.
74
+ const resultFields = sourceDef.fields.map(f => {
75
+ var _a;
76
+ const name = (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
77
+ const shapeEntry = outputShape.get(name);
78
+ if (!shapeEntry || !(0, malloy_types_1.fieldIsIntrinsic)(f)) {
79
+ return (0, malloy_types_1.fieldIsIntrinsic)(f) && !shapeEntry
80
+ ? { ...f, accessModifier: exports.USER_TYPE_HIDDEN_ACCESS }
81
+ : f;
82
+ }
83
+ const shapeAnnotation = shapeEntry.field.annotation;
84
+ if (!shapeAnnotation) {
85
+ return f;
86
+ }
87
+ return { ...f, annotation: mergeAnnotation(f.annotation, shapeAnnotation) };
88
+ });
89
+ return {
90
+ ...sourceDef,
91
+ fields: [...resultFields, ...fieldsToAdd],
92
+ };
93
+ }
94
+ *nextShape() {
95
+ for (const ref of this.userTypes) {
96
+ const next = new Shape();
97
+ const entry = this.modelEntry(ref);
98
+ if (entry === undefined) {
99
+ ref.logError('user-type-not-found', `User type '${ref.name}' is not defined`);
100
+ continue;
101
+ }
102
+ if (!(0, malloy_types_1.isUserTypeDef)(entry.entry)) {
103
+ ref.logError('not-a-user-type', `'${ref.name}' is not a user type`);
104
+ continue;
105
+ }
106
+ for (const sf of entry.entry.fields) {
107
+ const field = (0, malloy_types_1.mkFieldDef)(sf.typeDef, sf.name);
108
+ if (sf.annotation) {
109
+ field.annotation = sf.annotation;
110
+ }
111
+ next.set(sf.name, { field, fromShape: ref });
112
+ }
113
+ yield next;
114
+ }
115
+ }
116
+ }
117
+ exports.TypedSource = TypedSource;
118
+ /**
119
+ * Insert shapeAnnotation behind fieldAnnotation in the inherits chain.
120
+ * Chain: field → shape → (whatever field previously inherited from)
121
+ */
122
+ function mergeAnnotation(fieldAnnotation, shapeAnnotation) {
123
+ if (!fieldAnnotation) {
124
+ return shapeAnnotation;
125
+ }
126
+ return {
127
+ ...fieldAnnotation,
128
+ inherits: fieldAnnotation.inherits
129
+ ? { ...shapeAnnotation, inherits: fieldAnnotation.inherits }
130
+ : shapeAnnotation,
131
+ };
132
+ }
133
+ //# sourceMappingURL=typed-source.js.map
@@ -0,0 +1,10 @@
1
+ import type { SourceDef } from '../../../model/malloy_types';
2
+ import { Source } from './source';
3
+ import type { ModelEntryReference } from '../types/malloy-element';
4
+ export declare class VirtualTableSource extends Source {
5
+ readonly connectionName: ModelEntryReference;
6
+ readonly virtualName: string;
7
+ elementType: string;
8
+ constructor(connectionName: ModelEntryReference, virtualName: string);
9
+ getSourceDef(): SourceDef;
10
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.VirtualTableSource = void 0;
8
+ const source_1 = require("./source");
9
+ const error_factory_1 = require("../error-factory");
10
+ class VirtualTableSource extends source_1.Source {
11
+ constructor(connectionName, virtualName) {
12
+ super();
13
+ this.connectionName = connectionName;
14
+ this.virtualName = virtualName;
15
+ this.elementType = 'virtualTableSource';
16
+ this.has({ connectionName });
17
+ }
18
+ getSourceDef() {
19
+ var _a, _b, _c;
20
+ const connection = this.modelEntry(this.connectionName);
21
+ const name = this.connectionName.refString;
22
+ if (connection === undefined) {
23
+ (_a = this.namespace()) === null || _a === void 0 ? void 0 : _a.setEntry(name, { entry: { type: 'connection', name }, exported: true }, true);
24
+ }
25
+ else if (connection.entry.type !== 'connection') {
26
+ this.connectionName.logError('invalid-connection-for-table-source', `${this.connectionName.refString} is not a connection`);
27
+ return error_factory_1.ErrorFactory.structDef;
28
+ }
29
+ const dialect = (_b = this.translator()) === null || _b === void 0 ? void 0 : _b.root.connectionDialectZone.get(name);
30
+ if (dialect === undefined) {
31
+ this.logError('virtual-source-unknown-dialect', `Cannot determine dialect for connection '${name}'`);
32
+ return error_factory_1.ErrorFactory.structDef;
33
+ }
34
+ const sourceDef = {
35
+ type: 'virtual',
36
+ name: this.virtualName,
37
+ dialect,
38
+ connection: name,
39
+ fields: [],
40
+ location: this.location,
41
+ };
42
+ (_c = this.document()) === null || _c === void 0 ? void 0 : _c.rememberToAddModelAnnotations(sourceDef);
43
+ return sourceDef;
44
+ }
45
+ }
46
+ exports.VirtualTableSource = VirtualTableSource;
47
+ //# sourceMappingURL=virtual-source.js.map
@@ -0,0 +1,29 @@
1
+ import type { Annotation, AtomicTypeDef, UserTypeFieldDef } from '../../../model/malloy_types';
2
+ import { ListOf, MalloyElement } from '../types/malloy-element';
3
+ import type { Noteable } from '../types/noteable';
4
+ import { extendNoteMethod } from '../types/noteable';
5
+ export declare abstract class UserTypeMember extends MalloyElement implements Noteable {
6
+ readonly name: string;
7
+ readonly isNoteableObj = true;
8
+ extendNote: typeof extendNoteMethod;
9
+ note?: Annotation;
10
+ constructor(name: string);
11
+ abstract userTypeFieldDef(): UserTypeFieldDef;
12
+ }
13
+ export declare class UserTypeMemberDef extends UserTypeMember {
14
+ readonly typeDef: AtomicTypeDef;
15
+ elementType: string;
16
+ constructor(name: string, typeDef: AtomicTypeDef);
17
+ userTypeFieldDef(): UserTypeFieldDef;
18
+ }
19
+ export declare class UserTypeMemberIndirect extends UserTypeMember {
20
+ readonly shapeName: string;
21
+ readonly arrayDepth: number;
22
+ elementType: string;
23
+ constructor(name: string, shapeName: string, arrayDepth?: number);
24
+ userTypeFieldDef(): UserTypeFieldDef;
25
+ }
26
+ export declare class UserTypeShape extends ListOf<UserTypeMember> {
27
+ elementType: string;
28
+ userTypeFieldDefs(): UserTypeFieldDef[];
29
+ }