@base44-preview/cli 0.0.50-pr.480.f46dcd8 → 0.0.50-pr.481.3fd0022
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/cli/index.js +516 -115
- package/dist/cli/index.js.map +14 -11
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -219982,7 +219982,8 @@ var theme = {
|
|
|
219982
219982
|
bold: source_default.bold,
|
|
219983
219983
|
dim: source_default.dim,
|
|
219984
219984
|
error: source_default.red,
|
|
219985
|
-
warn: source_default.yellow
|
|
219985
|
+
warn: source_default.yellow,
|
|
219986
|
+
info: source_default.cyan
|
|
219986
219987
|
},
|
|
219987
219988
|
format: {
|
|
219988
219989
|
errorContext(ctx) {
|
|
@@ -235097,8 +235098,8 @@ var TOKEN_REFRESH_BUFFER_MS = 60 * 1000;
|
|
|
235097
235098
|
var refreshPromise = null;
|
|
235098
235099
|
async function readAuth() {
|
|
235099
235100
|
try {
|
|
235100
|
-
const
|
|
235101
|
-
const result = AuthDataSchema.safeParse(
|
|
235101
|
+
const authData = await readJsonFile(getAuthFilePath());
|
|
235102
|
+
const result = AuthDataSchema.safeParse(authData);
|
|
235102
235103
|
if (!result.success) {
|
|
235103
235104
|
throw new SchemaValidationError("Invalid authentication data", result.error, getAuthFilePath());
|
|
235104
235105
|
}
|
|
@@ -241594,30 +241595,12 @@ var ToolConfigSchema = exports_external.union([
|
|
|
241594
241595
|
EntityToolConfigSchema,
|
|
241595
241596
|
BackendFunctionToolConfigSchema
|
|
241596
241597
|
]);
|
|
241597
|
-
var EntityAccessRuleSchema = exports_external.union([
|
|
241598
|
-
exports_external.boolean(),
|
|
241599
|
-
exports_external.record(exports_external.string(), exports_external.unknown())
|
|
241600
|
-
]);
|
|
241601
|
-
var FunctionAccessEntrySchema = exports_external.looseObject({
|
|
241602
|
-
name: exports_external.string().min(1)
|
|
241603
|
-
});
|
|
241604
|
-
var AgentAccessConfigSchema = exports_external.object({
|
|
241605
|
-
entities: exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), EntityAccessRuleSchema)).optional().default({}),
|
|
241606
|
-
functions: exports_external.array(FunctionAccessEntrySchema).optional().default([])
|
|
241607
|
-
});
|
|
241608
|
-
var CodeModeConfigSchema = exports_external.object({
|
|
241609
|
-
access: AgentAccessConfigSchema.optional().default({
|
|
241610
|
-
entities: {},
|
|
241611
|
-
functions: []
|
|
241612
|
-
})
|
|
241613
|
-
});
|
|
241614
241598
|
var AgentConfigSchema = exports_external.looseObject({
|
|
241615
241599
|
name: exports_external.string().trim().min(1).max(100),
|
|
241616
241600
|
description: exports_external.string().trim().min(1, "Description is required"),
|
|
241617
241601
|
instructions: exports_external.string().trim().min(1, "Instructions are required"),
|
|
241618
241602
|
tool_configs: exports_external.array(ToolConfigSchema).optional().default([]),
|
|
241619
|
-
whatsapp_greeting: exports_external.string().nullable().optional()
|
|
241620
|
-
code_mode: CodeModeConfigSchema.optional()
|
|
241603
|
+
whatsapp_greeting: exports_external.string().nullable().optional()
|
|
241621
241604
|
});
|
|
241622
241605
|
var SyncAgentsResponseSchema = exports_external.object({
|
|
241623
241606
|
created: exports_external.array(exports_external.string()),
|
|
@@ -243425,10 +243408,12 @@ var package_default = {
|
|
|
243425
243408
|
"@types/ejs": "^3.1.5",
|
|
243426
243409
|
"@types/express": "^5.0.6",
|
|
243427
243410
|
"@types/json-schema": "^7.0.15",
|
|
243411
|
+
"@types/jsonwebtoken": "^9.0.10",
|
|
243428
243412
|
"@types/lodash": "^4.17.24",
|
|
243429
243413
|
"@types/multer": "^2.0.0",
|
|
243430
243414
|
"@types/node": "^22.10.5",
|
|
243431
243415
|
"@vercel/detect-agent": "^1.1.0",
|
|
243416
|
+
outdent: "^0.8.0",
|
|
243432
243417
|
chalk: "^5.6.2",
|
|
243433
243418
|
chokidar: "^5.0.0",
|
|
243434
243419
|
commander: "^12.1.0",
|
|
@@ -243443,6 +243428,7 @@ var package_default = {
|
|
|
243443
243428
|
globby: "^16.1.0",
|
|
243444
243429
|
"http-proxy-middleware": "^3.0.5",
|
|
243445
243430
|
"json-schema-to-typescript": "^15.0.4",
|
|
243431
|
+
jsonwebtoken: "^9.0.3",
|
|
243446
243432
|
json5: "^2.2.3",
|
|
243447
243433
|
ky: "^1.14.2",
|
|
243448
243434
|
lodash: "^4.17.23",
|
|
@@ -243458,6 +243444,7 @@ var package_default = {
|
|
|
243458
243444
|
typescript: "^5.7.2",
|
|
243459
243445
|
vitest: "^4.0.16",
|
|
243460
243446
|
yaml: "^2.8.2",
|
|
243447
|
+
qs: "^6.12.3",
|
|
243461
243448
|
zod: "^4.3.5"
|
|
243462
243449
|
},
|
|
243463
243450
|
engines: {
|
|
@@ -253070,9 +253057,12 @@ function getTypesCommand() {
|
|
|
253070
253057
|
return new Command("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
|
|
253071
253058
|
}
|
|
253072
253059
|
|
|
253060
|
+
// src/cli/commands/dev.ts
|
|
253061
|
+
import process21 from "node:process";
|
|
253062
|
+
|
|
253073
253063
|
// src/cli/dev/dev-server/main.ts
|
|
253074
253064
|
var import_cors = __toESM(require_lib4(), 1);
|
|
253075
|
-
var
|
|
253065
|
+
var import_express6 = __toESM(require_express(), 1);
|
|
253076
253066
|
import { dirname as dirname17, join as join24 } from "node:path";
|
|
253077
253067
|
|
|
253078
253068
|
// ../../node_modules/get-port/index.js
|
|
@@ -253636,7 +253626,9 @@ class Validator {
|
|
|
253636
253626
|
}
|
|
253637
253627
|
|
|
253638
253628
|
// src/cli/dev/dev-server/db/database.ts
|
|
253629
|
+
var PRIVATE_COLLECTION_PREFIX = "$";
|
|
253639
253630
|
var USER_COLLECTION = "user";
|
|
253631
|
+
var PRIVATE_USER_COLLECTION = PRIVATE_COLLECTION_PREFIX + USER_COLLECTION;
|
|
253640
253632
|
|
|
253641
253633
|
class Database {
|
|
253642
253634
|
collections = new Map;
|
|
@@ -253658,6 +253650,7 @@ class Database {
|
|
|
253658
253650
|
this.schemas.set(USER_COLLECTION, this.buildUserSchema(userEntity));
|
|
253659
253651
|
const collection = new import_nedb.default;
|
|
253660
253652
|
this.collections.set(USER_COLLECTION, collection);
|
|
253653
|
+
this.collections.set(PRIVATE_USER_COLLECTION, new import_nedb.default);
|
|
253661
253654
|
const userInfo = await readAuth();
|
|
253662
253655
|
const now = getNowISOTimestamp();
|
|
253663
253656
|
await collection.insertAsync({
|
|
@@ -253698,8 +253691,13 @@ class Database {
|
|
|
253698
253691
|
getCollection(name2) {
|
|
253699
253692
|
return this.collections.get(this.normalizeName(name2));
|
|
253700
253693
|
}
|
|
253694
|
+
getSchema(entityName) {
|
|
253695
|
+
return this.schemas.get(this.normalizeName(entityName));
|
|
253696
|
+
}
|
|
253701
253697
|
getCollectionNames() {
|
|
253702
|
-
return Array.from(this.collections.keys())
|
|
253698
|
+
return Array.from(this.collections.keys()).filter((name2) => {
|
|
253699
|
+
return !name2.startsWith(PRIVATE_COLLECTION_PREFIX);
|
|
253700
|
+
});
|
|
253703
253701
|
}
|
|
253704
253702
|
dropAll() {
|
|
253705
253703
|
for (const collection of this.collections.values()) {
|
|
@@ -253763,15 +253761,347 @@ function broadcastEntityEvent(io6, appId, entityName, event) {
|
|
|
253763
253761
|
});
|
|
253764
253762
|
}
|
|
253765
253763
|
|
|
253766
|
-
// src/cli/dev/dev-server/routes/
|
|
253767
|
-
var import_express3 = __toESM(require_express(), 1);
|
|
253768
|
-
|
|
253769
|
-
// src/cli/dev/dev-server/routes/entities/entities-user-router.ts
|
|
253764
|
+
// src/cli/dev/dev-server/routes/auth-router.ts
|
|
253770
253765
|
var import_express2 = __toESM(require_express(), 1);
|
|
253771
253766
|
var import_jsonwebtoken = __toESM(require_jsonwebtoken(), 1);
|
|
253772
|
-
|
|
253767
|
+
import { randomInt } from "node:crypto";
|
|
253768
|
+
var LOCAL_DEV_SECRET = "LOCAL_DEV_SECRET";
|
|
253769
|
+
var TEN_MINUTES = 10 * 60 * 1000;
|
|
253770
|
+
var generateCode = () => {
|
|
253771
|
+
return randomInt(1e5, 1e6).toString();
|
|
253772
|
+
};
|
|
253773
|
+
var createJwtToken = (email3) => {
|
|
253774
|
+
return import_jsonwebtoken.default.sign({ sub: email3 }, LOCAL_DEV_SECRET, {
|
|
253775
|
+
expiresIn: "360d"
|
|
253776
|
+
});
|
|
253777
|
+
};
|
|
253778
|
+
var LoginBody = object({ email: email2(), password: string2() });
|
|
253779
|
+
var VerifyOtpBody = object({ email: email2(), otp_code: string2() });
|
|
253780
|
+
function createAuthRouter(db2, logger2) {
|
|
253773
253781
|
const router = import_express2.Router({ mergeParams: true });
|
|
253774
253782
|
const parseBody = import_express2.json();
|
|
253783
|
+
router.post("/login", parseBody, async (req, res) => {
|
|
253784
|
+
const { email: email3, password } = LoginBody.parse(req.body);
|
|
253785
|
+
const result = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: email3 });
|
|
253786
|
+
if (result) {
|
|
253787
|
+
const privateUserData = await db2.getCollection(PRIVATE_USER_COLLECTION)?.findOneAsync({ email: email3 });
|
|
253788
|
+
if (result.role === "admin" || privateUserData?.password === password) {
|
|
253789
|
+
res.json({
|
|
253790
|
+
access_token: createJwtToken(email3),
|
|
253791
|
+
success: true,
|
|
253792
|
+
user: {}
|
|
253793
|
+
});
|
|
253794
|
+
} else {
|
|
253795
|
+
res.status(400).json({
|
|
253796
|
+
detail: "Invalid email or password",
|
|
253797
|
+
error_type: "HTTPException",
|
|
253798
|
+
message: "Invalid email or password",
|
|
253799
|
+
request_id: null,
|
|
253800
|
+
traceback: ""
|
|
253801
|
+
});
|
|
253802
|
+
}
|
|
253803
|
+
return;
|
|
253804
|
+
}
|
|
253805
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
253806
|
+
});
|
|
253807
|
+
router.post("/register", parseBody, async (req, res) => {
|
|
253808
|
+
const { email: email3, password } = LoginBody.parse(req.body);
|
|
253809
|
+
if ((password || "").length < 8) {
|
|
253810
|
+
res.status(400).json({
|
|
253811
|
+
detail: "Password must be at least 8 characters long",
|
|
253812
|
+
error_type: "HTTPException",
|
|
253813
|
+
message: "Password must be at least 8 characters long",
|
|
253814
|
+
request_id: null,
|
|
253815
|
+
traceback: ""
|
|
253816
|
+
});
|
|
253817
|
+
return;
|
|
253818
|
+
}
|
|
253819
|
+
const result = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: email3 });
|
|
253820
|
+
if (result) {
|
|
253821
|
+
res.status(400).json({
|
|
253822
|
+
detail: "A user with this email already exists",
|
|
253823
|
+
error_type: "HTTPException",
|
|
253824
|
+
message: "A user with this email already exists",
|
|
253825
|
+
request_id: null,
|
|
253826
|
+
traceback: ""
|
|
253827
|
+
});
|
|
253828
|
+
return;
|
|
253829
|
+
}
|
|
253830
|
+
const privateUserCollection = db2.getCollection(PRIVATE_USER_COLLECTION);
|
|
253831
|
+
const privateUserData = await privateUserCollection?.findOneAsync({
|
|
253832
|
+
email: email3
|
|
253833
|
+
});
|
|
253834
|
+
const otpCode = generateCode();
|
|
253835
|
+
const id2 = privateUserData ? privateUserData.id : nanoid3();
|
|
253836
|
+
if (!privateUserData) {
|
|
253837
|
+
await privateUserCollection?.insertAsync({
|
|
253838
|
+
id: id2,
|
|
253839
|
+
email: email3,
|
|
253840
|
+
otpCode,
|
|
253841
|
+
password,
|
|
253842
|
+
createdAt: Date.now()
|
|
253843
|
+
});
|
|
253844
|
+
} else {
|
|
253845
|
+
await privateUserCollection?.updateAsync({
|
|
253846
|
+
email: email3
|
|
253847
|
+
}, {
|
|
253848
|
+
$set: {
|
|
253849
|
+
otpCode,
|
|
253850
|
+
createdAt: Date.now()
|
|
253851
|
+
}
|
|
253852
|
+
});
|
|
253853
|
+
}
|
|
253854
|
+
logger2.log(theme.styles.info(`
|
|
253855
|
+
In order to complete registration use this verification code: ${otpCode}
|
|
253856
|
+
`));
|
|
253857
|
+
res.json({
|
|
253858
|
+
id: id2,
|
|
253859
|
+
message: "Registration successful. Please check your email for the verification code.",
|
|
253860
|
+
otp_expires_in_minutes: 10
|
|
253861
|
+
});
|
|
253862
|
+
});
|
|
253863
|
+
router.post("/verify-otp", parseBody, async (req, res) => {
|
|
253864
|
+
const { email: email3, otp_code } = VerifyOtpBody.parse(req.body);
|
|
253865
|
+
const privateUserCollection = db2.getCollection(PRIVATE_USER_COLLECTION);
|
|
253866
|
+
const privateUserData = await privateUserCollection?.findOneAsync({
|
|
253867
|
+
email: email3
|
|
253868
|
+
});
|
|
253869
|
+
if (!privateUserData || privateUserData.otpCode !== otp_code) {
|
|
253870
|
+
const appId = req.params.appId;
|
|
253871
|
+
res.status(500).json({
|
|
253872
|
+
detail: `{'email': '${email3}', 'app_id': '${appId}}'} -> Object not found`,
|
|
253873
|
+
error_type: "ObjectNotFoundError",
|
|
253874
|
+
message: `{'email': '${email3}', 'app_id': '${appId}}'} -> Object not found`,
|
|
253875
|
+
request_id: null,
|
|
253876
|
+
traceback: ""
|
|
253877
|
+
});
|
|
253878
|
+
return;
|
|
253879
|
+
}
|
|
253880
|
+
if (+Date.now() - privateUserData.createdAt > TEN_MINUTES) {
|
|
253881
|
+
res.status(400).json({
|
|
253882
|
+
detail: "Verification code has expired",
|
|
253883
|
+
error_type: "HTTPException",
|
|
253884
|
+
message: "Verification code has expired",
|
|
253885
|
+
request_id: null,
|
|
253886
|
+
traceback: ""
|
|
253887
|
+
});
|
|
253888
|
+
} else {
|
|
253889
|
+
await privateUserCollection?.updateAsync({
|
|
253890
|
+
email: email3
|
|
253891
|
+
}, {
|
|
253892
|
+
$unset: { otpCode: true }
|
|
253893
|
+
});
|
|
253894
|
+
const collection = db2.getCollection(USER_COLLECTION);
|
|
253895
|
+
const now = getNowISOTimestamp();
|
|
253896
|
+
const nameFromEmailMatch = /^([^@]+)/.exec(email3);
|
|
253897
|
+
const fullName = nameFromEmailMatch ? nameFromEmailMatch[1] : email3;
|
|
253898
|
+
await collection?.insertAsync({
|
|
253899
|
+
id: privateUserData.id,
|
|
253900
|
+
email: email3,
|
|
253901
|
+
full_name: fullName,
|
|
253902
|
+
is_service: false,
|
|
253903
|
+
is_verified: true,
|
|
253904
|
+
disabled: null,
|
|
253905
|
+
role: "user",
|
|
253906
|
+
collaborator_role: "editor",
|
|
253907
|
+
created_date: now,
|
|
253908
|
+
updated_date: now
|
|
253909
|
+
});
|
|
253910
|
+
res.json({
|
|
253911
|
+
id: privateUserData.id,
|
|
253912
|
+
access_token: createJwtToken(email3),
|
|
253913
|
+
message: "Email verified successfully. You are now logged in.",
|
|
253914
|
+
success: true
|
|
253915
|
+
});
|
|
253916
|
+
}
|
|
253917
|
+
});
|
|
253918
|
+
return router;
|
|
253919
|
+
}
|
|
253920
|
+
|
|
253921
|
+
// src/cli/dev/dev-server/routes/entities/entities-router.ts
|
|
253922
|
+
var import_express4 = __toESM(require_express(), 1);
|
|
253923
|
+
var import_jsonwebtoken3 = __toESM(require_jsonwebtoken(), 1);
|
|
253924
|
+
|
|
253925
|
+
// src/cli/dev/dev-server/db/rls.ts
|
|
253926
|
+
function resolveTemplate(value, user) {
|
|
253927
|
+
return value.replace(/\{\{user\.([\w.]+)\}\}/g, (_match, path18) => {
|
|
253928
|
+
if (path18.startsWith("data.")) {
|
|
253929
|
+
return String(user[path18.slice(5)] ?? "");
|
|
253930
|
+
}
|
|
253931
|
+
return String(user[path18] ?? "");
|
|
253932
|
+
});
|
|
253933
|
+
}
|
|
253934
|
+
function getRecordField(key2, record2) {
|
|
253935
|
+
if (key2.startsWith("data.")) {
|
|
253936
|
+
return record2[key2.slice(5)];
|
|
253937
|
+
}
|
|
253938
|
+
return record2[key2];
|
|
253939
|
+
}
|
|
253940
|
+
function evaluateOperator(recordValue, operator) {
|
|
253941
|
+
for (const [op2, opValue] of Object.entries(operator)) {
|
|
253942
|
+
switch (op2) {
|
|
253943
|
+
case "$in":
|
|
253944
|
+
if (!Array.isArray(opValue) || !opValue.includes(recordValue)) {
|
|
253945
|
+
return false;
|
|
253946
|
+
}
|
|
253947
|
+
break;
|
|
253948
|
+
case "$nin":
|
|
253949
|
+
if (!Array.isArray(opValue)) {
|
|
253950
|
+
return false;
|
|
253951
|
+
}
|
|
253952
|
+
if (Array.isArray(opValue) && opValue.includes(recordValue)) {
|
|
253953
|
+
return false;
|
|
253954
|
+
}
|
|
253955
|
+
break;
|
|
253956
|
+
case "$ne":
|
|
253957
|
+
if (recordValue === opValue)
|
|
253958
|
+
return false;
|
|
253959
|
+
break;
|
|
253960
|
+
case "$all":
|
|
253961
|
+
if (!Array.isArray(recordValue) || !Array.isArray(opValue)) {
|
|
253962
|
+
return false;
|
|
253963
|
+
}
|
|
253964
|
+
if (!opValue.every((v10) => recordValue.includes(v10))) {
|
|
253965
|
+
return false;
|
|
253966
|
+
}
|
|
253967
|
+
break;
|
|
253968
|
+
}
|
|
253969
|
+
}
|
|
253970
|
+
return true;
|
|
253971
|
+
}
|
|
253972
|
+
function evaluateUserCondition(condition, user) {
|
|
253973
|
+
for (const [key2, expected] of Object.entries(condition)) {
|
|
253974
|
+
const userValue = key2.startsWith("data.") ? user[key2.slice(5)] : user[key2];
|
|
253975
|
+
if (typeof expected === "object" && expected !== null) {
|
|
253976
|
+
if (!evaluateOperator(userValue, expected))
|
|
253977
|
+
return false;
|
|
253978
|
+
} else {
|
|
253979
|
+
if (userValue !== expected)
|
|
253980
|
+
return false;
|
|
253981
|
+
}
|
|
253982
|
+
}
|
|
253983
|
+
return true;
|
|
253984
|
+
}
|
|
253985
|
+
function evaluateCondition(condition, record2, user) {
|
|
253986
|
+
for (const [key2, value] of Object.entries(condition)) {
|
|
253987
|
+
if (key2 === "user_condition") {
|
|
253988
|
+
if (!evaluateUserCondition(value, user))
|
|
253989
|
+
return false;
|
|
253990
|
+
continue;
|
|
253991
|
+
}
|
|
253992
|
+
if (key2 === "$or") {
|
|
253993
|
+
const conditions = value;
|
|
253994
|
+
if (!conditions.some((c8) => evaluateCondition(c8, record2, user)))
|
|
253995
|
+
return false;
|
|
253996
|
+
continue;
|
|
253997
|
+
}
|
|
253998
|
+
if (key2 === "$and") {
|
|
253999
|
+
const conditions = value;
|
|
254000
|
+
if (!conditions.every((c8) => evaluateCondition(c8, record2, user)))
|
|
254001
|
+
return false;
|
|
254002
|
+
continue;
|
|
254003
|
+
}
|
|
254004
|
+
if (key2 === "$nor") {
|
|
254005
|
+
const conditions = value;
|
|
254006
|
+
if (conditions.some((c8) => evaluateCondition(c8, record2, user)))
|
|
254007
|
+
return false;
|
|
254008
|
+
continue;
|
|
254009
|
+
}
|
|
254010
|
+
const recordValue = getRecordField(key2, record2);
|
|
254011
|
+
const resolvedValue = typeof value === "string" ? resolveTemplate(value, user) : value;
|
|
254012
|
+
if (typeof resolvedValue === "object" && resolvedValue !== null) {
|
|
254013
|
+
if (!evaluateOperator(recordValue, resolvedValue))
|
|
254014
|
+
return false;
|
|
254015
|
+
} else {
|
|
254016
|
+
if (recordValue !== resolvedValue)
|
|
254017
|
+
return false;
|
|
254018
|
+
}
|
|
254019
|
+
}
|
|
254020
|
+
return true;
|
|
254021
|
+
}
|
|
254022
|
+
function checkRLS(rule, record2, user) {
|
|
254023
|
+
if (rule === undefined)
|
|
254024
|
+
return true;
|
|
254025
|
+
if (typeof rule === "boolean")
|
|
254026
|
+
return rule;
|
|
254027
|
+
if (!user)
|
|
254028
|
+
return false;
|
|
254029
|
+
return evaluateCondition(rule, record2, user);
|
|
254030
|
+
}
|
|
254031
|
+
function applyFLS(record2, schema10, user, operation) {
|
|
254032
|
+
const result = {};
|
|
254033
|
+
for (const [key2, value] of Object.entries(record2)) {
|
|
254034
|
+
const rule = schema10.properties[key2]?.rls?.[operation];
|
|
254035
|
+
if (!rule || checkRLS(rule, record2, user)) {
|
|
254036
|
+
result[key2] = value;
|
|
254037
|
+
}
|
|
254038
|
+
}
|
|
254039
|
+
return result;
|
|
254040
|
+
}
|
|
254041
|
+
|
|
254042
|
+
// src/cli/dev/dev-server/db/entity-queries.ts
|
|
254043
|
+
function parseSort(sort) {
|
|
254044
|
+
if (!sort) {
|
|
254045
|
+
return;
|
|
254046
|
+
}
|
|
254047
|
+
if (sort.startsWith("-")) {
|
|
254048
|
+
return { [sort.slice(1)]: -1 };
|
|
254049
|
+
}
|
|
254050
|
+
return { [sort]: 1 };
|
|
254051
|
+
}
|
|
254052
|
+
function parseFields(fields) {
|
|
254053
|
+
if (!fields) {
|
|
254054
|
+
return;
|
|
254055
|
+
}
|
|
254056
|
+
const projection = {};
|
|
254057
|
+
for (const field of fields.split(",")) {
|
|
254058
|
+
const trimmed = field.trim();
|
|
254059
|
+
if (trimmed) {
|
|
254060
|
+
projection[trimmed] = 1;
|
|
254061
|
+
}
|
|
254062
|
+
}
|
|
254063
|
+
return Object.keys(projection).length > 0 ? projection : undefined;
|
|
254064
|
+
}
|
|
254065
|
+
var queryEntity = async (collection, reqQuery) => {
|
|
254066
|
+
const { sort, limit, skip: skip2, fields, q: q13 } = reqQuery;
|
|
254067
|
+
let query = {};
|
|
254068
|
+
if (q13 && typeof q13 === "string") {
|
|
254069
|
+
try {
|
|
254070
|
+
query = JSON.parse(q13);
|
|
254071
|
+
} catch {
|
|
254072
|
+
throw new InvalidInputError("Invalid query parameter 'q'");
|
|
254073
|
+
}
|
|
254074
|
+
}
|
|
254075
|
+
let cursor3 = collection.findAsync(query);
|
|
254076
|
+
const sortObj = parseSort(sort);
|
|
254077
|
+
if (sortObj) {
|
|
254078
|
+
cursor3 = cursor3.sort(sortObj);
|
|
254079
|
+
}
|
|
254080
|
+
if (skip2) {
|
|
254081
|
+
const skipNum = Number.parseInt(skip2, 10);
|
|
254082
|
+
if (!Number.isNaN(skipNum)) {
|
|
254083
|
+
cursor3 = cursor3.skip(skipNum);
|
|
254084
|
+
}
|
|
254085
|
+
}
|
|
254086
|
+
if (limit) {
|
|
254087
|
+
const limitNum = Number.parseInt(limit, 10);
|
|
254088
|
+
if (!Number.isNaN(limitNum)) {
|
|
254089
|
+
cursor3 = cursor3.limit(limitNum);
|
|
254090
|
+
}
|
|
254091
|
+
}
|
|
254092
|
+
const projection = parseFields(fields);
|
|
254093
|
+
if (projection) {
|
|
254094
|
+
cursor3 = cursor3.projection(projection);
|
|
254095
|
+
}
|
|
254096
|
+
return cursor3;
|
|
254097
|
+
};
|
|
254098
|
+
|
|
254099
|
+
// src/cli/dev/dev-server/routes/entities/entities-user-router.ts
|
|
254100
|
+
var import_express3 = __toESM(require_express(), 1);
|
|
254101
|
+
var import_jsonwebtoken2 = __toESM(require_jsonwebtoken(), 1);
|
|
254102
|
+
function createUserRouter(db2, logger2) {
|
|
254103
|
+
const router = import_express3.Router({ mergeParams: true });
|
|
254104
|
+
const parseBody = import_express3.json();
|
|
253775
254105
|
function withAuth(handler) {
|
|
253776
254106
|
return async (req, res) => {
|
|
253777
254107
|
const auth2 = req.headers.authorization;
|
|
@@ -253780,13 +254110,13 @@ function createUserRouter(db2, logger2) {
|
|
|
253780
254110
|
return;
|
|
253781
254111
|
}
|
|
253782
254112
|
try {
|
|
253783
|
-
const { payload } =
|
|
253784
|
-
const
|
|
253785
|
-
if (!
|
|
254113
|
+
const { payload } = import_jsonwebtoken2.default.decode(auth2.replace("Bearer ", ""), { complete: true }) ?? {};
|
|
254114
|
+
const currentUser = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: payload?.sub });
|
|
254115
|
+
if (!currentUser) {
|
|
253786
254116
|
res.status(404).json({ error: "Unable to read data for the current user" });
|
|
253787
254117
|
return;
|
|
253788
254118
|
}
|
|
253789
|
-
await handler(req, res,
|
|
254119
|
+
await handler(req, res, currentUser);
|
|
253790
254120
|
} catch {
|
|
253791
254121
|
res.status(401).json({ error: "Unauthorized" });
|
|
253792
254122
|
}
|
|
@@ -253813,6 +254143,28 @@ function createUserRouter(db2, logger2) {
|
|
|
253813
254143
|
...req.body
|
|
253814
254144
|
});
|
|
253815
254145
|
}));
|
|
254146
|
+
router.get("/", withAuth(async (req, res, currentUser) => {
|
|
254147
|
+
const collection = db2.getCollection(USER_COLLECTION);
|
|
254148
|
+
if (!collection) {
|
|
254149
|
+
res.status(404).json({ error: `Entity "${USER_COLLECTION}" not found` });
|
|
254150
|
+
return;
|
|
254151
|
+
}
|
|
254152
|
+
try {
|
|
254153
|
+
if (currentUser.role === "admin") {
|
|
254154
|
+
const result = await queryEntity(collection, req.query);
|
|
254155
|
+
res.json(stripInternalFields(result));
|
|
254156
|
+
} else {
|
|
254157
|
+
res.json([stripInternalFields(currentUser)]);
|
|
254158
|
+
}
|
|
254159
|
+
} catch (error48) {
|
|
254160
|
+
if (error48 instanceof InvalidInputError) {
|
|
254161
|
+
res.status(400).json({ error: error48.message });
|
|
254162
|
+
} else {
|
|
254163
|
+
logger2.error(`Error in GET /${USER_COLLECTION}:`, error48);
|
|
254164
|
+
res.status(500).json({ error: "Internal server error" });
|
|
254165
|
+
}
|
|
254166
|
+
}
|
|
254167
|
+
}));
|
|
253816
254168
|
router.post("/bulk", async (_req, res) => {
|
|
253817
254169
|
res.json({});
|
|
253818
254170
|
});
|
|
@@ -253862,31 +254214,9 @@ function createUserRouter(db2, logger2) {
|
|
|
253862
254214
|
}
|
|
253863
254215
|
|
|
253864
254216
|
// src/cli/dev/dev-server/routes/entities/entities-router.ts
|
|
253865
|
-
function parseSort(sort) {
|
|
253866
|
-
if (!sort) {
|
|
253867
|
-
return;
|
|
253868
|
-
}
|
|
253869
|
-
if (sort.startsWith("-")) {
|
|
253870
|
-
return { [sort.slice(1)]: -1 };
|
|
253871
|
-
}
|
|
253872
|
-
return { [sort]: 1 };
|
|
253873
|
-
}
|
|
253874
|
-
function parseFields(fields) {
|
|
253875
|
-
if (!fields) {
|
|
253876
|
-
return;
|
|
253877
|
-
}
|
|
253878
|
-
const projection = {};
|
|
253879
|
-
for (const field of fields.split(",")) {
|
|
253880
|
-
const trimmed = field.trim();
|
|
253881
|
-
if (trimmed) {
|
|
253882
|
-
projection[trimmed] = 1;
|
|
253883
|
-
}
|
|
253884
|
-
}
|
|
253885
|
-
return Object.keys(projection).length > 0 ? projection : undefined;
|
|
253886
|
-
}
|
|
253887
254217
|
async function createEntityRoutes(db2, logger2, broadcast) {
|
|
253888
|
-
const router =
|
|
253889
|
-
const parseBody =
|
|
254218
|
+
const router = import_express4.Router({ mergeParams: true });
|
|
254219
|
+
const parseBody = import_express4.json();
|
|
253890
254220
|
function withCollection(handler) {
|
|
253891
254221
|
return async (req, res) => {
|
|
253892
254222
|
const collection = db2.getCollection(req.params.entityName);
|
|
@@ -253894,7 +254224,13 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
253894
254224
|
res.status(404).json({ error: `Entity "${req.params.entityName}" not found` });
|
|
253895
254225
|
return;
|
|
253896
254226
|
}
|
|
253897
|
-
|
|
254227
|
+
let currentUser;
|
|
254228
|
+
try {
|
|
254229
|
+
const auth2 = req.headers.authorization || "";
|
|
254230
|
+
const { payload } = import_jsonwebtoken3.default.decode(auth2.replace("Bearer ", ""), { complete: true }) ?? {};
|
|
254231
|
+
currentUser = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: payload?.sub });
|
|
254232
|
+
} catch {}
|
|
254233
|
+
await handler(req, res, collection, currentUser);
|
|
253898
254234
|
};
|
|
253899
254235
|
}
|
|
253900
254236
|
function emit(appId, entityName, type, data) {
|
|
@@ -253914,7 +254250,7 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
253914
254250
|
}
|
|
253915
254251
|
const userRouter = createUserRouter(db2, logger2);
|
|
253916
254252
|
router.use("/User", userRouter);
|
|
253917
|
-
router.get("/:entityName/:id", withCollection(async (req, res, collection) => {
|
|
254253
|
+
router.get("/:entityName/:id", withCollection(async (req, res, collection, currentUser) => {
|
|
253918
254254
|
const { entityName, id: id2 } = req.params;
|
|
253919
254255
|
try {
|
|
253920
254256
|
const doc2 = await collection.findOneAsync({ id: id2 });
|
|
@@ -253922,63 +254258,72 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
253922
254258
|
res.status(404).json({ error: `Record with id "${id2}" not found` });
|
|
253923
254259
|
return;
|
|
253924
254260
|
}
|
|
253925
|
-
|
|
254261
|
+
const schema10 = db2.getSchema(entityName);
|
|
254262
|
+
if (!checkRLS(schema10?.rls?.read, doc2, currentUser)) {
|
|
254263
|
+
res.status(404).json({
|
|
254264
|
+
message: `Entity ${entityName} with ID ${id2} not found`
|
|
254265
|
+
});
|
|
254266
|
+
return;
|
|
254267
|
+
}
|
|
254268
|
+
let result = stripInternalFields(doc2);
|
|
254269
|
+
if (schema10) {
|
|
254270
|
+
result = applyFLS(result, schema10, currentUser, "read");
|
|
254271
|
+
}
|
|
254272
|
+
res.json(result);
|
|
253926
254273
|
} catch (error48) {
|
|
253927
254274
|
logger2.error(`Error in GET /${entityName}/${id2}:`, error48);
|
|
253928
254275
|
res.status(500).json({ error: "Internal server error" });
|
|
253929
254276
|
}
|
|
253930
254277
|
}));
|
|
253931
|
-
router.get("/:entityName", withCollection(async (req, res, collection) => {
|
|
254278
|
+
router.get("/:entityName", withCollection(async (req, res, collection, currentUser) => {
|
|
253932
254279
|
const { entityName } = req.params;
|
|
253933
254280
|
try {
|
|
253934
|
-
const
|
|
253935
|
-
|
|
253936
|
-
|
|
253937
|
-
|
|
253938
|
-
query = JSON.parse(q13);
|
|
253939
|
-
} catch {
|
|
253940
|
-
res.status(400).json({ error: "Invalid query parameter 'q'" });
|
|
253941
|
-
return;
|
|
253942
|
-
}
|
|
253943
|
-
}
|
|
253944
|
-
let cursor3 = collection.findAsync(query);
|
|
253945
|
-
const sortObj = parseSort(sort);
|
|
253946
|
-
if (sortObj) {
|
|
253947
|
-
cursor3 = cursor3.sort(sortObj);
|
|
253948
|
-
}
|
|
253949
|
-
if (skip2) {
|
|
253950
|
-
const skipNum = Number.parseInt(skip2, 10);
|
|
253951
|
-
if (!Number.isNaN(skipNum)) {
|
|
253952
|
-
cursor3 = cursor3.skip(skipNum);
|
|
253953
|
-
}
|
|
254281
|
+
const schema10 = db2.getSchema(entityName);
|
|
254282
|
+
if (schema10?.rls?.read === false) {
|
|
254283
|
+
res.json([]);
|
|
254284
|
+
return;
|
|
253954
254285
|
}
|
|
253955
|
-
|
|
253956
|
-
|
|
253957
|
-
|
|
253958
|
-
cursor3 = cursor3.limit(limitNum);
|
|
253959
|
-
}
|
|
254286
|
+
let results = stripInternalFields(await queryEntity(collection, req.query));
|
|
254287
|
+
if (schema10?.rls?.read && schema10.rls.read !== true) {
|
|
254288
|
+
results = results.filter((doc2) => checkRLS(schema10.rls.read, doc2, currentUser));
|
|
253960
254289
|
}
|
|
253961
|
-
|
|
253962
|
-
|
|
253963
|
-
cursor3 = cursor3.projection(projection);
|
|
254290
|
+
if (schema10) {
|
|
254291
|
+
results = results.map((doc2) => applyFLS(doc2, schema10, currentUser, "read"));
|
|
253964
254292
|
}
|
|
253965
|
-
|
|
253966
|
-
res.json(stripInternalFields(docs));
|
|
254293
|
+
res.json(results);
|
|
253967
254294
|
} catch (error48) {
|
|
253968
|
-
|
|
253969
|
-
|
|
254295
|
+
if (error48 instanceof InvalidInputError) {
|
|
254296
|
+
res.status(400).json({ error: error48.message });
|
|
254297
|
+
} else {
|
|
254298
|
+
logger2.error(`Error in GET /${entityName}:`, error48);
|
|
254299
|
+
res.status(500).json({ error: "Internal server error" });
|
|
254300
|
+
}
|
|
253970
254301
|
}
|
|
253971
254302
|
}));
|
|
253972
|
-
router.post("/:entityName", parseBody, withCollection(async (req, res, collection) => {
|
|
254303
|
+
router.post("/:entityName", parseBody, withCollection(async (req, res, collection, currentUser) => {
|
|
253973
254304
|
const { appId, entityName } = req.params;
|
|
253974
254305
|
try {
|
|
253975
254306
|
const now = new Date().toISOString();
|
|
253976
254307
|
const { _id, ...body } = req.body;
|
|
253977
|
-
const
|
|
254308
|
+
const schema10 = db2.getSchema(entityName);
|
|
254309
|
+
if (!checkRLS(schema10?.rls?.create, {
|
|
254310
|
+
...body,
|
|
254311
|
+
created_by: currentUser?.email,
|
|
254312
|
+
created_by_id: currentUser?.id
|
|
254313
|
+
}, currentUser)) {
|
|
254314
|
+
res.status(403).json({ error: "Permission denied" });
|
|
254315
|
+
return;
|
|
254316
|
+
}
|
|
254317
|
+
let filteredBody = db2.prepareRecord(entityName, body);
|
|
254318
|
+
if (schema10) {
|
|
254319
|
+
filteredBody = applyFLS(filteredBody, schema10, currentUser, "write");
|
|
254320
|
+
}
|
|
253978
254321
|
db2.validate(entityName, filteredBody);
|
|
253979
254322
|
const record2 = {
|
|
253980
254323
|
...filteredBody,
|
|
253981
254324
|
id: nanoid3(),
|
|
254325
|
+
created_by: currentUser?.email,
|
|
254326
|
+
created_by_id: currentUser?.id,
|
|
253982
254327
|
created_date: now,
|
|
253983
254328
|
updated_date: now
|
|
253984
254329
|
};
|
|
@@ -253994,7 +254339,7 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
253994
254339
|
res.status(500).json({ error: "Internal server error" });
|
|
253995
254340
|
}
|
|
253996
254341
|
}));
|
|
253997
|
-
router.post("/:entityName/bulk", parseBody, withCollection(async (req, res, collection) => {
|
|
254342
|
+
router.post("/:entityName/bulk", parseBody, withCollection(async (req, res, collection, currentUser) => {
|
|
253998
254343
|
const { appId, entityName } = req.params;
|
|
253999
254344
|
if (!Array.isArray(req.body)) {
|
|
254000
254345
|
res.status(400).json({ error: "Request body must be an array" });
|
|
@@ -254002,13 +254347,27 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
254002
254347
|
}
|
|
254003
254348
|
try {
|
|
254004
254349
|
const now = new Date().toISOString();
|
|
254350
|
+
const schema10 = db2.getSchema(entityName);
|
|
254005
254351
|
const records = [];
|
|
254006
254352
|
for (const record2 of req.body) {
|
|
254007
|
-
|
|
254353
|
+
if (!checkRLS(schema10?.rls?.create, {
|
|
254354
|
+
...record2,
|
|
254355
|
+
created_by: currentUser?.email,
|
|
254356
|
+
created_by_id: currentUser?.id
|
|
254357
|
+
}, currentUser)) {
|
|
254358
|
+
res.status(403).json({ error: "Permission denied" });
|
|
254359
|
+
return;
|
|
254360
|
+
}
|
|
254361
|
+
let filteredRecord = db2.prepareRecord(entityName, record2);
|
|
254362
|
+
if (schema10) {
|
|
254363
|
+
filteredRecord = applyFLS(filteredRecord, schema10, currentUser, "write");
|
|
254364
|
+
}
|
|
254008
254365
|
db2.validate(entityName, filteredRecord);
|
|
254009
254366
|
records.push({
|
|
254010
254367
|
...filteredRecord,
|
|
254011
254368
|
id: nanoid3(),
|
|
254369
|
+
created_by: currentUser?.email,
|
|
254370
|
+
created_by_id: currentUser?.id,
|
|
254012
254371
|
created_date: now,
|
|
254013
254372
|
updated_date: now
|
|
254014
254373
|
});
|
|
@@ -254025,11 +254384,28 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
254025
254384
|
res.status(500).json({ error: "Internal server error" });
|
|
254026
254385
|
}
|
|
254027
254386
|
}));
|
|
254028
|
-
router.put("/:entityName/:id", parseBody, withCollection(async (req, res, collection) => {
|
|
254387
|
+
router.put("/:entityName/:id", parseBody, withCollection(async (req, res, collection, currentUser) => {
|
|
254029
254388
|
const { appId, entityName, id: id2 } = req.params;
|
|
254030
254389
|
const { id: _id, created_date: _created_date, ...body } = req.body;
|
|
254031
254390
|
try {
|
|
254032
|
-
const
|
|
254391
|
+
const schema10 = db2.getSchema(entityName);
|
|
254392
|
+
if (schema10?.rls?.update !== undefined) {
|
|
254393
|
+
const existing = await collection.findOneAsync({ id: id2 });
|
|
254394
|
+
if (!existing) {
|
|
254395
|
+
res.status(404).json({ error: `Record with id "${id2}" not found` });
|
|
254396
|
+
return;
|
|
254397
|
+
}
|
|
254398
|
+
if (!checkRLS(schema10.rls.update, existing, currentUser)) {
|
|
254399
|
+
res.status(404).json({
|
|
254400
|
+
message: `Entity ${entityName} with ID ${id2} not found`
|
|
254401
|
+
});
|
|
254402
|
+
return;
|
|
254403
|
+
}
|
|
254404
|
+
}
|
|
254405
|
+
let filteredBody = db2.prepareRecord(entityName, body, true);
|
|
254406
|
+
if (schema10) {
|
|
254407
|
+
filteredBody = applyFLS(filteredBody, schema10, currentUser, "write");
|
|
254408
|
+
}
|
|
254033
254409
|
db2.validate(entityName, filteredBody, true);
|
|
254034
254410
|
const updateData = {
|
|
254035
254411
|
...filteredBody,
|
|
@@ -254052,30 +254428,50 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
254052
254428
|
res.status(500).json({ error: "Internal server error" });
|
|
254053
254429
|
}
|
|
254054
254430
|
}));
|
|
254055
|
-
router.delete("/:entityName/:id", withCollection(async (req, res, collection) => {
|
|
254431
|
+
router.delete("/:entityName/:id", withCollection(async (req, res, collection, currentUser) => {
|
|
254056
254432
|
const { appId, entityName, id: id2 } = req.params;
|
|
254057
254433
|
try {
|
|
254058
254434
|
const doc2 = await collection.findOneAsync({ id: id2 });
|
|
254059
|
-
|
|
254060
|
-
if (numRemoved === 0) {
|
|
254435
|
+
if (!doc2) {
|
|
254061
254436
|
res.status(404).json({ error: `Record with id "${id2}" not found` });
|
|
254062
254437
|
return;
|
|
254063
254438
|
}
|
|
254064
|
-
|
|
254065
|
-
|
|
254439
|
+
const schema10 = db2.getSchema(entityName);
|
|
254440
|
+
if (!checkRLS(schema10?.rls?.delete, doc2, currentUser)) {
|
|
254441
|
+
res.status(404).json({
|
|
254442
|
+
message: `Entity ${entityName} with ID ${id2} not found`
|
|
254443
|
+
});
|
|
254444
|
+
return;
|
|
254066
254445
|
}
|
|
254446
|
+
await collection.removeAsync({ id: id2 }, { multi: false });
|
|
254447
|
+
emit(appId, entityName, "delete", stripInternalFields(doc2));
|
|
254067
254448
|
res.json({ success: true });
|
|
254068
254449
|
} catch (error48) {
|
|
254069
254450
|
logger2.error(`Error in DELETE /${entityName}/${id2}:`, error48);
|
|
254070
254451
|
res.status(500).json({ error: "Internal server error" });
|
|
254071
254452
|
}
|
|
254072
254453
|
}));
|
|
254073
|
-
router.delete("/:entityName", parseBody, withCollection(async (req, res, collection) => {
|
|
254454
|
+
router.delete("/:entityName", parseBody, withCollection(async (req, res, collection, currentUser) => {
|
|
254074
254455
|
const { entityName } = req.params;
|
|
254075
254456
|
try {
|
|
254076
254457
|
const query = req.body || {};
|
|
254077
|
-
const
|
|
254078
|
-
|
|
254458
|
+
const schema10 = db2.getSchema(entityName);
|
|
254459
|
+
const rlsDelete = schema10?.rls?.delete;
|
|
254460
|
+
if (rlsDelete !== undefined && rlsDelete !== true) {
|
|
254461
|
+
if (rlsDelete === false) {
|
|
254462
|
+
res.status(403).json({ error: "Permission denied" });
|
|
254463
|
+
return;
|
|
254464
|
+
}
|
|
254465
|
+
const docs = await collection.findAsync(query);
|
|
254466
|
+
const allowedIds = docs.filter((doc2) => checkRLS(rlsDelete, doc2, currentUser)).map((doc2) => doc2.id);
|
|
254467
|
+
const numRemoved = await collection.removeAsync({ id: { $in: allowedIds } }, { multi: true });
|
|
254468
|
+
res.json({ success: true, deleted: numRemoved });
|
|
254469
|
+
} else {
|
|
254470
|
+
const numRemoved = await collection.removeAsync(query, {
|
|
254471
|
+
multi: true
|
|
254472
|
+
});
|
|
254473
|
+
res.json({ success: true, deleted: numRemoved });
|
|
254474
|
+
}
|
|
254079
254475
|
} catch (error48) {
|
|
254080
254476
|
logger2.error(`Error in DELETE /${entityName}:`, error48);
|
|
254081
254477
|
res.status(500).json({ error: "Internal server error" });
|
|
@@ -254085,7 +254481,7 @@ async function createEntityRoutes(db2, logger2, broadcast) {
|
|
|
254085
254481
|
}
|
|
254086
254482
|
|
|
254087
254483
|
// src/cli/dev/dev-server/routes/integrations.ts
|
|
254088
|
-
var
|
|
254484
|
+
var import_express5 = __toESM(require_express(), 1);
|
|
254089
254485
|
var import_multer = __toESM(require_multer(), 1);
|
|
254090
254486
|
import { createHash, randomUUID as randomUUID4 } from "node:crypto";
|
|
254091
254487
|
import fs28 from "node:fs";
|
|
@@ -254094,8 +254490,8 @@ function createFileToken(fileUri) {
|
|
|
254094
254490
|
return createHash("sha256").update(fileUri).digest("hex");
|
|
254095
254491
|
}
|
|
254096
254492
|
function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger2) {
|
|
254097
|
-
const router =
|
|
254098
|
-
const parseBody =
|
|
254493
|
+
const router = import_express5.Router({ mergeParams: true });
|
|
254494
|
+
const parseBody = import_express5.json();
|
|
254099
254495
|
const privateFilesDir = path18.join(mediaFilesDir, "private");
|
|
254100
254496
|
fs28.mkdirSync(mediaFilesDir, { recursive: true });
|
|
254101
254497
|
fs28.mkdirSync(privateFilesDir, { recursive: true });
|
|
@@ -254165,7 +254561,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger2) {
|
|
|
254165
254561
|
return router;
|
|
254166
254562
|
}
|
|
254167
254563
|
function createCustomIntegrationRoutes(remoteProxy, logger2) {
|
|
254168
|
-
const router =
|
|
254564
|
+
const router = import_express5.Router({ mergeParams: true });
|
|
254169
254565
|
router.post("/:slug/:operationId", (req, res, next) => {
|
|
254170
254566
|
logger2.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
|
|
254171
254567
|
req.url = req.originalUrl;
|
|
@@ -255878,7 +256274,7 @@ async function createDevServer(options8) {
|
|
|
255878
256274
|
const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
|
|
255879
256275
|
const baseUrl = `http://localhost:${port}`;
|
|
255880
256276
|
const { functions, entities, project: project2 } = await options8.loadResources();
|
|
255881
|
-
const app =
|
|
256277
|
+
const app = import_express6.default();
|
|
255882
256278
|
const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
|
|
255883
256279
|
target: BASE44_APP_URL,
|
|
255884
256280
|
changeOrigin: true
|
|
@@ -255910,6 +256306,8 @@ async function createDevServer(options8) {
|
|
|
255910
256306
|
let emitEntityEvent = () => {};
|
|
255911
256307
|
const entityRoutes = await createEntityRoutes(db2, devLogger, (...args) => emitEntityEvent(...args));
|
|
255912
256308
|
app.use("/api/apps/:appId/entities", entityRoutes);
|
|
256309
|
+
const authRouter = createAuthRouter(db2, devLogger);
|
|
256310
|
+
app.use("/api/apps/:appId/auth", authRouter);
|
|
255913
256311
|
const { path: mediaFilesDir } = await $dir();
|
|
255914
256312
|
app.use("/media/private/:fileUri", (req, res, next) => {
|
|
255915
256313
|
const { fileUri } = req.params;
|
|
@@ -255929,13 +256327,15 @@ async function createDevServer(options8) {
|
|
|
255929
256327
|
}
|
|
255930
256328
|
next();
|
|
255931
256329
|
});
|
|
255932
|
-
app.use("/media",
|
|
256330
|
+
app.use("/media", import_express6.default.static(mediaFilesDir));
|
|
255933
256331
|
const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
|
|
255934
256332
|
app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
|
|
255935
256333
|
const customIntegrationRoutes = createCustomIntegrationRoutes(remoteProxy, devLogger);
|
|
255936
256334
|
app.use("/api/apps/:appId/integrations/custom", customIntegrationRoutes);
|
|
255937
256335
|
app.use((req, res, next) => {
|
|
255938
|
-
|
|
256336
|
+
if (!req.originalUrl.endsWith("analytics/track/batch")) {
|
|
256337
|
+
devLogger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
|
|
256338
|
+
}
|
|
255939
256339
|
remoteProxy(req, res, next);
|
|
255940
256340
|
});
|
|
255941
256341
|
const server = await new Promise((resolve9, reject) => {
|
|
@@ -256006,6 +256406,7 @@ async function devAction({ log }, options8) {
|
|
|
256006
256406
|
const { port: resolvedPort } = await createDevServer({
|
|
256007
256407
|
log,
|
|
256008
256408
|
port,
|
|
256409
|
+
cwd: process21.cwd(),
|
|
256009
256410
|
denoWrapperPath: getDenoWrapperPath(),
|
|
256010
256411
|
loadResources: async () => {
|
|
256011
256412
|
const { functions, entities, project: project2 } = await readProjectConfig();
|
|
@@ -260482,4 +260883,4 @@ export {
|
|
|
260482
260883
|
CLIExitError
|
|
260483
260884
|
};
|
|
260484
260885
|
|
|
260485
|
-
//# debugId=
|
|
260886
|
+
//# debugId=759CD39E93FDA9AF64756E2164756E21
|