@514labs/moose-lib 0.6.527 → 0.6.528

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 (37) hide show
  1. package/dist/browserCompatible.d.mts +2 -2
  2. package/dist/browserCompatible.d.ts +2 -2
  3. package/dist/browserCompatible.js +393 -2
  4. package/dist/browserCompatible.js.map +1 -1
  5. package/dist/browserCompatible.mjs +389 -2
  6. package/dist/browserCompatible.mjs.map +1 -1
  7. package/dist/compilerPlugin.js +2 -1
  8. package/dist/compilerPlugin.js.map +1 -1
  9. package/dist/compilerPlugin.mjs +2 -1
  10. package/dist/compilerPlugin.mjs.map +1 -1
  11. package/dist/dmv2/index.d.mts +2 -2
  12. package/dist/dmv2/index.d.ts +2 -2
  13. package/dist/dmv2/index.js +393 -2
  14. package/dist/dmv2/index.js.map +1 -1
  15. package/dist/dmv2/index.mjs +389 -2
  16. package/dist/dmv2/index.mjs.map +1 -1
  17. package/dist/{index-k_kpRxE3.d.mts → index-BTIlwBBZ.d.mts} +13 -2
  18. package/dist/{index-7uxZbwmY.d.ts → index-w7pvlv3c.d.ts} +13 -2
  19. package/dist/index.d.mts +4 -4
  20. package/dist/index.d.ts +4 -4
  21. package/dist/index.js +394 -2
  22. package/dist/index.js.map +1 -1
  23. package/dist/index.mjs +390 -2
  24. package/dist/index.mjs.map +1 -1
  25. package/dist/moose-runner.js +36 -3
  26. package/dist/moose-runner.js.map +1 -1
  27. package/dist/moose-runner.mjs +36 -3
  28. package/dist/moose-runner.mjs.map +1 -1
  29. package/dist/{view-BCWJcLF6.d.mts → query-client-6YrlC3Df.d.mts} +420 -80
  30. package/dist/{view-BCWJcLF6.d.ts → query-client-6YrlC3Df.d.ts} +420 -80
  31. package/dist/testing/index.d.mts +1 -1
  32. package/dist/testing/index.d.ts +1 -1
  33. package/dist/testing/index.js +10 -1
  34. package/dist/testing/index.js.map +1 -1
  35. package/dist/testing/index.mjs +10 -1
  36. package/dist/testing/index.mjs.map +1 -1
  37. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- export { C as ClickHouseEngines, L as LifeCycle, a as OlapConfig, O as OlapTable, S as S3QueueTableSettings, T as TableConstraint, V as View, a4 as ViewConfig } from '../view-BCWJcLF6.mjs';
2
- export { A as Aggregated, f as Api, g as ApiConfig, a6 as ConsumerConfig, C as ConsumptionApi, c as DeadLetter, D as DeadLetterModel, d as DeadLetterQueue, l as ETLPipeline, m as ETLPipelineConfig, E as EgressConfig, F as FrameworkApp, I as IngestApi, e as IngestConfig, h as IngestPipeline, aa as IngestPipelineConfig, M as MaterializedView, ab as MaterializedViewConfig, j as SelectRowPolicy, k as SelectRowPolicyConfig, S as SimpleAggregated, i as SqlResource, a as Stream, b as StreamConfig, T as Task, a9 as TaskConfig, a8 as TaskContext, a7 as TransformConfig, n as WebApp, o as WebAppConfig, p as WebAppHandler, W as Workflow, x as getApi, w as getApis, v as getIngestApi, u as getIngestApis, N as getMaterializedView, O as getMaterializedViews, P as getSelectRowPolicies, Q as getSelectRowPolicy, z as getSqlResource, y as getSqlResources, t as getStream, s as getStreams, r as getTable, q as getTables, K as getView, L as getViews, J as getWebApp, H as getWebApps, G as getWorkflow, B as getWorkflows } from '../index-k_kpRxE3.mjs';
1
+ export { j as COMPLEX_KEY_LAYOUTS, C as ClickHouseEngines, f as ClickHouseExternalSource, D as DictionaryColumnConfig, d as DictionaryLayout, e as DictionaryLifetime, h as ExecutableExternalSource, E as ExternalSource, H as HttpExternalSource, L as LifeCycle, g as MongodbExternalSource, M as MysqlExternalSource, a as OlapConfig, b as OlapDictionary, c as OlapDictionaryConfig, O as OlapTable, P as PostgresqlExternalSource, R as RedisExternalSource, i as S3ExternalSource, S as S3QueueTableSettings, T as TableConstraint, V as View, aj as ViewConfig } from '../query-client-6YrlC3Df.mjs';
2
+ export { A as Aggregated, f as Api, g as ApiConfig, a8 as ConsumerConfig, C as ConsumptionApi, c as DeadLetter, D as DeadLetterModel, d as DeadLetterQueue, l as ETLPipeline, m as ETLPipelineConfig, E as EgressConfig, F as FrameworkApp, I as IngestApi, e as IngestConfig, h as IngestPipeline, ac as IngestPipelineConfig, M as MaterializedView, ad as MaterializedViewConfig, j as SelectRowPolicy, k as SelectRowPolicyConfig, S as SimpleAggregated, i as SqlResource, a as Stream, b as StreamConfig, T as Task, ab as TaskConfig, aa as TaskContext, a9 as TransformConfig, n as WebApp, o as WebAppConfig, p as WebAppHandler, W as Workflow, x as getApi, w as getApis, v as getIngestApi, u as getIngestApis, N as getMaterializedView, O as getMaterializedViews, R as getOlapDictionaries, U as getOlapDictionary, P as getSelectRowPolicies, Q as getSelectRowPolicy, z as getSqlResource, y as getSqlResources, t as getStream, s as getStreams, r as getTable, q as getTables, K as getView, L as getViews, J as getWebApp, H as getWebApps, G as getWorkflow, B as getWorkflows } from '../index-BTIlwBBZ.mjs';
3
3
  import '@clickhouse/client';
4
4
  import 'typia';
5
5
  import 'typia/lib/tags';
@@ -1,5 +1,5 @@
1
- export { C as ClickHouseEngines, L as LifeCycle, a as OlapConfig, O as OlapTable, S as S3QueueTableSettings, T as TableConstraint, V as View, a4 as ViewConfig } from '../view-BCWJcLF6.js';
2
- export { A as Aggregated, f as Api, g as ApiConfig, a6 as ConsumerConfig, C as ConsumptionApi, c as DeadLetter, D as DeadLetterModel, d as DeadLetterQueue, l as ETLPipeline, m as ETLPipelineConfig, E as EgressConfig, F as FrameworkApp, I as IngestApi, e as IngestConfig, h as IngestPipeline, aa as IngestPipelineConfig, M as MaterializedView, ab as MaterializedViewConfig, j as SelectRowPolicy, k as SelectRowPolicyConfig, S as SimpleAggregated, i as SqlResource, a as Stream, b as StreamConfig, T as Task, a9 as TaskConfig, a8 as TaskContext, a7 as TransformConfig, n as WebApp, o as WebAppConfig, p as WebAppHandler, W as Workflow, x as getApi, w as getApis, v as getIngestApi, u as getIngestApis, N as getMaterializedView, O as getMaterializedViews, P as getSelectRowPolicies, Q as getSelectRowPolicy, z as getSqlResource, y as getSqlResources, t as getStream, s as getStreams, r as getTable, q as getTables, K as getView, L as getViews, J as getWebApp, H as getWebApps, G as getWorkflow, B as getWorkflows } from '../index-7uxZbwmY.js';
1
+ export { j as COMPLEX_KEY_LAYOUTS, C as ClickHouseEngines, f as ClickHouseExternalSource, D as DictionaryColumnConfig, d as DictionaryLayout, e as DictionaryLifetime, h as ExecutableExternalSource, E as ExternalSource, H as HttpExternalSource, L as LifeCycle, g as MongodbExternalSource, M as MysqlExternalSource, a as OlapConfig, b as OlapDictionary, c as OlapDictionaryConfig, O as OlapTable, P as PostgresqlExternalSource, R as RedisExternalSource, i as S3ExternalSource, S as S3QueueTableSettings, T as TableConstraint, V as View, aj as ViewConfig } from '../query-client-6YrlC3Df.js';
2
+ export { A as Aggregated, f as Api, g as ApiConfig, a8 as ConsumerConfig, C as ConsumptionApi, c as DeadLetter, D as DeadLetterModel, d as DeadLetterQueue, l as ETLPipeline, m as ETLPipelineConfig, E as EgressConfig, F as FrameworkApp, I as IngestApi, e as IngestConfig, h as IngestPipeline, ac as IngestPipelineConfig, M as MaterializedView, ad as MaterializedViewConfig, j as SelectRowPolicy, k as SelectRowPolicyConfig, S as SimpleAggregated, i as SqlResource, a as Stream, b as StreamConfig, T as Task, ab as TaskConfig, aa as TaskContext, a9 as TransformConfig, n as WebApp, o as WebAppConfig, p as WebAppHandler, W as Workflow, x as getApi, w as getApis, v as getIngestApi, u as getIngestApis, N as getMaterializedView, O as getMaterializedViews, R as getOlapDictionaries, U as getOlapDictionary, P as getSelectRowPolicies, Q as getSelectRowPolicy, z as getSqlResource, y as getSqlResources, t as getStream, s as getStreams, r as getTable, q as getTables, K as getView, L as getViews, J as getWebApp, H as getWebApps, G as getWorkflow, B as getWorkflows } from '../index-w7pvlv3c.js';
3
3
  import '@clickhouse/client';
4
4
  import 'typia';
5
5
  import 'typia/lib/tags';
@@ -484,6 +484,7 @@ var init_runtime = __esm({
484
484
  var dmv2_exports = {};
485
485
  __export(dmv2_exports, {
486
486
  Api: () => Api,
487
+ COMPLEX_KEY_LAYOUTS: () => COMPLEX_KEY_LAYOUTS,
487
488
  ClickHouseEngines: () => ClickHouseEngines,
488
489
  ConsumptionApi: () => ConsumptionApi,
489
490
  DeadLetterQueue: () => DeadLetterQueue,
@@ -492,6 +493,7 @@ __export(dmv2_exports, {
492
493
  IngestPipeline: () => IngestPipeline,
493
494
  LifeCycle: () => LifeCycle,
494
495
  MaterializedView: () => MaterializedView,
496
+ OlapDictionary: () => OlapDictionary,
495
497
  OlapTable: () => OlapTable,
496
498
  SelectRowPolicy: () => SelectRowPolicy,
497
499
  SqlResource: () => SqlResource,
@@ -506,6 +508,8 @@ __export(dmv2_exports, {
506
508
  getIngestApis: () => getIngestApis,
507
509
  getMaterializedView: () => getMaterializedView,
508
510
  getMaterializedViews: () => getMaterializedViews,
511
+ getOlapDictionaries: () => getOlapDictionaries,
512
+ getOlapDictionary: () => getOlapDictionary,
509
513
  getSelectRowPolicies: () => getSelectRowPolicies,
510
514
  getSelectRowPolicy: () => getSelectRowPolicy,
511
515
  getSqlResource: () => getSqlResource,
@@ -687,6 +691,7 @@ var quoteIdentifier = (name) => {
687
691
  };
688
692
  var isTable = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "OlapTable";
689
693
  var isView = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "View";
694
+ var isDictionary = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "OlapDictionary";
690
695
  var isColumn = (value) => typeof value === "object" && value !== null && !("kind" in value) && "name" in value && "annotations" in value;
691
696
  function sqlImpl(strings, ...values) {
692
697
  return new Sql(strings, values);
@@ -713,7 +718,7 @@ var Sql = class _Sql {
713
718
  );
714
719
  }
715
720
  const valuesLength = rawValues.reduce(
716
- (len, value) => len + (instanceofSql(value) ? value.values.length : isColumn(value) || isTable(value) || isView(value) ? 0 : 1),
721
+ (len, value) => len + (instanceofSql(value) ? value.values.length : isColumn(value) || isTable(value) || isView(value) || isDictionary(value) ? 0 : 1),
717
722
  0
718
723
  );
719
724
  this.values = new Array(valuesLength);
@@ -760,6 +765,14 @@ var Sql = class _Sql {
760
765
  this.strings[pos] += `\`${child.name}\``;
761
766
  }
762
767
  this.strings[pos] += rawString;
768
+ } else if (isDictionary(child)) {
769
+ if (/\b(?:FROM|JOIN)\s*$/i.test(this.strings[pos])) {
770
+ console.warn(
771
+ `OlapDictionary '${child.getQualifiedName()}' interpolated after FROM/JOIN in sql tag. Dictionaries render as string literals (e.g. 'db.dict_name') for use with dictGet(), not as table identifiers. ClickHouse dictionaries cannot be queried directly with FROM/JOIN.`
772
+ );
773
+ }
774
+ this.strings[pos] += `'${child.getQualifiedName().replace(/'/g, "''")}'`;
775
+ this.strings[pos] += rawString;
763
776
  } else {
764
777
  this.values[pos++] = child;
765
778
  this.strings[pos] = rawString;
@@ -1000,6 +1013,12 @@ function getSelectRowPolicies() {
1000
1013
  function getSelectRowPolicy(name) {
1001
1014
  return getMooseInternal().selectRowPolicies.get(name);
1002
1015
  }
1016
+ function getOlapDictionaries() {
1017
+ return getMooseInternal().olapDictionaries;
1018
+ }
1019
+ function getOlapDictionary(name) {
1020
+ return getMooseInternal().olapDictionaries.get(name);
1021
+ }
1003
1022
 
1004
1023
  // src/consumption-apis/standalone.ts
1005
1024
  var import_node_async_hooks = require("async_hooks");
@@ -1197,7 +1216,8 @@ function createRegistryFrom(existing) {
1197
1216
  webApps: toTrackingMap(existing?.webApps),
1198
1217
  materializedViews: toTrackingMap(existing?.materializedViews),
1199
1218
  views: toTrackingMap(existing?.views),
1200
- selectRowPolicies: toTrackingMap(existing?.selectRowPolicies)
1219
+ selectRowPolicies: toTrackingMap(existing?.selectRowPolicies),
1220
+ olapDictionaries: toTrackingMap(existing?.olapDictionaries)
1201
1221
  };
1202
1222
  }
1203
1223
  var moose_internal = {
@@ -1237,6 +1257,10 @@ var moose_internal = {
1237
1257
  selectRowPolicies: new MutationTrackingMap(
1238
1258
  void 0,
1239
1259
  markRegistryMutated
1260
+ ),
1261
+ olapDictionaries: new MutationTrackingMap(
1262
+ void 0,
1263
+ markRegistryMutated
1240
1264
  )
1241
1265
  };
1242
1266
  var defaultRetentionPeriod = 60 * 60 * 24 * 7;
@@ -3118,6 +3142,369 @@ var LifeCycle = /* @__PURE__ */ ((LifeCycle2) => {
3118
3142
  return LifeCycle2;
3119
3143
  })(LifeCycle || {});
3120
3144
 
3145
+ // src/dmv2/sdk/olapDictionary.ts
3146
+ var COMPLEX_KEY_LAYOUTS = /* @__PURE__ */ new Set([
3147
+ "COMPLEX_KEY_HASHED",
3148
+ "COMPLEX_KEY_SPARSE_HASHED",
3149
+ "COMPLEX_KEY_HASHED_ARRAY",
3150
+ "COMPLEX_KEY_CACHE",
3151
+ "COMPLEX_KEY_SSD_CACHE",
3152
+ "COMPLEX_KEY_DIRECT"
3153
+ ]);
3154
+ function dataTypeToString(dataType) {
3155
+ if (typeof dataType === "string") {
3156
+ return dataType;
3157
+ }
3158
+ if (typeof dataType === "object" && dataType !== null) {
3159
+ if ("nullable" in dataType) {
3160
+ const inner = dataTypeToString(
3161
+ dataType.nullable
3162
+ );
3163
+ return `Nullable(${inner})`;
3164
+ }
3165
+ if ("elementType" in dataType) {
3166
+ const arr = dataType;
3167
+ const inner = dataTypeToString(arr.elementType);
3168
+ return arr.elementNullable ? `Array(Nullable(${inner}))` : `Array(${inner})`;
3169
+ }
3170
+ if ("name" in dataType && "values" in dataType) {
3171
+ const d = dataType;
3172
+ const entries = d.values.map(
3173
+ (v) => v.value.String !== void 0 ? `'${v.name}' = '${v.value.String}'` : `'${v.name}' = ${v.value.Int ?? 0}`
3174
+ ).join(", ");
3175
+ return `${d.name}(${entries})`;
3176
+ }
3177
+ }
3178
+ throw new Error(
3179
+ `OlapDictionary: unsupported column data type for dictionary attribute: ${JSON.stringify(dataType)}. Dictionaries only support scalar value types (strings, integers, floats, booleans, dates, Nullable wrappers, Array wrappers, and Enum types).`
3180
+ );
3181
+ }
3182
+ function buildDictionaryColumns(columns, overrides) {
3183
+ return columns.map((col) => {
3184
+ const override = overrides?.[col.name] ?? {};
3185
+ const result = {
3186
+ name: col.name,
3187
+ typeString: dataTypeToString(col.data_type)
3188
+ };
3189
+ if (override.defaultValue !== void 0)
3190
+ result.defaultValue = override.defaultValue;
3191
+ if (override.expression !== void 0)
3192
+ result.expression = override.expression;
3193
+ if (override.isInjective !== void 0)
3194
+ result.isInjective = override.isInjective;
3195
+ if (override.isHierarchical !== void 0)
3196
+ result.isHierarchical = override.isHierarchical;
3197
+ if (override.isObjectId !== void 0)
3198
+ result.isObjectId = override.isObjectId;
3199
+ if (override.comment !== void 0) result.comment = override.comment;
3200
+ return result;
3201
+ });
3202
+ }
3203
+ function serializeLifetime(lifetime) {
3204
+ if (typeof lifetime === "number") {
3205
+ if (!Number.isFinite(lifetime) || lifetime < 0 || !Number.isInteger(lifetime)) {
3206
+ throw new Error(
3207
+ `OlapDictionary: lifetime must be a finite non-negative integer (got ${lifetime}).`
3208
+ );
3209
+ }
3210
+ if (lifetime === 0) {
3211
+ return { type: "STATIC" };
3212
+ }
3213
+ return { type: "SINGLE", seconds: lifetime };
3214
+ }
3215
+ if (!Number.isFinite(lifetime.min) || !Number.isFinite(lifetime.max) || !Number.isInteger(lifetime.min) || !Number.isInteger(lifetime.max) || lifetime.min < 0 || lifetime.max < lifetime.min) {
3216
+ throw new Error(
3217
+ `OlapDictionary: lifetime range must use finite non-negative integers with min <= max (got min=${lifetime.min}, max=${lifetime.max}).`
3218
+ );
3219
+ }
3220
+ if (lifetime.min === 0 && lifetime.max === 0) {
3221
+ return { type: "STATIC" };
3222
+ }
3223
+ if (lifetime.min === lifetime.max) {
3224
+ return { type: "SINGLE", seconds: lifetime.min };
3225
+ }
3226
+ return { type: "RANGE", min: lifetime.min, max: lifetime.max };
3227
+ }
3228
+ function serializeLayout(layout) {
3229
+ const { type, ...rest } = layout;
3230
+ const snakeCaseFields = {};
3231
+ for (const [key, value] of Object.entries(rest)) {
3232
+ if (value === void 0) continue;
3233
+ const snake = key.replace(/([A-Z])/g, "_$1").toLowerCase();
3234
+ snakeCaseFields[snake] = value;
3235
+ }
3236
+ return { type, ...snakeCaseFields };
3237
+ }
3238
+ function externalTypeToRust(type) {
3239
+ const mapping = {
3240
+ http: "HTTP",
3241
+ clickhouse: "CLICK_HOUSE",
3242
+ mysql: "MYSQL",
3243
+ postgresql: "POSTGRESQL",
3244
+ redis: "REDIS",
3245
+ mongodb: "MONGODB",
3246
+ executable: "EXECUTABLE",
3247
+ s3: "S3"
3248
+ };
3249
+ return mapping[type];
3250
+ }
3251
+ function serializeExternalSource(ext) {
3252
+ const { type, ...rest } = ext;
3253
+ const inner = {
3254
+ source_type: externalTypeToRust(type)
3255
+ };
3256
+ for (const [key, value] of Object.entries(rest)) {
3257
+ inner[key] = value;
3258
+ }
3259
+ return {
3260
+ type: "EXTERNAL",
3261
+ externalSource: inner
3262
+ };
3263
+ }
3264
+ function serializeSource(config) {
3265
+ if (config.sourceTable !== void 0) {
3266
+ const table = config.sourceTable;
3267
+ if (table instanceof OlapTable) {
3268
+ return {
3269
+ type: "TABLE",
3270
+ table: table.generateTableName(),
3271
+ database: table.config.database,
3272
+ ...config.invalidateQuery !== void 0 ? { invalidateQuery: config.invalidateQuery } : {}
3273
+ };
3274
+ } else {
3275
+ return {
3276
+ type: "TABLE",
3277
+ table: table.name,
3278
+ database: table.database,
3279
+ ...config.invalidateQuery !== void 0 ? { invalidateQuery: config.invalidateQuery } : {}
3280
+ };
3281
+ }
3282
+ }
3283
+ if (config.sourceQuery !== void 0) {
3284
+ return {
3285
+ type: "QUERY",
3286
+ query: toStaticQuery(config.sourceQuery),
3287
+ ...config.invalidateQuery !== void 0 ? { invalidateQuery: config.invalidateQuery } : {}
3288
+ };
3289
+ }
3290
+ if (config.externalSource !== void 0) {
3291
+ return serializeExternalSource(config.externalSource);
3292
+ }
3293
+ throw new Error(
3294
+ "OlapDictionary: no source configured (unreachable after validation)"
3295
+ );
3296
+ }
3297
+ var OlapDictionary = class {
3298
+ /** @internal */
3299
+ kind = "OlapDictionary";
3300
+ /** Dictionary name */
3301
+ name;
3302
+ /** User configuration */
3303
+ config;
3304
+ /** Compiler-injected columns (name + type from T) */
3305
+ _columns;
3306
+ /** Serialized column list (DictionaryColumn JSON objects) */
3307
+ serializedColumns;
3308
+ constructor(name, config, _schema, columns) {
3309
+ if (_schema === void 0 || columns === void 0) {
3310
+ throw new Error(
3311
+ "Supply the type param T so that the schema is inserted by the compiler plugin."
3312
+ );
3313
+ }
3314
+ this.name = name;
3315
+ this.config = config;
3316
+ this._columns = columns;
3317
+ const sourcesSet = [
3318
+ config.sourceTable !== void 0,
3319
+ config.sourceQuery !== void 0,
3320
+ config.externalSource !== void 0
3321
+ ].filter(Boolean).length;
3322
+ if (sourcesSet === 0) {
3323
+ throw new Error(
3324
+ `OlapDictionary '${name}': exactly one of sourceTable, sourceQuery, or externalSource must be set (none provided).`
3325
+ );
3326
+ }
3327
+ if (sourcesSet > 1) {
3328
+ throw new Error(
3329
+ `OlapDictionary '${name}': exactly one of sourceTable, sourceQuery, or externalSource must be set (${sourcesSet} provided).`
3330
+ );
3331
+ }
3332
+ if (config.sourceQuery !== void 0 && !config.sourceTables?.length) {
3333
+ throw new Error(
3334
+ `OlapDictionary '${name}': sourceQuery requires sourceTables to be set for dependency tracking.`
3335
+ );
3336
+ }
3337
+ if (config.sourceQuery !== void 0) {
3338
+ if (!toStaticQuery(config.sourceQuery).trim()) {
3339
+ throw new Error(
3340
+ `OlapDictionary '${name}': sourceQuery must not be blank.`
3341
+ );
3342
+ }
3343
+ }
3344
+ if (!config.primaryKey.length) {
3345
+ throw new Error(
3346
+ `OlapDictionary '${name}': primaryKey must contain at least one column name.`
3347
+ );
3348
+ }
3349
+ if (!COMPLEX_KEY_LAYOUTS.has(config.layout.type)) {
3350
+ if (config.primaryKey.length !== 1) {
3351
+ throw new Error(
3352
+ `OlapDictionary '${name}': layout '${config.layout.type}' requires exactly 1 primary key column (got ${config.primaryKey.length}). Use a COMPLEX_KEY_* layout for string or multi-column keys.`
3353
+ );
3354
+ }
3355
+ }
3356
+ this.serializedColumns = buildDictionaryColumns(
3357
+ columns,
3358
+ config.columns
3359
+ );
3360
+ if (!config.metadata?.source) {
3361
+ const stack = new Error().stack;
3362
+ const sourceInfo = getSourceFileFromStack(stack);
3363
+ if (sourceInfo) {
3364
+ this.config.metadata = {
3365
+ ...config.metadata,
3366
+ source: { file: sourceInfo }
3367
+ };
3368
+ }
3369
+ }
3370
+ const olapDictionaries = getMooseInternal().olapDictionaries;
3371
+ if (!isClientOnlyMode() && olapDictionaries.has(name)) {
3372
+ throw new Error(`OlapDictionary with name '${name}' already exists`);
3373
+ }
3374
+ olapDictionaries.set(name, this);
3375
+ }
3376
+ /**
3377
+ * Returns the qualified dictionary name for use in dictGet calls.
3378
+ * Format: `database.name` if database is set, otherwise just `name`.
3379
+ */
3380
+ getQualifiedName() {
3381
+ if (this.config.database) {
3382
+ return `${this.config.database}.${this.name}`;
3383
+ }
3384
+ return this.name;
3385
+ }
3386
+ /**
3387
+ * Formats key arguments for use in dictGet/dictHas SQL functions.
3388
+ * Strings are treated as SQL identifiers, numbers as literals.
3389
+ */
3390
+ formatKeyArgs(keys) {
3391
+ if (keys.length !== this.config.primaryKey.length) {
3392
+ throw new Error(
3393
+ `OlapDictionary '${this.name}': expected ${this.config.primaryKey.length} key argument(s) but got ${keys.length}.`
3394
+ );
3395
+ }
3396
+ const parts = keys.map((k) => {
3397
+ if (typeof k === "object" && "strings" in k) {
3398
+ return toStaticQuery(k);
3399
+ }
3400
+ if (typeof k === "string") {
3401
+ return `\`${k.replace(/`/g, "``")}\``;
3402
+ }
3403
+ return String(k);
3404
+ });
3405
+ return parts.length === 1 ? parts[0] : `(${parts.join(", ")})`;
3406
+ }
3407
+ /**
3408
+ * Generates a `dictGet('dict', 'attr', key)` SQL fragment.
3409
+ *
3410
+ * @param attr - The attribute (column) name to retrieve
3411
+ * @param keys - Key expression(s). Strings are treated as column identifiers.
3412
+ *
3413
+ * @example
3414
+ * ```typescript
3415
+ * sql`SELECT ${ProductDict.get("ProductName", "product_id")} AS name FROM ...`
3416
+ * // → SELECT dictGet('db.dict_products', 'ProductName', `product_id`) AS name FROM ...
3417
+ * ```
3418
+ */
3419
+ get(attr, ...keys) {
3420
+ if (!keys.length) {
3421
+ throw new Error(
3422
+ `OlapDictionary.get('${attr}'): at least one key argument is required.`
3423
+ );
3424
+ }
3425
+ const qualifiedName = this.getQualifiedName().replace(/'/g, "''");
3426
+ const escapedAttr = attr.replace(/'/g, "''");
3427
+ const keyExpr = this.formatKeyArgs(keys);
3428
+ return sql.raw(`dictGet('${qualifiedName}', '${escapedAttr}', ${keyExpr})`);
3429
+ }
3430
+ /**
3431
+ * Generates a `dictGetOrDefault('dict', 'attr', key, default)` SQL fragment.
3432
+ *
3433
+ * @param attr - The attribute (column) name to retrieve
3434
+ * @param defaultVal - The default value if the key is not found
3435
+ * @param keys - Key expression(s)
3436
+ */
3437
+ getOrDefault(attr, defaultVal, ...keys) {
3438
+ if (!keys.length) {
3439
+ throw new Error(
3440
+ `OlapDictionary.getOrDefault('${attr}'): at least one key argument is required.`
3441
+ );
3442
+ }
3443
+ const qualifiedName = this.getQualifiedName().replace(/'/g, "''");
3444
+ const escapedAttr = attr.replace(/'/g, "''");
3445
+ const keyExpr = this.formatKeyArgs(keys);
3446
+ let defaultExpr;
3447
+ if (typeof defaultVal === "object" && "strings" in defaultVal) {
3448
+ defaultExpr = toStaticQuery(defaultVal);
3449
+ } else if (typeof defaultVal === "string") {
3450
+ defaultExpr = `'${defaultVal.replace(/'/g, "''")}'`;
3451
+ } else {
3452
+ defaultExpr = String(defaultVal);
3453
+ }
3454
+ return sql.raw(
3455
+ `dictGetOrDefault('${qualifiedName}', '${escapedAttr}', ${keyExpr}, ${defaultExpr})`
3456
+ );
3457
+ }
3458
+ /**
3459
+ * Generates a `dictHas('dict', key)` SQL fragment.
3460
+ *
3461
+ * @param keys - Key expression(s)
3462
+ *
3463
+ * @example
3464
+ * ```typescript
3465
+ * sql`SELECT * FROM source WHERE ${ProductDict.has("product_id")}`
3466
+ * // → SELECT * FROM source WHERE dictHas('db.dict_products', `product_id`)
3467
+ * ```
3468
+ */
3469
+ has(...keys) {
3470
+ if (!keys.length) {
3471
+ throw new Error(
3472
+ `OlapDictionary.has(): at least one key argument is required.`
3473
+ );
3474
+ }
3475
+ const qualifiedName = this.getQualifiedName().replace(/'/g, "''");
3476
+ const keyExpr = this.formatKeyArgs(keys);
3477
+ return sql.raw(`dictHas('${qualifiedName}', ${keyExpr})`);
3478
+ }
3479
+ /**
3480
+ * Serializes this dictionary to the JSON format expected by the Rust CLI.
3481
+ * @internal
3482
+ */
3483
+ toJson() {
3484
+ const source = serializeSource(this.config);
3485
+ const result = {
3486
+ name: this.name,
3487
+ source,
3488
+ primaryKey: this.config.primaryKey,
3489
+ columns: this.serializedColumns,
3490
+ layout: serializeLayout(this.config.layout),
3491
+ lifetime: serializeLifetime(this.config.lifetime),
3492
+ settings: this.config.settings ?? {},
3493
+ lifeCycle: this.config.lifeCycle ?? "FULLY_MANAGED" /* FULLY_MANAGED */
3494
+ };
3495
+ if (this.config.database !== void 0)
3496
+ result.database = this.config.database;
3497
+ if (this.config.clusterName !== void 0)
3498
+ result.clusterName = this.config.clusterName;
3499
+ if (this.config.invalidateQuery !== void 0)
3500
+ result.invalidateQuery = this.config.invalidateQuery;
3501
+ if (this.config.comment !== void 0) result.comment = this.config.comment;
3502
+ if (this.config.metadata !== void 0)
3503
+ result.metadata = this.config.metadata;
3504
+ return result;
3505
+ }
3506
+ };
3507
+
3121
3508
  // src/dmv2/sdk/webApp.ts
3122
3509
  var RESERVED_MOUNT_PATHS = [
3123
3510
  "/admin",
@@ -3247,6 +3634,7 @@ Examples:
3247
3634
  // Annotate the CommonJS export names for ESM import in node:
3248
3635
  0 && (module.exports = {
3249
3636
  Api,
3637
+ COMPLEX_KEY_LAYOUTS,
3250
3638
  ClickHouseEngines,
3251
3639
  ConsumptionApi,
3252
3640
  DeadLetterQueue,
@@ -3255,6 +3643,7 @@ Examples:
3255
3643
  IngestPipeline,
3256
3644
  LifeCycle,
3257
3645
  MaterializedView,
3646
+ OlapDictionary,
3258
3647
  OlapTable,
3259
3648
  SelectRowPolicy,
3260
3649
  SqlResource,
@@ -3269,6 +3658,8 @@ Examples:
3269
3658
  getIngestApis,
3270
3659
  getMaterializedView,
3271
3660
  getMaterializedViews,
3661
+ getOlapDictionaries,
3662
+ getOlapDictionary,
3272
3663
  getSelectRowPolicies,
3273
3664
  getSelectRowPolicy,
3274
3665
  getSqlResource,