@google-cloud/kcmd 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +18 -20
  2. package/build/ts/kcmd/cli.js +6164 -5631
  3. package/build/ts/kcmd/gcp/biglake.d.ts +2 -0
  4. package/build/ts/kcmd/gcp/biglake.js +13 -4
  5. package/build/ts/kcmd/gcp/spanner.d.ts +10 -0
  6. package/build/ts/kcmd/gcp/spanner.js +6 -3
  7. package/build/ts/kcmd/layouts/okf.js +49 -7
  8. package/build/ts/kcmd/layouts/semantic-model.d.ts +13 -0
  9. package/build/ts/kcmd/layouts/semantic-model.js +129 -50
  10. package/build/ts/kcmd/okf/concept.d.ts +1 -1
  11. package/build/ts/kcmd/okf/concept.js +6 -0
  12. package/build/ts/kcmd/okf/concept_to_entry.d.ts +2 -0
  13. package/build/ts/kcmd/okf/concept_to_entry.js +29 -2
  14. package/build/ts/kcmd/okf/init_okf_workspace.js +7 -9
  15. package/build/ts/kcmd/okf/okf_metadata.js +17 -0
  16. package/build/ts/kcmd/semantic/bigquery.js +139 -195
  17. package/build/ts/kcmd/semantic/binding.js +14 -19
  18. package/build/ts/kcmd/semantic/deploy_bigquery.js +6 -13
  19. package/build/ts/kcmd/semantic/deploy_knowledge_catalog.d.ts +10 -35
  20. package/build/ts/kcmd/semantic/deploy_knowledge_catalog.js +105 -162
  21. package/build/ts/kcmd/semantic/deploy_spanner.js +7 -14
  22. package/build/ts/kcmd/semantic/deployment_target.d.ts +1 -4
  23. package/build/ts/kcmd/semantic/deployment_target.js +6 -62
  24. package/build/ts/kcmd/semantic/graph_ddl.d.ts +10 -0
  25. package/build/ts/kcmd/semantic/graph_ddl.js +152 -59
  26. package/build/ts/kcmd/semantic/import_model.d.ts +26 -4
  27. package/build/ts/kcmd/semantic/import_model.js +531 -111
  28. package/build/ts/kcmd/semantic/ir.d.ts +2 -4
  29. package/build/ts/kcmd/semantic/kc_converter.d.ts +7 -1
  30. package/build/ts/kcmd/semantic/kc_converter.js +32 -27
  31. package/build/ts/kcmd/semantic/kc_custom_types.d.ts +5 -12
  32. package/build/ts/kcmd/semantic/kc_custom_types.js +43 -114
  33. package/build/ts/kcmd/semantic/kc_ids.d.ts +4 -5
  34. package/build/ts/kcmd/semantic/kc_ids.js +4 -7
  35. package/build/ts/kcmd/semantic/knowledge_catalog.d.ts +0 -3
  36. package/build/ts/kcmd/semantic/knowledge_catalog.js +3 -86
  37. package/build/ts/kcmd/semantic/loader.d.ts +7 -11
  38. package/build/ts/kcmd/semantic/loader.js +282 -171
  39. package/build/ts/kcmd/semantic/osi_converter.js +14 -65
  40. package/build/ts/kcmd/semantic/parameters.d.ts +1 -0
  41. package/build/ts/kcmd/semantic/parameters.js +22 -3
  42. package/build/ts/kcmd/semantic/pull_kc.d.ts +1 -5
  43. package/build/ts/kcmd/semantic/pull_kc.js +38 -112
  44. package/build/ts/kcmd/semantic/resolve_inheritance.d.ts +7 -2
  45. package/build/ts/kcmd/semantic/resolve_inheritance.js +37 -21
  46. package/build/ts/kcmd/semantic/resolve_profiles.d.ts +51 -10
  47. package/build/ts/kcmd/semantic/resolve_profiles.js +213 -32
  48. package/build/ts/kcmd/semantic/runtime/runtime.d.ts +4 -12
  49. package/build/ts/kcmd/semantic/runtime/runtime.js +4 -21
  50. package/build/ts/kcmd/semantic/runtime/store.d.ts +14 -19
  51. package/build/ts/kcmd/semantic/runtime/store.js +21 -37
  52. package/build/ts/kcmd/semantic/source_dialect.d.ts +9 -2
  53. package/build/ts/kcmd/semantic/source_dialect.js +83 -33
  54. package/build/ts/kcmd/semantic/source_entries.d.ts +1 -1
  55. package/build/ts/kcmd/semantic/source_entries.js +95 -36
  56. package/build/ts/kcmd/semantic/sql_expr_utils.d.ts +13 -7
  57. package/build/ts/kcmd/semantic/sql_expr_utils.js +240 -67
  58. package/build/ts/kcmd/semantic/sql_parser.d.ts +5 -2
  59. package/build/ts/kcmd/semantic/sql_parser.js +22 -0
  60. package/build/ts/kcmd/semantic/transpile.d.ts +12 -10
  61. package/build/ts/kcmd/semantic/transpile.js +79 -61
  62. package/build/ts/kcmd/semantic/validate.d.ts +37 -2
  63. package/build/ts/kcmd/semantic/validate.js +467 -126
  64. package/build/ts/kcmd/snapshot.d.ts +4 -0
  65. package/build/ts/kcmd/snapshot.js +7 -0
  66. package/build/ts/kcmd/sync.js +44 -7
  67. package/package.json +1 -1
@@ -23,7 +23,8 @@ export interface PolyglotEngine {
23
23
  error?: string;
24
24
  };
25
25
  }
26
- interface SqlToken {
26
+ export interface SqlToken {
27
+ token_type: string;
27
28
  text: string;
28
29
  span: {
29
30
  start: number;
@@ -33,12 +34,14 @@ interface SqlToken {
33
34
  trailing_comments: string[];
34
35
  }
35
36
  export declare function loadSqlEngine(): Promise<PolyglotEngine>;
37
+ export declare function loadedSqlEngine(): PolyglotEngine | undefined;
36
38
  export interface SqlColumn {
37
39
  qualifier?: string;
38
40
  name: string;
39
41
  }
40
42
  export declare function sqlColumns(expression: string, dialect: string): SqlColumn[] | undefined;
43
+ export declare function soleColumn(expression: string, dialect: string): SqlColumn | undefined;
41
44
  export declare function sqlExpressionTree(expression: string, dialect: string): any;
45
+ export declare function sqlTokens(expression: string, dialect: string): SqlToken[] | undefined;
42
46
  export declare function holdsNoSql(expression: string, dialect: string): boolean;
43
47
  export declare function withoutComments(expression: string, dialect: string): string;
44
- export {};
@@ -8,8 +8,11 @@
8
8
  // first, and so does a test.
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.loadSqlEngine = loadSqlEngine;
11
+ exports.loadedSqlEngine = loadedSqlEngine;
11
12
  exports.sqlColumns = sqlColumns;
13
+ exports.soleColumn = soleColumn;
12
14
  exports.sqlExpressionTree = sqlExpressionTree;
15
+ exports.sqlTokens = sqlTokens;
13
16
  exports.holdsNoSql = holdsNoSql;
14
17
  exports.withoutComments = withoutComments;
15
18
  const node_fs_1 = require("node:fs");
@@ -42,6 +45,10 @@ function loadSqlEngine() {
42
45
  }
43
46
  return enginePromise;
44
47
  }
48
+ // The engine loadSqlEngine has loaded, or undefined before it has.
49
+ function loadedSqlEngine() {
50
+ return loadedEngine;
51
+ }
45
52
  // The engine's dialect for each kcmd dialect. The engine has no Spanner
46
53
  // dialect, so Spanner's GoogleSQL is read as BigQuery's.
47
54
  const PARSER_DIALECTS = {
@@ -73,6 +80,21 @@ function sqlColumns(expression, dialect) {
73
80
  collectColumns(tree, columns, new Set(), PARSER_DIALECTS[dialect.toUpperCase()] ?? 'generic');
74
81
  return columns;
75
82
  }
83
+ // The column `expression` is, read in `dialect`, when it is one column and
84
+ // nothing else, perhaps in parentheses: `orders.amount`, `` (`order`) `` or
85
+ // `amount`, but not a struct path such as `orders.address.city` or any other
86
+ // expression. Undefined otherwise, or when the engine cannot read it. Throws
87
+ // when the engine is not loaded.
88
+ function soleColumn(expression, dialect) {
89
+ let tree = sqlExpressionTree(expression, dialect);
90
+ const kind = (node) => node && Object.keys(node).length === 1 ? Object.keys(node)[0] : undefined;
91
+ while (kind(tree) === 'paren')
92
+ tree = tree.paren.this;
93
+ if (kind(tree) !== 'column')
94
+ return undefined;
95
+ const columns = sqlColumns(expression, dialect);
96
+ return columns?.length === 1 ? columns[0] : undefined;
97
+ }
76
98
  // The engine's tree of `expression` read as one expression in `dialect`, or
77
99
  // undefined when it cannot be read so or is empty. A text that starts with a
78
100
  // keyword, such as `Order.amount`, is read again inside parentheses on lines
@@ -1,4 +1,4 @@
1
- import { SemanticModel } from './ir';
1
+ import { Field, ProfileSpec, SemanticModel } from './ir';
2
2
  export interface TranspileRequest {
3
3
  id: string;
4
4
  dialect: string;
@@ -13,11 +13,13 @@ export type SqlTranspiler = (requests: TranspileRequest[], target: string) => Pr
13
13
  export interface TranspileOptions {
14
14
  target?: string;
15
15
  transpiler?: SqlTranspiler;
16
+ translatesProfile?: (profile: ProfileSpec, model: SemanticModel) => boolean;
16
17
  }
17
18
  export interface TranspileResult {
18
19
  model: SemanticModel;
19
20
  warnings: string[];
20
21
  }
22
+ type TranspileNode = Pick<Field, 'expression' | 'dialects' | 'stringForm' | 'importedExpression' | 'importedDialect'>;
21
23
  /**
22
24
  * Returns true if `expression`, read as generic SQL (`ANSI_SQL`), quotes a
23
25
  * column, table qualifier, or struct field with double quotes (`"..."`).
@@ -43,9 +45,10 @@ export declare function hasDoubleQuotedColumn(expression: string): boolean;
43
45
  */
44
46
  export declare function doubleQuotedNames(expression: string): string[];
45
47
  /**
46
- * Adds a translated `opts.target` dialect entry to every field or metric in
47
- * `model` whose only texts are in vendor dialects or whose `ANSI_SQL` text
48
- * double-quotes a column name, returning a cloned model plus diagnostics.
48
+ * Adds a translated `opts.target` dialect entry to every field, metric and
49
+ * profile field binding in `model` whose only texts are in vendor dialects or
50
+ * whose `ANSI_SQL` text double-quotes a column name, returning a cloned model
51
+ * plus diagnostics.
49
52
  *
50
53
  * The input model is never mutated. When no node needs transpilation, the clone
51
54
  * is returned unchanged and the transpiler is not invoked. The
@@ -56,13 +59,11 @@ export declare function doubleQuotedNames(expression: string): string[];
56
59
  */
57
60
  export declare function transpileModel(model: SemanticModel, opts?: TranspileOptions): Promise<TranspileResult>;
58
61
  /**
59
- * Returns true if the default translator reads SQL written in `dialect`
60
- * (treating an empty string as `ANSI_SQL`).
61
- *
62
- * `transpileModel` leaves a text in any other dialect as written, with a
63
- * warning.
62
+ * Whether `transpileModel`, with the default translator, gives `node` a
63
+ * BIGQUERY text in a model whose entities are `entityNames`. False until
64
+ * `loadSqlEngine()` has loaded the engine.
64
65
  */
65
- export declare function transpilesFrom(dialect: string): boolean;
66
+ export declare function translatesToBigQuery(node: TranspileNode, entityNames: string[]): boolean;
66
67
  /**
67
68
  * The default {@link SqlTranspiler}: transpiles via the embedded
68
69
  * @polyglot-sql/sdk Rust/WASM engine. There is no external runtime dependency
@@ -72,3 +73,4 @@ export declare function transpilesFrom(dialect: string): boolean;
72
73
  * that request, so the caller degrades to the imported form + warning.
73
74
  */
74
75
  export declare const polyglotTranspiler: SqlTranspiler;
76
+ export {};
@@ -34,7 +34,7 @@ exports.polyglotTranspiler = void 0;
34
34
  exports.hasDoubleQuotedColumn = hasDoubleQuotedColumn;
35
35
  exports.doubleQuotedNames = doubleQuotedNames;
36
36
  exports.transpileModel = transpileModel;
37
- exports.transpilesFrom = transpilesFrom;
37
+ exports.translatesToBigQuery = translatesToBigQuery;
38
38
  const sql_expr_utils_1 = require("./sql_expr_utils");
39
39
  const sql_identifiers_1 = require("./sql_identifiers");
40
40
  const sql_parser_1 = require("./sql_parser");
@@ -164,9 +164,10 @@ function sourceToTranspile(node, target) {
164
164
  return undefined;
165
165
  }
166
166
  /**
167
- * Adds a translated `opts.target` dialect entry to every field or metric in
168
- * `model` whose only texts are in vendor dialects or whose `ANSI_SQL` text
169
- * double-quotes a column name, returning a cloned model plus diagnostics.
167
+ * Adds a translated `opts.target` dialect entry to every field, metric and
168
+ * profile field binding in `model` whose only texts are in vendor dialects or
169
+ * whose `ANSI_SQL` text double-quotes a column name, returning a cloned model
170
+ * plus diagnostics.
170
171
  *
171
172
  * The input model is never mutated. When no node needs transpilation, the clone
172
173
  * is returned unchanged and the transpiler is not invoked. The
@@ -214,6 +215,15 @@ async function transpileModel(model, opts = {}) {
214
215
  }
215
216
  for (const m of clone.metrics)
216
217
  add(m, `metric '${m.name}'`);
218
+ for (const p of clone.profiles ?? []) {
219
+ if (opts.translatesProfile && !opts.translatesProfile(p, clone))
220
+ continue;
221
+ for (const pe of p.entities) {
222
+ for (const f of pe.fields ?? []) {
223
+ add(f, `profile '${p.name}': field '${pe.name}.${f.name}'`);
224
+ }
225
+ }
226
+ }
217
227
  if (!pending.length)
218
228
  return { model: clone, warnings };
219
229
  const responses = await transpiler(pending.map(p => p.request), target);
@@ -236,27 +246,17 @@ async function transpileModel(model, opts = {}) {
236
246
  // the exact case the emitter needs. Comparing the output against itself
237
247
  // (rather than the vendor input) avoids false positives from dialect-
238
248
  // specific identifier quoting.
239
- const cols = (0, sql_expr_utils_1.columnReferences)(res.sql, target);
240
- if (cols === undefined) {
249
+ const reached = qualifiersReached(res.sql, target, entityNames);
250
+ if (!reached) {
241
251
  warnings.push(`${ctx}: transpiled '${request.dialect}' -> '${target}' could not ` +
242
252
  `be parsed; qualifier check was skipped`);
243
253
  }
244
- else {
245
- const emitterVisible = (0, sql_expr_utils_1.entitiesReached)(cols, entityNames);
246
- const anyCase = [
247
- ...new Set(cols.flatMap(c => {
248
- if (!c.qualifier)
249
- return [];
250
- const lower = c.qualifier.toLowerCase();
251
- return entityNames.filter(n => n.toLowerCase() === lower);
252
- })),
253
- ];
254
- if (!sameSet(emitterVisible, anyCase)) {
255
- warnings.push(`${ctx}: transpiled '${request.dialect}' -> '${target}' but it re-cased an entity qualifier the emitter matches ` +
256
- `case-sensitively (${fmtSet(emitterVisible)} vs ${fmtSet(anyCase)}); ` +
257
- `left untranslated`);
258
- continue;
259
- }
254
+ else if (!sameSet(reached.exact, reached.anyCase)) {
255
+ warnings.push(`${ctx}: transpiled '${request.dialect}' -> '${target}' but it ` +
256
+ `re-cased an entity qualifier the emitter matches case-sensitively ` +
257
+ `(${fmtSet(reached.exact)} vs ${fmtSet(reached.anyCase)}); left ` +
258
+ `untranslated`);
259
+ continue;
260
260
  }
261
261
  p.accept(res.sql);
262
262
  warnings.push(`${ctx}: transpiled '${request.dialect}' -> '${target}'`);
@@ -268,6 +268,35 @@ async function transpileModel(model, opts = {}) {
268
268
  }
269
269
  return { model: clone, warnings };
270
270
  }
271
+ // The entities among `entityNames` that `sql`, in `target`, qualifies a
272
+ // column with in their exact case and in any case, or undefined when the
273
+ // parser cannot read `sql`.
274
+ function qualifiersReached(sql, target, entityNames) {
275
+ const cols = (0, sql_expr_utils_1.columnReferences)(sql, target);
276
+ if (cols === undefined)
277
+ return undefined;
278
+ const anyCase = new Set(cols.flatMap(c => {
279
+ const lower = c.qualifier?.toLowerCase();
280
+ return entityNames.filter(n => n.toLowerCase() === lower);
281
+ }));
282
+ return { exact: (0, sql_expr_utils_1.entitiesReached)(cols, entityNames), anyCase: [...anyCase] };
283
+ }
284
+ /**
285
+ * Whether `transpileModel`, with the default translator, gives `node` a
286
+ * BIGQUERY text in a model whose entities are `entityNames`. False until
287
+ * `loadSqlEngine()` has loaded the engine.
288
+ */
289
+ function translatesToBigQuery(node, entityNames) {
290
+ const source = sourceToTranspile(node, DEFAULT_TARGET);
291
+ const engine = (0, sql_parser_1.loadedSqlEngine)();
292
+ if (!source || !engine)
293
+ return false;
294
+ const { sql } = transpileWith(engine, { id: '', ...source }, polyglotDialect(DEFAULT_TARGET));
295
+ if (sql === undefined)
296
+ return false;
297
+ const reached = qualifiersReached(sql, DEFAULT_TARGET, entityNames);
298
+ return !reached || sameSet(reached.exact, reached.anyCase);
299
+ }
271
300
  function sameSet(a, b) {
272
301
  if (a.length !== b.length)
273
302
  return false;
@@ -298,16 +327,6 @@ function polyglotDialect(token) {
298
327
  return undefined;
299
328
  return POLYGLOT_DIALECTS[token.toUpperCase()];
300
329
  }
301
- /**
302
- * Returns true if the default translator reads SQL written in `dialect`
303
- * (treating an empty string as `ANSI_SQL`).
304
- *
305
- * `transpileModel` leaves a text in any other dialect as written, with a
306
- * warning.
307
- */
308
- function transpilesFrom(dialect) {
309
- return polyglotDialect(dialect || 'ANSI_SQL') !== undefined;
310
- }
311
330
  /**
312
331
  * The default {@link SqlTranspiler}: transpiles via the embedded
313
332
  * @polyglot-sql/sdk Rust/WASM engine. There is no external runtime dependency
@@ -335,37 +354,36 @@ const polyglotTranspiler = async (requests, target) => {
335
354
  const reason = `SQL transpiler engine unavailable: ${errMessage(err)}`;
336
355
  return requests.map(r => ({ id: r.id, error: reason }));
337
356
  }
338
- return requests.map(r => {
339
- const read = polyglotDialect(r.dialect);
340
- if (read === undefined)
341
- return { id: r.id, error: `unsupported source dialect '${r.dialect}'` };
342
- try {
343
- const res = engine.transpile(r.expression, read, write);
344
- if (!res.success || !res.sql || res.sql.length === 0)
345
- return {
346
- id: r.id,
347
- error: res.error ?? 'transpilation produced no output'
348
- };
349
- // A field/metric is a single scalar expression, so the engine should
350
- // return exactly one statement. More than one means the input was not a
351
- // lone expression; taking [0] would silently drop the rest, so reject it.
352
- if (res.sql.length > 1)
353
- return {
354
- id: r.id,
355
- error: `expected a single expression but got ${res.sql.length} statements`
356
- };
357
- if (write !== 'bigquery')
358
- return { id: r.id, sql: res.sql[0] };
359
- const repaired = repairForBigQuery(engine, res.sql[0], read);
360
- return 'error' in repaired ? { id: r.id, error: repaired.error } :
361
- { id: r.id, sql: repaired.sql };
362
- }
363
- catch (err) {
364
- return { id: r.id, error: errMessage(err) };
365
- }
366
- });
357
+ return requests.map(r => transpileWith(engine, r, write));
367
358
  };
368
359
  exports.polyglotTranspiler = polyglotTranspiler;
360
+ // The engine's answer to `r`, with `write` as the engine's target dialect.
361
+ function transpileWith(engine, r, write) {
362
+ const read = polyglotDialect(r.dialect);
363
+ if (read === undefined)
364
+ return { id: r.id, error: `unsupported source dialect '${r.dialect}'` };
365
+ try {
366
+ const res = engine.transpile(r.expression, read, write);
367
+ if (!res.success || !res.sql || res.sql.length === 0)
368
+ return { id: r.id, error: res.error ?? 'transpilation produced no output' };
369
+ // A field/metric is a single scalar expression, so the engine should
370
+ // return exactly one statement. More than one means the input was not a
371
+ // lone expression; taking [0] would silently drop the rest, so reject it.
372
+ if (res.sql.length > 1)
373
+ return {
374
+ id: r.id,
375
+ error: `expected a single expression but got ${res.sql.length} statements`
376
+ };
377
+ if (write !== 'bigquery')
378
+ return { id: r.id, sql: res.sql[0] };
379
+ const repaired = repairForBigQuery(engine, res.sql[0], read);
380
+ return 'error' in repaired ? { id: r.id, error: repaired.error } :
381
+ { id: r.id, sql: repaired.sql };
382
+ }
383
+ catch (err) {
384
+ return { id: r.id, error: errMessage(err) };
385
+ }
386
+ }
369
387
  function errMessage(err) {
370
388
  return err instanceof Error ? err.message : String(err);
371
389
  }
@@ -3,12 +3,13 @@ import { SpannerClient } from '../gcp/spanner';
3
3
  import { ResolvedDeployment } from './deployment_target';
4
4
  import { SemanticModel } from './ir';
5
5
  import { LoadedModel } from './loader';
6
+ import { AvailabilityReport, DeclaredProfiles, DialectLoad, LocalCheckError, ProfileFiles } from './resolve_profiles';
6
7
  export declare function validatePushRequirements(models: LoadedModel[], opts?: {
7
8
  fieldsPruned?: boolean;
8
9
  warnings?: string[];
9
10
  v2Aspects?: boolean;
10
11
  }): string[];
11
- export declare function validateDeployments(model: SemanticModel, document: string): string[];
12
+ export declare function validateDeployments(model: SemanticModel, document: string, load?: DialectLoad): string[];
12
13
  export declare function validateInlineDialects(model: SemanticModel, document: string): string[];
13
14
  export declare function validateInheritedColumns(model: SemanticModel, document: string): string[];
14
15
  export declare function inlineBindingWarnings(model: SemanticModel, document: string, namedProfiles: boolean): string[];
@@ -25,11 +26,45 @@ export declare function validateActions(model: SemanticModel, document: string,
25
26
  export declare function validateInheritance(models: LoadedModel[]): string[];
26
27
  export declare function validateExpressionReferences(models: LoadedModel[], fieldsPruned?: boolean, warnings?: string[], flaggedMetrics?: Set<string>): string[];
27
28
  export declare function deploymentTableErrors(document: string, model: SemanticModel, deployment: ResolvedDeployment): string[];
29
+ export declare function spannerMetricsErrors(document: string, model: SemanticModel, deployment: ResolvedDeployment): string[];
30
+ export declare function kcV2Aspects(): boolean;
31
+ export interface LocalCheckScope {
32
+ docs: Array<{
33
+ name: string;
34
+ text: string;
35
+ }>;
36
+ loaded: {
37
+ models: LoadedModel[];
38
+ warnings: string[];
39
+ };
40
+ models: LoadedModel[];
41
+ profileDocs: ProfileFiles;
42
+ declaredBy: DeclaredProfiles;
43
+ load: DialectLoad;
44
+ }
45
+ export interface DeploymentPlan {
46
+ deployment: ResolvedDeployment;
47
+ at: string;
48
+ model: LoadedModel;
49
+ report: AvailabilityReport;
50
+ generated?: {
51
+ ddl: string[];
52
+ warnings: string[];
53
+ };
54
+ }
55
+ export declare function withProfileFiles(base: LoadedModel, profileDocs: ProfileFiles): LoadedModel | {
56
+ errors: LocalCheckError[];
57
+ };
58
+ export declare function localChecks(scope: LocalCheckScope, warn: (w: string) => void, selected?: string[]): Promise<{
59
+ plans: DeploymentPlan[];
60
+ } | {
61
+ errors: LocalCheckError[];
62
+ }>;
63
+ export declare function pruningLines({ deployment, model, report: r }: DeploymentPlan): string[];
28
64
  export declare function validateBigQueryDataSources(models: LoadedModel[], bq: BigQueryClient, defaultProject: string, graph?: {
29
65
  at: string;
30
66
  dataset: string;
31
67
  location: string;
32
68
  }): Promise<string[]>;
33
- export declare function storeMessage(message: string | undefined, status: number): string;
34
69
  export declare function validateSpannerActionStatements(models: LoadedModel[], spanner: SpannerClient): Promise<string[]>;
35
70
  export declare function validateBigQueryActionStatements(models: LoadedModel[], bq: BigQueryClient, defaultProject: string): Promise<string[]>;