@niledatabase/server 5.0.0-alpha.14 → 5.0.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8,6 +8,12 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
8
  var pg__default = /*#__PURE__*/_interopDefault(pg);
9
9
 
10
10
  // src/types.ts
11
+ var ExtensionState = /* @__PURE__ */ ((ExtensionState2) => {
12
+ ExtensionState2["onHandleRequest"] = "onHandleRequest";
13
+ ExtensionState2["onRequest"] = "onRequest";
14
+ ExtensionState2["onResponse"] = "onResposne";
15
+ return ExtensionState2;
16
+ })(ExtensionState || {});
11
17
  var APIErrorErrorCodeEnum = {
12
18
  InternalError: "internal_error",
13
19
  BadRequest: "bad_request",
@@ -189,7 +195,12 @@ async function request(url, _init, config) {
189
195
  params.headers.set("request-id", crypto.randomUUID());
190
196
  params.cache = "no-store";
191
197
  }
192
- await config.extensionCtx?.handleOnRequest(config, _init, params);
198
+ await config.extensionCtx?.runExtensions(
199
+ "onRequest" /* onRequest */,
200
+ config,
201
+ params,
202
+ _init
203
+ );
193
204
  try {
194
205
  const res = await fetch(fullUrl, {
195
206
  ...params
@@ -209,6 +220,14 @@ async function request(url, _init, config) {
209
220
  statusText: res?.statusText,
210
221
  text: await loggingRes?.text()
211
222
  });
223
+ const updatedRes = await config.extensionCtx?.runExtensions(
224
+ "onResposne" /* onResponse */,
225
+ config,
226
+ params
227
+ );
228
+ if (updatedRes) {
229
+ return updatedRes;
230
+ }
212
231
  return res;
213
232
  } catch (e) {
214
233
  if (e instanceof Error) {
@@ -232,16 +251,13 @@ async function auth(req, config) {
232
251
  info(`using session ${sessionUrl}`);
233
252
  req.headers.delete("content-length");
234
253
  const res = await request(sessionUrl, { request: req }, config);
235
- if (!res) {
236
- info("no session found");
237
- return void 0;
238
- }
239
- info("session active");
240
254
  try {
241
255
  const session = await new Response(res.body).json();
242
256
  if (Object.keys(session).length === 0) {
257
+ info("no session found");
243
258
  return void 0;
244
259
  }
260
+ info("session active");
245
261
  return session;
246
262
  } catch (e) {
247
263
  error(e);
@@ -480,7 +496,7 @@ async function PUT3(config, init) {
480
496
  init.method = "PUT";
481
497
  const url = `${apiRoutes(config).INVITE(tenantId)}`;
482
498
  const res = await request(url, init, config);
483
- const location = res?.headers.get("location");
499
+ const location = res?.headers?.get("location");
484
500
  if (location) {
485
501
  return new Response(res?.body, {
486
502
  status: 302,
@@ -853,7 +869,7 @@ async function route11(req, config) {
853
869
  ).catch((e) => {
854
870
  error("an error as occurred", e);
855
871
  });
856
- const location = res?.headers.get("location");
872
+ const location = res?.headers?.get("location");
857
873
  if (location) {
858
874
  return new Response(res?.body, {
859
875
  status: 302,
@@ -954,7 +970,7 @@ async function route15(req, config) {
954
970
  },
955
971
  config
956
972
  );
957
- const location = res?.headers.get("location");
973
+ const location = res?.headers?.get("location");
958
974
  if (location) {
959
975
  return new Response(res?.body, {
960
976
  status: 302,
@@ -998,7 +1014,7 @@ async function route16(req, config) {
998
1014
  },
999
1015
  config
1000
1016
  );
1001
- const location = res?.headers.get("location");
1017
+ const location = res?.headers?.get("location");
1002
1018
  if (location) {
1003
1019
  return new Response(res?.body, {
1004
1020
  status: 302,
@@ -1028,8 +1044,21 @@ async function fetchVerifyEmail(config, method, body) {
1028
1044
 
1029
1045
  // src/api/handlers/GET.ts
1030
1046
  function GETTER(configRoutes, config) {
1031
- const { info, warn } = config.logger("[GET MATCHER]");
1032
- return async function GET7(req) {
1047
+ const { error, info, warn } = config.logger("[GET MATCHER]");
1048
+ return async function GET7(...params) {
1049
+ const handledRequest = await config.extensionCtx?.runExtensions(
1050
+ "onHandleRequest" /* onHandleRequest */,
1051
+ config,
1052
+ params
1053
+ );
1054
+ if (handledRequest) {
1055
+ return handledRequest;
1056
+ }
1057
+ const req = params[0] instanceof Request ? params[0] : null;
1058
+ if (!req) {
1059
+ error("Proxy requests failed, a Request object was not passed.");
1060
+ return;
1061
+ }
1033
1062
  if (matches(configRoutes, req)) {
1034
1063
  info("matches me");
1035
1064
  return route(req, config);
@@ -1203,7 +1232,20 @@ async function fetchSignUp(config, payload) {
1203
1232
  // src/api/handlers/POST.ts
1204
1233
  function POSTER(configRoutes, config) {
1205
1234
  const { info, warn, error } = config.logger("[POST MATCHER]");
1206
- return async function POST6(req) {
1235
+ return async function POST6(...params) {
1236
+ const handledRequest = await config.extensionCtx?.runExtensions(
1237
+ "onHandleRequest" /* onHandleRequest */,
1238
+ config,
1239
+ params
1240
+ );
1241
+ if (handledRequest) {
1242
+ return handledRequest;
1243
+ }
1244
+ const req = params[0] instanceof Request ? params[0] : null;
1245
+ if (!req) {
1246
+ error("Proxy requests failed, a Request object was not passed.");
1247
+ return;
1248
+ }
1207
1249
  if (matchesLog(configRoutes, req)) {
1208
1250
  try {
1209
1251
  const json = await req.clone().json();
@@ -1378,8 +1420,21 @@ function matches19(configRoutes, request2) {
1378
1420
 
1379
1421
  // src/api/handlers/DELETE.ts
1380
1422
  function DELETER(configRoutes, config) {
1381
- const { info, warn } = config.logger("[DELETE MATCHER]");
1382
- return async function DELETE5(req) {
1423
+ const { error, info, warn } = config.logger("[DELETE MATCHER]");
1424
+ return async function DELETE5(...params) {
1425
+ const handledRequest = await config.extensionCtx?.runExtensions(
1426
+ "onHandleRequest" /* onHandleRequest */,
1427
+ config,
1428
+ params
1429
+ );
1430
+ if (handledRequest) {
1431
+ return handledRequest;
1432
+ }
1433
+ const req = params[0] instanceof Request ? params[0] : null;
1434
+ if (!req) {
1435
+ error("Proxy requests failed, a Request object was not passed.");
1436
+ return;
1437
+ }
1383
1438
  if (matches19(configRoutes, req)) {
1384
1439
  info("matches tenant invite id");
1385
1440
  return route19(req, config);
@@ -1388,10 +1443,6 @@ function DELETER(configRoutes, config) {
1388
1443
  info("matches tenant user");
1389
1444
  return route18(req, config);
1390
1445
  }
1391
- if (matches3(configRoutes, req)) {
1392
- info("matches tenant users");
1393
- return route3(req, config);
1394
- }
1395
1446
  if (matches6(configRoutes, req)) {
1396
1447
  info("matches tenants");
1397
1448
  return route6(req, config);
@@ -1407,8 +1458,21 @@ function DELETER(configRoutes, config) {
1407
1458
 
1408
1459
  // src/api/handlers/PUT.ts
1409
1460
  function PUTER(configRoutes, config) {
1410
- const { info, warn } = config.logger("[PUT MATCHER]");
1411
- return async function PUT6(req) {
1461
+ const { error, info, warn } = config.logger("[PUT MATCHER]");
1462
+ return async function PUT6(...params) {
1463
+ const handledRequest = await config.extensionCtx?.runExtensions(
1464
+ "onHandleRequest" /* onHandleRequest */,
1465
+ config,
1466
+ params
1467
+ );
1468
+ if (handledRequest) {
1469
+ return handledRequest;
1470
+ }
1471
+ const req = params[0] instanceof Request ? params[0] : null;
1472
+ if (!req) {
1473
+ error("Proxy requests failed, a Request object was not passed.");
1474
+ return;
1475
+ }
1412
1476
  if (matches4(configRoutes, req)) {
1413
1477
  info("matches tenant invite");
1414
1478
  return route4(req, config);
@@ -2347,6 +2411,9 @@ var Auth = class {
2347
2411
  }
2348
2412
  info(`Obtaining providers for ${email}`);
2349
2413
  info(`Attempting sign in with email ${email}`);
2414
+ if (!email) {
2415
+ throw new Error("Email missing from payload, unable to sign in");
2416
+ }
2350
2417
  const body = JSON.stringify({
2351
2418
  email,
2352
2419
  password,
@@ -2464,6 +2531,7 @@ function defaultCallbackUrl({ config }) {
2464
2531
  async function obtainCsrf(config, rawResponse = false) {
2465
2532
  const res = await fetchCsrf(config);
2466
2533
  const csrfCook = parseCSRF(res.headers);
2534
+ const h = new Headers();
2467
2535
  if (csrfCook) {
2468
2536
  const [, value] = csrfCook.split("=");
2469
2537
  const [token] = decodeURIComponent(value).split("|");
@@ -2475,7 +2543,8 @@ async function obtainCsrf(config, rawResponse = false) {
2475
2543
  parseToken(res.headers)
2476
2544
  ].filter(Boolean).join("; ");
2477
2545
  config.headers.set("cookie", cookie);
2478
- updateHeaders(new Headers({ cookie }));
2546
+ h.set("cookie", cookie);
2547
+ updateHeaders(h);
2479
2548
  }
2480
2549
  if (!rawResponse) {
2481
2550
  return { csrfToken: token };
@@ -2923,24 +2992,26 @@ function handlersWithContext(config) {
2923
2992
  function updateConfig(response, config) {
2924
2993
  let origin = "http://localhost:3000";
2925
2994
  let headers = null;
2926
- if (response?.status === 302) {
2927
- const location = response.headers.get("location");
2928
- if (location) {
2929
- const urlLocation = new URL(location);
2930
- origin = urlLocation.origin;
2995
+ if (response instanceof Response) {
2996
+ if (response?.status === 302) {
2997
+ const location = response.headers.get("location");
2998
+ if (location) {
2999
+ const urlLocation = new URL(location);
3000
+ origin = urlLocation.origin;
3001
+ }
2931
3002
  }
2932
- }
2933
- const setCookies = [];
2934
- if (response?.headers) {
2935
- for (const [key17, value] of response.headers) {
2936
- if (key17.toLowerCase() === "set-cookie") {
2937
- setCookies.push(value);
3003
+ const setCookies = [];
3004
+ if (response?.headers) {
3005
+ for (const [key17, value] of response.headers) {
3006
+ if (key17.toLowerCase() === "set-cookie") {
3007
+ setCookies.push(value);
3008
+ }
2938
3009
  }
2939
3010
  }
2940
- }
2941
- if (setCookies.length > 0) {
2942
- const cookieHeader = setCookies.map((cookieStr) => cookieStr.split(";")[0]).join("; ");
2943
- headers = new Headers({ cookie: cookieHeader });
3011
+ if (setCookies.length > 0) {
3012
+ const cookieHeader = setCookies.map((cookieStr) => cookieStr.split(";")[0]).join("; ");
3013
+ headers = new Headers({ cookie: cookieHeader });
3014
+ }
2944
3015
  }
2945
3016
  return {
2946
3017
  ...config,
@@ -2951,26 +3022,51 @@ function updateConfig(response, config) {
2951
3022
  }
2952
3023
 
2953
3024
  // src/api/utils/extensions.ts
2954
- function bindHandleOnRequest(instance) {
2955
- return async function handleOnRequest(config, _init, params) {
3025
+ function getRequestConfig(params) {
3026
+ if (typeof params[1] === "object") {
3027
+ return params[1];
3028
+ }
3029
+ return {};
3030
+ }
3031
+ function bindRunExtensions(instance) {
3032
+ return async function runExtensions(toRun, config, params, _init) {
2956
3033
  const { debug } = config.logger("[EXTENSIONS]");
3034
+ const extensionConfig = getRequestConfig(
3035
+ Array.isArray(params) ? params : [null, params]
3036
+ );
2957
3037
  if (config.extensions) {
2958
3038
  for (const create2 of config.extensions) {
2959
3039
  if (typeof create2 !== "function") {
2960
- return void 0;
3040
+ continue;
3041
+ }
3042
+ const ext = create2(instance);
3043
+ if (extensionConfig.disableExtensions?.includes(ext.id)) {
3044
+ continue;
2961
3045
  }
2962
- const ext = await create2(instance);
2963
- if (ext.onRequest) {
3046
+ if (ext.onHandleRequest && toRun === "onHandleRequest" /* onHandleRequest */) {
3047
+ const result = await ext.onHandleRequest(
3048
+ ...Array.isArray(params) ? params : [params]
3049
+ );
3050
+ if (result != null) {
3051
+ return result;
3052
+ }
3053
+ continue;
3054
+ }
3055
+ const [param] = Array.isArray(params) ? params : [params];
3056
+ if (ext.onRequest && toRun === "onRequest" /* onRequest */) {
2964
3057
  const previousContext = instance.getContext();
2965
3058
  if (previousContext.preserveHeaders) {
2966
3059
  instance.setContext({ preserveHeaders: false });
2967
3060
  }
3061
+ if (!_init) {
3062
+ continue;
3063
+ }
2968
3064
  await ext.onRequest(_init.request);
2969
3065
  const updatedContext = instance.getContext();
2970
3066
  if (updatedContext?.headers) {
2971
3067
  const cookie = updatedContext.headers.get("cookie");
2972
- if (cookie) {
2973
- params.headers.set(
3068
+ if (cookie && param.headers) {
3069
+ param.headers.set(
2974
3070
  "cookie",
2975
3071
  mergeCookies(
2976
3072
  previousContext.preserveHeaders ? previousContext.headers?.get("cookie") : null,
@@ -2978,22 +3074,31 @@ function bindHandleOnRequest(instance) {
2978
3074
  )
2979
3075
  );
2980
3076
  }
2981
- if (updatedContext.tenantId) {
2982
- params.headers.set(
3077
+ if (updatedContext.tenantId && param.headers) {
3078
+ param.headers.set(
2983
3079
  TENANT_COOKIE,
2984
3080
  String(updatedContext.headers.get(TENANT_COOKIE))
2985
3081
  );
2986
3082
  }
2987
3083
  }
2988
3084
  debug(`${ext.id ?? create2.name} ran onRequest`);
3085
+ continue;
3086
+ }
3087
+ if (ext.onResponse && toRun === "onResposne" /* onResponse */) {
3088
+ const result = await ext.onResponse(param);
3089
+ if (result != null) {
3090
+ return result;
3091
+ }
3092
+ continue;
2989
3093
  }
2990
3094
  }
2991
3095
  }
3096
+ return void 0;
2992
3097
  };
2993
3098
  }
2994
3099
  function buildExtensionConfig(instance) {
2995
3100
  return {
2996
- handleOnRequest: bindHandleOnRequest(instance)
3101
+ runExtensions: bindRunExtensions(instance)
2997
3102
  };
2998
3103
  }
2999
3104
  function mergeCookies(...cookieStrings) {
@@ -3015,7 +3120,6 @@ var Server = class {
3015
3120
  auth;
3016
3121
  #config;
3017
3122
  #handlers;
3018
- #paths;
3019
3123
  #manager;
3020
3124
  #headers;
3021
3125
  #preserveHeaders;
@@ -3045,13 +3149,23 @@ var Server = class {
3045
3149
  withContext: handlersWithContext(this.#config)
3046
3150
  };
3047
3151
  this.#preserveHeaders = config?.preserveHeaders ?? false;
3048
- this.#paths = this.#config.paths;
3049
3152
  this.#config.tenantId = getTenantId({ config: this.#config });
3050
3153
  this.#manager = new DBManager(this.#config);
3051
3154
  this.#handleHeaders(config);
3052
3155
  this.users = new Users(this.#config);
3053
3156
  this.tenants = new Tenants(this.#config);
3054
3157
  this.auth = new Auth(this.#config);
3158
+ if (config?.extensions) {
3159
+ for (const create2 of config.extensions) {
3160
+ if (typeof create2 !== "function") {
3161
+ continue;
3162
+ }
3163
+ const ext = create2(this);
3164
+ if (ext.onConfigure) {
3165
+ ext.onConfigure();
3166
+ }
3167
+ }
3168
+ }
3055
3169
  }
3056
3170
  get db() {
3057
3171
  const pool = this.#manager.getConnection(this.#config);
@@ -3061,6 +3175,28 @@ var Server = class {
3061
3175
  }
3062
3176
  });
3063
3177
  }
3178
+ get logger() {
3179
+ return this.#config.logger;
3180
+ }
3181
+ get extensions() {
3182
+ return {
3183
+ remove: async (id) => {
3184
+ if (!this.#config.extensions) return;
3185
+ const resolved = this.#config.extensions.map((ext) => ext(this));
3186
+ const index = resolved.findIndex((ext) => ext.id === id);
3187
+ if (index !== -1) {
3188
+ this.#config.extensions.splice(index, 1);
3189
+ }
3190
+ return resolved;
3191
+ },
3192
+ add: (extension) => {
3193
+ if (!this.#config.extensions) {
3194
+ this.#config.extensions = [];
3195
+ }
3196
+ this.#config.extensions.push(extension);
3197
+ }
3198
+ };
3199
+ }
3064
3200
  /**
3065
3201
  * A convenience function that applies a config and ensures whatever was passed is set properly
3066
3202
  */
@@ -3076,12 +3212,15 @@ var Server = class {
3076
3212
  this.#reset();
3077
3213
  return this;
3078
3214
  }
3079
- getPaths() {
3080
- return this.#paths;
3081
- }
3082
3215
  get handlers() {
3083
3216
  return this.#handlers;
3084
3217
  }
3218
+ get paths() {
3219
+ return this.#config.paths;
3220
+ }
3221
+ set paths(paths) {
3222
+ this.#config.paths = paths;
3223
+ }
3085
3224
  /**
3086
3225
  * Allow the setting of headers from a req or header object.
3087
3226
  * Makes it possible to handle REST requests easily
@@ -3089,7 +3228,27 @@ var Server = class {
3089
3228
  * @param req
3090
3229
  * @returns undefined
3091
3230
  */
3092
- setContext(req) {
3231
+ setContext = (req, ...remaining) => {
3232
+ let atLeastOne = false;
3233
+ if (this.#config?.extensions) {
3234
+ for (const create2 of this.#config.extensions) {
3235
+ if (typeof create2 !== "function") {
3236
+ continue;
3237
+ }
3238
+ const ext = create2(this);
3239
+ if (typeof ext.onSetContext === "function") {
3240
+ if (req) {
3241
+ ext.onSetContext(req, ...remaining);
3242
+ atLeastOne = true;
3243
+ } else {
3244
+ this.#config.logger("extension").warn("attempted to call onSetContext without a value");
3245
+ }
3246
+ }
3247
+ }
3248
+ }
3249
+ if (atLeastOne) {
3250
+ return;
3251
+ }
3093
3252
  try {
3094
3253
  if (req instanceof Headers) {
3095
3254
  this.#handleHeaders(req);
@@ -3119,11 +3278,14 @@ var Server = class {
3119
3278
  return;
3120
3279
  }
3121
3280
  if (typeof req === "object") {
3122
- const headers = new Headers(req);
3123
- if (headers) {
3124
- this.#handleHeaders(headers);
3125
- this.#reset();
3126
- return;
3281
+ try {
3282
+ const headers = new Headers(req);
3283
+ if (headers) {
3284
+ this.#handleHeaders(headers);
3285
+ this.#reset();
3286
+ return;
3287
+ }
3288
+ } catch {
3127
3289
  }
3128
3290
  }
3129
3291
  const { warn } = Logger(this.#config)("[API]");
@@ -3132,12 +3294,12 @@ var Server = class {
3132
3294
  "Set context expects a Request, Header instance or an object of Record<string, string>"
3133
3295
  );
3134
3296
  }
3135
- }
3297
+ };
3136
3298
  getContext() {
3137
3299
  return {
3138
3300
  headers: this.#headers,
3139
- userId: this.#config.userId,
3140
- tenantId: this.#config.tenantId,
3301
+ userId: this.#config?.userId,
3302
+ tenantId: this.#config?.tenantId,
3141
3303
  preserveHeaders: this.#preserveHeaders
3142
3304
  };
3143
3305
  }
@@ -3190,6 +3352,7 @@ var Server = class {
3190
3352
  */
3191
3353
  #reset = () => {
3192
3354
  this.#config.headers = this.#headers ?? new Headers();
3355
+ this.#config.extensionCtx = buildExtensionConfig(this);
3193
3356
  this.users = new Users(this.#config);
3194
3357
  this.tenants = new Tenants(this.#config);
3195
3358
  this.auth = new Auth(this.#config);
@@ -3204,6 +3367,7 @@ function create(config) {
3204
3367
  }
3205
3368
 
3206
3369
  exports.APIErrorErrorCodeEnum = APIErrorErrorCodeEnum;
3370
+ exports.ExtensionState = ExtensionState;
3207
3371
  exports.HEADER_ORIGIN = HEADER_ORIGIN;
3208
3372
  exports.HEADER_SECURE_COOKIES = HEADER_SECURE_COOKIES;
3209
3373
  exports.LoginUserResponseTokenTypeEnum = LoginUserResponseTokenTypeEnum;
@@ -3213,6 +3377,7 @@ exports.TENANT_COOKIE = TENANT_COOKIE;
3213
3377
  exports.USER_COOKIE = USER_COOKIE;
3214
3378
  exports.parseCSRF = parseCSRF;
3215
3379
  exports.parseCallback = parseCallback;
3380
+ exports.parseResetToken = parseResetToken;
3216
3381
  exports.parseToken = parseToken;
3217
3382
  //# sourceMappingURL=index.js.map
3218
3383
  //# sourceMappingURL=index.js.map