@sqrzro/server 2.0.0-bz.10 → 2.0.0-bz.12

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.
Files changed (84) hide show
  1. package/auth.d.ts +1 -1
  2. package/auth.js +1 -1
  3. package/cache.d.ts +1 -1
  4. package/cache.js +1 -1
  5. package/dist/auth.d.ts +100 -0
  6. package/dist/auth.js +891 -0
  7. package/dist/cache.d.ts +4 -0
  8. package/dist/cache.js +46 -0
  9. package/dist/forms.d.ts +46 -0
  10. package/dist/forms.js +327 -0
  11. package/dist/{lists/ListService.d.ts → lists.d.ts} +5 -3
  12. package/dist/lists.js +61 -0
  13. package/dist/mail.d.ts +12 -0
  14. package/dist/mail.js +97 -0
  15. package/dist/middleware.d.ts +5 -3
  16. package/dist/middleware.js +58 -22
  17. package/dist/{database/schema.d.ts → schema.d.ts} +38 -34
  18. package/dist/schema.js +77 -0
  19. package/dist/{url/URLService.d.ts → url.d.ts} +4 -2
  20. package/dist/url.js +56 -0
  21. package/forms.d.ts +1 -1
  22. package/forms.js +1 -1
  23. package/lists.d.ts +1 -1
  24. package/lists.js +1 -1
  25. package/mail.d.ts +1 -1
  26. package/mail.js +1 -1
  27. package/package.json +10 -11
  28. package/schema.d.ts +1 -1
  29. package/schema.js +1 -1
  30. package/url.d.ts +1 -1
  31. package/url.js +1 -1
  32. package/database.d.ts +0 -1
  33. package/database.js +0 -1
  34. package/dist/auth/AuthService.d.ts +0 -14
  35. package/dist/auth/AuthService.js +0 -135
  36. package/dist/auth/ClientService.d.ts +0 -11
  37. package/dist/auth/ClientService.js +0 -47
  38. package/dist/auth/LoginRequest.d.ts +0 -4
  39. package/dist/auth/LoginRequest.js +0 -8
  40. package/dist/auth/MFARequest.d.ts +0 -4
  41. package/dist/auth/MFARequest.js +0 -9
  42. package/dist/auth/MFAService.d.ts +0 -6
  43. package/dist/auth/MFAService.js +0 -105
  44. package/dist/auth/PasswordRequest.d.ts +0 -4
  45. package/dist/auth/PasswordRequest.js +0 -12
  46. package/dist/auth/PasswordResetRequest.d.ts +0 -4
  47. package/dist/auth/PasswordResetRequest.js +0 -13
  48. package/dist/auth/PasswordService.d.ts +0 -8
  49. package/dist/auth/PasswordService.js +0 -54
  50. package/dist/auth/SessionService.d.ts +0 -42
  51. package/dist/auth/SessionService.js +0 -127
  52. package/dist/auth/index.d.ts +0 -6
  53. package/dist/auth/index.js +0 -6
  54. package/dist/auth/interfaces.d.ts +0 -20
  55. package/dist/auth/interfaces.js +0 -1
  56. package/dist/cache/CacheService.d.ts +0 -2
  57. package/dist/cache/CacheService.js +0 -14
  58. package/dist/cache/index.d.ts +0 -1
  59. package/dist/cache/index.js +0 -1
  60. package/dist/database/DatabaseService.d.ts +0 -7
  61. package/dist/database/DatabaseService.js +0 -12
  62. package/dist/database/schema.js +0 -42
  63. package/dist/forms/FormService.d.ts +0 -16
  64. package/dist/forms/FormService.js +0 -78
  65. package/dist/forms/ImageService.d.ts +0 -7
  66. package/dist/forms/ImageService.js +0 -19
  67. package/dist/forms/ValidationError.d.ts +0 -4
  68. package/dist/forms/ValidationError.js +0 -7
  69. package/dist/forms/ValidationService.d.ts +0 -20
  70. package/dist/forms/ValidationService.js +0 -59
  71. package/dist/forms/index.d.ts +0 -3
  72. package/dist/forms/index.js +0 -3
  73. package/dist/forms/lang.d.ts +0 -2
  74. package/dist/forms/lang.js +0 -115
  75. package/dist/lists/ListService.js +0 -28
  76. package/dist/lists/index.d.ts +0 -1
  77. package/dist/lists/index.js +0 -1
  78. package/dist/mail/MailService.d.ts +0 -12
  79. package/dist/mail/MailService.js +0 -55
  80. package/dist/mail/index.d.ts +0 -1
  81. package/dist/mail/index.js +0 -1
  82. package/dist/url/URLService.js +0 -48
  83. package/dist/url/index.d.ts +0 -1
  84. package/dist/url/index.js +0 -1
@@ -1 +0,0 @@
1
- export * from './CacheService';
@@ -1,7 +0,0 @@
1
- import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
2
- declare global {
3
- var db: ReturnType<typeof createSingleton> | undefined;
4
- }
5
- declare function createSingleton(): PostgresJsDatabase;
6
- export declare const db: PostgresJsDatabase;
7
- export {};
@@ -1,12 +0,0 @@
1
- import { drizzle } from 'drizzle-orm/postgres-js';
2
- import postgres from 'postgres';
3
- function createSingleton() {
4
- if (!process.env.DATABASE_URL) {
5
- throw new Error('DATABASE_URL is not defined');
6
- }
7
- return drizzle(postgres(process.env.DATABASE_URL, { prepare: false }));
8
- }
9
- export const db = globalThis.db ?? createSingleton();
10
- if (!process.env.VERCEL_ENV) {
11
- globalThis.db = db;
12
- }
@@ -1,42 +0,0 @@
1
- /* istanbul ignore file */
2
- import { integer, pgEnum, pgSchema, text, timestamp } from 'drizzle-orm/pg-core';
3
- const DEFAULT_ROLE = 10;
4
- export const mfaType = pgEnum('mfaType', ['TOTP', 'HARDWARE']);
5
- export const scope = pgEnum('scope', ['ANON', 'MFA', 'AUTHED']);
6
- export const authSchema = pgSchema('auth');
7
- export const authUserTable = authSchema.table('user_credentials', {
8
- id: text('id').primaryKey(),
9
- email: text('email').notNull().unique(),
10
- password: text('password'),
11
- role: integer('role').notNull().default(DEFAULT_ROLE),
12
- });
13
- export const authSessionTable = authSchema.table('sessions', {
14
- id: text('id').primaryKey(),
15
- userId: text('userId')
16
- .notNull()
17
- .references(() => authUserTable.id),
18
- scope: scope('scope').notNull().default('ANON'),
19
- expiresAt: timestamp('expiresAt').notNull(),
20
- });
21
- export const authResetTable = authSchema.table('resets', {
22
- id: text('id').primaryKey(),
23
- userId: text('userId')
24
- .notNull()
25
- .references(() => authUserTable.id),
26
- expiresAt: timestamp('expiresAt').notNull(),
27
- });
28
- export const authMFATable = authSchema.table('mfas', {
29
- id: text('id').primaryKey(),
30
- name: text('name').notNull(),
31
- userId: text('userId')
32
- .notNull()
33
- .references(() => authUserTable.id),
34
- type: mfaType('type').notNull().default('TOTP'),
35
- secret: text('secret').notNull(),
36
- verifiedAt: timestamp('verifiedAt'),
37
- });
38
- export const authClientTable = authSchema.table('client_credentials', {
39
- id: text('id').primaryKey(),
40
- alias: text('alias').notNull().unique(),
41
- secret: text('secret').notNull().unique(),
42
- });
@@ -1,16 +0,0 @@
1
- import type { Errorable } from '@sqrzro/interfaces';
2
- import type Joi from 'joi';
3
- import ValidationError from './ValidationError';
4
- interface SubmitFormArgs<F extends object> {
5
- formData: F;
6
- onSuccess?: (model: F) => Promise<void> | void;
7
- onValidationError?: (error: ValidationError) => void;
8
- request?: Joi.ObjectSchema<F>;
9
- }
10
- interface SubmitFormArgsWithFn<F extends object, M> extends Omit<SubmitFormArgs<F>, 'onSuccess'> {
11
- fn: (data: F) => Promise<M | null>;
12
- onSuccess?: (model: M) => Promise<void> | void;
13
- }
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>>;
16
- export {};
@@ -1,78 +0,0 @@
1
- /* eslint-disable max-statements */
2
- import ValidationError from './ValidationError';
3
- import { validateSchema } from './ValidationService';
4
- function serializeError(err) {
5
- return {
6
- cause: err.cause,
7
- message: err.message,
8
- name: err.name,
9
- stack: err.stack,
10
- };
11
- }
12
- function hasFn(args) {
13
- return Boolean(Object.prototype.hasOwnProperty.call(args, 'fn'));
14
- }
15
- export async function submitForm(args) {
16
- let data = { ...args.formData };
17
- if (args.request) {
18
- const [validated, validationError] = await validateSchema(args.formData, args.request);
19
- if (validationError !== null) {
20
- if (validationError instanceof ValidationError) {
21
- args.onValidationError?.(validationError);
22
- }
23
- return [null, serializeError(validationError)];
24
- }
25
- data = validated;
26
- }
27
- if (!hasFn(args)) {
28
- try {
29
- await args.onSuccess?.(data);
30
- }
31
- catch (err) {
32
- if (err instanceof Error) {
33
- return [null, serializeError(err)];
34
- }
35
- return [
36
- null,
37
- serializeError(new Error('The submitForm onSuccess function encountered an unknown error')),
38
- ];
39
- }
40
- return [data, null];
41
- }
42
- let model = null;
43
- try {
44
- model = await args.fn(data);
45
- }
46
- catch (err) {
47
- if (err instanceof ValidationError) {
48
- args.onValidationError?.(err);
49
- return [null, serializeError(err)];
50
- }
51
- if (err instanceof Error) {
52
- return [null, serializeError(err)];
53
- }
54
- return [
55
- null,
56
- serializeError(new Error('The function supplied to submitForm encountered an unknown error')),
57
- ];
58
- }
59
- if (!model) {
60
- return [
61
- null,
62
- serializeError(new Error('No model has been returned from the function supplied to submitForm')),
63
- ];
64
- }
65
- try {
66
- await args.onSuccess?.(model);
67
- }
68
- catch (err) {
69
- if (err instanceof Error) {
70
- return [null, serializeError(err)];
71
- }
72
- return [
73
- null,
74
- serializeError(new Error('The submitForm onSuccess function encountered an unknown error')),
75
- ];
76
- }
77
- return [model, null];
78
- }
@@ -1,7 +0,0 @@
1
- import type { Errorable } from '@sqrzro/interfaces';
2
- interface ImageValidationConfig {
3
- maxSize?: number;
4
- types?: string[];
5
- }
6
- export declare function validateImage(image: File | null, config?: ImageValidationConfig): Promise<Errorable<File>>;
7
- export {};
@@ -1,19 +0,0 @@
1
- 'use server';
2
- const DEFAULT_TYPES = ['image/png', 'image/jpeg', 'image/jpg'];
3
- // 5MB
4
- const DEFAULT_MAX_SIZE = 5242880;
5
- export async function validateImage(image, config) {
6
- if (!image) {
7
- return Promise.resolve([null, new Error('IMAGE_UNDEFINED')]);
8
- }
9
- if (!(image instanceof File)) {
10
- return Promise.resolve([null, new Error('IMAGE_NOT_VALID')]);
11
- }
12
- if (!(config?.types || DEFAULT_TYPES).includes(image.type)) {
13
- return Promise.resolve([null, new Error('IMAGE_TYPE_NOT_VALID')]);
14
- }
15
- if (image.size > (config?.maxSize || DEFAULT_MAX_SIZE)) {
16
- return Promise.resolve([null, new Error('IMAGE_TOO_HEAVY')]);
17
- }
18
- return Promise.resolve([image, null]);
19
- }
@@ -1,4 +0,0 @@
1
- declare class ValidationError extends Error {
2
- constructor(messages: Record<string, string>);
3
- }
4
- export default ValidationError;
@@ -1,7 +0,0 @@
1
- class ValidationError extends Error {
2
- constructor(messages) {
3
- super(JSON.stringify(messages));
4
- this.name = 'ValidationError';
5
- }
6
- }
7
- export default ValidationError;
@@ -1,20 +0,0 @@
1
- import type { Errorable } from '@sqrzro/interfaces';
2
- import Joi from 'joi';
3
- export declare function validate(): typeof Joi;
4
- export type ValidationCustomHelpers<V = any> = Joi.CustomHelpers<V>;
5
- export type ValidationExternalHelpers<V = any> = Joi.ExternalHelpers<V>;
6
- export type ValidationErrorReport = Joi.ErrorReport;
7
- /**
8
- * This function takes FormData and a schema. It then attempts to transform the FormData into an
9
- * object that matches `T`. This is because the FormData object is not typed and we want to be able
10
- * to validate it properly typed.
11
- *
12
- * Once transformed, the object is validated against the schema. This will result in either a
13
- * properly typed `T` object or an array of validation errors.
14
- * @param formData
15
- * @param validation
16
- * @returns
17
- */
18
- export declare function validateSchema<T>(formData: T, validation: Joi.ObjectSchema<T>): Promise<Errorable<T>>;
19
- export declare function createSchema<T>(schema: Joi.SchemaMap<T, true>): Joi.ObjectSchema<T>;
20
- export declare function extendSchema<T, U extends T>(schema: Joi.ObjectSchema<T>, appends: Joi.PartialSchemaMap<U>): Joi.ObjectSchema<U>;
@@ -1,59 +0,0 @@
1
- import Joi from 'joi';
2
- import lang from './lang';
3
- import ValidationError from './ValidationError';
4
- export function validate() {
5
- return Joi;
6
- }
7
- function getErrorMessages() {
8
- return Object.entries(lang).reduce((acc, [key, value]) => {
9
- if (!value) {
10
- return acc;
11
- }
12
- return {
13
- ...acc,
14
- [key]: value,
15
- };
16
- }, {});
17
- }
18
- function transformErrors(error) {
19
- const messages = error.details.reduce((acc, cur) => ({
20
- ...acc,
21
- [cur.path.join('.')]: cur.message.replace(/"/gu, ''),
22
- }), {});
23
- return new ValidationError(messages);
24
- }
25
- /**
26
- * This function takes FormData and a schema. It then attempts to transform the FormData into an
27
- * object that matches `T`. This is because the FormData object is not typed and we want to be able
28
- * to validate it properly typed.
29
- *
30
- * Once transformed, the object is validated against the schema. This will result in either a
31
- * properly typed `T` object or an array of validation errors.
32
- * @param formData
33
- * @param validation
34
- * @returns
35
- */
36
- export async function validateSchema(formData, validation) {
37
- try {
38
- const validated = await validation.validateAsync(formData, {
39
- abortEarly: false,
40
- messages: getErrorMessages(),
41
- });
42
- return [validated, null];
43
- }
44
- catch (err) {
45
- if (err instanceof Joi.ValidationError) {
46
- return [null, transformErrors(err)];
47
- }
48
- if (err instanceof Error) {
49
- return [null, err];
50
- }
51
- return [null, new Error('Unknown validation error occured')];
52
- }
53
- }
54
- export function createSchema(schema) {
55
- return Joi.object(schema);
56
- }
57
- export function extendSchema(schema, appends) {
58
- return schema.append(appends);
59
- }
@@ -1,3 +0,0 @@
1
- export * from './FormService';
2
- export * from './ImageService';
3
- export * from './ValidationService';
@@ -1,3 +0,0 @@
1
- export * from './FormService';
2
- export * from './ImageService';
3
- export * from './ValidationService';
@@ -1,2 +0,0 @@
1
- declare const messages: Record<string, string>;
2
- export default messages;
@@ -1,115 +0,0 @@
1
- const messages = {
2
- 'alternatives.all': '',
3
- 'alternatives.any': '',
4
- 'alternatives.match': '',
5
- 'alternatives.one': '',
6
- 'alternatives.types': '',
7
- 'any.custom': '',
8
- 'any.default': '',
9
- 'any.failover': '',
10
- 'any.invalid': '',
11
- 'any.only': '',
12
- 'any.ref': '',
13
- 'any.required': '{{#label}} is required',
14
- 'any.unknown': '',
15
- 'array.base': '',
16
- 'array.excludes': '',
17
- 'array.includesRequiredBoth': '',
18
- 'array.includesRequiredKnowns': '',
19
- 'array.includesRequiredUnknowns': '',
20
- 'array.includes': '',
21
- 'array.length': '',
22
- 'array.max': '',
23
- 'array.min': '',
24
- 'array.orderedLength': '',
25
- 'array.sort': '',
26
- 'array.sort.mismatching': '',
27
- 'array.sort.unsupported': '',
28
- 'array.sparse': '',
29
- 'array.unique': '',
30
- 'array.hasKnown': '',
31
- 'array.hasUnknown': '',
32
- 'binary.base': '',
33
- 'binary.length': '',
34
- 'binary.max': '',
35
- 'binary.min': '',
36
- 'boolean.base': '',
37
- 'date.base': '',
38
- 'date.format': '',
39
- 'date.greater': '',
40
- 'date.less': '',
41
- 'date.max': '',
42
- 'date.min': '',
43
- 'date.strict': '',
44
- 'function.arity': '',
45
- 'function.class': '',
46
- 'function.maxArity': '',
47
- 'function.minArity': '',
48
- 'number.base': '{{#label}} should be a number',
49
- 'number.greater': '',
50
- 'number.infinity': '',
51
- 'number.integer': '',
52
- 'number.less': '',
53
- 'number.max': '',
54
- 'number.min': '{{#label}} should be greater than or equal to {{#limit}}',
55
- 'number.multiple': '',
56
- 'number.negative': '',
57
- 'number.port': '',
58
- 'number.positive': '',
59
- 'number.precision': '',
60
- 'number.unsafe': '',
61
- 'object.unknown': '',
62
- 'object.and': '',
63
- 'object.assert': '',
64
- 'object.base': '',
65
- 'object.length': '',
66
- 'object.max': '',
67
- 'object.min': '',
68
- 'object.missing': '',
69
- 'object.nand': '',
70
- 'object.pattern.match': '',
71
- 'object.refType': '',
72
- 'object.regex': '',
73
- 'object.rename.multiple': '',
74
- 'object.rename.override': '',
75
- 'object.schema': '',
76
- 'object.instance': '',
77
- 'object.with': '',
78
- 'object.without': '',
79
- 'object.xor': '',
80
- 'object.oxor': '',
81
- 'string.alphanum': '',
82
- 'string.base64': '',
83
- 'string.base': '',
84
- 'string.creditCard': '',
85
- 'string.dataUri': '',
86
- 'string.domain': '',
87
- 'string.email': '',
88
- 'string.empty': '{{#label}} is required',
89
- 'string.guid': '',
90
- 'string.hexAlign': '',
91
- 'string.hex': '',
92
- 'string.hostname': '',
93
- 'string.ipVersion': '',
94
- 'string.ip': '',
95
- 'string.isoDate': '',
96
- 'string.isoDuration': '',
97
- 'string.length': '',
98
- 'string.lowercase': '',
99
- 'string.max': '',
100
- 'string.min': '',
101
- 'string.normalize': '',
102
- 'string.pattern.base': '',
103
- 'string.pattern.name': '',
104
- 'string.pattern.invert.base': '',
105
- 'string.pattern.invert.name': '',
106
- 'string.token': '',
107
- 'string.trim': '',
108
- 'string.uppercase': '',
109
- 'string.uri': '',
110
- 'string.uriCustomScheme': '',
111
- 'string.uriRelativeOnly': '',
112
- 'symbol.base': '',
113
- 'symbol.map': '',
114
- };
115
- export default messages;
@@ -1,28 +0,0 @@
1
- import { getFromObject } from '@sqrzro/utility';
2
- const DEFAULT_SORT = 'id';
3
- const DEFAULT_DIR = 'asc';
4
- const DEFAULT_PAGE = 1;
5
- const DEFAULT_LIMIT = 10;
6
- function createPaginationArgs(page) {
7
- return { skip: (page - 1) * DEFAULT_LIMIT, take: DEFAULT_LIMIT };
8
- }
9
- function createFindManyArgs(searchParams, allowedFilters = []) {
10
- const { dir, page, sort, ...filters } = searchParams || {};
11
- return {
12
- ...createPaginationArgs(page ? parseInt(page, 10) : DEFAULT_PAGE),
13
- orderBy: { [sort || DEFAULT_SORT]: dir || DEFAULT_DIR },
14
- where: getFromObject(filters, allowedFilters),
15
- };
16
- }
17
- export async function getList({ allowedFilters, fn, searchParams, }) {
18
- try {
19
- const args = createFindManyArgs(searchParams, allowedFilters);
20
- return [await fn(args), null];
21
- }
22
- catch (err) {
23
- if (err instanceof Error) {
24
- return [null, err];
25
- }
26
- return [null, new Error('[getList] An unknown error occurred')];
27
- }
28
- }
@@ -1 +0,0 @@
1
- export * from './ListService';
@@ -1 +0,0 @@
1
- export * from './ListService';
@@ -1,12 +0,0 @@
1
- /// <reference types="react" />
2
- type MailFn<T extends object> = () => Promise<{
3
- subject: string;
4
- template: (data: T) => React.ReactElement;
5
- }>;
6
- export declare function createMail<T extends object>(subject: string, template: (data: T) => React.ReactElement): Promise<MailFn<T>>;
7
- export declare function getMail<T extends object>(mail: MailFn<T>, data: T): Promise<{
8
- subject: string;
9
- html: string;
10
- }>;
11
- export declare function sendMail<T extends object>(mail: Promise<MailFn<T>>, data: T, to: string): Promise<boolean>;
12
- export {};
@@ -1,55 +0,0 @@
1
- export async function createMail(subject, template) {
2
- return Promise.resolve(async () => Promise.resolve({ subject, template }));
3
- }
4
- export async function getMail(mail, data) {
5
- const { subject, template } = await mail();
6
- const ReactDOMServer = (await import('react-dom/server')).default;
7
- return {
8
- subject,
9
- html: ReactDOMServer.renderToStaticMarkup(template(data)),
10
- };
11
- }
12
- function getSenderDetails() {
13
- if (!process.env.MAIL_FROM) {
14
- throw new Error('Mail from address has not been set');
15
- }
16
- const matches = /^(?<name>[^<]+)<(?<email>[^>]+)>$/u.exec(process.env.MAIL_FROM);
17
- if (!matches?.groups?.name || !matches?.groups?.email) {
18
- throw new Error('Mail from address is not the correct format. It should be "Name <email>".');
19
- }
20
- return {
21
- email: matches.groups.email.trim(),
22
- name: matches.groups.name.trim(),
23
- };
24
- }
25
- export async function sendMail(mail, data, to) {
26
- if (!process.env.MAIL_API_URL) {
27
- throw new Error('Mail URL has not been set');
28
- }
29
- if (!process.env.MAIL_API_KEY) {
30
- throw new Error('Mail API key has not been set');
31
- }
32
- const from = getSenderDetails();
33
- const { subject, html } = await getMail(await mail, data);
34
- try {
35
- const response = await fetch(process.env.MAIL_API_URL, {
36
- method: 'POST',
37
- headers: { 'Api-Token': process.env.MAIL_API_KEY, 'Content-Type': 'application/json' },
38
- body: JSON.stringify({
39
- from,
40
- html,
41
- subject,
42
- to: [{ email: to }],
43
- }),
44
- });
45
- const json = (await response.json());
46
- return json.success;
47
- }
48
- catch (err) {
49
- /* eslint-disable-next-line no-console */
50
- console.log('err', err);
51
- /* eslint-disable-next-line no-warning-comments */
52
- // TODO: Log error to Sentry
53
- return false;
54
- }
55
- }
@@ -1 +0,0 @@
1
- export * from './MailService';
@@ -1 +0,0 @@
1
- export * from './MailService';
@@ -1,48 +0,0 @@
1
- import { headers } from 'next/headers';
2
- /**
3
- * Uses a number of methods to determine the current origin.
4
- *
5
- * First, it checks if an `x-origin` header. This will have been set by the `handleMiddleware`
6
- * function, further up the chain. For more information on how it is being set, see the
7
- * `middleware` documentation.
8
- *
9
- * There are some situations where middleware is not being applied, such as API routes (because the
10
- * redirection is not necessary, and API routes handle their own authentication). In these cases,
11
- * this function tries to piece together the origin from the `x-forwarded-proto` and
12
- * `x-forwarded-host` headers.
13
- *
14
- * Finally, if the origin cannot be determined, an error is thrown.
15
- *
16
- * @returns The origin of the current request.
17
- */
18
- export function getOrigin() {
19
- const origin = headers().get('x-origin');
20
- if (origin) {
21
- return origin;
22
- }
23
- const proto = headers().get('x-forwarded-proto');
24
- const host = headers().get('x-forwarded-host');
25
- if (proto && host) {
26
- return `${proto}://${host}`;
27
- }
28
- throw new Error('No origin could be determined');
29
- }
30
- /**
31
- * Builds a URL from the current origin and a given pathname. For more information on how the origin
32
- * is determined, see the `getOrigin` function. This function then just concatenates the origin and
33
- * the pathname, and performs some cleanup to ensure the URL is valid.
34
- *
35
- * @param pathname
36
- * @returns The URL, with the origin and pathname combined.
37
- */
38
- export function getURL(pathname) {
39
- const origin = getOrigin();
40
- if (!pathname) {
41
- return origin;
42
- }
43
- const isSecure = origin.startsWith('https://');
44
- const protocol = isSecure ? 'https://' : 'http://';
45
- const originWithoutProtocol = origin.replace(/^https?:\/\//u, '');
46
- const cleanURL = `${originWithoutProtocol}/${pathname}`.replace(/\/+/gu, '/');
47
- return `${protocol}${cleanURL}`;
48
- }
@@ -1 +0,0 @@
1
- export * from './URLService';
package/dist/url/index.js DELETED
@@ -1 +0,0 @@
1
- export * from './URLService';