@malloydata/malloy 0.0.220-dev241205182408 → 0.0.220-dev241206021955
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/dialect/snowflake/snowflake.js +2 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -6
- package/dist/lang/ast/expressions/expr-aggregate-function.js +1 -1
- package/dist/lang/ast/expressions/expr-time-extract.js +3 -3
- package/dist/lang/ast/expressions/expr-time.js +1 -1
- package/dist/lang/ast/expressions/time-literal.js +1 -1
- package/dist/lang/ast/field-space/static-space.js +3 -4
- package/dist/lang/ast/field-space/view-field.d.ts +1 -1
- package/dist/lang/ast/index.d.ts +0 -1
- package/dist/lang/ast/index.js +0 -1
- package/dist/lang/ast/query-builders/reduce-builder.js +1 -1
- package/dist/lang/ast/typedesc-utils.js +1 -1
- package/dist/lang/ast/types/expression-def.js +4 -4
- package/dist/lang/ast/view-elements/reference-view.js +1 -1
- package/dist/lang/test/imports.spec.js +2 -2
- package/dist/lang/test/query.spec.js +1 -1
- package/dist/malloy.js +1 -1
- package/dist/model/composite_source_utils.js +1 -1
- package/dist/model/malloy_query.js +11 -2
- package/dist/model/malloy_types.d.ts +13 -27
- package/dist/model/malloy_types.js +14 -42
- package/package.json +1 -1
- package/dist/lang/ast/expressions/top-by.d.ts +0 -10
- package/dist/lang/ast/expressions/top-by.js +0 -50
|
@@ -392,8 +392,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
392
392
|
return 'DOUBLE';
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
|
-
else if (malloyType.type === 'record' ||
|
|
396
|
-
(0, malloy_types_1.isRepeatedRecordType)(malloyType)) {
|
|
395
|
+
else if (malloyType.type === 'record' || (0, malloy_types_1.isRepeatedRecord)(malloyType)) {
|
|
397
396
|
const sqlFields = malloyType.fields.reduce((ret, f) => {
|
|
398
397
|
var _a;
|
|
399
398
|
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
@@ -408,7 +407,7 @@ ${(0, utils_1.indent)(sql)}
|
|
|
408
407
|
? recordScehma
|
|
409
408
|
: `ARRAY(${recordScehma})`;
|
|
410
409
|
}
|
|
411
|
-
else if ((0, malloy_types_1.
|
|
410
|
+
else if ((0, malloy_types_1.isScalarArray)(malloyType)) {
|
|
412
411
|
return `ARRAY(${this.malloyTypeToSQLType(malloyType.elementTypeDef)})`;
|
|
413
412
|
}
|
|
414
413
|
return malloyType.type;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, 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
3
|
export type { QueryDataRow, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, SQLSentence, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryRunStats, NamedQuery, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, LeafAtomicTypeDef, LeafAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, ArrayLiteralNode, } from './model';
|
|
4
|
-
export {
|
|
4
|
+
export { isSourceDef, Segment, isLeafAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isScalarArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, } from './model';
|
|
5
5
|
export { MalloyTranslator, } from './lang';
|
|
6
6
|
export type { LogMessage, TranslateResponse } from './lang';
|
|
7
7
|
export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, } from './malloy';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isScalarArray = exports.
|
|
4
|
-
exports.Tag = exports.toAsyncGenerator = 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 =
|
|
3
|
+
exports.InMemoryURLReader = exports.EmptyURLReader = exports.SingleConnectionRuntime = exports.ConnectionRuntime = exports.AtomicFieldType = exports.Runtime = exports.Malloy = exports.Model = exports.MalloyTranslator = exports.composeSQLExpr = exports.indent = exports.expressionIsUngroupedAggregate = exports.expressionIsScalar = exports.expressionIsCalculation = exports.expressionIsAnalytic = exports.expressionIsAggregate = exports.mkFieldDef = exports.mkArrayDef = exports.isScalarArray = exports.isRepeatedRecord = exports.isSamplingRows = exports.isSamplingPercent = exports.isSamplingEnable = exports.isJoinedSource = exports.isJoined = exports.isLeafAtomic = 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;
|
|
4
|
+
exports.Tag = exports.toAsyncGenerator = 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 = void 0;
|
|
5
5
|
/*
|
|
6
6
|
* Copyright 2023 Google LLC
|
|
7
7
|
*
|
|
@@ -48,18 +48,16 @@ Object.defineProperty(exports, "spread", { enumerable: true, get: function () {
|
|
|
48
48
|
Object.defineProperty(exports, "Dialect", { enumerable: true, get: function () { return dialect_1.Dialect; } });
|
|
49
49
|
Object.defineProperty(exports, "TinyParser", { enumerable: true, get: function () { return dialect_1.TinyParser; } });
|
|
50
50
|
var model_1 = require("./model");
|
|
51
|
-
Object.defineProperty(exports, "isRepeatedRecord", { enumerable: true, get: function () { return model_1.isRepeatedRecord; } });
|
|
52
51
|
Object.defineProperty(exports, "isSourceDef", { enumerable: true, get: function () { return model_1.isSourceDef; } });
|
|
53
52
|
// Used in Composer Demo
|
|
54
53
|
Object.defineProperty(exports, "Segment", { enumerable: true, get: function () { return model_1.Segment; } });
|
|
55
54
|
Object.defineProperty(exports, "isLeafAtomic", { enumerable: true, get: function () { return model_1.isLeafAtomic; } });
|
|
56
|
-
Object.defineProperty(exports, "
|
|
55
|
+
Object.defineProperty(exports, "isJoined", { enumerable: true, get: function () { return model_1.isJoined; } });
|
|
57
56
|
Object.defineProperty(exports, "isJoinedSource", { enumerable: true, get: function () { return model_1.isJoinedSource; } });
|
|
58
57
|
Object.defineProperty(exports, "isSamplingEnable", { enumerable: true, get: function () { return model_1.isSamplingEnable; } });
|
|
59
58
|
Object.defineProperty(exports, "isSamplingPercent", { enumerable: true, get: function () { return model_1.isSamplingPercent; } });
|
|
60
59
|
Object.defineProperty(exports, "isSamplingRows", { enumerable: true, get: function () { return model_1.isSamplingRows; } });
|
|
61
|
-
Object.defineProperty(exports, "
|
|
62
|
-
Object.defineProperty(exports, "isScalarArrayType", { enumerable: true, get: function () { return model_1.isScalarArrayType; } });
|
|
60
|
+
Object.defineProperty(exports, "isRepeatedRecord", { enumerable: true, get: function () { return model_1.isRepeatedRecord; } });
|
|
63
61
|
Object.defineProperty(exports, "isScalarArray", { enumerable: true, get: function () { return model_1.isScalarArray; } });
|
|
64
62
|
Object.defineProperty(exports, "mkArrayDef", { enumerable: true, get: function () { return model_1.mkArrayDef; } });
|
|
65
63
|
Object.defineProperty(exports, "mkFieldDef", { enumerable: true, get: function () { return model_1.mkFieldDef; } });
|
|
@@ -241,7 +241,7 @@ function getJoinUsage(fs, expr) {
|
|
|
241
241
|
if (frag.node === 'field') {
|
|
242
242
|
const def = lookupWithPath(fs, frag.path);
|
|
243
243
|
const field = def.def;
|
|
244
|
-
if ((0, malloy_types_1.isAtomic)(field) && !(0, malloy_types_1.
|
|
244
|
+
if ((0, malloy_types_1.isAtomic)(field) && !(0, malloy_types_1.isJoined)(field)) {
|
|
245
245
|
if ((0, malloy_types_1.hasExpression)(field)) {
|
|
246
246
|
const defUsage = getJoinUsage(def.fs, field.e);
|
|
247
247
|
result.push(...defUsage.map(r => [...def.joinPath, ...r]));
|
|
@@ -60,10 +60,10 @@ class ExprTimeExtract extends expression_def_1.ExpressionDef {
|
|
|
60
60
|
from: [first, last],
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
|
-
if (!(0, malloy_types_1.
|
|
63
|
+
if (!(0, malloy_types_1.isTemporalType)(first.type)) {
|
|
64
64
|
return from.first.loggedErrorExpr('invalid-type-for-time-extraction', `Can't extract ${extractTo} from '${first.type}'`);
|
|
65
65
|
}
|
|
66
|
-
if (!(0, malloy_types_1.
|
|
66
|
+
if (!(0, malloy_types_1.isTemporalType)(last.type)) {
|
|
67
67
|
return from.last.loggedErrorExpr('invalid-type-for-time-extraction', `Cannot extract ${extractTo} from '${last.type}'`);
|
|
68
68
|
}
|
|
69
69
|
let valueType = first.type;
|
|
@@ -109,7 +109,7 @@ class ExprTimeExtract extends expression_def_1.ExpressionDef {
|
|
|
109
109
|
}
|
|
110
110
|
else {
|
|
111
111
|
const argV = from.getExpression(fs);
|
|
112
|
-
if ((0, malloy_types_1.
|
|
112
|
+
if ((0, malloy_types_1.isTemporalType)(argV.type)) {
|
|
113
113
|
return (0, expr_value_1.computedExprValue)({
|
|
114
114
|
dataType: { type: 'number', numberType: 'integer' },
|
|
115
115
|
value: {
|
|
@@ -49,7 +49,7 @@ class ExprTime extends expression_def_1.ExpressionDef {
|
|
|
49
49
|
dstType: { type: timeType },
|
|
50
50
|
e: expr.value,
|
|
51
51
|
};
|
|
52
|
-
if ((0, malloy_types_1.
|
|
52
|
+
if ((0, malloy_types_1.isTemporalType)(expr.type)) {
|
|
53
53
|
toTs.srcType = { type: expr.type };
|
|
54
54
|
}
|
|
55
55
|
value = toTs;
|
|
@@ -166,7 +166,7 @@ class GranularLiteral extends TimeLiteral {
|
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
// Compiler is unsure about rangeEnd = newEnd for some reason
|
|
169
|
-
if (rangeEnd && (0, malloy_types_1.
|
|
169
|
+
if (rangeEnd && (0, malloy_types_1.isTemporalType)(testValue.type)) {
|
|
170
170
|
const rangeType = testValue.type;
|
|
171
171
|
const range = new range_1.Range(new expr_time_1.ExprTime(rangeType, rangeStart.value), new expr_time_1.ExprTime(rangeType, rangeEnd.value));
|
|
172
172
|
return range.apply(fs, op, left);
|
|
@@ -50,10 +50,10 @@ class StaticSpace {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
defToSpaceField(from) {
|
|
53
|
-
if ((0, malloy_types_1.
|
|
53
|
+
if ((0, malloy_types_1.isJoined)(from)) {
|
|
54
54
|
return new StructSpaceField(from);
|
|
55
55
|
}
|
|
56
|
-
else if ((0, malloy_types_1.
|
|
56
|
+
else if ((0, malloy_types_1.isTurtle)(from)) {
|
|
57
57
|
return new ir_view_field_1.IRViewField(this, from);
|
|
58
58
|
}
|
|
59
59
|
return new column_space_field_1.ColumnSpaceField(from);
|
|
@@ -120,8 +120,7 @@ class StaticSpace {
|
|
|
120
120
|
if (found instanceof space_field_1.SpaceField) {
|
|
121
121
|
const definition = found.fieldDef();
|
|
122
122
|
if (definition) {
|
|
123
|
-
if (!(found instanceof struct_space_field_base_1.StructSpaceFieldBase) &&
|
|
124
|
-
(0, malloy_types_1.isJoinedField)(definition)) {
|
|
123
|
+
if (!(found instanceof struct_space_field_base_1.StructSpaceFieldBase) && (0, malloy_types_1.isJoined)(definition)) {
|
|
125
124
|
// We have looked up a field which is a join, but not a StructSpaceField
|
|
126
125
|
// because it is someting like "dimension: joinedArray is arrayComputation"
|
|
127
126
|
// which wasn't known to be a join when the fieldspace was constructed.
|
|
@@ -55,7 +55,7 @@ export declare abstract class ViewField extends SpaceField {
|
|
|
55
55
|
} | {
|
|
56
56
|
compositeFieldUsage: import("../../../model/malloy_types").CompositeFieldUsage;
|
|
57
57
|
type: "array";
|
|
58
|
-
elementTypeDef: import("../../../model/malloy_types").LeafAtomicTypeDef | import("../../../model/malloy_types").
|
|
58
|
+
elementTypeDef: import("../../../model/malloy_types").LeafAtomicTypeDef | import("../../../model/malloy_types").ScalarArrayTypeDef | import("../../../model/malloy_types").RepeatedRecordTypeDef;
|
|
59
59
|
expressionType: import("../../../model/malloy_types").ExpressionType;
|
|
60
60
|
evalSpace: import("../../../model/malloy_types").EvalSpace;
|
|
61
61
|
} | {
|
package/dist/lang/ast/index.d.ts
CHANGED
|
@@ -58,7 +58,6 @@ export * from './expressions/expr-array-literal';
|
|
|
58
58
|
export * from './expressions/expr-record-literal';
|
|
59
59
|
export * from './expressions/range';
|
|
60
60
|
export * from './expressions/time-frame';
|
|
61
|
-
export * from './expressions/top-by';
|
|
62
61
|
export * from './expressions/unary';
|
|
63
62
|
export * from './statements/import-statement';
|
|
64
63
|
export * from './query-properties/extend';
|
package/dist/lang/ast/index.js
CHANGED
|
@@ -96,7 +96,6 @@ __exportStar(require("./expressions/expr-array-literal"), exports);
|
|
|
96
96
|
__exportStar(require("./expressions/expr-record-literal"), exports);
|
|
97
97
|
__exportStar(require("./expressions/range"), exports);
|
|
98
98
|
__exportStar(require("./expressions/time-frame"), exports);
|
|
99
|
-
__exportStar(require("./expressions/top-by"), exports);
|
|
100
99
|
__exportStar(require("./expressions/unary"), exports);
|
|
101
100
|
__exportStar(require("./statements/import-statement"), exports);
|
|
102
101
|
__exportStar(require("./query-properties/extend"), exports);
|
|
@@ -161,7 +161,7 @@ class ReduceBuilder extends QuerySegmentBuilder {
|
|
|
161
161
|
fieldAnalytic =
|
|
162
162
|
(0, malloy_types_1.hasExpression)(field) && (0, malloy_types_1.expressionIsAnalytic)(field.expressionType);
|
|
163
163
|
}
|
|
164
|
-
if ((0, malloy_types_1.
|
|
164
|
+
if ((0, malloy_types_1.isTemporalType)(fieldType) || fieldAggregate) {
|
|
165
165
|
reduceSegment.defaultOrderBy = true;
|
|
166
166
|
reduceSegment.orderBy = [{ field: fieldName, dir: 'desc' }];
|
|
167
167
|
usableDefaultOrderField = undefined;
|
|
@@ -125,7 +125,7 @@ function atomicDef(td) {
|
|
|
125
125
|
if (model_1.TD.isAtomic(td)) {
|
|
126
126
|
switch (td.type) {
|
|
127
127
|
case 'array': {
|
|
128
|
-
return (0, model_1.
|
|
128
|
+
return (0, model_1.isRepeatedRecord)(td)
|
|
129
129
|
? {
|
|
130
130
|
type: 'array',
|
|
131
131
|
elementTypeDef: td.elementTypeDef,
|
|
@@ -154,7 +154,7 @@ class ExprDuration extends ExpressionDef {
|
|
|
154
154
|
apply(fs, op, left) {
|
|
155
155
|
const lhs = left.getExpression(fs);
|
|
156
156
|
this.typeCheck(this, lhs);
|
|
157
|
-
if ((0, malloy_types_1.
|
|
157
|
+
if ((0, malloy_types_1.isTemporalType)(lhs.type) && (op === '+' || op === '-')) {
|
|
158
158
|
const num = this.n.getExpression(fs);
|
|
159
159
|
if (!TDU.typeEq(num, TDU.numberT)) {
|
|
160
160
|
this.logError('invalid-duration-quantity', `Duration quantity needs number not '${num.type}`);
|
|
@@ -209,8 +209,8 @@ function getMorphicValue(mv, mt) {
|
|
|
209
209
|
}
|
|
210
210
|
exports.getMorphicValue = getMorphicValue;
|
|
211
211
|
function timeCompare(left, lhs, op, rhs) {
|
|
212
|
-
const leftIsTime = (0, malloy_types_1.
|
|
213
|
-
const rightIsTime = (0, malloy_types_1.
|
|
212
|
+
const leftIsTime = (0, malloy_types_1.isTemporalType)(lhs.type);
|
|
213
|
+
const rightIsTime = (0, malloy_types_1.isTemporalType)(rhs.type);
|
|
214
214
|
const node = (0, binary_operators_1.getExprNode)(op);
|
|
215
215
|
if (leftIsTime && rightIsTime) {
|
|
216
216
|
if (lhs.type !== rhs.type) {
|
|
@@ -371,7 +371,7 @@ function delta(fs, left, op, right) {
|
|
|
371
371
|
if (noGo) {
|
|
372
372
|
return noGo;
|
|
373
373
|
}
|
|
374
|
-
const timeLHS = (0, malloy_types_1.
|
|
374
|
+
const timeLHS = (0, malloy_types_1.isTemporalType)(lhs.type);
|
|
375
375
|
const err = errorCascade(timeLHS ? 'error' : 'number', lhs, rhs);
|
|
376
376
|
if (err)
|
|
377
377
|
return err;
|
|
@@ -89,7 +89,7 @@ class ReferenceView extends view_1.View {
|
|
|
89
89
|
outputStruct,
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
|
-
else if ((0, malloy_types_1.
|
|
92
|
+
else if ((0, malloy_types_1.isTurtle)(fieldDef)) {
|
|
93
93
|
if (this.reference.list.length > 1) {
|
|
94
94
|
if (forRefinement) {
|
|
95
95
|
this.logError('refinement-with-joined-view', 'Cannot use view from join as refinement');
|
|
@@ -92,8 +92,8 @@ source: botProjQSrc is botProjQ
|
|
|
92
92
|
const maybeField = newSrc === null || newSrc === void 0 ? void 0 : newSrc.fields.find(f => f.name === 'b');
|
|
93
93
|
expect(maybeField).toBeDefined();
|
|
94
94
|
const f = maybeField;
|
|
95
|
-
expect((0, model_1.
|
|
96
|
-
if ((0, model_1.
|
|
95
|
+
expect((0, model_1.isJoined)(f)).toBeTruthy();
|
|
96
|
+
if ((0, model_1.isJoined)(f)) {
|
|
97
97
|
expect(f.type).toBe('query_source');
|
|
98
98
|
if (f.type === 'query_source') {
|
|
99
99
|
expect(typeof f.query.structRef).not.toBe('string');
|
|
@@ -1038,7 +1038,7 @@ describe('query:', () => {
|
|
|
1038
1038
|
const q = t.translated.queryList[0].pipeline[0];
|
|
1039
1039
|
if (q.type === 'reduce' && q.extendSource) {
|
|
1040
1040
|
expect(q.extendSource.length).toBe(1);
|
|
1041
|
-
expect((0, model_1.
|
|
1041
|
+
expect((0, model_1.isJoined)(q.extendSource[0])).toBeTruthy();
|
|
1042
1042
|
expect(q.extendSource[0].type).toBe('table');
|
|
1043
1043
|
}
|
|
1044
1044
|
else {
|
package/dist/malloy.js
CHANGED
|
@@ -1041,7 +1041,7 @@ class Explore extends Entity {
|
|
|
1041
1041
|
this._fieldMap = new Map(this.structDef.fields.map(fieldDef => {
|
|
1042
1042
|
const name = fieldDef.as || fieldDef.name;
|
|
1043
1043
|
const sourceField = sourceFields.get(fieldDef.name);
|
|
1044
|
-
if ((0, model_1.
|
|
1044
|
+
if ((0, model_1.isJoined)(fieldDef)) {
|
|
1045
1045
|
return [name, new ExploreField(fieldDef, this, sourceField)];
|
|
1046
1046
|
}
|
|
1047
1047
|
else if (fieldDef.type === 'turtle') {
|
|
@@ -107,7 +107,7 @@ function _resolveCompositeSources(path, source, compositeFieldUsage, narrowedCom
|
|
|
107
107
|
error: { code: 'composite_source_not_defined', data: { path: newPath } },
|
|
108
108
|
};
|
|
109
109
|
}
|
|
110
|
-
if (!(0, malloy_types_1.
|
|
110
|
+
if (!(0, malloy_types_1.isJoined)(join) || !(0, malloy_types_1.isSourceDef)(join)) {
|
|
111
111
|
return {
|
|
112
112
|
error: { code: 'composite_source_not_a_join', data: { path: newPath } },
|
|
113
113
|
};
|
|
@@ -1269,7 +1269,7 @@ class FieldInstanceResult {
|
|
|
1269
1269
|
if (fi instanceof FieldInstanceField) {
|
|
1270
1270
|
if (fi.fieldUsage.type === 'result') {
|
|
1271
1271
|
if (fi.f.fieldDef.type === 'turtle' ||
|
|
1272
|
-
(0, malloy_types_1.
|
|
1272
|
+
(0, malloy_types_1.isJoined)(fi.f.fieldDef) ||
|
|
1273
1273
|
(0, malloy_types_1.expressionIsAnalytic)(fi.f.fieldDef.expressionType)) {
|
|
1274
1274
|
continue;
|
|
1275
1275
|
}
|
|
@@ -3597,7 +3597,16 @@ class QueryModel {
|
|
|
3597
3597
|
// for (const f of ret.outputStruct.fields) {
|
|
3598
3598
|
// fieldNames.push(getIdentifier(f));
|
|
3599
3599
|
// }
|
|
3600
|
-
const fieldNames =
|
|
3600
|
+
const fieldNames = [];
|
|
3601
|
+
for (const f of ret.outputStruct.fields) {
|
|
3602
|
+
if ((0, malloy_types_1.isAtomic)(f)) {
|
|
3603
|
+
const quoted = q.parent.dialect.sqlMaybeQuoteIdentifier(f.name);
|
|
3604
|
+
fieldNames.push(quoted);
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
// const fieldNames = getAtomicFields(ret.outputStruct).map(fieldDef =>
|
|
3608
|
+
// q.parent.dialect.sqlMaybeQuoteIdentifier(fieldDef.name)
|
|
3609
|
+
// );
|
|
3601
3610
|
ret.lastStageName = stageWriter.addStage(q.parent.dialect.sqlFinalStage(ret.lastStageName, fieldNames));
|
|
3602
3611
|
}
|
|
3603
3612
|
return {
|
|
@@ -342,7 +342,7 @@ export interface HasExpression {
|
|
|
342
342
|
}
|
|
343
343
|
export declare function hasExpression<T extends FieldDef>(f: T): f is T & Expression & HasExpression;
|
|
344
344
|
export type TemporalFieldType = 'date' | 'timestamp';
|
|
345
|
-
export declare function
|
|
345
|
+
export declare function isTemporalType(s: string): s is TemporalFieldType;
|
|
346
346
|
export type CastType = 'string' | 'number' | TemporalFieldType | 'boolean' | 'json';
|
|
347
347
|
export type AtomicFieldType = CastType | 'sql native' | 'record' | 'array' | 'error';
|
|
348
348
|
export declare function isAtomicFieldType(s: string): s is AtomicFieldType;
|
|
@@ -381,11 +381,11 @@ export interface NativeUnsupportedTypeDef {
|
|
|
381
381
|
rawType?: string;
|
|
382
382
|
}
|
|
383
383
|
export type NativeUnsupportedFieldDef = NativeUnsupportedTypeDef & AtomicFieldDef;
|
|
384
|
-
export interface
|
|
384
|
+
export interface ScalarArrayTypeDef {
|
|
385
385
|
type: 'array';
|
|
386
386
|
elementTypeDef: Exclude<AtomicTypeDef, RecordTypeDef>;
|
|
387
387
|
}
|
|
388
|
-
export interface
|
|
388
|
+
export interface ScalarArrayDef extends ScalarArrayTypeDef, StructDefBase, JoinBase, FieldBase {
|
|
389
389
|
type: 'array';
|
|
390
390
|
join: 'many';
|
|
391
391
|
}
|
|
@@ -411,12 +411,10 @@ export interface RepeatedRecordDef extends RepeatedRecordTypeDef, StructDefBase,
|
|
|
411
411
|
type: 'array';
|
|
412
412
|
join: 'many';
|
|
413
413
|
}
|
|
414
|
-
export type ArrayTypeDef =
|
|
415
|
-
export type ArrayDef =
|
|
416
|
-
export declare function
|
|
417
|
-
export declare function
|
|
418
|
-
export declare function isScalarArrayType(td: AtomicTypeDef): td is LeafArrayTypeDef;
|
|
419
|
-
export declare function isScalarArray(fd: FieldDef | QueryFieldDef | StructDef): fd is LeafArrayDef;
|
|
414
|
+
export type ArrayTypeDef = ScalarArrayTypeDef | RepeatedRecordTypeDef;
|
|
415
|
+
export type ArrayDef = ScalarArrayDef | RepeatedRecordDef;
|
|
416
|
+
export declare function isRepeatedRecord(fd: FieldDef | QueryFieldDef | StructDef | AtomicTypeDef): fd is RepeatedRecordTypeDef;
|
|
417
|
+
export declare function isScalarArray(td: AtomicTypeDef | FieldDef | QueryFieldDef | StructDef): td is ScalarArrayTypeDef;
|
|
420
418
|
export interface ErrorTypeDef {
|
|
421
419
|
type: 'error';
|
|
422
420
|
}
|
|
@@ -436,8 +434,7 @@ export interface JoinBase {
|
|
|
436
434
|
export type Joinable = CompositeSourceDef | TableSourceDef | SQLSourceDef | QuerySourceDef | RepeatedRecordDef | RecordDef | ArrayDef;
|
|
437
435
|
export type JoinFieldDef = Joinable & JoinBase;
|
|
438
436
|
export declare function isJoinable(sd: StructDef): sd is Joinable;
|
|
439
|
-
export declare function
|
|
440
|
-
export declare function isJoined(sd: StructDef): sd is JoinFieldDef;
|
|
437
|
+
export declare function isJoined(sd: TypedDef): sd is JoinFieldDef;
|
|
441
438
|
export declare function isJoinedSource(sd: StructDef): sd is SourceDef & JoinBase;
|
|
442
439
|
export type DateUnit = 'day' | 'week' | 'month' | 'quarter' | 'year';
|
|
443
440
|
export declare function isDateUnit(str: string): str is DateUnit;
|
|
@@ -477,17 +474,6 @@ export interface FunctionOrderByDefaultExpression extends ExprLeaf {
|
|
|
477
474
|
dir: 'asc' | 'desc';
|
|
478
475
|
}
|
|
479
476
|
export type FunctionOrderBy = FunctionOrderByExpression | FunctionOrderByDefaultExpression;
|
|
480
|
-
export interface ByName {
|
|
481
|
-
by: 'name';
|
|
482
|
-
name: string;
|
|
483
|
-
}
|
|
484
|
-
export interface ByExpression {
|
|
485
|
-
by: 'expression';
|
|
486
|
-
e: Expr;
|
|
487
|
-
}
|
|
488
|
-
export type By = ByName | ByExpression;
|
|
489
|
-
export declare function isByName(by: By | undefined): by is ByName;
|
|
490
|
-
export declare function isByExpression(by: By | undefined): by is ByExpression;
|
|
491
477
|
/** reference to a data source */
|
|
492
478
|
export type StructRef = string | SourceDef;
|
|
493
479
|
export declare function refIsStructDef(ref: StructRef): ref is SourceDef;
|
|
@@ -694,8 +680,8 @@ export interface ConnectionDef extends NamedObject {
|
|
|
694
680
|
export type TemporalTypeDef = DateTypeDef | TimestampTypeDef;
|
|
695
681
|
export type LeafAtomicTypeDef = StringTypeDef | TemporalTypeDef | NumberTypeDef | BooleanTypeDef | JSONTypeDef | NativeUnsupportedTypeDef | ErrorTypeDef;
|
|
696
682
|
export type LeafAtomicDef = LeafAtomicTypeDef & FieldBase;
|
|
697
|
-
export type AtomicTypeDef = LeafAtomicTypeDef |
|
|
698
|
-
export type AtomicFieldDef = LeafAtomicDef |
|
|
683
|
+
export type AtomicTypeDef = LeafAtomicTypeDef | ScalarArrayTypeDef | RecordTypeDef | RepeatedRecordTypeDef;
|
|
684
|
+
export type AtomicFieldDef = LeafAtomicDef | ScalarArrayDef | RecordDef | RepeatedRecordDef;
|
|
699
685
|
export declare function isLeafAtomic(fd: FieldDef | QueryFieldDef | AtomicTypeDef): fd is LeafAtomicDef;
|
|
700
686
|
export type FieldDef = LeafAtomicDef | JoinFieldDef | TurtleDef;
|
|
701
687
|
export type FieldDefType = AtomicFieldType | 'turtle' | JoinElementType;
|
|
@@ -705,6 +691,7 @@ export interface RefToField {
|
|
|
705
691
|
annotation?: Annotation;
|
|
706
692
|
}
|
|
707
693
|
export type QueryFieldDef = AtomicFieldDef | TurtleDef | RefToField;
|
|
694
|
+
export type TypedDef = AtomicTypeDef | JoinFieldDef | TurtleDef | RefToField | StructDef;
|
|
708
695
|
/** Get the output name for a NamedObject */
|
|
709
696
|
export declare function getIdentifier(n: AliasedName): string;
|
|
710
697
|
export type NamedModelObject = StructDef | NamedQuery | FunctionDef | ConnectionDef;
|
|
@@ -782,15 +769,14 @@ export interface QueryResult extends CompiledQuery {
|
|
|
782
769
|
runStats?: QueryRunStats;
|
|
783
770
|
profilingUrl?: string;
|
|
784
771
|
}
|
|
785
|
-
export declare function
|
|
786
|
-
export declare function isAtomic(def:
|
|
772
|
+
export declare function isTurtle(def: TypedDef): def is TurtleDef;
|
|
773
|
+
export declare function isAtomic(def: TypedDef): def is AtomicTypeDef;
|
|
787
774
|
export interface SearchResultRow {
|
|
788
775
|
field_name: string;
|
|
789
776
|
field_value: string;
|
|
790
777
|
weight: number;
|
|
791
778
|
}
|
|
792
779
|
export type SearchResult = SearchResultRow[];
|
|
793
|
-
export declare function getAtomicFields(structDef: StructDef): AtomicFieldDef[];
|
|
794
780
|
export declare function isValueString(value: QueryValue, field: FieldDef): value is string | null;
|
|
795
781
|
export declare function isValueNumber(value: QueryValue, field: FieldDef): value is number | null;
|
|
796
782
|
export declare function isValueBoolean(value: QueryValue, field: FieldDef): value is boolean | null;
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.
|
|
26
|
-
exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.
|
|
25
|
+
exports.isBaseTable = exports.isSourceDef = exports.sourceBase = exports.isSegmentSQL = exports.isIndexSegment = exports.isRawSegment = exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isPartialSegment = exports.isReduceSegment = exports.structHasErrors = exports.segmentHasErrors = exports.refIsStructDef = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.isJoinedSource = exports.isJoined = exports.isJoinable = exports.isMatrixOperation = exports.isScalarArray = exports.isRepeatedRecord = exports.mkArrayDef = exports.mkFieldDef = exports.fieldIsIntrinsic = exports.isCastType = exports.canOrderBy = exports.isAtomicFieldType = exports.isTemporalType = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.paramHasValue = exports.isRawCast = exports.mkTemporal = exports.isAsymmetricExpr = exports.exprIsLeaf = exports.exprHasE = exports.exprHasKids = void 0;
|
|
26
|
+
exports.TD = exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isAtomic = exports.isTurtle = exports.getIdentifier = exports.isLeafAtomic = exports.mergeEvalSpaces = exports.isLiteral = void 0;
|
|
27
27
|
function exprHasKids(e) {
|
|
28
28
|
return 'kids' in e;
|
|
29
29
|
}
|
|
@@ -147,10 +147,10 @@ function hasExpression(f) {
|
|
|
147
147
|
return 'e' in f;
|
|
148
148
|
}
|
|
149
149
|
exports.hasExpression = hasExpression;
|
|
150
|
-
function
|
|
150
|
+
function isTemporalType(s) {
|
|
151
151
|
return s === 'date' || s === 'timestamp';
|
|
152
152
|
}
|
|
153
|
-
exports.
|
|
153
|
+
exports.isTemporalType = isTemporalType;
|
|
154
154
|
function isAtomicFieldType(s) {
|
|
155
155
|
return [
|
|
156
156
|
'string',
|
|
@@ -180,10 +180,10 @@ function fieldIsIntrinsic(f) {
|
|
|
180
180
|
}
|
|
181
181
|
exports.fieldIsIntrinsic = fieldIsIntrinsic;
|
|
182
182
|
function mkFieldDef(atd, name, dialect) {
|
|
183
|
-
if (
|
|
183
|
+
if (isScalarArray(atd)) {
|
|
184
184
|
return mkArrayDef(atd.elementTypeDef, name, dialect);
|
|
185
185
|
}
|
|
186
|
-
if (
|
|
186
|
+
if (isRepeatedRecord(atd)) {
|
|
187
187
|
const { type, fields, elementTypeDef } = atd;
|
|
188
188
|
return { type, fields, elementTypeDef, join: 'many', name, dialect };
|
|
189
189
|
}
|
|
@@ -219,21 +219,13 @@ function mkArrayDef(ofType, name, dialect) {
|
|
|
219
219
|
};
|
|
220
220
|
}
|
|
221
221
|
exports.mkArrayDef = mkArrayDef;
|
|
222
|
-
function isRepeatedRecordType(td) {
|
|
223
|
-
return td.type === 'array' && td.elementTypeDef.type === 'record_element';
|
|
224
|
-
}
|
|
225
|
-
exports.isRepeatedRecordType = isRepeatedRecordType;
|
|
226
222
|
function isRepeatedRecord(fd) {
|
|
227
223
|
return fd.type === 'array' && fd.elementTypeDef.type === 'record_element';
|
|
228
224
|
}
|
|
229
225
|
exports.isRepeatedRecord = isRepeatedRecord;
|
|
230
|
-
function
|
|
226
|
+
function isScalarArray(td) {
|
|
231
227
|
return td.type === 'array' && td.elementTypeDef.type !== 'record_element';
|
|
232
228
|
}
|
|
233
|
-
exports.isScalarArrayType = isScalarArrayType;
|
|
234
|
-
function isScalarArray(fd) {
|
|
235
|
-
return fd.type === 'array' && fd.elementTypeDef.type !== 'record_element';
|
|
236
|
-
}
|
|
237
229
|
exports.isScalarArray = isScalarArray;
|
|
238
230
|
function isMatrixOperation(x) {
|
|
239
231
|
return ['left', 'right', 'full', 'inner'].includes(x);
|
|
@@ -250,16 +242,12 @@ function isJoinable(sd) {
|
|
|
250
242
|
].includes(sd.type);
|
|
251
243
|
}
|
|
252
244
|
exports.isJoinable = isJoinable;
|
|
253
|
-
function isJoinedField(fd) {
|
|
254
|
-
return 'join' in fd;
|
|
255
|
-
}
|
|
256
|
-
exports.isJoinedField = isJoinedField;
|
|
257
245
|
function isJoined(sd) {
|
|
258
246
|
return 'join' in sd;
|
|
259
247
|
}
|
|
260
248
|
exports.isJoined = isJoined;
|
|
261
249
|
function isJoinedSource(sd) {
|
|
262
|
-
return isSourceDef(sd) &&
|
|
250
|
+
return isSourceDef(sd) && isJoined(sd);
|
|
263
251
|
}
|
|
264
252
|
exports.isJoinedSource = isJoinedSource;
|
|
265
253
|
function isDateUnit(str) {
|
|
@@ -282,20 +270,6 @@ var ValueType;
|
|
|
282
270
|
ValueType["Number"] = "number";
|
|
283
271
|
ValueType["String"] = "string";
|
|
284
272
|
})(ValueType || (exports.ValueType = ValueType = {}));
|
|
285
|
-
function isByName(by) {
|
|
286
|
-
if (by === undefined) {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
return by.by === 'name';
|
|
290
|
-
}
|
|
291
|
-
exports.isByName = isByName;
|
|
292
|
-
function isByExpression(by) {
|
|
293
|
-
if (by === undefined) {
|
|
294
|
-
return false;
|
|
295
|
-
}
|
|
296
|
-
return by.by === 'name';
|
|
297
|
-
}
|
|
298
|
-
exports.isByExpression = isByExpression;
|
|
299
273
|
function refIsStructDef(ref) {
|
|
300
274
|
return typeof ref !== 'string';
|
|
301
275
|
}
|
|
@@ -407,7 +381,7 @@ function mergeEvalSpaces(...evalSpaces) {
|
|
|
407
381
|
exports.mergeEvalSpaces = mergeEvalSpaces;
|
|
408
382
|
function isLeafAtomic(fd) {
|
|
409
383
|
return (fd.type === 'string' ||
|
|
410
|
-
|
|
384
|
+
isTemporalType(fd.type) ||
|
|
411
385
|
fd.type === 'number' ||
|
|
412
386
|
fd.type === 'boolean' ||
|
|
413
387
|
fd.type === 'json' ||
|
|
@@ -423,18 +397,14 @@ function getIdentifier(n) {
|
|
|
423
397
|
return n.name;
|
|
424
398
|
}
|
|
425
399
|
exports.getIdentifier = getIdentifier;
|
|
426
|
-
function
|
|
400
|
+
function isTurtle(def) {
|
|
427
401
|
return def.type === 'turtle';
|
|
428
402
|
}
|
|
429
|
-
exports.
|
|
403
|
+
exports.isTurtle = isTurtle;
|
|
430
404
|
function isAtomic(def) {
|
|
431
405
|
return isAtomicFieldType(def.type);
|
|
432
406
|
}
|
|
433
407
|
exports.isAtomic = isAtomic;
|
|
434
|
-
function getAtomicFields(structDef) {
|
|
435
|
-
return structDef.fields.filter(isAtomic);
|
|
436
|
-
}
|
|
437
|
-
exports.getAtomicFields = getAtomicFields;
|
|
438
408
|
function isValueString(value, field) {
|
|
439
409
|
return field.type === 'string';
|
|
440
410
|
}
|
|
@@ -474,7 +444,9 @@ exports.TD = {
|
|
|
474
444
|
isDate: (td) => (td === null || td === void 0 ? void 0 : td.type) === 'date',
|
|
475
445
|
isTimestamp: (td) => (td === null || td === void 0 ? void 0 : td.type) === 'timestamp',
|
|
476
446
|
isTemporal(td) {
|
|
477
|
-
|
|
447
|
+
var _a;
|
|
448
|
+
const typ = (_a = td === null || td === void 0 ? void 0 : td.type) !== null && _a !== void 0 ? _a : '';
|
|
449
|
+
return isTemporalType(typ);
|
|
478
450
|
},
|
|
479
451
|
isError: (td) => (td === null || td === void 0 ? void 0 : td.type) === 'error',
|
|
480
452
|
eq(x, y) {
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { By } from '../../../model/malloy_types';
|
|
2
|
-
import { ExpressionDef } from '../types/expression-def';
|
|
3
|
-
import { FieldSpace } from '../types/field-space';
|
|
4
|
-
import { MalloyElement } from '../types/malloy-element';
|
|
5
|
-
export declare class TopBy extends MalloyElement {
|
|
6
|
-
readonly by: string | ExpressionDef;
|
|
7
|
-
elementType: string;
|
|
8
|
-
constructor(by: string | ExpressionDef);
|
|
9
|
-
getBy(fs: FieldSpace): By;
|
|
10
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* Copyright 2023 Google LLC
|
|
4
|
-
*
|
|
5
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
-
* a copy of this software and associated documentation files
|
|
7
|
-
* (the "Software"), to deal in the Software without restriction,
|
|
8
|
-
* including without limitation the rights to use, copy, modify, merge,
|
|
9
|
-
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
10
|
-
* and to permit persons to whom the Software is furnished to do so,
|
|
11
|
-
* subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be
|
|
14
|
-
* included in all copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.TopBy = void 0;
|
|
26
|
-
const malloy_types_1 = require("../../../model/malloy_types");
|
|
27
|
-
const expression_def_1 = require("../types/expression-def");
|
|
28
|
-
const malloy_element_1 = require("../types/malloy-element");
|
|
29
|
-
class TopBy extends malloy_element_1.MalloyElement {
|
|
30
|
-
constructor(by) {
|
|
31
|
-
super();
|
|
32
|
-
this.by = by;
|
|
33
|
-
this.elementType = 'topBy';
|
|
34
|
-
if (by instanceof expression_def_1.ExpressionDef) {
|
|
35
|
-
this.has({ by: by });
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
getBy(fs) {
|
|
39
|
-
if (this.by instanceof expression_def_1.ExpressionDef) {
|
|
40
|
-
const byExpr = this.by.getExpression(fs);
|
|
41
|
-
if (!(0, malloy_types_1.expressionIsAggregate)(byExpr.expressionType)) {
|
|
42
|
-
this.logError('top-by-non-aggregate', 'top by expression must be an aggregate');
|
|
43
|
-
}
|
|
44
|
-
return { by: 'expression', e: byExpr.value };
|
|
45
|
-
}
|
|
46
|
-
return { by: 'name', name: this.by };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
exports.TopBy = TopBy;
|
|
50
|
-
//# sourceMappingURL=top-by.js.map
|