@rebasepro/server 0.9.1-canary.29ed165 → 0.9.1-canary.437af5f

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.
@@ -9,24 +9,9 @@ export declare class ApiError extends Error {
9
9
  readonly statusCode: number;
10
10
  readonly code: string;
11
11
  readonly details?: unknown;
12
- /**
13
- * Whether this outcome is a routine part of normal operation rather than
14
- * something an operator should look at. Expected errors log at debug; every
15
- * other operational error logs at warn.
16
- *
17
- * The motivating case is `POST /auth/refresh` with no session: clients
18
- * refresh on page load before they know whether one exists, so every
19
- * anonymous page view is a 401 — correct, and not worth a warning line.
20
- */
21
- readonly expected: boolean;
22
- constructor(statusCode: number, code: string, message: string, details?: unknown, expected?: boolean);
12
+ constructor(statusCode: number, code: string, message: string, details?: unknown);
23
13
  static badRequest(message: string, code?: string, details?: unknown): ApiError;
24
14
  static unauthorized(message: string, code?: string): ApiError;
25
- /**
26
- * A 401 that is a normal outcome, not an incident — logged at debug.
27
- * See {@link ApiError.expected}.
28
- */
29
- static unauthenticated(message: string, code?: string): ApiError;
30
15
  static forbidden(message: string, code?: string): ApiError;
31
16
  static notFound(message: string, code?: string): ApiError;
32
17
  static conflict(message: string, code?: string): ApiError;
@@ -12,11 +12,8 @@ import { CollectionConfig } from "@rebasepro/types";
12
12
  * columns, so the set is exact);
13
13
  * - the foreign-key column behind an owning relation, which callers may write
14
14
  * directly instead of through the relation property;
15
- * - anything named in `options.extraKnownFields` — for an auth collection the
16
- * credential keys the auth adapter consumes before a row is ever built;
17
15
  * - nothing else. `id` in particular is not automatically known — see below.
18
16
  */
19
17
  export declare function assertKnownWriteFields(values: Record<string, unknown>, collection: CollectionConfig, options?: {
20
18
  rowIndex?: number;
21
- extraKnownFields?: readonly string[];
22
19
  }): void;
package/dist/index.es.js CHANGED
@@ -3539,23 +3539,12 @@ var ApiError = class ApiError extends Error {
3539
3539
  statusCode;
3540
3540
  code;
3541
3541
  details;
3542
- /**
3543
- * Whether this outcome is a routine part of normal operation rather than
3544
- * something an operator should look at. Expected errors log at debug; every
3545
- * other operational error logs at warn.
3546
- *
3547
- * The motivating case is `POST /auth/refresh` with no session: clients
3548
- * refresh on page load before they know whether one exists, so every
3549
- * anonymous page view is a 401 — correct, and not worth a warning line.
3550
- */
3551
- expected;
3552
- constructor(statusCode, code, message, details, expected = false) {
3542
+ constructor(statusCode, code, message, details) {
3553
3543
  super(message);
3554
3544
  this.name = "ApiError";
3555
3545
  this.statusCode = statusCode;
3556
3546
  this.code = code;
3557
3547
  this.details = details;
3558
- this.expected = expected;
3559
3548
  }
3560
3549
  static badRequest(message, code = "BAD_REQUEST", details) {
3561
3550
  return new ApiError(400, code, message, details);
@@ -3563,13 +3552,6 @@ var ApiError = class ApiError extends Error {
3563
3552
  static unauthorized(message, code = "UNAUTHORIZED") {
3564
3553
  return new ApiError(401, code, message);
3565
3554
  }
3566
- /**
3567
- * A 401 that is a normal outcome, not an incident — logged at debug.
3568
- * See {@link ApiError.expected}.
3569
- */
3570
- static unauthenticated(message, code = "UNAUTHORIZED") {
3571
- return new ApiError(401, code, message, void 0, true);
3572
- }
3573
3555
  static forbidden(message, code = "FORBIDDEN") {
3574
3556
  return new ApiError(403, code, message);
3575
3557
  }
@@ -3602,10 +3584,7 @@ var errorHandler = (err, c) => {
3602
3584
  const error = err;
3603
3585
  const reqId = typeof c.get === "function" ? c.get("requestId") : void 0;
3604
3586
  if (error instanceof ApiError || error.name === "ApiError") {
3605
- const expected = error instanceof ApiError && error.expected;
3606
- const line = `[API] ${c.req.method} ${c.req.path} → ${error.statusCode} ${error.code}: ${error.message}` + (reqId ? ` [${reqId}]` : "");
3607
- if (expected) logger.debug(line);
3608
- else logger.warn(`⚠️ ${line}`);
3587
+ logger.warn(`⚠️ [API] ${c.req.method} ${c.req.path} → ${error.statusCode} ${error.code}: ${error.message}` + (reqId ? ` [${reqId}]` : ""));
3609
3588
  return c.json({ error: {
3610
3589
  message: error.message,
3611
3590
  code: error.code || "INTERNAL_ERROR",
@@ -3847,8 +3826,6 @@ function parseQueryOptions(query) {
3847
3826
  * columns, so the set is exact);
3848
3827
  * - the foreign-key column behind an owning relation, which callers may write
3849
3828
  * directly instead of through the relation property;
3850
- * - anything named in `options.extraKnownFields` — for an auth collection the
3851
- * credential keys the auth adapter consumes before a row is ever built;
3852
3829
  * - nothing else. `id` in particular is not automatically known — see below.
3853
3830
  */
3854
3831
  function assertKnownWriteFields(values, collection, options) {
@@ -3856,7 +3833,6 @@ function assertKnownWriteFields(values, collection, options) {
3856
3833
  if (!collection.properties || Object.keys(collection.properties).length === 0) return;
3857
3834
  const known = new Set(Object.keys(collection.properties));
3858
3835
  for (const relation of Object.values(resolveCollectionRelations(collection))) if (relation.localKey) known.add(relation.localKey);
3859
- for (const field of options?.extraKnownFields ?? []) known.add(field);
3860
3836
  const unknown = Object.keys(values).filter((key) => !known.has(key));
3861
3837
  if (unknown.length === 0) return;
3862
3838
  const where = options?.rowIndex !== void 0 ? `Row ${options.rowIndex}: ` : "";
@@ -4105,13 +4081,9 @@ var RestApiGenerator = class {
4105
4081
  const body = await parseJsonBody(c);
4106
4082
  const isAuth = collection.auth;
4107
4083
  const isAuthCollection = isAuth === true || isAuth && typeof isAuth === "object" && isAuth.enabled === true;
4108
- const collectionAuthConfig = typeof isAuth === "object" ? isAuth : void 0;
4109
4084
  if (!isAuthCollection) assertKnownWriteFields(body, resolvedCollection);
4110
- else {
4111
- const contract = this.authAdapter?.describeUserCreationContract?.(collectionAuthConfig);
4112
- if (contract?.validate) assertKnownWriteFields(body, resolvedCollection, { extraKnownFields: contract.extraFields });
4113
- }
4114
4085
  if (isAuthCollection && this.authAdapter?.prepareUserCreation) {
4086
+ const collectionAuthConfig = typeof isAuth === "object" ? isAuth : void 0;
4115
4087
  const prepared = await this.authAdapter.prepareUserCreation(body, collectionAuthConfig);
4116
4088
  const entity = await driver.save({
4117
4089
  path,
@@ -10375,7 +10347,7 @@ function createAuthRoutes(config) {
10375
10347
  oldPassword: string().min(1, "Old password is required").max(128),
10376
10348
  newPassword: string().min(1, "New password is required").max(128)
10377
10349
  });
10378
- const refreshSchema = object({ refreshToken: string().min(1).optional() });
10350
+ const refreshSchema = object({ refreshToken: config.cookieAuth ? string().optional() : string().min(1, "Refresh token is required") });
10379
10351
  object({ refreshToken: string().optional() });
10380
10352
  object({
10381
10353
  displayName: string().max(255).optional(),
@@ -10759,7 +10731,7 @@ function createAuthRoutes(config) {
10759
10731
  */
10760
10732
  router.post("/refresh", async (c) => {
10761
10733
  const refreshToken = readRefreshToken(c, parseBody(refreshSchema, await c.req.json().catch(() => ({}))), config.cookieAuth);
10762
- if (!refreshToken) throw ApiError.unauthenticated("No refresh token presented", "NO_SESSION");
10734
+ if (!refreshToken) throw ApiError.badRequest("Refresh token is required", "INVALID_INPUT");
10763
10735
  const tokenHash = hashRefreshToken(refreshToken);
10764
10736
  const storedToken = await authRepo.findRefreshTokenByHash(tokenHash);
10765
10737
  if (!storedToken) {
@@ -11281,16 +11253,6 @@ function createBuiltinAuthAdapter(config) {
11281
11253
  collectionAuthConfig: collectionAuth ?? collectionAuthConfig
11282
11254
  });
11283
11255
  },
11284
- describeUserCreationContract(collectionAuth) {
11285
- if ((collectionAuth ?? collectionAuthConfig)?.onCreateUser || resolvedOps.onAdminCreateUser) return {
11286
- validate: false,
11287
- extraFields: []
11288
- };
11289
- return {
11290
- validate: true,
11291
- extraFields: ["password"]
11292
- };
11293
- },
11294
11256
  async finalizeUserCreation(entity, clearPassword) {
11295
11257
  return finalizeAdminUserCreation(entity, clearPassword, {
11296
11258
  authRepo: authRepository,