@budibase/backend-core 2.32.6 → 2.32.8
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 +446 -409
- package/dist/index.js.map +4 -4
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +4 -4
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/cache/appMetadata.js +3 -3
- package/dist/src/cache/appMetadata.js.map +1 -1
- package/dist/src/configs/configs.d.ts +2 -1
- package/dist/src/configs/configs.js +7 -0
- package/dist/src/configs/configs.js.map +1 -1
- package/dist/src/db/couch/DatabaseImpl.d.ts +1 -0
- package/dist/src/db/couch/DatabaseImpl.js +35 -5
- package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
- package/dist/src/features/index.js +2 -1
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/sql/sql.js +29 -21
- package/dist/src/sql/sql.js.map +1 -1
- package/dist/src/sql/sqlTable.d.ts +3 -0
- package/dist/src/sql/sqlTable.js +9 -1
- package/dist/src/sql/sqlTable.js.map +1 -1
- package/dist/tests/core/utilities/mocks/licenses.d.ts +0 -1
- package/dist/tests/core/utilities/mocks/licenses.js +1 -5
- package/dist/tests/core/utilities/mocks/licenses.js.map +1 -1
- package/package.json +4 -4
- package/src/cache/appMetadata.ts +3 -3
- package/src/configs/configs.ts +7 -0
- package/src/db/couch/DatabaseImpl.ts +35 -6
- package/src/features/index.ts +2 -0
- package/src/sql/sql.ts +43 -31
- package/src/sql/sqlTable.ts +12 -1
- package/tests/core/utilities/mocks/licenses.ts +0 -4
package/dist/index.js
CHANGED
|
@@ -54228,6 +54228,7 @@ var configs_exports = {};
|
|
|
54228
54228
|
__export(configs_exports, {
|
|
54229
54229
|
analyticsEnabled: () => analyticsEnabled,
|
|
54230
54230
|
generateConfigID: () => generateConfigID,
|
|
54231
|
+
getAIConfig: () => getAIConfig,
|
|
54231
54232
|
getConfig: () => getConfig,
|
|
54232
54233
|
getDefaultGoogleConfig: () => getDefaultGoogleConfig,
|
|
54233
54234
|
getGoogleConfig: () => getGoogleConfig,
|
|
@@ -58452,6 +58453,7 @@ var AppState = /* @__PURE__ */ ((AppState2) => {
|
|
|
58452
58453
|
return AppState2;
|
|
58453
58454
|
})(AppState || {});
|
|
58454
58455
|
var EXPIRY_SECONDS = 3600;
|
|
58456
|
+
var INVALID_EXPIRY_SECONDS = 60;
|
|
58455
58457
|
async function populateFromDB(appId) {
|
|
58456
58458
|
return doWithDB(
|
|
58457
58459
|
appId,
|
|
@@ -58474,7 +58476,7 @@ async function getAppMetadata(appId) {
|
|
|
58474
58476
|
} catch (err) {
|
|
58475
58477
|
if (err && err.status === 404) {
|
|
58476
58478
|
metadata = { state: "invalid" /* INVALID */ };
|
|
58477
|
-
expiry =
|
|
58479
|
+
expiry = INVALID_EXPIRY_SECONDS;
|
|
58478
58480
|
} else {
|
|
58479
58481
|
throw err;
|
|
58480
58482
|
}
|
|
@@ -59814,6 +59816,385 @@ __export(features_exports, {
|
|
|
59814
59816
|
});
|
|
59815
59817
|
var import_posthog_node = require("posthog-node");
|
|
59816
59818
|
var import_dd_trace3 = __toESM(require("dd-trace"));
|
|
59819
|
+
|
|
59820
|
+
// src/utils/index.ts
|
|
59821
|
+
var utils_exports4 = {};
|
|
59822
|
+
__export(utils_exports4, {
|
|
59823
|
+
Duration: () => Duration,
|
|
59824
|
+
DurationType: () => DurationType,
|
|
59825
|
+
clearCookie: () => clearCookie,
|
|
59826
|
+
compare: () => compare,
|
|
59827
|
+
getAppIdFromCtx: () => getAppIdFromCtx,
|
|
59828
|
+
getCookie: () => getCookie,
|
|
59829
|
+
hasCircularStructure: () => hasCircularStructure,
|
|
59830
|
+
hash: () => hash,
|
|
59831
|
+
isAudited: () => isAudited,
|
|
59832
|
+
isClient: () => isClient,
|
|
59833
|
+
isPublicApiRequest: () => isPublicApiRequest,
|
|
59834
|
+
isServingApp: () => isServingApp,
|
|
59835
|
+
isServingBuilder: () => isServingBuilder,
|
|
59836
|
+
isServingBuilderPreview: () => isServingBuilderPreview,
|
|
59837
|
+
isValidInternalAPIKey: () => isValidInternalAPIKey,
|
|
59838
|
+
newid: () => newid,
|
|
59839
|
+
openJwt: () => openJwt,
|
|
59840
|
+
resolveAppUrl: () => resolveAppUrl,
|
|
59841
|
+
setCookie: () => setCookie,
|
|
59842
|
+
timeout: () => timeout,
|
|
59843
|
+
validEmail: () => validEmail
|
|
59844
|
+
});
|
|
59845
|
+
|
|
59846
|
+
// src/utils/hashing.ts
|
|
59847
|
+
var bcrypt = environment_default.JS_BCRYPT ? require("bcryptjs") : require("bcrypt");
|
|
59848
|
+
var SALT_ROUNDS = environment_default.SALT_ROUNDS || 10;
|
|
59849
|
+
async function hash(data) {
|
|
59850
|
+
const salt = await bcrypt.genSalt(SALT_ROUNDS);
|
|
59851
|
+
return bcrypt.hash(data, salt);
|
|
59852
|
+
}
|
|
59853
|
+
async function compare(data, encrypted) {
|
|
59854
|
+
return bcrypt.compare(data, encrypted);
|
|
59855
|
+
}
|
|
59856
|
+
|
|
59857
|
+
// src/tenancy/index.ts
|
|
59858
|
+
var tenancy_exports = {};
|
|
59859
|
+
__export(tenancy_exports, {
|
|
59860
|
+
addTenantToUrl: () => addTenantToUrl,
|
|
59861
|
+
getTenantDB: () => getTenantDB,
|
|
59862
|
+
getTenantIDFromCtx: () => getTenantIDFromCtx,
|
|
59863
|
+
getTenantInfo: () => getTenantInfo,
|
|
59864
|
+
isUserInAppTenant: () => isUserInAppTenant,
|
|
59865
|
+
saveTenantInfo: () => saveTenantInfo
|
|
59866
|
+
});
|
|
59867
|
+
|
|
59868
|
+
// src/tenancy/db.ts
|
|
59869
|
+
function getTenantDB(tenantId) {
|
|
59870
|
+
return getDB(getGlobalDBName(tenantId));
|
|
59871
|
+
}
|
|
59872
|
+
async function saveTenantInfo(tenantInfo) {
|
|
59873
|
+
const db = getTenantDB(tenantInfo.tenantId);
|
|
59874
|
+
return db.put({
|
|
59875
|
+
_id: "tenant_info",
|
|
59876
|
+
...tenantInfo
|
|
59877
|
+
});
|
|
59878
|
+
}
|
|
59879
|
+
async function getTenantInfo(tenantId) {
|
|
59880
|
+
try {
|
|
59881
|
+
const db = getTenantDB(tenantId);
|
|
59882
|
+
const tenantInfo = await db.get("tenant_info");
|
|
59883
|
+
delete tenantInfo.owner.password;
|
|
59884
|
+
return tenantInfo;
|
|
59885
|
+
} catch {
|
|
59886
|
+
return void 0;
|
|
59887
|
+
}
|
|
59888
|
+
}
|
|
59889
|
+
|
|
59890
|
+
// src/tenancy/tenancy.ts
|
|
59891
|
+
function addTenantToUrl(url) {
|
|
59892
|
+
const tenantId = getTenantId();
|
|
59893
|
+
if (isMultiTenant()) {
|
|
59894
|
+
const char = url.indexOf("?") === -1 ? "?" : "&";
|
|
59895
|
+
url += `${char}tenantId=${tenantId}`;
|
|
59896
|
+
}
|
|
59897
|
+
return url;
|
|
59898
|
+
}
|
|
59899
|
+
var isUserInAppTenant = (appId, user) => {
|
|
59900
|
+
let userTenantId;
|
|
59901
|
+
if (user) {
|
|
59902
|
+
userTenantId = user.tenantId || DEFAULT_TENANT_ID;
|
|
59903
|
+
} else {
|
|
59904
|
+
userTenantId = getTenantId();
|
|
59905
|
+
}
|
|
59906
|
+
const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID;
|
|
59907
|
+
return tenantId === userTenantId;
|
|
59908
|
+
};
|
|
59909
|
+
var ALL_STRATEGIES = Object.values(TenantResolutionStrategy);
|
|
59910
|
+
var getTenantIDFromCtx = (ctx, opts) => {
|
|
59911
|
+
if (!isMultiTenant()) {
|
|
59912
|
+
return DEFAULT_TENANT_ID;
|
|
59913
|
+
}
|
|
59914
|
+
if (opts.allowNoTenant === void 0) {
|
|
59915
|
+
opts.allowNoTenant = false;
|
|
59916
|
+
}
|
|
59917
|
+
if (!opts.includeStrategies) {
|
|
59918
|
+
opts.includeStrategies = ALL_STRATEGIES;
|
|
59919
|
+
}
|
|
59920
|
+
if (!opts.excludeStrategies) {
|
|
59921
|
+
opts.excludeStrategies = [];
|
|
59922
|
+
}
|
|
59923
|
+
const isAllowed = (strategy) => {
|
|
59924
|
+
if (opts.excludeStrategies?.includes(strategy)) {
|
|
59925
|
+
return false;
|
|
59926
|
+
}
|
|
59927
|
+
if (opts.includeStrategies?.includes(strategy)) {
|
|
59928
|
+
return true;
|
|
59929
|
+
}
|
|
59930
|
+
};
|
|
59931
|
+
if (isAllowed("user" /* USER */)) {
|
|
59932
|
+
const userTenantId = ctx.user?.tenantId;
|
|
59933
|
+
if (userTenantId) {
|
|
59934
|
+
return userTenantId;
|
|
59935
|
+
}
|
|
59936
|
+
}
|
|
59937
|
+
if (isAllowed("header" /* HEADER */)) {
|
|
59938
|
+
const headerTenantId = ctx.request.headers["x-budibase-tenant-id" /* TENANT_ID */];
|
|
59939
|
+
if (headerTenantId) {
|
|
59940
|
+
return headerTenantId;
|
|
59941
|
+
}
|
|
59942
|
+
}
|
|
59943
|
+
if (isAllowed("query" /* QUERY */)) {
|
|
59944
|
+
const queryTenantId = ctx.request.query.tenantId;
|
|
59945
|
+
if (queryTenantId) {
|
|
59946
|
+
return queryTenantId;
|
|
59947
|
+
}
|
|
59948
|
+
}
|
|
59949
|
+
if (isAllowed("subdomain" /* SUBDOMAIN */)) {
|
|
59950
|
+
let platformHost;
|
|
59951
|
+
try {
|
|
59952
|
+
platformHost = new URL(getPlatformURL()).host.split(":")[0];
|
|
59953
|
+
} catch (err) {
|
|
59954
|
+
if (err.code !== "ERR_INVALID_URL") {
|
|
59955
|
+
throw err;
|
|
59956
|
+
}
|
|
59957
|
+
}
|
|
59958
|
+
const requestHost = ctx.host;
|
|
59959
|
+
if (platformHost && requestHost.includes(platformHost)) {
|
|
59960
|
+
const tenantId = requestHost.substring(
|
|
59961
|
+
0,
|
|
59962
|
+
requestHost.indexOf(`.${platformHost}`)
|
|
59963
|
+
);
|
|
59964
|
+
if (tenantId) {
|
|
59965
|
+
return tenantId;
|
|
59966
|
+
}
|
|
59967
|
+
}
|
|
59968
|
+
}
|
|
59969
|
+
if (isAllowed("path" /* PATH */)) {
|
|
59970
|
+
const match = ctx.matched.find(
|
|
59971
|
+
(m) => !!m.paramNames.find((p) => p.name === "tenantId")
|
|
59972
|
+
);
|
|
59973
|
+
const ctxUrl = ctx.originalUrl;
|
|
59974
|
+
let url;
|
|
59975
|
+
if (ctxUrl.includes("?")) {
|
|
59976
|
+
url = ctxUrl.split("?")[0];
|
|
59977
|
+
} else {
|
|
59978
|
+
url = ctxUrl;
|
|
59979
|
+
}
|
|
59980
|
+
if (match) {
|
|
59981
|
+
const params2 = match.params(url, match.captures(url), {});
|
|
59982
|
+
if (params2.tenantId) {
|
|
59983
|
+
return params2.tenantId;
|
|
59984
|
+
}
|
|
59985
|
+
}
|
|
59986
|
+
}
|
|
59987
|
+
if (!opts.allowNoTenant) {
|
|
59988
|
+
ctx.throw(403, "Tenant id not set");
|
|
59989
|
+
}
|
|
59990
|
+
return void 0;
|
|
59991
|
+
};
|
|
59992
|
+
|
|
59993
|
+
// src/utils/utils.ts
|
|
59994
|
+
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
59995
|
+
var APP_PREFIX3 = "app" /* APP */ + SEPARATOR;
|
|
59996
|
+
var PROD_APP_PREFIX = "/app/";
|
|
59997
|
+
var BUILDER_PREVIEW_PATH = "/app/preview";
|
|
59998
|
+
var BUILDER_PREFIX = "/builder";
|
|
59999
|
+
var BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`;
|
|
60000
|
+
var PUBLIC_API_PREFIX = "/api/public/v";
|
|
60001
|
+
function confirmAppId(possibleAppId) {
|
|
60002
|
+
return possibleAppId && possibleAppId.startsWith(APP_PREFIX3) ? possibleAppId : void 0;
|
|
60003
|
+
}
|
|
60004
|
+
async function resolveAppUrl(ctx) {
|
|
60005
|
+
const appUrl = ctx.path.split("/")[2];
|
|
60006
|
+
let possibleAppUrl = `/${appUrl.toLowerCase()}`;
|
|
60007
|
+
let tenantId = getTenantId();
|
|
60008
|
+
if (!environment_default.isDev() && environment_default.MULTI_TENANCY) {
|
|
60009
|
+
tenantId = getTenantIDFromCtx(ctx, {
|
|
60010
|
+
includeStrategies: ["subdomain" /* SUBDOMAIN */]
|
|
60011
|
+
});
|
|
60012
|
+
}
|
|
60013
|
+
const apps = await doInTenant(
|
|
60014
|
+
tenantId,
|
|
60015
|
+
() => getAllApps({ dev: false })
|
|
60016
|
+
);
|
|
60017
|
+
const app = apps.filter(
|
|
60018
|
+
(a) => a.url && a.url.toLowerCase() === possibleAppUrl
|
|
60019
|
+
)[0];
|
|
60020
|
+
return app && app.appId ? app.appId : void 0;
|
|
60021
|
+
}
|
|
60022
|
+
function isServingApp(ctx) {
|
|
60023
|
+
if (ctx.path.startsWith(`/${APP_PREFIX3}`)) {
|
|
60024
|
+
return true;
|
|
60025
|
+
}
|
|
60026
|
+
return ctx.path.startsWith(PROD_APP_PREFIX);
|
|
60027
|
+
}
|
|
60028
|
+
function isServingBuilder(ctx) {
|
|
60029
|
+
return ctx.path.startsWith(BUILDER_APP_PREFIX);
|
|
60030
|
+
}
|
|
60031
|
+
function isServingBuilderPreview(ctx) {
|
|
60032
|
+
return ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
60033
|
+
}
|
|
60034
|
+
function isPublicApiRequest(ctx) {
|
|
60035
|
+
return ctx.path.startsWith(PUBLIC_API_PREFIX);
|
|
60036
|
+
}
|
|
60037
|
+
async function getAppIdFromCtx(ctx) {
|
|
60038
|
+
const options2 = [ctx.request.headers["x-budibase-app-id" /* APP_ID */]];
|
|
60039
|
+
let appId;
|
|
60040
|
+
for (let option of options2) {
|
|
60041
|
+
appId = confirmAppId(option);
|
|
60042
|
+
if (appId) {
|
|
60043
|
+
break;
|
|
60044
|
+
}
|
|
60045
|
+
}
|
|
60046
|
+
if (!appId && ctx.request.body && ctx.request.body.appId) {
|
|
60047
|
+
appId = confirmAppId(ctx.request.body.appId);
|
|
60048
|
+
}
|
|
60049
|
+
const pathId = parseAppIdFromUrlPath(ctx.path);
|
|
60050
|
+
if (!appId && pathId) {
|
|
60051
|
+
appId = confirmAppId(pathId);
|
|
60052
|
+
}
|
|
60053
|
+
const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
60054
|
+
const isViewingProdApp = ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview;
|
|
60055
|
+
if (!appId && isViewingProdApp) {
|
|
60056
|
+
appId = confirmAppId(await resolveAppUrl(ctx));
|
|
60057
|
+
}
|
|
60058
|
+
const referer = ctx.request.headers.referer;
|
|
60059
|
+
if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
|
|
60060
|
+
const refererId = parseAppIdFromUrlPath(ctx.request.headers.referer);
|
|
60061
|
+
appId = confirmAppId(refererId);
|
|
60062
|
+
}
|
|
60063
|
+
return appId;
|
|
60064
|
+
}
|
|
60065
|
+
function parseAppIdFromUrlPath(url) {
|
|
60066
|
+
if (!url) {
|
|
60067
|
+
return;
|
|
60068
|
+
}
|
|
60069
|
+
return url.split("?")[0].split("/").find((subPath) => subPath.startsWith(APP_PREFIX3));
|
|
60070
|
+
}
|
|
60071
|
+
function openJwt(token) {
|
|
60072
|
+
if (!token) {
|
|
60073
|
+
return void 0;
|
|
60074
|
+
}
|
|
60075
|
+
try {
|
|
60076
|
+
return import_jsonwebtoken.default.verify(token, environment_default.JWT_SECRET);
|
|
60077
|
+
} catch (e) {
|
|
60078
|
+
if (environment_default.JWT_SECRET_FALLBACK) {
|
|
60079
|
+
return import_jsonwebtoken.default.verify(token, environment_default.JWT_SECRET_FALLBACK);
|
|
60080
|
+
} else {
|
|
60081
|
+
throw e;
|
|
60082
|
+
}
|
|
60083
|
+
}
|
|
60084
|
+
}
|
|
60085
|
+
function isValidInternalAPIKey(apiKey) {
|
|
60086
|
+
if (environment_default.INTERNAL_API_KEY && environment_default.INTERNAL_API_KEY === apiKey) {
|
|
60087
|
+
return true;
|
|
60088
|
+
}
|
|
60089
|
+
return !!(environment_default.INTERNAL_API_KEY_FALLBACK && environment_default.INTERNAL_API_KEY_FALLBACK === apiKey);
|
|
60090
|
+
}
|
|
60091
|
+
function getCookie(ctx, name) {
|
|
60092
|
+
const cookie = ctx.cookies.get(name);
|
|
60093
|
+
if (!cookie) {
|
|
60094
|
+
return void 0;
|
|
60095
|
+
}
|
|
60096
|
+
return openJwt(cookie);
|
|
60097
|
+
}
|
|
60098
|
+
function setCookie(ctx, value, name = "builder", opts = { sign: true }) {
|
|
60099
|
+
if (value && opts && opts.sign) {
|
|
60100
|
+
value = import_jsonwebtoken.default.sign(value, environment_default.JWT_SECRET);
|
|
60101
|
+
}
|
|
60102
|
+
const config = {
|
|
60103
|
+
expires: MAX_VALID_DATE,
|
|
60104
|
+
path: "/",
|
|
60105
|
+
httpOnly: false,
|
|
60106
|
+
overwrite: true
|
|
60107
|
+
};
|
|
60108
|
+
if (environment_default.COOKIE_DOMAIN) {
|
|
60109
|
+
config.domain = environment_default.COOKIE_DOMAIN;
|
|
60110
|
+
}
|
|
60111
|
+
ctx.cookies.set(name, value, config);
|
|
60112
|
+
}
|
|
60113
|
+
function clearCookie(ctx, name) {
|
|
60114
|
+
setCookie(ctx, null, name);
|
|
60115
|
+
}
|
|
60116
|
+
function isClient(ctx) {
|
|
60117
|
+
return ctx.headers["x-budibase-type" /* TYPE */] === "client";
|
|
60118
|
+
}
|
|
60119
|
+
function timeout(timeMs) {
|
|
60120
|
+
return new Promise((resolve) => setTimeout(resolve, timeMs));
|
|
60121
|
+
}
|
|
60122
|
+
function isAudited(event) {
|
|
60123
|
+
return !!AuditedEventFriendlyName[event];
|
|
60124
|
+
}
|
|
60125
|
+
function hasCircularStructure(json) {
|
|
60126
|
+
if (typeof json !== "object") {
|
|
60127
|
+
return false;
|
|
60128
|
+
}
|
|
60129
|
+
try {
|
|
60130
|
+
JSON.stringify(json);
|
|
60131
|
+
} catch (err) {
|
|
60132
|
+
if (err instanceof Error && err?.message.includes("circular structure")) {
|
|
60133
|
+
return true;
|
|
60134
|
+
}
|
|
60135
|
+
}
|
|
60136
|
+
return false;
|
|
60137
|
+
}
|
|
60138
|
+
|
|
60139
|
+
// src/utils/stringUtils.ts
|
|
60140
|
+
function validEmail(value) {
|
|
60141
|
+
return value && !!value.match(
|
|
60142
|
+
/^(([^<>()[\]\\.,;:\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,}))$/
|
|
60143
|
+
);
|
|
60144
|
+
}
|
|
60145
|
+
|
|
60146
|
+
// src/utils/Duration.ts
|
|
60147
|
+
var DurationType = /* @__PURE__ */ ((DurationType2) => {
|
|
60148
|
+
DurationType2["MILLISECONDS"] = "milliseconds";
|
|
60149
|
+
DurationType2["SECONDS"] = "seconds";
|
|
60150
|
+
DurationType2["MINUTES"] = "minutes";
|
|
60151
|
+
DurationType2["HOURS"] = "hours";
|
|
60152
|
+
DurationType2["DAYS"] = "days";
|
|
60153
|
+
return DurationType2;
|
|
60154
|
+
})(DurationType || {});
|
|
60155
|
+
var conversion = {
|
|
60156
|
+
milliseconds: 1,
|
|
60157
|
+
seconds: 1e3,
|
|
60158
|
+
minutes: 60 * 1e3,
|
|
60159
|
+
hours: 60 * 60 * 1e3,
|
|
60160
|
+
days: 24 * 60 * 60 * 1e3
|
|
60161
|
+
};
|
|
60162
|
+
var Duration = class _Duration {
|
|
60163
|
+
static convert(from, to, duration) {
|
|
60164
|
+
const milliseconds = duration * conversion[from];
|
|
60165
|
+
return milliseconds / conversion[to];
|
|
60166
|
+
}
|
|
60167
|
+
static from(from, duration) {
|
|
60168
|
+
return {
|
|
60169
|
+
to: (to) => {
|
|
60170
|
+
return _Duration.convert(from, to, duration);
|
|
60171
|
+
},
|
|
60172
|
+
toMs: () => {
|
|
60173
|
+
return _Duration.convert(from, "milliseconds" /* MILLISECONDS */, duration);
|
|
60174
|
+
},
|
|
60175
|
+
toSeconds: () => {
|
|
60176
|
+
return _Duration.convert(from, "seconds" /* SECONDS */, duration);
|
|
60177
|
+
}
|
|
60178
|
+
};
|
|
60179
|
+
}
|
|
60180
|
+
static fromSeconds(duration) {
|
|
60181
|
+
return _Duration.from("seconds" /* SECONDS */, duration);
|
|
60182
|
+
}
|
|
60183
|
+
static fromMinutes(duration) {
|
|
60184
|
+
return _Duration.from("minutes" /* MINUTES */, duration);
|
|
60185
|
+
}
|
|
60186
|
+
static fromHours(duration) {
|
|
60187
|
+
return _Duration.from("hours" /* HOURS */, duration);
|
|
60188
|
+
}
|
|
60189
|
+
static fromDays(duration) {
|
|
60190
|
+
return _Duration.from("days" /* DAYS */, duration);
|
|
60191
|
+
}
|
|
60192
|
+
static fromMilliseconds(duration) {
|
|
60193
|
+
return _Duration.from("milliseconds" /* MILLISECONDS */, duration);
|
|
60194
|
+
}
|
|
60195
|
+
};
|
|
60196
|
+
|
|
60197
|
+
// src/features/index.ts
|
|
59817
60198
|
var posthog;
|
|
59818
60199
|
function init4(opts) {
|
|
59819
60200
|
if (environment_default.POSTHOG_TOKEN && environment_default.POSTHOG_API_HOST && !environment_default.SELF_HOSTED && environment_default.POSTHOG_FEATURE_FLAGS_ENABLED) {
|
|
@@ -59821,6 +60202,7 @@ function init4(opts) {
|
|
|
59821
60202
|
posthog = new import_posthog_node.PostHog(environment_default.POSTHOG_TOKEN, {
|
|
59822
60203
|
host: environment_default.POSTHOG_API_HOST,
|
|
59823
60204
|
personalApiKey: environment_default.POSTHOG_PERSONAL_TOKEN,
|
|
60205
|
+
featureFlagsPollingInterval: Duration.fromMinutes(3).toMs(),
|
|
59824
60206
|
...opts
|
|
59825
60207
|
});
|
|
59826
60208
|
} else {
|
|
@@ -60097,7 +60479,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60097
60479
|
return this.getDb();
|
|
60098
60480
|
}
|
|
60099
60481
|
// this function fetches the DB and handles if DB creation is needed
|
|
60100
|
-
async
|
|
60482
|
+
async performCallWithDBCreation(call) {
|
|
60101
60483
|
const db = this.getDb();
|
|
60102
60484
|
const fnc = await call(db);
|
|
60103
60485
|
try {
|
|
@@ -60105,11 +60487,20 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60105
60487
|
} catch (err) {
|
|
60106
60488
|
if (err.statusCode === 404 && err.reason === DATABASE_NOT_FOUND) {
|
|
60107
60489
|
await this.checkAndCreateDb();
|
|
60108
|
-
return await this.
|
|
60490
|
+
return await this.performCallWithDBCreation(call);
|
|
60109
60491
|
}
|
|
60110
60492
|
throw new CouchDBError(`CouchDB error: ${err.message}`, err);
|
|
60111
60493
|
}
|
|
60112
60494
|
}
|
|
60495
|
+
async performCall(call) {
|
|
60496
|
+
const db = this.getDb();
|
|
60497
|
+
const fnc = await call(db);
|
|
60498
|
+
try {
|
|
60499
|
+
return await fnc();
|
|
60500
|
+
} catch (err) {
|
|
60501
|
+
throw new CouchDBError(`CouchDB error: ${err.message}`, err);
|
|
60502
|
+
}
|
|
60503
|
+
}
|
|
60113
60504
|
async get(id) {
|
|
60114
60505
|
return this.performCall((db) => {
|
|
60115
60506
|
if (!id) {
|
|
@@ -60193,7 +60584,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60193
60584
|
if (!document._id) {
|
|
60194
60585
|
throw new Error("Cannot store document without _id field.");
|
|
60195
60586
|
}
|
|
60196
|
-
return this.
|
|
60587
|
+
return this.performCallWithDBCreation(async (db) => {
|
|
60197
60588
|
if (!document.createdAt) {
|
|
60198
60589
|
document.createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
60199
60590
|
}
|
|
@@ -60215,7 +60606,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60215
60606
|
}
|
|
60216
60607
|
async bulkDocs(documents) {
|
|
60217
60608
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
60218
|
-
return this.
|
|
60609
|
+
return this.performCallWithDBCreation((db) => {
|
|
60219
60610
|
return () => db.bulk({
|
|
60220
60611
|
docs: documents.map((d) => ({ createdAt: now, ...d, updatedAt: now }))
|
|
60221
60612
|
});
|
|
@@ -60223,7 +60614,21 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
60223
60614
|
}
|
|
60224
60615
|
async allDocs(params2) {
|
|
60225
60616
|
return this.performCall((db) => {
|
|
60226
|
-
return () =>
|
|
60617
|
+
return async () => {
|
|
60618
|
+
try {
|
|
60619
|
+
return await db.list(params2);
|
|
60620
|
+
} catch (err) {
|
|
60621
|
+
if (err.reason === DATABASE_NOT_FOUND) {
|
|
60622
|
+
return {
|
|
60623
|
+
offset: 0,
|
|
60624
|
+
total_rows: 0,
|
|
60625
|
+
rows: []
|
|
60626
|
+
};
|
|
60627
|
+
} else {
|
|
60628
|
+
throw err;
|
|
60629
|
+
}
|
|
60630
|
+
}
|
|
60631
|
+
};
|
|
60227
60632
|
});
|
|
60228
60633
|
}
|
|
60229
60634
|
async _sqlQuery(url, method, body2) {
|
|
@@ -60786,142 +61191,6 @@ __export(user_exports, {
|
|
|
60786
61191
|
invalidateUser: () => invalidateUser
|
|
60787
61192
|
});
|
|
60788
61193
|
|
|
60789
|
-
// src/tenancy/index.ts
|
|
60790
|
-
var tenancy_exports = {};
|
|
60791
|
-
__export(tenancy_exports, {
|
|
60792
|
-
addTenantToUrl: () => addTenantToUrl,
|
|
60793
|
-
getTenantDB: () => getTenantDB,
|
|
60794
|
-
getTenantIDFromCtx: () => getTenantIDFromCtx,
|
|
60795
|
-
getTenantInfo: () => getTenantInfo,
|
|
60796
|
-
isUserInAppTenant: () => isUserInAppTenant,
|
|
60797
|
-
saveTenantInfo: () => saveTenantInfo
|
|
60798
|
-
});
|
|
60799
|
-
|
|
60800
|
-
// src/tenancy/db.ts
|
|
60801
|
-
function getTenantDB(tenantId) {
|
|
60802
|
-
return getDB(getGlobalDBName(tenantId));
|
|
60803
|
-
}
|
|
60804
|
-
async function saveTenantInfo(tenantInfo) {
|
|
60805
|
-
const db = getTenantDB(tenantInfo.tenantId);
|
|
60806
|
-
return db.put({
|
|
60807
|
-
_id: "tenant_info",
|
|
60808
|
-
...tenantInfo
|
|
60809
|
-
});
|
|
60810
|
-
}
|
|
60811
|
-
async function getTenantInfo(tenantId) {
|
|
60812
|
-
try {
|
|
60813
|
-
const db = getTenantDB(tenantId);
|
|
60814
|
-
const tenantInfo = await db.get("tenant_info");
|
|
60815
|
-
delete tenantInfo.owner.password;
|
|
60816
|
-
return tenantInfo;
|
|
60817
|
-
} catch {
|
|
60818
|
-
return void 0;
|
|
60819
|
-
}
|
|
60820
|
-
}
|
|
60821
|
-
|
|
60822
|
-
// src/tenancy/tenancy.ts
|
|
60823
|
-
function addTenantToUrl(url) {
|
|
60824
|
-
const tenantId = getTenantId();
|
|
60825
|
-
if (isMultiTenant()) {
|
|
60826
|
-
const char = url.indexOf("?") === -1 ? "?" : "&";
|
|
60827
|
-
url += `${char}tenantId=${tenantId}`;
|
|
60828
|
-
}
|
|
60829
|
-
return url;
|
|
60830
|
-
}
|
|
60831
|
-
var isUserInAppTenant = (appId, user) => {
|
|
60832
|
-
let userTenantId;
|
|
60833
|
-
if (user) {
|
|
60834
|
-
userTenantId = user.tenantId || DEFAULT_TENANT_ID;
|
|
60835
|
-
} else {
|
|
60836
|
-
userTenantId = getTenantId();
|
|
60837
|
-
}
|
|
60838
|
-
const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID;
|
|
60839
|
-
return tenantId === userTenantId;
|
|
60840
|
-
};
|
|
60841
|
-
var ALL_STRATEGIES = Object.values(TenantResolutionStrategy);
|
|
60842
|
-
var getTenantIDFromCtx = (ctx, opts) => {
|
|
60843
|
-
if (!isMultiTenant()) {
|
|
60844
|
-
return DEFAULT_TENANT_ID;
|
|
60845
|
-
}
|
|
60846
|
-
if (opts.allowNoTenant === void 0) {
|
|
60847
|
-
opts.allowNoTenant = false;
|
|
60848
|
-
}
|
|
60849
|
-
if (!opts.includeStrategies) {
|
|
60850
|
-
opts.includeStrategies = ALL_STRATEGIES;
|
|
60851
|
-
}
|
|
60852
|
-
if (!opts.excludeStrategies) {
|
|
60853
|
-
opts.excludeStrategies = [];
|
|
60854
|
-
}
|
|
60855
|
-
const isAllowed = (strategy) => {
|
|
60856
|
-
if (opts.excludeStrategies?.includes(strategy)) {
|
|
60857
|
-
return false;
|
|
60858
|
-
}
|
|
60859
|
-
if (opts.includeStrategies?.includes(strategy)) {
|
|
60860
|
-
return true;
|
|
60861
|
-
}
|
|
60862
|
-
};
|
|
60863
|
-
if (isAllowed("user" /* USER */)) {
|
|
60864
|
-
const userTenantId = ctx.user?.tenantId;
|
|
60865
|
-
if (userTenantId) {
|
|
60866
|
-
return userTenantId;
|
|
60867
|
-
}
|
|
60868
|
-
}
|
|
60869
|
-
if (isAllowed("header" /* HEADER */)) {
|
|
60870
|
-
const headerTenantId = ctx.request.headers["x-budibase-tenant-id" /* TENANT_ID */];
|
|
60871
|
-
if (headerTenantId) {
|
|
60872
|
-
return headerTenantId;
|
|
60873
|
-
}
|
|
60874
|
-
}
|
|
60875
|
-
if (isAllowed("query" /* QUERY */)) {
|
|
60876
|
-
const queryTenantId = ctx.request.query.tenantId;
|
|
60877
|
-
if (queryTenantId) {
|
|
60878
|
-
return queryTenantId;
|
|
60879
|
-
}
|
|
60880
|
-
}
|
|
60881
|
-
if (isAllowed("subdomain" /* SUBDOMAIN */)) {
|
|
60882
|
-
let platformHost;
|
|
60883
|
-
try {
|
|
60884
|
-
platformHost = new URL(getPlatformURL()).host.split(":")[0];
|
|
60885
|
-
} catch (err) {
|
|
60886
|
-
if (err.code !== "ERR_INVALID_URL") {
|
|
60887
|
-
throw err;
|
|
60888
|
-
}
|
|
60889
|
-
}
|
|
60890
|
-
const requestHost = ctx.host;
|
|
60891
|
-
if (platformHost && requestHost.includes(platformHost)) {
|
|
60892
|
-
const tenantId = requestHost.substring(
|
|
60893
|
-
0,
|
|
60894
|
-
requestHost.indexOf(`.${platformHost}`)
|
|
60895
|
-
);
|
|
60896
|
-
if (tenantId) {
|
|
60897
|
-
return tenantId;
|
|
60898
|
-
}
|
|
60899
|
-
}
|
|
60900
|
-
}
|
|
60901
|
-
if (isAllowed("path" /* PATH */)) {
|
|
60902
|
-
const match = ctx.matched.find(
|
|
60903
|
-
(m) => !!m.paramNames.find((p) => p.name === "tenantId")
|
|
60904
|
-
);
|
|
60905
|
-
const ctxUrl = ctx.originalUrl;
|
|
60906
|
-
let url;
|
|
60907
|
-
if (ctxUrl.includes("?")) {
|
|
60908
|
-
url = ctxUrl.split("?")[0];
|
|
60909
|
-
} else {
|
|
60910
|
-
url = ctxUrl;
|
|
60911
|
-
}
|
|
60912
|
-
if (match) {
|
|
60913
|
-
const params2 = match.params(url, match.captures(url), {});
|
|
60914
|
-
if (params2.tenantId) {
|
|
60915
|
-
return params2.tenantId;
|
|
60916
|
-
}
|
|
60917
|
-
}
|
|
60918
|
-
}
|
|
60919
|
-
if (!opts.allowNoTenant) {
|
|
60920
|
-
ctx.throw(403, "Tenant id not set");
|
|
60921
|
-
}
|
|
60922
|
-
return void 0;
|
|
60923
|
-
};
|
|
60924
|
-
|
|
60925
61194
|
// src/platform/index.ts
|
|
60926
61195
|
var platform_exports = {};
|
|
60927
61196
|
__export(platform_exports, {
|
|
@@ -61044,249 +61313,6 @@ __export(redlockImpl_exports, {
|
|
|
61044
61313
|
newRedlock: () => newRedlock
|
|
61045
61314
|
});
|
|
61046
61315
|
var import_redlock = __toESM(require("redlock"));
|
|
61047
|
-
|
|
61048
|
-
// src/utils/index.ts
|
|
61049
|
-
var utils_exports4 = {};
|
|
61050
|
-
__export(utils_exports4, {
|
|
61051
|
-
Duration: () => Duration,
|
|
61052
|
-
DurationType: () => DurationType,
|
|
61053
|
-
clearCookie: () => clearCookie,
|
|
61054
|
-
compare: () => compare,
|
|
61055
|
-
getAppIdFromCtx: () => getAppIdFromCtx,
|
|
61056
|
-
getCookie: () => getCookie,
|
|
61057
|
-
hasCircularStructure: () => hasCircularStructure,
|
|
61058
|
-
hash: () => hash,
|
|
61059
|
-
isAudited: () => isAudited,
|
|
61060
|
-
isClient: () => isClient,
|
|
61061
|
-
isPublicApiRequest: () => isPublicApiRequest,
|
|
61062
|
-
isServingApp: () => isServingApp,
|
|
61063
|
-
isServingBuilder: () => isServingBuilder,
|
|
61064
|
-
isServingBuilderPreview: () => isServingBuilderPreview,
|
|
61065
|
-
isValidInternalAPIKey: () => isValidInternalAPIKey,
|
|
61066
|
-
newid: () => newid,
|
|
61067
|
-
openJwt: () => openJwt,
|
|
61068
|
-
resolveAppUrl: () => resolveAppUrl,
|
|
61069
|
-
setCookie: () => setCookie,
|
|
61070
|
-
timeout: () => timeout,
|
|
61071
|
-
validEmail: () => validEmail
|
|
61072
|
-
});
|
|
61073
|
-
|
|
61074
|
-
// src/utils/hashing.ts
|
|
61075
|
-
var bcrypt = environment_default.JS_BCRYPT ? require("bcryptjs") : require("bcrypt");
|
|
61076
|
-
var SALT_ROUNDS = environment_default.SALT_ROUNDS || 10;
|
|
61077
|
-
async function hash(data) {
|
|
61078
|
-
const salt = await bcrypt.genSalt(SALT_ROUNDS);
|
|
61079
|
-
return bcrypt.hash(data, salt);
|
|
61080
|
-
}
|
|
61081
|
-
async function compare(data, encrypted) {
|
|
61082
|
-
return bcrypt.compare(data, encrypted);
|
|
61083
|
-
}
|
|
61084
|
-
|
|
61085
|
-
// src/utils/utils.ts
|
|
61086
|
-
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
61087
|
-
var APP_PREFIX3 = "app" /* APP */ + SEPARATOR;
|
|
61088
|
-
var PROD_APP_PREFIX = "/app/";
|
|
61089
|
-
var BUILDER_PREVIEW_PATH = "/app/preview";
|
|
61090
|
-
var BUILDER_PREFIX = "/builder";
|
|
61091
|
-
var BUILDER_APP_PREFIX = `${BUILDER_PREFIX}/app/`;
|
|
61092
|
-
var PUBLIC_API_PREFIX = "/api/public/v";
|
|
61093
|
-
function confirmAppId(possibleAppId) {
|
|
61094
|
-
return possibleAppId && possibleAppId.startsWith(APP_PREFIX3) ? possibleAppId : void 0;
|
|
61095
|
-
}
|
|
61096
|
-
async function resolveAppUrl(ctx) {
|
|
61097
|
-
const appUrl = ctx.path.split("/")[2];
|
|
61098
|
-
let possibleAppUrl = `/${appUrl.toLowerCase()}`;
|
|
61099
|
-
let tenantId = getTenantId();
|
|
61100
|
-
if (!environment_default.isDev() && environment_default.MULTI_TENANCY) {
|
|
61101
|
-
tenantId = getTenantIDFromCtx(ctx, {
|
|
61102
|
-
includeStrategies: ["subdomain" /* SUBDOMAIN */]
|
|
61103
|
-
});
|
|
61104
|
-
}
|
|
61105
|
-
const apps = await doInTenant(
|
|
61106
|
-
tenantId,
|
|
61107
|
-
() => getAllApps({ dev: false })
|
|
61108
|
-
);
|
|
61109
|
-
const app = apps.filter(
|
|
61110
|
-
(a) => a.url && a.url.toLowerCase() === possibleAppUrl
|
|
61111
|
-
)[0];
|
|
61112
|
-
return app && app.appId ? app.appId : void 0;
|
|
61113
|
-
}
|
|
61114
|
-
function isServingApp(ctx) {
|
|
61115
|
-
if (ctx.path.startsWith(`/${APP_PREFIX3}`)) {
|
|
61116
|
-
return true;
|
|
61117
|
-
}
|
|
61118
|
-
return ctx.path.startsWith(PROD_APP_PREFIX);
|
|
61119
|
-
}
|
|
61120
|
-
function isServingBuilder(ctx) {
|
|
61121
|
-
return ctx.path.startsWith(BUILDER_APP_PREFIX);
|
|
61122
|
-
}
|
|
61123
|
-
function isServingBuilderPreview(ctx) {
|
|
61124
|
-
return ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
61125
|
-
}
|
|
61126
|
-
function isPublicApiRequest(ctx) {
|
|
61127
|
-
return ctx.path.startsWith(PUBLIC_API_PREFIX);
|
|
61128
|
-
}
|
|
61129
|
-
async function getAppIdFromCtx(ctx) {
|
|
61130
|
-
const options2 = [ctx.request.headers["x-budibase-app-id" /* APP_ID */]];
|
|
61131
|
-
let appId;
|
|
61132
|
-
for (let option of options2) {
|
|
61133
|
-
appId = confirmAppId(option);
|
|
61134
|
-
if (appId) {
|
|
61135
|
-
break;
|
|
61136
|
-
}
|
|
61137
|
-
}
|
|
61138
|
-
if (!appId && ctx.request.body && ctx.request.body.appId) {
|
|
61139
|
-
appId = confirmAppId(ctx.request.body.appId);
|
|
61140
|
-
}
|
|
61141
|
-
const pathId = parseAppIdFromUrlPath(ctx.path);
|
|
61142
|
-
if (!appId && pathId) {
|
|
61143
|
-
appId = confirmAppId(pathId);
|
|
61144
|
-
}
|
|
61145
|
-
const isBuilderPreview = ctx.path.startsWith(BUILDER_PREVIEW_PATH);
|
|
61146
|
-
const isViewingProdApp = ctx.path.startsWith(PROD_APP_PREFIX) && !isBuilderPreview;
|
|
61147
|
-
if (!appId && isViewingProdApp) {
|
|
61148
|
-
appId = confirmAppId(await resolveAppUrl(ctx));
|
|
61149
|
-
}
|
|
61150
|
-
const referer = ctx.request.headers.referer;
|
|
61151
|
-
if (!appId && referer?.includes(BUILDER_APP_PREFIX)) {
|
|
61152
|
-
const refererId = parseAppIdFromUrlPath(ctx.request.headers.referer);
|
|
61153
|
-
appId = confirmAppId(refererId);
|
|
61154
|
-
}
|
|
61155
|
-
return appId;
|
|
61156
|
-
}
|
|
61157
|
-
function parseAppIdFromUrlPath(url) {
|
|
61158
|
-
if (!url) {
|
|
61159
|
-
return;
|
|
61160
|
-
}
|
|
61161
|
-
return url.split("?")[0].split("/").find((subPath) => subPath.startsWith(APP_PREFIX3));
|
|
61162
|
-
}
|
|
61163
|
-
function openJwt(token) {
|
|
61164
|
-
if (!token) {
|
|
61165
|
-
return void 0;
|
|
61166
|
-
}
|
|
61167
|
-
try {
|
|
61168
|
-
return import_jsonwebtoken.default.verify(token, environment_default.JWT_SECRET);
|
|
61169
|
-
} catch (e) {
|
|
61170
|
-
if (environment_default.JWT_SECRET_FALLBACK) {
|
|
61171
|
-
return import_jsonwebtoken.default.verify(token, environment_default.JWT_SECRET_FALLBACK);
|
|
61172
|
-
} else {
|
|
61173
|
-
throw e;
|
|
61174
|
-
}
|
|
61175
|
-
}
|
|
61176
|
-
}
|
|
61177
|
-
function isValidInternalAPIKey(apiKey) {
|
|
61178
|
-
if (environment_default.INTERNAL_API_KEY && environment_default.INTERNAL_API_KEY === apiKey) {
|
|
61179
|
-
return true;
|
|
61180
|
-
}
|
|
61181
|
-
return !!(environment_default.INTERNAL_API_KEY_FALLBACK && environment_default.INTERNAL_API_KEY_FALLBACK === apiKey);
|
|
61182
|
-
}
|
|
61183
|
-
function getCookie(ctx, name) {
|
|
61184
|
-
const cookie = ctx.cookies.get(name);
|
|
61185
|
-
if (!cookie) {
|
|
61186
|
-
return void 0;
|
|
61187
|
-
}
|
|
61188
|
-
return openJwt(cookie);
|
|
61189
|
-
}
|
|
61190
|
-
function setCookie(ctx, value, name = "builder", opts = { sign: true }) {
|
|
61191
|
-
if (value && opts && opts.sign) {
|
|
61192
|
-
value = import_jsonwebtoken.default.sign(value, environment_default.JWT_SECRET);
|
|
61193
|
-
}
|
|
61194
|
-
const config = {
|
|
61195
|
-
expires: MAX_VALID_DATE,
|
|
61196
|
-
path: "/",
|
|
61197
|
-
httpOnly: false,
|
|
61198
|
-
overwrite: true
|
|
61199
|
-
};
|
|
61200
|
-
if (environment_default.COOKIE_DOMAIN) {
|
|
61201
|
-
config.domain = environment_default.COOKIE_DOMAIN;
|
|
61202
|
-
}
|
|
61203
|
-
ctx.cookies.set(name, value, config);
|
|
61204
|
-
}
|
|
61205
|
-
function clearCookie(ctx, name) {
|
|
61206
|
-
setCookie(ctx, null, name);
|
|
61207
|
-
}
|
|
61208
|
-
function isClient(ctx) {
|
|
61209
|
-
return ctx.headers["x-budibase-type" /* TYPE */] === "client";
|
|
61210
|
-
}
|
|
61211
|
-
function timeout(timeMs) {
|
|
61212
|
-
return new Promise((resolve) => setTimeout(resolve, timeMs));
|
|
61213
|
-
}
|
|
61214
|
-
function isAudited(event) {
|
|
61215
|
-
return !!AuditedEventFriendlyName[event];
|
|
61216
|
-
}
|
|
61217
|
-
function hasCircularStructure(json) {
|
|
61218
|
-
if (typeof json !== "object") {
|
|
61219
|
-
return false;
|
|
61220
|
-
}
|
|
61221
|
-
try {
|
|
61222
|
-
JSON.stringify(json);
|
|
61223
|
-
} catch (err) {
|
|
61224
|
-
if (err instanceof Error && err?.message.includes("circular structure")) {
|
|
61225
|
-
return true;
|
|
61226
|
-
}
|
|
61227
|
-
}
|
|
61228
|
-
return false;
|
|
61229
|
-
}
|
|
61230
|
-
|
|
61231
|
-
// src/utils/stringUtils.ts
|
|
61232
|
-
function validEmail(value) {
|
|
61233
|
-
return value && !!value.match(
|
|
61234
|
-
/^(([^<>()[\]\\.,;:\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,}))$/
|
|
61235
|
-
);
|
|
61236
|
-
}
|
|
61237
|
-
|
|
61238
|
-
// src/utils/Duration.ts
|
|
61239
|
-
var DurationType = /* @__PURE__ */ ((DurationType2) => {
|
|
61240
|
-
DurationType2["MILLISECONDS"] = "milliseconds";
|
|
61241
|
-
DurationType2["SECONDS"] = "seconds";
|
|
61242
|
-
DurationType2["MINUTES"] = "minutes";
|
|
61243
|
-
DurationType2["HOURS"] = "hours";
|
|
61244
|
-
DurationType2["DAYS"] = "days";
|
|
61245
|
-
return DurationType2;
|
|
61246
|
-
})(DurationType || {});
|
|
61247
|
-
var conversion = {
|
|
61248
|
-
milliseconds: 1,
|
|
61249
|
-
seconds: 1e3,
|
|
61250
|
-
minutes: 60 * 1e3,
|
|
61251
|
-
hours: 60 * 60 * 1e3,
|
|
61252
|
-
days: 24 * 60 * 60 * 1e3
|
|
61253
|
-
};
|
|
61254
|
-
var Duration = class _Duration {
|
|
61255
|
-
static convert(from, to, duration) {
|
|
61256
|
-
const milliseconds = duration * conversion[from];
|
|
61257
|
-
return milliseconds / conversion[to];
|
|
61258
|
-
}
|
|
61259
|
-
static from(from, duration) {
|
|
61260
|
-
return {
|
|
61261
|
-
to: (to) => {
|
|
61262
|
-
return _Duration.convert(from, to, duration);
|
|
61263
|
-
},
|
|
61264
|
-
toMs: () => {
|
|
61265
|
-
return _Duration.convert(from, "milliseconds" /* MILLISECONDS */, duration);
|
|
61266
|
-
},
|
|
61267
|
-
toSeconds: () => {
|
|
61268
|
-
return _Duration.convert(from, "seconds" /* SECONDS */, duration);
|
|
61269
|
-
}
|
|
61270
|
-
};
|
|
61271
|
-
}
|
|
61272
|
-
static fromSeconds(duration) {
|
|
61273
|
-
return _Duration.from("seconds" /* SECONDS */, duration);
|
|
61274
|
-
}
|
|
61275
|
-
static fromMinutes(duration) {
|
|
61276
|
-
return _Duration.from("minutes" /* MINUTES */, duration);
|
|
61277
|
-
}
|
|
61278
|
-
static fromHours(duration) {
|
|
61279
|
-
return _Duration.from("hours" /* HOURS */, duration);
|
|
61280
|
-
}
|
|
61281
|
-
static fromDays(duration) {
|
|
61282
|
-
return _Duration.from("days" /* DAYS */, duration);
|
|
61283
|
-
}
|
|
61284
|
-
static fromMilliseconds(duration) {
|
|
61285
|
-
return _Duration.from("milliseconds" /* MILLISECONDS */, duration);
|
|
61286
|
-
}
|
|
61287
|
-
};
|
|
61288
|
-
|
|
61289
|
-
// src/redis/redlockImpl.ts
|
|
61290
61316
|
async function getClient(type, opts) {
|
|
61291
61317
|
if (type === "custom" /* CUSTOM */) {
|
|
61292
61318
|
return newRedlock(opts);
|
|
@@ -66198,6 +66224,9 @@ async function getSCIMConfig() {
|
|
|
66198
66224
|
const config = await getConfig("scim" /* SCIM */);
|
|
66199
66225
|
return config?.config;
|
|
66200
66226
|
}
|
|
66227
|
+
async function getAIConfig() {
|
|
66228
|
+
return getConfig("ai" /* AI */);
|
|
66229
|
+
}
|
|
66201
66230
|
|
|
66202
66231
|
// src/migrations/index.ts
|
|
66203
66232
|
var migrations_exports = {};
|
|
@@ -67984,9 +68013,17 @@ var SqlTableQueryBuilder = class {
|
|
|
67984
68013
|
constructor(client) {
|
|
67985
68014
|
this.sqlClient = client;
|
|
67986
68015
|
}
|
|
67987
|
-
|
|
68016
|
+
getBaseSqlClient() {
|
|
67988
68017
|
return this.sqlClient;
|
|
67989
68018
|
}
|
|
68019
|
+
getSqlClient() {
|
|
68020
|
+
return this.extendedSqlClient || this.sqlClient;
|
|
68021
|
+
}
|
|
68022
|
+
// if working in a database like MySQL with many variants (MariaDB)
|
|
68023
|
+
// we can set another client which overrides the base one
|
|
68024
|
+
setExtendedSqlClient(client) {
|
|
68025
|
+
this.extendedSqlClient = client;
|
|
68026
|
+
}
|
|
67990
68027
|
/**
|
|
67991
68028
|
* @param json the input JSON structure from which an SQL query will be built.
|
|
67992
68029
|
* @return the operation that was found in the JSON.
|
|
@@ -68138,6 +68175,7 @@ var InternalBuilder = class {
|
|
|
68138
68175
|
return `"${str}"`;
|
|
68139
68176
|
case "mssql" /* MS_SQL */:
|
|
68140
68177
|
return `[${str}]`;
|
|
68178
|
+
case "mariadb" /* MARIADB */:
|
|
68141
68179
|
case "mysql2" /* MY_SQL */:
|
|
68142
68180
|
return `\`${str}\``;
|
|
68143
68181
|
}
|
|
@@ -68445,7 +68483,7 @@ var InternalBuilder = class {
|
|
|
68445
68483
|
)}${wrap}, FALSE)`
|
|
68446
68484
|
);
|
|
68447
68485
|
});
|
|
68448
|
-
} else if (this.client === "mysql2" /* MY_SQL */) {
|
|
68486
|
+
} else if (this.client === "mysql2" /* MY_SQL */ || this.client === "mariadb" /* MARIADB */) {
|
|
68449
68487
|
const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS";
|
|
68450
68488
|
iterate(mode, (q2, key, value) => {
|
|
68451
68489
|
return q2[rawFnc](
|
|
@@ -68748,7 +68786,7 @@ var InternalBuilder = class {
|
|
|
68748
68786
|
continue;
|
|
68749
68787
|
}
|
|
68750
68788
|
const relatedTable = meta.tables?.[toTable];
|
|
68751
|
-
const toAlias = aliases?.[toTable] || toTable, fromAlias = aliases?.[fromTable] || fromTable;
|
|
68789
|
+
const toAlias = aliases?.[toTable] || toTable, fromAlias = aliases?.[fromTable] || fromTable, throughAlias = throughTable && aliases?.[throughTable] || throughTable;
|
|
68752
68790
|
let toTableWithSchema = this.tableNameWithSchema(toTable, {
|
|
68753
68791
|
alias: toAlias,
|
|
68754
68792
|
schema: endpoint.schema
|
|
@@ -68767,29 +68805,25 @@ var InternalBuilder = class {
|
|
|
68767
68805
|
);
|
|
68768
68806
|
const fieldList = relationshipFields.map((field) => this.buildJsonField(field)).join(",");
|
|
68769
68807
|
const primaryKey = `${toAlias}.${toPrimary || toKey}`;
|
|
68770
|
-
let subQuery = knex3.from(toTableWithSchema).
|
|
68771
|
-
|
|
68772
|
-
|
|
68808
|
+
let subQuery = knex3.from(toTableWithSchema).orderBy(primaryKey);
|
|
68809
|
+
const isManyToMany = throughTable && toPrimary && fromPrimary;
|
|
68810
|
+
let correlatedTo = isManyToMany ? `${throughAlias}.${fromKey}` : `${toAlias}.${toKey}`, correlatedFrom = isManyToMany ? `${fromAlias}.${fromPrimary}` : `${fromAlias}.${fromKey}`;
|
|
68811
|
+
if (isManyToMany) {
|
|
68773
68812
|
let throughTableWithSchema = this.tableNameWithSchema(throughTable, {
|
|
68774
68813
|
alias: throughAlias,
|
|
68775
68814
|
schema: endpoint.schema
|
|
68776
68815
|
});
|
|
68777
68816
|
subQuery = subQuery.join(throughTableWithSchema, function() {
|
|
68778
68817
|
this.on(`${toAlias}.${toPrimary}`, "=", `${throughAlias}.${toKey}`);
|
|
68779
|
-
})
|
|
68780
|
-
`${throughAlias}.${fromKey}`,
|
|
68781
|
-
"=",
|
|
68782
|
-
knex3.raw(this.quotedIdentifier(`${fromAlias}.${fromPrimary}`))
|
|
68783
|
-
);
|
|
68784
|
-
} else {
|
|
68785
|
-
subQuery = subQuery.where(
|
|
68786
|
-
`${toAlias}.${toKey}`,
|
|
68787
|
-
"=",
|
|
68788
|
-
knex3.raw(this.quotedIdentifier(`${fromAlias}.${fromKey}`))
|
|
68789
|
-
);
|
|
68818
|
+
});
|
|
68790
68819
|
}
|
|
68820
|
+
subQuery = subQuery.where(
|
|
68821
|
+
correlatedTo,
|
|
68822
|
+
"=",
|
|
68823
|
+
knex3.raw(this.quotedIdentifier(correlatedFrom))
|
|
68824
|
+
);
|
|
68791
68825
|
const standardWrap = (select) => {
|
|
68792
|
-
subQuery = subQuery.select(`${toAlias}.*`);
|
|
68826
|
+
subQuery = subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit());
|
|
68793
68827
|
return knex3.select(knex3.raw(select)).from({
|
|
68794
68828
|
[toAlias]: subQuery
|
|
68795
68829
|
});
|
|
@@ -68807,11 +68841,14 @@ var InternalBuilder = class {
|
|
|
68807
68841
|
`json_agg(json_build_object(${fieldList}))`
|
|
68808
68842
|
);
|
|
68809
68843
|
break;
|
|
68810
|
-
case "
|
|
68844
|
+
case "mariadb" /* MARIADB */:
|
|
68811
68845
|
wrapperQuery = subQuery.select(
|
|
68812
|
-
knex3.raw(
|
|
68846
|
+
knex3.raw(
|
|
68847
|
+
`json_arrayagg(json_object(${fieldList}) LIMIT ${getRelationshipLimit()})`
|
|
68848
|
+
)
|
|
68813
68849
|
);
|
|
68814
68850
|
break;
|
|
68851
|
+
case "mysql2" /* MY_SQL */:
|
|
68815
68852
|
case "oracledb" /* ORACLE */:
|
|
68816
68853
|
wrapperQuery = standardWrap(
|
|
68817
68854
|
`json_arrayagg(json_object(${fieldList}))`
|
|
@@ -68820,7 +68857,7 @@ var InternalBuilder = class {
|
|
|
68820
68857
|
case "mssql" /* MS_SQL */:
|
|
68821
68858
|
wrapperQuery = knex3.raw(
|
|
68822
68859
|
`(SELECT ${this.quote(toAlias)} = (${knex3.select(`${fromAlias}.*`).from({
|
|
68823
|
-
[fromAlias]: subQuery.select(`${toAlias}.*`)
|
|
68860
|
+
[fromAlias]: subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit())
|
|
68824
68861
|
})} FOR JSON PATH))`
|
|
68825
68862
|
);
|
|
68826
68863
|
break;
|
|
@@ -68931,7 +68968,7 @@ var InternalBuilder = class {
|
|
|
68931
68968
|
return query;
|
|
68932
68969
|
}
|
|
68933
68970
|
const parsedBody = body2.map((row) => this.parseBody(row));
|
|
68934
|
-
if (this.client === "pg" /* POSTGRES */ || this.client === "sqlite3" /* SQL_LITE */ || this.client === "mysql2" /* MY_SQL */) {
|
|
68971
|
+
if (this.client === "pg" /* POSTGRES */ || this.client === "sqlite3" /* SQL_LITE */ || this.client === "mysql2" /* MY_SQL */ || this.client === "mariadb" /* MARIADB */) {
|
|
68935
68972
|
const primary = this.table.primary;
|
|
68936
68973
|
if (!primary) {
|
|
68937
68974
|
throw new Error("Primary key is required for upsert");
|
|
@@ -69035,7 +69072,7 @@ var SqlQueryBuilder = class extends sqlTable_default {
|
|
|
69035
69072
|
_query(json, opts = {}) {
|
|
69036
69073
|
const sqlClient = this.getSqlClient();
|
|
69037
69074
|
const config = {
|
|
69038
|
-
client:
|
|
69075
|
+
client: this.getBaseSqlClient()
|
|
69039
69076
|
};
|
|
69040
69077
|
if (sqlClient === "sqlite3" /* SQL_LITE */ || sqlClient === "oracledb" /* ORACLE */) {
|
|
69041
69078
|
config.useNullAsDefault = true;
|
|
@@ -69137,7 +69174,7 @@ var SqlQueryBuilder = class extends sqlTable_default {
|
|
|
69137
69174
|
let id;
|
|
69138
69175
|
if (sqlClient === "mssql" /* MS_SQL */) {
|
|
69139
69176
|
id = results?.[0].id;
|
|
69140
|
-
} else if (sqlClient === "mysql2" /* MY_SQL */) {
|
|
69177
|
+
} else if (sqlClient === "mysql2" /* MY_SQL */ || sqlClient === "mariadb" /* MARIADB */) {
|
|
69141
69178
|
id = results?.insertId;
|
|
69142
69179
|
}
|
|
69143
69180
|
row = processFn(
|