@budibase/backend-core 2.13.28 → 2.13.30

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
@@ -5969,7 +5969,7 @@ __export(src_exports, {
5969
5969
  tenancy: () => tenancy,
5970
5970
  timers: () => timers_exports,
5971
5971
  users: () => users_exports3,
5972
- utils: () => utils_exports2
5972
+ utils: () => utils_exports3
5973
5973
  });
5974
5974
  module.exports = __toCommonJS(src_exports);
5975
5975
 
@@ -6370,6 +6370,7 @@ init_src();
6370
6370
  // src/redis/redlockImpl.ts
6371
6371
  var redlockImpl_exports = {};
6372
6372
  __export(redlockImpl_exports, {
6373
+ AUTO_EXTEND_POLLING_MS: () => AUTO_EXTEND_POLLING_MS,
6373
6374
  doWithLock: () => doWithLock,
6374
6375
  newRedlock: () => newRedlock
6375
6376
  });
@@ -6377,15 +6378,571 @@ var import_redlock = __toESM(require("redlock"));
6377
6378
  init_init();
6378
6379
  init_src();
6379
6380
  init_context2();
6381
+ init_logging();
6382
+
6383
+ // ../shared-core/src/constants.ts
6384
+ var OperatorOptions = {
6385
+ Equals: {
6386
+ value: "equal",
6387
+ label: "Equals"
6388
+ },
6389
+ NotEquals: {
6390
+ value: "notEqual",
6391
+ label: "Not equals"
6392
+ },
6393
+ Empty: {
6394
+ value: "empty",
6395
+ label: "Is empty"
6396
+ },
6397
+ NotEmpty: {
6398
+ value: "notEmpty",
6399
+ label: "Is not empty"
6400
+ },
6401
+ StartsWith: {
6402
+ value: "string",
6403
+ label: "Starts with"
6404
+ },
6405
+ Like: {
6406
+ value: "fuzzy",
6407
+ label: "Like"
6408
+ },
6409
+ MoreThan: {
6410
+ value: "rangeLow",
6411
+ label: "More than or equal to"
6412
+ },
6413
+ LessThan: {
6414
+ value: "rangeHigh",
6415
+ label: "Less than or equal to"
6416
+ },
6417
+ Contains: {
6418
+ value: "contains",
6419
+ label: "Contains"
6420
+ },
6421
+ NotContains: {
6422
+ value: "notContains",
6423
+ label: "Does not contain"
6424
+ },
6425
+ In: {
6426
+ value: "oneOf",
6427
+ label: "Is in"
6428
+ },
6429
+ ContainsAny: {
6430
+ value: "containsAny",
6431
+ label: "Has any"
6432
+ }
6433
+ };
6434
+
6435
+ // ../shared-core/src/filters.ts
6436
+ init_src();
6437
+ var import_dayjs = __toESM(require_dayjs_min());
6438
+
6439
+ // ../shared-core/src/helpers/integrations.ts
6440
+ init_src();
6441
+
6442
+ // ../shared-core/src/filters.ts
6443
+ var NoEmptyFilterStrings = [
6444
+ OperatorOptions.StartsWith.value,
6445
+ OperatorOptions.Like.value,
6446
+ OperatorOptions.Equals.value,
6447
+ OperatorOptions.NotEquals.value,
6448
+ OperatorOptions.Contains.value,
6449
+ OperatorOptions.NotContains.value
6450
+ ];
6451
+
6452
+ // ../shared-core/src/utils.ts
6453
+ var utils_exports2 = {};
6454
+ __export(utils_exports2, {
6455
+ filterValueToLabel: () => filterValueToLabel,
6456
+ parallelForeach: () => parallelForeach,
6457
+ unreachable: () => unreachable
6458
+ });
6459
+ function unreachable(value, message = `No such case in exhaustive switch: ${value}`) {
6460
+ throw new Error(message);
6461
+ }
6462
+ async function parallelForeach(items, task, maxConcurrency) {
6463
+ const promises = [];
6464
+ let index2 = 0;
6465
+ const processItem = async (item) => {
6466
+ try {
6467
+ await task(item);
6468
+ } finally {
6469
+ processNext();
6470
+ }
6471
+ };
6472
+ const processNext = () => {
6473
+ if (index2 >= items.length) {
6474
+ return;
6475
+ }
6476
+ const item = items[index2];
6477
+ index2++;
6478
+ const promise = processItem(item);
6479
+ promises.push(promise);
6480
+ if (promises.length >= maxConcurrency) {
6481
+ Promise.race(promises).then(processNext);
6482
+ } else {
6483
+ processNext();
6484
+ }
6485
+ };
6486
+ processNext();
6487
+ await Promise.all(promises);
6488
+ }
6489
+ function filterValueToLabel() {
6490
+ return Object.keys(OperatorOptions).reduce(
6491
+ (acc, key) => {
6492
+ const ops = OperatorOptions;
6493
+ const op = ops[key];
6494
+ acc[op["value"]] = op.label;
6495
+ return acc;
6496
+ },
6497
+ {}
6498
+ );
6499
+ }
6500
+
6501
+ // ../shared-core/src/sdk/index.ts
6502
+ var sdk_exports = {};
6503
+ __export(sdk_exports, {
6504
+ applications: () => applications_exports,
6505
+ users: () => users_exports2
6506
+ });
6507
+
6508
+ // ../shared-core/src/sdk/documents/applications.ts
6509
+ var applications_exports = {};
6510
+ __export(applications_exports, {
6511
+ getDevAppID: () => getDevAppID2,
6512
+ getProdAppID: () => getProdAppID2
6513
+ });
6514
+ init_src();
6515
+ var APP_PREFIX2 = prefixed("app" /* APP */);
6516
+ var APP_DEV_PREFIX2 = prefixed("app_dev" /* APP_DEV */);
6517
+ function getDevAppID2(appId) {
6518
+ if (!appId) {
6519
+ throw new Error("No app ID provided");
6520
+ }
6521
+ if (appId.startsWith(APP_DEV_PREFIX2)) {
6522
+ return appId;
6523
+ }
6524
+ const split = appId.split(APP_PREFIX2);
6525
+ split.shift();
6526
+ const rest = split.join(APP_PREFIX2);
6527
+ return `${APP_DEV_PREFIX2}${rest}`;
6528
+ }
6529
+ function getProdAppID2(appId) {
6530
+ if (!appId) {
6531
+ throw new Error("No app ID provided");
6532
+ }
6533
+ if (!appId.startsWith(APP_DEV_PREFIX2)) {
6534
+ return appId;
6535
+ }
6536
+ const split = appId.split(APP_DEV_PREFIX2);
6537
+ split.shift();
6538
+ const rest = split.join(APP_DEV_PREFIX2);
6539
+ return `${APP_PREFIX2}${rest}`;
6540
+ }
6541
+
6542
+ // ../shared-core/src/sdk/documents/users.ts
6543
+ var users_exports2 = {};
6544
+ __export(users_exports2, {
6545
+ canCreateApps: () => canCreateApps,
6546
+ containsUserID: () => containsUserID,
6547
+ getGlobalUserID: () => getGlobalUserID,
6548
+ hasAdminPermissions: () => hasAdminPermissions,
6549
+ hasAppBuilderPermissions: () => hasAppBuilderPermissions,
6550
+ hasAppCreatorPermissions: () => hasAppCreatorPermissions,
6551
+ hasBuilderPermissions: () => hasBuilderPermissions,
6552
+ hasCreatorPermissions: () => hasCreatorPermissions,
6553
+ isAdmin: () => isAdmin,
6554
+ isAdminOrBuilder: () => isAdminOrBuilder,
6555
+ isAdminOrGlobalBuilder: () => isAdminOrGlobalBuilder,
6556
+ isBuilder: () => isBuilder,
6557
+ isCreator: () => isCreator,
6558
+ isGlobalBuilder: () => isGlobalBuilder
6559
+ });
6560
+ init_src();
6561
+ var _ = __toESM(require("lodash/fp"));
6562
+ function isBuilder(user, appId) {
6563
+ if (!user) {
6564
+ return false;
6565
+ }
6566
+ if (user.builder?.global) {
6567
+ return true;
6568
+ } else if (appId && user.builder?.apps?.includes(getProdAppID2(appId))) {
6569
+ return true;
6570
+ }
6571
+ return false;
6572
+ }
6573
+ function isGlobalBuilder(user) {
6574
+ return isBuilder(user) && !hasAppBuilderPermissions(user) || isAdmin(user);
6575
+ }
6576
+ function canCreateApps(user) {
6577
+ return isGlobalBuilder(user) || hasCreatorPermissions(user);
6578
+ }
6579
+ function isAdmin(user) {
6580
+ if (!user) {
6581
+ return false;
6582
+ }
6583
+ return hasAdminPermissions(user);
6584
+ }
6585
+ function isAdminOrBuilder(user, appId) {
6586
+ return isBuilder(user, appId) || isAdmin(user);
6587
+ }
6588
+ function isAdminOrGlobalBuilder(user, appId) {
6589
+ return isGlobalBuilder(user) || isAdmin(user);
6590
+ }
6591
+ function hasAppBuilderPermissions(user) {
6592
+ if (!user) {
6593
+ return false;
6594
+ }
6595
+ const appLength = user.builder?.apps?.length;
6596
+ const isGlobalBuilder3 = !!user.builder?.global;
6597
+ return !isGlobalBuilder3 && appLength != null && appLength > 0;
6598
+ }
6599
+ function hasAppCreatorPermissions(user) {
6600
+ if (!user) {
6601
+ return false;
6602
+ }
6603
+ return _.flow(
6604
+ _.get("roles"),
6605
+ _.values,
6606
+ _.find((x) => x === "CREATOR"),
6607
+ (x) => !!x
6608
+ )(user);
6609
+ }
6610
+ function hasBuilderPermissions(user) {
6611
+ if (!user) {
6612
+ return false;
6613
+ }
6614
+ return user.builder?.global || hasAppBuilderPermissions(user) || hasCreatorPermissions(user);
6615
+ }
6616
+ function hasAdminPermissions(user) {
6617
+ if (!user) {
6618
+ return false;
6619
+ }
6620
+ return !!user.admin?.global;
6621
+ }
6622
+ function hasCreatorPermissions(user) {
6623
+ if (!user) {
6624
+ return false;
6625
+ }
6626
+ return !!user.builder?.creator;
6627
+ }
6628
+ function isCreator(user) {
6629
+ if (!user) {
6630
+ return false;
6631
+ }
6632
+ return isGlobalBuilder(user) || hasAdminPermissions(user) || hasCreatorPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
6633
+ }
6634
+ function getGlobalUserID(userId) {
6635
+ if (typeof userId !== "string") {
6636
+ return userId;
6637
+ }
6638
+ const prefix = `${"ro" /* ROW */}${SEPARATOR}${"ta_users" /* USER_METADATA */}${SEPARATOR}`;
6639
+ if (!userId.startsWith(prefix)) {
6640
+ return userId;
6641
+ }
6642
+ return userId.split(prefix)[1];
6643
+ }
6644
+ function containsUserID(value) {
6645
+ if (typeof value !== "string") {
6646
+ return false;
6647
+ }
6648
+ return value.includes(`${"us" /* USER */}${SEPARATOR}`);
6649
+ }
6650
+
6651
+ // ../shared-core/src/table.ts
6652
+ init_src();
6653
+ var allowDisplayColumnByType = {
6654
+ ["string" /* STRING */]: true,
6655
+ ["longform" /* LONGFORM */]: true,
6656
+ ["options" /* OPTIONS */]: true,
6657
+ ["number" /* NUMBER */]: true,
6658
+ ["datetime" /* DATETIME */]: true,
6659
+ ["formula" /* FORMULA */]: true,
6660
+ ["auto" /* AUTO */]: true,
6661
+ ["internal" /* INTERNAL */]: true,
6662
+ ["barcodeqr" /* BARCODEQR */]: true,
6663
+ ["bigint" /* BIGINT */]: true,
6664
+ ["boolean" /* BOOLEAN */]: false,
6665
+ ["array" /* ARRAY */]: false,
6666
+ ["attachment" /* ATTACHMENT */]: false,
6667
+ ["link" /* LINK */]: false,
6668
+ ["json" /* JSON */]: false,
6669
+ ["bb_reference" /* BB_REFERENCE */]: false
6670
+ };
6671
+ var allowSortColumnByType = {
6672
+ ["string" /* STRING */]: true,
6673
+ ["longform" /* LONGFORM */]: true,
6674
+ ["options" /* OPTIONS */]: true,
6675
+ ["number" /* NUMBER */]: true,
6676
+ ["datetime" /* DATETIME */]: true,
6677
+ ["auto" /* AUTO */]: true,
6678
+ ["internal" /* INTERNAL */]: true,
6679
+ ["barcodeqr" /* BARCODEQR */]: true,
6680
+ ["bigint" /* BIGINT */]: true,
6681
+ ["boolean" /* BOOLEAN */]: true,
6682
+ ["json" /* JSON */]: true,
6683
+ ["formula" /* FORMULA */]: false,
6684
+ ["attachment" /* ATTACHMENT */]: false,
6685
+ ["array" /* ARRAY */]: false,
6686
+ ["link" /* LINK */]: false,
6687
+ ["bb_reference" /* BB_REFERENCE */]: false
6688
+ };
6689
+
6690
+ // src/utils/index.ts
6691
+ var utils_exports3 = {};
6692
+ __export(utils_exports3, {
6693
+ Duration: () => Duration,
6694
+ DurationType: () => DurationType,
6695
+ clearCookie: () => clearCookie,
6696
+ compare: () => compare,
6697
+ getAppIdFromCtx: () => getAppIdFromCtx,
6698
+ getCookie: () => getCookie,
6699
+ hasCircularStructure: () => hasCircularStructure,
6700
+ hash: () => hash,
6701
+ isAudited: () => isAudited,
6702
+ isClient: () => isClient,
6703
+ isPublicApiRequest: () => isPublicApiRequest,
6704
+ isServingApp: () => isServingApp,
6705
+ isServingBuilder: () => isServingBuilder,
6706
+ isServingBuilderPreview: () => isServingBuilderPreview,
6707
+ isValidInternalAPIKey: () => isValidInternalAPIKey,
6708
+ newid: () => newid,
6709
+ openJwt: () => openJwt,
6710
+ resolveAppUrl: () => resolveAppUrl,
6711
+ setCookie: () => setCookie,
6712
+ timeout: () => timeout,
6713
+ validEmail: () => validEmail
6714
+ });
6715
+
6716
+ // src/utils/hashing.ts
6380
6717
  init_environment2();
6381
- init_logging();
6718
+ init_newid();
6719
+ var bcrypt = environment_default.JS_BCRYPT ? require("bcryptjs") : require("bcrypt");
6720
+ var SALT_ROUNDS = environment_default.SALT_ROUNDS || 10;
6721
+ async function hash(data) {
6722
+ const salt = await bcrypt.genSalt(SALT_ROUNDS);
6723
+ return bcrypt.hash(data, salt);
6724
+ }
6725
+ async function compare(data, encrypted) {
6726
+ return bcrypt.compare(data, encrypted);
6727
+ }
6728
+
6729
+ // src/utils/utils.ts
6730
+ init_db4();
6731
+ init_constants3();
6732
+ init_environment2();
6733
+ init_context2();
6734
+ init_src();
6735
+ var jwt = require("jsonwebtoken");
6736
+ var APP_PREFIX3 = "app" /* APP */ + SEPARATOR;
6737
+ var PROD_APP_PREFIX = "/app/";
6738
+ var BUILDER_PREVIEW_PATH = "/app/preview";
6739
+ var BUILDER_PREFIX = "/builder";
6740
+ var BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`;
6741
+ var PUBLIC_API_PREFIX = "/api/public/v";
6742
+ function confirmAppId(possibleAppId) {
6743
+ return possibleAppId && possibleAppId.startsWith(APP_PREFIX3) ? possibleAppId : void 0;
6744
+ }
6745
+ async function resolveAppUrl(ctx) {
6746
+ const appUrl = ctx.path.split("/")[2];
6747
+ let possibleAppUrl = `/${appUrl.toLowerCase()}`;
6748
+ let tenantId = getTenantId();
6749
+ if (environment_default.MULTI_TENANCY) {
6750
+ tenantId = getTenantIDFromCtx(ctx, {
6751
+ includeStrategies: ["subdomain" /* SUBDOMAIN */]
6752
+ });
6753
+ }
6754
+ const apps = await doInTenant(
6755
+ tenantId,
6756
+ () => getAllApps({ dev: false })
6757
+ );
6758
+ const app = apps.filter(
6759
+ (a) => a.url && a.url.toLowerCase() === possibleAppUrl
6760
+ )[0];
6761
+ return app && app.appId ? app.appId : void 0;
6762
+ }
6763
+ function isServingApp(ctx) {
6764
+ if (ctx.path.startsWith(`/${APP_PREFIX3}`)) {
6765
+ return true;
6766
+ }
6767
+ if (ctx.path.startsWith(PROD_APP_PREFIX)) {
6768
+ return true;
6769
+ }
6770
+ return false;
6771
+ }
6772
+ function isServingBuilder(ctx) {
6773
+ return ctx.path.startsWith(BUILDER_APP_PREFIX);
6774
+ }
6775
+ function isServingBuilderPreview(ctx) {
6776
+ return ctx.path.startsWith(BUILDER_PREVIEW_PATH);
6777
+ }
6778
+ function isPublicApiRequest(ctx) {
6779
+ return ctx.path.startsWith(PUBLIC_API_PREFIX);
6780
+ }
6781
+ async function getAppIdFromCtx(ctx) {
6782
+ const options2 = [ctx.request.headers["x-budibase-app-id" /* APP_ID */]];
6783
+ let appId;
6784
+ for (let option of options2) {
6785
+ appId = confirmAppId(option);
6786
+ if (appId) {
6787
+ break;
6788
+ }
6789
+ }
6790
+ if (!appId && ctx.request.body && ctx.request.body.appId) {
6791
+ appId = confirmAppId(ctx.request.body.appId);
6792
+ }
6793
+ const pathId = parseAppIdFromUrl(ctx.path);
6794
+ if (!appId && pathId) {
6795
+ appId = confirmAppId(pathId);
6796
+ }
6797
+ const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH);
6798
+ const isViewingProdApp = ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview;
6799
+ if (!appId && isViewingProdApp) {
6800
+ appId = confirmAppId(await resolveAppUrl(ctx));
6801
+ }
6802
+ const referer = ctx.request.headers.referer;
6803
+ if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
6804
+ const refererId = parseAppIdFromUrl(ctx.request.headers.referer);
6805
+ appId = confirmAppId(refererId);
6806
+ }
6807
+ return appId;
6808
+ }
6809
+ function parseAppIdFromUrl(url) {
6810
+ if (!url) {
6811
+ return;
6812
+ }
6813
+ return url.split("/").find((subPath) => subPath.startsWith(APP_PREFIX3));
6814
+ }
6815
+ function openJwt(token) {
6816
+ if (!token) {
6817
+ return token;
6818
+ }
6819
+ try {
6820
+ return jwt.verify(token, environment_default.JWT_SECRET);
6821
+ } catch (e) {
6822
+ if (environment_default.JWT_SECRET_FALLBACK) {
6823
+ return jwt.verify(token, environment_default.JWT_SECRET_FALLBACK);
6824
+ } else {
6825
+ throw e;
6826
+ }
6827
+ }
6828
+ }
6829
+ function isValidInternalAPIKey(apiKey) {
6830
+ if (environment_default.INTERNAL_API_KEY && environment_default.INTERNAL_API_KEY === apiKey) {
6831
+ return true;
6832
+ }
6833
+ if (environment_default.INTERNAL_API_KEY_FALLBACK && environment_default.INTERNAL_API_KEY_FALLBACK === apiKey) {
6834
+ return true;
6835
+ }
6836
+ return false;
6837
+ }
6838
+ function getCookie(ctx, name) {
6839
+ const cookie = ctx.cookies.get(name);
6840
+ if (!cookie) {
6841
+ return cookie;
6842
+ }
6843
+ return openJwt(cookie);
6844
+ }
6845
+ function setCookie(ctx, value, name = "builder", opts = { sign: true }) {
6846
+ if (value && opts && opts.sign) {
6847
+ value = jwt.sign(value, environment_default.JWT_SECRET);
6848
+ }
6849
+ const config = {
6850
+ expires: MAX_VALID_DATE,
6851
+ path: "/",
6852
+ httpOnly: false,
6853
+ overwrite: true
6854
+ };
6855
+ if (environment_default.COOKIE_DOMAIN) {
6856
+ config.domain = environment_default.COOKIE_DOMAIN;
6857
+ }
6858
+ ctx.cookies.set(name, value, config);
6859
+ }
6860
+ function clearCookie(ctx, name) {
6861
+ setCookie(ctx, null, name);
6862
+ }
6863
+ function isClient(ctx) {
6864
+ return ctx.headers["x-budibase-type" /* TYPE */] === "client";
6865
+ }
6866
+ function timeout(timeMs) {
6867
+ return new Promise((resolve) => setTimeout(resolve, timeMs));
6868
+ }
6869
+ function isAudited(event) {
6870
+ return !!AuditedEventFriendlyName[event];
6871
+ }
6872
+ function hasCircularStructure(json) {
6873
+ if (typeof json !== "object") {
6874
+ return false;
6875
+ }
6876
+ try {
6877
+ JSON.stringify(json);
6878
+ } catch (err) {
6879
+ if (err instanceof Error && err?.message.includes("circular structure")) {
6880
+ return true;
6881
+ }
6882
+ }
6883
+ return false;
6884
+ }
6885
+
6886
+ // src/utils/stringUtils.ts
6887
+ function validEmail(value) {
6888
+ return value && !!value.match(
6889
+ /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
6890
+ );
6891
+ }
6892
+
6893
+ // src/utils/Duration.ts
6894
+ var DurationType = /* @__PURE__ */ ((DurationType4) => {
6895
+ DurationType4["MILLISECONDS"] = "milliseconds";
6896
+ DurationType4["SECONDS"] = "seconds";
6897
+ DurationType4["MINUTES"] = "minutes";
6898
+ DurationType4["HOURS"] = "hours";
6899
+ DurationType4["DAYS"] = "days";
6900
+ return DurationType4;
6901
+ })(DurationType || {});
6902
+ var conversion = {
6903
+ milliseconds: 1,
6904
+ seconds: 1e3,
6905
+ minutes: 60 * 1e3,
6906
+ hours: 60 * 60 * 1e3,
6907
+ days: 24 * 60 * 60 * 1e3
6908
+ };
6909
+ var Duration = class _Duration {
6910
+ static convert(from, to, duration) {
6911
+ const milliseconds = duration * conversion[from];
6912
+ return milliseconds / conversion[to];
6913
+ }
6914
+ static from(from, duration) {
6915
+ return {
6916
+ to: (to) => {
6917
+ return _Duration.convert(from, to, duration);
6918
+ },
6919
+ toMs: () => {
6920
+ return _Duration.convert(from, "milliseconds" /* MILLISECONDS */, duration);
6921
+ },
6922
+ toSeconds: () => {
6923
+ return _Duration.convert(from, "seconds" /* SECONDS */, duration);
6924
+ }
6925
+ };
6926
+ }
6927
+ static fromSeconds(duration) {
6928
+ return _Duration.from("seconds" /* SECONDS */, duration);
6929
+ }
6930
+ static fromMinutes(duration) {
6931
+ return _Duration.from("minutes" /* MINUTES */, duration);
6932
+ }
6933
+ static fromHours(duration) {
6934
+ return _Duration.from("hours" /* HOURS */, duration);
6935
+ }
6936
+ static fromDays(duration) {
6937
+ return _Duration.from("days" /* DAYS */, duration);
6938
+ }
6939
+ };
6940
+
6941
+ // src/redis/redlockImpl.ts
6382
6942
  async function getClient(type, opts) {
6383
6943
  if (type === "custom" /* CUSTOM */) {
6384
6944
  return newRedlock(opts);
6385
6945
  }
6386
- if (environment_default.isTest() && type !== "try_once" /* TRY_ONCE */) {
6387
- return newRedlock(OPTIONS.TEST);
6388
- }
6389
6946
  switch (type) {
6390
6947
  case "try_once" /* TRY_ONCE */: {
6391
6948
  return newRedlock(OPTIONS.TRY_ONCE);
@@ -6399,8 +6956,11 @@ async function getClient(type, opts) {
6399
6956
  case "delay_500" /* DELAY_500 */: {
6400
6957
  return newRedlock(OPTIONS.DELAY_500);
6401
6958
  }
6959
+ case "auto_extend" /* AUTO_EXTEND */: {
6960
+ return newRedlock(OPTIONS.AUTO_EXTEND);
6961
+ }
6402
6962
  default: {
6403
- throw new Error(`Could not get redlock client: ${type}`);
6963
+ throw utils_exports2.unreachable(type);
6404
6964
  }
6405
6965
  }
6406
6966
  }
@@ -6412,11 +6972,6 @@ var OPTIONS = {
6412
6972
  TRY_TWICE: {
6413
6973
  retryCount: 1
6414
6974
  },
6415
- TEST: {
6416
- // higher retry count in unit tests
6417
- // due to high contention.
6418
- retryCount: 100
6419
- },
6420
6975
  DEFAULT: {
6421
6976
  // the expected clock drift; for more details
6422
6977
  // see http://redis.io/topics/distlock
@@ -6436,10 +6991,14 @@ var OPTIONS = {
6436
6991
  },
6437
6992
  DELAY_500: {
6438
6993
  retryDelay: 500
6994
+ },
6995
+ CUSTOM: {},
6996
+ AUTO_EXTEND: {
6997
+ retryCount: -1
6439
6998
  }
6440
6999
  };
6441
7000
  async function newRedlock(opts = {}) {
6442
- let options2 = { ...OPTIONS.DEFAULT, ...opts };
7001
+ const options2 = { ...OPTIONS.DEFAULT, ...opts };
6443
7002
  const redisWrapper = await getLockClient();
6444
7003
  const client = redisWrapper.getClient();
6445
7004
  return new import_redlock.default([client], options2);
@@ -6452,12 +7011,24 @@ function getLockName(opts) {
6452
7011
  }
6453
7012
  return name;
6454
7013
  }
7014
+ var AUTO_EXTEND_POLLING_MS = Duration.fromSeconds(10).toMs();
6455
7015
  async function doWithLock(opts, task) {
6456
7016
  const redlock = await getClient(opts.type, opts.customOptions);
6457
7017
  let lock;
7018
+ let timeout2;
6458
7019
  try {
6459
7020
  const name = getLockName(opts);
6460
- lock = await redlock.lock(name, opts.ttl);
7021
+ const ttl = opts.type === "auto_extend" /* AUTO_EXTEND */ ? AUTO_EXTEND_POLLING_MS : opts.ttl;
7022
+ lock = await redlock.lock(name, ttl);
7023
+ if (opts.type === "auto_extend" /* AUTO_EXTEND */) {
7024
+ const extendInIntervals = () => {
7025
+ timeout2 = setTimeout(async () => {
7026
+ lock = await lock.extend(ttl, () => opts.onExtend && opts.onExtend());
7027
+ extendInIntervals();
7028
+ }, ttl / 2);
7029
+ };
7030
+ extendInIntervals();
7031
+ }
6461
7032
  const result = await task();
6462
7033
  return { executed: true, result };
6463
7034
  } catch (e) {
@@ -6472,9 +7043,8 @@ async function doWithLock(opts, task) {
6472
7043
  throw e;
6473
7044
  }
6474
7045
  } finally {
6475
- if (lock) {
6476
- await lock.unlock();
6477
- }
7046
+ clearTimeout(timeout2);
7047
+ await lock?.unlock();
6478
7048
  }
6479
7049
  }
6480
7050
 
@@ -6731,259 +7301,6 @@ __export(invite_exports, {
6731
7301
  getInviteCodes: () => getInviteCodes,
6732
7302
  updateCode: () => updateCode
6733
7303
  });
6734
-
6735
- // src/utils/index.ts
6736
- var utils_exports2 = {};
6737
- __export(utils_exports2, {
6738
- Duration: () => Duration,
6739
- DurationType: () => DurationType,
6740
- clearCookie: () => clearCookie,
6741
- compare: () => compare,
6742
- getAppIdFromCtx: () => getAppIdFromCtx,
6743
- getCookie: () => getCookie,
6744
- hasCircularStructure: () => hasCircularStructure,
6745
- hash: () => hash,
6746
- isAudited: () => isAudited,
6747
- isClient: () => isClient,
6748
- isPublicApiRequest: () => isPublicApiRequest,
6749
- isServingApp: () => isServingApp,
6750
- isServingBuilder: () => isServingBuilder,
6751
- isServingBuilderPreview: () => isServingBuilderPreview,
6752
- isValidInternalAPIKey: () => isValidInternalAPIKey,
6753
- newid: () => newid,
6754
- openJwt: () => openJwt,
6755
- resolveAppUrl: () => resolveAppUrl,
6756
- setCookie: () => setCookie,
6757
- timeout: () => timeout,
6758
- validEmail: () => validEmail
6759
- });
6760
-
6761
- // src/utils/hashing.ts
6762
- init_environment2();
6763
- init_newid();
6764
- var bcrypt = environment_default.JS_BCRYPT ? require("bcryptjs") : require("bcrypt");
6765
- var SALT_ROUNDS = environment_default.SALT_ROUNDS || 10;
6766
- async function hash(data) {
6767
- const salt = await bcrypt.genSalt(SALT_ROUNDS);
6768
- return bcrypt.hash(data, salt);
6769
- }
6770
- async function compare(data, encrypted) {
6771
- return bcrypt.compare(data, encrypted);
6772
- }
6773
-
6774
- // src/utils/utils.ts
6775
- init_db4();
6776
- init_constants3();
6777
- init_environment2();
6778
- init_context2();
6779
- init_src();
6780
- var jwt = require("jsonwebtoken");
6781
- var APP_PREFIX2 = "app" /* APP */ + SEPARATOR;
6782
- var PROD_APP_PREFIX = "/app/";
6783
- var BUILDER_PREVIEW_PATH = "/app/preview";
6784
- var BUILDER_PREFIX = "/builder";
6785
- var BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`;
6786
- var PUBLIC_API_PREFIX = "/api/public/v";
6787
- function confirmAppId(possibleAppId) {
6788
- return possibleAppId && possibleAppId.startsWith(APP_PREFIX2) ? possibleAppId : void 0;
6789
- }
6790
- async function resolveAppUrl(ctx) {
6791
- const appUrl = ctx.path.split("/")[2];
6792
- let possibleAppUrl = `/${appUrl.toLowerCase()}`;
6793
- let tenantId = getTenantId();
6794
- if (environment_default.MULTI_TENANCY) {
6795
- tenantId = getTenantIDFromCtx(ctx, {
6796
- includeStrategies: ["subdomain" /* SUBDOMAIN */]
6797
- });
6798
- }
6799
- const apps = await doInTenant(
6800
- tenantId,
6801
- () => getAllApps({ dev: false })
6802
- );
6803
- const app = apps.filter(
6804
- (a) => a.url && a.url.toLowerCase() === possibleAppUrl
6805
- )[0];
6806
- return app && app.appId ? app.appId : void 0;
6807
- }
6808
- function isServingApp(ctx) {
6809
- if (ctx.path.startsWith(`/${APP_PREFIX2}`)) {
6810
- return true;
6811
- }
6812
- if (ctx.path.startsWith(PROD_APP_PREFIX)) {
6813
- return true;
6814
- }
6815
- return false;
6816
- }
6817
- function isServingBuilder(ctx) {
6818
- return ctx.path.startsWith(BUILDER_APP_PREFIX);
6819
- }
6820
- function isServingBuilderPreview(ctx) {
6821
- return ctx.path.startsWith(BUILDER_PREVIEW_PATH);
6822
- }
6823
- function isPublicApiRequest(ctx) {
6824
- return ctx.path.startsWith(PUBLIC_API_PREFIX);
6825
- }
6826
- async function getAppIdFromCtx(ctx) {
6827
- const options2 = [ctx.request.headers["x-budibase-app-id" /* APP_ID */]];
6828
- let appId;
6829
- for (let option of options2) {
6830
- appId = confirmAppId(option);
6831
- if (appId) {
6832
- break;
6833
- }
6834
- }
6835
- if (!appId && ctx.request.body && ctx.request.body.appId) {
6836
- appId = confirmAppId(ctx.request.body.appId);
6837
- }
6838
- const pathId = parseAppIdFromUrl(ctx.path);
6839
- if (!appId && pathId) {
6840
- appId = confirmAppId(pathId);
6841
- }
6842
- const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH);
6843
- const isViewingProdApp = ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview;
6844
- if (!appId && isViewingProdApp) {
6845
- appId = confirmAppId(await resolveAppUrl(ctx));
6846
- }
6847
- const referer = ctx.request.headers.referer;
6848
- if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
6849
- const refererId = parseAppIdFromUrl(ctx.request.headers.referer);
6850
- appId = confirmAppId(refererId);
6851
- }
6852
- return appId;
6853
- }
6854
- function parseAppIdFromUrl(url) {
6855
- if (!url) {
6856
- return;
6857
- }
6858
- return url.split("/").find((subPath) => subPath.startsWith(APP_PREFIX2));
6859
- }
6860
- function openJwt(token) {
6861
- if (!token) {
6862
- return token;
6863
- }
6864
- try {
6865
- return jwt.verify(token, environment_default.JWT_SECRET);
6866
- } catch (e) {
6867
- if (environment_default.JWT_SECRET_FALLBACK) {
6868
- return jwt.verify(token, environment_default.JWT_SECRET_FALLBACK);
6869
- } else {
6870
- throw e;
6871
- }
6872
- }
6873
- }
6874
- function isValidInternalAPIKey(apiKey) {
6875
- if (environment_default.INTERNAL_API_KEY && environment_default.INTERNAL_API_KEY === apiKey) {
6876
- return true;
6877
- }
6878
- if (environment_default.INTERNAL_API_KEY_FALLBACK && environment_default.INTERNAL_API_KEY_FALLBACK === apiKey) {
6879
- return true;
6880
- }
6881
- return false;
6882
- }
6883
- function getCookie(ctx, name) {
6884
- const cookie = ctx.cookies.get(name);
6885
- if (!cookie) {
6886
- return cookie;
6887
- }
6888
- return openJwt(cookie);
6889
- }
6890
- function setCookie(ctx, value, name = "builder", opts = { sign: true }) {
6891
- if (value && opts && opts.sign) {
6892
- value = jwt.sign(value, environment_default.JWT_SECRET);
6893
- }
6894
- const config = {
6895
- expires: MAX_VALID_DATE,
6896
- path: "/",
6897
- httpOnly: false,
6898
- overwrite: true
6899
- };
6900
- if (environment_default.COOKIE_DOMAIN) {
6901
- config.domain = environment_default.COOKIE_DOMAIN;
6902
- }
6903
- ctx.cookies.set(name, value, config);
6904
- }
6905
- function clearCookie(ctx, name) {
6906
- setCookie(ctx, null, name);
6907
- }
6908
- function isClient(ctx) {
6909
- return ctx.headers["x-budibase-type" /* TYPE */] === "client";
6910
- }
6911
- function timeout(timeMs) {
6912
- return new Promise((resolve) => setTimeout(resolve, timeMs));
6913
- }
6914
- function isAudited(event) {
6915
- return !!AuditedEventFriendlyName[event];
6916
- }
6917
- function hasCircularStructure(json) {
6918
- if (typeof json !== "object") {
6919
- return false;
6920
- }
6921
- try {
6922
- JSON.stringify(json);
6923
- } catch (err) {
6924
- if (err instanceof Error && err?.message.includes("circular structure")) {
6925
- return true;
6926
- }
6927
- }
6928
- return false;
6929
- }
6930
-
6931
- // src/utils/stringUtils.ts
6932
- function validEmail(value) {
6933
- return value && !!value.match(
6934
- /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
6935
- );
6936
- }
6937
-
6938
- // src/utils/Duration.ts
6939
- var DurationType = /* @__PURE__ */ ((DurationType4) => {
6940
- DurationType4["MILLISECONDS"] = "milliseconds";
6941
- DurationType4["SECONDS"] = "seconds";
6942
- DurationType4["MINUTES"] = "minutes";
6943
- DurationType4["HOURS"] = "hours";
6944
- DurationType4["DAYS"] = "days";
6945
- return DurationType4;
6946
- })(DurationType || {});
6947
- var conversion = {
6948
- milliseconds: 1,
6949
- seconds: 1e3,
6950
- minutes: 60 * 1e3,
6951
- hours: 60 * 60 * 1e3,
6952
- days: 24 * 60 * 60 * 1e3
6953
- };
6954
- var Duration = class _Duration {
6955
- static convert(from, to, duration) {
6956
- const milliseconds = duration * conversion[from];
6957
- return milliseconds / conversion[to];
6958
- }
6959
- static from(from, duration) {
6960
- return {
6961
- to: (to) => {
6962
- return _Duration.convert(from, to, duration);
6963
- },
6964
- toMs: () => {
6965
- return _Duration.convert(from, "milliseconds" /* MILLISECONDS */, duration);
6966
- },
6967
- toSeconds: () => {
6968
- return _Duration.convert(from, "seconds" /* SECONDS */, duration);
6969
- }
6970
- };
6971
- }
6972
- static fromSeconds(duration) {
6973
- return _Duration.from("seconds" /* SECONDS */, duration);
6974
- }
6975
- static fromMinutes(duration) {
6976
- return _Duration.from("minutes" /* MINUTES */, duration);
6977
- }
6978
- static fromHours(duration) {
6979
- return _Duration.from("hours" /* HOURS */, duration);
6980
- }
6981
- static fromDays(duration) {
6982
- return _Duration.from("days" /* DAYS */, duration);
6983
- }
6984
- };
6985
-
6986
- // src/cache/invite.ts
6987
7304
  init_environment2();
6988
7305
  init_context2();
6989
7306
  init_init();
@@ -7196,266 +7513,6 @@ var EmailUnavailableError = class extends Error {
7196
7513
 
7197
7514
  // src/users/utils.ts
7198
7515
  init_context2();
7199
-
7200
- // ../shared-core/src/constants.ts
7201
- var OperatorOptions = {
7202
- Equals: {
7203
- value: "equal",
7204
- label: "Equals"
7205
- },
7206
- NotEquals: {
7207
- value: "notEqual",
7208
- label: "Not equals"
7209
- },
7210
- Empty: {
7211
- value: "empty",
7212
- label: "Is empty"
7213
- },
7214
- NotEmpty: {
7215
- value: "notEmpty",
7216
- label: "Is not empty"
7217
- },
7218
- StartsWith: {
7219
- value: "string",
7220
- label: "Starts with"
7221
- },
7222
- Like: {
7223
- value: "fuzzy",
7224
- label: "Like"
7225
- },
7226
- MoreThan: {
7227
- value: "rangeLow",
7228
- label: "More than or equal to"
7229
- },
7230
- LessThan: {
7231
- value: "rangeHigh",
7232
- label: "Less than or equal to"
7233
- },
7234
- Contains: {
7235
- value: "contains",
7236
- label: "Contains"
7237
- },
7238
- NotContains: {
7239
- value: "notContains",
7240
- label: "Does not contain"
7241
- },
7242
- In: {
7243
- value: "oneOf",
7244
- label: "Is in"
7245
- },
7246
- ContainsAny: {
7247
- value: "containsAny",
7248
- label: "Has any"
7249
- }
7250
- };
7251
-
7252
- // ../shared-core/src/filters.ts
7253
- init_src();
7254
- var import_dayjs = __toESM(require_dayjs_min());
7255
-
7256
- // ../shared-core/src/helpers/integrations.ts
7257
- init_src();
7258
-
7259
- // ../shared-core/src/filters.ts
7260
- var NoEmptyFilterStrings = [
7261
- OperatorOptions.StartsWith.value,
7262
- OperatorOptions.Like.value,
7263
- OperatorOptions.Equals.value,
7264
- OperatorOptions.NotEquals.value,
7265
- OperatorOptions.Contains.value,
7266
- OperatorOptions.NotContains.value
7267
- ];
7268
-
7269
- // ../shared-core/src/sdk/index.ts
7270
- var sdk_exports = {};
7271
- __export(sdk_exports, {
7272
- applications: () => applications_exports,
7273
- users: () => users_exports2
7274
- });
7275
-
7276
- // ../shared-core/src/sdk/documents/applications.ts
7277
- var applications_exports = {};
7278
- __export(applications_exports, {
7279
- getDevAppID: () => getDevAppID2,
7280
- getProdAppID: () => getProdAppID2
7281
- });
7282
- init_src();
7283
- var APP_PREFIX3 = prefixed("app" /* APP */);
7284
- var APP_DEV_PREFIX2 = prefixed("app_dev" /* APP_DEV */);
7285
- function getDevAppID2(appId) {
7286
- if (!appId) {
7287
- throw new Error("No app ID provided");
7288
- }
7289
- if (appId.startsWith(APP_DEV_PREFIX2)) {
7290
- return appId;
7291
- }
7292
- const split = appId.split(APP_PREFIX3);
7293
- split.shift();
7294
- const rest = split.join(APP_PREFIX3);
7295
- return `${APP_DEV_PREFIX2}${rest}`;
7296
- }
7297
- function getProdAppID2(appId) {
7298
- if (!appId) {
7299
- throw new Error("No app ID provided");
7300
- }
7301
- if (!appId.startsWith(APP_DEV_PREFIX2)) {
7302
- return appId;
7303
- }
7304
- const split = appId.split(APP_DEV_PREFIX2);
7305
- split.shift();
7306
- const rest = split.join(APP_DEV_PREFIX2);
7307
- return `${APP_PREFIX3}${rest}`;
7308
- }
7309
-
7310
- // ../shared-core/src/sdk/documents/users.ts
7311
- var users_exports2 = {};
7312
- __export(users_exports2, {
7313
- canCreateApps: () => canCreateApps,
7314
- containsUserID: () => containsUserID,
7315
- getGlobalUserID: () => getGlobalUserID,
7316
- hasAdminPermissions: () => hasAdminPermissions,
7317
- hasAppBuilderPermissions: () => hasAppBuilderPermissions,
7318
- hasAppCreatorPermissions: () => hasAppCreatorPermissions,
7319
- hasBuilderPermissions: () => hasBuilderPermissions,
7320
- hasCreatorPermissions: () => hasCreatorPermissions,
7321
- isAdmin: () => isAdmin,
7322
- isAdminOrBuilder: () => isAdminOrBuilder,
7323
- isAdminOrGlobalBuilder: () => isAdminOrGlobalBuilder,
7324
- isBuilder: () => isBuilder,
7325
- isCreator: () => isCreator,
7326
- isGlobalBuilder: () => isGlobalBuilder
7327
- });
7328
- init_src();
7329
- var _ = __toESM(require("lodash/fp"));
7330
- function isBuilder(user, appId) {
7331
- if (!user) {
7332
- return false;
7333
- }
7334
- if (user.builder?.global) {
7335
- return true;
7336
- } else if (appId && user.builder?.apps?.includes(getProdAppID2(appId))) {
7337
- return true;
7338
- }
7339
- return false;
7340
- }
7341
- function isGlobalBuilder(user) {
7342
- return isBuilder(user) && !hasAppBuilderPermissions(user) || isAdmin(user);
7343
- }
7344
- function canCreateApps(user) {
7345
- return isGlobalBuilder(user) || hasCreatorPermissions(user);
7346
- }
7347
- function isAdmin(user) {
7348
- if (!user) {
7349
- return false;
7350
- }
7351
- return hasAdminPermissions(user);
7352
- }
7353
- function isAdminOrBuilder(user, appId) {
7354
- return isBuilder(user, appId) || isAdmin(user);
7355
- }
7356
- function isAdminOrGlobalBuilder(user, appId) {
7357
- return isGlobalBuilder(user) || isAdmin(user);
7358
- }
7359
- function hasAppBuilderPermissions(user) {
7360
- if (!user) {
7361
- return false;
7362
- }
7363
- const appLength = user.builder?.apps?.length;
7364
- const isGlobalBuilder3 = !!user.builder?.global;
7365
- return !isGlobalBuilder3 && appLength != null && appLength > 0;
7366
- }
7367
- function hasAppCreatorPermissions(user) {
7368
- if (!user) {
7369
- return false;
7370
- }
7371
- return _.flow(
7372
- _.get("roles"),
7373
- _.values,
7374
- _.find((x) => x === "CREATOR"),
7375
- (x) => !!x
7376
- )(user);
7377
- }
7378
- function hasBuilderPermissions(user) {
7379
- if (!user) {
7380
- return false;
7381
- }
7382
- return user.builder?.global || hasAppBuilderPermissions(user) || hasCreatorPermissions(user);
7383
- }
7384
- function hasAdminPermissions(user) {
7385
- if (!user) {
7386
- return false;
7387
- }
7388
- return !!user.admin?.global;
7389
- }
7390
- function hasCreatorPermissions(user) {
7391
- if (!user) {
7392
- return false;
7393
- }
7394
- return !!user.builder?.creator;
7395
- }
7396
- function isCreator(user) {
7397
- if (!user) {
7398
- return false;
7399
- }
7400
- return isGlobalBuilder(user) || hasAdminPermissions(user) || hasCreatorPermissions(user) || hasAppBuilderPermissions(user) || hasAppCreatorPermissions(user);
7401
- }
7402
- function getGlobalUserID(userId) {
7403
- if (typeof userId !== "string") {
7404
- return userId;
7405
- }
7406
- const prefix = `${"ro" /* ROW */}${SEPARATOR}${"ta_users" /* USER_METADATA */}${SEPARATOR}`;
7407
- if (!userId.startsWith(prefix)) {
7408
- return userId;
7409
- }
7410
- return userId.split(prefix)[1];
7411
- }
7412
- function containsUserID(value) {
7413
- if (typeof value !== "string") {
7414
- return false;
7415
- }
7416
- return value.includes(`${"us" /* USER */}${SEPARATOR}`);
7417
- }
7418
-
7419
- // ../shared-core/src/table.ts
7420
- init_src();
7421
- var allowDisplayColumnByType = {
7422
- ["string" /* STRING */]: true,
7423
- ["longform" /* LONGFORM */]: true,
7424
- ["options" /* OPTIONS */]: true,
7425
- ["number" /* NUMBER */]: true,
7426
- ["datetime" /* DATETIME */]: true,
7427
- ["formula" /* FORMULA */]: true,
7428
- ["auto" /* AUTO */]: true,
7429
- ["internal" /* INTERNAL */]: true,
7430
- ["barcodeqr" /* BARCODEQR */]: true,
7431
- ["bigint" /* BIGINT */]: true,
7432
- ["boolean" /* BOOLEAN */]: false,
7433
- ["array" /* ARRAY */]: false,
7434
- ["attachment" /* ATTACHMENT */]: false,
7435
- ["link" /* LINK */]: false,
7436
- ["json" /* JSON */]: false,
7437
- ["bb_reference" /* BB_REFERENCE */]: false
7438
- };
7439
- var allowSortColumnByType = {
7440
- ["string" /* STRING */]: true,
7441
- ["longform" /* LONGFORM */]: true,
7442
- ["options" /* OPTIONS */]: true,
7443
- ["number" /* NUMBER */]: true,
7444
- ["datetime" /* DATETIME */]: true,
7445
- ["auto" /* AUTO */]: true,
7446
- ["internal" /* INTERNAL */]: true,
7447
- ["barcodeqr" /* BARCODEQR */]: true,
7448
- ["bigint" /* BIGINT */]: true,
7449
- ["boolean" /* BOOLEAN */]: true,
7450
- ["json" /* JSON */]: true,
7451
- ["formula" /* FORMULA */]: false,
7452
- ["attachment" /* ATTACHMENT */]: false,
7453
- ["array" /* ARRAY */]: false,
7454
- ["link" /* LINK */]: false,
7455
- ["bb_reference" /* BB_REFERENCE */]: false
7456
- };
7457
-
7458
- // src/users/utils.ts
7459
7516
  var isBuilder2 = sdk_exports.users.isBuilder;
7460
7517
  var isAdmin2 = sdk_exports.users.isAdmin;
7461
7518
  var isCreator2 = sdk_exports.users.isCreator;