@malloydata/malloy 0.0.237-dev250225015031 → 0.0.237-dev250225213433

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 (38) hide show
  1. package/dist/annotation.d.ts +15 -0
  2. package/dist/annotation.js +86 -0
  3. package/dist/index.d.ts +2 -1
  4. package/dist/index.js +5 -3
  5. package/dist/lang/ast/types/annotation-elements.d.ts +1 -1
  6. package/dist/lang/ast/types/annotation-elements.js +2 -2
  7. package/dist/lang/ast/types/malloy-element.d.ts +1 -1
  8. package/dist/lang/ast/types/malloy-element.js +2 -2
  9. package/dist/lang/malloy-to-ast.d.ts +1 -1
  10. package/dist/lang/malloy-to-ast.js +2 -2
  11. package/dist/lang/parse-malloy.d.ts +1 -1
  12. package/dist/lang/parse-malloy.js +4 -3
  13. package/dist/lang/parse-utils.d.ts +0 -11
  14. package/dist/lang/parse-utils.js +4 -82
  15. package/dist/lang/syntax-errors/custom-error-messages.d.ts +4 -2
  16. package/dist/lang/syntax-errors/custom-error-messages.js +75 -16
  17. package/dist/lang/syntax-errors/malloy-error-strategy.d.ts +4 -6
  18. package/dist/lang/syntax-errors/malloy-error-strategy.js +3 -22
  19. package/dist/lang/syntax-errors/malloy-parser-error-listener.d.ts +1 -1
  20. package/dist/lang/syntax-errors/malloy-parser-error-listener.js +107 -10
  21. package/dist/lang/test/literals.spec.js +0 -34
  22. package/dist/lang/test/syntax-errors.spec.js +113 -59
  23. package/dist/malloy.d.ts +13 -8
  24. package/dist/malloy.js +23 -23
  25. package/dist/model/malloy_query.d.ts +3 -1
  26. package/dist/model/malloy_query.js +18 -3
  27. package/dist/model/materialization/utils.js +2 -2
  28. package/dist/to_stable.d.ts +3 -0
  29. package/dist/to_stable.js +170 -0
  30. package/package.json +3 -1
  31. package/dist/lang/lib/Malloy/MalloyTagLexer.d.ts +0 -42
  32. package/dist/lang/lib/Malloy/MalloyTagLexer.js +0 -385
  33. package/dist/lang/lib/Malloy/MalloyTagParser.d.ts +0 -180
  34. package/dist/lang/lib/Malloy/MalloyTagParser.js +0 -1051
  35. package/dist/lang/lib/Malloy/MalloyTagVisitor.d.ts +0 -120
  36. package/dist/lang/lib/Malloy/MalloyTagVisitor.js +0 -4
  37. package/dist/tags.d.ts +0 -72
  38. package/dist/tags.js +0 -512
@@ -6,11 +6,19 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.MalloyParserErrorListener = exports.commonErrorCases = void 0;
9
+ exports.MalloyParserErrorListener = exports.malloyCustomErrorCases = void 0;
10
10
  const MalloyParser_1 = require("../lib/Malloy/MalloyParser");
11
11
  const custom_error_messages_1 = require("./custom-error-messages");
12
12
  const parse_log_1 = require("../parse-log");
13
- exports.commonErrorCases = [
13
+ // A set of custom error messages and their triggering cases,
14
+ // used for syntax error message re-writing when ANTLR would
15
+ // otherwise print a standard (and not very useful) error message.
16
+ //
17
+ // Most Malloy errors are detected and generated in language elements
18
+ // inside `src/lang/ast`. These custom error messages are used to
19
+ // cover a variety of cases that are not as straightforward to
20
+ // catch in the AST.
21
+ exports.malloyCustomErrorCases = [
14
22
  {
15
23
  errorMessage: "'view:' must be followed by '<identifier> is {'",
16
24
  ruleContextOptions: ['exploreQueryDef'],
@@ -18,7 +26,7 @@ exports.commonErrorCases = [
18
26
  precedingTokenOptions: [[MalloyParser_1.MalloyParser.VIEW], [MalloyParser_1.MalloyParser.COLON]],
19
27
  },
20
28
  {
21
- errorMessage: "Missing '}' at '${currentToken}'",
29
+ errorMessage: "Missing '}' at '${offendingSymbol}'",
22
30
  ruleContextOptions: ['vExpr'],
23
31
  offendingSymbol: MalloyParser_1.MalloyParser.VIEW,
24
32
  currentToken: MalloyParser_1.MalloyParser.OCURLY,
@@ -30,17 +38,106 @@ exports.commonErrorCases = [
30
38
  'queryProperties',
31
39
  'exploreStatement',
32
40
  ],
33
- lookAheadOptions: [
34
- [MalloyParser_1.MalloyParser.EOF],
35
- [MalloyParser_1.MalloyParser.RUN],
36
- [MalloyParser_1.MalloyParser.SOURCE],
37
- ],
41
+ offendingSymbolTextOptions: ['<eof>', 'run:', 'source:'],
38
42
  },
39
43
  {
40
44
  errorMessage: "'aggregate:' entries must include a name (ex: `some_name is count()`)",
41
45
  precedingTokenOptions: [[MalloyParser_1.MalloyParser.AGGREGATE]],
42
46
  lookAheadOptions: [[-MalloyParser_1.MalloyParser.IS]],
43
- lookbackFromOffendingSymbol: true,
47
+ },
48
+ {
49
+ errorMessage: "Expected ':' following 'source'",
50
+ offendingSymbol: MalloyParser_1.MalloyParser.SOURCE_KW,
51
+ ruleContextOptions: ['malloyDocument'],
52
+ },
53
+ {
54
+ errorMessage: "Expected ':' following '${offendingSymbol}'",
55
+ offendingSymbolTextOptions: [
56
+ 'dimension',
57
+ 'measure',
58
+ 'where',
59
+ 'declare',
60
+ 'join_one',
61
+ 'join_many',
62
+ 'join_cross',
63
+ 'primary_key',
64
+ ],
65
+ ruleContextOptions: ['exploreStatement'],
66
+ },
67
+ {
68
+ errorMessage: "Expected 'is' or '(' following identifier '${previousToken}'",
69
+ ruleContextOptions: ['sourceDefinition'],
70
+ lookbackSiblingRuleOptions: [
71
+ MalloyParser_1.MalloyParser.RULE_sourceNameDef,
72
+ MalloyParser_1.MalloyParser.RULE_sourceParameters,
73
+ ],
74
+ },
75
+ {
76
+ errorMessage: "Unexpected '{' following source expression. Expected: 'extend', 'include', '+' or '->'",
77
+ offendingSymbol: MalloyParser_1.MalloyParser.OCURLY,
78
+ ruleContextOptions: ['malloyDocument'],
79
+ predecessorHasAncestorRule: MalloyParser_1.MalloyParser.RULE_sqExplore,
80
+ },
81
+ {
82
+ errorMessage: "Unexpected 'join:'. Did you mean 'join_one:', 'join_many:' or 'join_cross:'?",
83
+ ruleContextOptions: ['exploreStatement'],
84
+ offendingSymbolTextOptions: ['join'],
85
+ lookAheadOptions: [[MalloyParser_1.MalloyParser.COLON]],
86
+ },
87
+ {
88
+ errorMessage: "Unexpected '${offendingSymbol}'. Did you mean 'primary_key:'?",
89
+ ruleContextOptions: ['exploreStatement'],
90
+ offendingSymbolTextOptions: ['primarykey', 'primary'],
91
+ lookAheadOptions: [
92
+ [MalloyParser_1.MalloyParser.COLON],
93
+ ['key', MalloyParser_1.MalloyParser.COLON],
94
+ ['key', MalloyParser_1.MalloyParser.IDENTIFIER],
95
+ ],
96
+ },
97
+ {
98
+ errorMessage: "Unexpected '${offendingSymbol}'. Did you mean 'group_by:'?",
99
+ ruleContextOptions: ['queryStatement'],
100
+ offendingSymbolTextOptions: ['groupby', 'group'],
101
+ lookAheadOptions: [
102
+ [MalloyParser_1.MalloyParser.COLON],
103
+ ['by', MalloyParser_1.MalloyParser.COLON],
104
+ ['by', MalloyParser_1.MalloyParser.IDENTIFIER],
105
+ ],
106
+ },
107
+ {
108
+ errorMessage: "Unexpected '${offendingSymbol}'. Did you mean 'order_by:'?",
109
+ ruleContextOptions: ['queryStatement'],
110
+ offendingSymbolTextOptions: ['orderby', 'order'],
111
+ lookAheadOptions: [
112
+ [MalloyParser_1.MalloyParser.COLON],
113
+ ['by', MalloyParser_1.MalloyParser.COLON],
114
+ ['by', MalloyParser_1.MalloyParser.IDENTIFIER],
115
+ ],
116
+ },
117
+ {
118
+ errorMessage: "Expected ':' following '${offendingSymbol}'",
119
+ offendingSymbolTextOptions: [
120
+ 'group_by',
121
+ 'declare',
122
+ 'join_one',
123
+ 'join_many',
124
+ 'join_cross',
125
+ 'extend',
126
+ 'select',
127
+ 'project',
128
+ 'index',
129
+ 'aggregate',
130
+ 'calculate',
131
+ 'top',
132
+ 'limit',
133
+ 'order_by',
134
+ 'where',
135
+ 'having',
136
+ 'nest',
137
+ 'sample',
138
+ 'timezone',
139
+ ],
140
+ ruleContextOptions: ['queryStatement'],
44
141
  },
45
142
  ];
46
143
  class MalloyParserErrorListener {
@@ -57,7 +154,7 @@ class MalloyParserErrorListener {
57
154
  const range = offendingSymbol
58
155
  ? this.translator.rangeFromToken(offendingSymbol)
59
156
  : { start: errAt, end: errAt };
60
- const overrideMessage = (0, custom_error_messages_1.checkCustomErrorMessage)(recognizer, offendingSymbol, exports.commonErrorCases);
157
+ const overrideMessage = (0, custom_error_messages_1.checkCustomErrorMessage)(recognizer, offendingSymbol, exports.malloyCustomErrorCases);
61
158
  if (overrideMessage) {
62
159
  message = overrideMessage;
63
160
  }
@@ -23,7 +23,6 @@
23
23
  */
24
24
  Object.defineProperty(exports, "__esModule", { value: true });
25
25
  const test_translator_1 = require("./test-translator");
26
- const parse_utils_1 = require("../parse-utils");
27
26
  require("./parse-expects");
28
27
  const granular_result_1 = require("../ast/types/granular-result");
29
28
  describe('literals', () => {
@@ -154,39 +153,6 @@ describe('literals', () => {
154
153
  test('regex', () => {
155
154
  expect((0, test_translator_1.expr) `r'RegularExpression'`).toTranslate();
156
155
  });
157
- describe('quote comprehension inside strings', () => {
158
- test('\\b', () => {
159
- expect((0, parse_utils_1.parseString)('\\b')).toEqual('\b');
160
- });
161
- test('\\f', () => {
162
- expect((0, parse_utils_1.parseString)('\\f')).toEqual('\f');
163
- });
164
- test('\\n', () => {
165
- expect((0, parse_utils_1.parseString)('\\n')).toEqual('\n');
166
- });
167
- test('\\r', () => {
168
- expect((0, parse_utils_1.parseString)('\\r')).toEqual('\r');
169
- });
170
- test('\\t', () => {
171
- expect((0, parse_utils_1.parseString)('\\t')).toEqual('\t');
172
- });
173
- test('unicode ?', () => {
174
- expect((0, parse_utils_1.parseString)('\\u003f')).toEqual('?');
175
- expect((0, parse_utils_1.parseString)('\\u003F')).toEqual('?');
176
- });
177
- test('normal stuff', () => {
178
- expect((0, parse_utils_1.parseString)('normal stuff')).toEqual('normal stuff');
179
- });
180
- test('stuff & nonsense', () => {
181
- expect((0, parse_utils_1.parseString)('stuff \\u0026 nonsense')).toEqual('stuff & nonsense');
182
- });
183
- test('one thing\\nnext thing', () => {
184
- expect((0, parse_utils_1.parseString)('one thing\\nnext thing')).toEqual('one thing\nnext thing');
185
- });
186
- test('quote stripping works', () => {
187
- expect((0, parse_utils_1.parseString)('|42|', '|')).toEqual('42');
188
- });
189
- });
190
156
  describe('string parsing in language', () => {
191
157
  const tz = 'America/Mexico_City';
192
158
  test('multi-line indent increasing', () => {
@@ -8,62 +8,91 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  const test_translator_1 = require("./test-translator");
10
10
  require("./parse-expects");
11
- describe('errors', () => {
12
- test('source missing closing curly: EOF', () => {
13
- expect('source: x is a extend {').toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at '<EOF>'"));
11
+ /**
12
+ * Unit tests intended to cover the custom error messages defined in
13
+ * malloy-custom-error-messages.ts.
14
+ *
15
+ * These tests are intended to prevent unintended regressions. It is
16
+ * okay to change or remove tests here as long as you are doing so
17
+ * for a good reason.
18
+ */
19
+ describe('custom error messages', () => {
20
+ describe('source', () => {
21
+ test('missing alias', () => {
22
+ expect('source: x extend { }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected 'is' or '(' following identifier 'x'"));
23
+ });
24
+ test('missing closing curly: EOF', () => {
25
+ expect('source: x is a extend {').toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at '<EOF>'"));
26
+ });
27
+ test('source: missing colon in root context', () => {
28
+ expect('source x is a extend { }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'source'"));
29
+ });
30
+ test('opening curly to EOF', () => {
31
+ expect(`
32
+ source: y is x extend {
33
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at '<EOF>'"));
34
+ });
35
+ test('expression missing operand before curly', () => {
36
+ expect("source: a is presto.table('malloytest.state_facts') {}").toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected '{' following source expression. Expected: 'extend', 'include', '+' or '->'"));
37
+ });
38
+ test('missing opening curly after source extend keyword', () => {
39
+ expect(`
40
+ source: x is a extend
41
+ primary_key: id
42
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("missing '{' at 'primary_key:'"));
43
+ });
14
44
  });
15
- test('view is missing name', () => {
16
- expect(`
17
- source: x is a extend {
18
- view: {
19
- group_by: b
45
+ describe('exploreProperties', () => {
46
+ test('misspelled "join"', () => {
47
+ expect(`source: x is a extend {
48
+ join: data is y on dataId = data.id
49
+ }`).toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'join:'. Did you mean 'join_one:', 'join_many:' or 'join_cross:'?"));
50
+ expect(`source: x is a extend {
51
+ primary_key: name
52
+ join: data is y on dataId = data.id
53
+ }`).toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'join:'. Did you mean 'join_one:', 'join_many:' or 'join_cross:'?"));
54
+ });
55
+ test('misspelled "primary_key:"', () => {
56
+ expect('source: x is a extend { primaryKey: name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'primaryKey'. Did you mean 'primary_key:'?"));
57
+ expect('source: x is a extend { primary key: name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'primary'. Did you mean 'primary_key:'?"));
58
+ });
59
+ test('explore statement keyword missing colon', () => {
60
+ expect('source: x is a extend { where x > 5 }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'where'"));
61
+ expect('source: x is a extend { primary_key name }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'primary_key'"));
62
+ expect('source: x is a extend { declare total is value.sum() }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'declare'"));
63
+ });
64
+ test('incorrect opening curly after dimension', () => {
65
+ expect(`
66
+ source: x is a extend {
67
+ dimension: {
68
+ test is best
69
+ }
20
70
  }
21
- }
22
- `).toLogAtLeast((0, test_translator_1.errorMessage)("'view:' must be followed by '<identifier> is {'"));
71
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("extraneous input '{' expecting {BQ_STRING, IDENTIFIER}"));
72
+ });
23
73
  });
24
- test('missing closing curly, source>view', () => {
25
- expect(`
26
- source: x is a extend {
27
- view: y is {
28
- group_by: b
74
+ describe('view', () => {
75
+ test('view is missing name', () => {
76
+ expect(`
77
+ source: x is a extend { view: {
78
+ group_by: b
79
+ } }
80
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("'view:' must be followed by '<identifier> is {'"));
81
+ });
82
+ test('missing closing curly, source>view', () => {
83
+ expect(`
84
+ source: x is a extend {
85
+ view: y is {
86
+ group_by: b
29
87
 
30
- view: z is {
31
- group_by: c
32
- }
33
- }
34
- `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at 'view:'"));
35
- });
36
- test('incorrect opening curly after dimension', () => {
37
- expect(`
38
- source: x is a extend {
39
- dimension: {
40
- test is best
88
+ view: z is {
89
+ group_by: c
90
+ }
41
91
  }
42
- }
43
- `).toLogAtLeast((0, test_translator_1.errorMessage)("extraneous input '{' expecting {BQ_STRING, IDENTIFIER}"));
44
- });
45
- test('misspelled primarykey', () => {
46
- expect(`
47
- source: x is a extend {
48
- primarykey: id
49
- }
50
- `).toLogAtLeast((0, test_translator_1.errorMessage)("no viable alternative at input 'primarykey'"));
51
- });
52
- test('missing opening curly after source extend keyword', () => {
53
- expect(`
54
- source: x is a extend
55
- primary_key: id
56
- `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '{' after 'extend'"));
57
- });
58
- test('missing alias for aggregate entry', () => {
59
- expect(`
60
- run: x -> {
61
- aggregate: count()
62
- }
63
- `).toLogAtLeast((0, test_translator_1.errorMessage)("'aggregate:' entries must include a name (ex: `some_name is count()`)"));
64
- });
65
- test('missing alias for aggregate inside source>view', () => {
66
- expect(`
92
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at 'view:'"));
93
+ });
94
+ test('missing alias for aggregate inside source>view', () => {
95
+ expect(`
67
96
  source: x is aa extend {
68
97
  measure: airport_count is count()
69
98
 
@@ -73,16 +102,41 @@ describe('errors', () => {
73
102
  }
74
103
  }
75
104
  `).toLogAtLeast((0, test_translator_1.errorMessage)("'aggregate:' entries must include a name (ex: `some_name is count()`)"));
105
+ });
76
106
  });
77
- test('run opening curly to EOF', () => {
78
- expect(`
79
- run: x -> {
80
- `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at '<EOF>'"));
107
+ describe('queryStatement', () => {
108
+ test('misspelled group_by:', () => {
109
+ expect('source: x is a -> { groupBy: name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'groupBy'. Did you mean 'group_by:'?"));
110
+ expect('source: x is a -> { group by: name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'group'. Did you mean 'group_by:'?"));
111
+ expect('source: x is a -> { group by name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'group'. Did you mean 'group_by:'?"));
112
+ });
113
+ test('misspelled order_by:', () => {
114
+ expect('source: x is a -> { orderBy: name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'orderBy'. Did you mean 'order_by:'?"));
115
+ expect('source: x is a -> { order by: name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'order'. Did you mean 'order_by:'?"));
116
+ expect('source: x is a -> { order by name }').toLogAtLeast((0, test_translator_1.errorMessage)("Unexpected 'order'. Did you mean 'order_by:'?"));
117
+ });
118
+ test('query statement keyword missing colon', () => {
119
+ expect('source: x is a -> { group_by x > 5 }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'group_by'"));
120
+ expect('source: x is a -> { declare name is id }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'declare'"));
121
+ expect('source: x is a -> { select * }').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'select'"));
122
+ expect('source: x is a -> { project i, j, k}').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'project'"));
123
+ expect('source: x is a -> { where val > 5}').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'where'"));
124
+ expect('source: x is a -> { order_by name desc, 2 asc}').toLogAtLeast((0, test_translator_1.errorMessage)("Expected ':' following 'order_by'"));
125
+ });
81
126
  });
82
- test('source opening curly to EOF', () => {
83
- expect(`
84
- source: y is x extend {
85
- `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at '<EOF>'"));
127
+ describe('run', () => {
128
+ test('missing alias for aggregate entry', () => {
129
+ expect(`
130
+ run: x -> {
131
+ aggregate: count()
132
+ }
133
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("'aggregate:' entries must include a name (ex: `some_name is count()`)"));
134
+ });
135
+ test('run opening curly to EOF', () => {
136
+ expect(`
137
+ run: x -> {
138
+ `).toLogAtLeast((0, test_translator_1.errorMessage)("Missing '}' at '<EOF>'"));
139
+ });
86
140
  });
87
141
  });
88
142
  //# sourceMappingURL=syntax-errors.spec.js.map
package/dist/malloy.d.ts CHANGED
@@ -6,9 +6,14 @@ import { DocumentHelpContext } from './lang/parse-tree-walkers/document-help-con
6
6
  import { CompiledQuery, DocumentLocation, DocumentReference, BooleanFieldDef, JSONFieldDef, NumberFieldDef, StringFieldDef, FilterCondition, Query as InternalQuery, ModelDef, DocumentPosition as ModelDocumentPosition, NamedQuery, QueryData, QueryDataRow, QueryResult, SearchIndexResult, SearchValueMapResult, StructDef, TurtleDef, NativeUnsupportedFieldDef, QueryRunStats, ImportLocation, Annotation, SQLSentence, SQLSourceDef, AtomicFieldDef, DateFieldDef, TimestampFieldDef, SourceDef, QueryToMaterialize } from './model';
7
7
  import { EventStream, InvalidationKey, ModelString, ModelURL, QueryString, QueryURL, URLReader } from './runtime_types';
8
8
  import { Connection, FetchSchemaOptions, InfoConnection, LookupConnection } from './connection/types';
9
- import { Tag, TagParse, TagParseSpec, Taggable } from './tags';
9
+ import { Tag } from '@malloydata/malloy-tag';
10
10
  import { Dialect } from './dialect';
11
11
  import { PathInfo } from './lang/parse-tree-walkers/find-table-path-walker';
12
+ import { MalloyTagParse, TagParseSpec } from './annotation';
13
+ export interface Taggable {
14
+ tagParse: (spec?: TagParseSpec) => MalloyTagParse;
15
+ getTaglines: (prefix?: RegExp) => string[];
16
+ }
12
17
  export interface Loggable {
13
18
  debug: (message?: any, ...optionalParams: any[]) => void;
14
19
  info: (message?: any, ...optionalParams: any[]) => void;
@@ -185,7 +190,7 @@ export declare class Model implements Taggable {
185
190
  _referenceAt: (location: ModelDocumentPosition) => DocumentReference | undefined;
186
191
  _importAt: (location: ModelDocumentPosition) => ImportLocation | undefined;
187
192
  constructor(modelDef: ModelDef, problems: LogMessage[], fromSources: string[], referenceAt?: (location: ModelDocumentPosition) => DocumentReference | undefined, importAt?: (location: ModelDocumentPosition) => ImportLocation | undefined);
188
- tagParse(spec?: TagParseSpec): TagParse;
193
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
189
194
  getTaglines(prefix?: RegExp): string[];
190
195
  /**
191
196
  * Retrieve a document reference for the token at the given position within
@@ -260,7 +265,7 @@ export declare class PreparedQuery implements Taggable {
260
265
  _modelDef: ModelDef;
261
266
  _query: InternalQuery | NamedQuery;
262
267
  constructor(query: InternalQuery, model: ModelDef, problems: LogMessage[], name?: string | undefined);
263
- tagParse(spec?: TagParseSpec): TagParse;
268
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
264
269
  getTaglines(prefix?: RegExp): string[];
265
270
  /**
266
271
  * Generate the SQL for this query.
@@ -457,7 +462,7 @@ export declare class PreparedResult implements Taggable {
457
462
  protected inner: CompiledQuery;
458
463
  constructor(query: CompiledQuery, modelDef: ModelDef);
459
464
  static fromJson({ query, modelDef, }: PreparedResultJSON): PreparedResult;
460
- tagParse(spec?: TagParseSpec): TagParse;
465
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
461
466
  getTaglines(prefix?: RegExp): string[];
462
467
  get annotation(): Annotation | undefined;
463
468
  get modelAnnotation(): Annotation | undefined;
@@ -587,7 +592,7 @@ export declare class Explore extends Entity implements Taggable {
587
592
  get source(): Explore | undefined;
588
593
  isIntrinsic(): boolean;
589
594
  isExploreField(): this is ExploreField;
590
- tagParse(spec?: TagParseSpec): TagParse;
595
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
591
596
  getTaglines(prefix?: RegExp): string[];
592
597
  private parsedModelTag?;
593
598
  get modelTag(): Tag;
@@ -632,7 +637,7 @@ export declare class AtomicField extends Entity implements Taggable {
632
637
  protected parent: Explore;
633
638
  constructor(fieldTypeDef: AtomicFieldDef, parent: Explore, source?: AtomicField);
634
639
  get type(): AtomicFieldType;
635
- tagParse(spec?: TagParseSpec): TagParse;
640
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
636
641
  getTaglines(prefix?: RegExp): string[];
637
642
  isIntrinsic(): boolean;
638
643
  isQueryField(): this is QueryField;
@@ -723,7 +728,7 @@ export declare class Query extends Entity {
723
728
  export declare class QueryField extends Query implements Taggable {
724
729
  protected parent: Explore;
725
730
  constructor(turtleDef: TurtleDef, parent: Explore, source?: Query);
726
- tagParse(spec?: TagParseSpec): TagParse;
731
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
727
732
  getTaglines(prefix?: RegExp): string[];
728
733
  isQueryField(): this is QueryField;
729
734
  isExploreField(): this is ExploreField;
@@ -744,7 +749,7 @@ export declare class ExploreField extends Explore {
744
749
  get joinRelationship(): JoinRelationship;
745
750
  get isRecord(): boolean;
746
751
  get isArray(): boolean;
747
- tagParse(spec?: TagParseSpec): TagParse;
752
+ tagParse(spec?: TagParseSpec): MalloyTagParse;
748
753
  isQueryField(): this is QueryField;
749
754
  isExploreField(): this is ExploreField;
750
755
  isAtomicField(): this is AtomicField;
package/dist/malloy.js CHANGED
@@ -26,10 +26,10 @@ exports.InMemoryModelCache = exports.CacheManager = exports.CSVWriter = exports.
26
26
  const lang_1 = require("./lang");
27
27
  const model_1 = require("./model");
28
28
  const luxon_1 = require("luxon");
29
- const tags_1 = require("./tags");
30
29
  const dialect_1 = require("./dialect");
31
30
  const version_1 = require("./version");
32
31
  const uuid_1 = require("uuid");
32
+ const annotation_1 = require("./annotation");
33
33
  const MALLOY_INTERNAL_URL = 'internal://internal.malloy';
34
34
  class Malloy {
35
35
  static get version() {
@@ -446,10 +446,10 @@ class Model {
446
446
  this._importAt = importAt;
447
447
  }
448
448
  tagParse(spec) {
449
- return tags_1.Tag.annotationToTag(this.modelDef.annotation, spec);
449
+ return (0, annotation_1.annotationToTag)(this.modelDef.annotation, spec);
450
450
  }
451
451
  getTaglines(prefix) {
452
- return tags_1.Tag.annotationToTaglines(this.modelDef.annotation, prefix);
452
+ return (0, annotation_1.annotationToTaglines)(this.modelDef.annotation, prefix);
453
453
  }
454
454
  /**
455
455
  * Retrieve a document reference for the token at the given position within
@@ -569,12 +569,12 @@ class PreparedQuery {
569
569
  this._modelDef = model;
570
570
  }
571
571
  tagParse(spec) {
572
- const modelScope = tags_1.Tag.annotationToTag(this._modelDef.annotation).tag;
573
- spec = tags_1.Tag.addModelScope(spec, modelScope);
574
- return tags_1.Tag.annotationToTag(this._query.annotation, spec);
572
+ const modelScope = (0, annotation_1.annotationToTag)(this._modelDef.annotation).tag;
573
+ spec = (0, annotation_1.addModelScope)(spec, modelScope);
574
+ return (0, annotation_1.annotationToTag)(this._query.annotation, spec);
575
575
  }
576
576
  getTaglines(prefix) {
577
- return tags_1.Tag.annotationToTaglines(this._query.annotation, prefix);
577
+ return (0, annotation_1.annotationToTaglines)(this._query.annotation, prefix);
578
578
  }
579
579
  /**
580
580
  * Generate the SQL for this query.
@@ -831,12 +831,12 @@ class PreparedResult {
831
831
  return new PreparedResult(query, modelDef);
832
832
  }
833
833
  tagParse(spec) {
834
- const modelScope = tags_1.Tag.annotationToTag(this.modelDef.annotation).tag;
835
- spec = tags_1.Tag.addModelScope(spec, modelScope);
836
- return tags_1.Tag.annotationToTag(this.inner.annotation, spec);
834
+ const modelScope = (0, annotation_1.annotationToTag)(this.modelDef.annotation).tag;
835
+ spec = (0, annotation_1.addModelScope)(spec, modelScope);
836
+ return (0, annotation_1.annotationToTag)(this.inner.annotation, spec);
837
837
  }
838
838
  getTaglines(prefix) {
839
- return tags_1.Tag.annotationToTaglines(this.inner.annotation, prefix);
839
+ return (0, annotation_1.annotationToTaglines)(this.inner.annotation, prefix);
840
840
  }
841
841
  get annotation() {
842
842
  return this.inner.annotation;
@@ -845,7 +845,7 @@ class PreparedResult {
845
845
  return this.modelDef.annotation;
846
846
  }
847
847
  get modelTag() {
848
- return tags_1.Tag.annotationToTag(this.modelDef.annotation).tag;
848
+ return (0, annotation_1.annotationToTag)(this.modelDef.annotation).tag;
849
849
  }
850
850
  /**
851
851
  * @return The name of the connection this query should be run against.
@@ -1096,13 +1096,13 @@ class Explore extends Entity {
1096
1096
  return false;
1097
1097
  }
1098
1098
  tagParse(spec) {
1099
- return tags_1.Tag.annotationToTag(this._structDef.annotation, spec);
1099
+ return (0, annotation_1.annotationToTag)(this._structDef.annotation, spec);
1100
1100
  }
1101
1101
  getTaglines(prefix) {
1102
- return tags_1.Tag.annotationToTaglines(this._structDef.annotation, prefix);
1102
+ return (0, annotation_1.annotationToTaglines)(this._structDef.annotation, prefix);
1103
1103
  }
1104
1104
  get modelTag() {
1105
- this.parsedModelTag || (this.parsedModelTag = tags_1.Tag.annotationToTag(this._structDef.modelAnnotation).tag);
1105
+ this.parsedModelTag || (this.parsedModelTag = (0, annotation_1.annotationToTag)(this._structDef.modelAnnotation).tag);
1106
1106
  return this.parsedModelTag;
1107
1107
  }
1108
1108
  /**
@@ -1343,11 +1343,11 @@ class AtomicField extends Entity {
1343
1343
  }
1344
1344
  }
1345
1345
  tagParse(spec) {
1346
- spec = tags_1.Tag.addModelScope(spec, this.parent.modelTag);
1347
- return tags_1.Tag.annotationToTag(this.fieldTypeDef.annotation, spec);
1346
+ spec = (0, annotation_1.addModelScope)(spec, this.parent.modelTag);
1347
+ return (0, annotation_1.annotationToTag)(this.fieldTypeDef.annotation, spec);
1348
1348
  }
1349
1349
  getTaglines(prefix) {
1350
- return tags_1.Tag.annotationToTaglines(this.fieldTypeDef.annotation, prefix);
1350
+ return (0, annotation_1.annotationToTaglines)(this.fieldTypeDef.annotation, prefix);
1351
1351
  }
1352
1352
  isIntrinsic() {
1353
1353
  return (0, model_1.fieldIsIntrinsic)(this.fieldTypeDef);
@@ -1573,11 +1573,11 @@ class QueryField extends Query {
1573
1573
  this.parent = parent;
1574
1574
  }
1575
1575
  tagParse(spec) {
1576
- spec = tags_1.Tag.addModelScope(spec, this.parent.modelTag);
1577
- return tags_1.Tag.annotationToTag(this.turtleDef.annotation, spec);
1576
+ spec = (0, annotation_1.addModelScope)(spec, this.parent.modelTag);
1577
+ return (0, annotation_1.annotationToTag)(this.turtleDef.annotation, spec);
1578
1578
  }
1579
1579
  getTaglines(prefix) {
1580
- return tags_1.Tag.annotationToTaglines(this.turtleDef.annotation, prefix);
1580
+ return (0, annotation_1.annotationToTaglines)(this.turtleDef.annotation, prefix);
1581
1581
  }
1582
1582
  isQueryField() {
1583
1583
  return true;
@@ -1633,8 +1633,8 @@ class ExploreField extends Explore {
1633
1633
  return this.joinRelationship !== JoinRelationship.OneToOne;
1634
1634
  }
1635
1635
  tagParse(spec) {
1636
- spec = tags_1.Tag.addModelScope(spec, this._parentExplore.modelTag);
1637
- return tags_1.Tag.annotationToTag(this._structDef.annotation, spec);
1636
+ spec = (0, annotation_1.addModelScope)(spec, this._parentExplore.modelTag);
1637
+ return (0, annotation_1.annotationToTag)(this._structDef.annotation, spec);
1638
1638
  }
1639
1639
  isQueryField() {
1640
1640
  return false;
@@ -4,7 +4,7 @@ import { Connection } from '../connection/types';
4
4
  import { AndChain } from './utils';
5
5
  import { QueryInfo } from '../dialect/dialect';
6
6
  import { EventStream } from '../runtime_types';
7
- import { Tag } from '../tags';
7
+ import { Tag } from '@malloydata/malloy-tag';
8
8
  interface TurtleDefPlus extends TurtleDef, Filtered {
9
9
  }
10
10
  /** Parent from QueryStruct. */
@@ -225,6 +225,8 @@ declare class JoinInstance {
225
225
  export declare class Segment {
226
226
  static nextStructDef(structDef: SourceDef, segment: PipeSegment): QueryResultDef;
227
227
  }
228
+ export declare function getResultStructDefForView(source: SourceDef, view: TurtleDef): SourceDef;
229
+ export declare function getResultStructDefForQuery(model: ModelDef, query: Query): SourceDef;
228
230
  type StageGroupMaping = {
229
231
  fromGroup: number;
230
232
  toGroup: number;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryModel = exports.Segment = void 0;
3
+ exports.QueryModel = exports.getResultStructDefForQuery = exports.getResultStructDefForView = exports.Segment = void 0;
4
4
  /*
5
5
  * Copyright 2023 Google LLC
6
6
  *
@@ -29,7 +29,7 @@ const standardsql_1 = require("../dialect/standardsql/standardsql");
29
29
  const malloy_types_1 = require("./malloy_types");
30
30
  const utils_1 = require("./utils");
31
31
  const utils_2 = require("./materialization/utils");
32
- const tags_1 = require("../tags");
32
+ const annotation_1 = require("../annotation");
33
33
  function pathToCol(path) {
34
34
  return path.map(el => encodeURIComponent(el)).join('/');
35
35
  }
@@ -1564,6 +1564,21 @@ class Segment {
1564
1564
  }
1565
1565
  }
1566
1566
  exports.Segment = Segment;
1567
+ function getResultStructDefForView(source, view) {
1568
+ const qs = new QueryStruct(source, undefined, {
1569
+ model: new QueryModel(undefined),
1570
+ }, {});
1571
+ const queryQueryQuery = QueryQuery.makeQuery(view, qs, new StageWriter(true, undefined), // stage write indicates we want to get a result.
1572
+ false);
1573
+ return queryQueryQuery.getResultStructDef();
1574
+ }
1575
+ exports.getResultStructDefForView = getResultStructDefForView;
1576
+ function getResultStructDefForQuery(model, query) {
1577
+ const queryModel = new QueryModel(model);
1578
+ const compiled = queryModel.compileQuery(query);
1579
+ return compiled.structs[compiled.structs.length - 1];
1580
+ }
1581
+ exports.getResultStructDefForQuery = getResultStructDefForQuery;
1567
1582
  /** Query builder object. */
1568
1583
  class QueryQuery extends QueryField {
1569
1584
  constructor(fieldDef, parent, stageWriter, isJoinedSubquery) {
@@ -3087,7 +3102,7 @@ class QueryStruct {
3087
3102
  modelCompilerFlags() {
3088
3103
  if (this._modelTag === undefined) {
3089
3104
  const annotation = this.structDef.modelAnnotation;
3090
- const { tag } = tags_1.Tag.annotationToTag(annotation, { prefix: /^##!\s*/ });
3105
+ const { tag } = (0, annotation_1.annotationToTag)(annotation, { prefix: /^##!\s*/ });
3091
3106
  this._modelTag = tag;
3092
3107
  }
3093
3108
  return this._modelTag;