@malloydata/malloy 0.0.395 → 0.0.397
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/annotation.d.ts +85 -1
- package/dist/annotation.js +133 -47
- package/dist/api/core.js +2 -7
- package/dist/api/foundation/compile.d.ts +7 -6
- package/dist/api/foundation/compile.js +22 -6
- package/dist/api/foundation/core.d.ts +10 -0
- package/dist/api/foundation/core.js +32 -9
- package/dist/api/foundation/runtime.d.ts +85 -5
- package/dist/api/foundation/runtime.js +184 -14
- package/dist/api/foundation/types.d.ts +2 -0
- package/dist/lang/ast/expressions/expr-func.js +30 -11
- package/dist/lang/ast/expressions/expr-given.js +1 -0
- package/dist/lang/ast/field-space/reference-field.js +1 -1
- package/dist/lang/ast/source-elements/sql-source.js +4 -0
- package/dist/lang/ast/source-elements/table-source.js +4 -0
- package/dist/lang/ast/statements/define-given.d.ts +1 -0
- package/dist/lang/ast/statements/define-given.js +7 -0
- package/dist/lang/ast/statements/import-statement.js +4 -0
- package/dist/lang/ast/types/annotation-elements.d.ts +1 -0
- package/dist/lang/ast/types/annotation-elements.js +10 -3
- package/dist/lang/ast/types/malloy-element.d.ts +1 -0
- package/dist/lang/ast/types/malloy-element.js +4 -0
- package/dist/lang/composite-source-utils.js +1 -1
- package/dist/lang/malloy-to-ast.d.ts +9 -1
- package/dist/lang/malloy-to-ast.js +37 -11
- package/dist/lang/malloy-to-stable-query.js +3 -3
- package/dist/lang/parse-log.d.ts +7 -1
- package/dist/lang/parse-log.js +12 -0
- package/dist/lang/parse-malloy.d.ts +4 -1
- package/dist/lang/parse-malloy.js +26 -4
- package/dist/lang/parse-tree-walkers/model-annotation-walker.js +3 -11
- package/dist/lang/parse-utils.d.ts +10 -2
- package/dist/lang/parse-utils.js +89 -29
- package/dist/lang/test/test-translator.d.ts +19 -5
- package/dist/lang/test/test-translator.js +15 -12
- package/dist/lang/zone.d.ts +2 -0
- package/dist/lang/zone.js +10 -0
- package/dist/model/constant_expression_compiler.js +14 -5
- package/dist/model/expression_compiler.js +19 -17
- package/dist/model/field_instance.js +7 -3
- package/dist/model/given_binding.js +26 -21
- package/dist/model/index.d.ts +1 -0
- package/dist/model/index.js +3 -1
- package/dist/model/malloy_compile_error.d.ts +13 -0
- package/dist/model/malloy_compile_error.js +23 -0
- package/dist/model/malloy_types.d.ts +9 -0
- package/dist/model/persist_utils.js +1 -1
- package/dist/model/query_model_impl.js +2 -1
- package/dist/model/query_node.d.ts +5 -5
- package/dist/model/query_node.js +22 -17
- package/dist/model/query_query.js +23 -11
- package/dist/model/sql_compiled.js +6 -3
- package/dist/prefix.d.ts +51 -0
- package/dist/prefix.js +99 -0
- package/dist/taggable.d.ts +17 -1
- package/dist/test/resultMatchers.js +2 -1
- package/dist/to_stable.d.ts +7 -1
- package/dist/to_stable.js +13 -16
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/dist/annotation.d.ts
CHANGED
|
@@ -1,12 +1,96 @@
|
|
|
1
1
|
import type { Tag } from '@malloydata/malloy-tag';
|
|
2
|
-
import type { Annotation } from './model';
|
|
2
|
+
import type { Annotation, DocumentLocation } from './model';
|
|
3
3
|
import type { LogMessage } from './lang';
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Argument shape for the deprecated RegExp form of
|
|
6
|
+
* {@link annotationToTag}. The RegExp form cannot see block annotations
|
|
7
|
+
* (`#|`…`|#`). Pass a route string to `annotationToTag` instead, or use the
|
|
8
|
+
* {@link Annotations} view on a tagged entity.
|
|
9
|
+
*/
|
|
4
10
|
export interface TagParseSpec {
|
|
5
11
|
prefix?: RegExp;
|
|
6
12
|
}
|
|
13
|
+
/** One annotation, unparsed — its raw text and where its content begins. */
|
|
14
|
+
export interface AnnotationText {
|
|
15
|
+
/** The annotation exactly as written — prefix + content. */
|
|
16
|
+
rawText: string;
|
|
17
|
+
/** Offset where the content begins; `rawText.slice(contentIndex)` is the content. */
|
|
18
|
+
contentIndex: number;
|
|
19
|
+
/** Where `rawText` begins in the source document. */
|
|
20
|
+
at: DocumentLocation;
|
|
21
|
+
/**
|
|
22
|
+
* For block annotations: characters of leading whitespace removed from
|
|
23
|
+
* each body line by the translator's dedent pass. A BYO parser that wants
|
|
24
|
+
* source-mapped error columns adds this to the parser's reported column for
|
|
25
|
+
* body lines (`source_col = indentStripped + parser_col`).
|
|
26
|
+
*/
|
|
27
|
+
indentStripped?: number;
|
|
28
|
+
}
|
|
29
|
+
/** An {@link AnnotationText} that also carries its route (`''` is MOTLY). */
|
|
30
|
+
export interface RoutedAnnotation extends AnnotationText {
|
|
31
|
+
route: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Collect annotations, using the shared prefix parser.
|
|
35
|
+
* - no `route`: every annotation, each carrying its own `route` (the only way
|
|
36
|
+
* to reach one whose prefix is malformed).
|
|
37
|
+
* - a `route`: only annotations on that route, `route` omitted from each result
|
|
38
|
+
* (you passed it); malformed prefixes excluded.
|
|
39
|
+
*/
|
|
40
|
+
export declare function collectAnnotations(annote: Annotation | undefined): RoutedAnnotation[];
|
|
41
|
+
export declare function collectAnnotations(annote: Annotation | undefined, route: string): AnnotationText[];
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated The RegExp form cannot see block annotations (`#|`…`|#`). Use
|
|
44
|
+
* `new Annotations(annote).texts(route)` instead, or the {@link Annotations}
|
|
45
|
+
* view on a tagged entity (`entity.annotations.texts(route)`).
|
|
46
|
+
*/
|
|
7
47
|
export declare function annotationToTaglines(annote: Annotation | undefined, prefix?: RegExp): string[];
|
|
8
48
|
export interface MalloyTagParse {
|
|
9
49
|
tag: Tag;
|
|
10
50
|
log: LogMessage[];
|
|
11
51
|
}
|
|
52
|
+
/** Parse the annotations on `route` (default `''`, the MOTLY tag route) as MOTLY. */
|
|
53
|
+
export declare function annotationToTag(annote: Annotation | undefined, route?: string): MalloyTagParse;
|
|
54
|
+
/**
|
|
55
|
+
* @deprecated The RegExp `prefix` form cannot see block annotations
|
|
56
|
+
* (`#|`…`|#`) and cannot report content offsets for error mapping. Pass a route
|
|
57
|
+
* string (the other overload), or use {@link Annotations.parseAsTag} on a
|
|
58
|
+
* tagged entity.
|
|
59
|
+
*/
|
|
12
60
|
export declare function annotationToTag(annote: Annotation | undefined, spec?: TagParseSpec): MalloyTagParse;
|
|
61
|
+
/**
|
|
62
|
+
* The route-aware annotation API for a tagged entity.
|
|
63
|
+
*
|
|
64
|
+
* An annotation has a *prefix* (everything from `#`/`##` up to the first
|
|
65
|
+
* whitespace) that resolves to a *route* — a namespace key. Built-in routes:
|
|
66
|
+
* `''` (MOTLY tags, the human default), `!` (compiler flags), `@` (persistence
|
|
67
|
+
* directives), `"` (doc-string markdown). Apps stake their own routes with
|
|
68
|
+
* brackets: `#(myApp) ...` is route `myApp`. The grammar (forms, bracket
|
|
69
|
+
* pairs, malformation warnings) lives in `./prefix.ts`.
|
|
70
|
+
*
|
|
71
|
+
* All annotation reading lives here, written once; each tagged class only has
|
|
72
|
+
* to say *where* its annotation is (by handing it to the constructor). Unlike
|
|
73
|
+
* the deprecated RegExp readers (`tagParse`/`getTaglines`), this sees block
|
|
74
|
+
* annotations.
|
|
75
|
+
*/
|
|
76
|
+
export declare class Annotations {
|
|
77
|
+
private readonly annote;
|
|
78
|
+
constructor(annote: Annotation | undefined);
|
|
79
|
+
/**
|
|
80
|
+
* Raw annotation text strings (prefix + content) — all routes if `route` is
|
|
81
|
+
* omitted, just that route's otherwise. The route-based successor to the
|
|
82
|
+
* deprecated `getTaglines`. For source-mapped offsets (bring-your-own
|
|
83
|
+
* parsers), see {@link forRoute}.
|
|
84
|
+
*/
|
|
85
|
+
texts(route?: string): string[];
|
|
86
|
+
/**
|
|
87
|
+
* Your route's annotations as objects (`rawText` + `contentIndex` + `at`) —
|
|
88
|
+
* the bring-your-own-parser door. A non-MOTLY app (e.g. JSON on its own
|
|
89
|
+
* route) reads these to slice the content (`rawText.slice(contentIndex)`)
|
|
90
|
+
* itself and map its parser's errors back to source via `at`. Malformed-prefix
|
|
91
|
+
* annotations are excluded.
|
|
92
|
+
*/
|
|
93
|
+
forRoute(route: string): AnnotationText[];
|
|
94
|
+
/** Parse a route's annotations as a MOTLY tag. Default `''` is the tag route. */
|
|
95
|
+
parseAsTag(route?: string): MalloyTagParse;
|
|
96
|
+
}
|
package/dist/annotation.js
CHANGED
|
@@ -1,50 +1,80 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Annotations = void 0;
|
|
4
|
+
exports.collectAnnotations = collectAnnotations;
|
|
3
5
|
exports.annotationToTaglines = annotationToTaglines;
|
|
4
6
|
exports.annotationToTag = annotationToTag;
|
|
5
7
|
const malloy_tag_1 = require("@malloydata/malloy-tag");
|
|
8
|
+
const prefix_1 = require("./prefix");
|
|
9
|
+
/** Every Note of an annotation, inherited first, in document order. */
|
|
10
|
+
function* notesInOrder(annote) {
|
|
11
|
+
if (annote.inherits)
|
|
12
|
+
yield* notesInOrder(annote.inherits);
|
|
13
|
+
if (annote.blockNotes)
|
|
14
|
+
yield* annote.blockNotes;
|
|
15
|
+
if (annote.notes)
|
|
16
|
+
yield* annote.notes;
|
|
17
|
+
}
|
|
18
|
+
function collectAnnotations(annote, route) {
|
|
19
|
+
if (route === undefined) {
|
|
20
|
+
return Array.from(notesInOrder(annote !== null && annote !== void 0 ? annote : {}), note => {
|
|
21
|
+
const { route: noteRoute, contentIndex } = (0, prefix_1.parsePrefix)(note.text);
|
|
22
|
+
return {
|
|
23
|
+
rawText: note.text,
|
|
24
|
+
contentIndex,
|
|
25
|
+
at: note.at,
|
|
26
|
+
route: noteRoute,
|
|
27
|
+
indentStripped: note.indentStripped,
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const matching = [];
|
|
32
|
+
for (const note of notesInOrder(annote !== null && annote !== void 0 ? annote : {})) {
|
|
33
|
+
const parsed = (0, prefix_1.parsePrefix)(note.text);
|
|
34
|
+
if (parsed.route === route && parsed.malformation !== 'malformed-route') {
|
|
35
|
+
matching.push({
|
|
36
|
+
rawText: note.text,
|
|
37
|
+
contentIndex: parsed.contentIndex,
|
|
38
|
+
at: note.at,
|
|
39
|
+
indentStripped: note.indentStripped,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return matching;
|
|
44
|
+
}
|
|
6
45
|
/**
|
|
7
46
|
* Collect all matching Notes from an Annotation, walking the inherits
|
|
8
47
|
* chain. Returns notes in inheritance order (inherited first).
|
|
48
|
+
*
|
|
49
|
+
* @deprecated RegExp prefix matching; use {@link collectAnnotations} with a route.
|
|
9
50
|
*/
|
|
10
51
|
function collectNotes(annote, prefix) {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
: [];
|
|
14
|
-
const allNotes = [];
|
|
15
|
-
if (annote.blockNotes) {
|
|
16
|
-
allNotes.push(...annote.blockNotes);
|
|
17
|
-
}
|
|
18
|
-
if (annote.notes) {
|
|
19
|
-
allNotes.push(...annote.notes);
|
|
20
|
-
}
|
|
21
|
-
if (prefix) {
|
|
22
|
-
const matching = allNotes.filter(note => note.text.match(prefix));
|
|
23
|
-
return inherited.concat(matching);
|
|
24
|
-
}
|
|
25
|
-
return inherited.concat(allNotes);
|
|
52
|
+
const notes = [...notesInOrder(annote)];
|
|
53
|
+
return prefix ? notes.filter(note => note.text.match(prefix)) : notes;
|
|
26
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* @deprecated The RegExp form cannot see block annotations (`#|`…`|#`). Use
|
|
57
|
+
* `new Annotations(annote).texts(route)` instead, or the {@link Annotations}
|
|
58
|
+
* view on a tagged entity (`entity.annotations.texts(route)`).
|
|
59
|
+
*/
|
|
27
60
|
function annotationToTaglines(annote, prefix) {
|
|
28
61
|
return collectNotes(annote || {}, prefix).map(n => n.text);
|
|
29
62
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
annote || (annote = {});
|
|
33
|
-
const notes = collectNotes(annote, prefix);
|
|
63
|
+
/** Parse a run of Notes as MOTLY into one Tag, collecting errors. */
|
|
64
|
+
function parseTaglines(lines) {
|
|
34
65
|
const allErrs = [];
|
|
35
66
|
const session = new malloy_tag_1.TagParser();
|
|
36
|
-
for (const
|
|
67
|
+
for (const line of lines) {
|
|
37
68
|
const origin = {
|
|
38
|
-
url:
|
|
39
|
-
startLine:
|
|
40
|
-
startColumn:
|
|
69
|
+
url: line.at.url,
|
|
70
|
+
startLine: line.at.range.start.line,
|
|
71
|
+
startColumn: line.at.range.start.character,
|
|
41
72
|
};
|
|
42
|
-
const noteParse = session.parseAnnotation(
|
|
43
|
-
allErrs.push(...noteParse.log.map((e) => mapMalloyError(e,
|
|
73
|
+
const noteParse = session.parseAnnotation(line.text, origin);
|
|
74
|
+
allErrs.push(...noteParse.log.map((e) => mapMalloyError(e, line)));
|
|
44
75
|
}
|
|
45
76
|
const tag = session.finish();
|
|
46
|
-
const
|
|
47
|
-
for (const refError of refErrors) {
|
|
77
|
+
for (const refError of tag.validateReferences()) {
|
|
48
78
|
allErrs.push({
|
|
49
79
|
code: 'tag-reference-error',
|
|
50
80
|
severity: 'warn',
|
|
@@ -53,25 +83,78 @@ function annotationToTag(annote, spec = {}) {
|
|
|
53
83
|
}
|
|
54
84
|
return { tag, log: allErrs };
|
|
55
85
|
}
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
86
|
+
function annotationToTag(annote, arg) {
|
|
87
|
+
if (typeof arg === 'object') {
|
|
88
|
+
const prefix = arg.prefix || /^##? /;
|
|
89
|
+
return parseTaglines(collectNotes(annote !== null && annote !== void 0 ? annote : {}, prefix));
|
|
90
|
+
}
|
|
91
|
+
const matched = collectAnnotations(annote, arg !== null && arg !== void 0 ? arg : '');
|
|
92
|
+
return parseTaglines(matched.map(a => ({
|
|
93
|
+
text: a.rawText,
|
|
94
|
+
at: a.at,
|
|
95
|
+
indentStripped: a.indentStripped,
|
|
96
|
+
})));
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The route-aware annotation API for a tagged entity.
|
|
100
|
+
*
|
|
101
|
+
* An annotation has a *prefix* (everything from `#`/`##` up to the first
|
|
102
|
+
* whitespace) that resolves to a *route* — a namespace key. Built-in routes:
|
|
103
|
+
* `''` (MOTLY tags, the human default), `!` (compiler flags), `@` (persistence
|
|
104
|
+
* directives), `"` (doc-string markdown). Apps stake their own routes with
|
|
105
|
+
* brackets: `#(myApp) ...` is route `myApp`. The grammar (forms, bracket
|
|
106
|
+
* pairs, malformation warnings) lives in `./prefix.ts`.
|
|
107
|
+
*
|
|
108
|
+
* All annotation reading lives here, written once; each tagged class only has
|
|
109
|
+
* to say *where* its annotation is (by handing it to the constructor). Unlike
|
|
110
|
+
* the deprecated RegExp readers (`tagParse`/`getTaglines`), this sees block
|
|
111
|
+
* annotations.
|
|
112
|
+
*/
|
|
113
|
+
class Annotations {
|
|
114
|
+
constructor(annote) {
|
|
115
|
+
this.annote = annote;
|
|
64
116
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Raw annotation text strings (prefix + content) — all routes if `route` is
|
|
119
|
+
* omitted, just that route's otherwise. The route-based successor to the
|
|
120
|
+
* deprecated `getTaglines`. For source-mapped offsets (bring-your-own
|
|
121
|
+
* parsers), see {@link forRoute}.
|
|
122
|
+
*/
|
|
123
|
+
texts(route) {
|
|
124
|
+
const items = route === undefined
|
|
125
|
+
? collectAnnotations(this.annote)
|
|
126
|
+
: collectAnnotations(this.annote, route);
|
|
127
|
+
return items.map(a => a.rawText);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Your route's annotations as objects (`rawText` + `contentIndex` + `at`) —
|
|
131
|
+
* the bring-your-own-parser door. A non-MOTLY app (e.g. JSON on its own
|
|
132
|
+
* route) reads these to slice the content (`rawText.slice(contentIndex)`)
|
|
133
|
+
* itself and map its parser's errors back to source via `at`. Malformed-prefix
|
|
134
|
+
* annotations are excluded.
|
|
135
|
+
*/
|
|
136
|
+
forRoute(route) {
|
|
137
|
+
return collectAnnotations(this.annote, route);
|
|
138
|
+
}
|
|
139
|
+
/** Parse a route's annotations as a MOTLY tag. Default `''` is the tag route. */
|
|
140
|
+
parseAsTag(route = '') {
|
|
141
|
+
return annotationToTag(this.annote, route);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.Annotations = Annotations;
|
|
145
|
+
function mapMalloyError(e, note) {
|
|
146
|
+
var _a;
|
|
147
|
+
// MOTLY reports `e.line` / `e.offset` into the *stripped* note text it
|
|
148
|
+
// parsed. To map back to source:
|
|
149
|
+
// line 0 (opener line): col = opener_col + prefix_len + e.offset
|
|
150
|
+
// line N>0 (body lines): col = indentStripped + e.offset
|
|
151
|
+
// `indentStripped` is the per-line dedent recorded on the Note by the
|
|
152
|
+
// translator (uniform per block, so the same formula serves every body
|
|
153
|
+
// line). Prefix length is everything before the separator, via parsePrefix.
|
|
71
154
|
const line = note.at.range.start.line + e.line;
|
|
72
155
|
const character = e.line === 0
|
|
73
|
-
? note.at.range.start.character +
|
|
74
|
-
: e.offset;
|
|
156
|
+
? note.at.range.start.character + prefixLength(note.text) + e.offset
|
|
157
|
+
: ((_a = note.indentStripped) !== null && _a !== void 0 ? _a : 0) + e.offset;
|
|
75
158
|
const loc = { line, character };
|
|
76
159
|
return {
|
|
77
160
|
code: 'tag-parse-error',
|
|
@@ -79,11 +162,14 @@ function mapMalloyError(e, note) {
|
|
|
79
162
|
message: e.message,
|
|
80
163
|
at: {
|
|
81
164
|
url: note.at.url,
|
|
82
|
-
range: {
|
|
83
|
-
start: loc,
|
|
84
|
-
end: loc,
|
|
85
|
-
},
|
|
165
|
+
range: { start: loc, end: loc },
|
|
86
166
|
},
|
|
87
167
|
};
|
|
88
168
|
}
|
|
169
|
+
/** Length of the annotation prefix per malloy-tag's `stripPrefix`: index of
|
|
170
|
+
* the first whitespace, or 0 if none. */
|
|
171
|
+
function prefixLength(text) {
|
|
172
|
+
const { contentIndex } = (0, prefix_1.parsePrefix)(text);
|
|
173
|
+
return contentIndex === text.length ? 0 : contentIndex - 1;
|
|
174
|
+
}
|
|
89
175
|
//# sourceMappingURL=annotation.js.map
|
package/dist/api/core.js
CHANGED
|
@@ -56,7 +56,6 @@ const lang_1 = require("../lang");
|
|
|
56
56
|
const model_1 = require("../model");
|
|
57
57
|
const to_stable_1 = require("../to_stable");
|
|
58
58
|
const sql_block_1 = require("../model/sql_block");
|
|
59
|
-
const annotation_1 = require("../annotation");
|
|
60
59
|
const malloy_tag_1 = require("@malloydata/malloy-tag");
|
|
61
60
|
const util_1 = require("./util");
|
|
62
61
|
const timing_1 = require("../timing");
|
|
@@ -506,9 +505,7 @@ function statedCompileQuery(state) {
|
|
|
506
505
|
defaultRowLimit: state.defaultRowLimit,
|
|
507
506
|
});
|
|
508
507
|
timer.contribute([sqlTimer.stop()]);
|
|
509
|
-
const modelAnnotations = (0,
|
|
510
|
-
value: l,
|
|
511
|
-
}));
|
|
508
|
+
const modelAnnotations = (0, to_stable_1.toStableAnnotations)(result.modelDef.annotation);
|
|
512
509
|
let source;
|
|
513
510
|
if (query.compositeResolvedSourceDef) {
|
|
514
511
|
source = query.compositeResolvedSourceDef;
|
|
@@ -522,9 +519,7 @@ function statedCompileQuery(state) {
|
|
|
522
519
|
source = (0, model_1.safeRecordGet)(result.modelDef.contents, query.structRef);
|
|
523
520
|
}
|
|
524
521
|
}
|
|
525
|
-
const sourceAnnotations = (0,
|
|
526
|
-
value: l,
|
|
527
|
-
}));
|
|
522
|
+
const sourceAnnotations = (0, to_stable_1.toStableAnnotations)(source.annotation);
|
|
528
523
|
const sourceMetadataTag = malloy_tag_1.Tag.withPrefix('#(malloy) ');
|
|
529
524
|
sourceMetadataTag.set(['source', 'name'], translatedQuery.sourceExplore);
|
|
530
525
|
const sourceArguments = (_b = translatedQuery.sourceArguments) !== null && _b !== void 0 ? _b : ((0, model_1.isSourceDef)(source) ? source.arguments : undefined);
|
|
@@ -54,6 +54,12 @@ export declare class MalloyError extends Error {
|
|
|
54
54
|
*/
|
|
55
55
|
constructor(message: string, problems?: LogMessage[]);
|
|
56
56
|
}
|
|
57
|
+
type CompileRequest = Compilable & CompileOptions & CompileQueryOptions & ParseOptions & {
|
|
58
|
+
urlReader: URLReader;
|
|
59
|
+
connections: LookupConnection<InfoConnection>;
|
|
60
|
+
model?: Model;
|
|
61
|
+
cacheManager?: CacheManager;
|
|
62
|
+
};
|
|
57
63
|
export declare class Malloy {
|
|
58
64
|
static get version(): string;
|
|
59
65
|
/**
|
|
@@ -109,12 +115,7 @@ export declare class Malloy {
|
|
|
109
115
|
* @param model A compiled model to build upon (optional).
|
|
110
116
|
* @return A (promise of a) compiled `Model`.
|
|
111
117
|
*/
|
|
112
|
-
static compile(
|
|
113
|
-
urlReader: URLReader;
|
|
114
|
-
connections: LookupConnection<InfoConnection>;
|
|
115
|
-
model?: Model;
|
|
116
|
-
cacheManager?: CacheManager;
|
|
117
|
-
} & Compilable & CompileOptions & CompileQueryOptions & ParseOptions): Promise<Model>;
|
|
118
|
+
static compile(req: CompileRequest): Promise<Model>;
|
|
118
119
|
/**
|
|
119
120
|
* A dialect must provide a response for every table, or the translator loop
|
|
120
121
|
* will never exit. Because there was a time when this happened, we throw
|
|
@@ -37,9 +37,6 @@ class MalloyError extends Error {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
exports.MalloyError = MalloyError;
|
|
40
|
-
// =============================================================================
|
|
41
|
-
// Malloy Static Class
|
|
42
|
-
// =============================================================================
|
|
43
40
|
class Malloy {
|
|
44
41
|
static get version() {
|
|
45
42
|
return version_1.MALLOY_VERSION;
|
|
@@ -70,6 +67,7 @@ class Malloy {
|
|
|
70
67
|
return (0, registry_1.getRegisteredConnectionTypes)();
|
|
71
68
|
}
|
|
72
69
|
static _parse(source, url, eventStream, options, invalidationKey) {
|
|
70
|
+
var _a;
|
|
73
71
|
if (url === undefined) {
|
|
74
72
|
url = new URL(MALLOY_INTERNAL_URL);
|
|
75
73
|
}
|
|
@@ -79,7 +77,7 @@ class Malloy {
|
|
|
79
77
|
}
|
|
80
78
|
const translator = new lang_1.MalloyTranslator(url.toString(), importBaseURL.toString(), {
|
|
81
79
|
urls: { [url.toString()]: source },
|
|
82
|
-
}, eventStream);
|
|
80
|
+
}, eventStream, (_a = options === null || options === void 0 ? void 0 : options.restrictedMode) !== null && _a !== void 0 ? _a : false);
|
|
83
81
|
if (options === null || options === void 0 ? void 0 : options.testEnvironment) {
|
|
84
82
|
translator.allDialectsEnabled = true;
|
|
85
83
|
}
|
|
@@ -110,8 +108,19 @@ class Malloy {
|
|
|
110
108
|
* @param model A compiled model to build upon (optional).
|
|
111
109
|
* @return A (promise of a) compiled `Model`.
|
|
112
110
|
*/
|
|
113
|
-
static async compile(
|
|
111
|
+
static async compile(req) {
|
|
114
112
|
var _a, _b, _c, _d, _e;
|
|
113
|
+
let { url, source, importBaseURL, cacheManager } = req;
|
|
114
|
+
const { parse, urlReader, connections, model, refreshSchemaCache, noThrowOnError, eventStream, restrictedMode, } = req;
|
|
115
|
+
if (restrictedMode) {
|
|
116
|
+
// Restricted-mode compiles do not participate in the model-def
|
|
117
|
+
// cache. The cache key is the URL, but restricted vs. unrestricted
|
|
118
|
+
// produces different validation outcomes, so allowing a restricted
|
|
119
|
+
// compile to serve from (or write to) the same cache as
|
|
120
|
+
// unrestricted compiles would let restricted mode be bypassed by a
|
|
121
|
+
// prior unrestricted compile of the same URL.
|
|
122
|
+
cacheManager = undefined;
|
|
123
|
+
}
|
|
115
124
|
let refreshTimestamp;
|
|
116
125
|
if (refreshSchemaCache) {
|
|
117
126
|
refreshTimestamp =
|
|
@@ -145,6 +154,13 @@ class Malloy {
|
|
|
145
154
|
// It's not cached, so we may need to get the actual source
|
|
146
155
|
const _url = url.toString();
|
|
147
156
|
if (parse !== undefined) {
|
|
157
|
+
// A pre-parsed translator's restrictedMode was fixed at parse
|
|
158
|
+
// time and cannot be changed here. Loudly reject mismatched
|
|
159
|
+
// requests rather than silently inheriting the parse-time value.
|
|
160
|
+
if (restrictedMode !== undefined &&
|
|
161
|
+
parse._translator.restrictedMode !== restrictedMode) {
|
|
162
|
+
throw new Error(`Malloy.compile: restrictedMode (${restrictedMode}) does not match the pre-parsed translator's restrictedMode (${parse._translator.restrictedMode}). Set restrictedMode at parse time.`);
|
|
163
|
+
}
|
|
148
164
|
translator = parse._translator;
|
|
149
165
|
const invalidationKey = (_a = parse._invalidationKey) !== null && _a !== void 0 ? _a : (await (0, readers_1.getInvalidationKey)(urlReader, url));
|
|
150
166
|
invalidationKeys[_url] = invalidationKey;
|
|
@@ -161,7 +177,7 @@ class Malloy {
|
|
|
161
177
|
}
|
|
162
178
|
translator = new lang_1.MalloyTranslator(_url, importBaseURL.toString(), {
|
|
163
179
|
urls: { [_url]: source },
|
|
164
|
-
}, eventStream);
|
|
180
|
+
}, eventStream, restrictedMode !== null && restrictedMode !== void 0 ? restrictedMode : false);
|
|
165
181
|
}
|
|
166
182
|
for (;;) {
|
|
167
183
|
const result = translator.translate(model === null || model === void 0 ? void 0 : model._modelDef);
|
|
@@ -5,6 +5,7 @@ import type { Dialect } from '../../dialect';
|
|
|
5
5
|
import type { BuildGraph, CompileQueryOptions } from './types';
|
|
6
6
|
import { Tag } from '@malloydata/malloy-tag';
|
|
7
7
|
import type { MalloyTagParse, TagParseSpec } from '../../annotation';
|
|
8
|
+
import { Annotations } from '../../annotation';
|
|
8
9
|
import type * as Malloy from '@malloydata/malloy-interfaces';
|
|
9
10
|
import type { Taggable } from '../../taggable';
|
|
10
11
|
declare abstract class Entity {
|
|
@@ -101,6 +102,7 @@ export declare class Explore extends Entity implements Taggable {
|
|
|
101
102
|
isExploreField(): this is ExploreField;
|
|
102
103
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
103
104
|
getTaglines(prefix?: RegExp): string[];
|
|
105
|
+
get annotations(): Annotations;
|
|
104
106
|
private parsedModelTag?;
|
|
105
107
|
get modelTag(): Tag;
|
|
106
108
|
/**
|
|
@@ -141,6 +143,7 @@ export declare class AtomicField extends Entity implements Taggable {
|
|
|
141
143
|
get type(): AtomicFieldType;
|
|
142
144
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
143
145
|
getTaglines(prefix?: RegExp): string[];
|
|
146
|
+
get annotations(): Annotations;
|
|
144
147
|
isIntrinsic(): boolean;
|
|
145
148
|
isQueryField(): this is QueryField;
|
|
146
149
|
isExploreField(): this is ExploreField;
|
|
@@ -208,6 +211,7 @@ export declare class QueryField extends Query implements Taggable {
|
|
|
208
211
|
constructor(turtleDef: TurtleDef, parent: Explore, source?: Query);
|
|
209
212
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
210
213
|
getTaglines(prefix?: RegExp): string[];
|
|
214
|
+
get annotations(): Annotations;
|
|
211
215
|
isQueryField(): this is QueryField;
|
|
212
216
|
isExploreField(): this is ExploreField;
|
|
213
217
|
isAtomicField(): this is AtomicField;
|
|
@@ -223,6 +227,7 @@ export declare class ExploreField extends Explore {
|
|
|
223
227
|
get isRecord(): boolean;
|
|
224
228
|
get isArray(): boolean;
|
|
225
229
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
230
|
+
get annotations(): Annotations;
|
|
226
231
|
isQueryField(): this is QueryField;
|
|
227
232
|
isExploreField(): this is ExploreField;
|
|
228
233
|
isAtomicField(): this is AtomicField;
|
|
@@ -282,6 +287,7 @@ export declare class Model implements Taggable {
|
|
|
282
287
|
get givens(): ReadonlyMap<string, Given>;
|
|
283
288
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
284
289
|
getTaglines(prefix?: RegExp): string[];
|
|
290
|
+
get annotations(): Annotations;
|
|
285
291
|
/**
|
|
286
292
|
* Retrieve a document reference for the token at the given position within
|
|
287
293
|
* the document that produced this model.
|
|
@@ -419,6 +425,7 @@ export declare class PersistSource implements Taggable {
|
|
|
419
425
|
* Get annotation taglines matching an optional prefix.
|
|
420
426
|
*/
|
|
421
427
|
getTaglines(prefix?: RegExp): string[];
|
|
428
|
+
get annotations(): Annotations;
|
|
422
429
|
/**
|
|
423
430
|
* The connection name for this source.
|
|
424
431
|
*/
|
|
@@ -484,6 +491,7 @@ export declare class Given implements Taggable {
|
|
|
484
491
|
get location(): DocumentLocation | undefined;
|
|
485
492
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
486
493
|
getTaglines(prefix?: RegExp): string[];
|
|
494
|
+
get annotations(): Annotations;
|
|
487
495
|
}
|
|
488
496
|
export declare class PreparedQuery implements Taggable {
|
|
489
497
|
private _model;
|
|
@@ -494,6 +502,7 @@ export declare class PreparedQuery implements Taggable {
|
|
|
494
502
|
get _modelDef(): ModelDef;
|
|
495
503
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
496
504
|
getTaglines(prefix?: RegExp): string[];
|
|
505
|
+
get annotations(): Annotations;
|
|
497
506
|
/**
|
|
498
507
|
* Generate the SQL for this query.
|
|
499
508
|
*
|
|
@@ -537,6 +546,7 @@ export declare class PreparedResult implements Taggable {
|
|
|
537
546
|
static fromJson({ query, modelDef, }: PreparedResultJSON): PreparedResult;
|
|
538
547
|
tagParse(spec?: TagParseSpec): MalloyTagParse;
|
|
539
548
|
getTaglines(prefix?: RegExp): string[];
|
|
549
|
+
get annotations(): Annotations;
|
|
540
550
|
get annotation(): Annotation | undefined;
|
|
541
551
|
get modelAnnotation(): Annotation | undefined;
|
|
542
552
|
get modelTag(): Tag;
|
|
@@ -154,8 +154,11 @@ class Explore extends Entity {
|
|
|
154
154
|
getTaglines(prefix) {
|
|
155
155
|
return (0, annotation_1.annotationToTaglines)(this._structDef.annotation, prefix);
|
|
156
156
|
}
|
|
157
|
+
get annotations() {
|
|
158
|
+
return new annotation_1.Annotations(this._structDef.annotation);
|
|
159
|
+
}
|
|
157
160
|
get modelTag() {
|
|
158
|
-
this.parsedModelTag || (this.parsedModelTag =
|
|
161
|
+
this.parsedModelTag || (this.parsedModelTag = new annotation_1.Annotations(this._structDef.modelAnnotation).parseAsTag().tag);
|
|
159
162
|
return this.parsedModelTag;
|
|
160
163
|
}
|
|
161
164
|
/**
|
|
@@ -465,6 +468,9 @@ class AtomicField extends Entity {
|
|
|
465
468
|
getTaglines(prefix) {
|
|
466
469
|
return (0, annotation_1.annotationToTaglines)(this.fieldTypeDef.annotation, prefix);
|
|
467
470
|
}
|
|
471
|
+
get annotations() {
|
|
472
|
+
return new annotation_1.Annotations(this.fieldTypeDef.annotation);
|
|
473
|
+
}
|
|
468
474
|
isIntrinsic() {
|
|
469
475
|
return (0, model_1.fieldIsIntrinsic)(this.fieldTypeDef);
|
|
470
476
|
}
|
|
@@ -666,6 +672,9 @@ class QueryField extends Query {
|
|
|
666
672
|
getTaglines(prefix) {
|
|
667
673
|
return (0, annotation_1.annotationToTaglines)(this.turtleDef.annotation, prefix);
|
|
668
674
|
}
|
|
675
|
+
get annotations() {
|
|
676
|
+
return new annotation_1.Annotations(this.turtleDef.annotation);
|
|
677
|
+
}
|
|
669
678
|
isQueryField() {
|
|
670
679
|
return true;
|
|
671
680
|
}
|
|
@@ -719,6 +728,9 @@ class ExploreField extends Explore {
|
|
|
719
728
|
tagParse(spec) {
|
|
720
729
|
return (0, annotation_1.annotationToTag)(this._structDef.annotation, spec);
|
|
721
730
|
}
|
|
731
|
+
get annotations() {
|
|
732
|
+
return new annotation_1.Annotations(this._structDef.annotation);
|
|
733
|
+
}
|
|
722
734
|
isQueryField() {
|
|
723
735
|
return false;
|
|
724
736
|
}
|
|
@@ -807,6 +819,9 @@ class Model {
|
|
|
807
819
|
getTaglines(prefix) {
|
|
808
820
|
return (0, annotation_1.annotationToTaglines)(this.modelDef.annotation, prefix);
|
|
809
821
|
}
|
|
822
|
+
get annotations() {
|
|
823
|
+
return new annotation_1.Annotations(this.modelDef.annotation);
|
|
824
|
+
}
|
|
810
825
|
/**
|
|
811
826
|
* Retrieve a document reference for the token at the given position within
|
|
812
827
|
* the document that produced this model.
|
|
@@ -932,7 +947,7 @@ class Model {
|
|
|
932
947
|
*/
|
|
933
948
|
getBuildPlan() {
|
|
934
949
|
// Require experimental.persistence compiler flag
|
|
935
|
-
const modelTag = this.
|
|
950
|
+
const modelTag = this.annotations.parseAsTag('!').tag;
|
|
936
951
|
if (!modelTag.has('experimental', 'persistence')) {
|
|
937
952
|
throw new Error('Model must have ##! experimental.persistence to use getBuildPlan()');
|
|
938
953
|
}
|
|
@@ -1057,6 +1072,9 @@ class PersistSource {
|
|
|
1057
1072
|
getTaglines(prefix) {
|
|
1058
1073
|
return this.explore.getTaglines(prefix);
|
|
1059
1074
|
}
|
|
1075
|
+
get annotations() {
|
|
1076
|
+
return this.explore.annotations;
|
|
1077
|
+
}
|
|
1060
1078
|
/**
|
|
1061
1079
|
* The connection name for this source.
|
|
1062
1080
|
*/
|
|
@@ -1159,6 +1177,9 @@ class Given {
|
|
|
1159
1177
|
getTaglines(prefix) {
|
|
1160
1178
|
return (0, annotation_1.annotationToTaglines)(this._internal.annotation, prefix);
|
|
1161
1179
|
}
|
|
1180
|
+
get annotations() {
|
|
1181
|
+
return new annotation_1.Annotations(this._internal.annotation);
|
|
1182
|
+
}
|
|
1162
1183
|
}
|
|
1163
1184
|
exports.Given = Given;
|
|
1164
1185
|
class PreparedQuery {
|
|
@@ -1177,6 +1198,9 @@ class PreparedQuery {
|
|
|
1177
1198
|
getTaglines(prefix) {
|
|
1178
1199
|
return (0, annotation_1.annotationToTaglines)(this._query.annotation, prefix);
|
|
1179
1200
|
}
|
|
1201
|
+
get annotations() {
|
|
1202
|
+
return new annotation_1.Annotations(this._query.annotation);
|
|
1203
|
+
}
|
|
1180
1204
|
/**
|
|
1181
1205
|
* Generate the SQL for this query.
|
|
1182
1206
|
*
|
|
@@ -1281,6 +1305,9 @@ class PreparedResult {
|
|
|
1281
1305
|
getTaglines(prefix) {
|
|
1282
1306
|
return (0, annotation_1.annotationToTaglines)(this.inner.annotation, prefix);
|
|
1283
1307
|
}
|
|
1308
|
+
get annotations() {
|
|
1309
|
+
return new annotation_1.Annotations(this.inner.annotation);
|
|
1310
|
+
}
|
|
1284
1311
|
get annotation() {
|
|
1285
1312
|
return this.inner.annotation;
|
|
1286
1313
|
}
|
|
@@ -1288,7 +1315,7 @@ class PreparedResult {
|
|
|
1288
1315
|
return this.modelDef.annotation;
|
|
1289
1316
|
}
|
|
1290
1317
|
get modelTag() {
|
|
1291
|
-
return
|
|
1318
|
+
return new annotation_1.Annotations(this.modelDef.annotation).parseAsTag().tag;
|
|
1292
1319
|
}
|
|
1293
1320
|
/**
|
|
1294
1321
|
* @return The name of the connection this query should be run against.
|
|
@@ -1361,9 +1388,7 @@ class PreparedResult {
|
|
|
1361
1388
|
const structs = this.inner.structs;
|
|
1362
1389
|
const struct = structs[structs.length - 1];
|
|
1363
1390
|
const schema = { fields: (0, to_stable_1.convertFieldInfos)(struct, struct.fields) };
|
|
1364
|
-
const annotations = (0,
|
|
1365
|
-
value: l,
|
|
1366
|
-
}));
|
|
1391
|
+
const annotations = (0, to_stable_1.toStableAnnotations)(this.inner.annotation);
|
|
1367
1392
|
const metadataAnnot = struct.resultMetadata
|
|
1368
1393
|
? (0, to_stable_1.getResultStructMetadataAnnotation)(struct, struct.resultMetadata)
|
|
1369
1394
|
: undefined;
|
|
@@ -1392,9 +1417,7 @@ class PreparedResult {
|
|
|
1392
1417
|
.set(['query_name'], this.inner.queryName || struct.name)
|
|
1393
1418
|
.toString(),
|
|
1394
1419
|
});
|
|
1395
|
-
const modelAnnotations = (0,
|
|
1396
|
-
value: l,
|
|
1397
|
-
}));
|
|
1420
|
+
const modelAnnotations = (0, to_stable_1.toStableAnnotations)(this.modelDef.annotation);
|
|
1398
1421
|
return {
|
|
1399
1422
|
schema,
|
|
1400
1423
|
data,
|