@budibase/backend-core 2.13.50 → 2.13.52

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
@@ -2905,6 +2905,123 @@ var init_newid = __esm({
2905
2905
  }
2906
2906
  });
2907
2907
 
2908
+ // src/db/instrumentation.ts
2909
+ var import_dd_trace, DDInstrumentedDatabase;
2910
+ var init_instrumentation = __esm({
2911
+ "src/db/instrumentation.ts"() {
2912
+ "use strict";
2913
+ import_dd_trace = __toESM(require("dd-trace"));
2914
+ DDInstrumentedDatabase = class {
2915
+ constructor(db) {
2916
+ this.db = db;
2917
+ }
2918
+ get name() {
2919
+ return this.db.name;
2920
+ }
2921
+ exists() {
2922
+ return import_dd_trace.default.trace("db.exists", (span) => {
2923
+ span?.addTags({ db_name: this.name });
2924
+ return this.db.exists();
2925
+ });
2926
+ }
2927
+ checkSetup() {
2928
+ return import_dd_trace.default.trace("db.checkSetup", (span) => {
2929
+ span?.addTags({ db_name: this.name });
2930
+ return this.db.checkSetup();
2931
+ });
2932
+ }
2933
+ get(id) {
2934
+ return import_dd_trace.default.trace("db.get", (span) => {
2935
+ span?.addTags({ db_name: this.name, doc_id: id });
2936
+ return this.db.get(id);
2937
+ });
2938
+ }
2939
+ getMultiple(ids, opts) {
2940
+ return import_dd_trace.default.trace("db.getMultiple", (span) => {
2941
+ span?.addTags({
2942
+ db_name: this.name,
2943
+ num_docs: ids.length,
2944
+ allow_missing: opts?.allowMissing
2945
+ });
2946
+ return this.db.getMultiple(ids, opts);
2947
+ });
2948
+ }
2949
+ remove(id, rev) {
2950
+ return import_dd_trace.default.trace("db.remove", (span) => {
2951
+ span?.addTags({ db_name: this.name, doc_id: id });
2952
+ return this.db.remove(id, rev);
2953
+ });
2954
+ }
2955
+ put(document, opts) {
2956
+ return import_dd_trace.default.trace("db.put", (span) => {
2957
+ span?.addTags({ db_name: this.name, doc_id: document._id });
2958
+ return this.db.put(document, opts);
2959
+ });
2960
+ }
2961
+ bulkDocs(documents) {
2962
+ return import_dd_trace.default.trace("db.bulkDocs", (span) => {
2963
+ span?.addTags({ db_name: this.name, num_docs: documents.length });
2964
+ return this.db.bulkDocs(documents);
2965
+ });
2966
+ }
2967
+ allDocs(params2) {
2968
+ return import_dd_trace.default.trace("db.allDocs", (span) => {
2969
+ span?.addTags({ db_name: this.name });
2970
+ return this.db.allDocs(params2);
2971
+ });
2972
+ }
2973
+ query(viewName, params2) {
2974
+ return import_dd_trace.default.trace("db.query", (span) => {
2975
+ span?.addTags({ db_name: this.name, view_name: viewName });
2976
+ return this.db.query(viewName, params2);
2977
+ });
2978
+ }
2979
+ destroy() {
2980
+ return import_dd_trace.default.trace("db.destroy", (span) => {
2981
+ span?.addTags({ db_name: this.name });
2982
+ return this.db.destroy();
2983
+ });
2984
+ }
2985
+ compact() {
2986
+ return import_dd_trace.default.trace("db.compact", (span) => {
2987
+ span?.addTags({ db_name: this.name });
2988
+ return this.db.compact();
2989
+ });
2990
+ }
2991
+ dump(stream2, opts) {
2992
+ return import_dd_trace.default.trace("db.dump", (span) => {
2993
+ span?.addTags({ db_name: this.name });
2994
+ return this.db.dump(stream2, opts);
2995
+ });
2996
+ }
2997
+ load(...args) {
2998
+ return import_dd_trace.default.trace("db.load", (span) => {
2999
+ span?.addTags({ db_name: this.name });
3000
+ return this.db.load(...args);
3001
+ });
3002
+ }
3003
+ createIndex(...args) {
3004
+ return import_dd_trace.default.trace("db.createIndex", (span) => {
3005
+ span?.addTags({ db_name: this.name });
3006
+ return this.db.createIndex(...args);
3007
+ });
3008
+ }
3009
+ deleteIndex(...args) {
3010
+ return import_dd_trace.default.trace("db.deleteIndex", (span) => {
3011
+ span?.addTags({ db_name: this.name });
3012
+ return this.db.deleteIndex(...args);
3013
+ });
3014
+ }
3015
+ getIndexes(...args) {
3016
+ return import_dd_trace.default.trace("db.getIndexes", (span) => {
3017
+ span?.addTags({ db_name: this.name });
3018
+ return this.db.getIndexes(...args);
3019
+ });
3020
+ }
3021
+ };
3022
+ }
3023
+ });
3024
+
2908
3025
  // src/db/couch/DatabaseImpl.ts
2909
3026
  function buildNano(couchInfo) {
2910
3027
  return (0, import_nano.default)({
@@ -2918,7 +3035,8 @@ function buildNano(couchInfo) {
2918
3035
  });
2919
3036
  }
2920
3037
  function DatabaseWithConnection(dbName, connection, opts) {
2921
- return new DatabaseImpl(dbName, opts, connection);
3038
+ const db = new DatabaseImpl(dbName, opts, connection);
3039
+ return new DDInstrumentedDatabase(db);
2922
3040
  }
2923
3041
  var import_nano, DatabaseImpl;
2924
3042
  var init_DatabaseImpl = __esm({
@@ -2930,6 +3048,7 @@ var init_DatabaseImpl = __esm({
2930
3048
  init_utils2();
2931
3049
  init_pouchDB();
2932
3050
  init_newid();
3051
+ init_instrumentation();
2933
3052
  DatabaseImpl = class _DatabaseImpl {
2934
3053
  constructor(dbName, opts, connection) {
2935
3054
  this.couchInfo = getCouchInfo();
@@ -3146,7 +3265,7 @@ var init_couch = __esm({
3146
3265
 
3147
3266
  // src/db/db.ts
3148
3267
  function getDB(dbName, opts) {
3149
- return new DatabaseImpl(dbName, opts);
3268
+ return new DDInstrumentedDatabase(new DatabaseImpl(dbName, opts));
3150
3269
  }
3151
3270
  async function doWithDB(dbName, cb, opts) {
3152
3271
  const db = getDB(dbName, opts);
@@ -3167,6 +3286,7 @@ var init_db3 = __esm({
3167
3286
  "src/db/db.ts"() {
3168
3287
  "use strict";
3169
3288
  init_couch();
3289
+ init_instrumentation();
3170
3290
  }
3171
3291
  });
3172
3292
 
@@ -3590,529 +3710,149 @@ var init_utils3 = __esm({
3590
3710
  }
3591
3711
  });
3592
3712
 
3593
- // src/timers/timers.ts
3594
- function set(callback, period) {
3595
- const interval = setInterval(callback, period);
3596
- intervals.push(interval);
3597
- return interval;
3598
- }
3599
- function clear(interval) {
3600
- const idx = intervals.indexOf(interval);
3601
- if (idx !== -1) {
3602
- intervals.splice(idx, 1);
3603
- }
3604
- clearInterval(interval);
3605
- }
3606
- function cleanup() {
3607
- for (let interval of intervals) {
3608
- clearInterval(interval);
3609
- }
3610
- intervals = [];
3713
+ // src/logging/correlation/correlation.ts
3714
+ var correlation_exports = {};
3715
+ __export(correlation_exports, {
3716
+ getId: () => getId,
3717
+ setHeader: () => setHeader
3718
+ });
3719
+ function getId() {
3720
+ return correlator.getId();
3611
3721
  }
3612
- var intervals, ExecutionTimeoutError, ExecutionTimeTracker;
3613
- var init_timers = __esm({
3614
- "src/timers/timers.ts"() {
3722
+ var correlator, setHeader;
3723
+ var init_correlation = __esm({
3724
+ "src/logging/correlation/correlation.ts"() {
3615
3725
  "use strict";
3616
- intervals = [];
3617
- ExecutionTimeoutError = class extends Error {
3618
- constructor() {
3619
- super(...arguments);
3620
- this.name = "ExecutionTimeoutError";
3621
- }
3622
- };
3623
- ExecutionTimeTracker = class _ExecutionTimeTracker {
3624
- constructor(limitMs) {
3625
- this.limitMs = limitMs;
3626
- this.totalTimeMs = 0;
3627
- }
3628
- static withLimit(limitMs) {
3629
- return new _ExecutionTimeTracker(limitMs);
3630
- }
3631
- track(f) {
3632
- this.checkLimit();
3633
- const start2 = process.hrtime.bigint();
3634
- try {
3635
- return f();
3636
- } finally {
3637
- const end2 = process.hrtime.bigint();
3638
- this.totalTimeMs += Number(end2 - start2) / 1e6;
3639
- this.checkLimit();
3640
- }
3641
- }
3642
- get elapsedMS() {
3643
- return this.totalTimeMs;
3644
- }
3645
- checkLimit() {
3646
- if (this.totalTimeMs > this.limitMs) {
3647
- throw new ExecutionTimeoutError(
3648
- `Execution time limit of ${this.limitMs}ms exceeded: ${this.totalTimeMs}ms`
3649
- );
3650
- }
3726
+ init_constants4();
3727
+ correlator = require("correlation-id");
3728
+ setHeader = (headers) => {
3729
+ const correlationId = correlator.getId();
3730
+ if (correlationId) {
3731
+ headers["x-budibase-correlation-id" /* CORRELATION_ID */] = correlationId;
3651
3732
  }
3652
3733
  };
3653
3734
  }
3654
3735
  });
3655
3736
 
3656
- // src/timers/index.ts
3657
- var timers_exports = {};
3658
- __export(timers_exports, {
3659
- ExecutionTimeTracker: () => ExecutionTimeTracker,
3660
- ExecutionTimeoutError: () => ExecutionTimeoutError,
3661
- cleanup: () => cleanup,
3662
- clear: () => clear,
3663
- set: () => set
3664
- });
3665
- var init_timers2 = __esm({
3666
- "src/timers/index.ts"() {
3737
+ // src/logging/correlation/index.ts
3738
+ var init_correlation2 = __esm({
3739
+ "src/logging/correlation/index.ts"() {
3667
3740
  "use strict";
3668
- init_timers();
3741
+ init_correlation();
3669
3742
  }
3670
3743
  });
3671
3744
 
3672
- // src/redis/redis.ts
3673
- function pickClient(selectDb) {
3674
- return CLIENTS[selectDb];
3675
- }
3676
- function connectionError(selectDb, timeout2, err) {
3677
- if (CLOSED) {
3678
- return;
3679
- }
3680
- pickClient(selectDb).disconnect();
3681
- CLOSED = true;
3682
- clearTimeout(timeout2);
3683
- CONNECTED = false;
3684
- console.error("Redis connection failed - " + err);
3685
- setTimeout(() => {
3686
- init2();
3687
- }, RETRY_PERIOD_MS);
3745
+ // src/objectStore/utils.ts
3746
+ function budibaseTempDir() {
3747
+ return bbTmp;
3688
3748
  }
3689
- function init2(selectDb = DEFAULT_SELECT_DB) {
3690
- const RedisCore = environment_default.MOCK_REDIS && MockRedis ? MockRedis : import_ioredis.default;
3691
- let timeout2;
3692
- CLOSED = false;
3693
- let client = pickClient(selectDb);
3694
- if (client && CONNECTED) {
3695
- return;
3696
- }
3697
- if (environment_default.MOCK_REDIS) {
3698
- CLIENTS[selectDb] = new RedisCore(getRedisOptions());
3699
- }
3700
- timeout2 = setTimeout(() => {
3701
- if (!CONNECTED) {
3702
- connectionError(
3703
- selectDb,
3704
- timeout2,
3705
- "Did not successfully connect in timeout"
3706
- );
3749
+ var import_path, import_os, import_fs2, ObjectStoreBuckets, bbTmp;
3750
+ var init_utils4 = __esm({
3751
+ "src/objectStore/utils.ts"() {
3752
+ "use strict";
3753
+ import_path = require("path");
3754
+ import_os = require("os");
3755
+ import_fs2 = __toESM(require("fs"));
3756
+ init_environment2();
3757
+ ObjectStoreBuckets = {
3758
+ BACKUPS: environment_default.BACKUPS_BUCKET_NAME,
3759
+ APPS: environment_default.APPS_BUCKET_NAME,
3760
+ TEMPLATES: environment_default.TEMPLATES_BUCKET_NAME,
3761
+ GLOBAL: environment_default.GLOBAL_BUCKET_NAME,
3762
+ PLUGINS: environment_default.PLUGIN_BUCKET_NAME
3763
+ };
3764
+ bbTmp = (0, import_path.join)((0, import_os.tmpdir)(), ".budibase");
3765
+ try {
3766
+ import_fs2.default.mkdirSync(bbTmp);
3767
+ } catch (e) {
3768
+ if (e.code !== "EEXIST") {
3769
+ throw e;
3770
+ }
3707
3771
  }
3708
- }, STARTUP_TIMEOUT_MS);
3709
- if (client) {
3710
- client.disconnect();
3711
- }
3712
- const { host, port } = getRedisConnectionDetails();
3713
- const opts = getRedisOptions();
3714
- if (CLUSTERED) {
3715
- client = new RedisCore.Cluster([{ host, port }], opts);
3716
- } else {
3717
- client = new RedisCore(opts);
3718
3772
  }
3719
- client.on("end", (err) => {
3720
- if (environment_default.isTest()) {
3721
- return;
3722
- }
3723
- connectionError(selectDb, timeout2, err);
3724
- });
3725
- client.on("error", (err) => {
3726
- connectionError(selectDb, timeout2, err);
3727
- });
3728
- client.on("connect", () => {
3729
- clearTimeout(timeout2);
3730
- CONNECTED = true;
3731
- });
3732
- CLIENTS[selectDb] = client;
3773
+ });
3774
+
3775
+ // src/cache/appMetadata.ts
3776
+ var appMetadata_exports = {};
3777
+ __export(appMetadata_exports, {
3778
+ AppState: () => AppState,
3779
+ getAppMetadata: () => getAppMetadata,
3780
+ invalidateAppMetadata: () => invalidateAppMetadata
3781
+ });
3782
+ async function populateFromDB(appId) {
3783
+ return doWithDB(
3784
+ appId,
3785
+ (db) => {
3786
+ return db.get("app_metadata" /* APP_METADATA */);
3787
+ },
3788
+ { skip_setup: true }
3789
+ );
3733
3790
  }
3734
- function waitForConnection(selectDb = DEFAULT_SELECT_DB) {
3735
- return new Promise((resolve) => {
3736
- if (pickClient(selectDb) == null) {
3737
- init2();
3738
- } else if (CONNECTED) {
3739
- resolve("");
3740
- return;
3791
+ function isInvalid(metadata) {
3792
+ return !metadata || metadata.state === "invalid" /* INVALID */;
3793
+ }
3794
+ async function getAppMetadata(appId) {
3795
+ const client = await getAppClient();
3796
+ let metadata = await client.get(appId);
3797
+ if (!metadata) {
3798
+ let expiry = EXPIRY_SECONDS;
3799
+ try {
3800
+ metadata = await populateFromDB(appId);
3801
+ } catch (err) {
3802
+ if (err && err.status === 404) {
3803
+ metadata = { state: "invalid" /* INVALID */ };
3804
+ expiry = void 0;
3805
+ } else {
3806
+ throw err;
3807
+ }
3741
3808
  }
3742
- const interval = set(() => {
3743
- if (CONNECTED) {
3744
- clear(interval);
3745
- resolve("");
3809
+ if (isInvalid(metadata)) {
3810
+ const temp = await client.get(appId);
3811
+ if (temp) {
3812
+ metadata = temp;
3746
3813
  }
3747
- }, 500);
3748
- });
3814
+ }
3815
+ await client.store(appId, metadata, expiry);
3816
+ }
3817
+ return metadata;
3749
3818
  }
3750
- function promisifyStream(stream2, client) {
3751
- return new Promise((resolve, reject) => {
3752
- const outputKeys = /* @__PURE__ */ new Set();
3753
- stream2.on("data", (keys2) => {
3754
- keys2.forEach((key) => {
3755
- outputKeys.add(key);
3756
- });
3757
- });
3758
- stream2.on("error", (err) => {
3759
- reject(err);
3760
- });
3761
- stream2.on("end", async () => {
3762
- const keysArray = Array.from(outputKeys);
3763
- try {
3764
- let getPromises = [];
3765
- for (let key of keysArray) {
3766
- getPromises.push(client.get(key));
3767
- }
3768
- const jsonArray = await Promise.all(getPromises);
3769
- resolve(
3770
- keysArray.map((key) => ({
3771
- key: removeDbPrefix(key),
3772
- value: JSON.parse(jsonArray.shift())
3773
- }))
3774
- );
3775
- } catch (err) {
3776
- reject(err);
3777
- }
3778
- });
3779
- });
3819
+ async function invalidateAppMetadata(appId, newMetadata) {
3820
+ if (!appId) {
3821
+ throw "Cannot invalidate if no app ID provided.";
3822
+ }
3823
+ const client = await getAppClient();
3824
+ await client.delete(appId);
3825
+ if (newMetadata) {
3826
+ await client.store(appId, newMetadata, EXPIRY_SECONDS);
3827
+ }
3780
3828
  }
3781
- var import_ioredis, MockRedis, RETRY_PERIOD_MS, STARTUP_TIMEOUT_MS, CLUSTERED, DEFAULT_SELECT_DB, CLOSED, CLIENTS, CONNECTED, RedisWrapper, redis_default;
3782
- var init_redis = __esm({
3783
- "src/redis/redis.ts"() {
3829
+ var AppState, EXPIRY_SECONDS;
3830
+ var init_appMetadata = __esm({
3831
+ "src/cache/appMetadata.ts"() {
3784
3832
  "use strict";
3785
- init_environment2();
3786
- import_ioredis = __toESM(require("ioredis"));
3787
- init_utils3();
3788
- init_timers2();
3789
- if (environment_default.MOCK_REDIS) {
3790
- try {
3791
- MockRedis = require("ioredis-mock");
3792
- } catch (err) {
3793
- console.log("Mock redis unavailable");
3794
- }
3795
- }
3796
- RETRY_PERIOD_MS = 2e3;
3797
- STARTUP_TIMEOUT_MS = 5e3;
3798
- CLUSTERED = environment_default.REDIS_CLUSTERED;
3799
- DEFAULT_SELECT_DB = 0 /* DEFAULT */;
3800
- CLOSED = false;
3801
- CLIENTS = {};
3802
- CONNECTED = false;
3803
- if (environment_default.MOCK_REDIS) {
3804
- CONNECTED = true;
3805
- }
3806
- RedisWrapper = class {
3807
- constructor(db, selectDb = null) {
3808
- this._db = db;
3809
- this._select = selectDb || DEFAULT_SELECT_DB;
3810
- }
3811
- getClient() {
3812
- return pickClient(this._select);
3813
- }
3814
- async init() {
3815
- CLOSED = false;
3816
- init2(this._select);
3817
- await waitForConnection(this._select);
3818
- if (this._select && !environment_default.isTest()) {
3819
- this.getClient().select(this._select);
3820
- }
3821
- return this;
3822
- }
3823
- async finish() {
3824
- CLOSED = true;
3825
- this.getClient().disconnect();
3826
- }
3827
- async scan(key = "") {
3828
- const db = this._db;
3829
- key = `${db}${SEPARATOR2}${key}`;
3830
- let stream2;
3831
- if (CLUSTERED) {
3832
- let node = this.getClient().nodes("master");
3833
- stream2 = node[0].scanStream({ match: key + "*", count: 100 });
3834
- } else {
3835
- stream2 = this.getClient().scanStream({ match: key + "*", count: 100 });
3836
- }
3837
- return promisifyStream(stream2, this.getClient());
3838
- }
3839
- async keys(pattern) {
3840
- const db = this._db;
3841
- return this.getClient().keys(addDbPrefix(db, pattern));
3842
- }
3843
- async exists(key) {
3844
- const db = this._db;
3845
- return await this.getClient().exists(addDbPrefix(db, key));
3846
- }
3847
- async get(key) {
3848
- const db = this._db;
3849
- let response = await this.getClient().get(addDbPrefix(db, key));
3850
- if (response != null && response.key) {
3851
- response.key = key;
3852
- }
3853
- try {
3854
- return JSON.parse(response);
3855
- } catch (err) {
3856
- return response;
3857
- }
3858
- }
3859
- async bulkGet(keys2) {
3860
- const db = this._db;
3861
- if (keys2.length === 0) {
3862
- return {};
3863
- }
3864
- const prefixedKeys = keys2.map((key) => addDbPrefix(db, key));
3865
- let response = await this.getClient().mget(prefixedKeys);
3866
- if (Array.isArray(response)) {
3867
- let final = {};
3868
- let count = 0;
3869
- for (let result of response) {
3870
- if (result) {
3871
- let parsed;
3872
- try {
3873
- parsed = JSON.parse(result);
3874
- } catch (err) {
3875
- parsed = result;
3876
- }
3877
- final[keys2[count]] = parsed;
3878
- }
3879
- count++;
3880
- }
3881
- return final;
3882
- } else {
3883
- throw new Error(`Invalid response: ${response}`);
3884
- }
3885
- }
3886
- async store(key, value, expirySeconds = null) {
3887
- const db = this._db;
3888
- if (typeof value === "object") {
3889
- value = JSON.stringify(value);
3890
- }
3891
- const prefixedKey = addDbPrefix(db, key);
3892
- await this.getClient().set(prefixedKey, value);
3893
- if (expirySeconds) {
3894
- await this.getClient().expire(prefixedKey, expirySeconds);
3895
- }
3896
- }
3897
- async getTTL(key) {
3898
- const db = this._db;
3899
- const prefixedKey = addDbPrefix(db, key);
3900
- return this.getClient().ttl(prefixedKey);
3901
- }
3902
- async setExpiry(key, expirySeconds) {
3903
- const db = this._db;
3904
- const prefixedKey = addDbPrefix(db, key);
3905
- await this.getClient().expire(prefixedKey, expirySeconds);
3906
- }
3907
- async delete(key) {
3908
- const db = this._db;
3909
- await this.getClient().del(addDbPrefix(db, key));
3910
- }
3911
- async clear() {
3912
- let items = await this.scan();
3913
- await Promise.all(items.map((obj) => this.delete(obj.key)));
3914
- }
3915
- };
3916
- redis_default = RedisWrapper;
3833
+ init_init();
3834
+ init_db4();
3835
+ AppState = /* @__PURE__ */ ((AppState2) => {
3836
+ AppState2["INVALID"] = "invalid";
3837
+ return AppState2;
3838
+ })(AppState || {});
3839
+ EXPIRY_SECONDS = 3600;
3917
3840
  }
3918
3841
  });
3919
3842
 
3920
- // src/redis/init.ts
3921
- var init_exports = {};
3922
- __export(init_exports, {
3923
- getAppClient: () => getAppClient,
3924
- getCacheClient: () => getCacheClient,
3925
- getInviteClient: () => getInviteClient,
3926
- getLockClient: () => getLockClient,
3927
- getPasswordResetClient: () => getPasswordResetClient,
3928
- getSessionClient: () => getSessionClient,
3929
- getSocketClient: () => getSocketClient,
3930
- getUserClient: () => getUserClient,
3931
- getWritethroughClient: () => getWritethroughClient,
3932
- init: () => init3,
3933
- shutdown: () => shutdown
3934
- });
3935
- async function init3() {
3936
- userClient = await new redis_default("users" /* USER_CACHE */).init();
3937
- sessionClient = await new redis_default("session" /* SESSIONS */).init();
3938
- appClient = await new redis_default("appMetadata" /* APP_METADATA */).init();
3939
- cacheClient = await new redis_default("data_cache" /* GENERIC_CACHE */).init();
3940
- lockClient = await new redis_default("locks" /* LOCKS */).init();
3941
- writethroughClient = await new redis_default("writeThrough" /* WRITE_THROUGH */).init();
3942
- inviteClient = await new redis_default("invitation" /* INVITATIONS */).init();
3943
- passwordResetClient = await new redis_default("pwReset" /* PW_RESETS */).init();
3944
- socketClient = await new redis_default(
3945
- "socket_io" /* SOCKET_IO */,
3946
- 1 /* SOCKET_IO */
3947
- ).init();
3948
- }
3949
- async function shutdown() {
3950
- if (userClient)
3951
- await userClient.finish();
3952
- if (sessionClient)
3953
- await sessionClient.finish();
3954
- if (appClient)
3955
- await appClient.finish();
3956
- if (cacheClient)
3957
- await cacheClient.finish();
3958
- if (writethroughClient)
3959
- await writethroughClient.finish();
3960
- if (lockClient)
3961
- await lockClient.finish();
3962
- if (inviteClient)
3963
- await inviteClient.finish();
3964
- if (passwordResetClient)
3965
- await passwordResetClient.finish();
3966
- if (socketClient)
3967
- await socketClient.finish();
3843
+ // src/docIds/ids.ts
3844
+ function generateRowID(tableId, id) {
3845
+ id = id || newid();
3846
+ return `${"ro" /* ROW */}${SEPARATOR}${tableId}${SEPARATOR}${id}`;
3968
3847
  }
3969
- async function getUserClient() {
3970
- if (!userClient) {
3971
- await init3();
3972
- }
3973
- return userClient;
3848
+ function generateWorkspaceID() {
3849
+ return `${"workspace" /* WORKSPACE */}${SEPARATOR}${newid()}`;
3974
3850
  }
3975
- async function getSessionClient() {
3976
- if (!sessionClient) {
3977
- await init3();
3978
- }
3979
- return sessionClient;
3851
+ function generateGlobalUserID(id) {
3852
+ return `${"us" /* USER */}${SEPARATOR}${id || newid()}`;
3980
3853
  }
3981
- async function getAppClient() {
3982
- if (!appClient) {
3983
- await init3();
3984
- }
3985
- return appClient;
3986
- }
3987
- async function getCacheClient() {
3988
- if (!cacheClient) {
3989
- await init3();
3990
- }
3991
- return cacheClient;
3992
- }
3993
- async function getWritethroughClient() {
3994
- if (!writethroughClient) {
3995
- await init3();
3996
- }
3997
- return writethroughClient;
3998
- }
3999
- async function getLockClient() {
4000
- if (!lockClient) {
4001
- await init3();
4002
- }
4003
- return lockClient;
4004
- }
4005
- async function getSocketClient() {
4006
- if (!socketClient) {
4007
- await init3();
4008
- }
4009
- return socketClient;
4010
- }
4011
- async function getInviteClient() {
4012
- if (!inviteClient) {
4013
- await init3();
4014
- }
4015
- return inviteClient;
4016
- }
4017
- async function getPasswordResetClient() {
4018
- if (!passwordResetClient) {
4019
- await init3();
4020
- }
4021
- return passwordResetClient;
4022
- }
4023
- var userClient, sessionClient, appClient, cacheClient, writethroughClient, lockClient, socketClient, inviteClient, passwordResetClient;
4024
- var init_init = __esm({
4025
- "src/redis/init.ts"() {
4026
- "use strict";
4027
- init_redis();
4028
- init_utils3();
4029
- process.on("exit", async () => {
4030
- await shutdown();
4031
- });
4032
- }
4033
- });
4034
-
4035
- // src/cache/appMetadata.ts
4036
- var appMetadata_exports = {};
4037
- __export(appMetadata_exports, {
4038
- AppState: () => AppState,
4039
- getAppMetadata: () => getAppMetadata,
4040
- invalidateAppMetadata: () => invalidateAppMetadata
4041
- });
4042
- async function populateFromDB(appId) {
4043
- return doWithDB(
4044
- appId,
4045
- (db) => {
4046
- return db.get("app_metadata" /* APP_METADATA */);
4047
- },
4048
- { skip_setup: true }
4049
- );
4050
- }
4051
- function isInvalid(metadata) {
4052
- return !metadata || metadata.state === "invalid" /* INVALID */;
4053
- }
4054
- async function getAppMetadata(appId) {
4055
- const client = await getAppClient();
4056
- let metadata = await client.get(appId);
4057
- if (!metadata) {
4058
- let expiry = EXPIRY_SECONDS;
4059
- try {
4060
- metadata = await populateFromDB(appId);
4061
- } catch (err) {
4062
- if (err && err.status === 404) {
4063
- metadata = { state: "invalid" /* INVALID */ };
4064
- expiry = void 0;
4065
- } else {
4066
- throw err;
4067
- }
4068
- }
4069
- if (isInvalid(metadata)) {
4070
- const temp = await client.get(appId);
4071
- if (temp) {
4072
- metadata = temp;
4073
- }
4074
- }
4075
- await client.store(appId, metadata, expiry);
4076
- }
4077
- return metadata;
4078
- }
4079
- async function invalidateAppMetadata(appId, newMetadata) {
4080
- if (!appId) {
4081
- throw "Cannot invalidate if no app ID provided.";
4082
- }
4083
- const client = await getAppClient();
4084
- await client.delete(appId);
4085
- if (newMetadata) {
4086
- await client.store(appId, newMetadata, EXPIRY_SECONDS);
4087
- }
4088
- }
4089
- var AppState, EXPIRY_SECONDS;
4090
- var init_appMetadata = __esm({
4091
- "src/cache/appMetadata.ts"() {
4092
- "use strict";
4093
- init_init();
4094
- init_db4();
4095
- AppState = /* @__PURE__ */ ((AppState2) => {
4096
- AppState2["INVALID"] = "invalid";
4097
- return AppState2;
4098
- })(AppState || {});
4099
- EXPIRY_SECONDS = 3600;
4100
- }
4101
- });
4102
-
4103
- // src/docIds/ids.ts
4104
- function generateRowID(tableId, id) {
4105
- id = id || newid();
4106
- return `${"ro" /* ROW */}${SEPARATOR}${tableId}${SEPARATOR}${id}`;
4107
- }
4108
- function generateWorkspaceID() {
4109
- return `${"workspace" /* WORKSPACE */}${SEPARATOR}${newid()}`;
4110
- }
4111
- function generateGlobalUserID(id) {
4112
- return `${"us" /* USER */}${SEPARATOR}${id || newid()}`;
4113
- }
4114
- function isGlobalUserID(id) {
4115
- return isGlobalUserIDRegex.test(id);
3854
+ function isGlobalUserID(id) {
3855
+ return isGlobalUserIDRegex.test(id);
4116
3856
  }
4117
3857
  function generateUserMetadataID(globalId) {
4118
3858
  return generateRowID("ta_users" /* USER_METADATA */, globalId);
@@ -4430,7 +4170,7 @@ function pagination(data, pageSize, {
4430
4170
  nextPage
4431
4171
  };
4432
4172
  }
4433
- var init_utils4 = __esm({
4173
+ var init_utils5 = __esm({
4434
4174
  "src/db/utils.ts"() {
4435
4175
  "use strict";
4436
4176
  init_environment2();
@@ -5445,7 +5185,7 @@ var init_db4 = __esm({
5445
5185
  "use strict";
5446
5186
  init_couch();
5447
5187
  init_db3();
5448
- init_utils4();
5188
+ init_utils5();
5449
5189
  init_views();
5450
5190
  init_conversions();
5451
5191
  init_Replication();
@@ -5457,68 +5197,6 @@ var init_db4 = __esm({
5457
5197
  }
5458
5198
  });
5459
5199
 
5460
- // src/logging/correlation/correlation.ts
5461
- var correlation_exports = {};
5462
- __export(correlation_exports, {
5463
- getId: () => getId,
5464
- setHeader: () => setHeader
5465
- });
5466
- function getId() {
5467
- return correlator.getId();
5468
- }
5469
- var correlator, setHeader;
5470
- var init_correlation = __esm({
5471
- "src/logging/correlation/correlation.ts"() {
5472
- "use strict";
5473
- init_constants4();
5474
- correlator = require("correlation-id");
5475
- setHeader = (headers) => {
5476
- const correlationId = correlator.getId();
5477
- if (correlationId) {
5478
- headers["x-budibase-correlation-id" /* CORRELATION_ID */] = correlationId;
5479
- }
5480
- };
5481
- }
5482
- });
5483
-
5484
- // src/logging/correlation/index.ts
5485
- var init_correlation2 = __esm({
5486
- "src/logging/correlation/index.ts"() {
5487
- "use strict";
5488
- init_correlation();
5489
- }
5490
- });
5491
-
5492
- // src/objectStore/utils.ts
5493
- function budibaseTempDir() {
5494
- return bbTmp;
5495
- }
5496
- var import_path, import_os, import_fs2, ObjectStoreBuckets, bbTmp;
5497
- var init_utils5 = __esm({
5498
- "src/objectStore/utils.ts"() {
5499
- "use strict";
5500
- import_path = require("path");
5501
- import_os = require("os");
5502
- import_fs2 = __toESM(require("fs"));
5503
- init_environment2();
5504
- ObjectStoreBuckets = {
5505
- BACKUPS: environment_default.BACKUPS_BUCKET_NAME,
5506
- APPS: environment_default.APPS_BUCKET_NAME,
5507
- TEMPLATES: environment_default.TEMPLATES_BUCKET_NAME,
5508
- GLOBAL: environment_default.GLOBAL_BUCKET_NAME,
5509
- PLUGINS: environment_default.PLUGIN_BUCKET_NAME
5510
- };
5511
- bbTmp = (0, import_path.join)((0, import_os.tmpdir)(), ".budibase");
5512
- try {
5513
- import_fs2.default.mkdirSync(bbTmp);
5514
- } catch (e) {
5515
- if (e.code !== "EEXIST") {
5516
- throw e;
5517
- }
5518
- }
5519
- }
5520
- });
5521
-
5522
5200
  // src/objectStore/objectStore.ts
5523
5201
  function sanitizeKey(input) {
5524
5202
  return sanitize(sanitizeBucket(input)).replace(/\\/g, "/");
@@ -5827,7 +5505,7 @@ var init_objectStore = __esm({
5827
5505
  import_path2 = require("path");
5828
5506
  import_fs3 = __toESM(require("fs"));
5829
5507
  init_environment2();
5830
- init_utils5();
5508
+ init_utils4();
5831
5509
  import_uuid2 = require("uuid");
5832
5510
  init_db4();
5833
5511
  sanitize = require("sanitize-s3-objectkey");
@@ -6085,7 +5763,7 @@ var init_objectStore2 = __esm({
6085
5763
  "src/objectStore/index.ts"() {
6086
5764
  "use strict";
6087
5765
  init_objectStore();
6088
- init_utils5();
5766
+ init_utils4();
6089
5767
  init_buckets();
6090
5768
  }
6091
5769
  });
@@ -6173,7 +5851,7 @@ var init_system2 = __esm({
6173
5851
  });
6174
5852
 
6175
5853
  // src/logging/pino/logger.ts
6176
- var import_pino, import_pino_pretty, pinoInstance, isPlainObject2, isError2, isMessage2, getLogParams3, logger;
5854
+ var import_pino, import_pino_pretty, import_dd_trace2, import_ext, pinoInstance, isPlainObject2, isError2, isMessage2, getLogParams3, logger;
6177
5855
  var init_logger = __esm({
6178
5856
  "src/logging/pino/logger.ts"() {
6179
5857
  "use strict";
@@ -6182,6 +5860,8 @@ var init_logger = __esm({
6182
5860
  init_environment2();
6183
5861
  init_context2();
6184
5862
  init_correlation2();
5863
+ import_dd_trace2 = __toESM(require("dd-trace"));
5864
+ import_ext = require("dd-trace/ext");
6185
5865
  init_system2();
6186
5866
  if (!environment_default.DISABLE_PINO_LOGGER) {
6187
5867
  let isPlainObject = function(obj) {
@@ -6215,6 +5895,10 @@ var init_logger = __esm({
6215
5895
  identityType: identity?.type,
6216
5896
  correlationId: getId()
6217
5897
  };
5898
+ const span = import_dd_trace2.default.scope().active();
5899
+ if (span) {
5900
+ import_dd_trace2.default.inject(span.context(), import_ext.formats.LOG, contextObject);
5901
+ }
6218
5902
  const mergingObject = {
6219
5903
  err: error,
6220
5904
  pid: process.pid,
@@ -6295,91 +5979,530 @@ var init_logger = __esm({
6295
5979
  if (!obj.err) {
6296
5980
  obj.err = new Error();
6297
5981
  }
6298
- pinoInstance?.trace(obj, msg);
6299
- };
6300
- console.debug = (...arg) => {
6301
- const [obj, msg] = getLogParams2(arg);
6302
- pinoInstance?.debug(obj, msg);
6303
- };
6304
- const getTenantId2 = () => {
6305
- let tenantId;
6306
- try {
6307
- tenantId = getTenantId();
6308
- } catch (e) {
5982
+ pinoInstance?.trace(obj, msg);
5983
+ };
5984
+ console.debug = (...arg) => {
5985
+ const [obj, msg] = getLogParams2(arg);
5986
+ pinoInstance?.debug(obj, msg);
5987
+ };
5988
+ const getTenantId2 = () => {
5989
+ let tenantId;
5990
+ try {
5991
+ tenantId = getTenantId();
5992
+ } catch (e) {
5993
+ }
5994
+ return tenantId;
5995
+ };
5996
+ const getAppId2 = () => {
5997
+ let appId;
5998
+ try {
5999
+ appId = getAppId();
6000
+ } catch (e) {
6001
+ }
6002
+ return appId;
6003
+ };
6004
+ const getAutomationId2 = () => {
6005
+ let appId;
6006
+ try {
6007
+ appId = getAutomationId();
6008
+ } catch (e) {
6009
+ }
6010
+ return appId;
6011
+ };
6012
+ const getIdentity3 = () => {
6013
+ let identity;
6014
+ try {
6015
+ identity = getIdentity();
6016
+ } catch (e) {
6017
+ }
6018
+ return identity;
6019
+ };
6020
+ }
6021
+ logger = pinoInstance;
6022
+ }
6023
+ });
6024
+
6025
+ // src/logging/alerts.ts
6026
+ function isSuppressed(e) {
6027
+ return e && e["suppressAlert"];
6028
+ }
6029
+ function logAlert(message, e) {
6030
+ if (e && NonErrors.includes(e.name) && isSuppressed(e)) {
6031
+ return;
6032
+ }
6033
+ console.error(`bb-alert: ${message}`, e);
6034
+ }
6035
+ function logAlertWithInfo(message, db, id, error) {
6036
+ message = `${message} - db: ${db} - doc: ${id} - error: `;
6037
+ logAlert(message, error);
6038
+ }
6039
+ function logWarn(message, e) {
6040
+ console.warn(`bb-warn: ${message}`, e);
6041
+ }
6042
+ var NonErrors;
6043
+ var init_alerts = __esm({
6044
+ "src/logging/alerts.ts"() {
6045
+ "use strict";
6046
+ NonErrors = ["AccountError"];
6047
+ }
6048
+ });
6049
+
6050
+ // src/logging/index.ts
6051
+ var logging_exports = {};
6052
+ __export(logging_exports, {
6053
+ correlation: () => correlation_exports,
6054
+ logAlert: () => logAlert,
6055
+ logAlertWithInfo: () => logAlertWithInfo,
6056
+ logWarn: () => logWarn,
6057
+ logger: () => logger,
6058
+ system: () => system_exports
6059
+ });
6060
+ var init_logging = __esm({
6061
+ "src/logging/index.ts"() {
6062
+ "use strict";
6063
+ init_correlation();
6064
+ init_logger();
6065
+ init_alerts();
6066
+ init_system2();
6067
+ }
6068
+ });
6069
+
6070
+ // src/timers/timers.ts
6071
+ function set(callback, period) {
6072
+ const interval = setInterval(callback, period);
6073
+ intervals.push(interval);
6074
+ return interval;
6075
+ }
6076
+ function clear(interval) {
6077
+ const idx = intervals.indexOf(interval);
6078
+ if (idx !== -1) {
6079
+ intervals.splice(idx, 1);
6080
+ }
6081
+ clearInterval(interval);
6082
+ }
6083
+ function cleanup() {
6084
+ for (let interval of intervals) {
6085
+ clearInterval(interval);
6086
+ }
6087
+ intervals = [];
6088
+ }
6089
+ var intervals, ExecutionTimeoutError, ExecutionTimeTracker;
6090
+ var init_timers = __esm({
6091
+ "src/timers/timers.ts"() {
6092
+ "use strict";
6093
+ intervals = [];
6094
+ ExecutionTimeoutError = class extends Error {
6095
+ constructor() {
6096
+ super(...arguments);
6097
+ this.name = "ExecutionTimeoutError";
6098
+ }
6099
+ };
6100
+ ExecutionTimeTracker = class _ExecutionTimeTracker {
6101
+ constructor(limitMs) {
6102
+ this.limitMs = limitMs;
6103
+ this.totalTimeMs = 0;
6104
+ }
6105
+ static withLimit(limitMs) {
6106
+ return new _ExecutionTimeTracker(limitMs);
6107
+ }
6108
+ track(f) {
6109
+ this.checkLimit();
6110
+ const start2 = process.hrtime.bigint();
6111
+ try {
6112
+ return f();
6113
+ } finally {
6114
+ const end2 = process.hrtime.bigint();
6115
+ this.totalTimeMs += Number(end2 - start2) / 1e6;
6116
+ this.checkLimit();
6117
+ }
6118
+ }
6119
+ get elapsedMS() {
6120
+ return this.totalTimeMs;
6121
+ }
6122
+ checkLimit() {
6123
+ if (this.totalTimeMs > this.limitMs) {
6124
+ throw new ExecutionTimeoutError(
6125
+ `Execution time limit of ${this.limitMs}ms exceeded: ${this.totalTimeMs}ms`
6126
+ );
6127
+ }
6128
+ }
6129
+ };
6130
+ }
6131
+ });
6132
+
6133
+ // src/timers/index.ts
6134
+ var timers_exports = {};
6135
+ __export(timers_exports, {
6136
+ ExecutionTimeTracker: () => ExecutionTimeTracker,
6137
+ ExecutionTimeoutError: () => ExecutionTimeoutError,
6138
+ cleanup: () => cleanup,
6139
+ clear: () => clear,
6140
+ set: () => set
6141
+ });
6142
+ var init_timers2 = __esm({
6143
+ "src/timers/index.ts"() {
6144
+ "use strict";
6145
+ init_timers();
6146
+ }
6147
+ });
6148
+
6149
+ // src/redis/redis.ts
6150
+ function pickClient(selectDb) {
6151
+ return CLIENTS[selectDb];
6152
+ }
6153
+ function connectionError(timeout2, err) {
6154
+ if (CLOSED) {
6155
+ return;
6156
+ }
6157
+ CLOSED = true;
6158
+ clearTimeout(timeout2);
6159
+ CONNECTED = false;
6160
+ logAlert("Redis connection failed", err);
6161
+ setTimeout(() => {
6162
+ init2();
6163
+ }, RETRY_PERIOD_MS);
6164
+ }
6165
+ function init2(selectDb = DEFAULT_SELECT_DB) {
6166
+ const RedisCore = environment_default.MOCK_REDIS && MockRedis ? MockRedis : import_ioredis.default;
6167
+ let timeout2;
6168
+ CLOSED = false;
6169
+ let client = pickClient(selectDb);
6170
+ if (client && CONNECTED) {
6171
+ return;
6172
+ }
6173
+ if (environment_default.MOCK_REDIS) {
6174
+ CLIENTS[selectDb] = new RedisCore(getRedisOptions());
6175
+ }
6176
+ timeout2 = setTimeout(() => {
6177
+ if (!CONNECTED) {
6178
+ connectionError(timeout2, "Did not successfully connect in timeout");
6179
+ }
6180
+ }, STARTUP_TIMEOUT_MS);
6181
+ if (client) {
6182
+ client.disconnect();
6183
+ }
6184
+ const { host, port } = getRedisConnectionDetails();
6185
+ const opts = getRedisOptions();
6186
+ if (CLUSTERED) {
6187
+ client = new RedisCore.Cluster([{ host, port }], opts);
6188
+ } else {
6189
+ client = new RedisCore(opts);
6190
+ }
6191
+ client.on("end", (err) => {
6192
+ if (environment_default.isTest()) {
6193
+ return;
6194
+ }
6195
+ connectionError(timeout2, err);
6196
+ });
6197
+ client.on("error", (err) => {
6198
+ connectionError(timeout2, err);
6199
+ });
6200
+ client.on("connect", () => {
6201
+ console.log(`Connected to Redis DB: ${selectDb}`);
6202
+ clearTimeout(timeout2);
6203
+ CONNECTED = true;
6204
+ });
6205
+ CLIENTS[selectDb] = client;
6206
+ }
6207
+ function waitForConnection(selectDb = DEFAULT_SELECT_DB) {
6208
+ return new Promise((resolve) => {
6209
+ if (pickClient(selectDb) == null) {
6210
+ init2();
6211
+ } else if (CONNECTED) {
6212
+ resolve("");
6213
+ return;
6214
+ }
6215
+ const interval = set(() => {
6216
+ if (CONNECTED) {
6217
+ clear(interval);
6218
+ resolve("");
6219
+ }
6220
+ }, 500);
6221
+ });
6222
+ }
6223
+ function promisifyStream(stream2, client) {
6224
+ return new Promise((resolve, reject) => {
6225
+ const outputKeys = /* @__PURE__ */ new Set();
6226
+ stream2.on("data", (keys2) => {
6227
+ keys2.forEach((key) => {
6228
+ outputKeys.add(key);
6229
+ });
6230
+ });
6231
+ stream2.on("error", (err) => {
6232
+ reject(err);
6233
+ });
6234
+ stream2.on("end", async () => {
6235
+ const keysArray = Array.from(outputKeys);
6236
+ try {
6237
+ let getPromises = [];
6238
+ for (let key of keysArray) {
6239
+ getPromises.push(client.get(key));
6240
+ }
6241
+ const jsonArray = await Promise.all(getPromises);
6242
+ resolve(
6243
+ keysArray.map((key) => ({
6244
+ key: removeDbPrefix(key),
6245
+ value: JSON.parse(jsonArray.shift())
6246
+ }))
6247
+ );
6248
+ } catch (err) {
6249
+ reject(err);
6250
+ }
6251
+ });
6252
+ });
6253
+ }
6254
+ var import_ioredis, MockRedis, RETRY_PERIOD_MS, STARTUP_TIMEOUT_MS, CLUSTERED, DEFAULT_SELECT_DB, CLOSED, CLIENTS, CONNECTED, RedisWrapper, redis_default;
6255
+ var init_redis = __esm({
6256
+ "src/redis/redis.ts"() {
6257
+ "use strict";
6258
+ init_environment2();
6259
+ import_ioredis = __toESM(require("ioredis"));
6260
+ init_utils3();
6261
+ init_logging();
6262
+ init_timers2();
6263
+ if (environment_default.MOCK_REDIS) {
6264
+ try {
6265
+ MockRedis = require("ioredis-mock");
6266
+ } catch (err) {
6267
+ console.log("Mock redis unavailable");
6268
+ }
6269
+ }
6270
+ RETRY_PERIOD_MS = 2e3;
6271
+ STARTUP_TIMEOUT_MS = 5e3;
6272
+ CLUSTERED = environment_default.REDIS_CLUSTERED;
6273
+ DEFAULT_SELECT_DB = 0 /* DEFAULT */;
6274
+ CLOSED = false;
6275
+ CLIENTS = {};
6276
+ CONNECTED = false;
6277
+ if (environment_default.MOCK_REDIS) {
6278
+ CONNECTED = true;
6279
+ }
6280
+ RedisWrapper = class {
6281
+ constructor(db, selectDb = null) {
6282
+ this._db = db;
6283
+ this._select = selectDb || DEFAULT_SELECT_DB;
6284
+ }
6285
+ getClient() {
6286
+ return pickClient(this._select);
6287
+ }
6288
+ async init() {
6289
+ CLOSED = false;
6290
+ init2(this._select);
6291
+ await waitForConnection(this._select);
6292
+ if (this._select && !environment_default.isTest()) {
6293
+ this.getClient().select(this._select);
6294
+ }
6295
+ return this;
6296
+ }
6297
+ async finish() {
6298
+ CLOSED = true;
6299
+ this.getClient().disconnect();
6300
+ }
6301
+ async scan(key = "") {
6302
+ const db = this._db;
6303
+ key = `${db}${SEPARATOR2}${key}`;
6304
+ let stream2;
6305
+ if (CLUSTERED) {
6306
+ let node = this.getClient().nodes("master");
6307
+ stream2 = node[0].scanStream({ match: key + "*", count: 100 });
6308
+ } else {
6309
+ stream2 = this.getClient().scanStream({ match: key + "*", count: 100 });
6310
+ }
6311
+ return promisifyStream(stream2, this.getClient());
6312
+ }
6313
+ async keys(pattern) {
6314
+ const db = this._db;
6315
+ return this.getClient().keys(addDbPrefix(db, pattern));
6316
+ }
6317
+ async exists(key) {
6318
+ const db = this._db;
6319
+ return await this.getClient().exists(addDbPrefix(db, key));
6320
+ }
6321
+ async get(key) {
6322
+ const db = this._db;
6323
+ let response = await this.getClient().get(addDbPrefix(db, key));
6324
+ if (response != null && response.key) {
6325
+ response.key = key;
6309
6326
  }
6310
- return tenantId;
6311
- };
6312
- const getAppId2 = () => {
6313
- let appId;
6314
6327
  try {
6315
- appId = getAppId();
6316
- } catch (e) {
6328
+ return JSON.parse(response);
6329
+ } catch (err) {
6330
+ return response;
6317
6331
  }
6318
- return appId;
6319
- };
6320
- const getAutomationId2 = () => {
6321
- let appId;
6322
- try {
6323
- appId = getAutomationId();
6324
- } catch (e) {
6332
+ }
6333
+ async bulkGet(keys2) {
6334
+ const db = this._db;
6335
+ if (keys2.length === 0) {
6336
+ return {};
6325
6337
  }
6326
- return appId;
6327
- };
6328
- const getIdentity3 = () => {
6329
- let identity;
6330
- try {
6331
- identity = getIdentity();
6332
- } catch (e) {
6338
+ const prefixedKeys = keys2.map((key) => addDbPrefix(db, key));
6339
+ let response = await this.getClient().mget(prefixedKeys);
6340
+ if (Array.isArray(response)) {
6341
+ let final = {};
6342
+ let count = 0;
6343
+ for (let result of response) {
6344
+ if (result) {
6345
+ let parsed;
6346
+ try {
6347
+ parsed = JSON.parse(result);
6348
+ } catch (err) {
6349
+ parsed = result;
6350
+ }
6351
+ final[keys2[count]] = parsed;
6352
+ }
6353
+ count++;
6354
+ }
6355
+ return final;
6356
+ } else {
6357
+ throw new Error(`Invalid response: ${response}`);
6333
6358
  }
6334
- return identity;
6335
- };
6336
- }
6337
- logger = pinoInstance;
6359
+ }
6360
+ async store(key, value, expirySeconds = null) {
6361
+ const db = this._db;
6362
+ if (typeof value === "object") {
6363
+ value = JSON.stringify(value);
6364
+ }
6365
+ const prefixedKey = addDbPrefix(db, key);
6366
+ await this.getClient().set(prefixedKey, value);
6367
+ if (expirySeconds) {
6368
+ await this.getClient().expire(prefixedKey, expirySeconds);
6369
+ }
6370
+ }
6371
+ async getTTL(key) {
6372
+ const db = this._db;
6373
+ const prefixedKey = addDbPrefix(db, key);
6374
+ return this.getClient().ttl(prefixedKey);
6375
+ }
6376
+ async setExpiry(key, expirySeconds) {
6377
+ const db = this._db;
6378
+ const prefixedKey = addDbPrefix(db, key);
6379
+ await this.getClient().expire(prefixedKey, expirySeconds);
6380
+ }
6381
+ async delete(key) {
6382
+ const db = this._db;
6383
+ await this.getClient().del(addDbPrefix(db, key));
6384
+ }
6385
+ async clear() {
6386
+ let items = await this.scan();
6387
+ await Promise.all(items.map((obj) => this.delete(obj.key)));
6388
+ }
6389
+ };
6390
+ redis_default = RedisWrapper;
6338
6391
  }
6339
6392
  });
6340
6393
 
6341
- // src/logging/alerts.ts
6342
- function isSuppressed(e) {
6343
- return e && e["suppressAlert"];
6394
+ // src/redis/init.ts
6395
+ var init_exports = {};
6396
+ __export(init_exports, {
6397
+ getAppClient: () => getAppClient,
6398
+ getCacheClient: () => getCacheClient,
6399
+ getInviteClient: () => getInviteClient,
6400
+ getLockClient: () => getLockClient,
6401
+ getPasswordResetClient: () => getPasswordResetClient,
6402
+ getSessionClient: () => getSessionClient,
6403
+ getSocketClient: () => getSocketClient,
6404
+ getUserClient: () => getUserClient,
6405
+ getWritethroughClient: () => getWritethroughClient,
6406
+ init: () => init3,
6407
+ shutdown: () => shutdown
6408
+ });
6409
+ async function init3() {
6410
+ userClient = await new redis_default("users" /* USER_CACHE */).init();
6411
+ sessionClient = await new redis_default("session" /* SESSIONS */).init();
6412
+ appClient = await new redis_default("appMetadata" /* APP_METADATA */).init();
6413
+ cacheClient = await new redis_default("data_cache" /* GENERIC_CACHE */).init();
6414
+ lockClient = await new redis_default("locks" /* LOCKS */).init();
6415
+ writethroughClient = await new redis_default("writeThrough" /* WRITE_THROUGH */).init();
6416
+ inviteClient = await new redis_default("invitation" /* INVITATIONS */).init();
6417
+ passwordResetClient = await new redis_default("pwReset" /* PW_RESETS */).init();
6418
+ socketClient = await new redis_default(
6419
+ "socket_io" /* SOCKET_IO */,
6420
+ 1 /* SOCKET_IO */
6421
+ ).init();
6344
6422
  }
6345
- function logAlert(message, e) {
6346
- if (e && NonErrors.includes(e.name) && isSuppressed(e)) {
6347
- return;
6423
+ async function shutdown() {
6424
+ if (userClient)
6425
+ await userClient.finish();
6426
+ if (sessionClient)
6427
+ await sessionClient.finish();
6428
+ if (appClient)
6429
+ await appClient.finish();
6430
+ if (cacheClient)
6431
+ await cacheClient.finish();
6432
+ if (writethroughClient)
6433
+ await writethroughClient.finish();
6434
+ if (lockClient)
6435
+ await lockClient.finish();
6436
+ if (inviteClient)
6437
+ await inviteClient.finish();
6438
+ if (passwordResetClient)
6439
+ await passwordResetClient.finish();
6440
+ if (socketClient)
6441
+ await socketClient.finish();
6442
+ }
6443
+ async function getUserClient() {
6444
+ if (!userClient) {
6445
+ await init3();
6348
6446
  }
6349
- console.error(`bb-alert: ${message}`, e);
6447
+ return userClient;
6350
6448
  }
6351
- function logAlertWithInfo(message, db, id, error) {
6352
- message = `${message} - db: ${db} - doc: ${id} - error: `;
6353
- logAlert(message, error);
6449
+ async function getSessionClient() {
6450
+ if (!sessionClient) {
6451
+ await init3();
6452
+ }
6453
+ return sessionClient;
6354
6454
  }
6355
- function logWarn(message, e) {
6356
- console.warn(`bb-warn: ${message}`, e);
6455
+ async function getAppClient() {
6456
+ if (!appClient) {
6457
+ await init3();
6458
+ }
6459
+ return appClient;
6357
6460
  }
6358
- var NonErrors;
6359
- var init_alerts = __esm({
6360
- "src/logging/alerts.ts"() {
6361
- "use strict";
6362
- NonErrors = ["AccountError"];
6461
+ async function getCacheClient() {
6462
+ if (!cacheClient) {
6463
+ await init3();
6363
6464
  }
6364
- });
6365
-
6366
- // src/logging/index.ts
6367
- var logging_exports = {};
6368
- __export(logging_exports, {
6369
- correlation: () => correlation_exports,
6370
- logAlert: () => logAlert,
6371
- logAlertWithInfo: () => logAlertWithInfo,
6372
- logWarn: () => logWarn,
6373
- logger: () => logger,
6374
- system: () => system_exports
6375
- });
6376
- var init_logging = __esm({
6377
- "src/logging/index.ts"() {
6465
+ return cacheClient;
6466
+ }
6467
+ async function getWritethroughClient() {
6468
+ if (!writethroughClient) {
6469
+ await init3();
6470
+ }
6471
+ return writethroughClient;
6472
+ }
6473
+ async function getLockClient() {
6474
+ if (!lockClient) {
6475
+ await init3();
6476
+ }
6477
+ return lockClient;
6478
+ }
6479
+ async function getSocketClient() {
6480
+ if (!socketClient) {
6481
+ await init3();
6482
+ }
6483
+ return socketClient;
6484
+ }
6485
+ async function getInviteClient() {
6486
+ if (!inviteClient) {
6487
+ await init3();
6488
+ }
6489
+ return inviteClient;
6490
+ }
6491
+ async function getPasswordResetClient() {
6492
+ if (!passwordResetClient) {
6493
+ await init3();
6494
+ }
6495
+ return passwordResetClient;
6496
+ }
6497
+ var userClient, sessionClient, appClient, cacheClient, writethroughClient, lockClient, socketClient, inviteClient, passwordResetClient;
6498
+ var init_init = __esm({
6499
+ "src/redis/init.ts"() {
6378
6500
  "use strict";
6379
- init_correlation();
6380
- init_logger();
6381
- init_alerts();
6382
- init_system2();
6501
+ init_redis();
6502
+ init_utils3();
6503
+ process.on("exit", async () => {
6504
+ await shutdown();
6505
+ });
6383
6506
  }
6384
6507
  });
6385
6508
 
@@ -6601,15 +6724,12 @@ var TTL = /* @__PURE__ */ ((TTL2) => {
6601
6724
  TTL2[TTL2["ONE_DAY"] = 86400] = "ONE_DAY";
6602
6725
  return TTL2;
6603
6726
  })(TTL || {});
6604
- function performExport(funcName) {
6605
- return (...args) => GENERIC[funcName](...args);
6606
- }
6607
- var keys = performExport("keys");
6608
- var get2 = performExport("get");
6609
- var store = performExport("store");
6610
- var destroy = performExport("delete");
6611
- var withCache = performExport("withCache");
6612
- var bustCache = performExport("bustCache");
6727
+ var keys = (...args) => GENERIC.keys(...args);
6728
+ var get2 = (...args) => GENERIC.get(...args);
6729
+ var store = (...args) => GENERIC.store(...args);
6730
+ var destroy = (...args) => GENERIC.delete(...args);
6731
+ var withCache = (...args) => GENERIC.withCache(...args);
6732
+ var bustCache = (...args) => GENERIC.bustCache(...args);
6613
6733
 
6614
6734
  // src/cache/user.ts
6615
6735
  var user_exports = {};
@@ -7068,13 +7188,13 @@ function validEmail(value) {
7068
7188
  }
7069
7189
 
7070
7190
  // src/utils/Duration.ts
7071
- var DurationType = /* @__PURE__ */ ((DurationType4) => {
7072
- DurationType4["MILLISECONDS"] = "milliseconds";
7073
- DurationType4["SECONDS"] = "seconds";
7074
- DurationType4["MINUTES"] = "minutes";
7075
- DurationType4["HOURS"] = "hours";
7076
- DurationType4["DAYS"] = "days";
7077
- return DurationType4;
7191
+ var DurationType = /* @__PURE__ */ ((DurationType3) => {
7192
+ DurationType3["MILLISECONDS"] = "milliseconds";
7193
+ DurationType3["SECONDS"] = "seconds";
7194
+ DurationType3["MINUTES"] = "minutes";
7195
+ DurationType3["HOURS"] = "hours";
7196
+ DurationType3["DAYS"] = "days";
7197
+ return DurationType3;
7078
7198
  })(DurationType || {});
7079
7199
  var conversion = {
7080
7200
  milliseconds: 1,
@@ -8309,7 +8429,7 @@ function createQueue(jobQueue, opts = {}) {
8309
8429
  if (!cleanupInterval && !environment_default.isTest()) {
8310
8430
  cleanupInterval = set(cleanup2, CLEANUP_PERIOD_MS);
8311
8431
  cleanup2().catch((err) => {
8312
- console.error(`Unable to cleanup automation queue initially - ${err}`);
8432
+ console.error(`Unable to cleanup ${jobQueue} initially - ${err}`);
8313
8433
  });
8314
8434
  }
8315
8435
  return queue;
@@ -11213,7 +11333,8 @@ var Writethrough = class {
11213
11333
  var passwordReset_exports = {};
11214
11334
  __export(passwordReset_exports, {
11215
11335
  createCode: () => createCode2,
11216
- getCode: () => getCode2
11336
+ getCode: () => getCode2,
11337
+ invalidateCode: () => invalidateCode
11217
11338
  });
11218
11339
  init_init();
11219
11340
  var TTL_SECONDS2 = Duration.fromHours(1).toSeconds();
@@ -11227,10 +11348,16 @@ async function getCode2(code) {
11227
11348
  const client = await getPasswordResetClient();
11228
11349
  const value = await client.get(code);
11229
11350
  if (!value) {
11230
- throw "Provided information is not valid, cannot reset password - please try again.";
11351
+ throw new Error(
11352
+ "Provided information is not valid, cannot reset password - please try again."
11353
+ );
11231
11354
  }
11232
11355
  return value;
11233
11356
  }
11357
+ async function invalidateCode(code) {
11358
+ const client = await getPasswordResetClient();
11359
+ await client.delete(code);
11360
+ }
11234
11361
 
11235
11362
  // src/configs/configs.ts
11236
11363
  init_context2();