@malloydata/malloy 0.0.373 → 0.0.375
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/api/foundation/config.d.ts +6 -4
- package/dist/api/foundation/config.js +43 -19
- package/dist/api/foundation/config_discover.js +6 -27
- package/dist/api/foundation/config_lookup.d.ts +31 -0
- package/dist/api/foundation/config_lookup.js +180 -0
- package/dist/api/foundation/config_overlays.d.ts +8 -1
- package/dist/api/foundation/config_resolve.d.ts +26 -36
- package/dist/api/foundation/config_resolve.js +66 -180
- package/dist/connection/registry.d.ts +6 -0
- package/dist/connection/registry.js +9 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
|
@@ -161,10 +161,12 @@ export declare class MalloyConfig {
|
|
|
161
161
|
*
|
|
162
162
|
* Returns the value the named overlay produces for the given path,
|
|
163
163
|
* or `undefined` if the overlay doesn't exist or the path has no value.
|
|
164
|
+
* Async because overlays may be async (secret stores, session readers);
|
|
165
|
+
* `await` tolerates both sync and Promise return types.
|
|
164
166
|
*
|
|
165
|
-
* config.readOverlay('config', 'rootDirectory')
|
|
166
|
-
* config.readOverlay('config', 'configURL')
|
|
167
|
-
* config.readOverlay('env', 'PG_PASSWORD')
|
|
167
|
+
* await config.readOverlay('config', 'rootDirectory')
|
|
168
|
+
* await config.readOverlay('config', 'configURL')
|
|
169
|
+
* await config.readOverlay('env', 'PG_PASSWORD')
|
|
168
170
|
*/
|
|
169
|
-
readOverlay(overlayName: string, ...path: string[]): unknown
|
|
171
|
+
readOverlay(overlayName: string, ...path: string[]): Promise<unknown>;
|
|
170
172
|
}
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.MalloyConfig = exports.Manifest = void 0;
|
|
8
|
-
const registry_1 = require("../../connection/registry");
|
|
9
8
|
const config_compile_1 = require("./config_compile");
|
|
10
9
|
const config_resolve_1 = require("./config_resolve");
|
|
10
|
+
const config_lookup_1 = require("./config_lookup");
|
|
11
11
|
const config_overlays_1 = require("./config_overlays");
|
|
12
12
|
/**
|
|
13
13
|
* In-memory manifest store. Reads, updates, and serializes manifest data.
|
|
@@ -175,24 +175,25 @@ class MalloyConfig {
|
|
|
175
175
|
// Compile → typed tree + validation warnings.
|
|
176
176
|
const compiled = (0, config_compile_1.compileConfig)(pojo);
|
|
177
177
|
log.push(...compiled.log);
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
// is added.
|
|
178
|
+
// Merge the host-supplied overlays onto the defaults. Same-named
|
|
179
|
+
// entries replace defaults; new keys are added.
|
|
181
180
|
const mergedOverlays = {
|
|
182
181
|
...(0, config_overlays_1.defaultConfigOverlays)(),
|
|
183
182
|
...overlays,
|
|
184
183
|
};
|
|
185
|
-
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
// Synchronous prep: extract literal sections (manifestPath, virtualMap),
|
|
185
|
+
// pull out compiled connection subtrees, fabricate bare entries for
|
|
186
|
+
// missing registered types when `includeDefaultConnections` is set.
|
|
187
|
+
// Reference resolution for connection properties is *not* done here —
|
|
188
|
+
// it happens async at `lookupConnection` time, so overlays that touch
|
|
189
|
+
// IO (secret stores, session reads) have a natural async seam.
|
|
190
|
+
const prepared = (0, config_resolve_1.prepareConfig)(compiled.compiled, log);
|
|
191
|
+
this._managedLookup = (0, config_lookup_1.buildManagedLookup)(prepared.compiledConnections, mergedOverlays, log);
|
|
191
192
|
this._connections = this._managedLookup;
|
|
192
193
|
this._overlays = mergedOverlays;
|
|
193
|
-
this.virtualMap = toVirtualMap(
|
|
194
|
-
this.manifestPath =
|
|
195
|
-
this.manifestURL = computeManifestURL(
|
|
194
|
+
this.virtualMap = toVirtualMap(prepared.virtualMap);
|
|
195
|
+
this.manifestPath = prepared.manifestPath;
|
|
196
|
+
this.manifestURL = computeManifestURL(prepared.manifestPath, mergedOverlays, log);
|
|
196
197
|
this.log = log;
|
|
197
198
|
}
|
|
198
199
|
/**
|
|
@@ -245,14 +246,16 @@ class MalloyConfig {
|
|
|
245
246
|
*
|
|
246
247
|
* Returns the value the named overlay produces for the given path,
|
|
247
248
|
* or `undefined` if the overlay doesn't exist or the path has no value.
|
|
249
|
+
* Async because overlays may be async (secret stores, session readers);
|
|
250
|
+
* `await` tolerates both sync and Promise return types.
|
|
248
251
|
*
|
|
249
|
-
* config.readOverlay('config', 'rootDirectory')
|
|
250
|
-
* config.readOverlay('config', 'configURL')
|
|
251
|
-
* config.readOverlay('env', 'PG_PASSWORD')
|
|
252
|
+
* await config.readOverlay('config', 'rootDirectory')
|
|
253
|
+
* await config.readOverlay('config', 'configURL')
|
|
254
|
+
* await config.readOverlay('env', 'PG_PASSWORD')
|
|
252
255
|
*/
|
|
253
|
-
readOverlay(overlayName, ...path) {
|
|
256
|
+
async readOverlay(overlayName, ...path) {
|
|
254
257
|
var _a, _b;
|
|
255
|
-
return (_b = (_a = this._overlays)[overlayName]) === null || _b === void 0 ? void 0 : _b.call(_a, path);
|
|
258
|
+
return await ((_b = (_a = this._overlays)[overlayName]) === null || _b === void 0 ? void 0 : _b.call(_a, path));
|
|
256
259
|
}
|
|
257
260
|
}
|
|
258
261
|
exports.MalloyConfig = MalloyConfig;
|
|
@@ -276,6 +279,14 @@ const MANIFEST_FILENAME = 'malloy-manifest.json';
|
|
|
276
279
|
*
|
|
277
280
|
* Rules:
|
|
278
281
|
* - If there's no `configURL` in the `config` overlay → undefined.
|
|
282
|
+
* - **The `config` overlay MUST resolve `configURL` synchronously.** This
|
|
283
|
+
* is the one construction-time overlay call; it runs before the first
|
|
284
|
+
* `lookupConnection` and must return a plain string (or undefined). If
|
|
285
|
+
* it returns a Promise, `manifestURL` would be `undefined` — persistence
|
|
286
|
+
* would silently stop working. To avoid the silent failure, we warn on
|
|
287
|
+
* Promise returns so hosts discover the mistake. Other fields inside the
|
|
288
|
+
* `config` overlay (`rootDirectory`, etc.) can still be async; only
|
|
289
|
+
* `configURL` is sync-only.
|
|
279
290
|
* - `manifestPath` defaults to `'MANIFESTS'`.
|
|
280
291
|
* - `new URL(manifestPath, configURL)` handles three shapes uniformly:
|
|
281
292
|
* "MANIFESTS" → relative to configURL's directory
|
|
@@ -285,9 +296,17 @@ const MANIFEST_FILENAME = 'malloy-manifest.json';
|
|
|
285
296
|
* - A trailing slash is forced onto the directory portion so that the
|
|
286
297
|
* final `new URL(MANIFEST_FILENAME, dir)` joins correctly.
|
|
287
298
|
*/
|
|
288
|
-
function computeManifestURL(manifestPath, overlays) {
|
|
299
|
+
function computeManifestURL(manifestPath, overlays, log) {
|
|
289
300
|
const configOverlay = overlays['config'];
|
|
290
301
|
const configURLValue = configOverlay === null || configOverlay === void 0 ? void 0 : configOverlay(['configURL']);
|
|
302
|
+
if (isThenable(configURLValue)) {
|
|
303
|
+
log.push({
|
|
304
|
+
message: 'the `config` overlay returned a Promise for `configURL`; `configURL` must be resolved synchronously. manifestURL will be undefined and persistence will not work.',
|
|
305
|
+
severity: 'warn',
|
|
306
|
+
code: 'config-overlay',
|
|
307
|
+
});
|
|
308
|
+
return undefined;
|
|
309
|
+
}
|
|
291
310
|
if (typeof configURLValue !== 'string')
|
|
292
311
|
return undefined;
|
|
293
312
|
let configURL;
|
|
@@ -336,6 +355,11 @@ function toVirtualMap(raw) {
|
|
|
336
355
|
function isRecord(value) {
|
|
337
356
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
338
357
|
}
|
|
358
|
+
function isThenable(value) {
|
|
359
|
+
return (typeof value === 'object' &&
|
|
360
|
+
value !== null &&
|
|
361
|
+
typeof value.then === 'function');
|
|
362
|
+
}
|
|
339
363
|
function isBuildManifestEntry(value) {
|
|
340
364
|
return isRecord(value) && typeof value['tableName'] === 'string';
|
|
341
365
|
}
|
|
@@ -82,35 +82,14 @@ async function tryReadAtLevel(dirURL, urlReader) {
|
|
|
82
82
|
tryReadJSON(sharedURL, urlReader),
|
|
83
83
|
tryReadJSON(localURL, urlReader),
|
|
84
84
|
]);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Shallow-merge top-level keys, local wins. `connections` is the one
|
|
89
|
-
// section we deep-merge by entry name (local winning) — the documented
|
|
90
|
-
// shop workflow is shared credentials as env refs in git, local
|
|
91
|
-
// overrides with literal values outside git.
|
|
92
|
-
//
|
|
93
|
-
// All other sections (virtualMap, manifestPath, includeDefaultConnections)
|
|
94
|
-
// are replaced wholesale when present in the local file. If you want to
|
|
95
|
-
// augment a shared virtualMap from the local file, you have to copy
|
|
96
|
-
// the shared entries into the local file explicitly.
|
|
97
|
-
const sharedConns = isRecord(sharedPOJO['connections'])
|
|
98
|
-
? sharedPOJO['connections']
|
|
99
|
-
: {};
|
|
100
|
-
const localConns = isRecord(localPOJO['connections'])
|
|
101
|
-
? localPOJO['connections']
|
|
102
|
-
: {};
|
|
103
|
-
const merged = {
|
|
104
|
-
...sharedPOJO,
|
|
105
|
-
...localPOJO,
|
|
106
|
-
connections: { ...sharedConns, ...localConns },
|
|
107
|
-
};
|
|
108
|
-
return { configURL: localURL, pojo: merged };
|
|
109
|
-
}
|
|
85
|
+
// Local supersedes shared entirely when both exist — no merging of any
|
|
86
|
+
// kind. The person writing a local file is responsible for including
|
|
87
|
+
// everything they need.
|
|
110
88
|
if (localPOJO)
|
|
111
89
|
return { configURL: localURL, pojo: localPOJO };
|
|
112
|
-
|
|
113
|
-
|
|
90
|
+
if (sharedPOJO)
|
|
91
|
+
return { configURL: sharedURL, pojo: sharedPOJO };
|
|
92
|
+
return null;
|
|
114
93
|
}
|
|
115
94
|
/**
|
|
116
95
|
* Try to read and parse a config file at `url`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LogMessage } from '../../lang/parse-log';
|
|
2
|
+
import type { ManagedConnectionLookup } from '../../connection/registry';
|
|
3
|
+
import type { ConfigDict } from './config_compile';
|
|
4
|
+
import type { ConfigOverlays } from './config_overlays';
|
|
5
|
+
/**
|
|
6
|
+
* Build the `ManagedConnectionLookup` a `MalloyConfig` hands to Runtime.
|
|
7
|
+
*
|
|
8
|
+
* Reference resolution and property-default application run *per lookup*,
|
|
9
|
+
* asynchronously. This is the point where overlays are actually called —
|
|
10
|
+
* which means secret stores, session readers, and any other IO-backed
|
|
11
|
+
* overlay has a natural async seam to live in. Construction of the
|
|
12
|
+
* `MalloyConfig` stays synchronous and zero-IO.
|
|
13
|
+
*
|
|
14
|
+
* Lookup flow for a connection name:
|
|
15
|
+
* 1. Find its compiled entry. Throw if the name is unknown.
|
|
16
|
+
* 2. Walk the entry tree, `await`-ing each overlay reference.
|
|
17
|
+
* 3. Fill in any property whose definition carries a `default` and that
|
|
18
|
+
* the user didn't specify (including post-step-2 drops from unresolved
|
|
19
|
+
* inline references).
|
|
20
|
+
* 4. Hand the resolved POJO to the registered factory.
|
|
21
|
+
* 5. Cache the resulting `Connection` by name so subsequent lookups skip
|
|
22
|
+
* the whole pipeline.
|
|
23
|
+
*
|
|
24
|
+
* Warnings collected during steps 2–3 (unknown overlay source) are pushed
|
|
25
|
+
* into the shared `log` array — same array exposed as `MalloyConfig.log`.
|
|
26
|
+
* The log grows the first time a connection is looked up; callers that
|
|
27
|
+
* read `log` before any lookup won't see resolution warnings. That's an
|
|
28
|
+
* intentional consequence of deferred resolution: we don't pay for
|
|
29
|
+
* warnings on connections nobody asks about.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildManagedLookup(compiledConnections: Record<string, ConfigDict>, overlays: ConfigOverlays, log: LogMessage[]): ManagedConnectionLookup;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright Contributors to the Malloy project
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.buildManagedLookup = buildManagedLookup;
|
|
8
|
+
const registry_1 = require("../../connection/registry");
|
|
9
|
+
/**
|
|
10
|
+
* Build the `ManagedConnectionLookup` a `MalloyConfig` hands to Runtime.
|
|
11
|
+
*
|
|
12
|
+
* Reference resolution and property-default application run *per lookup*,
|
|
13
|
+
* asynchronously. This is the point where overlays are actually called —
|
|
14
|
+
* which means secret stores, session readers, and any other IO-backed
|
|
15
|
+
* overlay has a natural async seam to live in. Construction of the
|
|
16
|
+
* `MalloyConfig` stays synchronous and zero-IO.
|
|
17
|
+
*
|
|
18
|
+
* Lookup flow for a connection name:
|
|
19
|
+
* 1. Find its compiled entry. Throw if the name is unknown.
|
|
20
|
+
* 2. Walk the entry tree, `await`-ing each overlay reference.
|
|
21
|
+
* 3. Fill in any property whose definition carries a `default` and that
|
|
22
|
+
* the user didn't specify (including post-step-2 drops from unresolved
|
|
23
|
+
* inline references).
|
|
24
|
+
* 4. Hand the resolved POJO to the registered factory.
|
|
25
|
+
* 5. Cache the resulting `Connection` by name so subsequent lookups skip
|
|
26
|
+
* the whole pipeline.
|
|
27
|
+
*
|
|
28
|
+
* Warnings collected during steps 2–3 (unknown overlay source) are pushed
|
|
29
|
+
* into the shared `log` array — same array exposed as `MalloyConfig.log`.
|
|
30
|
+
* The log grows the first time a connection is looked up; callers that
|
|
31
|
+
* read `log` before any lookup won't see resolution warnings. That's an
|
|
32
|
+
* intentional consequence of deferred resolution: we don't pay for
|
|
33
|
+
* warnings on connections nobody asks about.
|
|
34
|
+
*/
|
|
35
|
+
function buildManagedLookup(compiledConnections, overlays, log) {
|
|
36
|
+
const entries = Object.entries(compiledConnections);
|
|
37
|
+
const firstConnectionName = entries.length > 0 ? entries[0][0] : undefined;
|
|
38
|
+
const cache = new Map();
|
|
39
|
+
return {
|
|
40
|
+
async lookupConnection(connectionName) {
|
|
41
|
+
if (connectionName === undefined) {
|
|
42
|
+
connectionName = firstConnectionName;
|
|
43
|
+
}
|
|
44
|
+
if (connectionName === undefined) {
|
|
45
|
+
throw new Error('No connections defined in config');
|
|
46
|
+
}
|
|
47
|
+
const cached = cache.get(connectionName);
|
|
48
|
+
if (cached)
|
|
49
|
+
return cached;
|
|
50
|
+
const compiledEntry = compiledConnections[connectionName];
|
|
51
|
+
if (!compiledEntry) {
|
|
52
|
+
throw new Error(`No connection named "${connectionName}" found in config`);
|
|
53
|
+
}
|
|
54
|
+
const resolved = await resolveCompiledEntry(compiledEntry, overlays, log);
|
|
55
|
+
// compileConnections guarantees `is` is present and a string-valued
|
|
56
|
+
// literal node — resolveCompiledEntry preserves it. Defensive check
|
|
57
|
+
// in case a compiler bug sneaks through.
|
|
58
|
+
if (typeof resolved['is'] !== 'string') {
|
|
59
|
+
throw new Error(`Connection "${connectionName}" is missing a valid "is" field`);
|
|
60
|
+
}
|
|
61
|
+
const typeDef = (0, registry_1.getConnectionTypeDef)(resolved.is);
|
|
62
|
+
if (!typeDef) {
|
|
63
|
+
throw new Error(`No registered connection type "${resolved.is}" for connection "${connectionName}". ` +
|
|
64
|
+
'Did you forget to import the connection package?');
|
|
65
|
+
}
|
|
66
|
+
const connConfig = { name: connectionName };
|
|
67
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
68
|
+
if (key === 'is')
|
|
69
|
+
continue;
|
|
70
|
+
if (value !== undefined && value !== null) {
|
|
71
|
+
connConfig[key] = value;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const connection = await typeDef.factory(connConfig);
|
|
75
|
+
cache.set(connectionName, connection);
|
|
76
|
+
return connection;
|
|
77
|
+
},
|
|
78
|
+
async close() {
|
|
79
|
+
const connections = [...cache.values()];
|
|
80
|
+
cache.clear();
|
|
81
|
+
for (const conn of connections) {
|
|
82
|
+
await conn.close();
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Async walk of a single connection's compiled entry against the overlays,
|
|
89
|
+
* followed by property-default application. Returns the plain POJO that
|
|
90
|
+
* gets handed to the factory.
|
|
91
|
+
*/
|
|
92
|
+
async function resolveCompiledEntry(entry, overlays, log) {
|
|
93
|
+
const resolved = (await resolveNode(entry, overlays, log));
|
|
94
|
+
await applyPropertyDefaults(resolved, overlays);
|
|
95
|
+
return resolved;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Walk a node, awaiting any overlay calls. References that fail to resolve
|
|
99
|
+
* return `undefined`; the parent dict walker drops the corresponding
|
|
100
|
+
* property. Unknown overlay sources push a warning to the log (case 1);
|
|
101
|
+
* overlays returning undefined are silently dropped (case 2).
|
|
102
|
+
*/
|
|
103
|
+
async function resolveNode(node, overlays, log) {
|
|
104
|
+
switch (node.kind) {
|
|
105
|
+
case 'value':
|
|
106
|
+
return node.value;
|
|
107
|
+
case 'reference':
|
|
108
|
+
return resolveReference(node, overlays, log);
|
|
109
|
+
case 'dict': {
|
|
110
|
+
const out = {};
|
|
111
|
+
for (const [k, child] of Object.entries(node.entries)) {
|
|
112
|
+
const r = await resolveNode(child, overlays, log);
|
|
113
|
+
if (r !== undefined)
|
|
114
|
+
out[k] = r;
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function resolveReference(ref, overlays, log) {
|
|
121
|
+
const overlay = overlays[ref.source];
|
|
122
|
+
if (!overlay) {
|
|
123
|
+
// Case 1: unknown overlay source — warn and drop.
|
|
124
|
+
log.push({
|
|
125
|
+
message: `unknown overlay source "${ref.source}" for reference path ${JSON.stringify(ref.path)}`,
|
|
126
|
+
severity: 'warn',
|
|
127
|
+
code: 'config-overlay',
|
|
128
|
+
});
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
// Case 2: overlay returns undefined (sync or via a Promise) — silent drop.
|
|
132
|
+
// `await` tolerates both sync and Promise return types.
|
|
133
|
+
return await overlay(ref.path);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Fill in missing properties on a resolved entry from the registry's
|
|
137
|
+
* declared defaults. Reference-shaped defaults (like DuckDB's
|
|
138
|
+
* `workingDirectory: {config: 'rootDirectory'}`) resolve through the same
|
|
139
|
+
* overlays as inline refs. Unresolved defaults are silently dropped — a
|
|
140
|
+
* default is a hint, not a requirement (case 3).
|
|
141
|
+
*
|
|
142
|
+
* Interaction with inline references: if the user wrote a property as a
|
|
143
|
+
* reference that resolved to `undefined`, `resolveNode` already dropped it
|
|
144
|
+
* before we see the entry. From here the property looks absent, and the
|
|
145
|
+
* default applies — effectively "try the inline ref, else fall back to the
|
|
146
|
+
* default." Almost always what users want.
|
|
147
|
+
*/
|
|
148
|
+
async function applyPropertyDefaults(entry, overlays) {
|
|
149
|
+
var _a;
|
|
150
|
+
const typeName = entry['is'];
|
|
151
|
+
if (typeof typeName !== 'string')
|
|
152
|
+
return;
|
|
153
|
+
const props = (_a = (0, registry_1.getConnectionProperties)(typeName)) !== null && _a !== void 0 ? _a : [];
|
|
154
|
+
for (const prop of props) {
|
|
155
|
+
if (prop.default === undefined)
|
|
156
|
+
continue;
|
|
157
|
+
if (entry[prop.name] !== undefined)
|
|
158
|
+
continue;
|
|
159
|
+
const v = await resolveDefault(prop.default, overlays);
|
|
160
|
+
if (v !== undefined)
|
|
161
|
+
entry[prop.name] = v;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async function resolveDefault(def, overlays) {
|
|
165
|
+
if (typeof def !== 'object')
|
|
166
|
+
return def;
|
|
167
|
+
const keys = Object.keys(def);
|
|
168
|
+
if (keys.length !== 1)
|
|
169
|
+
return undefined;
|
|
170
|
+
const source = keys[0];
|
|
171
|
+
const raw = def[source];
|
|
172
|
+
const path = typeof raw === 'string' ? [raw] : raw;
|
|
173
|
+
if (!Array.isArray(path))
|
|
174
|
+
return undefined;
|
|
175
|
+
const overlay = overlays[source];
|
|
176
|
+
if (!overlay)
|
|
177
|
+
return undefined;
|
|
178
|
+
return await overlay(path);
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=config_lookup.js.map
|
|
@@ -2,13 +2,20 @@
|
|
|
2
2
|
* An overlay is a lambda that takes a compiled reference path and returns
|
|
3
3
|
* a value (or undefined if the path is not present in the overlay source).
|
|
4
4
|
*
|
|
5
|
+
* Overlays may return synchronously or asynchronously — the return type is
|
|
6
|
+
* `unknown | Promise<unknown>`. The reference resolver awaits every overlay
|
|
7
|
+
* result, so a sync overlay and an async overlay are interchangeable from
|
|
8
|
+
* the caller's perspective. Use sync for purely in-memory values (env vars,
|
|
9
|
+
* host context dicts) and async for anything that touches IO (secret stores,
|
|
10
|
+
* session fetches, enterprise-managed injected values).
|
|
11
|
+
*
|
|
5
12
|
* The path is an array because references can address nested data:
|
|
6
13
|
* {env: "HOME"} -> path = ["HOME"]
|
|
7
14
|
* {user: ["address", "zip"]} -> path = ["address", "zip"]
|
|
8
15
|
*
|
|
9
16
|
* Overlay values should resolve to ordinary JSON-compatible values.
|
|
10
17
|
*/
|
|
11
|
-
export type Overlay = (path: string[]) => unknown
|
|
18
|
+
export type Overlay = (path: string[]) => unknown | Promise<unknown>;
|
|
12
19
|
/**
|
|
13
20
|
* A dict keyed by overlay name. A config reference like
|
|
14
21
|
* `{env: "PG_PASSWORD"}` is resolved by looking up `overlays["env"]` and
|
|
@@ -1,49 +1,39 @@
|
|
|
1
1
|
import type { LogMessage } from '../../lang/parse-log';
|
|
2
|
-
import type { ConnectionConfigEntry } from '../../connection/registry';
|
|
3
2
|
import type { ConfigDict } from './config_compile';
|
|
4
|
-
import type { ConfigOverlays } from './config_overlays';
|
|
5
3
|
/**
|
|
6
|
-
* The
|
|
7
|
-
*
|
|
8
|
-
* applied. This is fed into the connection registry to build connections.
|
|
4
|
+
* The synchronous slice of config preparation. What the `MalloyConfig`
|
|
5
|
+
* constructor needs *before* any overlay IO happens:
|
|
9
6
|
*
|
|
10
|
-
* `
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* - `compiledConnections` — per-connection compiled subtrees. References
|
|
8
|
+
* inside these are resolved lazily at `lookupConnection` time, not here.
|
|
9
|
+
* Fabricated bare `{is: typeName}` entries are included when the POJO
|
|
10
|
+
* opts in via `includeDefaultConnections`.
|
|
11
|
+
* - `manifestPath` — raw string (never a reference; section compiler only
|
|
12
|
+
* produces value nodes).
|
|
13
|
+
* - `virtualMap` — raw literal POJO (same — virtualMap is a literal slot).
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* happened. It intentionally does not appear on this interface.
|
|
15
|
+
* `includeDefaultConnections` is an input directive, not an output value —
|
|
16
|
+
* fabrication has already happened by the time this returns.
|
|
17
17
|
*/
|
|
18
|
-
export interface
|
|
19
|
-
|
|
18
|
+
export interface PreparedConfig {
|
|
19
|
+
compiledConnections: Record<string, ConfigDict>;
|
|
20
20
|
manifestPath?: string;
|
|
21
21
|
virtualMap?: unknown;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
24
|
+
* Synchronous top-level walk of a compiled config tree. Extracts the
|
|
25
|
+
* non-connection sections (which only contain literals — see the section
|
|
26
|
+
* compilers) and hands back the compiled connection subtrees untouched.
|
|
26
27
|
*
|
|
27
|
-
*
|
|
28
|
+
* Reference resolution for connection properties is *not* done here. It is
|
|
29
|
+
* deferred until `lookupConnection` is called, at which point the async
|
|
30
|
+
* walker in `config_lookup.ts` can `await` overlays that do IO (secret
|
|
31
|
+
* stores, session fetches, etc.). This keeps `MalloyConfig` construction
|
|
32
|
+
* synchronous and zero-IO.
|
|
28
33
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* 2. **`includeDefaultConnections`** (`fabricateMissingConnections`) —
|
|
35
|
-
* fabricate a bare `{is: typeName}` entry for each registered backend
|
|
36
|
-
* not already represented. Property defaults then fill in their
|
|
37
|
-
* properties via (1).
|
|
38
|
-
*
|
|
39
|
-
* Order matters: fabrication runs before property defaults so that
|
|
40
|
-
* fabricated entries pick up defaults in the same pass as user-listed
|
|
41
|
-
* ones.
|
|
42
|
-
*
|
|
43
|
-
* Three unresolved-reference cases, each with different handling:
|
|
44
|
-
* 1. Unknown overlay source → warning, drop property
|
|
45
|
-
* 2. Known overlay → undefined → silent drop
|
|
46
|
-
* 3. Property default → unresolved (either of the above inside a default)
|
|
47
|
-
* → silent drop (a default is a hint, not a requirement)
|
|
34
|
+
* Fabrication of bare `{is: typeName}` compiled entries for registered
|
|
35
|
+
* backends not otherwise represented happens here when the config opts in
|
|
36
|
+
* via `includeDefaultConnections`. Property defaults are filled in at
|
|
37
|
+
* lookup time alongside reference resolution.
|
|
48
38
|
*/
|
|
49
|
-
export declare function
|
|
39
|
+
export declare function prepareConfig(compiled: ConfigDict, _log: LogMessage[]): PreparedConfig;
|
|
@@ -4,227 +4,113 @@
|
|
|
4
4
|
* SPDX-License-Identifier: MIT
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.prepareConfig = prepareConfig;
|
|
8
8
|
const registry_1 = require("../../connection/registry");
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* Synchronous top-level walk of a compiled config tree. Extracts the
|
|
11
|
+
* non-connection sections (which only contain literals — see the section
|
|
12
|
+
* compilers) and hands back the compiled connection subtrees untouched.
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
+
* Reference resolution for connection properties is *not* done here. It is
|
|
15
|
+
* deferred until `lookupConnection` is called, at which point the async
|
|
16
|
+
* walker in `config_lookup.ts` can `await` overlays that do IO (secret
|
|
17
|
+
* stores, session fetches, etc.). This keeps `MalloyConfig` construction
|
|
18
|
+
* synchronous and zero-IO.
|
|
14
19
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* 2. **`includeDefaultConnections`** (`fabricateMissingConnections`) —
|
|
21
|
-
* fabricate a bare `{is: typeName}` entry for each registered backend
|
|
22
|
-
* not already represented. Property defaults then fill in their
|
|
23
|
-
* properties via (1).
|
|
24
|
-
*
|
|
25
|
-
* Order matters: fabrication runs before property defaults so that
|
|
26
|
-
* fabricated entries pick up defaults in the same pass as user-listed
|
|
27
|
-
* ones.
|
|
28
|
-
*
|
|
29
|
-
* Three unresolved-reference cases, each with different handling:
|
|
30
|
-
* 1. Unknown overlay source → warning, drop property
|
|
31
|
-
* 2. Known overlay → undefined → silent drop
|
|
32
|
-
* 3. Property default → unresolved (either of the above inside a default)
|
|
33
|
-
* → silent drop (a default is a hint, not a requirement)
|
|
20
|
+
* Fabrication of bare `{is: typeName}` compiled entries for registered
|
|
21
|
+
* backends not otherwise represented happens here when the config opts in
|
|
22
|
+
* via `includeDefaultConnections`. Property defaults are filled in at
|
|
23
|
+
* lookup time alongside reference resolution.
|
|
34
24
|
*/
|
|
35
|
-
function
|
|
36
|
-
|
|
25
|
+
function prepareConfig(compiled, _log) {
|
|
26
|
+
let compiledConnections = {};
|
|
27
|
+
let manifestPath;
|
|
28
|
+
let virtualMap;
|
|
37
29
|
let includeDefaultConnections = false;
|
|
38
30
|
for (const [key, node] of Object.entries(compiled.entries)) {
|
|
39
31
|
switch (key) {
|
|
40
32
|
case 'connections': {
|
|
41
33
|
if (node.kind !== 'dict')
|
|
42
34
|
break;
|
|
43
|
-
|
|
35
|
+
compiledConnections = extractCompiledConnections(node);
|
|
44
36
|
break;
|
|
45
37
|
}
|
|
46
38
|
case 'manifestPath': {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
if (node.kind === 'value' && typeof node.value === 'string') {
|
|
40
|
+
manifestPath = node.value;
|
|
41
|
+
}
|
|
50
42
|
break;
|
|
51
43
|
}
|
|
52
44
|
case 'virtualMap': {
|
|
53
|
-
// virtualMap is literal
|
|
54
|
-
//
|
|
55
|
-
|
|
45
|
+
// virtualMap is a literal dict slot — compileVirtualMap never
|
|
46
|
+
// produces a reference node. MalloyConfig converts the raw POJO
|
|
47
|
+
// into its runtime Map-of-Maps representation.
|
|
48
|
+
if (node.kind === 'value')
|
|
49
|
+
virtualMap = node.value;
|
|
56
50
|
break;
|
|
57
51
|
}
|
|
58
52
|
case 'includeDefaultConnections': {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
if (node.kind === 'value' && typeof node.value === 'boolean') {
|
|
54
|
+
includeDefaultConnections = node.value;
|
|
55
|
+
}
|
|
62
56
|
break;
|
|
63
57
|
}
|
|
64
58
|
}
|
|
65
59
|
}
|
|
66
60
|
if (includeDefaultConnections) {
|
|
67
|
-
fabricateMissingConnections(
|
|
61
|
+
fabricateMissingConnections(compiledConnections);
|
|
68
62
|
}
|
|
69
|
-
|
|
70
|
-
// alike. This is the fix for the earlier bug where defaults only fired
|
|
71
|
-
// during fabrication, leaving explicit entries silently underconfigured.
|
|
72
|
-
applyPropertyDefaults(resolved.connections, overlays);
|
|
73
|
-
return resolved;
|
|
63
|
+
return { compiledConnections, manifestPath, virtualMap };
|
|
74
64
|
}
|
|
75
|
-
// =============================================================================
|
|
76
|
-
// Generic walk
|
|
77
|
-
// =============================================================================
|
|
78
65
|
/**
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
66
|
+
* Pull each well-formed compiled connection entry out of the `connections`
|
|
67
|
+
* subtree. Entries are already validated by `compileConnections` — anything
|
|
68
|
+
* shaped wrong was dropped or reported during compile. We defensively skip
|
|
69
|
+
* non-dict children here anyway.
|
|
82
70
|
*/
|
|
83
|
-
function
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return resolveReference(node, overlays, log);
|
|
89
|
-
case 'dict': {
|
|
90
|
-
const out = {};
|
|
91
|
-
for (const [k, child] of Object.entries(node.entries)) {
|
|
92
|
-
const r = resolveNode(child, overlays, log);
|
|
93
|
-
if (r !== undefined)
|
|
94
|
-
out[k] = r;
|
|
95
|
-
}
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function resolveReference(ref, overlays, log) {
|
|
101
|
-
const overlay = overlays[ref.source];
|
|
102
|
-
if (!overlay) {
|
|
103
|
-
// Case 1: unknown overlay source — warn and drop.
|
|
104
|
-
log.push({
|
|
105
|
-
message: `unknown overlay source "${ref.source}" for reference path ${JSON.stringify(ref.path)}`,
|
|
106
|
-
severity: 'warn',
|
|
107
|
-
code: 'config-overlay',
|
|
108
|
-
});
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
// Case 2: overlay returns undefined — silent drop (no log push).
|
|
112
|
-
return overlay(ref.path);
|
|
113
|
-
}
|
|
114
|
-
// =============================================================================
|
|
115
|
-
// Connections
|
|
116
|
-
// =============================================================================
|
|
117
|
-
function resolveConnections(node, overlays, log) {
|
|
118
|
-
const result = {};
|
|
119
|
-
for (const [name, connNode] of Object.entries(node.entries)) {
|
|
120
|
-
if (connNode.kind !== 'dict')
|
|
121
|
-
continue;
|
|
122
|
-
const resolved = resolveNode(connNode, overlays, log);
|
|
123
|
-
// compileConnectionEntry guarantees `is` is a string value node, and
|
|
124
|
-
// resolveNode preserves it. Any connection without `is` is a bug in the
|
|
125
|
-
// compiler; skip it defensively.
|
|
126
|
-
if (typeof resolved['is'] !== 'string')
|
|
127
|
-
continue;
|
|
128
|
-
result[name] = resolved;
|
|
71
|
+
function extractCompiledConnections(node) {
|
|
72
|
+
const out = {};
|
|
73
|
+
for (const [name, child] of Object.entries(node.entries)) {
|
|
74
|
+
if (child.kind === 'dict')
|
|
75
|
+
out[name] = child;
|
|
129
76
|
}
|
|
130
|
-
return
|
|
77
|
+
return out;
|
|
131
78
|
}
|
|
132
|
-
// =============================================================================
|
|
133
|
-
// Fabrication and property defaults
|
|
134
|
-
// =============================================================================
|
|
135
79
|
/**
|
|
136
|
-
*
|
|
137
|
-
* type not already represented in `
|
|
138
|
-
* `includeDefaultConnections
|
|
139
|
-
*
|
|
140
|
-
*
|
|
80
|
+
* Add a bare `{is: typeName}` compiled entry for each registered connection
|
|
81
|
+
* type not already represented in `compiledConnections`. Only runs when the
|
|
82
|
+
* POJO sets `includeDefaultConnections: true`. Property values (including
|
|
83
|
+
* reference-shaped defaults like DuckDB's `{config: 'rootDirectory'}`) are
|
|
84
|
+
* *not* filled in here — that is the job of the async lookup resolver.
|
|
141
85
|
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
86
|
+
* Skip rules:
|
|
87
|
+
* - Type already in use: some existing entry has `is: typeName`.
|
|
88
|
+
* - Name already taken: some existing entry is *named* `typeName`, even
|
|
89
|
+
* if its `is` points elsewhere. This protects a user who writes
|
|
90
|
+
* `{duckdb: {is: 'postgres', ...}}` — naming an entry after a type but
|
|
91
|
+
* pointing at a different backend — from being clobbered.
|
|
144
92
|
*
|
|
145
|
-
* Mutates `
|
|
146
|
-
* own freshly-built object.
|
|
93
|
+
* Mutates `compiledConnections` in place.
|
|
147
94
|
*/
|
|
148
|
-
function fabricateMissingConnections(
|
|
95
|
+
function fabricateMissingConnections(compiledConnections) {
|
|
149
96
|
const presentTypes = new Set();
|
|
150
|
-
for (const entry of Object.values(
|
|
151
|
-
|
|
152
|
-
|
|
97
|
+
for (const entry of Object.values(compiledConnections)) {
|
|
98
|
+
const isNode = entry.entries['is'];
|
|
99
|
+
if ((isNode === null || isNode === void 0 ? void 0 : isNode.kind) === 'value' && typeof isNode.value === 'string') {
|
|
100
|
+
presentTypes.add(isNode.value);
|
|
101
|
+
}
|
|
153
102
|
}
|
|
154
103
|
for (const typeName of (0, registry_1.getRegisteredConnectionTypes)()) {
|
|
155
|
-
// `presentTypes` catches {mydb: {is: 'duckdb'}}; the name check catches
|
|
156
|
-
// {duckdb: {is: 'jsondb'}}. Both cases leave the registered `duckdb`
|
|
157
|
-
// type alone — the first because it's already represented, the second
|
|
158
|
-
// because we can't use the obvious name without clobbering.
|
|
159
104
|
if (presentTypes.has(typeName))
|
|
160
105
|
continue;
|
|
161
|
-
if (
|
|
106
|
+
if (compiledConnections[typeName])
|
|
162
107
|
continue;
|
|
163
|
-
|
|
108
|
+
compiledConnections[typeName] = {
|
|
109
|
+
kind: 'dict',
|
|
110
|
+
entries: {
|
|
111
|
+
is: { kind: 'value', value: typeName },
|
|
112
|
+
},
|
|
113
|
+
};
|
|
164
114
|
}
|
|
165
115
|
}
|
|
166
|
-
/**
|
|
167
|
-
* For every connection entry, fill in any property that the user didn't
|
|
168
|
-
* specify and whose `ConnectionPropertyDefinition` declares a `default`.
|
|
169
|
-
* Runs uniformly on both user-listed and fabricated entries — the earlier
|
|
170
|
-
* behavior of only firing during fabrication was a bug that left explicit
|
|
171
|
-
* entries silently underconfigured (e.g. a user-listed `duckdb` never
|
|
172
|
-
* picked up `workingDirectory: {config: 'rootDirectory'}`).
|
|
173
|
-
*
|
|
174
|
-
* Defaults that are reference-shaped resolve through the overlays via
|
|
175
|
-
* `resolveDefault`. Unresolved defaults are silently dropped (case 3).
|
|
176
|
-
* User-specified values are never overwritten.
|
|
177
|
-
*
|
|
178
|
-
* Interaction with inline references: if the user specified a property
|
|
179
|
-
* as a reference-shaped value that failed to resolve (e.g. `{env: 'UNSET'}`),
|
|
180
|
-
* `resolveConnections` already dropped it before we see the entry. From
|
|
181
|
-
* our perspective the property is simply absent, so the default applies —
|
|
182
|
-
* effectively turning inline references into "try this first, else fall
|
|
183
|
-
* back to the default." This is almost always what users want.
|
|
184
|
-
*
|
|
185
|
-
* Mutates `connections` in place. Called only by `resolveConfig` on its
|
|
186
|
-
* own freshly-built object.
|
|
187
|
-
*/
|
|
188
|
-
function applyPropertyDefaults(connections, overlays) {
|
|
189
|
-
var _a;
|
|
190
|
-
for (const entry of Object.values(connections)) {
|
|
191
|
-
const typeName = entry.is;
|
|
192
|
-
if (typeof typeName !== 'string')
|
|
193
|
-
continue;
|
|
194
|
-
const props = (_a = (0, registry_1.getConnectionProperties)(typeName)) !== null && _a !== void 0 ? _a : [];
|
|
195
|
-
for (const prop of props) {
|
|
196
|
-
if (prop.default === undefined)
|
|
197
|
-
continue;
|
|
198
|
-
if (entry[prop.name] !== undefined)
|
|
199
|
-
continue;
|
|
200
|
-
const v = resolveDefault(prop.default, overlays);
|
|
201
|
-
if (v !== undefined)
|
|
202
|
-
entry[prop.name] = v;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Resolve a property `default` field. Literals pass through; single-key
|
|
208
|
-
* reference-shaped objects are resolved through the overlays. Case 3:
|
|
209
|
-
* an unresolved default is a hint, not a requirement — always silent drop.
|
|
210
|
-
*/
|
|
211
|
-
function resolveDefault(def, overlays) {
|
|
212
|
-
if (typeof def !== 'object')
|
|
213
|
-
return def;
|
|
214
|
-
const keys = Object.keys(def);
|
|
215
|
-
if (keys.length !== 1)
|
|
216
|
-
return undefined;
|
|
217
|
-
const source = keys[0];
|
|
218
|
-
const raw = def[source];
|
|
219
|
-
const path = typeof raw === 'string' ? [raw] : raw;
|
|
220
|
-
// The type says `raw` is `string | string[]`, but `default` comes from
|
|
221
|
-
// registered backend definitions which are runtime-dynamic — a
|
|
222
|
-
// malformed registration would blow up inside the overlay otherwise.
|
|
223
|
-
if (!Array.isArray(path))
|
|
224
|
-
return undefined;
|
|
225
|
-
const overlay = overlays[source];
|
|
226
|
-
if (!overlay)
|
|
227
|
-
return undefined;
|
|
228
|
-
return overlay(path);
|
|
229
|
-
}
|
|
230
116
|
//# sourceMappingURL=config_resolve.js.map
|
|
@@ -87,6 +87,12 @@ export declare function getConnectionTypeDisplayName(typeName: string): string |
|
|
|
87
87
|
* Get the names of all registered connection types.
|
|
88
88
|
*/
|
|
89
89
|
export declare function getRegisteredConnectionTypes(): string[];
|
|
90
|
+
/**
|
|
91
|
+
* Get the full definition (factory + properties + displayName) for a
|
|
92
|
+
* registered connection type. Used by the foundation layer's connection
|
|
93
|
+
* lookup to hand fully-resolved configs to the right factory.
|
|
94
|
+
*/
|
|
95
|
+
export declare function getConnectionTypeDef(typeName: string): ConnectionTypeDef | undefined;
|
|
90
96
|
/**
|
|
91
97
|
* Parse a JSON config string into a ConnectionsConfig.
|
|
92
98
|
* Entries without a valid `is` field are silently dropped.
|
|
@@ -9,6 +9,7 @@ exports.registerConnectionType = registerConnectionType;
|
|
|
9
9
|
exports.getConnectionProperties = getConnectionProperties;
|
|
10
10
|
exports.getConnectionTypeDisplayName = getConnectionTypeDisplayName;
|
|
11
11
|
exports.getRegisteredConnectionTypes = getRegisteredConnectionTypes;
|
|
12
|
+
exports.getConnectionTypeDef = getConnectionTypeDef;
|
|
12
13
|
exports.readConnectionsConfig = readConnectionsConfig;
|
|
13
14
|
exports.writeConnectionsConfig = writeConnectionsConfig;
|
|
14
15
|
exports.createConnectionsFromConfig = createConnectionsFromConfig;
|
|
@@ -57,6 +58,14 @@ function getConnectionTypeDisplayName(typeName) {
|
|
|
57
58
|
function getRegisteredConnectionTypes() {
|
|
58
59
|
return [...registry.keys()];
|
|
59
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Get the full definition (factory + properties + displayName) for a
|
|
63
|
+
* registered connection type. Used by the foundation layer's connection
|
|
64
|
+
* lookup to hand fully-resolved configs to the right factory.
|
|
65
|
+
*/
|
|
66
|
+
function getConnectionTypeDef(typeName) {
|
|
67
|
+
return registry.get(typeName);
|
|
68
|
+
}
|
|
60
69
|
/**
|
|
61
70
|
* Parse a JSON config string into a ConnectionsConfig.
|
|
62
71
|
* Entries without a valid `is` field are silently dropped.
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MALLOY_VERSION = "0.0.
|
|
1
|
+
export declare const MALLOY_VERSION = "0.0.375";
|
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.
|
|
5
|
+
exports.MALLOY_VERSION = '0.0.375';
|
|
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.
|
|
3
|
+
"version": "0.0.375",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dist/index.js",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"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"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@malloydata/malloy-filter": "0.0.
|
|
51
|
-
"@malloydata/malloy-interfaces": "0.0.
|
|
52
|
-
"@malloydata/malloy-tag": "0.0.
|
|
50
|
+
"@malloydata/malloy-filter": "0.0.375",
|
|
51
|
+
"@malloydata/malloy-interfaces": "0.0.375",
|
|
52
|
+
"@malloydata/malloy-tag": "0.0.375",
|
|
53
53
|
"@noble/hashes": "^1.8.0",
|
|
54
54
|
"antlr4ts": "^0.5.0-alpha.4",
|
|
55
55
|
"assert": "^2.0.0",
|
|
56
56
|
"jaro-winkler": "^0.2.8",
|
|
57
57
|
"jest-diff": "^29.6.2",
|
|
58
|
-
"lodash": "^4.
|
|
58
|
+
"lodash": "^4.18.1",
|
|
59
59
|
"luxon": "^3.5.0",
|
|
60
60
|
"uuid": "^8.3.2"
|
|
61
61
|
},
|