@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.mjs CHANGED
@@ -384,13 +384,17 @@ var init_runtime = __esm({
384
384
  const envUseSSL = this._parseBool(
385
385
  this._env("MOOSE_CLICKHOUSE_CONFIG__USE_SSL")
386
386
  );
387
+ const envRlsUser = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_USER");
388
+ const envRlsPassword = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_PASSWORD");
387
389
  return {
388
390
  host: envHost ?? projectConfig.clickhouse_config.host,
389
391
  port: envPort ?? projectConfig.clickhouse_config.host_port.toString(),
390
392
  username: envUser ?? projectConfig.clickhouse_config.user,
391
393
  password: envPassword ?? projectConfig.clickhouse_config.password,
392
394
  database: envDb ?? projectConfig.clickhouse_config.db_name,
393
- useSSL: envUseSSL !== void 0 ? envUseSSL : projectConfig.clickhouse_config.use_ssl || false
395
+ useSSL: envUseSSL !== void 0 ? envUseSSL : projectConfig.clickhouse_config.use_ssl || false,
396
+ rlsUser: envRlsUser ?? projectConfig.clickhouse_config.rls_user ?? void 0,
397
+ rlsPassword: envRlsPassword ?? projectConfig.clickhouse_config.rls_password ?? void 0
394
398
  };
395
399
  }
396
400
  async getStandaloneClickhouseConfig(overrides) {
@@ -405,6 +409,8 @@ var init_runtime = __esm({
405
409
  const envUseSSL = this._parseBool(
406
410
  this._env("MOOSE_CLICKHOUSE_CONFIG__USE_SSL")
407
411
  );
412
+ const envRlsUser = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_USER");
413
+ const envRlsPassword = this._env("MOOSE_CLICKHOUSE_CONFIG__RLS_PASSWORD");
408
414
  let projectConfig;
409
415
  try {
410
416
  projectConfig = await readProjectConfig();
@@ -425,7 +431,9 @@ var init_runtime = __esm({
425
431
  username: overrides?.username ?? envUser ?? projectConfig?.clickhouse_config.user ?? defaults.username,
426
432
  password: overrides?.password ?? envPassword ?? projectConfig?.clickhouse_config.password ?? defaults.password,
427
433
  database: overrides?.database ?? envDb ?? projectConfig?.clickhouse_config.db_name ?? defaults.database,
428
- useSSL: overrides?.useSSL ?? envUseSSL ?? projectConfig?.clickhouse_config.use_ssl ?? defaults.useSSL
434
+ useSSL: overrides?.useSSL ?? envUseSSL ?? projectConfig?.clickhouse_config.use_ssl ?? defaults.useSSL,
435
+ rlsUser: envRlsUser ?? projectConfig?.clickhouse_config.rls_user ?? void 0,
436
+ rlsPassword: envRlsPassword ?? projectConfig?.clickhouse_config.rls_password ?? void 0
429
437
  };
430
438
  }
431
439
  async getKafkaConfig() {
@@ -786,7 +794,8 @@ function createRegistryFrom(existing) {
786
794
  workflows: toTrackingMap(existing?.workflows),
787
795
  webApps: toTrackingMap(existing?.webApps),
788
796
  materializedViews: toTrackingMap(existing?.materializedViews),
789
- views: toTrackingMap(existing?.views)
797
+ views: toTrackingMap(existing?.views),
798
+ selectRowPolicies: toTrackingMap(existing?.selectRowPolicies)
790
799
  };
791
800
  }
792
801
  var moose_internal = {
@@ -822,7 +831,11 @@ var moose_internal = {
822
831
  void 0,
823
832
  markRegistryMutated
824
833
  ),
825
- views: new MutationTrackingMap(void 0, markRegistryMutated)
834
+ views: new MutationTrackingMap(void 0, markRegistryMutated),
835
+ selectRowPolicies: new MutationTrackingMap(
836
+ void 0,
837
+ markRegistryMutated
838
+ )
826
839
  };
827
840
  var defaultRetentionPeriod = 60 * 60 * 24 * 7;
828
841
  var initializeMooseInternalRegistry = () => {
@@ -853,6 +866,7 @@ var loadIndex = async () => {
853
866
  registry.webApps.clear();
854
867
  registry.materializedViews.clear();
855
868
  registry.views.clear();
869
+ registry.selectRowPolicies.clear();
856
870
  const outDir = getOutDir();
857
871
  const compiledDir = path4.isAbsolute(outDir) ? outDir : path4.join(process3.cwd(), outDir);
858
872
  Object.keys(__require.cache).forEach((key) => {
@@ -1253,10 +1267,7 @@ var OlapTable = class extends TypedBase {
1253
1267
  }
1254
1268
  tables.set(registryKey, this);
1255
1269
  }
1256
- /**
1257
- * Generates the versioned table name following Moose's naming convention
1258
- * Format: {tableName}_{version_with_dots_replaced_by_underscores}
1259
- */
1270
+ /** @internal Returns the versioned ClickHouse table name (e.g., "events_1_0_0") */
1260
1271
  generateTableName() {
1261
1272
  if (this._cachedTableName) {
1262
1273
  return this._cachedTableName;
@@ -2965,6 +2976,47 @@ var View = class {
2965
2976
  }
2966
2977
  };
2967
2978
 
2979
+ // src/dmv2/sdk/selectRowPolicy.ts
2980
+ var SelectRowPolicy = class {
2981
+ /** @internal */
2982
+ kind = "SelectRowPolicy";
2983
+ /** The name of the row policy */
2984
+ name;
2985
+ /** The policy configuration */
2986
+ config;
2987
+ constructor(name, config) {
2988
+ if (!name.trim()) {
2989
+ throw new Error("SelectRowPolicy name must not be empty");
2990
+ }
2991
+ if (!config.tables.length) {
2992
+ throw new Error(`SelectRowPolicy '${name}': tables must not be empty`);
2993
+ }
2994
+ if (!config.column.trim()) {
2995
+ throw new Error(`SelectRowPolicy '${name}': column must not be empty`);
2996
+ }
2997
+ if (!config.claim.trim()) {
2998
+ throw new Error(`SelectRowPolicy '${name}': claim must not be empty`);
2999
+ }
3000
+ this.name = name;
3001
+ this.config = Object.freeze({
3002
+ ...config,
3003
+ tables: Object.freeze([...config.tables])
3004
+ });
3005
+ const selectRowPolicies = getMooseInternal().selectRowPolicies;
3006
+ if (!isClientOnlyMode() && selectRowPolicies.has(this.name)) {
3007
+ throw new Error(`SelectRowPolicy with name ${this.name} already exists`);
3008
+ }
3009
+ selectRowPolicies.set(this.name, this);
3010
+ }
3011
+ /** Resolved table references for serialization */
3012
+ get tableRefs() {
3013
+ return this.config.tables.map((t) => ({
3014
+ name: t.generateTableName(),
3015
+ ...t.config.database ? { database: t.config.database } : {}
3016
+ }));
3017
+ }
3018
+ };
3019
+
2968
3020
  // src/dmv2/sdk/lifeCycle.ts
2969
3021
  var LifeCycle = /* @__PURE__ */ ((LifeCycle2) => {
2970
3022
  LifeCycle2["FULLY_MANAGED"] = "FULLY_MANAGED";
@@ -3176,6 +3228,12 @@ function getViews() {
3176
3228
  function getView(name) {
3177
3229
  return getMooseInternal().views.get(name);
3178
3230
  }
3231
+ function getSelectRowPolicies() {
3232
+ return getMooseInternal().selectRowPolicies;
3233
+ }
3234
+ function getSelectRowPolicy(name) {
3235
+ return getMooseInternal().selectRowPolicies.get(name);
3236
+ }
3179
3237
 
3180
3238
  // src/index.ts
3181
3239
  init_commons();
@@ -3254,12 +3312,27 @@ var MooseClient = class {
3254
3312
  this.workflow = new WorkflowClient(temporalClient);
3255
3313
  }
3256
3314
  };
3315
+ var MOOSE_RLS_ROLE = "moose_rls_role";
3316
+ var MOOSE_RLS_USER = "moose_rls_user";
3317
+ var MOOSE_RLS_SETTING_PREFIX = "SQL_moose_rls_";
3318
+ function buildRowPolicyOptionsFromClaims(config, claims) {
3319
+ const clickhouse_settings = /* @__PURE__ */ Object.create(null);
3320
+ for (const [settingName, claimName] of Object.entries(config)) {
3321
+ const value = claims[claimName];
3322
+ if (value !== void 0 && value !== null) {
3323
+ clickhouse_settings[settingName] = String(value);
3324
+ }
3325
+ }
3326
+ return { role: MOOSE_RLS_ROLE, clickhouse_settings };
3327
+ }
3257
3328
  var QueryClient = class {
3258
3329
  client;
3259
3330
  query_id_prefix;
3260
- constructor(client, query_id_prefix) {
3331
+ rowPolicyOptions;
3332
+ constructor(client, query_id_prefix, rowPolicyOptions) {
3261
3333
  this.client = client;
3262
3334
  this.query_id_prefix = query_id_prefix;
3335
+ this.rowPolicyOptions = rowPolicyOptions;
3263
3336
  }
3264
3337
  async execute(sql3) {
3265
3338
  const [query, query_params] = toQuery(sql3);
@@ -3274,7 +3347,11 @@ var QueryClient = class {
3274
3347
  // where response buffering would harm streaming performance and concurrency
3275
3348
  clickhouse_settings: {
3276
3349
  asterisk_include_materialized_columns: 1,
3277
- asterisk_include_alias_columns: 1
3350
+ asterisk_include_alias_columns: 1,
3351
+ ...this.rowPolicyOptions?.clickhouse_settings
3352
+ },
3353
+ ...this.rowPolicyOptions && {
3354
+ role: this.rowPolicyOptions.role
3278
3355
  }
3279
3356
  });
3280
3357
  const elapsedMs = performance.now() - start;
@@ -3727,58 +3804,148 @@ var MooseCache = class _MooseCache {
3727
3804
 
3728
3805
  // src/consumption-apis/standalone.ts
3729
3806
  init_commons();
3807
+ import { AsyncLocalStorage } from "async_hooks";
3808
+ var requestContextStorage = new AsyncLocalStorage();
3809
+ function isLegacyRequestArg(arg) {
3810
+ if (arg === null || typeof arg !== "object") return false;
3811
+ const obj = arg;
3812
+ return "method" in obj || "url" in obj || "headers" in obj;
3813
+ }
3814
+ function getRowPoliciesConfigFromRegistry() {
3815
+ const policies = getSelectRowPolicies();
3816
+ if (policies.size === 0) return void 0;
3817
+ const config = /* @__PURE__ */ Object.create(null);
3818
+ for (const policy of policies.values()) {
3819
+ config[`${MOOSE_RLS_SETTING_PREFIX}${policy.config.column}`] = policy.config.claim;
3820
+ }
3821
+ return config;
3822
+ }
3730
3823
  var standaloneUtils = null;
3731
3824
  var initPromise2 = null;
3825
+ var standaloneRlsClient = null;
3826
+ var standaloneClickhouseConfig = null;
3732
3827
  var toClientConfig = (config) => ({
3733
3828
  ...config,
3734
3829
  useSSL: config.useSSL ? "true" : "false"
3735
3830
  });
3736
- async function getMooseUtils(req) {
3737
- if (req !== void 0) {
3831
+ async function getMooseUtils(options) {
3832
+ if (options !== void 0 && isLegacyRequestArg(options)) {
3738
3833
  console.warn(
3739
- "[DEPRECATED] getMooseUtils(req) no longer requires a request parameter. Use getMooseUtils() instead."
3834
+ "[DEPRECATED] getMooseUtils(req) no longer requires a request parameter. Use getMooseUtils() instead, or getMooseUtils({ rlsContext }) for row policies."
3740
3835
  );
3836
+ options = void 0;
3741
3837
  }
3742
3838
  const runtimeContext = globalThis._mooseRuntimeContext;
3743
3839
  if (runtimeContext) {
3744
- return {
3745
- client: runtimeContext.client,
3746
- sql,
3747
- jwt: runtimeContext.jwt
3748
- };
3840
+ return resolveRuntimeUtils(runtimeContext, options);
3749
3841
  }
3750
- if (standaloneUtils) {
3751
- return standaloneUtils;
3842
+ await ensureStandaloneInit();
3843
+ if (options?.rlsContext) {
3844
+ return createStandaloneRlsUtils(options.rlsContext);
3752
3845
  }
3753
- if (initPromise2) {
3754
- return initPromise2;
3755
- }
3756
- initPromise2 = (async () => {
3757
- await Promise.resolve().then(() => (init_runtime(), runtime_exports));
3758
- const configRegistry = globalThis._mooseConfigRegistry;
3759
- if (!configRegistry) {
3846
+ return standaloneUtils;
3847
+ }
3848
+ function resolveRuntimeUtils(runtimeContext, options) {
3849
+ const reqCtx = requestContextStorage.getStore();
3850
+ const jwt = reqCtx?.jwt ?? runtimeContext.jwt;
3851
+ let rowPolicyOpts;
3852
+ if (options?.rlsContext) {
3853
+ if (!runtimeContext.rowPoliciesConfig) {
3760
3854
  throw new Error(
3761
- "Moose not initialized. Ensure you're running within a Moose app or have proper configuration set up."
3855
+ "rlsContext was provided but no row policies are configured. Define at least one SelectRowPolicy before using rlsContext."
3762
3856
  );
3763
3857
  }
3764
- const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig();
3765
- const clickhouseClient = getClickhouseClient(
3766
- toClientConfig(clickhouseConfig)
3858
+ rowPolicyOpts = buildRowPolicyOptionsFromClaims(
3859
+ runtimeContext.rowPoliciesConfig,
3860
+ options.rlsContext
3767
3861
  );
3768
- const queryClient = new QueryClient(clickhouseClient, "standalone");
3769
- const mooseClient = new MooseClient(queryClient);
3770
- standaloneUtils = {
3771
- client: mooseClient,
3862
+ } else {
3863
+ rowPolicyOpts = reqCtx?.rowPolicyOpts;
3864
+ }
3865
+ if (rowPolicyOpts) {
3866
+ const rlsClient = runtimeContext.rlsClickhouseClient ?? runtimeContext.clickhouseClient;
3867
+ const scopedQueryClient = new QueryClient(
3868
+ rlsClient,
3869
+ "rls-scoped",
3870
+ rowPolicyOpts
3871
+ );
3872
+ return {
3873
+ client: new MooseClient(scopedQueryClient, runtimeContext.temporalClient),
3772
3874
  sql,
3773
- jwt: void 0
3875
+ jwt
3774
3876
  };
3775
- return standaloneUtils;
3776
- })();
3777
- try {
3778
- return await initPromise2;
3779
- } finally {
3780
- initPromise2 = null;
3781
3877
  }
3878
+ return {
3879
+ client: runtimeContext.client,
3880
+ sql,
3881
+ jwt
3882
+ };
3883
+ }
3884
+ async function ensureStandaloneInit() {
3885
+ if (standaloneUtils) return;
3886
+ if (!initPromise2) {
3887
+ initPromise2 = (async () => {
3888
+ await Promise.resolve().then(() => (init_runtime(), runtime_exports));
3889
+ const configRegistry = globalThis._mooseConfigRegistry;
3890
+ if (!configRegistry) {
3891
+ throw new Error(
3892
+ "Moose not initialized. Ensure you're running within a Moose app or have proper configuration set up."
3893
+ );
3894
+ }
3895
+ const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig();
3896
+ standaloneClickhouseConfig = clickhouseConfig;
3897
+ const clickhouseClient = getClickhouseClient(
3898
+ toClientConfig(clickhouseConfig)
3899
+ );
3900
+ const queryClient = new QueryClient(clickhouseClient, "standalone");
3901
+ const mooseClient = new MooseClient(queryClient);
3902
+ standaloneUtils = {
3903
+ client: mooseClient,
3904
+ sql,
3905
+ jwt: void 0
3906
+ };
3907
+ return standaloneUtils;
3908
+ })();
3909
+ try {
3910
+ await initPromise2;
3911
+ } finally {
3912
+ initPromise2 = null;
3913
+ }
3914
+ } else {
3915
+ await initPromise2;
3916
+ }
3917
+ }
3918
+ function createStandaloneRlsUtils(rlsContext) {
3919
+ const rowPoliciesConfig = getRowPoliciesConfigFromRegistry();
3920
+ if (!rowPoliciesConfig) {
3921
+ throw new Error(
3922
+ "rlsContext was provided but no SelectRowPolicy primitives are registered. Define at least one SelectRowPolicy before using rlsContext."
3923
+ );
3924
+ }
3925
+ if (!standaloneRlsClient && standaloneClickhouseConfig) {
3926
+ standaloneRlsClient = getClickhouseClient(
3927
+ toClientConfig({
3928
+ ...standaloneClickhouseConfig,
3929
+ username: standaloneClickhouseConfig.rlsUser ?? MOOSE_RLS_USER,
3930
+ password: standaloneClickhouseConfig.rlsPassword ?? standaloneClickhouseConfig.password
3931
+ })
3932
+ );
3933
+ }
3934
+ const rowPolicyOpts = buildRowPolicyOptionsFromClaims(
3935
+ rowPoliciesConfig,
3936
+ rlsContext
3937
+ );
3938
+ const rlsClient = standaloneRlsClient ?? standaloneUtils.client.query.client;
3939
+ const scopedQueryClient = new QueryClient(
3940
+ rlsClient,
3941
+ "rls-scoped",
3942
+ rowPolicyOpts
3943
+ );
3944
+ return {
3945
+ client: new MooseClient(scopedQueryClient),
3946
+ sql,
3947
+ jwt: void 0
3948
+ };
3782
3949
  }
3783
3950
  async function getMooseClients(config) {
3784
3951
  console.warn(
@@ -4820,6 +4987,9 @@ export {
4820
4987
  MAX_RETRIES,
4821
4988
  MAX_RETRIES_PRODUCER,
4822
4989
  MAX_RETRY_TIME_MS,
4990
+ MOOSE_RLS_ROLE,
4991
+ MOOSE_RLS_SETTING_PREFIX,
4992
+ MOOSE_RLS_USER,
4823
4993
  MOOSE_RUNTIME_ENV_PREFIX,
4824
4994
  MaterializedView,
4825
4995
  MooseCache,
@@ -4828,6 +4998,7 @@ export {
4828
4998
  QueryClient,
4829
4999
  RETRY_FACTOR_PRODUCER,
4830
5000
  RETRY_INITIAL_TIME_MS,
5001
+ SelectRowPolicy,
4831
5002
  Sql,
4832
5003
  SqlResource,
4833
5004
  Stream,
@@ -4843,6 +5014,7 @@ export {
4843
5014
  avg,
4844
5015
  between,
4845
5016
  buildQuery,
5017
+ buildRowPolicyOptionsFromClaims,
4846
5018
  cliLog,
4847
5019
  columnsFromTable,
4848
5020
  compilerLog,
@@ -4873,6 +5045,8 @@ export {
4873
5045
  getMooseClients,
4874
5046
  getMooseUtils,
4875
5047
  getMooseUtilsFromRequest,
5048
+ getSelectRowPolicies,
5049
+ getSelectRowPolicy,
4876
5050
  getSqlResource,
4877
5051
  getSqlResources,
4878
5052
  getStream,