@514labs/moose-lib 0.6.457 → 0.6.458

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/index.js CHANGED
@@ -395,13 +395,17 @@ var init_runtime = __esm({
395
395
  const envUseSSL = this._parseBool(
396
396
  this._env("MOOSE_CLICKHOUSE_CONFIG__USE_SSL")
397
397
  );
398
+ const envRlsUser = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_USER");
399
+ const envRlsPassword = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_PASSWORD");
398
400
  return {
399
401
  host: envHost ?? projectConfig.clickhouse_config.host,
400
402
  port: envPort ?? projectConfig.clickhouse_config.host_port.toString(),
401
403
  username: envUser ?? projectConfig.clickhouse_config.user,
402
404
  password: envPassword ?? projectConfig.clickhouse_config.password,
403
405
  database: envDb ?? projectConfig.clickhouse_config.db_name,
404
- useSSL: envUseSSL !== void 0 ? envUseSSL : projectConfig.clickhouse_config.use_ssl || false
406
+ useSSL: envUseSSL !== void 0 ? envUseSSL : projectConfig.clickhouse_config.use_ssl || false,
407
+ rlsUser: envRlsUser ?? projectConfig.clickhouse_config.rls_user ?? void 0,
408
+ rlsPassword: envRlsPassword ?? projectConfig.clickhouse_config.rls_password ?? void 0
405
409
  };
406
410
  }
407
411
  async getStandaloneClickhouseConfig(overrides) {
@@ -416,6 +420,8 @@ var init_runtime = __esm({
416
420
  const envUseSSL = this._parseBool(
417
421
  this._env("MOOSE_CLICKHOUSE_CONFIG__USE_SSL")
418
422
  );
423
+ const envRlsUser = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_USER");
424
+ const envRlsPassword = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_PASSWORD");
419
425
  let projectConfig;
420
426
  try {
421
427
  projectConfig = await readProjectConfig();
@@ -436,7 +442,9 @@ var init_runtime = __esm({
436
442
  username: overrides?.username ?? envUser ?? projectConfig?.clickhouse_config.user ?? defaults.username,
437
443
  password: overrides?.password ?? envPassword ?? projectConfig?.clickhouse_config.password ?? defaults.password,
438
444
  database: overrides?.database ?? envDb ?? projectConfig?.clickhouse_config.db_name ?? defaults.database,
439
- useSSL: overrides?.useSSL ?? envUseSSL ?? projectConfig?.clickhouse_config.use_ssl ?? defaults.useSSL
445
+ useSSL: overrides?.useSSL ?? envUseSSL ?? projectConfig?.clickhouse_config.use_ssl ?? defaults.useSSL,
446
+ rlsUser: envRlsUser ?? projectConfig?.clickhouse_config.rls_user ?? void 0,
447
+ rlsPassword: envRlsPassword ?? projectConfig?.clickhouse_config.rls_password ?? void 0
440
448
  };
441
449
  }
442
450
  async getKafkaConfig() {
@@ -494,6 +502,9 @@ __export(index_exports, {
494
502
  MAX_RETRIES: () => MAX_RETRIES,
495
503
  MAX_RETRIES_PRODUCER: () => MAX_RETRIES_PRODUCER,
496
504
  MAX_RETRY_TIME_MS: () => MAX_RETRY_TIME_MS,
505
+ MOOSE_RLS_ROLE: () => MOOSE_RLS_ROLE,
506
+ MOOSE_RLS_SETTING_PREFIX: () => MOOSE_RLS_SETTING_PREFIX,
507
+ MOOSE_RLS_USER: () => MOOSE_RLS_USER,
497
508
  MOOSE_RUNTIME_ENV_PREFIX: () => MOOSE_RUNTIME_ENV_PREFIX,
498
509
  MaterializedView: () => MaterializedView,
499
510
  MooseCache: () => MooseCache,
@@ -502,6 +513,7 @@ __export(index_exports, {
502
513
  QueryClient: () => QueryClient,
503
514
  RETRY_FACTOR_PRODUCER: () => RETRY_FACTOR_PRODUCER,
504
515
  RETRY_INITIAL_TIME_MS: () => RETRY_INITIAL_TIME_MS,
516
+ SelectRowPolicy: () => SelectRowPolicy,
505
517
  Sql: () => Sql,
506
518
  SqlResource: () => SqlResource,
507
519
  Stream: () => Stream,
@@ -517,6 +529,7 @@ __export(index_exports, {
517
529
  avg: () => avg,
518
530
  between: () => between,
519
531
  buildQuery: () => buildQuery,
532
+ buildRowPolicyOptionsFromClaims: () => buildRowPolicyOptionsFromClaims,
520
533
  cliLog: () => cliLog,
521
534
  columnsFromTable: () => columnsFromTable,
522
535
  compilerLog: () => compilerLog,
@@ -547,6 +560,8 @@ __export(index_exports, {
547
560
  getMooseClients: () => getMooseClients,
548
561
  getMooseUtils: () => getMooseUtils,
549
562
  getMooseUtilsFromRequest: () => getMooseUtilsFromRequest,
563
+ getSelectRowPolicies: () => getSelectRowPolicies,
564
+ getSelectRowPolicy: () => getSelectRowPolicy,
550
565
  getSqlResource: () => getSqlResource,
551
566
  getSqlResources: () => getSqlResources,
552
567
  getStream: () => getStream,
@@ -934,7 +949,8 @@ function createRegistryFrom(existing) {
934
949
  workflows: toTrackingMap(existing?.workflows),
935
950
  webApps: toTrackingMap(existing?.webApps),
936
951
  materializedViews: toTrackingMap(existing?.materializedViews),
937
- views: toTrackingMap(existing?.views)
952
+ views: toTrackingMap(existing?.views),
953
+ selectRowPolicies: toTrackingMap(existing?.selectRowPolicies)
938
954
  };
939
955
  }
940
956
  var moose_internal = {
@@ -970,7 +986,11 @@ var moose_internal = {
970
986
  void 0,
971
987
  markRegistryMutated
972
988
  ),
973
- views: new MutationTrackingMap(void 0, markRegistryMutated)
989
+ views: new MutationTrackingMap(void 0, markRegistryMutated),
990
+ selectRowPolicies: new MutationTrackingMap(
991
+ void 0,
992
+ markRegistryMutated
993
+ )
974
994
  };
975
995
  var defaultRetentionPeriod = 60 * 60 * 24 * 7;
976
996
  var initializeMooseInternalRegistry = () => {
@@ -1001,6 +1021,7 @@ var loadIndex = async () => {
1001
1021
  registry.webApps.clear();
1002
1022
  registry.materializedViews.clear();
1003
1023
  registry.views.clear();
1024
+ registry.selectRowPolicies.clear();
1004
1025
  const outDir = getOutDir();
1005
1026
  const compiledDir = path4.isAbsolute(outDir) ? outDir : path4.join(import_process.default.cwd(), outDir);
1006
1027
  Object.keys(require.cache).forEach((key) => {
@@ -1401,10 +1422,7 @@ var OlapTable = class extends TypedBase {
1401
1422
  }
1402
1423
  tables.set(registryKey, this);
1403
1424
  }
1404
- /**
1405
- * Generates the versioned table name following Moose's naming convention
1406
- * Format: {tableName}_{version_with_dots_replaced_by_underscores}
1407
- */
1425
+ /** @internal Returns the versioned ClickHouse table name (e.g., "events_1_0_0") */
1408
1426
  generateTableName() {
1409
1427
  if (this._cachedTableName) {
1410
1428
  return this._cachedTableName;
@@ -3113,6 +3131,47 @@ var View = class {
3113
3131
  }
3114
3132
  };
3115
3133
 
3134
+ // src/dmv2/sdk/selectRowPolicy.ts
3135
+ var SelectRowPolicy = class {
3136
+ /** @internal */
3137
+ kind = "SelectRowPolicy";
3138
+ /** The name of the row policy */
3139
+ name;
3140
+ /** The policy configuration */
3141
+ config;
3142
+ constructor(name, config) {
3143
+ if (!name.trim()) {
3144
+ throw new Error("SelectRowPolicy name must not be empty");
3145
+ }
3146
+ if (!config.tables.length) {
3147
+ throw new Error(`SelectRowPolicy '${name}': tables must not be empty`);
3148
+ }
3149
+ if (!config.column.trim()) {
3150
+ throw new Error(`SelectRowPolicy '${name}': column must not be empty`);
3151
+ }
3152
+ if (!config.claim.trim()) {
3153
+ throw new Error(`SelectRowPolicy '${name}': claim must not be empty`);
3154
+ }
3155
+ this.name = name;
3156
+ this.config = Object.freeze({
3157
+ ...config,
3158
+ tables: Object.freeze([...config.tables])
3159
+ });
3160
+ const selectRowPolicies = getMooseInternal().selectRowPolicies;
3161
+ if (!isClientOnlyMode() && selectRowPolicies.has(this.name)) {
3162
+ throw new Error(`SelectRowPolicy with name ${this.name} already exists`);
3163
+ }
3164
+ selectRowPolicies.set(this.name, this);
3165
+ }
3166
+ /** Resolved table references for serialization */
3167
+ get tableRefs() {
3168
+ return this.config.tables.map((t) => ({
3169
+ name: t.generateTableName(),
3170
+ ...t.config.database ? { database: t.config.database } : {}
3171
+ }));
3172
+ }
3173
+ };
3174
+
3116
3175
  // src/dmv2/sdk/lifeCycle.ts
3117
3176
  var LifeCycle = /* @__PURE__ */ ((LifeCycle2) => {
3118
3177
  LifeCycle2["FULLY_MANAGED"] = "FULLY_MANAGED";
@@ -3324,6 +3383,12 @@ function getViews() {
3324
3383
  function getView(name) {
3325
3384
  return getMooseInternal().views.get(name);
3326
3385
  }
3386
+ function getSelectRowPolicies() {
3387
+ return getMooseInternal().selectRowPolicies;
3388
+ }
3389
+ function getSelectRowPolicy(name) {
3390
+ return getMooseInternal().selectRowPolicies.get(name);
3391
+ }
3327
3392
 
3328
3393
  // src/index.ts
3329
3394
  init_commons();
@@ -3399,12 +3464,27 @@ var MooseClient = class {
3399
3464
  this.workflow = new WorkflowClient(temporalClient);
3400
3465
  }
3401
3466
  };
3467
+ var MOOSE_RLS_ROLE = "moose_rls_role";
3468
+ var MOOSE_RLS_USER = "moose_rls_user";
3469
+ var MOOSE_RLS_SETTING_PREFIX = "SQL_moose_rls_";
3470
+ function buildRowPolicyOptionsFromClaims(config, claims) {
3471
+ const clickhouse_settings = /* @__PURE__ */ Object.create(null);
3472
+ for (const [settingName, claimName] of Object.entries(config)) {
3473
+ const value = claims[claimName];
3474
+ if (value !== void 0 && value !== null) {
3475
+ clickhouse_settings[settingName] = String(value);
3476
+ }
3477
+ }
3478
+ return { role: MOOSE_RLS_ROLE, clickhouse_settings };
3479
+ }
3402
3480
  var QueryClient = class {
3403
3481
  client;
3404
3482
  query_id_prefix;
3405
- constructor(client, query_id_prefix) {
3483
+ rowPolicyOptions;
3484
+ constructor(client, query_id_prefix, rowPolicyOptions) {
3406
3485
  this.client = client;
3407
3486
  this.query_id_prefix = query_id_prefix;
3487
+ this.rowPolicyOptions = rowPolicyOptions;
3408
3488
  }
3409
3489
  async execute(sql3) {
3410
3490
  const [query, query_params] = toQuery(sql3);
@@ -3419,7 +3499,11 @@ var QueryClient = class {
3419
3499
  // where response buffering would harm streaming performance and concurrency
3420
3500
  clickhouse_settings: {
3421
3501
  asterisk_include_materialized_columns: 1,
3422
- asterisk_include_alias_columns: 1
3502
+ asterisk_include_alias_columns: 1,
3503
+ ...this.rowPolicyOptions?.clickhouse_settings
3504
+ },
3505
+ ...this.rowPolicyOptions && {
3506
+ role: this.rowPolicyOptions.role
3423
3507
  }
3424
3508
  });
3425
3509
  const elapsedMs = import_perf_hooks.performance.now() - start;
@@ -3872,58 +3956,148 @@ var MooseCache = class _MooseCache {
3872
3956
 
3873
3957
  // src/consumption-apis/standalone.ts
3874
3958
  init_commons();
3959
+ var import_node_async_hooks = require("async_hooks");
3960
+ var requestContextStorage = new import_node_async_hooks.AsyncLocalStorage();
3961
+ function isLegacyRequestArg(arg) {
3962
+ if (arg === null || typeof arg !== "object") return false;
3963
+ const obj = arg;
3964
+ return "method" in obj || "url" in obj || "headers" in obj;
3965
+ }
3966
+ function getRowPoliciesConfigFromRegistry() {
3967
+ const policies = getSelectRowPolicies();
3968
+ if (policies.size === 0) return void 0;
3969
+ const config = /* @__PURE__ */ Object.create(null);
3970
+ for (const policy of policies.values()) {
3971
+ config[`${MOOSE_RLS_SETTING_PREFIX}${policy.config.column}`] = policy.config.claim;
3972
+ }
3973
+ return config;
3974
+ }
3875
3975
  var standaloneUtils = null;
3876
3976
  var initPromise2 = null;
3977
+ var standaloneRlsClient = null;
3978
+ var standaloneClickhouseConfig = null;
3877
3979
  var toClientConfig = (config) => ({
3878
3980
  ...config,
3879
3981
  useSSL: config.useSSL ? "true" : "false"
3880
3982
  });
3881
- async function getMooseUtils(req) {
3882
- if (req !== void 0) {
3983
+ async function getMooseUtils(options) {
3984
+ if (options !== void 0 && isLegacyRequestArg(options)) {
3883
3985
  console.warn(
3884
- "[DEPRECATED] getMooseUtils(req) no longer requires a request parameter. Use getMooseUtils() instead."
3986
+ "[DEPRECATED] getMooseUtils(req) no longer requires a request parameter. Use getMooseUtils() instead, or getMooseUtils({ rlsContext }) for row policies."
3885
3987
  );
3988
+ options = void 0;
3886
3989
  }
3887
3990
  const runtimeContext = globalThis._mooseRuntimeContext;
3888
3991
  if (runtimeContext) {
3889
- return {
3890
- client: runtimeContext.client,
3891
- sql,
3892
- jwt: runtimeContext.jwt
3893
- };
3992
+ return resolveRuntimeUtils(runtimeContext, options);
3894
3993
  }
3895
- if (standaloneUtils) {
3896
- return standaloneUtils;
3994
+ await ensureStandaloneInit();
3995
+ if (options?.rlsContext) {
3996
+ return createStandaloneRlsUtils(options.rlsContext);
3897
3997
  }
3898
- if (initPromise2) {
3899
- return initPromise2;
3900
- }
3901
- initPromise2 = (async () => {
3902
- await Promise.resolve().then(() => (init_runtime(), runtime_exports));
3903
- const configRegistry = globalThis._mooseConfigRegistry;
3904
- if (!configRegistry) {
3998
+ return standaloneUtils;
3999
+ }
4000
+ function resolveRuntimeUtils(runtimeContext, options) {
4001
+ const reqCtx = requestContextStorage.getStore();
4002
+ const jwt = reqCtx?.jwt ?? runtimeContext.jwt;
4003
+ let rowPolicyOpts;
4004
+ if (options?.rlsContext) {
4005
+ if (!runtimeContext.rowPoliciesConfig) {
3905
4006
  throw new Error(
3906
- "Moose not initialized. Ensure you're running within a Moose app or have proper configuration set up."
4007
+ "rlsContext was provided but no row policies are configured. Define at least one SelectRowPolicy before using rlsContext."
3907
4008
  );
3908
4009
  }
3909
- const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig();
3910
- const clickhouseClient = getClickhouseClient(
3911
- toClientConfig(clickhouseConfig)
4010
+ rowPolicyOpts = buildRowPolicyOptionsFromClaims(
4011
+ runtimeContext.rowPoliciesConfig,
4012
+ options.rlsContext
3912
4013
  );
3913
- const queryClient = new QueryClient(clickhouseClient, "standalone");
3914
- const mooseClient = new MooseClient(queryClient);
3915
- standaloneUtils = {
3916
- client: mooseClient,
4014
+ } else {
4015
+ rowPolicyOpts = reqCtx?.rowPolicyOpts;
4016
+ }
4017
+ if (rowPolicyOpts) {
4018
+ const rlsClient = runtimeContext.rlsClickhouseClient ?? runtimeContext.clickhouseClient;
4019
+ const scopedQueryClient = new QueryClient(
4020
+ rlsClient,
4021
+ "rls-scoped",
4022
+ rowPolicyOpts
4023
+ );
4024
+ return {
4025
+ client: new MooseClient(scopedQueryClient, runtimeContext.temporalClient),
3917
4026
  sql,
3918
- jwt: void 0
4027
+ jwt
3919
4028
  };
3920
- return standaloneUtils;
3921
- })();
3922
- try {
3923
- return await initPromise2;
3924
- } finally {
3925
- initPromise2 = null;
3926
4029
  }
4030
+ return {
4031
+ client: runtimeContext.client,
4032
+ sql,
4033
+ jwt
4034
+ };
4035
+ }
4036
+ async function ensureStandaloneInit() {
4037
+ if (standaloneUtils) return;
4038
+ if (!initPromise2) {
4039
+ initPromise2 = (async () => {
4040
+ await Promise.resolve().then(() => (init_runtime(), runtime_exports));
4041
+ const configRegistry = globalThis._mooseConfigRegistry;
4042
+ if (!configRegistry) {
4043
+ throw new Error(
4044
+ "Moose not initialized. Ensure you're running within a Moose app or have proper configuration set up."
4045
+ );
4046
+ }
4047
+ const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig();
4048
+ standaloneClickhouseConfig = clickhouseConfig;
4049
+ const clickhouseClient = getClickhouseClient(
4050
+ toClientConfig(clickhouseConfig)
4051
+ );
4052
+ const queryClient = new QueryClient(clickhouseClient, "standalone");
4053
+ const mooseClient = new MooseClient(queryClient);
4054
+ standaloneUtils = {
4055
+ client: mooseClient,
4056
+ sql,
4057
+ jwt: void 0
4058
+ };
4059
+ return standaloneUtils;
4060
+ })();
4061
+ try {
4062
+ await initPromise2;
4063
+ } finally {
4064
+ initPromise2 = null;
4065
+ }
4066
+ } else {
4067
+ await initPromise2;
4068
+ }
4069
+ }
4070
+ function createStandaloneRlsUtils(rlsContext) {
4071
+ const rowPoliciesConfig = getRowPoliciesConfigFromRegistry();
4072
+ if (!rowPoliciesConfig) {
4073
+ throw new Error(
4074
+ "rlsContext was provided but no SelectRowPolicy primitives are registered. Define at least one SelectRowPolicy before using rlsContext."
4075
+ );
4076
+ }
4077
+ if (!standaloneRlsClient && standaloneClickhouseConfig) {
4078
+ standaloneRlsClient = getClickhouseClient(
4079
+ toClientConfig({
4080
+ ...standaloneClickhouseConfig,
4081
+ username: standaloneClickhouseConfig.rlsUser ?? MOOSE_RLS_USER,
4082
+ password: standaloneClickhouseConfig.rlsPassword ?? standaloneClickhouseConfig.password
4083
+ })
4084
+ );
4085
+ }
4086
+ const rowPolicyOpts = buildRowPolicyOptionsFromClaims(
4087
+ rowPoliciesConfig,
4088
+ rlsContext
4089
+ );
4090
+ const rlsClient = standaloneRlsClient ?? standaloneUtils.client.query.client;
4091
+ const scopedQueryClient = new QueryClient(
4092
+ rlsClient,
4093
+ "rls-scoped",
4094
+ rowPolicyOpts
4095
+ );
4096
+ return {
4097
+ client: new MooseClient(scopedQueryClient),
4098
+ sql,
4099
+ jwt: void 0
4100
+ };
3927
4101
  }
3928
4102
  async function getMooseClients(config) {
3929
4103
  console.warn(
@@ -4966,6 +5140,9 @@ function createQueryHandler(config) {
4966
5140
  MAX_RETRIES,
4967
5141
  MAX_RETRIES_PRODUCER,
4968
5142
  MAX_RETRY_TIME_MS,
5143
+ MOOSE_RLS_ROLE,
5144
+ MOOSE_RLS_SETTING_PREFIX,
5145
+ MOOSE_RLS_USER,
4969
5146
  MOOSE_RUNTIME_ENV_PREFIX,
4970
5147
  MaterializedView,
4971
5148
  MooseCache,
@@ -4974,6 +5151,7 @@ function createQueryHandler(config) {
4974
5151
  QueryClient,
4975
5152
  RETRY_FACTOR_PRODUCER,
4976
5153
  RETRY_INITIAL_TIME_MS,
5154
+ SelectRowPolicy,
4977
5155
  Sql,
4978
5156
  SqlResource,
4979
5157
  Stream,
@@ -4989,6 +5167,7 @@ function createQueryHandler(config) {
4989
5167
  avg,
4990
5168
  between,
4991
5169
  buildQuery,
5170
+ buildRowPolicyOptionsFromClaims,
4992
5171
  cliLog,
4993
5172
  columnsFromTable,
4994
5173
  compilerLog,
@@ -5019,6 +5198,8 @@ function createQueryHandler(config) {
5019
5198
  getMooseClients,
5020
5199
  getMooseUtils,
5021
5200
  getMooseUtilsFromRequest,
5201
+ getSelectRowPolicies,
5202
+ getSelectRowPolicy,
5022
5203
  getSqlResource,
5023
5204
  getSqlResources,
5024
5205
  getStream,