@malloydata/malloy 0.0.294 → 0.0.295

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export type { QueryOptionsReader, RunSQLOptions } from './run_sql_options';
10
10
  export type { EventStream, ModelString, ModelURL, QueryString, QueryURL, URLReader, InvalidationKey, } from './runtime_types';
11
11
  export type { Connection, ConnectionConfig, ConnectionFactory, ConnectionParameter, ConnectionParameterValue, ConnectionConfigSchema, FetchSchemaOptions, InfoConnection, LookupConnection, PersistSQLResults, PooledConnection, TestableConnection, StreamingConnection, } from './connection/types';
12
12
  export { toAsyncGenerator } from './connection_utils';
13
- export { modelDefToModelInfo, sourceDefToSourceInfo } from './to_stable';
13
+ export { modelDefToModelInfo, sourceDefToSourceInfo, writeMalloyObjectToTag, extractMalloyObjectFromTag, } from './to_stable';
14
14
  export * as API from './api';
15
15
  export type { SQLSourceRequest } from './lang/translate-response';
16
16
  export { sqlKey } from './model/sql_block';
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.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.malloyToQuery = 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.isBasicAtomic = exports.Segment = 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.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = 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 = void 0;
37
+ exports.annotationToTaglines = exports.annotationToTag = exports.sqlKey = exports.API = exports.extractMalloyObjectFromTag = exports.writeMalloyObjectToTag = exports.sourceDefToSourceInfo = exports.modelDefToModelInfo = exports.toAsyncGenerator = 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 = void 0;
38
38
  /*
39
39
  * Copyright 2023 Google LLC
40
40
  *
@@ -137,6 +137,8 @@ Object.defineProperty(exports, "toAsyncGenerator", { enumerable: true, get: func
137
137
  var to_stable_1 = require("./to_stable");
138
138
  Object.defineProperty(exports, "modelDefToModelInfo", { enumerable: true, get: function () { return to_stable_1.modelDefToModelInfo; } });
139
139
  Object.defineProperty(exports, "sourceDefToSourceInfo", { enumerable: true, get: function () { return to_stable_1.sourceDefToSourceInfo; } });
140
+ Object.defineProperty(exports, "writeMalloyObjectToTag", { enumerable: true, get: function () { return to_stable_1.writeMalloyObjectToTag; } });
141
+ Object.defineProperty(exports, "extractMalloyObjectFromTag", { enumerable: true, get: function () { return to_stable_1.extractMalloyObjectFromTag; } });
140
142
  exports.API = __importStar(require("./api"));
141
143
  var sql_block_1 = require("./model/sql_block");
142
144
  Object.defineProperty(exports, "sqlKey", { enumerable: true, get: function () { return sql_block_1.sqlKey; } });
@@ -3,6 +3,7 @@ import type { ExprValue } from '../types/expr-value';
3
3
  import { ExpressionDef } from '../types/expression-def';
4
4
  import type { FieldSpace } from '../types/field-space';
5
5
  import { Range } from './range';
6
+ import type * as Malloy from '@malloydata/malloy-interfaces';
6
7
  /**
7
8
  * GranularTime is a moment in time which ALSO has a "granularity"
8
9
  * commonly this are created by applying ".datePart" to an expression
@@ -18,6 +19,7 @@ export declare class ExprGranularTime extends ExpressionDef {
18
19
  legalChildTypes: import("../../../model/malloy_types").TypeDesc[];
19
20
  constructor(expr: ExpressionDef, units: TimestampUnit, truncate: boolean);
20
21
  granular(): boolean;
22
+ drillExpression(): Malloy.Expression | undefined;
21
23
  getExpression(fs: FieldSpace): ExprValue;
22
24
  toRange(fs: FieldSpace): Range;
23
25
  }
@@ -82,6 +82,19 @@ class ExprGranularTime extends expression_def_1.ExpressionDef {
82
82
  granular() {
83
83
  return true;
84
84
  }
85
+ drillExpression() {
86
+ const lhs = this.expr.drillExpression();
87
+ if ((lhs === null || lhs === void 0 ? void 0 : lhs.kind) !== 'field_reference')
88
+ return undefined;
89
+ return {
90
+ kind: 'time_truncation',
91
+ field_reference: {
92
+ name: lhs.name,
93
+ path: lhs.path,
94
+ },
95
+ truncation: this.units,
96
+ };
97
+ }
85
98
  getExpression(fs) {
86
99
  const timeframe = this.units;
87
100
  const exprVal = this.expr.getExpression(fs);
@@ -2,10 +2,12 @@ import type { ExprValue } from '../types/expr-value';
2
2
  import type { FieldReference } from '../query-items/field-references';
3
3
  import type { FieldSpace } from '../types/field-space';
4
4
  import { ExpressionDef } from '../types/expression-def';
5
+ import type * as Malloy from '@malloydata/malloy-interfaces';
5
6
  export declare class ExprIdReference extends ExpressionDef {
6
7
  readonly fieldReference: FieldReference;
7
8
  elementType: string;
8
9
  constructor(fieldReference: FieldReference);
9
10
  get refString(): string;
11
+ drillExpression(): Malloy.Expression | undefined;
10
12
  getExpression(fs: FieldSpace): ExprValue;
11
13
  }
@@ -35,6 +35,13 @@ class ExprIdReference extends expression_def_1.ExpressionDef {
35
35
  get refString() {
36
36
  return this.fieldReference.refString;
37
37
  }
38
+ drillExpression() {
39
+ return {
40
+ kind: 'field_reference',
41
+ name: this.fieldReference.nameString,
42
+ path: this.fieldReference.path.slice(0, -1),
43
+ };
44
+ }
38
45
  getExpression(fs) {
39
46
  const def = this.fieldReference.getField(fs);
40
47
  if (def.found) {
@@ -101,6 +101,11 @@ class ReferenceField extends space_field_1.SpaceField {
101
101
  type: 'fieldref',
102
102
  path,
103
103
  at: this.fieldRef.location,
104
+ drillExpression: {
105
+ kind: 'field_reference',
106
+ name: path[path.length - 1],
107
+ path: path.slice(0, -1),
108
+ },
104
109
  };
105
110
  }
106
111
  const refTo = this.referenceTo;
@@ -147,6 +147,7 @@ class AtomicFieldDeclaration extends malloy_element_1.MalloyElement {
147
147
  else {
148
148
  ret.e = exprValue.value;
149
149
  }
150
+ ret.drillExpression = this.expr.drillExpression();
150
151
  ret.fieldUsage = exprValue.fieldUsage;
151
152
  ret.ungroupings = exprValue.ungroupings;
152
153
  ret.requiresGroupBy = exprValue.requiresGroupBy;
@@ -1,4 +1,4 @@
1
- import type { Expr, FilterCondition, PipeSegment, TypeDesc } from '../../../model/malloy_types';
1
+ import type { Expr, FilterCondition, PipeSegment, TurtleDef, TypeDesc } from '../../../model/malloy_types';
2
2
  import type { FieldReference } from '../query-items/field-references';
3
3
  import type { ExprValue } from '../types/expr-value';
4
4
  import { ExpressionDef } from '../types/expression-def';
@@ -22,4 +22,5 @@ export declare class Drill extends Filter implements QueryPropertyInterface {
22
22
  protected checkedDrillCondition(fs: FieldSpace, filter: FilterElement, reference: FieldReference, value: Literal): FilterCondition | undefined;
23
23
  protected checkedFilterCondition(fs: FieldSpace, filter: FilterElement): FilterCondition | undefined;
24
24
  }
25
- export declare function attachDrillPaths(pipeline: PipeSegment[], name: string): PipeSegment[];
25
+ export declare function updateNestedDrillPaths(nest: TurtleDef, name: string): TurtleDef;
26
+ export declare function attachDrillPaths(pipeline: PipeSegment[], nestName: string): PipeSegment[];
@@ -7,6 +7,7 @@
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.Drill = exports.DrillField = void 0;
10
+ exports.updateNestedDrillPaths = updateNestedDrillPaths;
10
11
  exports.attachDrillPaths = attachDrillPaths;
11
12
  const composite_source_utils_1 = require("../../../model/composite_source_utils");
12
13
  const malloy_types_1 = require("../../../model/malloy_types");
@@ -292,7 +293,8 @@ class Drill extends filters_1.Filter {
292
293
  fieldUsage: (0, composite_source_utils_1.mergeFieldUsage)(fExpr.fieldUsage, collectedWhereFieldUsage),
293
294
  stableFilter: {
294
295
  kind: 'literal_equality',
295
- field_reference: {
296
+ expression: {
297
+ kind: 'field_reference',
296
298
  name: fieldName.refString,
297
299
  path: reference.list.slice(0, -1).map(f => f.name),
298
300
  },
@@ -312,7 +314,39 @@ class Drill extends filters_1.Filter {
312
314
  }
313
315
  }
314
316
  exports.Drill = Drill;
315
- function attachDrillPaths(pipeline, name) {
317
+ function updateNestedDrillPaths(nest, name) {
318
+ if (nest.pipeline.length !== 1 || !(0, malloy_types_1.isQuerySegment)(nest.pipeline[0])) {
319
+ return nest;
320
+ }
321
+ return {
322
+ ...nest,
323
+ pipeline: [
324
+ {
325
+ ...nest.pipeline[0],
326
+ queryFields: nest.pipeline[0].queryFields.map(f => {
327
+ var _a;
328
+ if (f.type === 'turtle') {
329
+ return updateNestedDrillPaths(f, name);
330
+ }
331
+ const existing = f.drillExpression;
332
+ if (existing === undefined)
333
+ return f;
334
+ if (existing.kind !== 'field_reference') {
335
+ return { ...f, drillExpression: undefined };
336
+ }
337
+ return {
338
+ ...f,
339
+ drillExpression: {
340
+ ...existing,
341
+ path: [name, ...((_a = existing.path) !== null && _a !== void 0 ? _a : [])],
342
+ },
343
+ };
344
+ }),
345
+ },
346
+ ],
347
+ };
348
+ }
349
+ function attachDrillPaths(pipeline, nestName) {
316
350
  var _a;
317
351
  if (pipeline.length !== 1)
318
352
  return pipeline;
@@ -323,12 +357,23 @@ function attachDrillPaths(pipeline, name) {
323
357
  ...pipeline[0],
324
358
  filterList: (_a = pipeline[0].filterList) === null || _a === void 0 ? void 0 : _a.map(f => ({
325
359
  ...f,
326
- drillView: name,
327
- })),
328
- queryFields: pipeline[0].queryFields.map(f => ({
329
- ...f,
330
- drillView: name,
360
+ filterView: nestName,
331
361
  })),
362
+ queryFields: pipeline[0].queryFields.map(f => {
363
+ var _a;
364
+ if (f.type === 'turtle') {
365
+ return updateNestedDrillPaths(f, nestName);
366
+ }
367
+ const fieldName = f.type === 'fieldref' ? f.path[f.path.length - 1] : (_a = f.as) !== null && _a !== void 0 ? _a : f.name;
368
+ return {
369
+ ...f,
370
+ drillExpression: {
371
+ kind: 'field_reference',
372
+ name: fieldName,
373
+ path: [nestName],
374
+ },
375
+ };
376
+ }),
332
377
  },
333
378
  ];
334
379
  }
@@ -39,28 +39,28 @@ class FilterElement extends malloy_element_1.MalloyElement {
39
39
  this.elementType = 'filterElement';
40
40
  }
41
41
  getStableFilter() {
42
- const drillFilter = this.drillFilter();
43
- if (drillFilter !== undefined) {
42
+ if (this.expr instanceof expr_compare_1.ExprEquality &&
43
+ this.expr.op === '=' &&
44
+ (0, literal_1.isLiteral)(this.expr.right)) {
45
+ const lhs = this.expr.left.drillExpression();
46
+ if (lhs === undefined)
47
+ return undefined;
44
48
  return {
45
49
  kind: 'literal_equality',
46
- field_reference: {
47
- name: drillFilter.reference.nameString,
48
- path: drillFilter.reference.list.map(f => f.name).slice(0, -1),
49
- },
50
- value: drillFilter.value.getStableLiteral(),
50
+ expression: lhs,
51
+ value: this.expr.right.getStableLiteral(),
51
52
  };
52
53
  }
53
- const filterExpressionFilter = this.filterExpressionFilter();
54
- if (filterExpressionFilter !== undefined) {
54
+ else if (this.expr instanceof expr_compare_1.ExprCompare &&
55
+ this.expr.op === '~' &&
56
+ this.expr.right instanceof expr_filter_expr_1.ExprFilterExpression) {
57
+ const lhs = this.expr.left.drillExpression();
58
+ if (lhs === undefined)
59
+ return undefined;
55
60
  return {
56
61
  kind: 'filter_string',
57
- field_reference: {
58
- name: filterExpressionFilter.reference.nameString,
59
- path: filterExpressionFilter.reference.list
60
- .map(f => f.name)
61
- .slice(0, -1),
62
- },
63
- filter: filterExpressionFilter.filterExpression,
62
+ expression: lhs,
63
+ filter: this.expr.right.filterText,
64
64
  };
65
65
  }
66
66
  return undefined;
@@ -1,3 +1,4 @@
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
1
2
  import type { Expr, TimestampUnit } from '../../../model/malloy_types';
2
3
  import type { ExprValue } from './expr-value';
3
4
  import type { FieldSpace } from './field-space';
@@ -42,6 +43,7 @@ export declare abstract class ExpressionDef extends MalloyElement {
42
43
  * @param eVal ...list of expressions that must match legalChildTypes
43
44
  */
44
45
  typeCheck(eNode: ExpressionDef, eVal: ExprValue): boolean;
46
+ drillExpression(): Malloy.Expression | undefined;
45
47
  /**
46
48
  * This is the operation which makes partial comparison and value trees work
47
49
  * The default implementation merely constructs LEFT OP RIGHT, but specialized
@@ -124,6 +124,9 @@ class ExpressionDef extends malloy_element_1.MalloyElement {
124
124
  }
125
125
  return true;
126
126
  }
127
+ drillExpression() {
128
+ return undefined;
129
+ }
127
130
  /**
128
131
  * This is the operation which makes partial comparison and value trees work
129
132
  * The default implementation merely constructs LEFT OP RIGHT, but specialized
@@ -736,7 +736,8 @@ class MalloyToQuery extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor
736
736
  return {
737
737
  filter: {
738
738
  kind: 'filter_string',
739
- field_reference: {
739
+ expression: {
740
+ kind: 'field_reference',
740
741
  name,
741
742
  path,
742
743
  },
@@ -759,7 +760,8 @@ class MalloyToQuery extends AbstractParseTreeVisitor_1.AbstractParseTreeVisitor
759
760
  return {
760
761
  filter: {
761
762
  kind: 'literal_equality',
762
- field_reference: {
763
+ expression: {
764
+ kind: 'field_reference',
763
765
  name,
764
766
  path,
765
767
  },
@@ -1,3 +1,4 @@
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
1
2
  import type { QueryInfo, Dialect, DialectFieldList } from '../dialect';
2
3
  import type { AggregateFunctionType, CompiledQuery, Expr, FieldDef, Filtered, FunctionOverloadDef, FunctionParameterDef, JoinRelationship, ModelDef, OrderBy, OutputFieldNode, ParameterNode, PipeSegment, Query, QueryFieldDef, QuerySegment, RefToField, ResultMetadataDef, ResultStructMetadataDef, SearchIndexResult, SegmentFieldDef, StructDef, StructRef, TurtleDef, FunctionOrderBy, Argument, AggregateExpr, FilterCondition, GenericSQLExpr, FieldnameNode, FunctionCallNode, UngroupNode, SourceReferenceNode, SpreadExpr, FilteredExpr, SourceDef, BooleanFieldDef, QueryResultDef, QueryToMaterialize, PrepareResultOptions, CaseExpr, BasicAtomicDef, AtomicFieldDef, FilterMatchExpr } from './malloy_types';
3
4
  import type { Connection } from '../connection/types';
@@ -126,11 +127,12 @@ declare class FieldInstanceField implements FieldInstance {
126
127
  f: QueryField;
127
128
  fieldUsage: FieldUsage;
128
129
  parent: FieldInstanceResult;
130
+ readonly drillExpression: Malloy.Expression | undefined;
129
131
  type: FieldInstanceType;
130
132
  additionalGroupSets: number[];
131
133
  analyticalSQL: string | undefined;
132
134
  partitionSQL: string | undefined;
133
- constructor(f: QueryField, fieldUsage: FieldUsage, parent: FieldInstanceResult);
135
+ constructor(f: QueryField, fieldUsage: FieldUsage, parent: FieldInstanceResult, drillExpression: Malloy.Expression | undefined);
134
136
  root(): FieldInstanceResultRoot;
135
137
  getSQL(): string;
136
138
  getAnalyticalSQL(forPartition: boolean): string;
@@ -161,7 +163,7 @@ declare class FieldInstanceResult implements FieldInstance {
161
163
  * @returns QueryInfo
162
164
  */
163
165
  getQueryInfo(): QueryInfo;
164
- addField(as: string, field: QueryField, usage: FieldUsage): void;
166
+ addField(as: string, field: QueryField, usage: FieldUsage, drillExpression: Malloy.Expression | undefined): void;
165
167
  parentGroupSet(): number;
166
168
  add(name: string, f: FieldInstance): void;
167
169
  hasField(name: string): boolean;
@@ -259,6 +261,7 @@ declare class QueryQuery extends QueryField {
259
261
  addDependantExpr(resultStruct: FieldInstanceResult, context: QueryStruct, e: Expr, joinStack: string[]): void;
260
262
  addDependancies(resultStruct: FieldInstanceResult, field: QueryField): void;
261
263
  getSegmentFields(resultStruct: FieldInstanceResult): SegmentFieldDef[];
264
+ private getDrillExpression;
262
265
  expandFields(resultStruct: FieldInstanceResult): void;
263
266
  expandFilters(resultStruct: FieldInstanceResult): void;
264
267
  generateSQLFilters(resultStruct: FieldInstanceResult, which: 'where' | 'having'): AndChain;
@@ -1,8 +1,4 @@
1
1
  "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryModel = exports.Segment = void 0;
4
- exports.getResultStructDefForView = getResultStructDefForView;
5
- exports.getResultStructDefForQuery = getResultStructDefForQuery;
6
2
  /*
7
3
  * Copyright 2023 Google LLC
8
4
  *
@@ -25,6 +21,10 @@ exports.getResultStructDefForQuery = getResultStructDefForQuery;
25
21
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
22
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
23
  */
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.QueryModel = exports.Segment = void 0;
26
+ exports.getResultStructDefForView = getResultStructDefForView;
27
+ exports.getResultStructDefForQuery = getResultStructDefForQuery;
28
28
  const uuid_1 = require("uuid");
29
29
  const dialect_1 = require("../dialect");
30
30
  const standardsql_1 = require("../dialect/standardsql/standardsql");
@@ -1124,10 +1124,11 @@ function sqlSumDistinct(dialect, sqlExp, sqlDistintKey) {
1124
1124
  return ret;
1125
1125
  }
1126
1126
  class FieldInstanceField {
1127
- constructor(f, fieldUsage, parent) {
1127
+ constructor(f, fieldUsage, parent, drillExpression) {
1128
1128
  this.f = f;
1129
1129
  this.fieldUsage = fieldUsage;
1130
1130
  this.parent = parent;
1131
+ this.drillExpression = drillExpression;
1131
1132
  this.type = 'field';
1132
1133
  this.additionalGroupSets = [];
1133
1134
  }
@@ -1186,7 +1187,7 @@ class FieldInstanceResult {
1186
1187
  }
1187
1188
  return {};
1188
1189
  }
1189
- addField(as, field, usage) {
1190
+ addField(as, field, usage, drillExpression) {
1190
1191
  const fi = this.allFields.get(as);
1191
1192
  if (fi) {
1192
1193
  if (fi.type === 'query') {
@@ -1203,7 +1204,7 @@ class FieldInstanceResult {
1203
1204
  }
1204
1205
  }
1205
1206
  }
1206
- this.add(as, new FieldInstanceField(field, usage, this));
1207
+ this.add(as, new FieldInstanceField(field, usage, this, drillExpression));
1207
1208
  }
1208
1209
  parentGroupSet() {
1209
1210
  if (this.parent) {
@@ -1828,10 +1829,16 @@ class QueryQuery extends QueryField {
1828
1829
  ? fs.queryFields
1829
1830
  : [];
1830
1831
  }
1832
+ getDrillExpression(f) {
1833
+ if ((0, malloy_types_1.isAtomic)(f) || f.type === 'fieldref')
1834
+ return f.drillExpression;
1835
+ return undefined;
1836
+ }
1831
1837
  expandFields(resultStruct) {
1832
1838
  let resultIndex = 1;
1833
1839
  for (const f of this.getSegmentFields(resultStruct)) {
1834
1840
  const { as, field } = this.expandField(f);
1841
+ const drillExpression = this.getDrillExpression(f);
1835
1842
  if (field instanceof QueryQuery) {
1836
1843
  if (this.firstSegment.type === 'project') {
1837
1844
  throw new Error(`Nested views cannot be used in select - '${field.fieldDef.name}'`);
@@ -1844,7 +1851,7 @@ class QueryQuery extends QueryField {
1844
1851
  resultStruct.addField(as, field, {
1845
1852
  resultIndex,
1846
1853
  type: 'result',
1847
- });
1854
+ }, drillExpression);
1848
1855
  this.addDependancies(resultStruct, field);
1849
1856
  if (isBasicAggregate(field)) {
1850
1857
  if (this.firstSegment.type === 'project') {
@@ -1859,7 +1866,7 @@ class QueryQuery extends QueryField {
1859
1866
  resultStruct.addField(as, field, {
1860
1867
  resultIndex,
1861
1868
  type: 'result',
1862
- });
1869
+ }, drillExpression);
1863
1870
  }
1864
1871
  // else if (
1865
1872
  // this.firstSegment.type === "project" &&
@@ -1950,11 +1957,13 @@ class QueryQuery extends QueryField {
1950
1957
  : undefined;
1951
1958
  const sourceClasses = [sourceField];
1952
1959
  const referenceId = fi.f.referenceId;
1960
+ const drillExpression = fi.drillExpression;
1953
1961
  const base = {
1954
1962
  sourceField,
1955
1963
  sourceExpression,
1956
1964
  sourceClasses,
1957
1965
  referenceId,
1966
+ drillExpression,
1958
1967
  };
1959
1968
  if (isBasicCalculation(fi.f)) {
1960
1969
  filterList = fi.f.getFilterList();
@@ -2020,7 +2029,6 @@ class QueryQuery extends QueryField {
2020
2029
  join: 'many',
2021
2030
  name,
2022
2031
  resultMetadata,
2023
- drillView: fi.turtleDef.drillView,
2024
2032
  };
2025
2033
  fields.push(multiLineNest);
2026
2034
  }
@@ -2031,7 +2039,6 @@ class QueryQuery extends QueryField {
2031
2039
  join: 'one',
2032
2040
  name,
2033
2041
  resultMetadata,
2034
- drillView: fi.turtleDef.drillView,
2035
2042
  };
2036
2043
  fields.push(oneLineNest);
2037
2044
  }
@@ -2060,12 +2067,10 @@ class QueryQuery extends QueryField {
2060
2067
  }
2061
2068
  const location = fOut.location;
2062
2069
  const annotation = fOut.annotation;
2063
- const drillView = (0, malloy_types_1.isAtomic)(fOut) || (0, malloy_types_1.isTurtle)(fOut) ? fOut.drillView : undefined;
2064
2070
  const common = {
2065
2071
  resultMetadata,
2066
2072
  location,
2067
2073
  annotation,
2068
- drillView,
2069
2074
  };
2070
2075
  // build out the result fields...
2071
2076
  switch (fOut.type) {
@@ -2835,7 +2840,6 @@ class QueryQuery extends QueryField {
2835
2840
  type: 'turtle',
2836
2841
  name: 'starthere',
2837
2842
  pipeline,
2838
- drillView: fi.turtleDef.drillView,
2839
2843
  };
2840
2844
  const inputStruct = {
2841
2845
  type: 'nest_source',
@@ -2942,11 +2946,12 @@ class QueryQueryIndexStage extends QueryQuery {
2942
2946
  this.maxGroupSet = groupIndex;
2943
2947
  for (const f of this.firstSegment.indexFields) {
2944
2948
  const { as, field } = this.expandField(f);
2945
- this.indexPaths[as] = f.path;
2949
+ const referencePath = f.path;
2950
+ this.indexPaths[as] = referencePath;
2946
2951
  resultStruct.addField(as, field, {
2947
2952
  resultIndex,
2948
2953
  type: 'result',
2949
- });
2954
+ }, undefined);
2950
2955
  if (field instanceof QueryAtomicField) {
2951
2956
  this.addDependancies(resultStruct, field);
2952
2957
  }
@@ -2958,7 +2963,7 @@ class QueryQueryIndexStage extends QueryQuery {
2958
2963
  resultStruct.addField(measure, f, {
2959
2964
  resultIndex,
2960
2965
  type: 'result',
2961
- });
2966
+ }, undefined);
2962
2967
  this.addDependancies(resultStruct, f);
2963
2968
  }
2964
2969
  this.expandFilters(resultStruct);
@@ -3615,20 +3620,20 @@ class QueryStruct {
3615
3620
  return field;
3616
3621
  }
3617
3622
  getQueryFieldReference(f) {
3618
- const { path, annotation, drillView } = f;
3623
+ const { path, annotation, drillExpression } = f;
3619
3624
  const field = this.getFieldByName(path);
3620
- if (annotation || drillView) {
3625
+ if (annotation || drillExpression) {
3621
3626
  if (field.parent === undefined) {
3622
3627
  throw new Error('Inconcievable, field reference to orphaned query field');
3623
3628
  }
3624
3629
  // Made a field object from the source, but the annotations were computed by the compiler
3625
3630
  // when it generated the reference, and has both the source and reference annotations included.
3626
3631
  if (field instanceof QueryFieldStruct) {
3627
- const newDef = { ...field.fieldDef, annotation, drillView };
3632
+ const newDef = { ...field.fieldDef, annotation, drillExpression };
3628
3633
  return new QueryFieldStruct(newDef, undefined, field.parent, {}, field.referenceId);
3629
3634
  }
3630
3635
  else {
3631
- const newDef = { ...field.fieldDef, annotation, drillView };
3636
+ const newDef = { ...field.fieldDef, annotation, drillExpression };
3632
3637
  return field.parent.makeQueryField(newDef, field.referenceId);
3633
3638
  }
3634
3639
  }
@@ -3683,7 +3688,6 @@ class QueryStruct {
3683
3688
  pipeline,
3684
3689
  annotation,
3685
3690
  location: turtleDef.location,
3686
- drillView: turtleDef.drillView,
3687
3691
  };
3688
3692
  return flatTurtleDef;
3689
3693
  }
@@ -1,4 +1,4 @@
1
- import type { Filter } from '@malloydata/malloy-interfaces';
1
+ import type * as Malloy from '@malloydata/malloy-interfaces';
2
2
  /**
3
3
  * Field computations are compiled into an expression tree of "Expr"
4
4
  * type nodes. Each node is one of these three interfaces. The
@@ -60,8 +60,8 @@ export interface FilterCondition extends ExprE {
60
60
  code: string;
61
61
  expressionType: ExpressionType;
62
62
  fieldUsage?: FieldUsage[];
63
- drillView?: string;
64
- stableFilter?: Filter;
63
+ filterView?: string;
64
+ stableFilter?: Malloy.Filter;
65
65
  isSourceFilter?: boolean;
66
66
  }
67
67
  export interface FilteredExpr extends ExprWithKids {
@@ -265,6 +265,7 @@ export interface Expression {
265
265
  fieldUsage?: FieldUsage[];
266
266
  expressionType?: ExpressionType;
267
267
  code?: string;
268
+ drillExpression?: Malloy.Expression;
268
269
  }
269
270
  type ConstantExpr = Expr;
270
271
  interface ParameterInfo {
@@ -343,6 +344,7 @@ export interface ResultMetadataDef {
343
344
  filterList?: FilterCondition[];
344
345
  fieldKind: 'measure' | 'dimension' | 'struct';
345
346
  referenceId?: string;
347
+ drillExpression?: Malloy.Expression | undefined;
346
348
  drillable?: boolean;
347
349
  }
348
350
  export interface Ordered {
@@ -389,7 +391,7 @@ export interface FieldBase extends NamedObject, Expression, ResultMetadata {
389
391
  accessModifier?: NonDefaultAccessModifierLabel | undefined;
390
392
  requiresGroupBy?: RequiredGroupBy[];
391
393
  ungroupings?: AggregateUngrouping[];
392
- drillView?: string;
394
+ drillExpression?: Malloy.Expression | undefined;
393
395
  }
394
396
  export declare function fieldIsIntrinsic(f: FieldDef): f is AtomicFieldDef;
395
397
  export interface StringTypeDef {
@@ -610,7 +612,6 @@ export interface TurtleDef extends NamedObject, Pipeline {
610
612
  accessModifier?: NonDefaultAccessModifierLabel | undefined;
611
613
  fieldUsage?: FieldUsage[];
612
614
  requiredGroupBys?: string[][];
613
- drillView?: string;
614
615
  }
615
616
  interface StructDefBase extends HasLocation, NamedObject {
616
617
  type: string;
@@ -799,7 +800,7 @@ export interface RefToField {
799
800
  path: string[];
800
801
  annotation?: Annotation;
801
802
  at?: DocumentLocation;
802
- drillView?: string;
803
+ drillExpression?: Malloy.Expression | undefined;
803
804
  }
804
805
  export type QueryFieldDef = AtomicFieldDef | TurtleDef | RefToField;
805
806
  export type TypedDef = AtomicTypeDef | JoinFieldDef | TurtleDef | RefToField | StructDef;
@@ -1,4 +1,4 @@
1
- import type * as Malloy from '@malloydata/malloy-interfaces';
1
+ import * as Malloy from '@malloydata/malloy-interfaces';
2
2
  import type { FieldDef, ModelDef, ResultStructMetadataDef, SourceDef } from './model';
3
3
  import { Tag } from '@malloydata/malloy-tag';
4
4
  export declare function sourceDefToSourceInfo(sourceDef: SourceDef): Malloy.SourceInfo;
@@ -6,3 +6,15 @@ export declare function modelDefToModelInfo(modelDef: ModelDef): Malloy.ModelInf
6
6
  export declare function convertFieldInfos(source: SourceDef, fields: FieldDef[]): Malloy.FieldInfo[];
7
7
  export declare function writeLiteralToTag(tag: Tag, path: (string | number)[], literal: Malloy.LiteralValue): void;
8
8
  export declare function getResultStructMetadataAnnotation(field: SourceDef, resultMetadata: ResultStructMetadataDef): Malloy.Annotation | undefined;
9
+ /**
10
+ * Writes a Malloy interface object to a tag at a given path.
11
+ *
12
+ * E.g. `writeMalloyObjectToTag(tag, ['expr'], 'Expression', {kind: 'field_reference', name: 'carrier'})`
13
+ *
14
+ * produces the tag `#(malloy) expr { kind = field_reference name = carrier }`
15
+ */
16
+ export declare function writeMalloyObjectToTag(tag: Tag, path: (string | number)[], obj: unknown, type: string): void;
17
+ /**
18
+ * Extracts a Malloy interface object from a tag at a given path; the inverse of `writeMalloyObjectToTag`.
19
+ */
20
+ export declare function extractMalloyObjectFromTag(tag: Tag, type: string): unknown;
package/dist/to_stable.js CHANGED
@@ -5,12 +5,48 @@
5
5
  * This source code is licensed under the MIT license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
8
41
  Object.defineProperty(exports, "__esModule", { value: true });
9
42
  exports.sourceDefToSourceInfo = sourceDefToSourceInfo;
10
43
  exports.modelDefToModelInfo = modelDefToModelInfo;
11
44
  exports.convertFieldInfos = convertFieldInfos;
12
45
  exports.writeLiteralToTag = writeLiteralToTag;
13
46
  exports.getResultStructMetadataAnnotation = getResultStructMetadataAnnotation;
47
+ exports.writeMalloyObjectToTag = writeMalloyObjectToTag;
48
+ exports.extractMalloyObjectFromTag = extractMalloyObjectFromTag;
49
+ const Malloy = __importStar(require("@malloydata/malloy-interfaces"));
14
50
  const model_1 = require("./model");
15
51
  const malloy_query_1 = require("./model/malloy_query");
16
52
  const annotation_1 = require("./annotation");
@@ -220,25 +256,23 @@ function getResultMetadataAnnotation(field, resultMetadata) {
220
256
  tag.set(['drillable']);
221
257
  hasAny = true;
222
258
  }
223
- if ((0, model_1.isAtomic)(field) || (0, model_1.isTurtle)(field)) {
224
- if (field.drillView !== undefined) {
225
- tag.set(['drill_view'], field.drillView);
226
- hasAny = true;
227
- }
228
- }
229
259
  if (resultMetadata.filterList) {
230
260
  addDrillFiltersTag(tag, resultMetadata.filterList);
231
261
  hasAny = true;
232
262
  }
263
+ if (resultMetadata.drillExpression) {
264
+ writeExpressionToTag(tag, ['drill_expression'], resultMetadata.drillExpression);
265
+ hasAny = true;
266
+ }
233
267
  if (resultMetadata.fieldKind === 'dimension') {
234
268
  const dot = '.';
235
269
  // If field is joined-in from another table i.e. of type `tableName.columnName`,
236
270
  // return sourceField, else return name because this could be a renamed field.
237
- const drillExpression = (resultMetadata === null || resultMetadata === void 0 ? void 0 : resultMetadata.sourceExpression) ||
271
+ const drillExpressionCode = (resultMetadata === null || resultMetadata === void 0 ? void 0 : resultMetadata.sourceExpression) ||
238
272
  ((resultMetadata === null || resultMetadata === void 0 ? void 0 : resultMetadata.sourceField.includes(dot))
239
273
  ? resultMetadata === null || resultMetadata === void 0 ? void 0 : resultMetadata.sourceField
240
274
  : identifierCode(field.name));
241
- tag.set(['drill_expression'], drillExpression);
275
+ tag.set(['drill_expression', 'code'], drillExpressionCode);
242
276
  hasAny = true;
243
277
  }
244
278
  return hasAny
@@ -248,20 +282,16 @@ function getResultMetadataAnnotation(field, resultMetadata) {
248
282
  : undefined;
249
283
  }
250
284
  function addDrillFiltersTag(tag, drillFilters) {
251
- var _a;
252
285
  for (let i = 0; i < drillFilters.length; i++) {
253
286
  const filter = drillFilters[i];
254
287
  if (filter.expressionType !== 'scalar' || filter.isSourceFilter)
255
288
  continue;
256
289
  tag.set(['drill_filters', i, 'code'], filter.code);
257
- if (filter.drillView) {
258
- tag.set(['drill_filters', i, 'drill_view'], filter.drillView);
290
+ if (filter.filterView) {
291
+ tag.set(['drill_filters', i, 'filter_view'], filter.filterView);
259
292
  }
260
- if (filter.drillView === undefined && filter.stableFilter !== undefined) {
261
- tag.set(['drill_filters', i, 'field_reference'], [
262
- ...((_a = filter.stableFilter.field_reference.path) !== null && _a !== void 0 ? _a : []),
263
- filter.stableFilter.field_reference.name,
264
- ]);
293
+ if (filter.filterView === undefined && filter.stableFilter !== undefined) {
294
+ writeExpressionToTag(tag, ['drill_filters', i, 'expression'], filter.stableFilter.expression);
265
295
  if (filter.stableFilter.kind === 'filter_string') {
266
296
  tag.set(['drill_filters', i, 'kind'], 'filter_expression');
267
297
  tag.set(['drill_filters', i, 'filter_expression'], filter.stableFilter.filter);
@@ -273,32 +303,11 @@ function addDrillFiltersTag(tag, drillFilters) {
273
303
  }
274
304
  }
275
305
  }
306
+ function writeExpressionToTag(tag, path, expression) {
307
+ writeMalloyObjectToTag(tag, path, expression, 'Expression');
308
+ }
276
309
  function writeLiteralToTag(tag, path, literal) {
277
- tag.set([...path, 'kind'], literal.kind);
278
- switch (literal.kind) {
279
- case 'string_literal':
280
- tag.set([...path, 'string_value'], literal.string_value);
281
- break;
282
- case 'number_literal':
283
- tag.set([...path, 'number_value'], literal.number_value);
284
- break;
285
- case 'boolean_literal':
286
- tag.set([...path, 'boolean_value'], literal.boolean_value.toString());
287
- break;
288
- case 'date_literal':
289
- tag.set([...path, 'date_value'], literal.date_value);
290
- tag.set([...path, 'timezone'], literal.timezone);
291
- tag.set([...path, 'granularity'], literal.granularity);
292
- break;
293
- case 'timestamp_literal':
294
- tag.set([...path, 'timestamp_value'], literal.timestamp_value);
295
- tag.set([...path, 'timezone'], literal.timezone);
296
- tag.set([...path, 'granularity'], literal.granularity);
297
- break;
298
- case 'filter_expression_literal':
299
- tag.set([...path, 'filter_expression_value'], literal.filter_expression_value);
300
- break;
301
- }
310
+ writeMalloyObjectToTag(tag, path, literal, 'LiteralValue');
302
311
  }
303
312
  function escapeIdentifier(str) {
304
313
  return str.replace(/\\/g, '\\\\').replace(/`/g, '\\`');
@@ -469,4 +478,142 @@ function convertTimestampTimeframe(timeframe) {
469
478
  function convertJoinType(type) {
470
479
  return type;
471
480
  }
481
+ /**
482
+ * Writes a Malloy interface object to a tag at a given path.
483
+ *
484
+ * E.g. `writeMalloyObjectToTag(tag, ['expr'], 'Expression', {kind: 'field_reference', name: 'carrier'})`
485
+ *
486
+ * produces the tag `#(malloy) expr { kind = field_reference name = carrier }`
487
+ */
488
+ function writeMalloyObjectToTag(tag, path, obj, type) {
489
+ if (type === 'string') {
490
+ tag.set(path, obj);
491
+ return;
492
+ }
493
+ else if (type === 'number') {
494
+ tag.set(path, obj);
495
+ return;
496
+ }
497
+ else if (type === 'boolean') {
498
+ tag.set(path, obj.toString());
499
+ return;
500
+ }
501
+ const typelookup = Malloy.MALLOY_INTERFACE_TYPES[type];
502
+ if (typelookup === undefined) {
503
+ throw new Error(`Unknown Malloy interface type ${type}`);
504
+ }
505
+ if (typelookup.type === 'enum') {
506
+ if (typeof obj === 'string') {
507
+ tag.set(path, obj);
508
+ }
509
+ else {
510
+ throw new Error(`Expected string for enum ${type}`);
511
+ }
512
+ }
513
+ else if (typelookup.type === 'struct') {
514
+ for (const key in typelookup.fields) {
515
+ const valueType = typelookup.fields[key];
516
+ const value = obj[key];
517
+ if (value === undefined) {
518
+ if (!valueType.optional) {
519
+ throw new Error(`Mising value for non-optional field ${key} in type ${type}`);
520
+ }
521
+ }
522
+ else if (valueType.array) {
523
+ if (Array.isArray(value)) {
524
+ for (let i = 0; i < value.length; i++) {
525
+ writeMalloyObjectToTag(tag, [...path, key, i], value[i], valueType.type);
526
+ }
527
+ }
528
+ else {
529
+ throw new Error(`Expected array for field ${key} of type ${type} but got ${typeof obj}`);
530
+ }
531
+ }
532
+ else {
533
+ writeMalloyObjectToTag(tag, [...path, key], value, valueType.type);
534
+ }
535
+ }
536
+ }
537
+ else {
538
+ // enum
539
+ const kind = obj.kind;
540
+ tag.set([...path, 'kind'], kind);
541
+ const unionType = typelookup.options[kind];
542
+ if (unionType === undefined) {
543
+ throw new Error(`Unknown Malloy interface union kind ${kind} for type ${type}`);
544
+ }
545
+ writeMalloyObjectToTag(tag, path, obj, unionType);
546
+ }
547
+ }
548
+ /**
549
+ * Extracts a Malloy interface object from a tag at a given path; the inverse of `writeMalloyObjectToTag`.
550
+ */
551
+ function extractMalloyObjectFromTag(tag, type) {
552
+ if (type === 'string') {
553
+ return tag.text();
554
+ }
555
+ else if (type === 'number') {
556
+ return tag.numeric();
557
+ }
558
+ else if (type === 'boolean') {
559
+ return tag.text() === 'true';
560
+ }
561
+ const typeDef = Malloy.MALLOY_INTERFACE_TYPES[type];
562
+ if (typeDef === undefined) {
563
+ throw new Error(`Unknown Malloy interface type ${type}`);
564
+ }
565
+ if (typeDef.type === 'enum') {
566
+ const value = tag.text();
567
+ if (value === undefined) {
568
+ throw new Error(`Missing value for enum ${type}`);
569
+ }
570
+ if (value in typeDef.values) {
571
+ return value;
572
+ }
573
+ throw new Error(`Unknown value ${value} for enum ${type}`);
574
+ }
575
+ else if (typeDef.type === 'struct') {
576
+ const result = {};
577
+ for (const [key, type] of Object.entries(typeDef.fields)) {
578
+ const valueTag = tag.tag(key);
579
+ if (valueTag === undefined) {
580
+ if (type.optional)
581
+ continue;
582
+ else {
583
+ throw new Error(`Missing value for key ${key} of type ${type}`);
584
+ }
585
+ }
586
+ if (type.array) {
587
+ const arr = [];
588
+ const values = valueTag.array();
589
+ if (values === undefined) {
590
+ throw new Error(`Missing array value for key ${key} of type ${type}`);
591
+ }
592
+ for (const value of values) {
593
+ arr.push(extractMalloyObjectFromTag(value, type.type));
594
+ }
595
+ result[key] = arr;
596
+ }
597
+ else {
598
+ const value = extractMalloyObjectFromTag(valueTag, type.type);
599
+ if (value !== undefined && value !== null) {
600
+ result[key] = value;
601
+ }
602
+ }
603
+ }
604
+ return result;
605
+ } /* (typeDef.type === 'union') */
606
+ else {
607
+ const kind = tag.text('kind');
608
+ if (kind === undefined) {
609
+ throw new Error(`Missing kind for union ${type}`);
610
+ }
611
+ const unionType = typeDef.options[kind];
612
+ if (unionType === undefined) {
613
+ throw new Error(`Unknown kind ${kind} for union ${type}`);
614
+ }
615
+ const value = extractMalloyObjectFromTag(tag, unionType);
616
+ return { kind, ...value };
617
+ }
618
+ }
472
619
  //# sourceMappingURL=to_stable.js.map
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const MALLOY_VERSION = "0.0.294";
1
+ export declare const MALLOY_VERSION = "0.0.295";
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.294';
5
+ exports.MALLOY_VERSION = '0.0.295';
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.294",
3
+ "version": "0.0.295",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -41,9 +41,9 @@
41
41
  "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"
42
42
  },
43
43
  "dependencies": {
44
- "@malloydata/malloy-filter": "0.0.294",
45
- "@malloydata/malloy-interfaces": "0.0.294",
46
- "@malloydata/malloy-tag": "0.0.294",
44
+ "@malloydata/malloy-filter": "0.0.295",
45
+ "@malloydata/malloy-interfaces": "0.0.295",
46
+ "@malloydata/malloy-tag": "0.0.295",
47
47
  "antlr4ts": "^0.5.0-alpha.4",
48
48
  "assert": "^2.0.0",
49
49
  "jaro-winkler": "^0.2.8",