@sqrzro/server 2.0.0-bz.23 → 2.0.0-bz.25

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.
@@ -1,5 +1,8 @@
1
1
  import { createClient } from 'redis';
2
2
  let client = null;
3
+ function isLocalhost(url) {
4
+ return url.includes('localhost') || url.includes('127.0.0.1');
5
+ }
3
6
  async function getClient() {
4
7
  if (!process.env.REDIS_URL) {
5
8
  throw new Error('REDIS_URL is not defined. Access to the cache is not possible.');
@@ -9,7 +12,7 @@ async function getClient() {
9
12
  }
10
13
  client = createClient({
11
14
  socket: {
12
- tls: true,
15
+ tls: !isLocalhost(process.env.REDIS_URL),
13
16
  },
14
17
  url: process.env.REDIS_URL,
15
18
  });
@@ -1,6 +1,6 @@
1
1
  import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
2
2
  declare global {
3
- var db: ReturnType<typeof createSingleton> | undefined;
3
+ var szdb: ReturnType<typeof createSingleton> | undefined;
4
4
  }
5
5
  declare function createSingleton(): PostgresJsDatabase;
6
6
  export declare const db: PostgresJsDatabase;
@@ -6,7 +6,7 @@ function createSingleton() {
6
6
  }
7
7
  return drizzle(postgres(process.env.DATABASE_URL, { prepare: false }));
8
8
  }
9
- export const db = globalThis.db ?? createSingleton();
9
+ export const db = globalThis.szdb ?? createSingleton();
10
10
  if (!process.env.VERCEL_ENV) {
11
- globalThis.db = db;
11
+ globalThis.szdb = db;
12
12
  }
@@ -1,5 +1,6 @@
1
- import type { Errorable } from '@sqrzro/interfaces';
1
+ import type { SerializedErrorable } from '@sqrzro/interfaces';
2
2
  import type Joi from 'joi';
3
+ import { NextResponse } from 'next/server';
3
4
  import ValidationError from './ValidationError';
4
5
  interface SubmitFormArgs<F extends object> {
5
6
  formData: F;
@@ -11,6 +12,7 @@ interface SubmitFormArgsWithFn<F extends object, M> extends Omit<SubmitFormArgs<
11
12
  fn: (data: F) => Promise<M | null>;
12
13
  onSuccess?: (model: M) => Promise<void> | void;
13
14
  }
14
- export declare function submitForm<F extends object>(args: SubmitFormArgs<F>): Promise<Errorable<F>>;
15
- export declare function submitForm<F extends object, M>(args: SubmitFormArgsWithFn<F, M>): Promise<Errorable<M>>;
15
+ export declare function submitForm<F extends object>(args: SubmitFormArgs<F>): Promise<SerializedErrorable<F>>;
16
+ export declare function submitForm<F extends object, M>(args: SubmitFormArgsWithFn<F, M>): Promise<SerializedErrorable<M>>;
17
+ export declare function submitAPIRequest<F extends object, M>(args: SubmitFormArgsWithFn<F, M>): Promise<[M, null] | [null, NextResponse]>;
16
18
  export {};
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable max-statements */
2
+ import { NextResponse } from 'next/server';
2
3
  import ValidationError from './ValidationError';
3
4
  import { validateSchema } from './ValidationService';
4
5
  function serializeError(err) {
@@ -76,3 +77,22 @@ export async function submitForm(args) {
76
77
  }
77
78
  return [model, null];
78
79
  }
80
+ export async function submitAPIRequest(args) {
81
+ const [response, error] = await submitForm(args);
82
+ if (error !== null) {
83
+ if (error.name === 'ValidationError') {
84
+ try {
85
+ const errors = JSON.parse(error.message);
86
+ return [null, NextResponse.json(errors, { status: 422 })];
87
+ }
88
+ catch (err) {
89
+ return [
90
+ null,
91
+ NextResponse.json({ message: 'An unknown error occured' }, { status: 500 }),
92
+ ];
93
+ }
94
+ }
95
+ return [null, NextResponse.json({ message: error.message }, { status: 500 })];
96
+ }
97
+ return [response, null];
98
+ }
@@ -2,6 +2,7 @@ import { NextResponse } from 'next/server';
2
2
  const DEFAULT_REDIRECT = '/auth/login';
3
3
  function applyHeaders(request, response) {
4
4
  response.headers.set('x-origin', request.nextUrl.origin);
5
+ response.headers.set('x-pathname', request.nextUrl.pathname);
5
6
  response.headers.set('x-search-params', request.nextUrl.searchParams.toString());
6
7
  return response;
7
8
  }
@@ -14,6 +15,10 @@ function redirect(request, pathname = DEFAULT_REDIRECT) {
14
15
  }
15
16
  return applyHeaders(request, NextResponse.redirect(`${request.nextUrl.origin}${pathname}?r=${encodeURIComponent(getRelativeUrl(request.nextUrl))}`));
16
17
  }
18
+ /*
19
+ * When deployed to Vercel in a preview environment, we need to bypass the protection when fetching
20
+ * the session from the API.
21
+ */
17
22
  function bypassProtection() {
18
23
  const headers = new Headers();
19
24
  if (process.env.VERCEL_PROTECTION_BYPASS) {
@@ -22,26 +27,20 @@ function bypassProtection() {
22
27
  return { headers };
23
28
  }
24
29
  export async function handleMiddleware(request, nextFn) {
25
- console.log('middleware', request.nextUrl.pathname);
26
30
  // If the URL is /api/session, we should just return the response, otherwise we end up in a loop
27
31
  if (request.nextUrl.pathname === '/api/session') {
28
- console.log('URL is /api/session, returning');
29
32
  return applyHeaders(request, nextFn ? nextFn() : NextResponse.next());
30
33
  }
31
- console.log('URL is not /api/session, continuing');
32
34
  const sessionID = request.cookies.get(process.env.AUTH_COOKIE_NAME || 'auth_session')?.value || '';
33
- console.log(sessionID);
34
35
  try {
35
36
  const session = await fetch(`${request.nextUrl.origin}/api/session?id=${sessionID}&pathname=${request.nextUrl.pathname}`, bypassProtection());
36
37
  const json = (await session.json());
37
- console.log('json', json);
38
38
  if (json.redirect === null) {
39
39
  return applyHeaders(request, nextFn ? nextFn() : NextResponse.next());
40
40
  }
41
41
  return redirect(request, json.redirect);
42
42
  }
43
43
  catch (err) {
44
- console.log('error', err);
45
44
  return redirect(request);
46
45
  }
47
46
  }
@@ -15,6 +15,7 @@
15
15
  * @returns The origin of the current request.
16
16
  */
17
17
  export declare function getOrigin(): string;
18
+ export declare function getPathname(): string;
18
19
  /**
19
20
  * Builds a URL from the current origin and a given pathname. For more information on how the origin
20
21
  * is determined, see the `getOrigin` function. This function then just concatenates the origin and
@@ -23,4 +24,8 @@ export declare function getOrigin(): string;
23
24
  * @param pathname
24
25
  * @returns The URL, with the origin and pathname combined.
25
26
  */
27
+ export declare function makeURL(pathname?: string): string;
28
+ /**
29
+ * @deprecated Use `makeURL` instead.
30
+ */
26
31
  export declare function getURL(pathname?: string): string;
@@ -27,6 +27,13 @@ export function getOrigin() {
27
27
  }
28
28
  throw new Error('No origin could be determined');
29
29
  }
30
+ export function getPathname() {
31
+ const pathname = headers().get('x-pathname');
32
+ if (pathname) {
33
+ return pathname;
34
+ }
35
+ throw new Error('No pathname could be determined. Please make sure middleware is being applied to the current request.');
36
+ }
30
37
  /**
31
38
  * Builds a URL from the current origin and a given pathname. For more information on how the origin
32
39
  * is determined, see the `getOrigin` function. This function then just concatenates the origin and
@@ -35,7 +42,7 @@ export function getOrigin() {
35
42
  * @param pathname
36
43
  * @returns The URL, with the origin and pathname combined.
37
44
  */
38
- export function getURL(pathname) {
45
+ export function makeURL(pathname) {
39
46
  const origin = getOrigin();
40
47
  if (!pathname) {
41
48
  return origin;
@@ -46,3 +53,9 @@ export function getURL(pathname) {
46
53
  const cleanURL = `${originWithoutProtocol}/${pathname}`.replace(/\/+/gu, '/');
47
54
  return `${protocol}${cleanURL}`;
48
55
  }
56
+ /**
57
+ * @deprecated Use `makeURL` instead.
58
+ */
59
+ export function getURL(pathname) {
60
+ return makeURL(pathname);
61
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqrzro/server",
3
- "version": "2.0.0-bz.23",
3
+ "version": "2.0.0-bz.25",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "ISC",