@base44-preview/cli 0.0.50-pr.484.031bd45 → 0.0.50-pr.484.1c556f7

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 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) {
@@ -242001,88 +242002,123 @@ async function pushCustomOAuthSecret(provider, clientSecret) {
242001
242002
  [providerInfo.customOAuth.secretKey]: clientSecret
242002
242003
  });
242003
242004
  }
242004
- // src/core/resources/auth-config/sso.ts
242005
- var KNOWN_SSO_PROVIDERS = [
242006
- "google",
242007
- "microsoft",
242008
- "github",
242009
- "okta",
242010
- "custom"
242011
- ];
242012
- var BASE_SSO_SCOPE = "openid email profile";
242013
- var SSO_PROVIDER_SCHEMAS = {
242014
- google: {
242015
- requiredKeys: [],
242016
- defaults: {
242017
- sso_scope: BASE_SSO_SCOPE,
242018
- sso_discovery_url: "https://accounts.google.com/.well-known/openid-configuration"
242019
- }
242020
- },
242021
- microsoft: {
242022
- requiredKeys: ["sso_tenant_id"],
242023
- defaults: {
242024
- sso_scope: BASE_SSO_SCOPE
242025
- },
242026
- deriveDefaults: (options) => {
242027
- const tenantId = options.sso_tenant_id;
242028
- if (tenantId) {
242029
- return {
242030
- sso_discovery_url: `https://login.microsoftonline.com/${tenantId}/v2.0/.well-known/openid-configuration`
242031
- };
242032
- }
242033
- return {};
242034
- }
242005
+ // src/core/resources/auth-config/sso/secret-keys.ts
242006
+ var SSOSecretKey;
242007
+ ((SSOSecretKey2) => {
242008
+ SSOSecretKey2["Name"] = "sso_name";
242009
+ SSOSecretKey2["ClientId"] = "sso_client_id";
242010
+ SSOSecretKey2["ClientSecret"] = "sso_client_secret";
242011
+ SSOSecretKey2["Scope"] = "sso_scope";
242012
+ SSOSecretKey2["DiscoveryUrl"] = "sso_discovery_url";
242013
+ SSOSecretKey2["TenantId"] = "sso_tenant_id";
242014
+ SSOSecretKey2["AuthEndpoint"] = "sso_auth_endpoint";
242015
+ SSOSecretKey2["TokenEndpoint"] = "sso_token_endpoint";
242016
+ SSOSecretKey2["UserinfoEndpoint"] = "sso_userinfo_endpoint";
242017
+ SSOSecretKey2["OktaDomain"] = "sso_okta_domain";
242018
+ SSOSecretKey2["JwksUri"] = "sso_jwks_uri";
242019
+ })(SSOSecretKey ||= {});
242020
+ var ALL_SSO_SECRET_KEYS = Object.values(SSOSecretKey);
242021
+
242022
+ // src/core/resources/auth-config/sso/providers/custom.ts
242023
+ var DEFAULT_SCOPE = "openid email profile";
242024
+ var customProvider = {
242025
+ requiredKeys: [
242026
+ "sso_auth_endpoint" /* AuthEndpoint */,
242027
+ "sso_token_endpoint" /* TokenEndpoint */,
242028
+ "sso_userinfo_endpoint" /* UserinfoEndpoint */,
242029
+ "sso_jwks_uri" /* JwksUri */
242030
+ ],
242031
+ defaults: {
242032
+ ["sso_scope" /* Scope */]: DEFAULT_SCOPE
242033
+ }
242034
+ };
242035
+
242036
+ // src/core/resources/auth-config/sso/providers/github.ts
242037
+ var githubProvider = {
242038
+ requiredKeys: [],
242039
+ defaults: {
242040
+ ["sso_scope" /* Scope */]: "user:email",
242041
+ ["sso_auth_endpoint" /* AuthEndpoint */]: "https://github.com/login/oauth/authorize",
242042
+ ["sso_token_endpoint" /* TokenEndpoint */]: "https://github.com/login/oauth/access_token",
242043
+ ["sso_userinfo_endpoint" /* UserinfoEndpoint */]: "https://api.github.com/user"
242044
+ }
242045
+ };
242046
+
242047
+ // src/core/resources/auth-config/sso/providers/google.ts
242048
+ var DEFAULT_SCOPE2 = "openid email profile";
242049
+ var googleProvider = {
242050
+ requiredKeys: [],
242051
+ defaults: {
242052
+ ["sso_scope" /* Scope */]: DEFAULT_SCOPE2,
242053
+ ["sso_discovery_url" /* DiscoveryUrl */]: "https://accounts.google.com/.well-known/openid-configuration"
242054
+ }
242055
+ };
242056
+
242057
+ // src/core/resources/auth-config/sso/providers/microsoft.ts
242058
+ var DEFAULT_SCOPE3 = "openid email profile";
242059
+ var microsoftProvider = {
242060
+ requiredKeys: ["sso_tenant_id" /* TenantId */],
242061
+ defaults: {
242062
+ ["sso_scope" /* Scope */]: DEFAULT_SCOPE3
242035
242063
  },
242036
- github: {
242037
- requiredKeys: [],
242038
- defaults: {
242039
- sso_scope: "user:email",
242040
- sso_auth_endpoint: "https://github.com/login/oauth/authorize",
242041
- sso_token_endpoint: "https://github.com/login/oauth/access_token",
242042
- sso_userinfo_endpoint: "https://api.github.com/user"
242064
+ deriveDefaults: (secrets) => {
242065
+ const tenantId = secrets["sso_tenant_id" /* TenantId */];
242066
+ if (tenantId) {
242067
+ return {
242068
+ ["sso_discovery_url" /* DiscoveryUrl */]: `https://login.microsoftonline.com/${tenantId}/v2.0/.well-known/openid-configuration`
242069
+ };
242043
242070
  }
242071
+ return {};
242072
+ }
242073
+ };
242074
+
242075
+ // src/core/resources/auth-config/sso/providers/okta.ts
242076
+ var DEFAULT_SCOPE4 = "openid email profile";
242077
+ var oktaProvider = {
242078
+ requiredKeys: ["sso_okta_domain" /* OktaDomain */],
242079
+ defaults: {
242080
+ ["sso_scope" /* Scope */]: DEFAULT_SCOPE4
242044
242081
  },
242045
- okta: {
242046
- requiredKeys: ["sso_okta_domain"],
242047
- defaults: {
242048
- sso_scope: BASE_SSO_SCOPE
242049
- },
242050
- deriveDefaults: (options) => {
242051
- const domain2 = options.sso_okta_domain;
242052
- if (domain2) {
242053
- return {
242054
- sso_discovery_url: `https://${domain2}/.well-known/openid-configuration`
242055
- };
242056
- }
242057
- return {};
242082
+ deriveDefaults: (secrets) => {
242083
+ const domain2 = secrets["sso_okta_domain" /* OktaDomain */];
242084
+ if (domain2) {
242085
+ return {
242086
+ ["sso_discovery_url" /* DiscoveryUrl */]: `https://${domain2}/.well-known/openid-configuration`
242087
+ };
242058
242088
  }
242059
- },
242060
- custom: {
242061
- requiredKeys: [
242062
- "sso_auth_endpoint",
242063
- "sso_token_endpoint",
242064
- "sso_userinfo_endpoint",
242065
- "sso_jwks_uri"
242066
- ],
242067
- optionalKeys: ["sso_discovery_url"],
242068
- defaults: {
242069
- sso_scope: BASE_SSO_SCOPE
242070
- }
242071
- }
242072
- };
242073
- var ALL_SSO_SECRET_KEYS = [
242074
- "sso_name",
242075
- "sso_client_id",
242076
- "sso_client_secret",
242077
- "sso_scope",
242078
- "sso_discovery_url",
242079
- "sso_tenant_id",
242080
- "sso_auth_endpoint",
242081
- "sso_token_endpoint",
242082
- "sso_userinfo_endpoint",
242083
- "sso_okta_domain",
242084
- "sso_jwks_uri"
242085
- ];
242089
+ return {};
242090
+ }
242091
+ };
242092
+
242093
+ // src/core/resources/auth-config/sso/providers/index.ts
242094
+ var SSO_PROVIDER_SCHEMAS = {
242095
+ google: googleProvider,
242096
+ microsoft: microsoftProvider,
242097
+ github: githubProvider,
242098
+ okta: oktaProvider,
242099
+ custom: customProvider
242100
+ };
242101
+
242102
+ // src/core/resources/auth-config/sso/types.ts
242103
+ var KNOWN_SSO_PROVIDERS = {
242104
+ google: "google",
242105
+ microsoft: "microsoft",
242106
+ github: "github",
242107
+ okta: "okta",
242108
+ custom: "custom"
242109
+ };
242110
+
242111
+ // src/core/resources/auth-config/sso/operations.ts
242112
+ var OPTION_TO_SECRET_KEY = {
242113
+ scope: "sso_scope" /* Scope */,
242114
+ discoveryUrl: "sso_discovery_url" /* DiscoveryUrl */,
242115
+ tenantId: "sso_tenant_id" /* TenantId */,
242116
+ oktaDomain: "sso_okta_domain" /* OktaDomain */,
242117
+ authEndpoint: "sso_auth_endpoint" /* AuthEndpoint */,
242118
+ tokenEndpoint: "sso_token_endpoint" /* TokenEndpoint */,
242119
+ userinfoEndpoint: "sso_userinfo_endpoint" /* UserinfoEndpoint */,
242120
+ jwksUri: "sso_jwks_uri" /* JwksUri */
242121
+ };
242086
242122
  async function updateSSOConfig(authDir, provider, enable) {
242087
242123
  const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
242088
242124
  const merged = {
@@ -242099,22 +242135,12 @@ async function updateSSOConfig(authDir, provider, enable) {
242099
242135
  await writeAuthConfig(authDir, merged);
242100
242136
  return merged;
242101
242137
  }
242102
- var OPTION_TO_SECRET_KEY = {
242103
- scope: "sso_scope",
242104
- discoveryUrl: "sso_discovery_url",
242105
- tenantId: "sso_tenant_id",
242106
- oktaDomain: "sso_okta_domain",
242107
- authEndpoint: "sso_auth_endpoint",
242108
- tokenEndpoint: "sso_token_endpoint",
242109
- userinfoEndpoint: "sso_userinfo_endpoint",
242110
- jwksUri: "sso_jwks_uri"
242111
- };
242112
242138
  function buildSSOSecrets(provider, options) {
242113
242139
  const schema3 = SSO_PROVIDER_SCHEMAS[provider];
242114
242140
  const secrets = {};
242115
- secrets.sso_name = options.ssoName ?? provider;
242116
- secrets.sso_client_id = options.clientId;
242117
- secrets.sso_client_secret = options.clientSecret;
242141
+ secrets["sso_name" /* Name */] = options.ssoName ?? provider;
242142
+ secrets["sso_client_id" /* ClientId */] = options.clientId;
242143
+ secrets["sso_client_secret" /* ClientSecret */] = options.clientSecret;
242118
242144
  for (const [optionKey, secretKey] of Object.entries(OPTION_TO_SECRET_KEY)) {
242119
242145
  const value = options[optionKey];
242120
242146
  if (typeof value === "string" && value.length > 0) {
@@ -242140,8 +242166,8 @@ function buildSSOSecrets(provider, options) {
242140
242166
  missing.push(key);
242141
242167
  }
242142
242168
  }
242143
- if (provider === "custom" && !options.ssoName) {
242144
- missing.push("sso_name");
242169
+ if (provider === KNOWN_SSO_PROVIDERS.custom && !options.ssoName) {
242170
+ missing.push("sso_name" /* Name */);
242145
242171
  }
242146
242172
  if (missing.length > 0) {
242147
242173
  throw new InvalidInputError(`Missing required fields for ${provider}: ${missing.join(", ")}`);
@@ -243564,6 +243590,7 @@ var package_default = {
243564
243590
  "@types/ejs": "^3.1.5",
243565
243591
  "@types/express": "^5.0.6",
243566
243592
  "@types/json-schema": "^7.0.15",
243593
+ "@types/jsonwebtoken": "^9.0.10",
243567
243594
  "@types/lodash": "^4.17.24",
243568
243595
  "@types/multer": "^2.0.0",
243569
243596
  "@types/node": "^22.10.5",
@@ -243582,6 +243609,7 @@ var package_default = {
243582
243609
  globby: "^16.1.0",
243583
243610
  "http-proxy-middleware": "^3.0.5",
243584
243611
  "json-schema-to-typescript": "^15.0.4",
243612
+ jsonwebtoken: "^9.0.3",
243585
243613
  json5: "^2.2.3",
243586
243614
  ky: "^1.14.2",
243587
243615
  lodash: "^4.17.23",
@@ -243597,6 +243625,7 @@ var package_default = {
243597
243625
  typescript: "^5.7.2",
243598
243626
  vitest: "^4.0.16",
243599
243627
  yaml: "^2.8.2",
243628
+ qs: "^6.12.3",
243600
243629
  zod: "^4.3.5"
243601
243630
  },
243602
243631
  engines: {
@@ -251234,19 +251263,20 @@ function mergeFileWithFlags(fileConfig, options) {
251234
251263
  ssoName: options.ssoName ?? fileConfig.ssoName
251235
251264
  };
251236
251265
  }
251266
+ var providerNames = Object.keys(KNOWN_SSO_PROVIDERS);
251237
251267
  function validateProvider(provider) {
251238
251268
  if (!provider) {
251239
251269
  throw new InvalidInputError("Missing --provider.", {
251240
251270
  hints: [
251241
251271
  {
251242
- message: `Valid providers: ${KNOWN_SSO_PROVIDERS.join(", ")}`,
251243
- command: "base44 auth sso enable --provider google --client-id <id> --client-secret <secret>"
251272
+ message: `Valid providers: ${providerNames.join(", ")}`,
251273
+ command: "base44 auth sso enable --provider <provider> --client-id <id> --client-secret <secret>"
251244
251274
  }
251245
251275
  ]
251246
251276
  });
251247
251277
  }
251248
- if (!KNOWN_SSO_PROVIDERS.includes(provider)) {
251249
- throw new InvalidInputError(`Unknown provider "${provider}". Valid providers: ${KNOWN_SSO_PROVIDERS.join(", ")}`);
251278
+ if (!(provider in KNOWN_SSO_PROVIDERS)) {
251279
+ throw new InvalidInputError(`Unknown provider "${provider}". Valid providers: ${providerNames.join(", ")}`);
251250
251280
  }
251251
251281
  return provider;
251252
251282
  }
@@ -253367,9 +253397,12 @@ function getTypesCommand() {
253367
253397
  return new Command("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
253368
253398
  }
253369
253399
 
253400
+ // src/cli/commands/dev.ts
253401
+ import process21 from "node:process";
253402
+
253370
253403
  // src/cli/dev/dev-server/main.ts
253371
253404
  var import_cors = __toESM(require_lib4(), 1);
253372
- var import_express5 = __toESM(require_express(), 1);
253405
+ var import_express6 = __toESM(require_express(), 1);
253373
253406
  import { dirname as dirname18, join as join25 } from "node:path";
253374
253407
 
253375
253408
  // ../../node_modules/get-port/index.js
@@ -253933,7 +253966,9 @@ class Validator {
253933
253966
  }
253934
253967
 
253935
253968
  // src/cli/dev/dev-server/db/database.ts
253969
+ var PRIVATE_COLLECTION_PREFIX = "$";
253936
253970
  var USER_COLLECTION = "user";
253971
+ var PRIVATE_USER_COLLECTION = PRIVATE_COLLECTION_PREFIX + USER_COLLECTION;
253937
253972
 
253938
253973
  class Database {
253939
253974
  collections = new Map;
@@ -253955,6 +253990,7 @@ class Database {
253955
253990
  this.schemas.set(USER_COLLECTION, this.buildUserSchema(userEntity));
253956
253991
  const collection = new import_nedb.default;
253957
253992
  this.collections.set(USER_COLLECTION, collection);
253993
+ this.collections.set(PRIVATE_USER_COLLECTION, new import_nedb.default);
253958
253994
  const userInfo = await readAuth();
253959
253995
  const now = getNowISOTimestamp();
253960
253996
  await collection.insertAsync({
@@ -253996,7 +254032,9 @@ class Database {
253996
254032
  return this.collections.get(this.normalizeName(name2));
253997
254033
  }
253998
254034
  getCollectionNames() {
253999
- return Array.from(this.collections.keys());
254035
+ return Array.from(this.collections.keys()).filter((name2) => {
254036
+ return !name2.startsWith(PRIVATE_COLLECTION_PREFIX);
254037
+ });
254000
254038
  }
254001
254039
  dropAll() {
254002
254040
  for (const collection of this.collections.values()) {
@@ -254060,15 +254098,229 @@ function broadcastEntityEvent(io6, appId, entityName, event) {
254060
254098
  });
254061
254099
  }
254062
254100
 
254063
- // src/cli/dev/dev-server/routes/entities/entities-router.ts
254064
- var import_express3 = __toESM(require_express(), 1);
254065
-
254066
- // src/cli/dev/dev-server/routes/entities/entities-user-router.ts
254101
+ // src/cli/dev/dev-server/routes/auth-router.ts
254067
254102
  var import_express2 = __toESM(require_express(), 1);
254068
254103
  var import_jsonwebtoken = __toESM(require_jsonwebtoken(), 1);
254069
- function createUserRouter(db2, logger2) {
254104
+ import { randomInt } from "node:crypto";
254105
+ var LOCAL_DEV_SECRET = "LOCAL_DEV_SECRET";
254106
+ var TEN_MINUTES = 10 * 60 * 1000;
254107
+ var generateCode = () => {
254108
+ return randomInt(1e5, 1e6).toString();
254109
+ };
254110
+ var createJwtToken = (email3) => {
254111
+ return import_jsonwebtoken.default.sign({ sub: email3 }, LOCAL_DEV_SECRET, {
254112
+ expiresIn: "360d"
254113
+ });
254114
+ };
254115
+ var LoginBody = object({ email: email2(), password: string2() });
254116
+ var VerifyOtpBody = object({ email: email2(), otp_code: string2() });
254117
+ function createAuthRouter(db2, logger2) {
254070
254118
  const router = import_express2.Router({ mergeParams: true });
254071
254119
  const parseBody = import_express2.json();
254120
+ router.post("/login", parseBody, async (req, res) => {
254121
+ const { email: email3, password } = LoginBody.parse(req.body);
254122
+ const result = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: email3 });
254123
+ if (result) {
254124
+ const privateUserData = await db2.getCollection(PRIVATE_USER_COLLECTION)?.findOneAsync({ email: email3 });
254125
+ if (result.role === "admin" || privateUserData?.password === password) {
254126
+ res.json({
254127
+ access_token: createJwtToken(email3),
254128
+ success: true,
254129
+ user: {}
254130
+ });
254131
+ } else {
254132
+ res.status(400).json({
254133
+ detail: "Invalid email or password",
254134
+ error_type: "HTTPException",
254135
+ message: "Invalid email or password",
254136
+ request_id: null,
254137
+ traceback: ""
254138
+ });
254139
+ }
254140
+ return;
254141
+ }
254142
+ res.status(401).json({ error: "Unauthorized" });
254143
+ });
254144
+ router.post("/register", parseBody, async (req, res) => {
254145
+ const { email: email3, password } = LoginBody.parse(req.body);
254146
+ if ((password || "").length < 8) {
254147
+ res.status(400).json({
254148
+ detail: "Password must be at least 8 characters long",
254149
+ error_type: "HTTPException",
254150
+ message: "Password must be at least 8 characters long",
254151
+ request_id: null,
254152
+ traceback: ""
254153
+ });
254154
+ return;
254155
+ }
254156
+ const result = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: email3 });
254157
+ if (result) {
254158
+ res.status(400).json({
254159
+ detail: "A user with this email already exists",
254160
+ error_type: "HTTPException",
254161
+ message: "A user with this email already exists",
254162
+ request_id: null,
254163
+ traceback: ""
254164
+ });
254165
+ return;
254166
+ }
254167
+ const privateUserCollection = db2.getCollection(PRIVATE_USER_COLLECTION);
254168
+ const privateUserData = await privateUserCollection?.findOneAsync({
254169
+ email: email3
254170
+ });
254171
+ const otpCode = generateCode();
254172
+ const id2 = privateUserData ? privateUserData.id : nanoid3();
254173
+ if (!privateUserData) {
254174
+ await privateUserCollection?.insertAsync({
254175
+ id: id2,
254176
+ email: email3,
254177
+ otpCode,
254178
+ password,
254179
+ createdAt: Date.now()
254180
+ });
254181
+ } else {
254182
+ await privateUserCollection?.updateAsync({
254183
+ email: email3
254184
+ }, {
254185
+ $set: {
254186
+ otpCode,
254187
+ createdAt: Date.now()
254188
+ }
254189
+ });
254190
+ }
254191
+ logger2.log(theme.styles.info(`
254192
+ In order to complete registration use this verification code: ${otpCode}
254193
+ `));
254194
+ res.json({
254195
+ id: id2,
254196
+ message: "Registration successful. Please check your email for the verification code.",
254197
+ otp_expires_in_minutes: 10
254198
+ });
254199
+ });
254200
+ router.post("/verify-otp", parseBody, async (req, res) => {
254201
+ const { email: email3, otp_code } = VerifyOtpBody.parse(req.body);
254202
+ const privateUserCollection = db2.getCollection(PRIVATE_USER_COLLECTION);
254203
+ const privateUserData = await privateUserCollection?.findOneAsync({
254204
+ email: email3
254205
+ });
254206
+ if (!privateUserData || privateUserData.otpCode !== otp_code) {
254207
+ const appId = req.params.appId;
254208
+ res.status(500).json({
254209
+ detail: `{'email': '${email3}', 'app_id': '${appId}}'} -> Object not found`,
254210
+ error_type: "ObjectNotFoundError",
254211
+ message: `{'email': '${email3}', 'app_id': '${appId}}'} -> Object not found`,
254212
+ request_id: null,
254213
+ traceback: ""
254214
+ });
254215
+ return;
254216
+ }
254217
+ if (+Date.now() - privateUserData.createdAt > TEN_MINUTES) {
254218
+ res.status(400).json({
254219
+ detail: "Verification code has expired",
254220
+ error_type: "HTTPException",
254221
+ message: "Verification code has expired",
254222
+ request_id: null,
254223
+ traceback: ""
254224
+ });
254225
+ } else {
254226
+ await privateUserCollection?.updateAsync({
254227
+ email: email3
254228
+ }, {
254229
+ $unset: { otpCode: true }
254230
+ });
254231
+ const collection = db2.getCollection(USER_COLLECTION);
254232
+ const now = getNowISOTimestamp();
254233
+ const nameFromEmailMatch = /^([^@]+)/.exec(email3);
254234
+ const fullName = nameFromEmailMatch ? nameFromEmailMatch[1] : email3;
254235
+ await collection?.insertAsync({
254236
+ id: privateUserData.id,
254237
+ email: email3,
254238
+ full_name: fullName,
254239
+ is_service: false,
254240
+ is_verified: true,
254241
+ disabled: null,
254242
+ role: "user",
254243
+ collaborator_role: "editor",
254244
+ created_date: now,
254245
+ updated_date: now
254246
+ });
254247
+ res.json({
254248
+ id: privateUserData.id,
254249
+ access_token: createJwtToken(email3),
254250
+ message: "Email verified successfully. You are now logged in.",
254251
+ success: true
254252
+ });
254253
+ }
254254
+ });
254255
+ return router;
254256
+ }
254257
+
254258
+ // src/cli/dev/dev-server/routes/entities/entities-router.ts
254259
+ var import_express4 = __toESM(require_express(), 1);
254260
+
254261
+ // src/cli/dev/dev-server/db/entity-queries.ts
254262
+ function parseSort(sort) {
254263
+ if (!sort) {
254264
+ return;
254265
+ }
254266
+ if (sort.startsWith("-")) {
254267
+ return { [sort.slice(1)]: -1 };
254268
+ }
254269
+ return { [sort]: 1 };
254270
+ }
254271
+ function parseFields(fields) {
254272
+ if (!fields) {
254273
+ return;
254274
+ }
254275
+ const projection = {};
254276
+ for (const field of fields.split(",")) {
254277
+ const trimmed = field.trim();
254278
+ if (trimmed) {
254279
+ projection[trimmed] = 1;
254280
+ }
254281
+ }
254282
+ return Object.keys(projection).length > 0 ? projection : undefined;
254283
+ }
254284
+ var queryEntity = async (collection, reqQuery) => {
254285
+ const { sort, limit, skip: skip2, fields, q: q13 } = reqQuery;
254286
+ let query = {};
254287
+ if (q13 && typeof q13 === "string") {
254288
+ try {
254289
+ query = JSON.parse(q13);
254290
+ } catch {
254291
+ throw new InvalidInputError("Invalid query parameter 'q'");
254292
+ }
254293
+ }
254294
+ let cursor3 = collection.findAsync(query);
254295
+ const sortObj = parseSort(sort);
254296
+ if (sortObj) {
254297
+ cursor3 = cursor3.sort(sortObj);
254298
+ }
254299
+ if (skip2) {
254300
+ const skipNum = Number.parseInt(skip2, 10);
254301
+ if (!Number.isNaN(skipNum)) {
254302
+ cursor3 = cursor3.skip(skipNum);
254303
+ }
254304
+ }
254305
+ if (limit) {
254306
+ const limitNum = Number.parseInt(limit, 10);
254307
+ if (!Number.isNaN(limitNum)) {
254308
+ cursor3 = cursor3.limit(limitNum);
254309
+ }
254310
+ }
254311
+ const projection = parseFields(fields);
254312
+ if (projection) {
254313
+ cursor3 = cursor3.projection(projection);
254314
+ }
254315
+ return cursor3;
254316
+ };
254317
+
254318
+ // src/cli/dev/dev-server/routes/entities/entities-user-router.ts
254319
+ var import_express3 = __toESM(require_express(), 1);
254320
+ var import_jsonwebtoken2 = __toESM(require_jsonwebtoken(), 1);
254321
+ function createUserRouter(db2, logger2) {
254322
+ const router = import_express3.Router({ mergeParams: true });
254323
+ const parseBody = import_express3.json();
254072
254324
  function withAuth(handler) {
254073
254325
  return async (req, res) => {
254074
254326
  const auth2 = req.headers.authorization;
@@ -254077,7 +254329,7 @@ function createUserRouter(db2, logger2) {
254077
254329
  return;
254078
254330
  }
254079
254331
  try {
254080
- const { payload } = import_jsonwebtoken.default.decode(auth2.replace("Bearer ", ""), { complete: true }) ?? {};
254332
+ const { payload } = import_jsonwebtoken2.default.decode(auth2.replace("Bearer ", ""), { complete: true }) ?? {};
254081
254333
  const result = await db2.getCollection(USER_COLLECTION)?.findOneAsync({ email: payload?.sub });
254082
254334
  if (!result) {
254083
254335
  res.status(404).json({ error: "Unable to read data for the current user" });
@@ -254110,6 +254362,28 @@ function createUserRouter(db2, logger2) {
254110
254362
  ...req.body
254111
254363
  });
254112
254364
  }));
254365
+ router.get("/", withAuth(async (req, res, currentUser) => {
254366
+ const collection = db2.getCollection(USER_COLLECTION);
254367
+ if (!collection) {
254368
+ res.status(404).json({ error: `Entity "${USER_COLLECTION}" not found` });
254369
+ return;
254370
+ }
254371
+ try {
254372
+ if (currentUser.role === "admin") {
254373
+ const result = await queryEntity(collection, req.query);
254374
+ res.json(stripInternalFields(result));
254375
+ } else {
254376
+ res.json([stripInternalFields(currentUser)]);
254377
+ }
254378
+ } catch (error48) {
254379
+ if (error48 instanceof InvalidInputError) {
254380
+ res.status(400).json({ error: error48.message });
254381
+ } else {
254382
+ logger2.error(`Error in GET /${USER_COLLECTION}:`, error48);
254383
+ res.status(500).json({ error: "Internal server error" });
254384
+ }
254385
+ }
254386
+ }));
254113
254387
  router.post("/bulk", async (_req, res) => {
254114
254388
  res.json({});
254115
254389
  });
@@ -254159,31 +254433,9 @@ function createUserRouter(db2, logger2) {
254159
254433
  }
254160
254434
 
254161
254435
  // src/cli/dev/dev-server/routes/entities/entities-router.ts
254162
- function parseSort(sort) {
254163
- if (!sort) {
254164
- return;
254165
- }
254166
- if (sort.startsWith("-")) {
254167
- return { [sort.slice(1)]: -1 };
254168
- }
254169
- return { [sort]: 1 };
254170
- }
254171
- function parseFields(fields) {
254172
- if (!fields) {
254173
- return;
254174
- }
254175
- const projection = {};
254176
- for (const field of fields.split(",")) {
254177
- const trimmed = field.trim();
254178
- if (trimmed) {
254179
- projection[trimmed] = 1;
254180
- }
254181
- }
254182
- return Object.keys(projection).length > 0 ? projection : undefined;
254183
- }
254184
254436
  async function createEntityRoutes(db2, logger2, broadcast) {
254185
- const router = import_express3.Router({ mergeParams: true });
254186
- const parseBody = import_express3.json();
254437
+ const router = import_express4.Router({ mergeParams: true });
254438
+ const parseBody = import_express4.json();
254187
254439
  function withCollection(handler) {
254188
254440
  return async (req, res) => {
254189
254441
  const collection = db2.getCollection(req.params.entityName);
@@ -254228,42 +254480,14 @@ async function createEntityRoutes(db2, logger2, broadcast) {
254228
254480
  router.get("/:entityName", withCollection(async (req, res, collection) => {
254229
254481
  const { entityName } = req.params;
254230
254482
  try {
254231
- const { sort, limit, skip: skip2, fields, q: q13 } = req.query;
254232
- let query = {};
254233
- if (q13 && typeof q13 === "string") {
254234
- try {
254235
- query = JSON.parse(q13);
254236
- } catch {
254237
- res.status(400).json({ error: "Invalid query parameter 'q'" });
254238
- return;
254239
- }
254240
- }
254241
- let cursor3 = collection.findAsync(query);
254242
- const sortObj = parseSort(sort);
254243
- if (sortObj) {
254244
- cursor3 = cursor3.sort(sortObj);
254245
- }
254246
- if (skip2) {
254247
- const skipNum = Number.parseInt(skip2, 10);
254248
- if (!Number.isNaN(skipNum)) {
254249
- cursor3 = cursor3.skip(skipNum);
254250
- }
254251
- }
254252
- if (limit) {
254253
- const limitNum = Number.parseInt(limit, 10);
254254
- if (!Number.isNaN(limitNum)) {
254255
- cursor3 = cursor3.limit(limitNum);
254256
- }
254257
- }
254258
- const projection = parseFields(fields);
254259
- if (projection) {
254260
- cursor3 = cursor3.projection(projection);
254261
- }
254262
- const docs = await cursor3;
254263
- res.json(stripInternalFields(docs));
254483
+ res.json(stripInternalFields(await queryEntity(collection, req.query)));
254264
254484
  } catch (error48) {
254265
- logger2.error(`Error in GET /${entityName}:`, error48);
254266
- res.status(500).json({ error: "Internal server error" });
254485
+ if (error48 instanceof InvalidInputError) {
254486
+ res.status(400).json({ error: error48.message });
254487
+ } else {
254488
+ logger2.error(`Error in GET /${entityName}:`, error48);
254489
+ res.status(500).json({ error: "Internal server error" });
254490
+ }
254267
254491
  }
254268
254492
  }));
254269
254493
  router.post("/:entityName", parseBody, withCollection(async (req, res, collection) => {
@@ -254382,7 +254606,7 @@ async function createEntityRoutes(db2, logger2, broadcast) {
254382
254606
  }
254383
254607
 
254384
254608
  // src/cli/dev/dev-server/routes/integrations.ts
254385
- var import_express4 = __toESM(require_express(), 1);
254609
+ var import_express5 = __toESM(require_express(), 1);
254386
254610
  var import_multer = __toESM(require_multer(), 1);
254387
254611
  import { createHash, randomUUID as randomUUID4 } from "node:crypto";
254388
254612
  import fs28 from "node:fs";
@@ -254391,8 +254615,8 @@ function createFileToken(fileUri) {
254391
254615
  return createHash("sha256").update(fileUri).digest("hex");
254392
254616
  }
254393
254617
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger2) {
254394
- const router = import_express4.Router({ mergeParams: true });
254395
- const parseBody = import_express4.json();
254618
+ const router = import_express5.Router({ mergeParams: true });
254619
+ const parseBody = import_express5.json();
254396
254620
  const privateFilesDir = path18.join(mediaFilesDir, "private");
254397
254621
  fs28.mkdirSync(mediaFilesDir, { recursive: true });
254398
254622
  fs28.mkdirSync(privateFilesDir, { recursive: true });
@@ -254462,7 +254686,7 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger2) {
254462
254686
  return router;
254463
254687
  }
254464
254688
  function createCustomIntegrationRoutes(remoteProxy, logger2) {
254465
- const router = import_express4.Router({ mergeParams: true });
254689
+ const router = import_express5.Router({ mergeParams: true });
254466
254690
  router.post("/:slug/:operationId", (req, res, next) => {
254467
254691
  logger2.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
254468
254692
  req.url = req.originalUrl;
@@ -256175,7 +256399,7 @@ async function createDevServer(options8) {
256175
256399
  const port = userPort ?? await getPorts({ port: DEFAULT_PORT });
256176
256400
  const baseUrl = `http://localhost:${port}`;
256177
256401
  const { functions, entities, project: project2 } = await options8.loadResources();
256178
- const app = import_express5.default();
256402
+ const app = import_express6.default();
256179
256403
  const remoteProxy = import_http_proxy_middleware2.createProxyMiddleware({
256180
256404
  target: BASE44_APP_URL,
256181
256405
  changeOrigin: true
@@ -256207,6 +256431,8 @@ async function createDevServer(options8) {
256207
256431
  let emitEntityEvent = () => {};
256208
256432
  const entityRoutes = await createEntityRoutes(db2, devLogger, (...args) => emitEntityEvent(...args));
256209
256433
  app.use("/api/apps/:appId/entities", entityRoutes);
256434
+ const authRouter = createAuthRouter(db2, devLogger);
256435
+ app.use("/api/apps/:appId/auth", authRouter);
256210
256436
  const { path: mediaFilesDir } = await $dir();
256211
256437
  app.use("/media/private/:fileUri", (req, res, next) => {
256212
256438
  const { fileUri } = req.params;
@@ -256226,13 +256452,15 @@ async function createDevServer(options8) {
256226
256452
  }
256227
256453
  next();
256228
256454
  });
256229
- app.use("/media", import_express5.default.static(mediaFilesDir));
256455
+ app.use("/media", import_express6.default.static(mediaFilesDir));
256230
256456
  const integrationRoutes = createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, devLogger);
256231
256457
  app.use("/api/apps/:appId/integration-endpoints", integrationRoutes);
256232
256458
  const customIntegrationRoutes = createCustomIntegrationRoutes(remoteProxy, devLogger);
256233
256459
  app.use("/api/apps/:appId/integrations/custom", customIntegrationRoutes);
256234
256460
  app.use((req, res, next) => {
256235
- devLogger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
256461
+ if (!req.originalUrl.endsWith("analytics/track/batch")) {
256462
+ devLogger.warn(`"${req.originalUrl}" is not supported in local development, passing call to production`);
256463
+ }
256236
256464
  remoteProxy(req, res, next);
256237
256465
  });
256238
256466
  const server = await new Promise((resolve10, reject) => {
@@ -256303,6 +256531,7 @@ async function devAction({ log }, options8) {
256303
256531
  const { port: resolvedPort } = await createDevServer({
256304
256532
  log,
256305
256533
  port,
256534
+ cwd: process21.cwd(),
256306
256535
  denoWrapperPath: getDenoWrapperPath(),
256307
256536
  loadResources: async () => {
256308
256537
  const { functions, entities, project: project2 } = await readProjectConfig();
@@ -260779,4 +261008,4 @@ export {
260779
261008
  CLIExitError
260780
261009
  };
260781
261010
 
260782
- //# debugId=0E9D3CB9AD716D0D64756E2164756E21
261011
+ //# debugId=939FB46B90B442D864756E2164756E21