@base44-preview/cli 0.0.50-pr.484.f8f85fa → 0.0.50-pr.484.ff9acc3

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