Projektstart
This commit is contained in:
1
backend/node_modules/.bin/acorn
generated
vendored
Symbolic link
1
backend/node_modules/.bin/acorn
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../acorn/bin/acorn
|
||||
1
backend/node_modules/.bin/download-msgpackr-prebuilds
generated
vendored
Symbolic link
1
backend/node_modules/.bin/download-msgpackr-prebuilds
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../msgpackr-extract/bin/download-prebuilds.js
|
||||
1
backend/node_modules/.bin/glob
generated
vendored
Symbolic link
1
backend/node_modules/.bin/glob
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../glob/dist/esm/bin.mjs
|
||||
1
backend/node_modules/.bin/he
generated
vendored
Symbolic link
1
backend/node_modules/.bin/he
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../he/bin/he
|
||||
1
backend/node_modules/.bin/mime
generated
vendored
Symbolic link
1
backend/node_modules/.bin/mime
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../mime/cli.js
|
||||
1
backend/node_modules/.bin/node-gyp-build
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-gyp-build
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../node-gyp-build/bin.js
|
||||
1
backend/node_modules/.bin/node-gyp-build-optional
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-gyp-build-optional
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../node-gyp-build/optional.js
|
||||
1
backend/node_modules/.bin/node-gyp-build-optional-packages
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-gyp-build-optional-packages
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../node-gyp-build-optional-packages/bin.js
|
||||
1
backend/node_modules/.bin/node-gyp-build-optional-packages-optional
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-gyp-build-optional-packages-optional
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../node-gyp-build-optional-packages/optional.js
|
||||
1
backend/node_modules/.bin/node-gyp-build-optional-packages-test
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-gyp-build-optional-packages-test
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../node-gyp-build-optional-packages/build-test.js
|
||||
1
backend/node_modules/.bin/node-gyp-build-test
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-gyp-build-test
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../node-gyp-build/build-test.js
|
||||
1
backend/node_modules/.bin/node-which
generated
vendored
Symbolic link
1
backend/node_modules/.bin/node-which
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../which/bin/node-which
|
||||
1
backend/node_modules/.bin/pino
generated
vendored
Symbolic link
1
backend/node_modules/.bin/pino
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../pino/bin.js
|
||||
1
backend/node_modules/.bin/pino-pretty
generated
vendored
Symbolic link
1
backend/node_modules/.bin/pino-pretty
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../pino-pretty/bin.js
|
||||
1
backend/node_modules/.bin/prisma
generated
vendored
Symbolic link
1
backend/node_modules/.bin/prisma
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../prisma/build/index.js
|
||||
1
backend/node_modules/.bin/semver
generated
vendored
Symbolic link
1
backend/node_modules/.bin/semver
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../semver/bin/semver.js
|
||||
1
backend/node_modules/.bin/tlds
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tlds
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../tlds/bin.js
|
||||
1
backend/node_modules/.bin/ts-node
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../ts-node/dist/bin.js
|
||||
1
backend/node_modules/.bin/ts-node-cwd
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-cwd
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-cwd.js
|
||||
1
backend/node_modules/.bin/ts-node-esm
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-esm
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-esm.js
|
||||
1
backend/node_modules/.bin/ts-node-script
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-script
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-script.js
|
||||
1
backend/node_modules/.bin/ts-node-transpile-only
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-node-transpile-only
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-transpile.js
|
||||
1
backend/node_modules/.bin/ts-script
generated
vendored
Symbolic link
1
backend/node_modules/.bin/ts-script
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../ts-node/dist/bin-script-deprecated.js
|
||||
1
backend/node_modules/.bin/tsc
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tsc
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../typescript/bin/tsc
|
||||
1
backend/node_modules/.bin/tsserver
generated
vendored
Symbolic link
1
backend/node_modules/.bin/tsserver
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../typescript/bin/tsserver
|
||||
1
backend/node_modules/.bin/uuid
generated
vendored
Symbolic link
1
backend/node_modules/.bin/uuid
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../uuid/dist/esm/bin/uuid
|
||||
1
backend/node_modules/.bin/yaml
generated
vendored
Symbolic link
1
backend/node_modules/.bin/yaml
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../yaml/bin.mjs
|
||||
2810
backend/node_modules/.package-lock.json
generated
vendored
Normal file
2810
backend/node_modules/.package-lock.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
backend/node_modules/.prisma/client/default.d.ts
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/default.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./index"
|
||||
1
backend/node_modules/.prisma/client/default.js
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/default.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = { ...require('.') }
|
||||
9
backend/node_modules/.prisma/client/deno/edge.d.ts
generated
vendored
Normal file
9
backend/node_modules/.prisma/client/deno/edge.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
throw new Error(
|
||||
'@prisma/client/deno/edge did not initialize yet. Please run "prisma generate" and try to import it again.',
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export { PrismaClient }
|
||||
1
backend/node_modules/.prisma/client/edge.d.ts
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/edge.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./default"
|
||||
337
backend/node_modules/.prisma/client/edge.js
generated
vendored
Normal file
337
backend/node_modules/.prisma/client/edge.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
331
backend/node_modules/.prisma/client/index-browser.js
generated
vendored
Normal file
331
backend/node_modules/.prisma/client/index-browser.js
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const {
|
||||
Decimal,
|
||||
objectEnumValues,
|
||||
makeStrictEnum,
|
||||
Public,
|
||||
getRuntime,
|
||||
skip
|
||||
} = require('@prisma/client/runtime/index-browser.js')
|
||||
|
||||
|
||||
const Prisma = {}
|
||||
|
||||
exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 5.22.0
|
||||
* Query Engine version: 605197351a3c8bdd595af2d2a9bc3025bca48ea2
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "5.22.0",
|
||||
engine: "605197351a3c8bdd595af2d2a9bc3025bca48ea2"
|
||||
}
|
||||
|
||||
Prisma.PrismaClientKnownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientKnownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)};
|
||||
Prisma.PrismaClientUnknownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientUnknownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientRustPanicError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientRustPanicError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientInitializationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientInitializationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientValidationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientValidationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.NotFoundError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`NotFoundError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.Decimal = Decimal
|
||||
|
||||
/**
|
||||
* Re-export of sql-template-tag
|
||||
*/
|
||||
Prisma.sql = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`sqltag is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.empty = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`empty is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.join = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`join is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.raw = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`raw is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.validator = Public.validator
|
||||
|
||||
/**
|
||||
* Extensions
|
||||
*/
|
||||
Prisma.getExtensionContext = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.getExtensionContext is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.defineExtension = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.defineExtension is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
|
||||
/**
|
||||
* Shorthand utilities for JSON filtering
|
||||
*/
|
||||
Prisma.DbNull = objectEnumValues.instances.DbNull
|
||||
Prisma.JsonNull = objectEnumValues.instances.JsonNull
|
||||
Prisma.AnyNull = objectEnumValues.instances.AnyNull
|
||||
|
||||
Prisma.NullTypes = {
|
||||
DbNull: objectEnumValues.classes.DbNull,
|
||||
JsonNull: objectEnumValues.classes.JsonNull,
|
||||
AnyNull: objectEnumValues.classes.AnyNull
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enums
|
||||
*/
|
||||
|
||||
exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
ReadUncommitted: 'ReadUncommitted',
|
||||
ReadCommitted: 'ReadCommitted',
|
||||
RepeatableRead: 'RepeatableRead',
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
exports.Prisma.TenantScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.UserScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
email: 'email',
|
||||
password: 'password',
|
||||
role: 'role',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.MailboxAccountScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
email: 'email',
|
||||
provider: 'provider',
|
||||
isActive: 'isActive',
|
||||
imapHost: 'imapHost',
|
||||
imapPort: 'imapPort',
|
||||
imapTLS: 'imapTLS',
|
||||
smtpHost: 'smtpHost',
|
||||
smtpPort: 'smtpPort',
|
||||
smtpTLS: 'smtpTLS',
|
||||
oauthToken: 'oauthToken',
|
||||
appPassword: 'appPassword',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.MailboxFolderScalarFieldEnum = {
|
||||
id: 'id',
|
||||
mailboxAccountId: 'mailboxAccountId',
|
||||
name: 'name',
|
||||
remoteId: 'remoteId',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.MailItemScalarFieldEnum = {
|
||||
id: 'id',
|
||||
folderId: 'folderId',
|
||||
messageId: 'messageId',
|
||||
subject: 'subject',
|
||||
from: 'from',
|
||||
receivedAt: 'receivedAt',
|
||||
listId: 'listId',
|
||||
listUnsubscribe: 'listUnsubscribe',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.RuleScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
name: 'name',
|
||||
enabled: 'enabled',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.RuleConditionScalarFieldEnum = {
|
||||
id: 'id',
|
||||
ruleId: 'ruleId',
|
||||
type: 'type',
|
||||
value: 'value'
|
||||
};
|
||||
|
||||
exports.Prisma.RuleActionScalarFieldEnum = {
|
||||
id: 'id',
|
||||
ruleId: 'ruleId',
|
||||
type: 'type',
|
||||
target: 'target'
|
||||
};
|
||||
|
||||
exports.Prisma.CleanupJobScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
mailboxAccountId: 'mailboxAccountId',
|
||||
status: 'status',
|
||||
dryRun: 'dryRun',
|
||||
unsubscribeEnabled: 'unsubscribeEnabled',
|
||||
routingEnabled: 'routingEnabled',
|
||||
startedAt: 'startedAt',
|
||||
finishedAt: 'finishedAt',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.UnsubscribeAttemptScalarFieldEnum = {
|
||||
id: 'id',
|
||||
jobId: 'jobId',
|
||||
mailItemId: 'mailItemId',
|
||||
method: 'method',
|
||||
target: 'target',
|
||||
status: 'status',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.CleanupJobEventScalarFieldEnum = {
|
||||
id: 'id',
|
||||
jobId: 'jobId',
|
||||
level: 'level',
|
||||
message: 'message',
|
||||
progress: 'progress',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
};
|
||||
|
||||
exports.Prisma.QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
};
|
||||
|
||||
exports.Prisma.NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
};
|
||||
exports.UserRole = exports.$Enums.UserRole = {
|
||||
USER: 'USER',
|
||||
ADMIN: 'ADMIN'
|
||||
};
|
||||
|
||||
exports.MailProvider = exports.$Enums.MailProvider = {
|
||||
GMAIL: 'GMAIL',
|
||||
GMX: 'GMX',
|
||||
WEBDE: 'WEBDE'
|
||||
};
|
||||
|
||||
exports.RuleConditionType = exports.$Enums.RuleConditionType = {
|
||||
HEADER: 'HEADER',
|
||||
SUBJECT: 'SUBJECT',
|
||||
FROM: 'FROM',
|
||||
LIST_UNSUBSCRIBE: 'LIST_UNSUBSCRIBE',
|
||||
LIST_ID: 'LIST_ID'
|
||||
};
|
||||
|
||||
exports.RuleActionType = exports.$Enums.RuleActionType = {
|
||||
MOVE: 'MOVE',
|
||||
DELETE: 'DELETE',
|
||||
ARCHIVE: 'ARCHIVE',
|
||||
LABEL: 'LABEL'
|
||||
};
|
||||
|
||||
exports.JobStatus = exports.$Enums.JobStatus = {
|
||||
QUEUED: 'QUEUED',
|
||||
RUNNING: 'RUNNING',
|
||||
SUCCEEDED: 'SUCCEEDED',
|
||||
FAILED: 'FAILED',
|
||||
CANCELED: 'CANCELED'
|
||||
};
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
Tenant: 'Tenant',
|
||||
User: 'User',
|
||||
MailboxAccount: 'MailboxAccount',
|
||||
MailboxFolder: 'MailboxFolder',
|
||||
MailItem: 'MailItem',
|
||||
Rule: 'Rule',
|
||||
RuleCondition: 'RuleCondition',
|
||||
RuleAction: 'RuleAction',
|
||||
CleanupJob: 'CleanupJob',
|
||||
UnsubscribeAttempt: 'UnsubscribeAttempt',
|
||||
CleanupJobEvent: 'CleanupJobEvent'
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a stub Prisma Client that will error at runtime if called.
|
||||
*/
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
return new Proxy(this, {
|
||||
get(target, prop) {
|
||||
let message
|
||||
const runtime = getRuntime()
|
||||
if (runtime.isEdge) {
|
||||
message = `PrismaClient is not configured to run in ${runtime.prettyName}. In order to run Prisma Client on edge runtime, either:
|
||||
- Use Prisma Accelerate: https://pris.ly/d/accelerate
|
||||
- Use Driver Adapters: https://pris.ly/d/driver-adapters
|
||||
`;
|
||||
} else {
|
||||
message = 'PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `' + runtime.prettyName + '`).'
|
||||
}
|
||||
|
||||
message += `
|
||||
If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report`
|
||||
|
||||
throw new Error(message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.PrismaClient = PrismaClient
|
||||
|
||||
Object.assign(exports, Prisma)
|
||||
18548
backend/node_modules/.prisma/client/index.d.ts
generated
vendored
Normal file
18548
backend/node_modules/.prisma/client/index.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
358
backend/node_modules/.prisma/client/index.js
generated
vendored
Normal file
358
backend/node_modules/.prisma/client/index.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/node_modules/.prisma/client/libquery_engine-debian-openssl-3.0.x.so.node
generated
vendored
Executable file
BIN
backend/node_modules/.prisma/client/libquery_engine-debian-openssl-3.0.x.so.node
generated
vendored
Executable file
Binary file not shown.
97
backend/node_modules/.prisma/client/package.json
generated
vendored
Normal file
97
backend/node_modules/.prisma/client/package.json
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
{
|
||||
"name": "prisma-client-b4cf1bdb4cdb603270ffacebd51312a4f626848df3c1cfbd697266d48aa5aa9b",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"browser": "index-browser.js",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"require": {
|
||||
"node": "./index.js",
|
||||
"edge-light": "./wasm.js",
|
||||
"workerd": "./wasm.js",
|
||||
"worker": "./wasm.js",
|
||||
"browser": "./index-browser.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"import": {
|
||||
"node": "./index.js",
|
||||
"edge-light": "./wasm.js",
|
||||
"workerd": "./wasm.js",
|
||||
"worker": "./wasm.js",
|
||||
"browser": "./index-browser.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./edge": {
|
||||
"types": "./edge.d.ts",
|
||||
"require": "./edge.js",
|
||||
"import": "./edge.js",
|
||||
"default": "./edge.js"
|
||||
},
|
||||
"./react-native": {
|
||||
"types": "./react-native.d.ts",
|
||||
"require": "./react-native.js",
|
||||
"import": "./react-native.js",
|
||||
"default": "./react-native.js"
|
||||
},
|
||||
"./extension": {
|
||||
"types": "./extension.d.ts",
|
||||
"require": "./extension.js",
|
||||
"import": "./extension.js",
|
||||
"default": "./extension.js"
|
||||
},
|
||||
"./index-browser": {
|
||||
"types": "./index.d.ts",
|
||||
"require": "./index-browser.js",
|
||||
"import": "./index-browser.js",
|
||||
"default": "./index-browser.js"
|
||||
},
|
||||
"./index": {
|
||||
"types": "./index.d.ts",
|
||||
"require": "./index.js",
|
||||
"import": "./index.js",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./wasm": {
|
||||
"types": "./wasm.d.ts",
|
||||
"require": "./wasm.js",
|
||||
"import": "./wasm.js",
|
||||
"default": "./wasm.js"
|
||||
},
|
||||
"./runtime/library": {
|
||||
"types": "./runtime/library.d.ts",
|
||||
"require": "./runtime/library.js",
|
||||
"import": "./runtime/library.js",
|
||||
"default": "./runtime/library.js"
|
||||
},
|
||||
"./runtime/binary": {
|
||||
"types": "./runtime/binary.d.ts",
|
||||
"require": "./runtime/binary.js",
|
||||
"import": "./runtime/binary.js",
|
||||
"default": "./runtime/binary.js"
|
||||
},
|
||||
"./generator-build": {
|
||||
"require": "./generator-build/index.js",
|
||||
"import": "./generator-build/index.js",
|
||||
"default": "./generator-build/index.js"
|
||||
},
|
||||
"./sql": {
|
||||
"require": {
|
||||
"types": "./sql.d.ts",
|
||||
"node": "./sql.js",
|
||||
"default": "./sql.js"
|
||||
},
|
||||
"import": {
|
||||
"types": "./sql.d.ts",
|
||||
"node": "./sql.mjs",
|
||||
"default": "./sql.mjs"
|
||||
},
|
||||
"default": "./sql.js"
|
||||
},
|
||||
"./*": "./*"
|
||||
},
|
||||
"version": "5.22.0",
|
||||
"sideEffects": false
|
||||
}
|
||||
210
backend/node_modules/.prisma/client/schema.prisma
generated
vendored
Normal file
210
backend/node_modules/.prisma/client/schema.prisma
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
enum MailProvider {
|
||||
GMAIL
|
||||
GMX
|
||||
WEBDE
|
||||
}
|
||||
|
||||
enum UserRole {
|
||||
USER
|
||||
ADMIN
|
||||
}
|
||||
|
||||
enum JobStatus {
|
||||
QUEUED
|
||||
RUNNING
|
||||
SUCCEEDED
|
||||
FAILED
|
||||
CANCELED
|
||||
}
|
||||
|
||||
enum RuleActionType {
|
||||
MOVE
|
||||
DELETE
|
||||
ARCHIVE
|
||||
LABEL
|
||||
}
|
||||
|
||||
enum RuleConditionType {
|
||||
HEADER
|
||||
SUBJECT
|
||||
FROM
|
||||
LIST_UNSUBSCRIBE
|
||||
LIST_ID
|
||||
}
|
||||
|
||||
model Tenant {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
users User[]
|
||||
mailboxAccounts MailboxAccount[]
|
||||
rules Rule[]
|
||||
jobs CleanupJob[]
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
email String @unique
|
||||
password String
|
||||
role UserRole @default(USER)
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
}
|
||||
|
||||
model MailboxAccount {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
email String
|
||||
provider MailProvider
|
||||
isActive Boolean @default(true)
|
||||
imapHost String
|
||||
imapPort Int
|
||||
imapTLS Boolean
|
||||
smtpHost String?
|
||||
smtpPort Int?
|
||||
smtpTLS Boolean?
|
||||
oauthToken String?
|
||||
appPassword String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
folders MailboxFolder[]
|
||||
jobs CleanupJob[]
|
||||
|
||||
@@index([tenantId])
|
||||
}
|
||||
|
||||
model MailboxFolder {
|
||||
id String @id @default(cuid())
|
||||
mailboxAccountId String
|
||||
name String
|
||||
remoteId String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
mailboxAccount MailboxAccount @relation(fields: [mailboxAccountId], references: [id])
|
||||
mailItems MailItem[]
|
||||
|
||||
@@index([mailboxAccountId])
|
||||
}
|
||||
|
||||
model MailItem {
|
||||
id String @id @default(cuid())
|
||||
folderId String
|
||||
messageId String
|
||||
subject String?
|
||||
from String?
|
||||
receivedAt DateTime?
|
||||
listId String?
|
||||
listUnsubscribe String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
folder MailboxFolder @relation(fields: [folderId], references: [id])
|
||||
|
||||
@@index([folderId])
|
||||
@@index([messageId])
|
||||
}
|
||||
|
||||
model Rule {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
name String
|
||||
enabled Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
conditions RuleCondition[]
|
||||
actions RuleAction[]
|
||||
|
||||
@@index([tenantId])
|
||||
}
|
||||
|
||||
model RuleCondition {
|
||||
id String @id @default(cuid())
|
||||
ruleId String
|
||||
type RuleConditionType
|
||||
value String
|
||||
|
||||
rule Rule @relation(fields: [ruleId], references: [id])
|
||||
|
||||
@@index([ruleId])
|
||||
}
|
||||
|
||||
model RuleAction {
|
||||
id String @id @default(cuid())
|
||||
ruleId String
|
||||
type RuleActionType
|
||||
target String?
|
||||
|
||||
rule Rule @relation(fields: [ruleId], references: [id])
|
||||
|
||||
@@index([ruleId])
|
||||
}
|
||||
|
||||
model CleanupJob {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
mailboxAccountId String
|
||||
status JobStatus @default(QUEUED)
|
||||
dryRun Boolean @default(true)
|
||||
unsubscribeEnabled Boolean @default(true)
|
||||
routingEnabled Boolean @default(true)
|
||||
startedAt DateTime?
|
||||
finishedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||||
mailboxAccount MailboxAccount @relation(fields: [mailboxAccountId], references: [id])
|
||||
unsubscribeAttempts UnsubscribeAttempt[]
|
||||
events CleanupJobEvent[]
|
||||
|
||||
@@index([tenantId])
|
||||
@@index([mailboxAccountId])
|
||||
}
|
||||
|
||||
model UnsubscribeAttempt {
|
||||
id String @id @default(cuid())
|
||||
jobId String
|
||||
mailItemId String?
|
||||
method String
|
||||
target String
|
||||
status String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
job CleanupJob @relation(fields: [jobId], references: [id])
|
||||
|
||||
@@index([jobId])
|
||||
}
|
||||
|
||||
model CleanupJobEvent {
|
||||
id String @id @default(cuid())
|
||||
jobId String
|
||||
level String
|
||||
message String
|
||||
progress Int?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
job CleanupJob @relation(fields: [jobId], references: [id])
|
||||
|
||||
@@index([jobId])
|
||||
}
|
||||
1
backend/node_modules/.prisma/client/wasm.d.ts
generated
vendored
Normal file
1
backend/node_modules/.prisma/client/wasm.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export * from "./index"
|
||||
331
backend/node_modules/.prisma/client/wasm.js
generated
vendored
Normal file
331
backend/node_modules/.prisma/client/wasm.js
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
const {
|
||||
Decimal,
|
||||
objectEnumValues,
|
||||
makeStrictEnum,
|
||||
Public,
|
||||
getRuntime,
|
||||
skip
|
||||
} = require('@prisma/client/runtime/index-browser.js')
|
||||
|
||||
|
||||
const Prisma = {}
|
||||
|
||||
exports.Prisma = Prisma
|
||||
exports.$Enums = {}
|
||||
|
||||
/**
|
||||
* Prisma Client JS version: 5.22.0
|
||||
* Query Engine version: 605197351a3c8bdd595af2d2a9bc3025bca48ea2
|
||||
*/
|
||||
Prisma.prismaVersion = {
|
||||
client: "5.22.0",
|
||||
engine: "605197351a3c8bdd595af2d2a9bc3025bca48ea2"
|
||||
}
|
||||
|
||||
Prisma.PrismaClientKnownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientKnownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)};
|
||||
Prisma.PrismaClientUnknownRequestError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientUnknownRequestError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientRustPanicError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientRustPanicError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientInitializationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientInitializationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.PrismaClientValidationError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`PrismaClientValidationError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.NotFoundError = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`NotFoundError is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.Decimal = Decimal
|
||||
|
||||
/**
|
||||
* Re-export of sql-template-tag
|
||||
*/
|
||||
Prisma.sql = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`sqltag is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.empty = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`empty is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.join = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`join is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.raw = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`raw is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.validator = Public.validator
|
||||
|
||||
/**
|
||||
* Extensions
|
||||
*/
|
||||
Prisma.getExtensionContext = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.getExtensionContext is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
Prisma.defineExtension = () => {
|
||||
const runtimeName = getRuntime().prettyName;
|
||||
throw new Error(`Extensions.defineExtension is unable to run in this browser environment, or has been bundled for the browser (running in ${runtimeName}).
|
||||
In case this error is unexpected for you, please report it in https://pris.ly/prisma-prisma-bug-report`,
|
||||
)}
|
||||
|
||||
/**
|
||||
* Shorthand utilities for JSON filtering
|
||||
*/
|
||||
Prisma.DbNull = objectEnumValues.instances.DbNull
|
||||
Prisma.JsonNull = objectEnumValues.instances.JsonNull
|
||||
Prisma.AnyNull = objectEnumValues.instances.AnyNull
|
||||
|
||||
Prisma.NullTypes = {
|
||||
DbNull: objectEnumValues.classes.DbNull,
|
||||
JsonNull: objectEnumValues.classes.JsonNull,
|
||||
AnyNull: objectEnumValues.classes.AnyNull
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Enums
|
||||
*/
|
||||
|
||||
exports.Prisma.TransactionIsolationLevel = makeStrictEnum({
|
||||
ReadUncommitted: 'ReadUncommitted',
|
||||
ReadCommitted: 'ReadCommitted',
|
||||
RepeatableRead: 'RepeatableRead',
|
||||
Serializable: 'Serializable'
|
||||
});
|
||||
|
||||
exports.Prisma.TenantScalarFieldEnum = {
|
||||
id: 'id',
|
||||
name: 'name',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.UserScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
email: 'email',
|
||||
password: 'password',
|
||||
role: 'role',
|
||||
isActive: 'isActive',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.MailboxAccountScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
email: 'email',
|
||||
provider: 'provider',
|
||||
isActive: 'isActive',
|
||||
imapHost: 'imapHost',
|
||||
imapPort: 'imapPort',
|
||||
imapTLS: 'imapTLS',
|
||||
smtpHost: 'smtpHost',
|
||||
smtpPort: 'smtpPort',
|
||||
smtpTLS: 'smtpTLS',
|
||||
oauthToken: 'oauthToken',
|
||||
appPassword: 'appPassword',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.MailboxFolderScalarFieldEnum = {
|
||||
id: 'id',
|
||||
mailboxAccountId: 'mailboxAccountId',
|
||||
name: 'name',
|
||||
remoteId: 'remoteId',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.MailItemScalarFieldEnum = {
|
||||
id: 'id',
|
||||
folderId: 'folderId',
|
||||
messageId: 'messageId',
|
||||
subject: 'subject',
|
||||
from: 'from',
|
||||
receivedAt: 'receivedAt',
|
||||
listId: 'listId',
|
||||
listUnsubscribe: 'listUnsubscribe',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.RuleScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
name: 'name',
|
||||
enabled: 'enabled',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.RuleConditionScalarFieldEnum = {
|
||||
id: 'id',
|
||||
ruleId: 'ruleId',
|
||||
type: 'type',
|
||||
value: 'value'
|
||||
};
|
||||
|
||||
exports.Prisma.RuleActionScalarFieldEnum = {
|
||||
id: 'id',
|
||||
ruleId: 'ruleId',
|
||||
type: 'type',
|
||||
target: 'target'
|
||||
};
|
||||
|
||||
exports.Prisma.CleanupJobScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tenantId: 'tenantId',
|
||||
mailboxAccountId: 'mailboxAccountId',
|
||||
status: 'status',
|
||||
dryRun: 'dryRun',
|
||||
unsubscribeEnabled: 'unsubscribeEnabled',
|
||||
routingEnabled: 'routingEnabled',
|
||||
startedAt: 'startedAt',
|
||||
finishedAt: 'finishedAt',
|
||||
createdAt: 'createdAt',
|
||||
updatedAt: 'updatedAt'
|
||||
};
|
||||
|
||||
exports.Prisma.UnsubscribeAttemptScalarFieldEnum = {
|
||||
id: 'id',
|
||||
jobId: 'jobId',
|
||||
mailItemId: 'mailItemId',
|
||||
method: 'method',
|
||||
target: 'target',
|
||||
status: 'status',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.CleanupJobEventScalarFieldEnum = {
|
||||
id: 'id',
|
||||
jobId: 'jobId',
|
||||
level: 'level',
|
||||
message: 'message',
|
||||
progress: 'progress',
|
||||
createdAt: 'createdAt'
|
||||
};
|
||||
|
||||
exports.Prisma.SortOrder = {
|
||||
asc: 'asc',
|
||||
desc: 'desc'
|
||||
};
|
||||
|
||||
exports.Prisma.QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
};
|
||||
|
||||
exports.Prisma.NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
};
|
||||
exports.UserRole = exports.$Enums.UserRole = {
|
||||
USER: 'USER',
|
||||
ADMIN: 'ADMIN'
|
||||
};
|
||||
|
||||
exports.MailProvider = exports.$Enums.MailProvider = {
|
||||
GMAIL: 'GMAIL',
|
||||
GMX: 'GMX',
|
||||
WEBDE: 'WEBDE'
|
||||
};
|
||||
|
||||
exports.RuleConditionType = exports.$Enums.RuleConditionType = {
|
||||
HEADER: 'HEADER',
|
||||
SUBJECT: 'SUBJECT',
|
||||
FROM: 'FROM',
|
||||
LIST_UNSUBSCRIBE: 'LIST_UNSUBSCRIBE',
|
||||
LIST_ID: 'LIST_ID'
|
||||
};
|
||||
|
||||
exports.RuleActionType = exports.$Enums.RuleActionType = {
|
||||
MOVE: 'MOVE',
|
||||
DELETE: 'DELETE',
|
||||
ARCHIVE: 'ARCHIVE',
|
||||
LABEL: 'LABEL'
|
||||
};
|
||||
|
||||
exports.JobStatus = exports.$Enums.JobStatus = {
|
||||
QUEUED: 'QUEUED',
|
||||
RUNNING: 'RUNNING',
|
||||
SUCCEEDED: 'SUCCEEDED',
|
||||
FAILED: 'FAILED',
|
||||
CANCELED: 'CANCELED'
|
||||
};
|
||||
|
||||
exports.Prisma.ModelName = {
|
||||
Tenant: 'Tenant',
|
||||
User: 'User',
|
||||
MailboxAccount: 'MailboxAccount',
|
||||
MailboxFolder: 'MailboxFolder',
|
||||
MailItem: 'MailItem',
|
||||
Rule: 'Rule',
|
||||
RuleCondition: 'RuleCondition',
|
||||
RuleAction: 'RuleAction',
|
||||
CleanupJob: 'CleanupJob',
|
||||
UnsubscribeAttempt: 'UnsubscribeAttempt',
|
||||
CleanupJobEvent: 'CleanupJobEvent'
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a stub Prisma Client that will error at runtime if called.
|
||||
*/
|
||||
class PrismaClient {
|
||||
constructor() {
|
||||
return new Proxy(this, {
|
||||
get(target, prop) {
|
||||
let message
|
||||
const runtime = getRuntime()
|
||||
if (runtime.isEdge) {
|
||||
message = `PrismaClient is not configured to run in ${runtime.prettyName}. In order to run Prisma Client on edge runtime, either:
|
||||
- Use Prisma Accelerate: https://pris.ly/d/accelerate
|
||||
- Use Driver Adapters: https://pris.ly/d/driver-adapters
|
||||
`;
|
||||
} else {
|
||||
message = 'PrismaClient is unable to run in this browser environment, or has been bundled for the browser (running in `' + runtime.prettyName + '`).'
|
||||
}
|
||||
|
||||
message += `
|
||||
If this is unexpected, please open an issue: https://pris.ly/prisma-prisma-bug-report`
|
||||
|
||||
throw new Error(message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
exports.PrismaClient = PrismaClient
|
||||
|
||||
Object.assign(exports, Prisma)
|
||||
21
backend/node_modules/@cspotcode/source-map-support/LICENSE.md
generated
vendored
Normal file
21
backend/node_modules/@cspotcode/source-map-support/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Evan Wallace
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
289
backend/node_modules/@cspotcode/source-map-support/README.md
generated
vendored
Normal file
289
backend/node_modules/@cspotcode/source-map-support/README.md
generated
vendored
Normal file
@@ -0,0 +1,289 @@
|
||||
# Source Map Support
|
||||
|
||||
[](https://npmjs.org/package/@cspotcode/source-map-support)
|
||||
[](https://npmjs.org/package/@cspotcode/source-map-support)
|
||||
[](https://github.com/cspotcode/node-source-map-support/actions?query=workflow%3A%22Continuous+Integration%22)
|
||||
|
||||
This module provides source map support for stack traces in node via the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API). It uses the [source-map](https://github.com/mozilla/source-map) module to replace the paths and line numbers of source-mapped files with their original paths and line numbers. The output mimics node's stack trace format with the goal of making every compile-to-JS language more of a first-class citizen. Source maps are completely general (not specific to any one language) so you can use source maps with multiple compile-to-JS languages in the same node process.
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
#### Node support
|
||||
|
||||
```
|
||||
$ npm install @cspotcode/source-map-support
|
||||
```
|
||||
|
||||
Source maps can be generated using libraries such as [source-map-index-generator](https://github.com/twolfson/source-map-index-generator). Once you have a valid source map, place a source mapping comment somewhere in the file (usually done automatically or with an option by your transpiler):
|
||||
|
||||
```
|
||||
//# sourceMappingURL=path/to/source.map
|
||||
```
|
||||
|
||||
If multiple sourceMappingURL comments exist in one file, the last sourceMappingURL comment will be
|
||||
respected (e.g. if a file mentions the comment in code, or went through multiple transpilers).
|
||||
The path should either be absolute or relative to the compiled file.
|
||||
|
||||
From here you have two options.
|
||||
|
||||
##### CLI Usage
|
||||
|
||||
```bash
|
||||
node -r @cspotcode/source-map-support/register compiled.js
|
||||
# Or to enable hookRequire
|
||||
node -r @cspotcode/source-map-support/register-hook-require compiled.js
|
||||
```
|
||||
|
||||
##### Programmatic Usage
|
||||
|
||||
Put the following line at the top of the compiled file.
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install();
|
||||
```
|
||||
|
||||
It is also possible to install the source map support directly by
|
||||
requiring the `register` module which can be handy with ES6:
|
||||
|
||||
```js
|
||||
import '@cspotcode/source-map-support/register'
|
||||
|
||||
// Instead of:
|
||||
import sourceMapSupport from '@cspotcode/source-map-support'
|
||||
sourceMapSupport.install()
|
||||
```
|
||||
Note: if you're using babel-register, it includes source-map-support already.
|
||||
|
||||
It is also very useful with Mocha:
|
||||
|
||||
```
|
||||
$ mocha --require @cspotcode/source-map-support/register tests/
|
||||
```
|
||||
|
||||
#### Browser support
|
||||
|
||||
This library also works in Chrome. While the DevTools console already supports source maps, the V8 engine doesn't and `Error.prototype.stack` will be incorrect without this library. Everything will just work if you deploy your source files using [browserify](http://browserify.org/). Just make sure to pass the `--debug` flag to the browserify command so your source maps are included in the bundled code.
|
||||
|
||||
This library also works if you use another build process or just include the source files directly. In this case, include the file `browser-source-map-support.js` in your page and call `sourceMapSupport.install()`. It contains the whole library already bundled for the browser using browserify.
|
||||
|
||||
```html
|
||||
<script src="browser-source-map-support.js"></script>
|
||||
<script>sourceMapSupport.install();</script>
|
||||
```
|
||||
|
||||
This library also works if you use AMD (Asynchronous Module Definition), which is used in tools like [RequireJS](http://requirejs.org/). Just list `browser-source-map-support` as a dependency:
|
||||
|
||||
```html
|
||||
<script>
|
||||
define(['browser-source-map-support'], function(sourceMapSupport) {
|
||||
sourceMapSupport.install();
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
This module installs two things: a change to the `stack` property on `Error` objects and a handler for uncaught exceptions that mimics node's default exception handler (the handler can be seen in the demos below). You may want to disable the handler if you have your own uncaught exception handler. This can be done by passing an argument to the installer:
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
handleUncaughtExceptions: false
|
||||
});
|
||||
```
|
||||
|
||||
This module loads source maps from the filesystem by default. You can provide alternate loading behavior through a callback as shown below. For example, [Meteor](https://github.com/meteor) keeps all source maps cached in memory to avoid disk access.
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
retrieveSourceMap: function(source) {
|
||||
if (source === 'compiled.js') {
|
||||
return {
|
||||
url: 'original.js',
|
||||
map: fs.readFileSync('compiled.js.map', 'utf8')
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The module will by default assume a browser environment if XMLHttpRequest and window are defined. If either of these do not exist it will instead assume a node environment.
|
||||
In some rare cases, e.g. when running a browser emulation and where both variables are also set, you can explictly specify the environment to be either 'browser' or 'node'.
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
environment: 'node'
|
||||
});
|
||||
```
|
||||
|
||||
To support files with inline source maps, the `hookRequire` options can be specified, which will monitor all source files for inline source maps.
|
||||
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install({
|
||||
hookRequire: true
|
||||
});
|
||||
```
|
||||
|
||||
This monkey patches the `require` module loading chain, so is not enabled by default and is not recommended for any sort of production usage.
|
||||
|
||||
## Demos
|
||||
|
||||
#### Basic Demo
|
||||
|
||||
original.js:
|
||||
|
||||
```js
|
||||
throw new Error('test'); // This is the original code
|
||||
```
|
||||
|
||||
compiled.js:
|
||||
|
||||
```js
|
||||
require('@cspotcode/source-map-support').install();
|
||||
|
||||
throw new Error('test'); // This is the compiled code
|
||||
// The next line defines the sourceMapping.
|
||||
//# sourceMappingURL=compiled.js.map
|
||||
```
|
||||
|
||||
compiled.js.map:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"file": "compiled.js",
|
||||
"sources": ["original.js"],
|
||||
"names": [],
|
||||
"mappings": ";;AAAA,MAAM,IAAI"
|
||||
}
|
||||
```
|
||||
|
||||
Run compiled.js using node (notice how the stack trace uses original.js instead of compiled.js):
|
||||
|
||||
```
|
||||
$ node compiled.js
|
||||
|
||||
original.js:1
|
||||
throw new Error('test'); // This is the original code
|
||||
^
|
||||
Error: test
|
||||
at Object.<anonymous> (original.js:1:7)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
#### TypeScript Demo
|
||||
|
||||
demo.ts:
|
||||
|
||||
```typescript
|
||||
declare function require(name: string);
|
||||
require('@cspotcode/source-map-support').install();
|
||||
class Foo {
|
||||
constructor() { this.bar(); }
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
}
|
||||
new Foo();
|
||||
```
|
||||
|
||||
Compile and run the file using the TypeScript compiler from the terminal:
|
||||
|
||||
```
|
||||
$ npm install source-map-support typescript
|
||||
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
|
||||
$ node demo.js
|
||||
|
||||
demo.ts:5
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
^
|
||||
Error: this is a demo
|
||||
at Foo.bar (demo.ts:5:17)
|
||||
at new Foo (demo.ts:4:24)
|
||||
at Object.<anonymous> (demo.ts:7:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
There is also the option to use `-r source-map-support/register` with typescript, without the need add the `require('@cspotcode/source-map-support').install()` in the code base:
|
||||
|
||||
```
|
||||
$ npm install source-map-support typescript
|
||||
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
|
||||
$ node -r source-map-support/register demo.js
|
||||
|
||||
demo.ts:5
|
||||
bar() { throw new Error('this is a demo'); }
|
||||
^
|
||||
Error: this is a demo
|
||||
at Foo.bar (demo.ts:5:17)
|
||||
at new Foo (demo.ts:4:24)
|
||||
at Object.<anonymous> (demo.ts:7:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
at node.js:901:3
|
||||
```
|
||||
|
||||
#### CoffeeScript Demo
|
||||
|
||||
demo.coffee:
|
||||
|
||||
```coffee
|
||||
require('@cspotcode/source-map-support').install()
|
||||
foo = ->
|
||||
bar = -> throw new Error 'this is a demo'
|
||||
bar()
|
||||
foo()
|
||||
```
|
||||
|
||||
Compile and run the file using the CoffeeScript compiler from the terminal:
|
||||
|
||||
```sh
|
||||
$ npm install @cspotcode/source-map-support coffeescript
|
||||
$ node_modules/.bin/coffee --map --compile demo.coffee
|
||||
$ node demo.js
|
||||
|
||||
demo.coffee:3
|
||||
bar = -> throw new Error 'this is a demo'
|
||||
^
|
||||
Error: this is a demo
|
||||
at bar (demo.coffee:3:22)
|
||||
at foo (demo.coffee:4:3)
|
||||
at Object.<anonymous> (demo.coffee:5:1)
|
||||
at Object.<anonymous> (demo.coffee:1:1)
|
||||
at Module._compile (module.js:456:26)
|
||||
at Object.Module._extensions..js (module.js:474:10)
|
||||
at Module.load (module.js:356:32)
|
||||
at Function.Module._load (module.js:312:12)
|
||||
at Function.Module.runMain (module.js:497:10)
|
||||
at startup (node.js:119:16)
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
This repo contains both automated tests for node and manual tests for the browser. The automated tests can be run using mocha (type `mocha` in the root directory). To run the manual tests:
|
||||
|
||||
* Build the tests using `build.js`
|
||||
* Launch the HTTP server (`npm run serve-tests`) and visit
|
||||
* http://127.0.0.1:1336/amd-test
|
||||
* http://127.0.0.1:1336/browser-test
|
||||
* http://127.0.0.1:1336/browserify-test - **Currently not working** due to a bug with browserify (see [pull request #66](https://github.com/evanw/node-source-map-support/pull/66) for details).
|
||||
* For `header-test`, run `server.js` inside that directory and visit http://127.0.0.1:1337/
|
||||
|
||||
## License
|
||||
|
||||
This code is available under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
114
backend/node_modules/@cspotcode/source-map-support/browser-source-map-support.js
generated
vendored
Normal file
114
backend/node_modules/@cspotcode/source-map-support/browser-source-map-support.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Support for source maps in V8 stack traces
|
||||
* https://github.com/evanw/node-source-map-support
|
||||
*/
|
||||
/*
|
||||
The buffer module from node.js, for the browser.
|
||||
|
||||
@author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||
license MIT
|
||||
*/
|
||||
(this.define||function(R,U){this.sourceMapSupport=U()})("browser-source-map-support",function(R){(function e(C,J,A){function p(f,c){if(!J[f]){if(!C[f]){var l="function"==typeof require&&require;if(!c&&l)return l(f,!0);if(t)return t(f,!0);throw Error("Cannot find module '"+f+"'");}l=J[f]={exports:{}};C[f][0].call(l.exports,function(q){var r=C[f][1][q];return p(r?r:q)},l,l.exports,e,C,J,A)}return J[f].exports}for(var t="function"==typeof require&&require,m=0;m<A.length;m++)p(A[m]);return p})({1:[function(C,
|
||||
J,A){R=C("./source-map-support")},{"./source-map-support":21}],2:[function(C,J,A){(function(e){function p(m){m=m.charCodeAt(0);if(43===m)return 62;if(47===m)return 63;if(48>m)return-1;if(58>m)return m-48+52;if(91>m)return m-65;if(123>m)return m-97+26}var t="undefined"!==typeof Uint8Array?Uint8Array:Array;e.toByteArray=function(m){function f(d){q[k++]=d}if(0<m.length%4)throw Error("Invalid string. Length must be a multiple of 4");var c=m.length;var l="="===m.charAt(c-2)?2:"="===m.charAt(c-1)?1:0;var q=
|
||||
new t(3*m.length/4-l);var r=0<l?m.length-4:m.length;var k=0;for(c=0;c<r;c+=4){var u=p(m.charAt(c))<<18|p(m.charAt(c+1))<<12|p(m.charAt(c+2))<<6|p(m.charAt(c+3));f((u&16711680)>>16);f((u&65280)>>8);f(u&255)}2===l?(u=p(m.charAt(c))<<2|p(m.charAt(c+1))>>4,f(u&255)):1===l&&(u=p(m.charAt(c))<<10|p(m.charAt(c+1))<<4|p(m.charAt(c+2))>>2,f(u>>8&255),f(u&255));return q};e.fromByteArray=function(m){var f=m.length%3,c="",l;var q=0;for(l=m.length-f;q<l;q+=3){var r=(m[q]<<16)+(m[q+1]<<8)+m[q+2];r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>
|
||||
18&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>12&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>6&63)+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r&63);c+=r}switch(f){case 1:r=m[m.length-1];c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>2);c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<4&63);c+="==";break;case 2:r=(m[m.length-2]<<8)+
|
||||
m[m.length-1],c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>10),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r>>4&63),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(r<<2&63),c+="="}return c}})("undefined"===typeof A?this.base64js={}:A)},{}],3:[function(C,J,A){},{}],4:[function(C,J,A){(function(e){var p=Object.prototype.toString,t="function"===typeof e.alloc&&"function"===typeof e.allocUnsafe&&"function"===
|
||||
typeof e.from;J.exports=function(m,f,c){if("number"===typeof m)throw new TypeError('"value" argument must not be a number');if("ArrayBuffer"===p.call(m).slice(8,-1)){f>>>=0;var l=m.byteLength-f;if(0>l)throw new RangeError("'offset' is out of bounds");if(void 0===c)c=l;else if(c>>>=0,c>l)throw new RangeError("'length' is out of bounds");return t?e.from(m.slice(f,f+c)):new e(new Uint8Array(m.slice(f,f+c)))}if("string"===typeof m){c=f;if("string"!==typeof c||""===c)c="utf8";if(!e.isEncoding(c))throw new TypeError('"encoding" must be a valid string encoding');
|
||||
return t?e.from(m,c):new e(m,c)}return t?e.from(m):new e(m)}}).call(this,C("buffer").Buffer)},{buffer:5}],5:[function(C,J,A){function e(a,b,h){if(!(this instanceof e))return new e(a,b,h);var w=typeof a;if("number"===w)var y=0<a?a>>>0:0;else if("string"===w){if("base64"===b)for(a=(a.trim?a.trim():a.replace(/^\s+|\s+$/g,"")).replace(L,"");0!==a.length%4;)a+="=";y=e.byteLength(a,b)}else if("object"===w&&null!==a)"Buffer"===a.type&&z(a.data)&&(a=a.data),y=0<+a.length?Math.floor(+a.length):0;else throw new TypeError("must start with number, buffer, array or string");
|
||||
if(this.length>G)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+G.toString(16)+" bytes");if(e.TYPED_ARRAY_SUPPORT)var I=e._augment(new Uint8Array(y));else I=this,I.length=y,I._isBuffer=!0;if(e.TYPED_ARRAY_SUPPORT&&"number"===typeof a.byteLength)I._set(a);else{var K=a;if(z(K)||e.isBuffer(K)||K&&"object"===typeof K&&"number"===typeof K.length)if(e.isBuffer(a))for(b=0;b<y;b++)I[b]=a.readUInt8(b);else for(b=0;b<y;b++)I[b]=(a[b]%256+256)%256;else if("string"===w)I.write(a,
|
||||
0,b);else if("number"===w&&!e.TYPED_ARRAY_SUPPORT&&!h)for(b=0;b<y;b++)I[b]=0}return I}function p(a,b,h){var w="";for(h=Math.min(a.length,h);b<h;b++)w+=String.fromCharCode(a[b]);return w}function t(a,b,h){if(0!==a%1||0>a)throw new RangeError("offset is not uint");if(a+b>h)throw new RangeError("Trying to access beyond buffer length");}function m(a,b,h,w,y,I){if(!e.isBuffer(a))throw new TypeError("buffer must be a Buffer instance");if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");
|
||||
}function f(a,b,h,w){0>b&&(b=65535+b+1);for(var y=0,I=Math.min(a.length-h,2);y<I;y++)a[h+y]=(b&255<<8*(w?y:1-y))>>>8*(w?y:1-y)}function c(a,b,h,w){0>b&&(b=4294967295+b+1);for(var y=0,I=Math.min(a.length-h,4);y<I;y++)a[h+y]=b>>>8*(w?y:3-y)&255}function l(a,b,h,w,y,I){if(b>y||b<I)throw new TypeError("value is out of bounds");if(h+w>a.length)throw new TypeError("index out of range");}function q(a,b,h,w,y){y||l(a,b,h,4,3.4028234663852886E38,-3.4028234663852886E38);v.write(a,b,h,w,23,4);return h+4}function r(a,
|
||||
b,h,w,y){y||l(a,b,h,8,1.7976931348623157E308,-1.7976931348623157E308);v.write(a,b,h,w,52,8);return h+8}function k(a){for(var b=[],h=0;h<a.length;h++){var w=a.charCodeAt(h);if(127>=w)b.push(w);else{var y=h;55296<=w&&57343>=w&&h++;w=encodeURIComponent(a.slice(y,h+1)).substr(1).split("%");for(y=0;y<w.length;y++)b.push(parseInt(w[y],16))}}return b}function u(a){for(var b=[],h=0;h<a.length;h++)b.push(a.charCodeAt(h)&255);return b}function d(a,b,h,w,y){y&&(w-=w%y);for(y=0;y<w&&!(y+h>=b.length||y>=a.length);y++)b[y+
|
||||
h]=a[y];return y}function g(a){try{return decodeURIComponent(a)}catch(b){return String.fromCharCode(65533)}}var n=C("base64-js"),v=C("ieee754"),z=C("is-array");A.Buffer=e;A.SlowBuffer=e;A.INSPECT_MAX_BYTES=50;e.poolSize=8192;var G=1073741823;e.TYPED_ARRAY_SUPPORT=function(){try{var a=new ArrayBuffer(0),b=new Uint8Array(a);b.foo=function(){return 42};return 42===b.foo()&&"function"===typeof b.subarray&&0===(new Uint8Array(1)).subarray(1,1).byteLength}catch(h){return!1}}();e.isBuffer=function(a){return!(null==
|
||||
a||!a._isBuffer)};e.compare=function(a,b){if(!e.isBuffer(a)||!e.isBuffer(b))throw new TypeError("Arguments must be Buffers");for(var h=a.length,w=b.length,y=0,I=Math.min(h,w);y<I&&a[y]===b[y];y++);y!==I&&(h=a[y],w=b[y]);return h<w?-1:w<h?1:0};e.isEncoding=function(a){switch(String(a).toLowerCase()){case "hex":case "utf8":case "utf-8":case "ascii":case "binary":case "base64":case "raw":case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":return!0;default:return!1}};e.concat=function(a,b){if(!z(a))throw new TypeError("Usage: Buffer.concat(list[, length])");
|
||||
if(0===a.length)return new e(0);if(1===a.length)return a[0];var h;if(void 0===b)for(h=b=0;h<a.length;h++)b+=a[h].length;var w=new e(b),y=0;for(h=0;h<a.length;h++){var I=a[h];I.copy(w,y);y+=I.length}return w};e.byteLength=function(a,b){a+="";switch(b||"utf8"){case "ascii":case "binary":case "raw":var h=a.length;break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":h=2*a.length;break;case "hex":h=a.length>>>1;break;case "utf8":case "utf-8":h=k(a).length;break;case "base64":h=n.toByteArray(a).length;
|
||||
break;default:h=a.length}return h};e.prototype.length=void 0;e.prototype.parent=void 0;e.prototype.toString=function(a,b,h){var w=!1;b>>>=0;h=void 0===h||Infinity===h?this.length:h>>>0;a||(a="utf8");0>b&&(b=0);h>this.length&&(h=this.length);if(h<=b)return"";for(;;)switch(a){case "hex":a=b;b=h;h=this.length;if(!a||0>a)a=0;if(!b||0>b||b>h)b=h;w="";for(h=a;h<b;h++)a=w,w=this[h],w=16>w?"0"+w.toString(16):w.toString(16),w=a+w;return w;case "utf8":case "utf-8":w=a="";for(h=Math.min(this.length,h);b<h;b++)127>=
|
||||
this[b]?(a+=g(w)+String.fromCharCode(this[b]),w=""):w+="%"+this[b].toString(16);return a+g(w);case "ascii":return p(this,b,h);case "binary":return p(this,b,h);case "base64":return b=0===b&&h===this.length?n.fromByteArray(this):n.fromByteArray(this.slice(b,h)),b;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":b=this.slice(b,h);h="";for(a=0;a<b.length;a+=2)h+=String.fromCharCode(b[a]+256*b[a+1]);return h;default:if(w)throw new TypeError("Unknown encoding: "+a);a=(a+"").toLowerCase();w=!0}};
|
||||
e.prototype.equals=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return 0===e.compare(this,a)};e.prototype.inspect=function(){var a="",b=A.INSPECT_MAX_BYTES;0<this.length&&(a=this.toString("hex",0,b).match(/.{2}/g).join(" "),this.length>b&&(a+=" ... "));return"<Buffer "+a+">"};e.prototype.compare=function(a){if(!e.isBuffer(a))throw new TypeError("Argument must be a Buffer");return e.compare(this,a)};e.prototype.get=function(a){console.log(".get() is deprecated. Access using array indexes instead.");
|
||||
return this.readUInt8(a)};e.prototype.set=function(a,b){console.log(".set() is deprecated. Access using array indexes instead.");return this.writeUInt8(a,b)};e.prototype.write=function(a,b,h,w){if(isFinite(b))isFinite(h)||(w=h,h=void 0);else{var y=w;w=b;b=h;h=y}b=Number(b)||0;y=this.length-b;h?(h=Number(h),h>y&&(h=y)):h=y;w=String(w||"utf8").toLowerCase();switch(w){case "hex":b=Number(b)||0;w=this.length-b;h?(h=Number(h),h>w&&(h=w)):h=w;w=a.length;if(0!==w%2)throw Error("Invalid hex string");h>w/
|
||||
2&&(h=w/2);for(w=0;w<h;w++){y=parseInt(a.substr(2*w,2),16);if(isNaN(y))throw Error("Invalid hex string");this[b+w]=y}a=w;break;case "utf8":case "utf-8":a=d(k(a),this,b,h);break;case "ascii":a=d(u(a),this,b,h);break;case "binary":a=d(u(a),this,b,h);break;case "base64":a=d(n.toByteArray(a),this,b,h);break;case "ucs2":case "ucs-2":case "utf16le":case "utf-16le":y=[];for(var I=0;I<a.length;I++){var K=a.charCodeAt(I);w=K>>8;K%=256;y.push(K);y.push(w)}a=d(y,this,b,h,2);break;default:throw new TypeError("Unknown encoding: "+
|
||||
w);}return a};e.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};e.prototype.slice=function(a,b){var h=this.length;a=~~a;b=void 0===b?h:~~b;0>a?(a+=h,0>a&&(a=0)):a>h&&(a=h);0>b?(b+=h,0>b&&(b=0)):b>h&&(b=h);b<a&&(b=a);if(e.TYPED_ARRAY_SUPPORT)return e._augment(this.subarray(a,b));h=b-a;for(var w=new e(h,void 0,!0),y=0;y<h;y++)w[y]=this[y+a];return w};e.prototype.readUInt8=function(a,b){b||t(a,1,this.length);return this[a]};e.prototype.readUInt16LE=
|
||||
function(a,b){b||t(a,2,this.length);return this[a]|this[a+1]<<8};e.prototype.readUInt16BE=function(a,b){b||t(a,2,this.length);return this[a]<<8|this[a+1]};e.prototype.readUInt32LE=function(a,b){b||t(a,4,this.length);return(this[a]|this[a+1]<<8|this[a+2]<<16)+16777216*this[a+3]};e.prototype.readUInt32BE=function(a,b){b||t(a,4,this.length);return 16777216*this[a]+(this[a+1]<<16|this[a+2]<<8|this[a+3])};e.prototype.readInt8=function(a,b){b||t(a,1,this.length);return this[a]&128?-1*(255-this[a]+1):this[a]};
|
||||
e.prototype.readInt16LE=function(a,b){b||t(a,2,this.length);var h=this[a]|this[a+1]<<8;return h&32768?h|4294901760:h};e.prototype.readInt16BE=function(a,b){b||t(a,2,this.length);var h=this[a+1]|this[a]<<8;return h&32768?h|4294901760:h};e.prototype.readInt32LE=function(a,b){b||t(a,4,this.length);return this[a]|this[a+1]<<8|this[a+2]<<16|this[a+3]<<24};e.prototype.readInt32BE=function(a,b){b||t(a,4,this.length);return this[a]<<24|this[a+1]<<16|this[a+2]<<8|this[a+3]};e.prototype.readFloatLE=function(a,
|
||||
b){b||t(a,4,this.length);return v.read(this,a,!0,23,4)};e.prototype.readFloatBE=function(a,b){b||t(a,4,this.length);return v.read(this,a,!1,23,4)};e.prototype.readDoubleLE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!0,52,8)};e.prototype.readDoubleBE=function(a,b){b||t(a,8,this.length);return v.read(this,a,!1,52,8)};e.prototype.writeUInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,255,0);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));this[b]=a;return b+1};e.prototype.writeUInt16LE=function(a,
|
||||
b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeUInt16BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,65535,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeUInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b+3]=a>>>24,this[b+2]=a>>>16,this[b+1]=a>>>8,this[b]=a):c(this,a,b,!0);return b+4};e.prototype.writeUInt32BE=function(a,
|
||||
b,h){a=+a;b>>>=0;h||m(this,a,b,4,4294967295,0);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeInt8=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,1,127,-128);e.TYPED_ARRAY_SUPPORT||(a=Math.floor(a));0>a&&(a=255+a+1);this[b]=a;return b+1};e.prototype.writeInt16LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8):f(this,a,b,!0);return b+2};e.prototype.writeInt16BE=function(a,
|
||||
b,h){a=+a;b>>>=0;h||m(this,a,b,2,32767,-32768);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>8,this[b+1]=a):f(this,a,b,!1);return b+2};e.prototype.writeInt32LE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);e.TYPED_ARRAY_SUPPORT?(this[b]=a,this[b+1]=a>>>8,this[b+2]=a>>>16,this[b+3]=a>>>24):c(this,a,b,!0);return b+4};e.prototype.writeInt32BE=function(a,b,h){a=+a;b>>>=0;h||m(this,a,b,4,2147483647,-2147483648);0>a&&(a=4294967295+a+1);e.TYPED_ARRAY_SUPPORT?(this[b]=a>>>24,this[b+1]=a>>>16,this[b+
|
||||
2]=a>>>8,this[b+3]=a):c(this,a,b,!1);return b+4};e.prototype.writeFloatLE=function(a,b,h){return q(this,a,b,!0,h)};e.prototype.writeFloatBE=function(a,b,h){return q(this,a,b,!1,h)};e.prototype.writeDoubleLE=function(a,b,h){return r(this,a,b,!0,h)};e.prototype.writeDoubleBE=function(a,b,h){return r(this,a,b,!1,h)};e.prototype.copy=function(a,b,h,w){h||(h=0);w||0===w||(w=this.length);b||(b=0);if(w!==h&&0!==a.length&&0!==this.length){if(w<h)throw new TypeError("sourceEnd < sourceStart");if(0>b||b>=a.length)throw new TypeError("targetStart out of bounds");
|
||||
if(0>h||h>=this.length)throw new TypeError("sourceStart out of bounds");if(0>w||w>this.length)throw new TypeError("sourceEnd out of bounds");w>this.length&&(w=this.length);a.length-b<w-h&&(w=a.length-b+h);w-=h;if(1E3>w||!e.TYPED_ARRAY_SUPPORT)for(var y=0;y<w;y++)a[y+b]=this[y+h];else a._set(this.subarray(h,h+w),b)}};e.prototype.fill=function(a,b,h){a||(a=0);b||(b=0);h||(h=this.length);if(h<b)throw new TypeError("end < start");if(h!==b&&0!==this.length){if(0>b||b>=this.length)throw new TypeError("start out of bounds");
|
||||
if(0>h||h>this.length)throw new TypeError("end out of bounds");if("number"===typeof a)for(;b<h;b++)this[b]=a;else{a=k(a.toString());for(var w=a.length;b<h;b++)this[b]=a[b%w]}return this}};e.prototype.toArrayBuffer=function(){if("undefined"!==typeof Uint8Array){if(e.TYPED_ARRAY_SUPPORT)return(new e(this)).buffer;for(var a=new Uint8Array(this.length),b=0,h=a.length;b<h;b+=1)a[b]=this[b];return a.buffer}throw new TypeError("Buffer.toArrayBuffer not supported in this browser");};var D=e.prototype;e._augment=
|
||||
function(a){a.constructor=e;a._isBuffer=!0;a._get=a.get;a._set=a.set;a.get=D.get;a.set=D.set;a.write=D.write;a.toString=D.toString;a.toLocaleString=D.toString;a.toJSON=D.toJSON;a.equals=D.equals;a.compare=D.compare;a.copy=D.copy;a.slice=D.slice;a.readUInt8=D.readUInt8;a.readUInt16LE=D.readUInt16LE;a.readUInt16BE=D.readUInt16BE;a.readUInt32LE=D.readUInt32LE;a.readUInt32BE=D.readUInt32BE;a.readInt8=D.readInt8;a.readInt16LE=D.readInt16LE;a.readInt16BE=D.readInt16BE;a.readInt32LE=D.readInt32LE;a.readInt32BE=
|
||||
D.readInt32BE;a.readFloatLE=D.readFloatLE;a.readFloatBE=D.readFloatBE;a.readDoubleLE=D.readDoubleLE;a.readDoubleBE=D.readDoubleBE;a.writeUInt8=D.writeUInt8;a.writeUInt16LE=D.writeUInt16LE;a.writeUInt16BE=D.writeUInt16BE;a.writeUInt32LE=D.writeUInt32LE;a.writeUInt32BE=D.writeUInt32BE;a.writeInt8=D.writeInt8;a.writeInt16LE=D.writeInt16LE;a.writeInt16BE=D.writeInt16BE;a.writeInt32LE=D.writeInt32LE;a.writeInt32BE=D.writeInt32BE;a.writeFloatLE=D.writeFloatLE;a.writeFloatBE=D.writeFloatBE;a.writeDoubleLE=
|
||||
D.writeDoubleLE;a.writeDoubleBE=D.writeDoubleBE;a.fill=D.fill;a.inspect=D.inspect;a.toArrayBuffer=D.toArrayBuffer;return a};var L=/[^+\/0-9A-z]/g},{"base64-js":2,ieee754:6,"is-array":7}],6:[function(C,J,A){A.read=function(e,p,t,m,f){var c=8*f-m-1;var l=(1<<c)-1,q=l>>1,r=-7;f=t?f-1:0;var k=t?-1:1,u=e[p+f];f+=k;t=u&(1<<-r)-1;u>>=-r;for(r+=c;0<r;t=256*t+e[p+f],f+=k,r-=8);c=t&(1<<-r)-1;t>>=-r;for(r+=m;0<r;c=256*c+e[p+f],f+=k,r-=8);if(0===t)t=1-q;else{if(t===l)return c?NaN:Infinity*(u?-1:1);c+=Math.pow(2,
|
||||
m);t-=q}return(u?-1:1)*c*Math.pow(2,t-m)};A.write=function(e,p,t,m,f,c){var l,q=8*c-f-1,r=(1<<q)-1,k=r>>1,u=23===f?Math.pow(2,-24)-Math.pow(2,-77):0;c=m?0:c-1;var d=m?1:-1,g=0>p||0===p&&0>1/p?1:0;p=Math.abs(p);isNaN(p)||Infinity===p?(p=isNaN(p)?1:0,m=r):(m=Math.floor(Math.log(p)/Math.LN2),1>p*(l=Math.pow(2,-m))&&(m--,l*=2),p=1<=m+k?p+u/l:p+u*Math.pow(2,1-k),2<=p*l&&(m++,l/=2),m+k>=r?(p=0,m=r):1<=m+k?(p=(p*l-1)*Math.pow(2,f),m+=k):(p=p*Math.pow(2,k-1)*Math.pow(2,f),m=0));for(;8<=f;e[t+c]=p&255,c+=
|
||||
d,p/=256,f-=8);m=m<<f|p;for(q+=f;0<q;e[t+c]=m&255,c+=d,m/=256,q-=8);e[t+c-d]|=128*g}},{}],7:[function(C,J,A){var e=Object.prototype.toString;J.exports=Array.isArray||function(p){return!!p&&"[object Array]"==e.call(p)}},{}],8:[function(C,J,A){(function(e){function p(c,l){for(var q=0,r=c.length-1;0<=r;r--){var k=c[r];"."===k?c.splice(r,1):".."===k?(c.splice(r,1),q++):q&&(c.splice(r,1),q--)}if(l)for(;q--;q)c.unshift("..");return c}function t(c,l){if(c.filter)return c.filter(l);for(var q=[],r=0;r<c.length;r++)l(c[r],
|
||||
r,c)&&q.push(c[r]);return q}var m=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;A.resolve=function(){for(var c="",l=!1,q=arguments.length-1;-1<=q&&!l;q--){var r=0<=q?arguments[q]:e.cwd();if("string"!==typeof r)throw new TypeError("Arguments to path.resolve must be strings");r&&(c=r+"/"+c,l="/"===r.charAt(0))}c=p(t(c.split("/"),function(k){return!!k}),!l).join("/");return(l?"/":"")+c||"."};A.normalize=function(c){var l=A.isAbsolute(c),q="/"===f(c,-1);(c=p(t(c.split("/"),function(r){return!!r}),
|
||||
!l).join("/"))||l||(c=".");c&&q&&(c+="/");return(l?"/":"")+c};A.isAbsolute=function(c){return"/"===c.charAt(0)};A.join=function(){var c=Array.prototype.slice.call(arguments,0);return A.normalize(t(c,function(l,q){if("string"!==typeof l)throw new TypeError("Arguments to path.join must be strings");return l}).join("/"))};A.relative=function(c,l){function q(n){for(var v=0;v<n.length&&""===n[v];v++);for(var z=n.length-1;0<=z&&""===n[z];z--);return v>z?[]:n.slice(v,z-v+1)}c=A.resolve(c).substr(1);l=A.resolve(l).substr(1);
|
||||
for(var r=q(c.split("/")),k=q(l.split("/")),u=Math.min(r.length,k.length),d=u,g=0;g<u;g++)if(r[g]!==k[g]){d=g;break}u=[];for(g=d;g<r.length;g++)u.push("..");u=u.concat(k.slice(d));return u.join("/")};A.sep="/";A.delimiter=":";A.dirname=function(c){var l=m.exec(c).slice(1);c=l[0];l=l[1];if(!c&&!l)return".";l&&(l=l.substr(0,l.length-1));return c+l};A.basename=function(c,l){var q=m.exec(c).slice(1)[2];l&&q.substr(-1*l.length)===l&&(q=q.substr(0,q.length-l.length));return q};A.extname=function(c){return m.exec(c).slice(1)[3]};
|
||||
var f="b"==="ab".substr(-1)?function(c,l,q){return c.substr(l,q)}:function(c,l,q){0>l&&(l=c.length+l);return c.substr(l,q)}}).call(this,C("g5I+bs"))},{"g5I+bs":9}],9:[function(C,J,A){function e(){}C=J.exports={};C.nextTick=function(){if("undefined"!==typeof window&&window.setImmediate)return function(t){return window.setImmediate(t)};if("undefined"!==typeof window&&window.postMessage&&window.addEventListener){var p=[];window.addEventListener("message",function(t){var m=t.source;m!==window&&null!==
|
||||
m||"process-tick"!==t.data||(t.stopPropagation(),0<p.length&&p.shift()())},!0);return function(t){p.push(t);window.postMessage("process-tick","*")}}return function(t){setTimeout(t,0)}}();C.title="browser";C.browser=!0;C.env={};C.argv=[];C.on=e;C.addListener=e;C.once=e;C.off=e;C.removeListener=e;C.removeAllListeners=e;C.emit=e;C.binding=function(p){throw Error("process.binding is not supported");};C.cwd=function(){return"/"};C.chdir=function(p){throw Error("process.chdir is not supported");}},{}],
|
||||
10:[function(C,J,A){function e(){this._array=[];this._set=m?new Map:Object.create(null)}var p=C("./util"),t=Object.prototype.hasOwnProperty,m="undefined"!==typeof Map;e.fromArray=function(f,c){for(var l=new e,q=0,r=f.length;q<r;q++)l.add(f[q],c);return l};e.prototype.size=function(){return m?this._set.size:Object.getOwnPropertyNames(this._set).length};e.prototype.add=function(f,c){var l=m?f:p.toSetString(f),q=m?this.has(f):t.call(this._set,l),r=this._array.length;q&&!c||this._array.push(f);q||(m?
|
||||
this._set.set(f,r):this._set[l]=r)};e.prototype.has=function(f){if(m)return this._set.has(f);f=p.toSetString(f);return t.call(this._set,f)};e.prototype.indexOf=function(f){if(m){var c=this._set.get(f);if(0<=c)return c}else if(c=p.toSetString(f),t.call(this._set,c))return this._set[c];throw Error('"'+f+'" is not in the set.');};e.prototype.at=function(f){if(0<=f&&f<this._array.length)return this._array[f];throw Error("No element indexed by "+f);};e.prototype.toArray=function(){return this._array.slice()};
|
||||
A.ArraySet=e},{"./util":19}],11:[function(C,J,A){var e=C("./base64");A.encode=function(p){var t="",m=0>p?(-p<<1)+1:p<<1;do p=m&31,m>>>=5,0<m&&(p|=32),t+=e.encode(p);while(0<m);return t};A.decode=function(p,t,m){var f=p.length,c=0,l=0;do{if(t>=f)throw Error("Expected more digits in base 64 VLQ value.");var q=e.decode(p.charCodeAt(t++));if(-1===q)throw Error("Invalid base64 digit: "+p.charAt(t-1));var r=!!(q&32);q&=31;c+=q<<l;l+=5}while(r);p=c>>1;m.value=1===(c&1)?-p:p;m.rest=t}},{"./base64":12}],12:[function(C,
|
||||
J,A){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");A.encode=function(p){if(0<=p&&p<e.length)return e[p];throw new TypeError("Must be between 0 and 63: "+p);};A.decode=function(p){return 65<=p&&90>=p?p-65:97<=p&&122>=p?p-97+26:48<=p&&57>=p?p-48+52:43==p?62:47==p?63:-1}},{}],13:[function(C,J,A){function e(p,t,m,f,c,l){var q=Math.floor((t-p)/2)+p,r=c(m,f[q],!0);return 0===r?q:0<r?1<t-q?e(q,t,m,f,c,l):l==A.LEAST_UPPER_BOUND?t<f.length?t:-1:q:1<q-p?e(p,q,m,f,c,l):l==
|
||||
A.LEAST_UPPER_BOUND?q:0>p?-1:p}A.GREATEST_LOWER_BOUND=1;A.LEAST_UPPER_BOUND=2;A.search=function(p,t,m,f){if(0===t.length)return-1;p=e(-1,t.length,p,t,m,f||A.GREATEST_LOWER_BOUND);if(0>p)return-1;for(;0<=p-1&&0===m(t[p],t[p-1],!0);)--p;return p}},{}],14:[function(C,J,A){function e(){this._array=[];this._sorted=!0;this._last={generatedLine:-1,generatedColumn:0}}var p=C("./util");e.prototype.unsortedForEach=function(t,m){this._array.forEach(t,m)};e.prototype.add=function(t){var m=this._last,f=m.generatedLine,
|
||||
c=t.generatedLine,l=m.generatedColumn,q=t.generatedColumn;c>f||c==f&&q>=l||0>=p.compareByGeneratedPositionsInflated(m,t)?this._last=t:this._sorted=!1;this._array.push(t)};e.prototype.toArray=function(){this._sorted||(this._array.sort(p.compareByGeneratedPositionsInflated),this._sorted=!0);return this._array};A.MappingList=e},{"./util":19}],15:[function(C,J,A){function e(t,m,f){var c=t[m];t[m]=t[f];t[f]=c}function p(t,m,f,c){if(f<c){var l=f-1;e(t,Math.round(f+Math.random()*(c-f)),c);for(var q=t[c],
|
||||
r=f;r<c;r++)0>=m(t[r],q)&&(l+=1,e(t,l,r));e(t,l+1,r);l+=1;p(t,m,f,l-1);p(t,m,l+1,c)}}A.quickSort=function(t,m){p(t,m,0,t.length-1)}},{}],16:[function(C,J,A){function e(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));return null!=d.sections?new m(d,u):new p(d,u)}function p(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version"),n=f.getArg(d,"sources"),v=f.getArg(d,"names",[]),z=f.getArg(d,"sourceRoot",null),G=f.getArg(d,"sourcesContent",null),D=f.getArg(d,
|
||||
"mappings");d=f.getArg(d,"file",null);if(g!=this._version)throw Error("Unsupported version: "+g);z&&(z=f.normalize(z));n=n.map(String).map(f.normalize).map(function(L){return z&&f.isAbsolute(z)&&f.isAbsolute(L)?f.relative(z,L):L});this._names=l.fromArray(v.map(String),!0);this._sources=l.fromArray(n,!0);this.sourceRoot=z;this.sourcesContent=G;this._mappings=D;this._sourceMapURL=u;this.file=d}function t(){this.generatedColumn=this.generatedLine=0;this.name=this.originalColumn=this.originalLine=this.source=
|
||||
null}function m(k,u){var d=k;"string"===typeof k&&(d=f.parseSourceMapInput(k));var g=f.getArg(d,"version");d=f.getArg(d,"sections");if(g!=this._version)throw Error("Unsupported version: "+g);this._sources=new l;this._names=new l;var n={line:-1,column:0};this._sections=d.map(function(v){if(v.url)throw Error("Support for url field in sections not implemented.");var z=f.getArg(v,"offset"),G=f.getArg(z,"line"),D=f.getArg(z,"column");if(G<n.line||G===n.line&&D<n.column)throw Error("Section offsets must be ordered and non-overlapping.");
|
||||
n=z;return{generatedOffset:{generatedLine:G+1,generatedColumn:D+1},consumer:new e(f.getArg(v,"map"),u)}})}var f=C("./util"),c=C("./binary-search"),l=C("./array-set").ArraySet,q=C("./base64-vlq"),r=C("./quick-sort").quickSort;e.fromSourceMap=function(k){return p.fromSourceMap(k)};e.prototype._version=3;e.prototype.__generatedMappings=null;Object.defineProperty(e.prototype,"_generatedMappings",{configurable:!0,enumerable:!0,get:function(){this.__generatedMappings||this._parseMappings(this._mappings,
|
||||
this.sourceRoot);return this.__generatedMappings}});e.prototype.__originalMappings=null;Object.defineProperty(e.prototype,"_originalMappings",{configurable:!0,enumerable:!0,get:function(){this.__originalMappings||this._parseMappings(this._mappings,this.sourceRoot);return this.__originalMappings}});e.prototype._charIsMappingSeparator=function(k,u){var d=k.charAt(u);return";"===d||","===d};e.prototype._parseMappings=function(k,u){throw Error("Subclasses must implement _parseMappings");};e.GENERATED_ORDER=
|
||||
1;e.ORIGINAL_ORDER=2;e.GREATEST_LOWER_BOUND=1;e.LEAST_UPPER_BOUND=2;e.prototype.eachMapping=function(k,u,d){u=u||null;switch(d||e.GENERATED_ORDER){case e.GENERATED_ORDER:d=this._generatedMappings;break;case e.ORIGINAL_ORDER:d=this._originalMappings;break;default:throw Error("Unknown order of iteration.");}var g=this.sourceRoot;d.map(function(n){var v=null===n.source?null:this._sources.at(n.source);v=f.computeSourceURL(g,v,this._sourceMapURL);return{source:v,generatedLine:n.generatedLine,generatedColumn:n.generatedColumn,
|
||||
originalLine:n.originalLine,originalColumn:n.originalColumn,name:null===n.name?null:this._names.at(n.name)}},this).forEach(k,u)};e.prototype.allGeneratedPositionsFor=function(k){var u=f.getArg(k,"line"),d={source:f.getArg(k,"source"),originalLine:u,originalColumn:f.getArg(k,"column",0)};null!=this.sourceRoot&&(d.source=f.relative(this.sourceRoot,d.source));if(!this._sources.has(d.source))return[];d.source=this._sources.indexOf(d.source);var g=[];d=this._findMapping(d,this._originalMappings,"originalLine",
|
||||
"originalColumn",f.compareByOriginalPositions,c.LEAST_UPPER_BOUND);if(0<=d){var n=this._originalMappings[d];if(void 0===k.column)for(u=n.originalLine;n&&n.originalLine===u;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d];else for(k=n.originalColumn;n&&n.originalLine===u&&n.originalColumn==k;)g.push({line:f.getArg(n,"generatedLine",null),column:f.getArg(n,"generatedColumn",null),
|
||||
lastColumn:f.getArg(n,"lastGeneratedColumn",null)}),n=this._originalMappings[++d]}return g};A.SourceMapConsumer=e;p.prototype=Object.create(e.prototype);p.prototype.consumer=e;p.fromSourceMap=function(k,u){var d=Object.create(p.prototype),g=d._names=l.fromArray(k._names.toArray(),!0),n=d._sources=l.fromArray(k._sources.toArray(),!0);d.sourceRoot=k._sourceRoot;d.sourcesContent=k._generateSourcesContent(d._sources.toArray(),d.sourceRoot);d.file=k._file;d._sourceMapURL=u;for(var v=k._mappings.toArray().slice(),
|
||||
z=d.__generatedMappings=[],G=d.__originalMappings=[],D=0,L=v.length;D<L;D++){var a=v[D],b=new t;b.generatedLine=a.generatedLine;b.generatedColumn=a.generatedColumn;a.source&&(b.source=n.indexOf(a.source),b.originalLine=a.originalLine,b.originalColumn=a.originalColumn,a.name&&(b.name=g.indexOf(a.name)),G.push(b));z.push(b)}r(d.__originalMappings,f.compareByOriginalPositions);return d};p.prototype._version=3;Object.defineProperty(p.prototype,"sources",{get:function(){return this._sources.toArray().map(function(k){return f.computeSourceURL(this.sourceRoot,
|
||||
k,this._sourceMapURL)},this)}});p.prototype._parseMappings=function(k,u){for(var d=1,g=0,n=0,v=0,z=0,G=0,D=k.length,L=0,a={},b={},h=[],w=[],y,I,K,N,P;L<D;)if(";"===k.charAt(L))d++,L++,g=0;else if(","===k.charAt(L))L++;else{y=new t;y.generatedLine=d;for(N=L;N<D&&!this._charIsMappingSeparator(k,N);N++);I=k.slice(L,N);if(K=a[I])L+=I.length;else{for(K=[];L<N;)q.decode(k,L,b),P=b.value,L=b.rest,K.push(P);if(2===K.length)throw Error("Found a source, but no line and column");if(3===K.length)throw Error("Found a source and line, but no column");
|
||||
a[I]=K}y.generatedColumn=g+K[0];g=y.generatedColumn;1<K.length&&(y.source=z+K[1],z+=K[1],y.originalLine=n+K[2],n=y.originalLine,y.originalLine+=1,y.originalColumn=v+K[3],v=y.originalColumn,4<K.length&&(y.name=G+K[4],G+=K[4]));w.push(y);"number"===typeof y.originalLine&&h.push(y)}r(w,f.compareByGeneratedPositionsDeflated);this.__generatedMappings=w;r(h,f.compareByOriginalPositions);this.__originalMappings=h};p.prototype._findMapping=function(k,u,d,g,n,v){if(0>=k[d])throw new TypeError("Line must be greater than or equal to 1, got "+
|
||||
k[d]);if(0>k[g])throw new TypeError("Column must be greater than or equal to 0, got "+k[g]);return c.search(k,u,n,v)};p.prototype.computeColumnSpans=function(){for(var k=0;k<this._generatedMappings.length;++k){var u=this._generatedMappings[k];if(k+1<this._generatedMappings.length){var d=this._generatedMappings[k+1];if(u.generatedLine===d.generatedLine){u.lastGeneratedColumn=d.generatedColumn-1;continue}}u.lastGeneratedColumn=Infinity}};p.prototype.originalPositionFor=function(k){var u={generatedLine:f.getArg(k,
|
||||
"line"),generatedColumn:f.getArg(k,"column")};k=this._findMapping(u,this._generatedMappings,"generatedLine","generatedColumn",f.compareByGeneratedPositionsDeflated,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));if(0<=k&&(k=this._generatedMappings[k],k.generatedLine===u.generatedLine)){u=f.getArg(k,"source",null);null!==u&&(u=this._sources.at(u),u=f.computeSourceURL(this.sourceRoot,u,this._sourceMapURL));var d=f.getArg(k,"name",null);null!==d&&(d=this._names.at(d));return{source:u,line:f.getArg(k,"originalLine",
|
||||
null),column:f.getArg(k,"originalColumn",null),name:d}}return{source:null,line:null,column:null,name:null}};p.prototype.hasContentsOfAllSources=function(){return this.sourcesContent?this.sourcesContent.length>=this._sources.size()&&!this.sourcesContent.some(function(k){return null==k}):!1};p.prototype.sourceContentFor=function(k,u){if(!this.sourcesContent)return null;var d=k;null!=this.sourceRoot&&(d=f.relative(this.sourceRoot,d));if(this._sources.has(d))return this.sourcesContent[this._sources.indexOf(d)];
|
||||
var g=this.sources,n;for(n=0;n<g.length;++n)if(g[n]==k)return this.sourcesContent[n];var v;if(null!=this.sourceRoot&&(v=f.urlParse(this.sourceRoot))){g=d.replace(/^file:\/\//,"");if("file"==v.scheme&&this._sources.has(g))return this.sourcesContent[this._sources.indexOf(g)];if((!v.path||"/"==v.path)&&this._sources.has("/"+d))return this.sourcesContent[this._sources.indexOf("/"+d)]}if(u)return null;throw Error('"'+d+'" is not in the SourceMap.');};p.prototype.generatedPositionFor=function(k){var u=
|
||||
f.getArg(k,"source");null!=this.sourceRoot&&(u=f.relative(this.sourceRoot,u));if(!this._sources.has(u))return{line:null,column:null,lastColumn:null};u=this._sources.indexOf(u);u={source:u,originalLine:f.getArg(k,"line"),originalColumn:f.getArg(k,"column")};k=this._findMapping(u,this._originalMappings,"originalLine","originalColumn",f.compareByOriginalPositions,f.getArg(k,"bias",e.GREATEST_LOWER_BOUND));return 0<=k&&(k=this._originalMappings[k],k.source===u.source)?{line:f.getArg(k,"generatedLine",
|
||||
null),column:f.getArg(k,"generatedColumn",null),lastColumn:f.getArg(k,"lastGeneratedColumn",null)}:{line:null,column:null,lastColumn:null}};A.BasicSourceMapConsumer=p;m.prototype=Object.create(e.prototype);m.prototype.constructor=e;m.prototype._version=3;Object.defineProperty(m.prototype,"sources",{get:function(){for(var k=[],u=0;u<this._sections.length;u++)for(var d=0;d<this._sections[u].consumer.sources.length;d++)k.push(this._sections[u].consumer.sources[d]);return k}});m.prototype.originalPositionFor=
|
||||
function(k){var u={generatedLine:f.getArg(k,"line"),generatedColumn:f.getArg(k,"column")},d=c.search(u,this._sections,function(g,n){var v=g.generatedLine-n.generatedOffset.generatedLine;return v?v:g.generatedColumn-n.generatedOffset.generatedColumn});return(d=this._sections[d])?d.consumer.originalPositionFor({line:u.generatedLine-(d.generatedOffset.generatedLine-1),column:u.generatedColumn-(d.generatedOffset.generatedLine===u.generatedLine?d.generatedOffset.generatedColumn-1:0),bias:k.bias}):{source:null,
|
||||
line:null,column:null,name:null}};m.prototype.hasContentsOfAllSources=function(){return this._sections.every(function(k){return k.consumer.hasContentsOfAllSources()})};m.prototype.sourceContentFor=function(k,u){for(var d=0;d<this._sections.length;d++){var g=this._sections[d].consumer.sourceContentFor(k,!0);if(g)return g}if(u)return null;throw Error('"'+k+'" is not in the SourceMap.');};m.prototype.generatedPositionFor=function(k){for(var u=0;u<this._sections.length;u++){var d=this._sections[u];if(-1!==
|
||||
d.consumer.sources.indexOf(f.getArg(k,"source"))){var g=d.consumer.generatedPositionFor(k);if(g)return{line:g.line+(d.generatedOffset.generatedLine-1),column:g.column+(d.generatedOffset.generatedLine===g.line?d.generatedOffset.generatedColumn-1:0)}}}return{line:null,column:null}};m.prototype._parseMappings=function(k,u){this.__generatedMappings=[];this.__originalMappings=[];for(var d=0;d<this._sections.length;d++)for(var g=this._sections[d],n=g.consumer._generatedMappings,v=0;v<n.length;v++){var z=
|
||||
n[v],G=g.consumer._sources.at(z.source);G=f.computeSourceURL(g.consumer.sourceRoot,G,this._sourceMapURL);this._sources.add(G);G=this._sources.indexOf(G);var D=null;z.name&&(D=g.consumer._names.at(z.name),this._names.add(D),D=this._names.indexOf(D));z={source:G,generatedLine:z.generatedLine+(g.generatedOffset.generatedLine-1),generatedColumn:z.generatedColumn+(g.generatedOffset.generatedLine===z.generatedLine?g.generatedOffset.generatedColumn-1:0),originalLine:z.originalLine,originalColumn:z.originalColumn,
|
||||
name:D};this.__generatedMappings.push(z);"number"===typeof z.originalLine&&this.__originalMappings.push(z)}r(this.__generatedMappings,f.compareByGeneratedPositionsDeflated);r(this.__originalMappings,f.compareByOriginalPositions)};A.IndexedSourceMapConsumer=m},{"./array-set":10,"./base64-vlq":11,"./binary-search":13,"./quick-sort":15,"./util":19}],17:[function(C,J,A){function e(c){c||(c={});this._file=t.getArg(c,"file",null);this._sourceRoot=t.getArg(c,"sourceRoot",null);this._skipValidation=t.getArg(c,
|
||||
"skipValidation",!1);this._sources=new m;this._names=new m;this._mappings=new f;this._sourcesContents=null}var p=C("./base64-vlq"),t=C("./util"),m=C("./array-set").ArraySet,f=C("./mapping-list").MappingList;e.prototype._version=3;e.fromSourceMap=function(c){var l=c.sourceRoot,q=new e({file:c.file,sourceRoot:l});c.eachMapping(function(r){var k={generated:{line:r.generatedLine,column:r.generatedColumn}};null!=r.source&&(k.source=r.source,null!=l&&(k.source=t.relative(l,k.source)),k.original={line:r.originalLine,
|
||||
column:r.originalColumn},null!=r.name&&(k.name=r.name));q.addMapping(k)});c.sources.forEach(function(r){var k=r;null!==l&&(k=t.relative(l,r));q._sources.has(k)||q._sources.add(k);k=c.sourceContentFor(r);null!=k&&q.setSourceContent(r,k)});return q};e.prototype.addMapping=function(c){var l=t.getArg(c,"generated"),q=t.getArg(c,"original",null),r=t.getArg(c,"source",null);c=t.getArg(c,"name",null);this._skipValidation||this._validateMapping(l,q,r,c);null!=r&&(r=String(r),this._sources.has(r)||this._sources.add(r));
|
||||
null!=c&&(c=String(c),this._names.has(c)||this._names.add(c));this._mappings.add({generatedLine:l.line,generatedColumn:l.column,originalLine:null!=q&&q.line,originalColumn:null!=q&&q.column,source:r,name:c})};e.prototype.setSourceContent=function(c,l){var q=c;null!=this._sourceRoot&&(q=t.relative(this._sourceRoot,q));null!=l?(this._sourcesContents||(this._sourcesContents=Object.create(null)),this._sourcesContents[t.toSetString(q)]=l):this._sourcesContents&&(delete this._sourcesContents[t.toSetString(q)],
|
||||
0===Object.keys(this._sourcesContents).length&&(this._sourcesContents=null))};e.prototype.applySourceMap=function(c,l,q){var r=l;if(null==l){if(null==c.file)throw Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');r=c.file}var k=this._sourceRoot;null!=k&&(r=t.relative(k,r));var u=new m,d=new m;this._mappings.unsortedForEach(function(g){if(g.source===r&&null!=g.originalLine){var n=c.originalPositionFor({line:g.originalLine,
|
||||
column:g.originalColumn});null!=n.source&&(g.source=n.source,null!=q&&(g.source=t.join(q,g.source)),null!=k&&(g.source=t.relative(k,g.source)),g.originalLine=n.line,g.originalColumn=n.column,null!=n.name&&(g.name=n.name))}n=g.source;null==n||u.has(n)||u.add(n);g=g.name;null==g||d.has(g)||d.add(g)},this);this._sources=u;this._names=d;c.sources.forEach(function(g){var n=c.sourceContentFor(g);null!=n&&(null!=q&&(g=t.join(q,g)),null!=k&&(g=t.relative(k,g)),this.setSourceContent(g,n))},this)};e.prototype._validateMapping=
|
||||
function(c,l,q,r){if(l&&"number"!==typeof l.line&&"number"!==typeof l.column)throw Error("original.line and original.column are not numbers -- you probably meant to omit the original mapping entirely and only map the generated position. If so, pass null for the original mapping instead of an object with empty or null values.");if(!(c&&"line"in c&&"column"in c&&0<c.line&&0<=c.column&&!l&&!q&&!r||c&&"line"in c&&"column"in c&&l&&"line"in l&&"column"in l&&0<c.line&&0<=c.column&&0<l.line&&0<=l.column&&
|
||||
q))throw Error("Invalid mapping: "+JSON.stringify({generated:c,source:q,original:l,name:r}));};e.prototype._serializeMappings=function(){for(var c=0,l=1,q=0,r=0,k=0,u=0,d="",g,n,v,z=this._mappings.toArray(),G=0,D=z.length;G<D;G++){n=z[G];g="";if(n.generatedLine!==l)for(c=0;n.generatedLine!==l;)g+=";",l++;else if(0<G){if(!t.compareByGeneratedPositionsInflated(n,z[G-1]))continue;g+=","}g+=p.encode(n.generatedColumn-c);c=n.generatedColumn;null!=n.source&&(v=this._sources.indexOf(n.source),g+=p.encode(v-
|
||||
u),u=v,g+=p.encode(n.originalLine-1-r),r=n.originalLine-1,g+=p.encode(n.originalColumn-q),q=n.originalColumn,null!=n.name&&(n=this._names.indexOf(n.name),g+=p.encode(n-k),k=n));d+=g}return d};e.prototype._generateSourcesContent=function(c,l){return c.map(function(q){if(!this._sourcesContents)return null;null!=l&&(q=t.relative(l,q));q=t.toSetString(q);return Object.prototype.hasOwnProperty.call(this._sourcesContents,q)?this._sourcesContents[q]:null},this)};e.prototype.toJSON=function(){var c={version:this._version,
|
||||
sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};null!=this._file&&(c.file=this._file);null!=this._sourceRoot&&(c.sourceRoot=this._sourceRoot);this._sourcesContents&&(c.sourcesContent=this._generateSourcesContent(c.sources,c.sourceRoot));return c};e.prototype.toString=function(){return JSON.stringify(this.toJSON())};A.SourceMapGenerator=e},{"./array-set":10,"./base64-vlq":11,"./mapping-list":14,"./util":19}],18:[function(C,J,A){function e(f,c,l,q,r){this.children=
|
||||
[];this.sourceContents={};this.line=null==f?null:f;this.column=null==c?null:c;this.source=null==l?null:l;this.name=null==r?null:r;this.$$$isSourceNode$$$=!0;null!=q&&this.add(q)}var p=C("./source-map-generator").SourceMapGenerator,t=C("./util"),m=/(\r?\n)/;e.fromStringWithSourceMap=function(f,c,l){function q(z,G){if(null===z||void 0===z.source)r.add(G);else{var D=l?t.join(l,z.source):z.source;r.add(new e(z.originalLine,z.originalColumn,D,G,z.name))}}var r=new e,k=f.split(m),u=0,d=function(){var z=
|
||||
u<k.length?k[u++]:void 0,G=(u<k.length?k[u++]:void 0)||"";return z+G},g=1,n=0,v=null;c.eachMapping(function(z){if(null!==v)if(g<z.generatedLine)q(v,d()),g++,n=0;else{var G=k[u]||"",D=G.substr(0,z.generatedColumn-n);k[u]=G.substr(z.generatedColumn-n);n=z.generatedColumn;q(v,D);v=z;return}for(;g<z.generatedLine;)r.add(d()),g++;n<z.generatedColumn&&(G=k[u]||"",r.add(G.substr(0,z.generatedColumn)),k[u]=G.substr(z.generatedColumn),n=z.generatedColumn);v=z},this);u<k.length&&(v&&q(v,d()),r.add(k.splice(u).join("")));
|
||||
c.sources.forEach(function(z){var G=c.sourceContentFor(z);null!=G&&(null!=l&&(z=t.join(l,z)),r.setSourceContent(z,G))});return r};e.prototype.add=function(f){if(Array.isArray(f))f.forEach(function(c){this.add(c)},this);else if(f.$$$isSourceNode$$$||"string"===typeof f)f&&this.children.push(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.prepend=function(f){if(Array.isArray(f))for(var c=f.length-1;0<=c;c--)this.prepend(f[c]);
|
||||
else if(f.$$$isSourceNode$$$||"string"===typeof f)this.children.unshift(f);else throw new TypeError("Expected a SourceNode, string, or an array of SourceNodes and strings. Got "+f);return this};e.prototype.walk=function(f){for(var c,l=0,q=this.children.length;l<q;l++)c=this.children[l],c.$$$isSourceNode$$$?c.walk(f):""!==c&&f(c,{source:this.source,line:this.line,column:this.column,name:this.name})};e.prototype.join=function(f){var c,l=this.children.length;if(0<l){var q=[];for(c=0;c<l-1;c++)q.push(this.children[c]),
|
||||
q.push(f);q.push(this.children[c]);this.children=q}return this};e.prototype.replaceRight=function(f,c){var l=this.children[this.children.length-1];l.$$$isSourceNode$$$?l.replaceRight(f,c):"string"===typeof l?this.children[this.children.length-1]=l.replace(f,c):this.children.push("".replace(f,c));return this};e.prototype.setSourceContent=function(f,c){this.sourceContents[t.toSetString(f)]=c};e.prototype.walkSourceContents=function(f){for(var c=0,l=this.children.length;c<l;c++)this.children[c].$$$isSourceNode$$$&&
|
||||
this.children[c].walkSourceContents(f);var q=Object.keys(this.sourceContents);c=0;for(l=q.length;c<l;c++)f(t.fromSetString(q[c]),this.sourceContents[q[c]])};e.prototype.toString=function(){var f="";this.walk(function(c){f+=c});return f};e.prototype.toStringWithSourceMap=function(f){var c="",l=1,q=0,r=new p(f),k=!1,u=null,d=null,g=null,n=null;this.walk(function(v,z){c+=v;null!==z.source&&null!==z.line&&null!==z.column?(u===z.source&&d===z.line&&g===z.column&&n===z.name||r.addMapping({source:z.source,
|
||||
original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name}),u=z.source,d=z.line,g=z.column,n=z.name,k=!0):k&&(r.addMapping({generated:{line:l,column:q}}),u=null,k=!1);for(var G=0,D=v.length;G<D;G++)10===v.charCodeAt(G)?(l++,q=0,G+1===D?(u=null,k=!1):k&&r.addMapping({source:z.source,original:{line:z.line,column:z.column},generated:{line:l,column:q},name:z.name})):q++});this.walkSourceContents(function(v,z){r.setSourceContent(v,z)});return{code:c,map:r}};A.SourceNode=e},{"./source-map-generator":17,
|
||||
"./util":19}],19:[function(C,J,A){function e(d){return(d=d.match(k))?{scheme:d[1],auth:d[2],host:d[3],port:d[4],path:d[5]}:null}function p(d){var g="";d.scheme&&(g+=d.scheme+":");g+="//";d.auth&&(g+=d.auth+"@");d.host&&(g+=d.host);d.port&&(g+=":"+d.port);d.path&&(g+=d.path);return g}function t(d){var g=d,n=e(d);if(n){if(!n.path)return d;g=n.path}d=A.isAbsolute(g);g=g.split(/\/+/);for(var v,z=0,G=g.length-1;0<=G;G--)v=g[G],"."===v?g.splice(G,1):".."===v?z++:0<z&&(""===v?(g.splice(G+1,z),z=0):(g.splice(G,
|
||||
2),z--));g=g.join("/");""===g&&(g=d?"/":".");return n?(n.path=g,p(n)):g}function m(d,g){""===d&&(d=".");""===g&&(g=".");var n=e(g),v=e(d);v&&(d=v.path||"/");if(n&&!n.scheme)return v&&(n.scheme=v.scheme),p(n);if(n||g.match(u))return g;if(v&&!v.host&&!v.path)return v.host=g,p(v);n="/"===g.charAt(0)?g:t(d.replace(/\/+$/,"")+"/"+g);return v?(v.path=n,p(v)):n}function f(d){return d}function c(d){return q(d)?"$"+d:d}function l(d){return q(d)?d.slice(1):d}function q(d){if(!d)return!1;var g=d.length;if(9>
|
||||
g||95!==d.charCodeAt(g-1)||95!==d.charCodeAt(g-2)||111!==d.charCodeAt(g-3)||116!==d.charCodeAt(g-4)||111!==d.charCodeAt(g-5)||114!==d.charCodeAt(g-6)||112!==d.charCodeAt(g-7)||95!==d.charCodeAt(g-8)||95!==d.charCodeAt(g-9))return!1;for(g-=10;0<=g;g--)if(36!==d.charCodeAt(g))return!1;return!0}function r(d,g){return d===g?0:null===d?1:null===g?-1:d>g?1:-1}A.getArg=function(d,g,n){if(g in d)return d[g];if(3===arguments.length)return n;throw Error('"'+g+'" is a required argument.');};var k=/^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/,
|
||||
u=/^data:.+,.+$/;A.urlParse=e;A.urlGenerate=p;A.normalize=t;A.join=m;A.isAbsolute=function(d){return"/"===d.charAt(0)||k.test(d)};A.relative=function(d,g){""===d&&(d=".");d=d.replace(/\/$/,"");for(var n=0;0!==g.indexOf(d+"/");){var v=d.lastIndexOf("/");if(0>v)return g;d=d.slice(0,v);if(d.match(/^([^\/]+:\/)?\/*$/))return g;++n}return Array(n+1).join("../")+g.substr(d.length+1)};C=!("__proto__"in Object.create(null));A.toSetString=C?f:c;A.fromSetString=C?f:l;A.compareByOriginalPositions=function(d,
|
||||
g,n){var v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;if(0!==v||n)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v)return v;v=d.generatedLine-g.generatedLine;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsDeflated=function(d,g,n){var v=d.generatedLine-g.generatedLine;if(0!==v)return v;v=d.generatedColumn-g.generatedColumn;if(0!==v||n)return v;v=r(d.source,g.source);if(0!==v)return v;v=d.originalLine-
|
||||
g.originalLine;if(0!==v)return v;v=d.originalColumn-g.originalColumn;return 0!==v?v:r(d.name,g.name)};A.compareByGeneratedPositionsInflated=function(d,g){var n=d.generatedLine-g.generatedLine;if(0!==n)return n;n=d.generatedColumn-g.generatedColumn;if(0!==n)return n;n=r(d.source,g.source);if(0!==n)return n;n=d.originalLine-g.originalLine;if(0!==n)return n;n=d.originalColumn-g.originalColumn;return 0!==n?n:r(d.name,g.name)};A.parseSourceMapInput=function(d){return JSON.parse(d.replace(/^\)]}'[^\n]*\n/,
|
||||
""))};A.computeSourceURL=function(d,g,n){g=g||"";d&&("/"!==d[d.length-1]&&"/"!==g[0]&&(d+="/"),g=d+g);if(n){d=e(n);if(!d)throw Error("sourceMapURL could not be parsed");d.path&&(n=d.path.lastIndexOf("/"),0<=n&&(d.path=d.path.substring(0,n+1)));g=m(p(d),g)}return t(g)}},{}],20:[function(C,J,A){A.SourceMapGenerator=C("./lib/source-map-generator").SourceMapGenerator;A.SourceMapConsumer=C("./lib/source-map-consumer").SourceMapConsumer;A.SourceNode=C("./lib/source-node").SourceNode},{"./lib/source-map-consumer":16,
|
||||
"./lib/source-map-generator":17,"./lib/source-node":18}],21:[function(C,J,A){(function(e){function p(){return"browser"===a?!0:"node"===a?!1:"undefined"!==typeof window&&"function"===typeof XMLHttpRequest&&!(window.require&&window.module&&window.process&&"renderer"===window.process.type)}function t(x){return function(B){for(var F=0;F<x.length;F++){var E=x[F](B);if(E)return E}return null}}function m(x,B){if(!x)return B;var F=n.dirname(x),E=/^\w+:\/\/[^\/]*/.exec(F);E=E?E[0]:"";var H=F.slice(E.length);
|
||||
return E&&/^\/\w:/.test(H)?(E+="/",E+n.resolve(F.slice(E.length),B).replace(/\\/g,"/")):E+n.resolve(F.slice(E.length),B)}function f(x){var B=h[x.source];if(!B){var F=N(x.source);F?(B=h[x.source]={url:F.url,map:new g(F.map)},B.map.sourcesContent&&B.map.sources.forEach(function(E,H){var M=B.map.sourcesContent[H];if(M){var S=m(B.url,E);b[S]=M}})):B=h[x.source]={url:null,map:null}}return B&&B.map&&"function"===typeof B.map.originalPositionFor&&(F=B.map.originalPositionFor(x),null!==F.source)?(F.source=
|
||||
m(B.url,F.source),F):x}function c(x){var B=/^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(x);return B?(x=f({source:B[2],line:+B[3],column:B[4]-1}),"eval at "+B[1]+" ("+x.source+":"+x.line+":"+(x.column+1)+")"):(B=/^eval at ([^(]+) \((.+)\)$/.exec(x))?"eval at "+B[1]+" ("+c(B[2])+")":x}function l(){var x="";if(this.isNative())x="native";else{var B=this.getScriptNameOrSourceURL();!B&&this.isEval()&&(x=this.getEvalOrigin(),x+=", ");x=B?x+B:x+"<anonymous>";B=this.getLineNumber();null!=B&&(x+=":"+B,(B=
|
||||
this.getColumnNumber())&&(x+=":"+B))}B="";var F=this.getFunctionName(),E=!0,H=this.isConstructor();if(this.isToplevel()||H)H?B+="new "+(F||"<anonymous>"):F?B+=F:(B+=x,E=!1);else{H=this.getTypeName();"[object Object]"===H&&(H="null");var M=this.getMethodName();F?(H&&0!=F.indexOf(H)&&(B+=H+"."),B+=F,M&&F.indexOf("."+M)!=F.length-M.length-1&&(B+=" [as "+M+"]")):B+=H+"."+(M||"<anonymous>")}E&&(B+=" ("+x+")");return B}function q(x){var B={};Object.getOwnPropertyNames(Object.getPrototypeOf(x)).forEach(function(F){B[F]=
|
||||
/^(?:is|get)/.test(F)?function(){return x[F].call(x)}:x[F]});B.toString=l;return B}function r(x,B){void 0===B&&(B={nextPosition:null,curPosition:null});if(x.isNative())return B.curPosition=null,x;var F=x.getFileName()||x.getScriptNameOrSourceURL();if(F){var E=x.getLineNumber(),H=x.getColumnNumber()-1,M=/^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/,S=M.test;var V="object"===typeof e&&null!==e?e.version:"";M=S.call(M,V)?0:62;1===E&&H>M&&!p()&&!x.isEval()&&(H-=M);var O=
|
||||
f({source:F,line:E,column:H});B.curPosition=O;x=q(x);var T=x.getFunctionName;x.getFunctionName=function(){return null==B.nextPosition?T():B.nextPosition.name||T()};x.getFileName=function(){return O.source};x.getLineNumber=function(){return O.line};x.getColumnNumber=function(){return O.column+1};x.getScriptNameOrSourceURL=function(){return O.source};return x}var Q=x.isEval()&&x.getEvalOrigin();Q&&(Q=c(Q),x=q(x),x.getEvalOrigin=function(){return Q});return x}function k(x,B){L&&(b={},h={});for(var F=
|
||||
(x.name||"Error")+": "+(x.message||""),E={nextPosition:null,curPosition:null},H=[],M=B.length-1;0<=M;M--)H.push("\n at "+r(B[M],E)),E.nextPosition=E.curPosition;E.curPosition=E.nextPosition=null;return F+H.reverse().join("")}function u(x){var B=/\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(x.stack);if(B){x=B[1];var F=+B[2];B=+B[3];var E=b[x];if(!E&&v&&v.existsSync(x))try{E=v.readFileSync(x,"utf8")}catch(H){E=""}if(E&&(E=E.split(/(?:\r\n|\r|\n)/)[F-1]))return x+":"+F+"\n"+E+"\n"+Array(B).join(" ")+
|
||||
"^"}return null}function d(){var x=e.emit;e.emit=function(B){if("uncaughtException"===B){var F=arguments[1]&&arguments[1].stack,E=0<this.listeners(B).length;if(F&&!E){F=arguments[1];E=u(F);var H="object"===typeof e&&null!==e?e.stderr:void 0;H&&H._handle&&H._handle.setBlocking&&H._handle.setBlocking(!0);E&&(console.error(),console.error(E));console.error(F.stack);"object"===typeof e&&null!==e&&"function"===typeof e.exit&&e.exit(1);return}}return x.apply(this,arguments)}}var g=C("source-map").SourceMapConsumer,
|
||||
n=C("path");try{var v=C("fs");v.existsSync&&v.readFileSync||(v=null)}catch(x){}var z=C("buffer-from"),G=!1,D=!1,L=!1,a="auto",b={},h={},w=/^data:application\/json[^,]+base64,/,y=[],I=[],K=t(y);y.push(function(x){x=x.trim();/^file:/.test(x)&&(x=x.replace(/file:\/\/\/(\w:)?/,function(E,H){return H?"":"/"}));if(x in b)return b[x];var B="";try{if(v)v.existsSync(x)&&(B=v.readFileSync(x,"utf8"));else{var F=new XMLHttpRequest;F.open("GET",x,!1);F.send(null);4===F.readyState&&200===F.status&&(B=F.responseText)}}catch(E){}return b[x]=
|
||||
B});var N=t(I);I.push(function(x){a:{if(p())try{var B=new XMLHttpRequest;B.open("GET",x,!1);B.send(null);var F=B.getResponseHeader("SourceMap")||B.getResponseHeader("X-SourceMap");if(F){var E=F;break a}}catch(M){}E=K(x);B=/(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;for(var H;F=B.exec(E);)H=F;E=H?H[1]:null}if(!E)return null;w.test(E)?(H=E.slice(E.indexOf(",")+1),H=z(H,"base64").toString(),E=x):(E=m(x,E),H=K(E));return H?{url:E,
|
||||
map:H}:null});var P=y.slice(0),W=I.slice(0);A.wrapCallSite=r;A.getErrorSource=u;A.mapSourcePosition=f;A.retrieveSourceMap=N;A.install=function(x){x=x||{};if(x.environment&&(a=x.environment,-1===["node","browser","auto"].indexOf(a)))throw Error("environment "+a+" was unknown. Available options are {auto, browser, node}");x.retrieveFile&&(x.overrideRetrieveFile&&(y.length=0),y.unshift(x.retrieveFile));x.retrieveSourceMap&&(x.overrideRetrieveSourceMap&&(I.length=0),I.unshift(x.retrieveSourceMap));if(x.hookRequire&&
|
||||
!p()){var B=J.require("module"),F=B.prototype._compile;F.__sourceMapSupport||(B.prototype._compile=function(E,H){b[H]=E;h[H]=void 0;return F.call(this,E,H)},B.prototype._compile.__sourceMapSupport=!0)}L||(L="emptyCacheBetweenOperations"in x?x.emptyCacheBetweenOperations:!1);G||(G=!0,Error.prepareStackTrace=k);if(!D){x="handleUncaughtExceptions"in x?x.handleUncaughtExceptions:!0;try{!1===J.require("worker_threads").isMainThread&&(x=!1)}catch(E){}x&&"object"===typeof e&&null!==e&&"function"===typeof e.on&&
|
||||
(D=!0,d())}};A.resetRetrieveHandlers=function(){y.length=0;I.length=0;y=P.slice(0);I=W.slice(0);N=t(I);K=t(y)}}).call(this,C("g5I+bs"))},{"buffer-from":4,fs:3,"g5I+bs":9,path:8,"source-map":20}]},{},[1]);return R});
|
||||
50
backend/node_modules/@cspotcode/source-map-support/package.json
generated
vendored
Normal file
50
backend/node_modules/@cspotcode/source-map-support/package.json
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "@cspotcode/source-map-support",
|
||||
"description": "Fixes stack traces for files with source maps",
|
||||
"version": "0.8.1",
|
||||
"main": "./source-map-support.js",
|
||||
"types": "./source-map-support.d.ts",
|
||||
"scripts": {
|
||||
"build": "node build.js",
|
||||
"serve-tests": "http-server -p 1336",
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"/register.d.ts",
|
||||
"/register.js",
|
||||
"/register-hook-require.d.ts",
|
||||
"/register-hook-require.js",
|
||||
"/source-map-support.d.ts",
|
||||
"/source-map-support.js",
|
||||
"/browser-source-map-support.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.182",
|
||||
"browserify": "^4.2.3",
|
||||
"coffeescript": "^1.12.7",
|
||||
"http-server": "^0.11.1",
|
||||
"lodash": "^4.17.21",
|
||||
"mocha": "^3.5.3",
|
||||
"semver": "^7.3.7",
|
||||
"source-map": "0.6.1",
|
||||
"webpack": "^1.15.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cspotcode/node-source-map-support"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/cspotcode/node-source-map-support/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"volta": {
|
||||
"node": "16.11.0",
|
||||
"npm": "7.24.2"
|
||||
}
|
||||
}
|
||||
7
backend/node_modules/@cspotcode/source-map-support/register-hook-require.d.ts
generated
vendored
Executable file
7
backend/node_modules/@cspotcode/source-map-support/register-hook-require.d.ts
generated
vendored
Executable file
@@ -0,0 +1,7 @@
|
||||
// tslint:disable:no-useless-files
|
||||
|
||||
// For following usage:
|
||||
// import '@cspotcode/source-map-support/register-hook-require'
|
||||
// Instead of:
|
||||
// import sourceMapSupport from '@cspotcode/source-map-support'
|
||||
// sourceMapSupport.install({hookRequire: true})
|
||||
3
backend/node_modules/@cspotcode/source-map-support/register-hook-require.js
generated
vendored
Normal file
3
backend/node_modules/@cspotcode/source-map-support/register-hook-require.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
require('./').install({
|
||||
hookRequire: true
|
||||
});
|
||||
7
backend/node_modules/@cspotcode/source-map-support/register.d.ts
generated
vendored
Executable file
7
backend/node_modules/@cspotcode/source-map-support/register.d.ts
generated
vendored
Executable file
@@ -0,0 +1,7 @@
|
||||
// tslint:disable:no-useless-files
|
||||
|
||||
// For following usage:
|
||||
// import '@cspotcode/source-map-support/register'
|
||||
// Instead of:
|
||||
// import sourceMapSupport from '@cspotcode/source-map-support'
|
||||
// sourceMapSupport.install()
|
||||
1
backend/node_modules/@cspotcode/source-map-support/register.js
generated
vendored
Normal file
1
backend/node_modules/@cspotcode/source-map-support/register.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
require('./').install();
|
||||
76
backend/node_modules/@cspotcode/source-map-support/source-map-support.d.ts
generated
vendored
Executable file
76
backend/node_modules/@cspotcode/source-map-support/source-map-support.d.ts
generated
vendored
Executable file
@@ -0,0 +1,76 @@
|
||||
// Type definitions for source-map-support 0.5
|
||||
// Project: https://github.com/evanw/node-source-map-support
|
||||
// Definitions by: Bart van der Schoor <https://github.com/Bartvds>
|
||||
// Jason Cheatham <https://github.com/jason0x43>
|
||||
// Alcedo Nathaniel De Guzman Jr <https://github.com/natealcedo>
|
||||
// Griffin Yourick <https://github.com/tough-griff>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
export interface RawSourceMap {
|
||||
version: 3;
|
||||
sources: string[];
|
||||
names: string[];
|
||||
sourceRoot?: string;
|
||||
sourcesContent?: string[];
|
||||
mappings: string;
|
||||
file: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output of retrieveSourceMap().
|
||||
* From source-map-support:
|
||||
* The map field may be either a string or the parsed JSON object (i.e.,
|
||||
* it must be a valid argument to the SourceMapConsumer constructor).
|
||||
*/
|
||||
export interface UrlAndMap {
|
||||
url: string;
|
||||
map: string | RawSourceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to install().
|
||||
*/
|
||||
export interface Options {
|
||||
handleUncaughtExceptions?: boolean | undefined;
|
||||
hookRequire?: boolean | undefined;
|
||||
emptyCacheBetweenOperations?: boolean | undefined;
|
||||
environment?: 'auto' | 'browser' | 'node' | undefined;
|
||||
overrideRetrieveFile?: boolean | undefined;
|
||||
overrideRetrieveSourceMap?: boolean | undefined;
|
||||
retrieveFile?(path: string): string;
|
||||
retrieveSourceMap?(source: string): UrlAndMap | null;
|
||||
/**
|
||||
* Set false to disable redirection of require / import `source-map-support` to `@cspotcode/source-map-support`
|
||||
*/
|
||||
redirectConflictingLibrary?: boolean;
|
||||
/**
|
||||
* Callback will be called every time we redirect due to `redirectConflictingLibrary`
|
||||
* This allows consumers to log helpful warnings if they choose.
|
||||
* @param parent NodeJS.Module which made the require() or require.resolve() call
|
||||
* @param options options object internally passed to node's `_resolveFilename` hook
|
||||
*/
|
||||
onConflictingLibraryRedirect?: (request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void;
|
||||
}
|
||||
|
||||
export interface Position {
|
||||
source: string;
|
||||
line: number;
|
||||
column: number;
|
||||
}
|
||||
|
||||
export function wrapCallSite(frame: any /* StackFrame */): any /* StackFrame */;
|
||||
export function getErrorSource(error: Error): string | null;
|
||||
export function mapSourcePosition(position: Position): Position;
|
||||
export function retrieveSourceMap(source: string): UrlAndMap | null;
|
||||
export function resetRetrieveHandlers(): void;
|
||||
|
||||
/**
|
||||
* Install SourceMap support.
|
||||
* @param options Can be used to e.g. disable uncaughtException handler.
|
||||
*/
|
||||
export function install(options?: Options): void;
|
||||
|
||||
/**
|
||||
* Uninstall SourceMap support.
|
||||
*/
|
||||
export function uninstall(): void;
|
||||
938
backend/node_modules/@cspotcode/source-map-support/source-map-support.js
generated
vendored
Normal file
938
backend/node_modules/@cspotcode/source-map-support/source-map-support.js
generated
vendored
Normal file
@@ -0,0 +1,938 @@
|
||||
const { TraceMap, originalPositionFor, AnyMap } = require('@jridgewell/trace-mapping');
|
||||
var path = require('path');
|
||||
const { fileURLToPath, pathToFileURL } = require('url');
|
||||
var util = require('util');
|
||||
|
||||
var fs;
|
||||
try {
|
||||
fs = require('fs');
|
||||
if (!fs.existsSync || !fs.readFileSync) {
|
||||
// fs doesn't have all methods we need
|
||||
fs = null;
|
||||
}
|
||||
} catch (err) {
|
||||
/* nop */
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires a module which is protected against bundler minification.
|
||||
*
|
||||
* @param {NodeModule} mod
|
||||
* @param {string} request
|
||||
*/
|
||||
function dynamicRequire(mod, request) {
|
||||
return mod.require(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* enabled: boolean;
|
||||
* originalValue: any;
|
||||
* installedValue: any;
|
||||
* }} HookState
|
||||
* Used for installing and uninstalling hooks
|
||||
*/
|
||||
|
||||
// Increment this if the format of sharedData changes in a breaking way.
|
||||
var sharedDataVersion = 1;
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {T} defaults
|
||||
* @returns {T}
|
||||
*/
|
||||
function initializeSharedData(defaults) {
|
||||
var sharedDataKey = 'source-map-support/sharedData';
|
||||
if (typeof Symbol !== 'undefined') {
|
||||
sharedDataKey = Symbol.for(sharedDataKey);
|
||||
}
|
||||
var sharedData = this[sharedDataKey];
|
||||
if (!sharedData) {
|
||||
sharedData = { version: sharedDataVersion };
|
||||
if (Object.defineProperty) {
|
||||
Object.defineProperty(this, sharedDataKey, { value: sharedData });
|
||||
} else {
|
||||
this[sharedDataKey] = sharedData;
|
||||
}
|
||||
}
|
||||
if (sharedDataVersion !== sharedData.version) {
|
||||
throw new Error("Multiple incompatible instances of source-map-support were loaded");
|
||||
}
|
||||
for (var key in defaults) {
|
||||
if (!(key in sharedData)) {
|
||||
sharedData[key] = defaults[key];
|
||||
}
|
||||
}
|
||||
return sharedData;
|
||||
}
|
||||
|
||||
// If multiple instances of source-map-support are loaded into the same
|
||||
// context, they shouldn't overwrite each other. By storing handlers, caches,
|
||||
// and other state on a shared object, different instances of
|
||||
// source-map-support can work together in a limited way. This does require
|
||||
// that future versions of source-map-support continue to support the fields on
|
||||
// this object. If this internal contract ever needs to be broken, increment
|
||||
// sharedDataVersion. (This version number is not the same as any of the
|
||||
// package's version numbers, which should reflect the *external* API of
|
||||
// source-map-support.)
|
||||
var sharedData = initializeSharedData({
|
||||
|
||||
// Only install once if called multiple times
|
||||
// Remember how the environment looked before installation so we can restore if able
|
||||
/** @type {HookState} */
|
||||
errorPrepareStackTraceHook: undefined,
|
||||
/** @type {HookState} */
|
||||
processEmitHook: undefined,
|
||||
/** @type {HookState} */
|
||||
moduleResolveFilenameHook: undefined,
|
||||
|
||||
/** @type {Array<(request: string, parent: any, isMain: boolean, options: any, redirectedRequest: string) => void>} */
|
||||
onConflictingLibraryRedirectArr: [],
|
||||
|
||||
// If true, the caches are reset before a stack trace formatting operation
|
||||
emptyCacheBetweenOperations: false,
|
||||
|
||||
// Maps a file path to a string containing the file contents
|
||||
fileContentsCache: Object.create(null),
|
||||
|
||||
// Maps a file path to a source map for that file
|
||||
/** @type {Record<string, {url: string, map: TraceMap}} */
|
||||
sourceMapCache: Object.create(null),
|
||||
|
||||
// Priority list of retrieve handlers
|
||||
retrieveFileHandlers: [],
|
||||
retrieveMapHandlers: [],
|
||||
|
||||
// Priority list of internally-implemented handlers.
|
||||
// When resetting state, we must keep these.
|
||||
internalRetrieveFileHandlers: [],
|
||||
internalRetrieveMapHandlers: [],
|
||||
|
||||
});
|
||||
|
||||
// Supports {browser, node, auto}
|
||||
var environment = "auto";
|
||||
|
||||
// Regex for detecting source maps
|
||||
var reSourceMap = /^data:application\/json[^,]+base64,/;
|
||||
|
||||
function isInBrowser() {
|
||||
if (environment === "browser")
|
||||
return true;
|
||||
if (environment === "node")
|
||||
return false;
|
||||
return ((typeof window !== 'undefined') && (typeof XMLHttpRequest === 'function') && !(window.require && window.module && window.process && window.process.type === "renderer"));
|
||||
}
|
||||
|
||||
function hasGlobalProcessEventEmitter() {
|
||||
return ((typeof process === 'object') && (process !== null) && (typeof process.on === 'function'));
|
||||
}
|
||||
|
||||
function tryFileURLToPath(v) {
|
||||
if(isFileUrl(v)) {
|
||||
return fileURLToPath(v);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
// TODO un-copy these from resolve-uri; see if they can be exported from that lib
|
||||
function isFileUrl(input) {
|
||||
return input.startsWith('file:');
|
||||
}
|
||||
function isAbsoluteUrl(input) {
|
||||
return schemeRegex.test(input);
|
||||
}
|
||||
// Matches the scheme of a URL, eg "http://"
|
||||
const schemeRegex = /^[\w+.-]+:\/\//;
|
||||
function isSchemeRelativeUrl(input) {
|
||||
return input.startsWith('//');
|
||||
}
|
||||
|
||||
// #region Caches
|
||||
/** @param {string} pathOrFileUrl */
|
||||
function getCacheKey(pathOrFileUrl) {
|
||||
if(pathOrFileUrl.startsWith('node:')) return pathOrFileUrl;
|
||||
if(isFileUrl(pathOrFileUrl)) {
|
||||
// Must normalize spaces to %20, stuff like that
|
||||
return new URL(pathOrFileUrl).toString();
|
||||
} else {
|
||||
try {
|
||||
return pathToFileURL(pathOrFileUrl).toString();
|
||||
} catch {
|
||||
return pathOrFileUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getFileContentsCache(key) {
|
||||
return sharedData.fileContentsCache[getCacheKey(key)];
|
||||
}
|
||||
function hasFileContentsCacheFromKey(key) {
|
||||
return Object.prototype.hasOwnProperty.call(sharedData.fileContentsCache, key);
|
||||
}
|
||||
function getFileContentsCacheFromKey(key) {
|
||||
return sharedData.fileContentsCache[key];
|
||||
}
|
||||
function setFileContentsCache(key, value) {
|
||||
return sharedData.fileContentsCache[getCacheKey(key)] = value;
|
||||
}
|
||||
function getSourceMapCache(key) {
|
||||
return sharedData.sourceMapCache[getCacheKey(key)];
|
||||
}
|
||||
function setSourceMapCache(key, value) {
|
||||
return sharedData.sourceMapCache[getCacheKey(key)] = value;
|
||||
}
|
||||
function clearCaches() {
|
||||
sharedData.fileContentsCache = Object.create(null);
|
||||
sharedData.sourceMapCache = Object.create(null);
|
||||
}
|
||||
// #endregion Caches
|
||||
|
||||
function handlerExec(list, internalList) {
|
||||
return function(arg) {
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var ret = list[i](arg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < internalList.length; i++) {
|
||||
var ret = internalList[i](arg);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
var retrieveFile = handlerExec(sharedData.retrieveFileHandlers, sharedData.internalRetrieveFileHandlers);
|
||||
|
||||
sharedData.internalRetrieveFileHandlers.push(function(path) {
|
||||
// Trim the path to make sure there is no extra whitespace.
|
||||
path = path.trim();
|
||||
if (/^file:/.test(path)) {
|
||||
// existsSync/readFileSync can't handle file protocol, but once stripped, it works
|
||||
path = path.replace(/file:\/\/\/(\w:)?/, function(protocol, drive) {
|
||||
return drive ?
|
||||
'' : // file:///C:/dir/file -> C:/dir/file
|
||||
'/'; // file:///root-dir/file -> /root-dir/file
|
||||
});
|
||||
}
|
||||
const key = getCacheKey(path);
|
||||
if(hasFileContentsCacheFromKey(key)) {
|
||||
return getFileContentsCacheFromKey(key);
|
||||
}
|
||||
|
||||
var contents = '';
|
||||
try {
|
||||
if (!fs) {
|
||||
// Use SJAX if we are in the browser
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', path, /** async */ false);
|
||||
xhr.send(null);
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
contents = xhr.responseText;
|
||||
}
|
||||
} else if (fs.existsSync(path)) {
|
||||
// Otherwise, use the filesystem
|
||||
contents = fs.readFileSync(path, 'utf8');
|
||||
}
|
||||
} catch (er) {
|
||||
/* ignore any errors */
|
||||
}
|
||||
|
||||
return setFileContentsCache(path, contents);
|
||||
});
|
||||
|
||||
// Support URLs relative to a directory, but be careful about a protocol prefix
|
||||
// in case we are in the browser (i.e. directories may start with "http://" or "file:///")
|
||||
function supportRelativeURL(file, url) {
|
||||
if(!file) return url;
|
||||
// given that this happens within error formatting codepath, probably best to
|
||||
// fallback instead of throwing if anything goes wrong
|
||||
try {
|
||||
// if should output a URL
|
||||
if(isAbsoluteUrl(file) || isSchemeRelativeUrl(file)) {
|
||||
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
|
||||
return new URL(url, file).toString();
|
||||
}
|
||||
if(path.isAbsolute(url)) {
|
||||
return new URL(pathToFileURL(url), file).toString();
|
||||
}
|
||||
// url is relative path or URL
|
||||
return new URL(url.replace(/\\/g, '/'), file).toString();
|
||||
}
|
||||
// if should output a path (unless URL is something like https://)
|
||||
if(path.isAbsolute(file)) {
|
||||
if(isFileUrl(url)) {
|
||||
return fileURLToPath(url);
|
||||
}
|
||||
if(isSchemeRelativeUrl(url)) {
|
||||
return fileURLToPath(new URL(url, 'file://'));
|
||||
}
|
||||
if(isAbsoluteUrl(url)) {
|
||||
// url is a non-file URL
|
||||
// Go with the URL
|
||||
return url;
|
||||
}
|
||||
if(path.isAbsolute(url)) {
|
||||
// Normalize at all? decodeURI or normalize slashes?
|
||||
return path.normalize(url);
|
||||
}
|
||||
// url is relative path or URL
|
||||
return path.join(file, '..', decodeURI(url));
|
||||
}
|
||||
// If we get here, file is relative.
|
||||
// Shouldn't happen since node identifies modules with absolute paths or URLs.
|
||||
// But we can take a stab at returning something meaningful anyway.
|
||||
if(isAbsoluteUrl(url) || isSchemeRelativeUrl(url)) {
|
||||
return url;
|
||||
}
|
||||
return path.join(file, '..', url);
|
||||
} catch(e) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
// Return pathOrUrl in the same style as matchStyleOf: either a file URL or a native path
|
||||
function matchStyleOfPathOrUrl(matchStyleOf, pathOrUrl) {
|
||||
try {
|
||||
if(isAbsoluteUrl(matchStyleOf) || isSchemeRelativeUrl(matchStyleOf)) {
|
||||
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) return pathOrUrl;
|
||||
if(path.isAbsolute(pathOrUrl)) return pathToFileURL(pathOrUrl).toString();
|
||||
} else if(path.isAbsolute(matchStyleOf)) {
|
||||
if(isAbsoluteUrl(pathOrUrl) || isSchemeRelativeUrl(pathOrUrl)) {
|
||||
return fileURLToPath(new URL(pathOrUrl, 'file://'));
|
||||
}
|
||||
}
|
||||
return pathOrUrl;
|
||||
} catch(e) {
|
||||
return pathOrUrl;
|
||||
}
|
||||
}
|
||||
|
||||
function retrieveSourceMapURL(source) {
|
||||
var fileData;
|
||||
|
||||
if (isInBrowser()) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', source, false);
|
||||
xhr.send(null);
|
||||
fileData = xhr.readyState === 4 ? xhr.responseText : null;
|
||||
|
||||
// Support providing a sourceMappingURL via the SourceMap header
|
||||
var sourceMapHeader = xhr.getResponseHeader("SourceMap") ||
|
||||
xhr.getResponseHeader("X-SourceMap");
|
||||
if (sourceMapHeader) {
|
||||
return sourceMapHeader;
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Get the URL of the source map
|
||||
fileData = retrieveFile(tryFileURLToPath(source));
|
||||
var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
|
||||
// Keep executing the search to find the *last* sourceMappingURL to avoid
|
||||
// picking up sourceMappingURLs from comments, strings, etc.
|
||||
var lastMatch, match;
|
||||
while (match = re.exec(fileData)) lastMatch = match;
|
||||
if (!lastMatch) return null;
|
||||
return lastMatch[1];
|
||||
};
|
||||
|
||||
// Can be overridden by the retrieveSourceMap option to install. Takes a
|
||||
// generated source filename; returns a {map, optional url} object, or null if
|
||||
// there is no source map. The map field may be either a string or the parsed
|
||||
// JSON object (ie, it must be a valid argument to the SourceMapConsumer
|
||||
// constructor).
|
||||
/** @type {(source: string) => import('./source-map-support').UrlAndMap | null} */
|
||||
var retrieveSourceMap = handlerExec(sharedData.retrieveMapHandlers, sharedData.internalRetrieveMapHandlers);
|
||||
sharedData.internalRetrieveMapHandlers.push(function(source) {
|
||||
var sourceMappingURL = retrieveSourceMapURL(source);
|
||||
if (!sourceMappingURL) return null;
|
||||
|
||||
// Read the contents of the source map
|
||||
var sourceMapData;
|
||||
if (reSourceMap.test(sourceMappingURL)) {
|
||||
// Support source map URL as a data url
|
||||
var rawData = sourceMappingURL.slice(sourceMappingURL.indexOf(',') + 1);
|
||||
sourceMapData = Buffer.from(rawData, "base64").toString();
|
||||
sourceMappingURL = source;
|
||||
} else {
|
||||
// Support source map URLs relative to the source URL
|
||||
sourceMappingURL = supportRelativeURL(source, sourceMappingURL);
|
||||
sourceMapData = retrieveFile(tryFileURLToPath(sourceMappingURL));
|
||||
}
|
||||
|
||||
if (!sourceMapData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
url: sourceMappingURL,
|
||||
map: sourceMapData
|
||||
};
|
||||
});
|
||||
|
||||
function mapSourcePosition(position) {
|
||||
var sourceMap = getSourceMapCache(position.source);
|
||||
if (!sourceMap) {
|
||||
// Call the (overrideable) retrieveSourceMap function to get the source map.
|
||||
var urlAndMap = retrieveSourceMap(position.source);
|
||||
if (urlAndMap) {
|
||||
sourceMap = setSourceMapCache(position.source, {
|
||||
url: urlAndMap.url,
|
||||
map: new AnyMap(urlAndMap.map, urlAndMap.url)
|
||||
});
|
||||
|
||||
// Overwrite trace-mapping's resolutions, because they do not handle
|
||||
// Windows paths the way we want.
|
||||
// TODO Remove now that windows path support was added to resolve-uri and thus trace-mapping?
|
||||
sourceMap.map.resolvedSources = sourceMap.map.sources.map(s => supportRelativeURL(sourceMap.url, s));
|
||||
|
||||
// Load all sources stored inline with the source map into the file cache
|
||||
// to pretend like they are already loaded. They may not exist on disk.
|
||||
if (sourceMap.map.sourcesContent) {
|
||||
sourceMap.map.resolvedSources.forEach(function(resolvedSource, i) {
|
||||
var contents = sourceMap.map.sourcesContent[i];
|
||||
if (contents) {
|
||||
setFileContentsCache(resolvedSource, contents);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
sourceMap = setSourceMapCache(position.source, {
|
||||
url: null,
|
||||
map: null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the source URL relative to the URL of the source map
|
||||
if (sourceMap && sourceMap.map) {
|
||||
var originalPosition = originalPositionFor(sourceMap.map, position);
|
||||
|
||||
// Only return the original position if a matching line was found. If no
|
||||
// matching line is found then we return position instead, which will cause
|
||||
// the stack trace to print the path and line for the compiled file. It is
|
||||
// better to give a precise location in the compiled file than a vague
|
||||
// location in the original file.
|
||||
if (originalPosition.source !== null) {
|
||||
// originalPosition.source has *already* been resolved against sourceMap.url
|
||||
// so is *already* as absolute as possible.
|
||||
// However, we want to ensure we output in same format as input: URL or native path
|
||||
originalPosition.source = matchStyleOfPathOrUrl(
|
||||
position.source, originalPosition.source);
|
||||
return originalPosition;
|
||||
}
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
// Parses code generated by FormatEvalOrigin(), a function inside V8:
|
||||
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
||||
function mapEvalOrigin(origin) {
|
||||
// Most eval() calls are in this format
|
||||
var match = /^eval at ([^(]+) \((.+):(\d+):(\d+)\)$/.exec(origin);
|
||||
if (match) {
|
||||
var position = mapSourcePosition({
|
||||
source: match[2],
|
||||
line: +match[3],
|
||||
column: match[4] - 1
|
||||
});
|
||||
return 'eval at ' + match[1] + ' (' + position.source + ':' +
|
||||
position.line + ':' + (position.column + 1) + ')';
|
||||
}
|
||||
|
||||
// Parse nested eval() calls using recursion
|
||||
match = /^eval at ([^(]+) \((.+)\)$/.exec(origin);
|
||||
if (match) {
|
||||
return 'eval at ' + match[1] + ' (' + mapEvalOrigin(match[2]) + ')';
|
||||
}
|
||||
|
||||
// Make sure we still return useful information if we didn't find anything
|
||||
return origin;
|
||||
}
|
||||
|
||||
// This is copied almost verbatim from the V8 source code at
|
||||
// https://code.google.com/p/v8/source/browse/trunk/src/messages.js
|
||||
// Update 2022-04-29:
|
||||
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/builtins/builtins-callsite.cc#L175-L179
|
||||
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L795-L804
|
||||
// https://github.com/v8/v8/blob/98f6f100c5ab8e390e51422747c4ef644d5ac6f2/src/objects/call-site-info.cc#L717-L750
|
||||
// The implementation of wrapCallSite() used to just forward to the actual source
|
||||
// code of CallSite.prototype.toString but unfortunately a new release of V8
|
||||
// did something to the prototype chain and broke the shim. The only fix I
|
||||
// could find was copy/paste.
|
||||
function CallSiteToString() {
|
||||
var fileName;
|
||||
var fileLocation = "";
|
||||
if (this.isNative()) {
|
||||
fileLocation = "native";
|
||||
} else {
|
||||
fileName = this.getScriptNameOrSourceURL();
|
||||
if (!fileName && this.isEval()) {
|
||||
fileLocation = this.getEvalOrigin();
|
||||
fileLocation += ", "; // Expecting source position to follow.
|
||||
}
|
||||
|
||||
if (fileName) {
|
||||
fileLocation += fileName;
|
||||
} else {
|
||||
// Source code does not originate from a file and is not native, but we
|
||||
// can still get the source position inside the source string, e.g. in
|
||||
// an eval string.
|
||||
fileLocation += "<anonymous>";
|
||||
}
|
||||
var lineNumber = this.getLineNumber();
|
||||
if (lineNumber != null) {
|
||||
fileLocation += ":" + lineNumber;
|
||||
var columnNumber = this.getColumnNumber();
|
||||
if (columnNumber) {
|
||||
fileLocation += ":" + columnNumber;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var line = "";
|
||||
var isAsync = this.isAsync ? this.isAsync() : false;
|
||||
if(isAsync) {
|
||||
line += 'async ';
|
||||
var isPromiseAll = this.isPromiseAll ? this.isPromiseAll() : false;
|
||||
var isPromiseAny = this.isPromiseAny ? this.isPromiseAny() : false;
|
||||
if(isPromiseAny || isPromiseAll) {
|
||||
line += isPromiseAll ? 'Promise.all (index ' : 'Promise.any (index ';
|
||||
var promiseIndex = this.getPromiseIndex();
|
||||
line += promiseIndex + ')';
|
||||
}
|
||||
}
|
||||
var functionName = this.getFunctionName();
|
||||
var addSuffix = true;
|
||||
var isConstructor = this.isConstructor();
|
||||
var isMethodCall = !(this.isToplevel() || isConstructor);
|
||||
if (isMethodCall) {
|
||||
var typeName = this.getTypeName();
|
||||
// Fixes shim to be backward compatable with Node v0 to v4
|
||||
if (typeName === "[object Object]") {
|
||||
typeName = "null";
|
||||
}
|
||||
var methodName = this.getMethodName();
|
||||
if (functionName) {
|
||||
if (typeName && functionName.indexOf(typeName) != 0) {
|
||||
line += typeName + ".";
|
||||
}
|
||||
line += functionName;
|
||||
if (methodName && functionName.indexOf("." + methodName) != functionName.length - methodName.length - 1) {
|
||||
line += " [as " + methodName + "]";
|
||||
}
|
||||
} else {
|
||||
line += typeName + "." + (methodName || "<anonymous>");
|
||||
}
|
||||
} else if (isConstructor) {
|
||||
line += "new " + (functionName || "<anonymous>");
|
||||
} else if (functionName) {
|
||||
line += functionName;
|
||||
} else {
|
||||
line += fileLocation;
|
||||
addSuffix = false;
|
||||
}
|
||||
if (addSuffix) {
|
||||
line += " (" + fileLocation + ")";
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
function cloneCallSite(frame) {
|
||||
var object = {};
|
||||
Object.getOwnPropertyNames(Object.getPrototypeOf(frame)).forEach(function(name) {
|
||||
object[name] = /^(?:is|get)/.test(name) ? function() { return frame[name].call(frame); } : frame[name];
|
||||
});
|
||||
object.toString = CallSiteToString;
|
||||
return object;
|
||||
}
|
||||
|
||||
function wrapCallSite(frame, state) {
|
||||
// provides interface backward compatibility
|
||||
if (state === undefined) {
|
||||
state = { nextPosition: null, curPosition: null }
|
||||
}
|
||||
if(frame.isNative()) {
|
||||
state.curPosition = null;
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Most call sites will return the source file from getFileName(), but code
|
||||
// passed to eval() ending in "//# sourceURL=..." will return the source file
|
||||
// from getScriptNameOrSourceURL() instead
|
||||
var source = frame.getFileName() || frame.getScriptNameOrSourceURL();
|
||||
if (source) {
|
||||
// v8 does not expose its internal isWasm, etc methods, so we do this instead.
|
||||
if(source.startsWith('wasm://')) {
|
||||
state.curPosition = null;
|
||||
return frame;
|
||||
}
|
||||
|
||||
var line = frame.getLineNumber();
|
||||
var column = frame.getColumnNumber() - 1;
|
||||
|
||||
// Fix position in Node where some (internal) code is prepended.
|
||||
// See https://github.com/evanw/node-source-map-support/issues/36
|
||||
// Header removed in node at ^10.16 || >=11.11.0
|
||||
// v11 is not an LTS candidate, we can just test the one version with it.
|
||||
// Test node versions for: 10.16-19, 10.20+, 12-19, 20-99, 100+, or 11.11
|
||||
var noHeader = /^v(10\.1[6-9]|10\.[2-9][0-9]|10\.[0-9]{3,}|1[2-9]\d*|[2-9]\d|\d{3,}|11\.11)/;
|
||||
var headerLength = noHeader.test(process.version) ? 0 : 62;
|
||||
if (line === 1 && column > headerLength && !isInBrowser() && !frame.isEval()) {
|
||||
column -= headerLength;
|
||||
}
|
||||
|
||||
var position = mapSourcePosition({
|
||||
source: source,
|
||||
line: line,
|
||||
column: column
|
||||
});
|
||||
state.curPosition = position;
|
||||
frame = cloneCallSite(frame);
|
||||
var originalFunctionName = frame.getFunctionName;
|
||||
frame.getFunctionName = function() {
|
||||
if (state.nextPosition == null) {
|
||||
return originalFunctionName();
|
||||
}
|
||||
return state.nextPosition.name || originalFunctionName();
|
||||
};
|
||||
frame.getFileName = function() { return position.source; };
|
||||
frame.getLineNumber = function() { return position.line; };
|
||||
frame.getColumnNumber = function() { return position.column + 1; };
|
||||
frame.getScriptNameOrSourceURL = function() { return position.source; };
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Code called using eval() needs special handling
|
||||
var origin = frame.isEval() && frame.getEvalOrigin();
|
||||
if (origin) {
|
||||
origin = mapEvalOrigin(origin);
|
||||
frame = cloneCallSite(frame);
|
||||
frame.getEvalOrigin = function() { return origin; };
|
||||
return frame;
|
||||
}
|
||||
|
||||
// If we get here then we were unable to change the source position
|
||||
return frame;
|
||||
}
|
||||
|
||||
var kIsNodeError = undefined;
|
||||
try {
|
||||
// Get a deliberate ERR_INVALID_ARG_TYPE
|
||||
// TODO is there a better way to reliably get an instance of NodeError?
|
||||
path.resolve(123);
|
||||
} catch(e) {
|
||||
const symbols = Object.getOwnPropertySymbols(e);
|
||||
const symbol = symbols.find(function (s) {return s.toString().indexOf('kIsNodeError') >= 0});
|
||||
if(symbol) kIsNodeError = symbol;
|
||||
}
|
||||
|
||||
const ErrorPrototypeToString = (err) =>Error.prototype.toString.call(err);
|
||||
|
||||
/** @param {HookState} hookState */
|
||||
function createPrepareStackTrace(hookState) {
|
||||
return prepareStackTrace;
|
||||
|
||||
// This function is part of the V8 stack trace API, for more info see:
|
||||
// https://v8.dev/docs/stack-trace-api
|
||||
function prepareStackTrace(error, stack) {
|
||||
if(!hookState.enabled) return hookState.originalValue.apply(this, arguments);
|
||||
|
||||
if (sharedData.emptyCacheBetweenOperations) {
|
||||
clearCaches();
|
||||
}
|
||||
|
||||
// node gives its own errors special treatment. Mimic that behavior
|
||||
// https://github.com/nodejs/node/blob/3cbaabc4622df1b4009b9d026a1a970bdbae6e89/lib/internal/errors.js#L118-L128
|
||||
// https://github.com/nodejs/node/pull/39182
|
||||
var errorString;
|
||||
if (kIsNodeError) {
|
||||
if(kIsNodeError in error) {
|
||||
errorString = `${error.name} [${error.code}]: ${error.message}`;
|
||||
} else {
|
||||
errorString = ErrorPrototypeToString(error);
|
||||
}
|
||||
} else {
|
||||
var name = error.name || 'Error';
|
||||
var message = error.message || '';
|
||||
errorString = message ? name + ": " + message : name;
|
||||
}
|
||||
|
||||
var state = { nextPosition: null, curPosition: null };
|
||||
var processedStack = [];
|
||||
for (var i = stack.length - 1; i >= 0; i--) {
|
||||
processedStack.push('\n at ' + wrapCallSite(stack[i], state));
|
||||
state.nextPosition = state.curPosition;
|
||||
}
|
||||
state.curPosition = state.nextPosition = null;
|
||||
return errorString + processedStack.reverse().join('');
|
||||
}
|
||||
}
|
||||
|
||||
// Generate position and snippet of original source with pointer
|
||||
function getErrorSource(error) {
|
||||
var match = /\n at [^(]+ \((.*):(\d+):(\d+)\)/.exec(error.stack);
|
||||
if (match) {
|
||||
var source = match[1];
|
||||
var line = +match[2];
|
||||
var column = +match[3];
|
||||
|
||||
// Support the inline sourceContents inside the source map
|
||||
var contents = getFileContentsCache(source);
|
||||
|
||||
const sourceAsPath = tryFileURLToPath(source);
|
||||
|
||||
// Support files on disk
|
||||
if (!contents && fs && fs.existsSync(sourceAsPath)) {
|
||||
try {
|
||||
contents = fs.readFileSync(sourceAsPath, 'utf8');
|
||||
} catch (er) {
|
||||
contents = '';
|
||||
}
|
||||
}
|
||||
|
||||
// Format the line from the original source code like node does
|
||||
if (contents) {
|
||||
var code = contents.split(/(?:\r\n|\r|\n)/)[line - 1];
|
||||
if (code) {
|
||||
return source + ':' + line + '\n' + code + '\n' +
|
||||
new Array(column).join(' ') + '^';
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function printFatalErrorUponExit (error) {
|
||||
var source = getErrorSource(error);
|
||||
|
||||
// Ensure error is printed synchronously and not truncated
|
||||
if (process.stderr._handle && process.stderr._handle.setBlocking) {
|
||||
process.stderr._handle.setBlocking(true);
|
||||
}
|
||||
|
||||
if (source) {
|
||||
console.error(source);
|
||||
}
|
||||
|
||||
// Matches node's behavior for colorized output
|
||||
console.error(
|
||||
util.inspect(error, {
|
||||
customInspect: false,
|
||||
colors: process.stderr.isTTY
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function shimEmitUncaughtException () {
|
||||
const originalValue = process.emit;
|
||||
var hook = sharedData.processEmitHook = {
|
||||
enabled: true,
|
||||
originalValue,
|
||||
installedValue: undefined
|
||||
};
|
||||
var isTerminatingDueToFatalException = false;
|
||||
var fatalException;
|
||||
|
||||
process.emit = sharedData.processEmitHook.installedValue = function (type) {
|
||||
const hadListeners = originalValue.apply(this, arguments);
|
||||
if(hook.enabled) {
|
||||
if (type === 'uncaughtException' && !hadListeners) {
|
||||
isTerminatingDueToFatalException = true;
|
||||
fatalException = arguments[1];
|
||||
process.exit(1);
|
||||
}
|
||||
if (type === 'exit' && isTerminatingDueToFatalException) {
|
||||
printFatalErrorUponExit(fatalException);
|
||||
}
|
||||
}
|
||||
return hadListeners;
|
||||
};
|
||||
}
|
||||
|
||||
var originalRetrieveFileHandlers = sharedData.retrieveFileHandlers.slice(0);
|
||||
var originalRetrieveMapHandlers = sharedData.retrieveMapHandlers.slice(0);
|
||||
|
||||
exports.wrapCallSite = wrapCallSite;
|
||||
exports.getErrorSource = getErrorSource;
|
||||
exports.mapSourcePosition = mapSourcePosition;
|
||||
exports.retrieveSourceMap = retrieveSourceMap;
|
||||
|
||||
exports.install = function(options) {
|
||||
options = options || {};
|
||||
|
||||
if (options.environment) {
|
||||
environment = options.environment;
|
||||
if (["node", "browser", "auto"].indexOf(environment) === -1) {
|
||||
throw new Error("environment " + environment + " was unknown. Available options are {auto, browser, node}")
|
||||
}
|
||||
}
|
||||
|
||||
// Use dynamicRequire to avoid including in browser bundles
|
||||
var Module = dynamicRequire(module, 'module');
|
||||
|
||||
// Redirect subsequent imports of "source-map-support"
|
||||
// to this package
|
||||
const {redirectConflictingLibrary = true, onConflictingLibraryRedirect} = options;
|
||||
if(redirectConflictingLibrary) {
|
||||
if (!sharedData.moduleResolveFilenameHook) {
|
||||
const originalValue = Module._resolveFilename;
|
||||
const moduleResolveFilenameHook = sharedData.moduleResolveFilenameHook = {
|
||||
enabled: true,
|
||||
originalValue,
|
||||
installedValue: undefined,
|
||||
}
|
||||
Module._resolveFilename = sharedData.moduleResolveFilenameHook.installedValue = function (request, parent, isMain, options) {
|
||||
if (moduleResolveFilenameHook.enabled) {
|
||||
// Match all source-map-support entrypoints: source-map-support, source-map-support/register
|
||||
let requestRedirect;
|
||||
if (request === 'source-map-support') {
|
||||
requestRedirect = './';
|
||||
} else if (request === 'source-map-support/register') {
|
||||
requestRedirect = './register';
|
||||
}
|
||||
|
||||
if (requestRedirect !== undefined) {
|
||||
const newRequest = require.resolve(requestRedirect);
|
||||
for (const cb of sharedData.onConflictingLibraryRedirectArr) {
|
||||
cb(request, parent, isMain, options, newRequest);
|
||||
}
|
||||
request = newRequest;
|
||||
}
|
||||
}
|
||||
|
||||
return originalValue.call(this, request, parent, isMain, options);
|
||||
}
|
||||
}
|
||||
if (onConflictingLibraryRedirect) {
|
||||
sharedData.onConflictingLibraryRedirectArr.push(onConflictingLibraryRedirect);
|
||||
}
|
||||
}
|
||||
|
||||
// Allow sources to be found by methods other than reading the files
|
||||
// directly from disk.
|
||||
if (options.retrieveFile) {
|
||||
if (options.overrideRetrieveFile) {
|
||||
sharedData.retrieveFileHandlers.length = 0;
|
||||
}
|
||||
|
||||
sharedData.retrieveFileHandlers.unshift(options.retrieveFile);
|
||||
}
|
||||
|
||||
// Allow source maps to be found by methods other than reading the files
|
||||
// directly from disk.
|
||||
if (options.retrieveSourceMap) {
|
||||
if (options.overrideRetrieveSourceMap) {
|
||||
sharedData.retrieveMapHandlers.length = 0;
|
||||
}
|
||||
|
||||
sharedData.retrieveMapHandlers.unshift(options.retrieveSourceMap);
|
||||
}
|
||||
|
||||
// Support runtime transpilers that include inline source maps
|
||||
if (options.hookRequire && !isInBrowser()) {
|
||||
var $compile = Module.prototype._compile;
|
||||
|
||||
if (!$compile.__sourceMapSupport) {
|
||||
Module.prototype._compile = function(content, filename) {
|
||||
setFileContentsCache(filename, content);
|
||||
setSourceMapCache(filename, undefined);
|
||||
return $compile.call(this, content, filename);
|
||||
};
|
||||
|
||||
Module.prototype._compile.__sourceMapSupport = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Configure options
|
||||
if (!sharedData.emptyCacheBetweenOperations) {
|
||||
sharedData.emptyCacheBetweenOperations = 'emptyCacheBetweenOperations' in options ?
|
||||
options.emptyCacheBetweenOperations : false;
|
||||
}
|
||||
|
||||
|
||||
// Install the error reformatter
|
||||
if (!sharedData.errorPrepareStackTraceHook) {
|
||||
const originalValue = Error.prepareStackTrace;
|
||||
sharedData.errorPrepareStackTraceHook = {
|
||||
enabled: true,
|
||||
originalValue,
|
||||
installedValue: undefined
|
||||
};
|
||||
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.installedValue = createPrepareStackTrace(sharedData.errorPrepareStackTraceHook);
|
||||
}
|
||||
|
||||
if (!sharedData.processEmitHook) {
|
||||
var installHandler = 'handleUncaughtExceptions' in options ?
|
||||
options.handleUncaughtExceptions : true;
|
||||
|
||||
// Do not override 'uncaughtException' with our own handler in Node.js
|
||||
// Worker threads. Workers pass the error to the main thread as an event,
|
||||
// rather than printing something to stderr and exiting.
|
||||
try {
|
||||
// We need to use `dynamicRequire` because `require` on it's own will be optimized by WebPack/Browserify.
|
||||
var worker_threads = dynamicRequire(module, 'worker_threads');
|
||||
if (worker_threads.isMainThread === false) {
|
||||
installHandler = false;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
// Provide the option to not install the uncaught exception handler. This is
|
||||
// to support other uncaught exception handlers (in test frameworks, for
|
||||
// example). If this handler is not installed and there are no other uncaught
|
||||
// exception handlers, uncaught exceptions will be caught by node's built-in
|
||||
// exception handler and the process will still be terminated. However, the
|
||||
// generated JavaScript code will be shown above the stack trace instead of
|
||||
// the original source code.
|
||||
if (installHandler && hasGlobalProcessEventEmitter()) {
|
||||
shimEmitUncaughtException();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.uninstall = function() {
|
||||
if(sharedData.processEmitHook) {
|
||||
// Disable behavior
|
||||
sharedData.processEmitHook.enabled = false;
|
||||
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
|
||||
if(process.emit === sharedData.processEmitHook.installedValue) {
|
||||
process.emit = sharedData.processEmitHook.originalValue;
|
||||
}
|
||||
sharedData.processEmitHook = undefined;
|
||||
}
|
||||
if(sharedData.errorPrepareStackTraceHook) {
|
||||
// Disable behavior
|
||||
sharedData.errorPrepareStackTraceHook.enabled = false;
|
||||
// If possible or necessary, remove our hook function.
|
||||
// In vanilla environments, prepareStackTrace is `undefined`.
|
||||
// We cannot delegate to `undefined` the way we can to a function w/`.apply()`; our only option is to remove the function.
|
||||
// If we are the *first* hook installed, and another was installed on top of us, we have no choice but to remove both.
|
||||
if(Error.prepareStackTrace === sharedData.errorPrepareStackTraceHook.installedValue || typeof sharedData.errorPrepareStackTraceHook.originalValue !== 'function') {
|
||||
Error.prepareStackTrace = sharedData.errorPrepareStackTraceHook.originalValue;
|
||||
}
|
||||
sharedData.errorPrepareStackTraceHook = undefined;
|
||||
}
|
||||
if (sharedData.moduleResolveFilenameHook) {
|
||||
// Disable behavior
|
||||
sharedData.moduleResolveFilenameHook.enabled = false;
|
||||
// If possible, remove our hook function. May not be possible if subsequent third-party hooks have wrapped around us.
|
||||
var Module = dynamicRequire(module, 'module');
|
||||
if(Module._resolveFilename === sharedData.moduleResolveFilenameHook.installedValue) {
|
||||
Module._resolveFilename = sharedData.moduleResolveFilenameHook.originalValue;
|
||||
}
|
||||
sharedData.moduleResolveFilenameHook = undefined;
|
||||
}
|
||||
sharedData.onConflictingLibraryRedirectArr.length = 0;
|
||||
}
|
||||
|
||||
exports.resetRetrieveHandlers = function() {
|
||||
sharedData.retrieveFileHandlers.length = 0;
|
||||
sharedData.retrieveMapHandlers.length = 0;
|
||||
}
|
||||
22
backend/node_modules/@fastify/accept-negotiator/LICENSE
generated
vendored
Normal file
22
backend/node_modules/@fastify/accept-negotiator/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2022 The Fastify Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
52
backend/node_modules/@fastify/accept-negotiator/README.md
generated
vendored
Normal file
52
backend/node_modules/@fastify/accept-negotiator/README.md
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# @fastify/accept-negotiator
|
||||
|
||||
|
||||
[](https://github.com/fastify/accept-negotiator/actions/workflows/ci.yml)
|
||||
[](https://www.npmjs.com/package/@fastify/accept-negotiator)
|
||||
[](https://standardjs.com/)
|
||||
|
||||
A negotiator for the accept-headers
|
||||
|
||||
### Install
|
||||
```
|
||||
npm i @fastify/accept-negotiator
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
The module exports a function that you can use for negotiating an accept-header, e.g. accept-encoding. It takes 2 parameters:
|
||||
|
||||
```
|
||||
negotiate(header, supportedValues)
|
||||
```
|
||||
|
||||
- `header` (`string`, required) - The accept-header, e.g. accept-encoding
|
||||
- `supportedValues` (`string[]`, required) - The values, which are supported
|
||||
|
||||
```js
|
||||
const negotiate = require('@fastify/accept-negotiator').negotiate
|
||||
const encoding = negotiate('gzip, deflate, br', ['br'])
|
||||
console.log(encoding) // 'br*
|
||||
```
|
||||
|
||||
The module also exports a class that you can use for negotiating an accept-header, e.g. accept-encoding, and use caching for better performance.
|
||||
|
||||
|
||||
```
|
||||
Negotiate(supportedValues)
|
||||
```
|
||||
|
||||
- `supportedValues` (`string[]`, required) - The values, which are supported
|
||||
- `cache` (`{ set: Function; get: Function; has: Function }`, optional) - A Cache-Store, e.g. ES6-Map or mnemonist LRUCache
|
||||
|
||||
```js
|
||||
const Negotiator = require('@fastify/accept-negotiator').Negotiator
|
||||
const encodingNegotiator = new Negotiator({ supportedValues: ['br'], cache: new Map() })
|
||||
|
||||
const encoding = encodingNegotiator.negotiate('gzip, deflate, br')
|
||||
console.log(encoding) // 'br*
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Licensed under [MIT](./LICENSE).
|
||||
170
backend/node_modules/@fastify/accept-negotiator/index.js
generated
vendored
Normal file
170
backend/node_modules/@fastify/accept-negotiator/index.js
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
'use strict'
|
||||
|
||||
function Negotiator (options) {
|
||||
if (!new.target) {
|
||||
return new Negotiator(options)
|
||||
}
|
||||
|
||||
const {
|
||||
supportedValues = [],
|
||||
cache
|
||||
} = (options && typeof options === 'object' && options) || {}
|
||||
|
||||
this.supportedValues = supportedValues
|
||||
|
||||
this.cache = cache
|
||||
}
|
||||
|
||||
Negotiator.prototype.negotiate = function (header) {
|
||||
if (typeof header !== 'string') {
|
||||
return null
|
||||
}
|
||||
if (!this.cache) {
|
||||
return negotiate(header, this.supportedValues)
|
||||
}
|
||||
if (!this.cache.has(header)) {
|
||||
this.cache.set(header, negotiate(header, this.supportedValues))
|
||||
}
|
||||
return this.cache.get(header)
|
||||
}
|
||||
|
||||
function negotiate (header, supportedValues) {
|
||||
if (
|
||||
!header ||
|
||||
!Array.isArray(supportedValues) ||
|
||||
supportedValues.length === 0
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (header === '*') {
|
||||
return supportedValues[0]
|
||||
}
|
||||
|
||||
let preferredEncoding = null
|
||||
let preferredEncodingPriority = Infinity
|
||||
let preferredEncodingQuality = 0
|
||||
|
||||
function processMatch (enc, quality) {
|
||||
if (quality === 0 || preferredEncodingQuality > quality) {
|
||||
return false
|
||||
}
|
||||
|
||||
const encoding = (enc === '*' && supportedValues[0]) || enc
|
||||
const priority = supportedValues.indexOf(encoding)
|
||||
if (priority === -1) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (priority === 0 && quality === 1) {
|
||||
preferredEncoding = encoding
|
||||
return true
|
||||
} else if (preferredEncodingQuality < quality) {
|
||||
preferredEncoding = encoding
|
||||
preferredEncodingPriority = priority
|
||||
preferredEncodingQuality = quality
|
||||
} else if (preferredEncodingPriority > priority) {
|
||||
preferredEncoding = encoding
|
||||
preferredEncodingPriority = priority
|
||||
preferredEncodingQuality = quality
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
parse(header, processMatch)
|
||||
|
||||
return preferredEncoding
|
||||
}
|
||||
|
||||
const BEGIN = 0
|
||||
const TOKEN = 1
|
||||
const QUALITY = 2
|
||||
const END = 3
|
||||
|
||||
function parse (header, processMatch) {
|
||||
let str = ''
|
||||
let quality
|
||||
let state = BEGIN
|
||||
for (let i = 0, il = header.length; i < il; ++i) {
|
||||
const char = header[i]
|
||||
|
||||
if (char === ' ' || char === '\t') {
|
||||
continue
|
||||
} else if (char === ';') {
|
||||
if (state === TOKEN) {
|
||||
state = QUALITY
|
||||
quality = ''
|
||||
}
|
||||
continue
|
||||
} else if (char === ',') {
|
||||
if (state === TOKEN) {
|
||||
if (processMatch(str, 1)) {
|
||||
state = END
|
||||
break
|
||||
}
|
||||
state = BEGIN
|
||||
str = ''
|
||||
} else if (state === QUALITY) {
|
||||
if (processMatch(str, parseFloat(quality) || 0)) {
|
||||
state = END
|
||||
break
|
||||
}
|
||||
state = BEGIN
|
||||
str = ''
|
||||
quality = ''
|
||||
}
|
||||
continue
|
||||
} else if (
|
||||
state === QUALITY
|
||||
) {
|
||||
if (char === 'q' || char === '=') {
|
||||
continue
|
||||
} else if (
|
||||
char === '.' ||
|
||||
char === '1' ||
|
||||
char === '0' ||
|
||||
char === '2' ||
|
||||
char === '3' ||
|
||||
char === '4' ||
|
||||
char === '5' ||
|
||||
char === '6' ||
|
||||
char === '7' ||
|
||||
char === '8' ||
|
||||
char === '9'
|
||||
) {
|
||||
quality += char
|
||||
continue
|
||||
}
|
||||
} else if (state === BEGIN) {
|
||||
state = TOKEN
|
||||
str += char
|
||||
continue
|
||||
}
|
||||
if (state === TOKEN) {
|
||||
const prevChar = header[i - 1]
|
||||
if (prevChar === ' ' || prevChar === '\t') {
|
||||
str = ''
|
||||
}
|
||||
str += char
|
||||
continue
|
||||
}
|
||||
if (processMatch(str, parseFloat(quality) || 0)) {
|
||||
state = END
|
||||
break
|
||||
}
|
||||
state = BEGIN
|
||||
str = char
|
||||
quality = ''
|
||||
}
|
||||
|
||||
if (state === TOKEN) {
|
||||
processMatch(str, 1)
|
||||
} else if (state === QUALITY) {
|
||||
processMatch(str, parseFloat(quality) || 0)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = negotiate
|
||||
module.exports.default = negotiate
|
||||
module.exports.negotiate = negotiate
|
||||
module.exports.Negotiator = Negotiator
|
||||
51
backend/node_modules/@fastify/accept-negotiator/package.json
generated
vendored
Normal file
51
backend/node_modules/@fastify/accept-negotiator/package.json
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"name": "@fastify/accept-negotiator",
|
||||
"version": "1.1.0",
|
||||
"description": "a negotiator for the accept-headers",
|
||||
"type": "commonjs",
|
||||
"main": "index.js",
|
||||
"types": "types/index.d.ts",
|
||||
"scripts": {
|
||||
"lint": "standard index.js test/* benchmarks/*",
|
||||
"test": "npm run test:unit && npm run test:typescript",
|
||||
"test:unit": "tap",
|
||||
"test:typescript": "tsd"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"index.d.ts"
|
||||
]
|
||||
},
|
||||
"keywords": [
|
||||
"encoding",
|
||||
"negotiator",
|
||||
"accept-encoding",
|
||||
"accept",
|
||||
"http",
|
||||
"header"
|
||||
],
|
||||
"files": [
|
||||
"README.md",
|
||||
"LICENSE",
|
||||
"index.js",
|
||||
"types/index.d.ts"
|
||||
],
|
||||
"author": "Aras Abbasi",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"benchmark": "2.1.4",
|
||||
"standard": "17.0.0",
|
||||
"tap": "^16.3.0",
|
||||
"tsd": "^0.24.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/accept-negotiator.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/fastify/accept-negotiator/issues"
|
||||
}
|
||||
}
|
||||
17
backend/node_modules/@fastify/accept-negotiator/types/index.d.ts
generated
vendored
Normal file
17
backend/node_modules/@fastify/accept-negotiator/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
type CacheStore = { set: (key: string, value: string) => CacheStore, get: (key: string) => string | undefined, has: (key: string) => boolean }
|
||||
|
||||
type NegotiateFn = typeof negotiate
|
||||
|
||||
declare namespace negotiate {
|
||||
export class Negotiator<K extends string = string> {
|
||||
constructor (options: { supportedValues: K[]; cache?: CacheStore })
|
||||
|
||||
negotiate(header: string): K | null
|
||||
}
|
||||
|
||||
export const negotiate: NegotiateFn
|
||||
export { negotiate as default }
|
||||
}
|
||||
|
||||
declare function negotiate<K extends string = string>(header: string, supportedValues: K[]): K | null;
|
||||
export = negotiate;
|
||||
2
backend/node_modules/@fastify/ajv-compiler/.gitattributes
generated
vendored
Normal file
2
backend/node_modules/@fastify/ajv-compiler/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Set default behavior to automatically convert line endings
|
||||
* text=auto eol=lf
|
||||
21
backend/node_modules/@fastify/ajv-compiler/.github/.stale.yml
generated
vendored
Normal file
21
backend/node_modules/@fastify/ajv-compiler/.github/.stale.yml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 15
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "discussion"
|
||||
- "feature request"
|
||||
- "bug"
|
||||
- "help wanted"
|
||||
- "plugin suggestion"
|
||||
- "good first issue"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
13
backend/node_modules/@fastify/ajv-compiler/.github/dependabot.yml
generated
vendored
Normal file
13
backend/node_modules/@fastify/ajv-compiler/.github/dependabot.yml
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
8
backend/node_modules/@fastify/ajv-compiler/.github/tests_checker.yml
generated
vendored
Normal file
8
backend/node_modules/@fastify/ajv-compiler/.github/tests_checker.yml
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
comment: |
|
||||
Hello! Thank you for contributing!
|
||||
It appears that you have changed the code, but the tests that verify your change are missing. Could you please add them?
|
||||
fileExtensions:
|
||||
- '.ts'
|
||||
- '.js'
|
||||
|
||||
testDir: 'test'
|
||||
26
backend/node_modules/@fastify/ajv-compiler/.github/workflows/ci.yml
generated
vendored
Normal file
26
backend/node_modules/@fastify/ajv-compiler/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- next
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
|
||||
env:
|
||||
TZ: 'UTC'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3
|
||||
with:
|
||||
lint: true
|
||||
license-check: true
|
||||
2
backend/node_modules/@fastify/ajv-compiler/.taprc
generated
vendored
Normal file
2
backend/node_modules/@fastify/ajv-compiler/.taprc
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
files:
|
||||
- test/**/*.test.js
|
||||
24
backend/node_modules/@fastify/ajv-compiler/LICENSE
generated
vendored
Normal file
24
backend/node_modules/@fastify/ajv-compiler/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) The Fastify Team
|
||||
|
||||
The Fastify team members are listed at https://github.com/fastify/fastify#team
|
||||
and in the README file.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
236
backend/node_modules/@fastify/ajv-compiler/README.md
generated
vendored
Normal file
236
backend/node_modules/@fastify/ajv-compiler/README.md
generated
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
# @fastify/ajv-compiler
|
||||
|
||||
[](http://standardjs.com/)
|
||||
[](https://github.com/fastify/ajv-compiler/actions/workflows/ci.yml)
|
||||
|
||||
This module manages the [`ajv`](https://www.npmjs.com/package/ajv) instances for the Fastify framework.
|
||||
It isolates the `ajv` dependency so that the AJV version is not tightly coupled to the Fastify version.
|
||||
This allows the user to decide which version of AJV to use in their Fastify based application.
|
||||
|
||||
|
||||
## Versions
|
||||
|
||||
| `@fastify/ajv-compiler` | `ajv` | Default in `fastify` |
|
||||
|------------------------:|------:|---------------------:|
|
||||
| v1.x | v6.x | ^3.14 |
|
||||
| v2.x | v8.x | - |
|
||||
| v3.x | v8.x | ^4.x |
|
||||
|
||||
|
||||
### AJV Configuration
|
||||
|
||||
The Fastify's default [`ajv` options](https://github.com/ajv-validator/ajv/tree/v6#options) are:
|
||||
|
||||
```js
|
||||
{
|
||||
coerceTypes: 'array',
|
||||
useDefaults: true,
|
||||
removeAdditional: true,
|
||||
uriResolver: require('fast-uri'),
|
||||
addUsedSchema: false,
|
||||
// Explicitly set allErrors to `false`.
|
||||
// When set to `true`, a DoS attack is possible.
|
||||
allErrors: false
|
||||
}
|
||||
```
|
||||
|
||||
Moreover, the [`ajv-formats`](https://www.npmjs.com/package/ajv-formats) module is included by default.
|
||||
If you need to customize it, check the _usage_ section below.
|
||||
|
||||
To customize the `ajv`'s options, see how in the [Fastify official docs](https://fastify.dev/docs/latest/Reference/Server/#ajv).
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
This module is already used as default by Fastify.
|
||||
If you need to provide to your server instance a different version, refer to [the official doc](https://fastify.dev/docs/latest/Reference/Server/#schemacontroller).
|
||||
|
||||
### Customize the `ajv-formats` plugin
|
||||
|
||||
The `format` keyword is not part of the official `ajv` module since v7. To use it, you need to install the `ajv-formats` module and this module
|
||||
does it for you with the default configuration.
|
||||
|
||||
If you need to configure the `ajv-formats` plugin you can do it using the standard Fastify configuration:
|
||||
|
||||
```js
|
||||
const app = fastify({
|
||||
ajv: {
|
||||
plugins: [[require('ajv-formats'), { mode: 'fast' }]]
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
In this way, your setup will have precendence over the `@fastify/ajv-compiler` default configuration.
|
||||
|
||||
### Customize the `ajv` instance
|
||||
|
||||
If you need to customize the `ajv` instance and take full control of its configuration, you can do it by
|
||||
using the `onCreate` option in the Fastify configuration that accepts a syncronous function that receives the `ajv` instance:
|
||||
|
||||
```js
|
||||
const app = fastify({
|
||||
ajv: {
|
||||
onCreate: (ajv) => {
|
||||
// Modify the ajv instance as you need.
|
||||
ajv.addFormat('myFormat', (data) => typeof data === 'string')
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Fastify with JTD
|
||||
|
||||
The [JSON Type Definition](https://jsontypedef.com/) feature is supported by AJV v8.x and you can benefit from it in your Fastify application.
|
||||
|
||||
With Fastify v3.20.x and higher, you can use the `@fastify/ajv-compiler` module to load JSON Type Definitions like so:
|
||||
|
||||
```js
|
||||
const factory = require('@fastify/ajv-compiler')()
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
ajv: {
|
||||
customOptions: { }, // additional JTD options
|
||||
mode: 'JTD'
|
||||
},
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factory
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The defaults AJV JTD options are the same as the [Fastify's default options](#AJV-Configuration).
|
||||
|
||||
#### Fastify with JTD and serialization
|
||||
|
||||
You can use JTD Schemas to serialize your response object too:
|
||||
|
||||
```js
|
||||
const factoryValidator = require('@fastify/ajv-compiler')()
|
||||
const factorySerializer = require('@fastify/ajv-compiler')({ jtdSerializer: true })
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
ajv: {
|
||||
customOptions: { }, // additional JTD options
|
||||
mode: 'JTD'
|
||||
},
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factoryValidator,
|
||||
buildSerializer: factorySerializer
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
### AJV Standalone
|
||||
|
||||
AJV v8 introduces the [standalone feature](https://ajv.js.org/standalone.html) that let you to pre-compile your schemas and use them in your application for a faster startup.
|
||||
|
||||
To use this feature, you must be aware of the following:
|
||||
|
||||
1. You must generate and save the application's compiled schemas.
|
||||
2. Read the compiled schemas from the file and provide them back to your Fastify application.
|
||||
|
||||
|
||||
#### Generate and save the compiled schemas
|
||||
|
||||
Fastify helps you to generate the validation schemas functions and it is your choice to save them where you want.
|
||||
To accomplish this, you must use a new compiler: `StandaloneValidator`.
|
||||
|
||||
You must provide 2 parameters to this compiler:
|
||||
|
||||
- `readMode: false`: a boolean to indicate that you want generate the schemas functions string.
|
||||
- `storeFunction`" a sync function that must store the source code of the schemas functions. You may provide an async function too, but you must manage errors.
|
||||
|
||||
When `readMode: false`, **the compiler is meant to be used in development ONLY**.
|
||||
|
||||
|
||||
```js
|
||||
const { StandaloneValidator } = require('@fastify/ajv-compiler')
|
||||
const factory = StandaloneValidator({
|
||||
readMode: false,
|
||||
storeFunction (routeOpts, schemaValidationCode) {
|
||||
// routeOpts is like: { schema, method, url, httpPart }
|
||||
// schemaValidationCode is a string source code that is the compiled schema function
|
||||
const fileName = generateFileName(routeOpts)
|
||||
fs.writeFileSync(path.join(__dirname, fileName), schemaValidationCode)
|
||||
}
|
||||
})
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factory
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// ... add all your routes with schemas ...
|
||||
|
||||
app.ready().then(() => {
|
||||
// at this stage all your schemas are compiled and stored in the file system
|
||||
// now it is important to turn off the readMode
|
||||
})
|
||||
```
|
||||
|
||||
#### Read the compiled schemas functions
|
||||
|
||||
At this stage, you should have a file for every route's schema.
|
||||
To use them, you must use the `StandaloneValidator` with the parameters:
|
||||
|
||||
- `readMode: true`: a boolean to indicate that you want read and use the schemas functions string.
|
||||
- `restoreFunction`" a sync function that must return a function to validate the route.
|
||||
|
||||
Important keep away before you continue reading the documentation:
|
||||
|
||||
- when you use the `readMode: true`, the application schemas are not compiled (they are ignored). So, if you change your schemas, you must recompile them!
|
||||
- as you can see, you must relate the route's schema to the file name using the `routeOpts` object. You may use the `routeOpts.schema.$id` field to do so, it is up to you to define a unique schema identifier.
|
||||
|
||||
```js
|
||||
const { StandaloneValidator } = require('@fastify/ajv-compiler')
|
||||
const factory = StandaloneValidator({
|
||||
readMode: true,
|
||||
restoreFunction (routeOpts) {
|
||||
// routeOpts is like: { schema, method, url, httpPart }
|
||||
const fileName = generateFileName(routeOpts)
|
||||
return require(path.join(__dirname, fileName))
|
||||
}
|
||||
})
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factory
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// ... add all your routes with schemas as before...
|
||||
|
||||
app.listen({ port: 3000 })
|
||||
```
|
||||
|
||||
### How it works
|
||||
|
||||
This module provide a factory function to produce [Validator Compilers](https://fastify.dev/docs/latest/Reference/Server/#validatorcompiler) functions.
|
||||
|
||||
The Fastify factory function is just one per server instance and it is called for every encapsulated context created by the application through the `fastify.register()` call.
|
||||
|
||||
Every Validator Compiler produced, has a dedicated AJV instance, so, this factory will try to produce as less as possible AJV instances to reduce the memory footprint and the startup time.
|
||||
|
||||
The variables involved to choose if a Validator Compiler can be reused are:
|
||||
|
||||
- the AJV configuration: it is [one per server](https://fastify.dev/docs/latest/Reference/Server/#ajv)
|
||||
- the external JSON schemas: once a new schema is added to a fastify's context, calling `fastify.addSchema()`, it will cause a new AJV inizialization
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Licensed under [MIT](./LICENSE).
|
||||
37
backend/node_modules/@fastify/ajv-compiler/benchmark/small-object.mjs
generated
vendored
Normal file
37
backend/node_modules/@fastify/ajv-compiler/benchmark/small-object.mjs
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import cronometro from 'cronometro'
|
||||
|
||||
import fjs from 'fast-json-stringify'
|
||||
import AjvCompiler from '../index.js'
|
||||
|
||||
const fjsSerialize = buildFJSSerializerFunction({
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { type: 'string' },
|
||||
name: { type: 'string' }
|
||||
}
|
||||
})
|
||||
const ajvSerialize = buildAJVSerializerFunction({
|
||||
properties: {
|
||||
hello: { type: 'string' },
|
||||
name: { type: 'string' }
|
||||
}
|
||||
})
|
||||
|
||||
await cronometro({
|
||||
'fast-json-stringify': function () {
|
||||
fjsSerialize({ hello: 'Ciao', name: 'Manuel' })
|
||||
},
|
||||
'ajv serializer': function () {
|
||||
ajvSerialize({ hello: 'Ciao', name: 'Manuel' })
|
||||
}
|
||||
})
|
||||
|
||||
function buildFJSSerializerFunction (schema) {
|
||||
return fjs(schema)
|
||||
}
|
||||
|
||||
function buildAJVSerializerFunction (schema) {
|
||||
const factory = AjvCompiler({ jtdSerializer: true })
|
||||
const compiler = factory({}, { customOptions: {} })
|
||||
return compiler({ schema })
|
||||
}
|
||||
53
backend/node_modules/@fastify/ajv-compiler/index.js
generated
vendored
Normal file
53
backend/node_modules/@fastify/ajv-compiler/index.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
const AjvReference = Symbol.for('fastify.ajv-compiler.reference')
|
||||
const ValidatorCompiler = require('./lib/validator-compiler')
|
||||
const SerializerCompiler = require('./lib/serializer-compiler')
|
||||
|
||||
function AjvCompiler (opts) {
|
||||
const validatorPool = new Map()
|
||||
const serializerPool = new Map()
|
||||
|
||||
if (opts && opts.jtdSerializer === true) {
|
||||
return function buildSerializerFromPool (externalSchemas, serializerOpts) {
|
||||
const uniqueAjvKey = getPoolKey({}, serializerOpts)
|
||||
if (serializerPool.has(uniqueAjvKey)) {
|
||||
return serializerPool.get(uniqueAjvKey)
|
||||
}
|
||||
|
||||
const compiler = new SerializerCompiler(externalSchemas, serializerOpts)
|
||||
const ret = compiler.buildSerializerFunction.bind(compiler)
|
||||
serializerPool.set(uniqueAjvKey, ret)
|
||||
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
return function buildCompilerFromPool (externalSchemas, options) {
|
||||
const uniqueAjvKey = getPoolKey(externalSchemas, options.customOptions)
|
||||
if (validatorPool.has(uniqueAjvKey)) {
|
||||
return validatorPool.get(uniqueAjvKey)
|
||||
}
|
||||
|
||||
const compiler = new ValidatorCompiler(externalSchemas, options)
|
||||
const ret = compiler.buildValidatorFunction.bind(compiler)
|
||||
validatorPool.set(uniqueAjvKey, ret)
|
||||
|
||||
if (options.customOptions.code !== undefined) {
|
||||
ret[AjvReference] = compiler
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
function getPoolKey (externalSchemas, options) {
|
||||
const externals = JSON.stringify(externalSchemas)
|
||||
const ajvConfig = JSON.stringify(options)
|
||||
return `${externals}${ajvConfig}`
|
||||
}
|
||||
module.exports = AjvCompiler
|
||||
module.exports.default = AjvCompiler
|
||||
module.exports.AjvCompiler = AjvCompiler
|
||||
module.exports.AjvReference = AjvReference
|
||||
module.exports.StandaloneValidator = require('./standalone')
|
||||
14
backend/node_modules/@fastify/ajv-compiler/lib/default-ajv-options.js
generated
vendored
Normal file
14
backend/node_modules/@fastify/ajv-compiler/lib/default-ajv-options.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict'
|
||||
|
||||
const fastUri = require('fast-uri')
|
||||
|
||||
module.exports = Object.freeze({
|
||||
coerceTypes: 'array',
|
||||
useDefaults: true,
|
||||
removeAdditional: true,
|
||||
uriResolver: fastUri,
|
||||
addUsedSchema: false,
|
||||
// Explicitly set allErrors to `false`.
|
||||
// When set to `true`, a DoS attack is possible.
|
||||
allErrors: false
|
||||
})
|
||||
27
backend/node_modules/@fastify/ajv-compiler/lib/serializer-compiler.js
generated
vendored
Normal file
27
backend/node_modules/@fastify/ajv-compiler/lib/serializer-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict'
|
||||
|
||||
const AjvJTD = require('ajv/dist/jtd')
|
||||
|
||||
const defaultAjvOptions = require('./default-ajv-options')
|
||||
|
||||
class SerializerCompiler {
|
||||
constructor (externalSchemas, options) {
|
||||
this.ajv = new AjvJTD(Object.assign({}, defaultAjvOptions, options))
|
||||
|
||||
/**
|
||||
* https://ajv.js.org/json-type-definition.html#ref-form
|
||||
* Unlike JSON Schema, JTD does not allow to reference:
|
||||
* - any schema fragment other than root level definitions member
|
||||
* - root of the schema - there is another way to define a self-recursive schema (see Example 2)
|
||||
* - another schema file (but you can still combine schemas from multiple files using JavaScript).
|
||||
*
|
||||
* So we ignore the externalSchemas parameter.
|
||||
*/
|
||||
}
|
||||
|
||||
buildSerializerFunction ({ schema/*, method, url, httpStatus */ }) {
|
||||
return this.ajv.compileSerializer(schema)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SerializerCompiler
|
||||
58
backend/node_modules/@fastify/ajv-compiler/lib/validator-compiler.js
generated
vendored
Normal file
58
backend/node_modules/@fastify/ajv-compiler/lib/validator-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
'use strict'
|
||||
|
||||
const Ajv = require('ajv').default
|
||||
const AjvJTD = require('ajv/dist/jtd')
|
||||
|
||||
const defaultAjvOptions = require('./default-ajv-options')
|
||||
|
||||
class ValidatorCompiler {
|
||||
constructor (externalSchemas, options) {
|
||||
// This instance of Ajv is private
|
||||
// it should not be customized or used
|
||||
if (options.mode === 'JTD') {
|
||||
this.ajv = new AjvJTD(Object.assign({}, defaultAjvOptions, options.customOptions))
|
||||
} else {
|
||||
this.ajv = new Ajv(Object.assign({}, defaultAjvOptions, options.customOptions))
|
||||
}
|
||||
|
||||
let addFormatPlugin = true
|
||||
if (options.plugins && options.plugins.length > 0) {
|
||||
for (const plugin of options.plugins) {
|
||||
if (Array.isArray(plugin)) {
|
||||
addFormatPlugin = addFormatPlugin && plugin[0].name !== 'formatsPlugin'
|
||||
plugin[0](this.ajv, plugin[1])
|
||||
} else {
|
||||
addFormatPlugin = addFormatPlugin && plugin.name !== 'formatsPlugin'
|
||||
plugin(this.ajv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addFormatPlugin) {
|
||||
require('ajv-formats')(this.ajv)
|
||||
}
|
||||
|
||||
options.onCreate?.(this.ajv)
|
||||
|
||||
const sourceSchemas = Object.values(externalSchemas)
|
||||
for (const extSchema of sourceSchemas) {
|
||||
this.ajv.addSchema(extSchema)
|
||||
}
|
||||
}
|
||||
|
||||
buildValidatorFunction ({ schema/*, method, url, httpPart */ }) {
|
||||
// Ajv does not support compiling two schemas with the same
|
||||
// id inside the same instance. Therefore if we have already
|
||||
// compiled the schema with the given id, we just return it.
|
||||
if (schema.$id) {
|
||||
const stored = this.ajv.getSchema(schema.$id)
|
||||
if (stored) {
|
||||
return stored
|
||||
}
|
||||
}
|
||||
|
||||
return this.ajv.compile(schema)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ValidatorCompiler
|
||||
54
backend/node_modules/@fastify/ajv-compiler/package.json
generated
vendored
Normal file
54
backend/node_modules/@fastify/ajv-compiler/package.json
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "@fastify/ajv-compiler",
|
||||
"version": "3.6.0",
|
||||
"description": "Build and manage the AJV instances for the fastify framework",
|
||||
"main": "index.js",
|
||||
"type": "commonjs",
|
||||
"types": "types/index.d.ts",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "standard",
|
||||
"lint:fix": "standard --fix",
|
||||
"unit": "tap",
|
||||
"test": "npm run unit && npm run test:typescript",
|
||||
"test:typescript": "tsd",
|
||||
"ajv:compile": "ajv compile -s test/source.json -o test/validate_schema.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/ajv-compiler.git"
|
||||
},
|
||||
"keywords": [
|
||||
"ajv",
|
||||
"validator",
|
||||
"schema",
|
||||
"compiler",
|
||||
"fastify"
|
||||
],
|
||||
"author": "Manuel Spigolon <behemoth89@gmail.com> (https://github.com/Eomm)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/fastify/ajv-compiler/issues"
|
||||
},
|
||||
"homepage": "https://github.com/fastify/ajv-compiler#readme",
|
||||
"devDependencies": {
|
||||
"ajv-cli": "^5.0.0",
|
||||
"ajv-errors": "^3.0.0",
|
||||
"ajv-i18n": "^4.0.1",
|
||||
"ajv-merge-patch": "^5.0.1",
|
||||
"cronometro": "^3.0.1",
|
||||
"fastify": "^4.0.0",
|
||||
"require-from-string": "^2.0.2",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"standard": "^17.0.0",
|
||||
"tap": "^16.2.0",
|
||||
"tsd": "^0.31.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": "^8.11.0",
|
||||
"ajv-formats": "^2.1.1",
|
||||
"fast-uri": "^2.0.0"
|
||||
}
|
||||
}
|
||||
44
backend/node_modules/@fastify/ajv-compiler/standalone.js
generated
vendored
Normal file
44
backend/node_modules/@fastify/ajv-compiler/standalone.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
'use strict'
|
||||
|
||||
const ValidatorSelector = require('./index')
|
||||
const standaloneCode = require('ajv/dist/standalone').default
|
||||
|
||||
function StandaloneValidator (options = { readMode: true }) {
|
||||
if (options.readMode === true && !options.restoreFunction) {
|
||||
throw new Error('You must provide a restoreFunction options when readMode ON')
|
||||
}
|
||||
|
||||
if (options.readMode !== true && !options.storeFunction) {
|
||||
throw new Error('You must provide a storeFunction options when readMode OFF')
|
||||
}
|
||||
|
||||
if (options.readMode === true) {
|
||||
// READ MODE: it behalf only in the restore function provided by the user
|
||||
return function wrapper () {
|
||||
return function (opts) {
|
||||
return options.restoreFunction(opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WRITE MODE: it behalf on the default ValidatorSelector, wrapping the API to run the Ajv Standalone code generation
|
||||
const factory = ValidatorSelector()
|
||||
return function wrapper (externalSchemas, ajvOptions = {}) {
|
||||
if (!ajvOptions.customOptions || !ajvOptions.customOptions.code) {
|
||||
// to generate the validation source code, these options are mandatory
|
||||
ajvOptions.customOptions = Object.assign({}, ajvOptions.customOptions, { code: { source: true } })
|
||||
}
|
||||
|
||||
const compiler = factory(externalSchemas, ajvOptions)
|
||||
return function (opts) { // { schema/*, method, url, httpPart */ }
|
||||
const validationFunc = compiler(opts)
|
||||
|
||||
const schemaValidationCode = standaloneCode(compiler[ValidatorSelector.AjvReference].ajv, validationFunc)
|
||||
options.storeFunction(opts, schemaValidationCode)
|
||||
|
||||
return validationFunc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StandaloneValidator
|
||||
0
backend/node_modules/@fastify/ajv-compiler/test/.gitkeep
generated
vendored
Normal file
0
backend/node_modules/@fastify/ajv-compiler/test/.gitkeep
generated
vendored
Normal file
59
backend/node_modules/@fastify/ajv-compiler/test/duplicated-id-compile.test.js
generated
vendored
Normal file
59
backend/node_modules/@fastify/ajv-compiler/test/duplicated-id-compile.test.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
'use strict'
|
||||
|
||||
const t = require('tap')
|
||||
const AjvCompiler = require('../index')
|
||||
|
||||
const postSchema = Object.freeze({
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
type: 'object',
|
||||
$id: 'http://mydomain.com/user',
|
||||
title: 'User schema',
|
||||
description: 'Contains all user fields',
|
||||
properties: {
|
||||
username: { type: 'string', minLength: 4 },
|
||||
firstName: { type: 'string', minLength: 1 },
|
||||
lastName: { type: 'string', minLength: 1 },
|
||||
email: { type: 'string' },
|
||||
password: { type: 'string', minLength: 6 },
|
||||
bio: { type: 'string' }
|
||||
},
|
||||
required: ['username', 'firstName', 'lastName', 'email', 'bio', 'password']
|
||||
})
|
||||
|
||||
const patchSchema = Object.freeze({
|
||||
$schema: 'http://json-schema.org/draft-07/schema#',
|
||||
type: 'object',
|
||||
$id: 'http://mydomain.com/user',
|
||||
title: 'User schema',
|
||||
description: 'Contains all user fields',
|
||||
properties: {
|
||||
firstName: { type: 'string', minLength: 1 },
|
||||
lastName: { type: 'string', minLength: 1 },
|
||||
bio: { type: 'string' }
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyAjvOptionsDefault = Object.freeze({
|
||||
customOptions: {}
|
||||
})
|
||||
|
||||
t.test('must not store schema on compile', t => {
|
||||
t.plan(4)
|
||||
const factory = AjvCompiler()
|
||||
const compiler = factory({}, fastifyAjvOptionsDefault)
|
||||
const postFn = compiler({ schema: postSchema })
|
||||
const patchFn = compiler({ schema: patchSchema })
|
||||
|
||||
const resultForPost = postFn({})
|
||||
t.equal(resultForPost, false)
|
||||
t.has(postFn.errors, [
|
||||
{
|
||||
keyword: 'required',
|
||||
message: "must have required property 'username'"
|
||||
}
|
||||
])
|
||||
|
||||
const resultForPatch = patchFn({})
|
||||
t.ok(resultForPatch)
|
||||
t.notOk(patchFn.errors)
|
||||
})
|
||||
307
backend/node_modules/@fastify/ajv-compiler/test/index.test.js
generated
vendored
Normal file
307
backend/node_modules/@fastify/ajv-compiler/test/index.test.js
generated
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
'use strict'
|
||||
|
||||
const t = require('tap')
|
||||
const fastify = require('fastify')
|
||||
const AjvCompiler = require('../index')
|
||||
|
||||
const sym = Symbol.for('fastify.ajv-compiler.reference')
|
||||
|
||||
const sampleSchema = Object.freeze({
|
||||
$id: 'example1',
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string' }
|
||||
}
|
||||
})
|
||||
|
||||
const externalSchemas1 = Object.freeze({})
|
||||
const externalSchemas2 = Object.freeze({
|
||||
foo: {
|
||||
$id: 'foo',
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string' }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyAjvOptionsDefault = Object.freeze({
|
||||
customOptions: {}
|
||||
})
|
||||
|
||||
const fastifyJtdDefault = Object.freeze({
|
||||
customOptions: { },
|
||||
mode: 'JTD'
|
||||
})
|
||||
|
||||
const fastifyAjvOptionsCustom = Object.freeze({
|
||||
customOptions: {
|
||||
allErrors: true,
|
||||
removeAdditional: false
|
||||
},
|
||||
plugins: [
|
||||
require('ajv-formats'),
|
||||
[require('ajv-errors'), { singleError: false }]
|
||||
]
|
||||
})
|
||||
|
||||
t.test('basic usage', t => {
|
||||
t.plan(1)
|
||||
const factory = AjvCompiler()
|
||||
const compiler = factory(externalSchemas1, fastifyAjvOptionsDefault)
|
||||
const validatorFunc = compiler({ schema: sampleSchema })
|
||||
const result = validatorFunc({ name: 'hello' })
|
||||
t.equal(result, true)
|
||||
})
|
||||
|
||||
t.test('array coercion', t => {
|
||||
t.plan(2)
|
||||
const factory = AjvCompiler()
|
||||
const compiler = factory(externalSchemas1, fastifyAjvOptionsDefault)
|
||||
|
||||
const arraySchema = {
|
||||
$id: 'example1',
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'array', items: { type: 'string' } }
|
||||
}
|
||||
}
|
||||
|
||||
const validatorFunc = compiler({ schema: arraySchema })
|
||||
|
||||
const inputObj = { name: 'hello' }
|
||||
t.equal(validatorFunc(inputObj), true)
|
||||
t.same(inputObj, { name: ['hello'] }, 'the name property should be coerced to an array')
|
||||
})
|
||||
|
||||
t.test('nullable default', t => {
|
||||
t.plan(2)
|
||||
const factory = AjvCompiler()
|
||||
const compiler = factory({}, fastifyAjvOptionsDefault)
|
||||
const validatorFunc = compiler({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
nullable: { type: 'string', nullable: true },
|
||||
notNullable: { type: 'string' }
|
||||
}
|
||||
}
|
||||
})
|
||||
const input = { nullable: null, notNullable: null }
|
||||
const result = validatorFunc(input)
|
||||
t.equal(result, true)
|
||||
t.same(input, { nullable: null, notNullable: '' }, 'the notNullable field has been coerced')
|
||||
})
|
||||
|
||||
t.test('plugin loading', t => {
|
||||
t.plan(3)
|
||||
const factory = AjvCompiler()
|
||||
const compiler = factory(externalSchemas1, fastifyAjvOptionsCustom)
|
||||
const validatorFunc = compiler({
|
||||
schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
q: {
|
||||
type: 'string',
|
||||
format: 'date',
|
||||
formatMinimum: '2016-02-06',
|
||||
formatExclusiveMaximum: '2016-12-27'
|
||||
}
|
||||
},
|
||||
required: ['q'],
|
||||
errorMessage: 'hello world'
|
||||
}
|
||||
})
|
||||
const result = validatorFunc({ q: '2016-10-02' })
|
||||
t.equal(result, true)
|
||||
|
||||
const resultFail = validatorFunc({})
|
||||
t.equal(resultFail, false)
|
||||
t.equal(validatorFunc.errors[0].message, 'hello world')
|
||||
})
|
||||
|
||||
t.test('optimization - cache ajv instance', t => {
|
||||
t.plan(5)
|
||||
const factory = AjvCompiler()
|
||||
const compiler1 = factory(externalSchemas1, fastifyAjvOptionsDefault)
|
||||
const compiler2 = factory(externalSchemas1, fastifyAjvOptionsDefault)
|
||||
t.equal(compiler1, compiler2, 'same instance')
|
||||
t.same(compiler1, compiler2, 'same instance')
|
||||
|
||||
const compiler3 = factory(externalSchemas2, fastifyAjvOptionsDefault)
|
||||
t.not(compiler3, compiler1, 'new ajv instance when externa schema change')
|
||||
|
||||
const compiler4 = factory(externalSchemas1, fastifyAjvOptionsCustom)
|
||||
t.not(compiler4, compiler1, 'new ajv instance when externa schema change')
|
||||
t.not(compiler4, compiler3, 'new ajv instance when externa schema change')
|
||||
})
|
||||
|
||||
t.test('the onCreate callback can enhance the ajv instance', t => {
|
||||
t.plan(2)
|
||||
const factory = AjvCompiler()
|
||||
|
||||
const fastifyAjvCustomOptionsFormats = Object.freeze({
|
||||
onCreate (ajv) {
|
||||
for (const [formatName, format] of Object.entries(this.customOptions.formats)) {
|
||||
ajv.addFormat(formatName, format)
|
||||
}
|
||||
},
|
||||
customOptions: {
|
||||
formats: {
|
||||
date: /foo/
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const compiler1 = factory(externalSchemas1, fastifyAjvCustomOptionsFormats)
|
||||
const validatorFunc = compiler1({
|
||||
schema: {
|
||||
type: 'string',
|
||||
format: 'date'
|
||||
}
|
||||
})
|
||||
const result = validatorFunc('foo')
|
||||
t.equal(result, true)
|
||||
|
||||
const resultFail = validatorFunc('2016-10-02')
|
||||
t.equal(resultFail, false)
|
||||
})
|
||||
|
||||
// https://github.com/fastify/fastify/pull/2969
|
||||
t.test('compile same $id when in external schema', t => {
|
||||
t.plan(3)
|
||||
const factory = AjvCompiler()
|
||||
|
||||
const base = {
|
||||
$id: 'urn:schema:base',
|
||||
definitions: {
|
||||
hello: { type: 'string' }
|
||||
},
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: '#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const refSchema = {
|
||||
$id: 'urn:schema:ref',
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: 'urn:schema:base#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const compiler = factory({
|
||||
[base.$id]: base,
|
||||
[refSchema.$id]: refSchema
|
||||
|
||||
}, fastifyAjvOptionsDefault)
|
||||
|
||||
t.notOk(compiler[sym], 'the ajv reference do not exists if code is not activated')
|
||||
|
||||
const validatorFunc1 = compiler({
|
||||
schema: {
|
||||
$id: 'urn:schema:ref'
|
||||
}
|
||||
})
|
||||
|
||||
const validatorFunc2 = compiler({
|
||||
schema: {
|
||||
$id: 'urn:schema:ref'
|
||||
}
|
||||
})
|
||||
|
||||
t.pass('the compile does not fail if the schema compiled is already in the external schemas')
|
||||
t.equal(validatorFunc1, validatorFunc2, 'the returned function is the same')
|
||||
})
|
||||
|
||||
t.test('JTD MODE', t => {
|
||||
t.plan(2)
|
||||
|
||||
t.test('compile jtd schema', t => {
|
||||
t.plan(4)
|
||||
const factory = AjvCompiler()
|
||||
|
||||
const jtdSchema = {
|
||||
discriminator: 'version',
|
||||
mapping: {
|
||||
1: {
|
||||
properties: {
|
||||
foo: { type: 'uint8' }
|
||||
}
|
||||
},
|
||||
2: {
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const compiler = factory({}, fastifyJtdDefault)
|
||||
const validatorFunc = compiler({ schema: jtdSchema })
|
||||
t.pass('generated validation function for JTD SCHEMA')
|
||||
|
||||
const result = validatorFunc({
|
||||
version: '2',
|
||||
foo: []
|
||||
})
|
||||
t.notOk(result, 'failed validation')
|
||||
t.type(validatorFunc.errors, 'Array')
|
||||
|
||||
const success = validatorFunc({
|
||||
version: '1',
|
||||
foo: 42
|
||||
})
|
||||
t.ok(success)
|
||||
})
|
||||
|
||||
t.test('fastify integration', async t => {
|
||||
const factory = AjvCompiler()
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
ajv: {
|
||||
customOptions: { },
|
||||
mode: 'JTD'
|
||||
},
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factory
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/', {
|
||||
schema: {
|
||||
body: {
|
||||
discriminator: 'version',
|
||||
mapping: {
|
||||
1: {
|
||||
properties: {
|
||||
foo: { type: 'uint8' }
|
||||
}
|
||||
},
|
||||
2: {
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, () => {})
|
||||
|
||||
const res = await app.inject({
|
||||
url: '/',
|
||||
method: 'POST',
|
||||
payload: {
|
||||
version: '1',
|
||||
foo: 'this is not a number'
|
||||
}
|
||||
})
|
||||
|
||||
t.equal(res.statusCode, 400)
|
||||
t.equal(res.json().message, 'body/foo must be uint8')
|
||||
})
|
||||
})
|
||||
264
backend/node_modules/@fastify/ajv-compiler/test/plugins.test.js
generated
vendored
Normal file
264
backend/node_modules/@fastify/ajv-compiler/test/plugins.test.js
generated
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
'use strict'
|
||||
|
||||
const t = require('tap')
|
||||
const fastify = require('fastify')
|
||||
const AjvCompiler = require('../index')
|
||||
|
||||
const ajvFormats = require('ajv-formats')
|
||||
const ajvErrors = require('ajv-errors')
|
||||
const localize = require('ajv-i18n')
|
||||
|
||||
t.test('Format Baseline test', async (t) => {
|
||||
const app = buildApplication({
|
||||
customOptions: {
|
||||
validateFormats: false
|
||||
}
|
||||
})
|
||||
|
||||
const res = await app.inject({
|
||||
url: '/hello',
|
||||
headers: {
|
||||
'x-foo': 'hello',
|
||||
'x-date': 'not a date',
|
||||
'x-email': 'not an email'
|
||||
},
|
||||
query: {
|
||||
foo: 'hello',
|
||||
date: 'not a date',
|
||||
email: 'not an email'
|
||||
}
|
||||
})
|
||||
t.equal(res.statusCode, 200, 'format validation does not apply as configured')
|
||||
t.equal(res.payload, 'hello')
|
||||
})
|
||||
|
||||
t.test('Custom Format plugin loading test', (t) => {
|
||||
t.plan(6)
|
||||
const app = buildApplication({
|
||||
customOptions: {
|
||||
validateFormats: true
|
||||
},
|
||||
plugins: [[ajvFormats, { mode: 'fast' }]]
|
||||
})
|
||||
|
||||
app.inject('/hello', (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400, 'format validation applies')
|
||||
})
|
||||
|
||||
app.inject('/2ad0612c-7578-4b18-9a6f-579863f40e0b', (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400, 'format validation applies')
|
||||
})
|
||||
|
||||
app.inject({
|
||||
url: '/2ad0612c-7578-4b18-9a6f-579863f40e0b',
|
||||
headers: {
|
||||
'x-foo': 'hello',
|
||||
'x-date': new Date().toISOString(),
|
||||
'x-email': 'foo@bar.baz'
|
||||
},
|
||||
query: {
|
||||
foo: 'hello',
|
||||
date: new Date().toISOString(),
|
||||
email: 'foo@bar.baz'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 200)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('Format plugin set by default test', (t) => {
|
||||
t.plan(6)
|
||||
const app = buildApplication({})
|
||||
|
||||
app.inject('/hello', (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400, 'format validation applies')
|
||||
})
|
||||
|
||||
app.inject('/2ad0612c-7578-4b18-9a6f-579863f40e0b', (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400, 'format validation applies')
|
||||
})
|
||||
|
||||
app.inject({
|
||||
url: '/2ad0612c-7578-4b18-9a6f-579863f40e0b',
|
||||
headers: {
|
||||
'x-foo': 'hello',
|
||||
'x-date': new Date().toISOString(),
|
||||
'x-email': 'foo@bar.baz'
|
||||
},
|
||||
query: {
|
||||
foo: 'hello',
|
||||
date: new Date().toISOString(),
|
||||
email: 'foo@bar.baz'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 200)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('Custom error messages', (t) => {
|
||||
t.plan(9)
|
||||
|
||||
const app = buildApplication({
|
||||
customOptions: {
|
||||
removeAdditional: false,
|
||||
allErrors: true
|
||||
},
|
||||
plugins: [ajvFormats, ajvErrors]
|
||||
})
|
||||
|
||||
const errorMessage = {
|
||||
required: 'custom miss',
|
||||
type: 'custom type', // will not replace internal "type" error for the property "foo"
|
||||
_: 'custom type', // this prop will do it
|
||||
additionalProperties: 'custom too many params'
|
||||
}
|
||||
|
||||
app.post('/', {
|
||||
handler: () => { t.fail('dont call me') },
|
||||
schema: {
|
||||
body: {
|
||||
type: 'object',
|
||||
required: ['foo'],
|
||||
properties: {
|
||||
foo: { type: 'integer' }
|
||||
},
|
||||
additionalProperties: false,
|
||||
errorMessage
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.inject({
|
||||
url: '/',
|
||||
method: 'post',
|
||||
payload: {}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400)
|
||||
t.match(res.json().message, errorMessage.required)
|
||||
})
|
||||
|
||||
app.inject({
|
||||
url: '/',
|
||||
method: 'post',
|
||||
payload: { foo: 'not a number' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400)
|
||||
t.match(res.json().message, errorMessage.type)
|
||||
})
|
||||
|
||||
app.inject({
|
||||
url: '/',
|
||||
method: 'post',
|
||||
payload: { foo: 3, bar: 'ops' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400)
|
||||
t.match(res.json().message, errorMessage.additionalProperties)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('Custom i18n error messages', (t) => {
|
||||
t.plan(3)
|
||||
|
||||
const app = buildApplication({
|
||||
customOptions: {
|
||||
allErrors: true,
|
||||
messages: false
|
||||
},
|
||||
plugins: [ajvFormats]
|
||||
})
|
||||
|
||||
app.post('/', {
|
||||
handler: () => { t.fail('dont call me') },
|
||||
schema: {
|
||||
body: {
|
||||
type: 'object',
|
||||
required: ['foo'],
|
||||
properties: {
|
||||
foo: { type: 'integer' }
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.setErrorHandler((error, request, reply) => {
|
||||
t.pass('Error handler executed')
|
||||
if (error.validation) {
|
||||
localize.ru(error.validation)
|
||||
reply.status(400).send(error.validation)
|
||||
return
|
||||
}
|
||||
t.fail('not other errors')
|
||||
})
|
||||
|
||||
app.inject({
|
||||
method: 'POST',
|
||||
url: '/',
|
||||
payload: {
|
||||
foo: 'string'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.json()[0].message, 'должно быть integer')
|
||||
})
|
||||
})
|
||||
|
||||
function buildApplication (ajvOptions) {
|
||||
const factory = AjvCompiler()
|
||||
|
||||
const app = fastify({
|
||||
ajv: ajvOptions,
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factory
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.get('/:id', {
|
||||
schema: {
|
||||
headers: {
|
||||
type: 'object',
|
||||
required: [
|
||||
'x-foo',
|
||||
'x-date',
|
||||
'x-email'
|
||||
],
|
||||
properties: {
|
||||
'x-foo': { type: 'string' },
|
||||
'x-date': { type: 'string', format: 'date-time' },
|
||||
'x-email': { type: 'string', format: 'email' }
|
||||
}
|
||||
},
|
||||
query: {
|
||||
type: 'object',
|
||||
required: [
|
||||
'foo',
|
||||
'date',
|
||||
'email'
|
||||
],
|
||||
properties: {
|
||||
foo: { type: 'string' },
|
||||
date: { type: 'string', format: 'date-time' },
|
||||
email: { type: 'string', format: 'email' }
|
||||
}
|
||||
},
|
||||
params: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', format: 'uuid' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async () => 'hello')
|
||||
|
||||
return app
|
||||
}
|
||||
279
backend/node_modules/@fastify/ajv-compiler/test/serialization.test.js
generated
vendored
Normal file
279
backend/node_modules/@fastify/ajv-compiler/test/serialization.test.js
generated
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
'use strict'
|
||||
|
||||
const t = require('tap')
|
||||
const fastify = require('fastify')
|
||||
const AjvCompiler = require('../index')
|
||||
|
||||
const jtdSchema = {
|
||||
discriminator: 'version',
|
||||
mapping: {
|
||||
1: {
|
||||
properties: {
|
||||
foo: { type: 'uint8' }
|
||||
}
|
||||
},
|
||||
2: {
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const externalSchemas1 = Object.freeze({})
|
||||
const externalSchemas2 = Object.freeze({
|
||||
foo: {
|
||||
definitions: {
|
||||
coordinates: {
|
||||
properties: {
|
||||
lat: { type: 'float32' },
|
||||
lng: { type: 'float32' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const fastifyAjvOptionsDefault = Object.freeze({
|
||||
customOptions: {}
|
||||
})
|
||||
|
||||
t.test('basic serializer usage', t => {
|
||||
t.plan(4)
|
||||
const factory = AjvCompiler({ jtdSerializer: true })
|
||||
const compiler = factory(externalSchemas1, fastifyAjvOptionsDefault)
|
||||
const serializeFunc = compiler({ schema: jtdSchema })
|
||||
t.equal(serializeFunc({ version: '1', foo: 42 }), '{"version":"1","foo":42}')
|
||||
t.equal(serializeFunc({ version: '2', foo: 'hello' }), '{"version":"2","foo":"hello"}')
|
||||
t.equal(serializeFunc({ version: '3', foo: 'hello' }), '{"version":"3"}')
|
||||
t.equal(serializeFunc({ version: '2', foo: ['not', 1, { string: 'string' }] }), '{"version":"2","foo":"not,1,[object Object]"}')
|
||||
})
|
||||
|
||||
t.test('external schemas are ignored', t => {
|
||||
t.plan(1)
|
||||
const factory = AjvCompiler({ jtdSerializer: true })
|
||||
const compiler = factory(externalSchemas2, fastifyAjvOptionsDefault)
|
||||
const serializeFunc = compiler({
|
||||
schema: {
|
||||
definitions: {
|
||||
coordinates: {
|
||||
properties: {
|
||||
lat: { type: 'float32' },
|
||||
lng: { type: 'float32' }
|
||||
}
|
||||
}
|
||||
},
|
||||
properties: {
|
||||
userLoc: { ref: 'coordinates' },
|
||||
serverLoc: { ref: 'coordinates' }
|
||||
}
|
||||
}
|
||||
})
|
||||
t.equal(serializeFunc(
|
||||
{ userLoc: { lat: 50, lng: -90 }, serverLoc: { lat: -15, lng: 50 } }),
|
||||
'{"userLoc":{"lat":50,"lng":-90},"serverLoc":{"lat":-15,"lng":50}}'
|
||||
)
|
||||
})
|
||||
|
||||
t.test('fastify integration within JTD serializer', async t => {
|
||||
const factoryValidator = AjvCompiler()
|
||||
const factorySerializer = AjvCompiler({ jtdSerializer: true })
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
ajv: {
|
||||
customOptions: { },
|
||||
mode: 'JTD'
|
||||
},
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factoryValidator,
|
||||
buildSerializer: factorySerializer
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/', {
|
||||
schema: {
|
||||
body: jtdSchema,
|
||||
response: {
|
||||
200: {
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
createdAt: { type: 'timestamp' },
|
||||
karma: { type: 'int32' },
|
||||
isAdmin: { type: 'boolean' }
|
||||
}
|
||||
},
|
||||
400: jtdSchema
|
||||
}
|
||||
}
|
||||
}, async () => {
|
||||
return {
|
||||
id: '123',
|
||||
createdAt: new Date('1999-01-31T23:00:00.000Z'),
|
||||
karma: 42,
|
||||
isAdmin: true,
|
||||
remove: 'me'
|
||||
}
|
||||
})
|
||||
|
||||
{
|
||||
const res = await app.inject({
|
||||
url: '/',
|
||||
method: 'POST',
|
||||
payload: {
|
||||
version: '1',
|
||||
foo: 'not a number'
|
||||
}
|
||||
})
|
||||
|
||||
t.equal(res.statusCode, 400)
|
||||
t.same(res.json(), { version: 'undefined' })
|
||||
}
|
||||
|
||||
{
|
||||
const res = await app.inject({
|
||||
url: '/',
|
||||
method: 'POST',
|
||||
payload: {
|
||||
version: '1',
|
||||
foo: 32
|
||||
}
|
||||
})
|
||||
|
||||
t.equal(res.statusCode, 200)
|
||||
t.same(res.json(), {
|
||||
id: '123',
|
||||
createdAt: '1999-01-31T23:00:00.000Z',
|
||||
karma: 42,
|
||||
isAdmin: true
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.test('fastify integration and cached serializer', async t => {
|
||||
const factoryValidator = AjvCompiler()
|
||||
const factorySerializer = AjvCompiler({ jtdSerializer: true })
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
ajv: {
|
||||
customOptions: { },
|
||||
mode: 'JTD'
|
||||
},
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factoryValidator,
|
||||
buildSerializer: factorySerializer
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.register(async function plugin (app, opts) {
|
||||
app.post('/', {
|
||||
schema: {
|
||||
body: jtdSchema,
|
||||
response: {
|
||||
200: {
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
createdAt: { type: 'timestamp' },
|
||||
karma: { type: 'int32' },
|
||||
isAdmin: { type: 'boolean' }
|
||||
}
|
||||
},
|
||||
400: jtdSchema
|
||||
}
|
||||
}
|
||||
}, async () => {
|
||||
return {
|
||||
id: '123',
|
||||
createdAt: new Date('1999-01-31T23:00:00.000Z'),
|
||||
karma: 42,
|
||||
isAdmin: true,
|
||||
remove: 'me'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
app.register(async function plugin (app, opts) {
|
||||
app.post('/two', {
|
||||
schema: {
|
||||
body: jtdSchema,
|
||||
response: {
|
||||
400: jtdSchema
|
||||
}
|
||||
}
|
||||
}, () => {})
|
||||
})
|
||||
|
||||
{
|
||||
const res = await app.inject({
|
||||
url: '/',
|
||||
method: 'POST',
|
||||
payload: {
|
||||
version: '1',
|
||||
foo: 'not a number'
|
||||
}
|
||||
})
|
||||
|
||||
t.equal(res.statusCode, 400)
|
||||
t.same(res.json(), { version: 'undefined' })
|
||||
}
|
||||
|
||||
{
|
||||
const res = await app.inject({
|
||||
url: '/',
|
||||
method: 'POST',
|
||||
payload: {
|
||||
version: '1',
|
||||
foo: 32
|
||||
}
|
||||
})
|
||||
|
||||
t.equal(res.statusCode, 200)
|
||||
t.same(res.json(), {
|
||||
id: '123',
|
||||
createdAt: '1999-01-31T23:00:00.000Z',
|
||||
karma: 42,
|
||||
isAdmin: true
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.test('fastify integration within JTD serializer and custom options', async t => {
|
||||
const factorySerializer = AjvCompiler({ jtdSerializer: true })
|
||||
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
serializerOpts: {
|
||||
allErrors: true,
|
||||
logger: 'wrong-value'
|
||||
},
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildSerializer: factorySerializer
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/', {
|
||||
schema: {
|
||||
response: {
|
||||
200: {
|
||||
properties: {
|
||||
test: { type: 'boolean' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, async () => { })
|
||||
|
||||
try {
|
||||
await app.ready()
|
||||
t.fail('should throw')
|
||||
} catch (error) {
|
||||
t.equal(error.message, 'logger must implement log, warn and error methods', 'the wrong setting is forwarded to ajv/jtd')
|
||||
}
|
||||
})
|
||||
203
backend/node_modules/@fastify/ajv-compiler/test/standalone.test.js
generated
vendored
Normal file
203
backend/node_modules/@fastify/ajv-compiler/test/standalone.test.js
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
'use strict'
|
||||
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
const t = require('tap')
|
||||
const fastify = require('fastify')
|
||||
const sanitize = require('sanitize-filename')
|
||||
|
||||
const { StandaloneValidator: AjvStandaloneValidator } = require('../')
|
||||
|
||||
function generateFileName (routeOpts) {
|
||||
return `/ajv-generated-${sanitize(routeOpts.schema.$id)}-${routeOpts.method}-${routeOpts.httpPart}-${sanitize(routeOpts.url)}.js`
|
||||
}
|
||||
|
||||
const generatedFileNames = []
|
||||
|
||||
t.test('standalone', t => {
|
||||
t.plan(4)
|
||||
|
||||
t.teardown(async () => {
|
||||
for (const fileName of generatedFileNames) {
|
||||
await fs.promises.unlink(path.join(__dirname, fileName))
|
||||
}
|
||||
})
|
||||
|
||||
t.test('errors', t => {
|
||||
t.plan(2)
|
||||
t.throws(() => {
|
||||
AjvStandaloneValidator()
|
||||
}, 'missing restoreFunction')
|
||||
t.throws(() => {
|
||||
AjvStandaloneValidator({ readMode: false })
|
||||
}, 'missing storeFunction')
|
||||
})
|
||||
|
||||
t.test('generate standalone code', t => {
|
||||
t.plan(5)
|
||||
|
||||
const base = {
|
||||
$id: 'urn:schema:base',
|
||||
definitions: {
|
||||
hello: { type: 'string' }
|
||||
},
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: '#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const refSchema = {
|
||||
$id: 'urn:schema:ref',
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: 'urn:schema:base#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const endpointSchema = {
|
||||
schema: {
|
||||
$id: 'urn:schema:endpoint',
|
||||
$ref: 'urn:schema:ref'
|
||||
}
|
||||
}
|
||||
|
||||
const schemaMap = {
|
||||
[base.$id]: base,
|
||||
[refSchema.$id]: refSchema
|
||||
}
|
||||
|
||||
const factory = AjvStandaloneValidator({
|
||||
readMode: false,
|
||||
storeFunction (routeOpts, schemaValidationCode) {
|
||||
t.same(routeOpts, endpointSchema)
|
||||
t.type(schemaValidationCode, 'string')
|
||||
fs.writeFileSync(path.join(__dirname, '/ajv-generated.js'), schemaValidationCode)
|
||||
generatedFileNames.push('/ajv-generated.js')
|
||||
t.pass('stored the validation function')
|
||||
}
|
||||
})
|
||||
|
||||
const compiler = factory(schemaMap)
|
||||
compiler(endpointSchema)
|
||||
t.pass('compiled the endpoint schema')
|
||||
|
||||
t.test('usage standalone code', t => {
|
||||
t.plan(3)
|
||||
const standaloneValidate = require('./ajv-generated')
|
||||
|
||||
const valid = standaloneValidate({ hello: 'world' })
|
||||
t.ok(valid)
|
||||
|
||||
const invalid = standaloneValidate({ hello: [] })
|
||||
t.notOk(invalid)
|
||||
|
||||
t.ok(standaloneValidate)
|
||||
})
|
||||
})
|
||||
|
||||
t.test('fastify integration - writeMode', async t => {
|
||||
t.plan(6)
|
||||
|
||||
const factory = AjvStandaloneValidator({
|
||||
readMode: false,
|
||||
storeFunction (routeOpts, schemaValidationCode) {
|
||||
const fileName = generateFileName(routeOpts)
|
||||
t.ok(routeOpts)
|
||||
fs.writeFileSync(path.join(__dirname, fileName), schemaValidationCode)
|
||||
t.pass('stored the validation function')
|
||||
generatedFileNames.push(fileName)
|
||||
},
|
||||
restoreFunction () {
|
||||
t.fail('write mode ON')
|
||||
}
|
||||
})
|
||||
|
||||
const app = buildApp(factory)
|
||||
await app.ready()
|
||||
})
|
||||
|
||||
t.test('fastify integration - readMode', async t => {
|
||||
t.plan(6)
|
||||
|
||||
const factory = AjvStandaloneValidator({
|
||||
readMode: true,
|
||||
storeFunction () {
|
||||
t.fail('read mode ON')
|
||||
},
|
||||
restoreFunction (routeOpts) {
|
||||
t.pass('restore the validation function')
|
||||
const fileName = generateFileName(routeOpts)
|
||||
return require(path.join(__dirname, fileName))
|
||||
}
|
||||
})
|
||||
|
||||
const app = buildApp(factory)
|
||||
await app.ready()
|
||||
|
||||
let res = await app.inject({
|
||||
url: '/foo',
|
||||
method: 'POST',
|
||||
payload: { hello: [] }
|
||||
})
|
||||
t.equal(res.statusCode, 400)
|
||||
|
||||
res = await app.inject({
|
||||
url: '/bar?lang=invalid',
|
||||
method: 'GET'
|
||||
})
|
||||
t.equal(res.statusCode, 400)
|
||||
|
||||
res = await app.inject({
|
||||
url: '/bar?lang=it',
|
||||
method: 'GET'
|
||||
})
|
||||
t.equal(res.statusCode, 200)
|
||||
})
|
||||
|
||||
function buildApp (factory) {
|
||||
const app = fastify({
|
||||
jsonShorthand: false,
|
||||
schemaController: {
|
||||
compilersFactory: {
|
||||
buildValidator: factory
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.addSchema({
|
||||
$id: 'urn:schema:foo',
|
||||
type: 'object',
|
||||
properties: {
|
||||
name: { type: 'string' },
|
||||
id: { type: 'integer' }
|
||||
}
|
||||
})
|
||||
|
||||
app.post('/foo', {
|
||||
schema: {
|
||||
body: {
|
||||
$id: 'urn:schema:body',
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: 'urn:schema:foo#/properties/name' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}, () => { return 'ok' })
|
||||
|
||||
app.get('/bar', {
|
||||
schema: {
|
||||
query: {
|
||||
$id: 'urn:schema:query',
|
||||
type: 'object',
|
||||
properties: {
|
||||
lang: { type: 'string', enum: ['it', 'en'] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}, () => { return 'ok' })
|
||||
|
||||
return app
|
||||
}
|
||||
})
|
||||
72
backend/node_modules/@fastify/ajv-compiler/types/index.d.ts
generated
vendored
Normal file
72
backend/node_modules/@fastify/ajv-compiler/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
import { AnySchema, default as _ajv, Options as AjvOptions, ValidateFunction } from "ajv";
|
||||
import { default as AjvJTD, JTDOptions } from "ajv/dist/jtd";
|
||||
import type { Options, ErrorObject } from "ajv";
|
||||
import { AnyValidateFunction } from "ajv/dist/core";
|
||||
|
||||
type Ajv = _ajv;
|
||||
type AjvSerializerGenerator = typeof AjvCompiler
|
||||
|
||||
type AjvJTDCompile = AjvJTD['compileSerializer']
|
||||
type AjvCompile = (schema: AnySchema, _meta?: boolean) => AnyValidateFunction
|
||||
|
||||
declare namespace AjvCompiler {
|
||||
export type { Options, ErrorObject }
|
||||
export { Ajv };
|
||||
|
||||
export type BuildSerializerFromPool = typeof buildSerializerFromPool
|
||||
|
||||
export type BuildCompilerFromPool = typeof buildCompilerFromPool
|
||||
|
||||
export const AjvReference: Symbol
|
||||
|
||||
export enum HttpParts {
|
||||
Body = "body",
|
||||
Headers = "headers",
|
||||
Params = "params",
|
||||
Query = "querystring",
|
||||
}
|
||||
|
||||
export type RouteDefinition = {
|
||||
method: string,
|
||||
url: string,
|
||||
httpPart: HttpParts,
|
||||
schema?: unknown,
|
||||
}
|
||||
|
||||
export type StandaloneRestoreFunction = (opts: RouteDefinition) => ValidateFunction
|
||||
|
||||
export type StandaloneStoreFunction = (opts: RouteDefinition, schemaValidationCode: string) => void
|
||||
|
||||
export type StandaloneOptionsReadModeOn = {
|
||||
readMode: true;
|
||||
restoreFunction?: StandaloneRestoreFunction
|
||||
}
|
||||
|
||||
export type StandaloneOptionsReadModeOff = {
|
||||
readMode?: false | undefined;
|
||||
storeFunction?: StandaloneStoreFunction;
|
||||
}
|
||||
|
||||
export type StandaloneOptions = StandaloneOptionsReadModeOn | StandaloneOptionsReadModeOff
|
||||
|
||||
export type ValidatorFactory = BuildCompilerFromPool | BuildSerializerFromPool
|
||||
|
||||
export type ValidatorCompiler = ReturnType<ValidatorFactory>
|
||||
|
||||
export { StandaloneValidator }
|
||||
|
||||
export const AjvCompiler: AjvSerializerGenerator
|
||||
export { AjvCompiler as default }
|
||||
}
|
||||
|
||||
declare function buildCompilerFromPool(externalSchemas: { [key: string]: AnySchema | AnySchema[] }, options?: { mode: 'JTD'; customOptions?: JTDOptions; onCreate?: (ajvInstance: Ajv) => void }): AjvCompile
|
||||
declare function buildCompilerFromPool(externalSchemas: { [key: string]: AnySchema | AnySchema[] }, options?: { mode?: never; customOptions?: AjvOptions; onCreate?: (ajvInstance: Ajv) => void }): AjvCompile
|
||||
|
||||
declare function buildSerializerFromPool(externalSchemas: any, serializerOpts?: { mode?: never; } & JTDOptions): AjvJTDCompile
|
||||
|
||||
declare function AjvCompiler(opts: { jtdSerializer: true }): AjvCompiler.BuildSerializerFromPool
|
||||
declare function AjvCompiler(opts?: { jtdSerializer?: false }): AjvCompiler.BuildCompilerFromPool
|
||||
|
||||
declare function StandaloneValidator(options: AjvCompiler.StandaloneOptions): AjvCompiler.BuildCompilerFromPool;
|
||||
|
||||
export = AjvCompiler
|
||||
227
backend/node_modules/@fastify/ajv-compiler/types/index.test-d.ts
generated
vendored
Normal file
227
backend/node_modules/@fastify/ajv-compiler/types/index.test-d.ts
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
import { AnySchemaObject, ValidateFunction } from "ajv";
|
||||
import { AnyValidateFunction } from "ajv/dist/core";
|
||||
import { expectAssignable, expectType } from "tsd";
|
||||
import AjvCompiler, { AjvReference, ValidatorFactory, StandaloneValidator, RouteDefinition, ErrorObject, BuildCompilerFromPool, BuildSerializerFromPool, ValidatorCompiler } from "..";
|
||||
|
||||
{
|
||||
const compiler = AjvCompiler({});
|
||||
expectType<BuildCompilerFromPool>(compiler);
|
||||
}
|
||||
{
|
||||
const compiler = AjvCompiler();
|
||||
expectType<BuildCompilerFromPool>(compiler);
|
||||
}
|
||||
{
|
||||
const compiler = AjvCompiler({ jtdSerializer: false});
|
||||
expectType<BuildCompilerFromPool>(compiler);
|
||||
}
|
||||
|
||||
{
|
||||
const factory = AjvCompiler({ jtdSerializer: false });
|
||||
expectType<BuildCompilerFromPool>(factory);
|
||||
factory({}, {
|
||||
onCreate(ajv) {
|
||||
expectType<import("ajv").default>(ajv)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const compiler = AjvCompiler({ jtdSerializer: true});
|
||||
expectType<BuildSerializerFromPool>(compiler);
|
||||
}
|
||||
const reader = StandaloneValidator({
|
||||
readMode: true,
|
||||
restoreFunction: (route: RouteDefinition) => {
|
||||
expectAssignable<RouteDefinition>(route)
|
||||
return {} as ValidateFunction
|
||||
},
|
||||
});
|
||||
expectAssignable<ValidatorFactory>(reader);
|
||||
|
||||
const writer = StandaloneValidator({
|
||||
readMode: false,
|
||||
storeFunction: (route: RouteDefinition, code: string) => {
|
||||
expectAssignable<RouteDefinition>(route)
|
||||
expectAssignable<string>(code)
|
||||
},
|
||||
});
|
||||
expectAssignable<ValidatorFactory>(writer);
|
||||
|
||||
expectType<unknown>(({} as ErrorObject).data)
|
||||
expectType<string>(({} as ErrorObject).instancePath)
|
||||
expectType<string>(({} as ErrorObject).keyword)
|
||||
expectType<string | undefined>(({} as ErrorObject).message)
|
||||
expectType<Record<string, any>>(({} as ErrorObject).params)
|
||||
expectType<AnySchemaObject | undefined>(({} as ErrorObject).parentSchema)
|
||||
expectType<string | undefined>(({} as ErrorObject).propertyName)
|
||||
expectType<unknown>(({} as ErrorObject).schema)
|
||||
expectType<string>(({} as ErrorObject).schemaPath)
|
||||
|
||||
expectType<Symbol>(AjvReference)
|
||||
|
||||
{
|
||||
const jtdSchema = {
|
||||
discriminator: 'version',
|
||||
mapping: {
|
||||
1: {
|
||||
properties: {
|
||||
foo: { type: 'uint8' }
|
||||
}
|
||||
},
|
||||
2: {
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const externalSchemas1 = {
|
||||
foo: {
|
||||
definitions: {
|
||||
coordinates: {
|
||||
properties: {
|
||||
lat: { type: 'float32' },
|
||||
lng: { type: 'float32' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const factory = AjvCompiler({ jtdSerializer: true })
|
||||
expectType<BuildSerializerFromPool>(factory)
|
||||
const compiler = factory(externalSchemas1, {})
|
||||
expectAssignable<Function>(compiler)
|
||||
const serializeFunc = compiler({ schema: jtdSchema })
|
||||
expectType<(data: unknown) => string>(serializeFunc)
|
||||
expectType<string>(serializeFunc({ version: '1', foo: 42 }))
|
||||
}
|
||||
// JTD
|
||||
{
|
||||
|
||||
const factory = AjvCompiler()
|
||||
expectType<BuildCompilerFromPool>(factory)
|
||||
|
||||
const jtdSchema = {
|
||||
discriminator: 'version',
|
||||
mapping: {
|
||||
1: {
|
||||
properties: {
|
||||
foo: { type: 'uint8' }
|
||||
}
|
||||
},
|
||||
2: {
|
||||
properties: {
|
||||
foo: { type: 'string' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const compiler = factory({}, {
|
||||
customOptions: {},
|
||||
mode: 'JTD'
|
||||
})
|
||||
expectAssignable<ValidatorCompiler>(compiler)
|
||||
const validatorFunc = compiler({ schema: jtdSchema })
|
||||
expectAssignable<ValidateFunction>(validatorFunc)
|
||||
|
||||
expectType<boolean | Promise<any>>(validatorFunc({
|
||||
version: '2',
|
||||
foo: []
|
||||
}))
|
||||
}
|
||||
|
||||
// generate standalone code
|
||||
{
|
||||
const base = {
|
||||
$id: 'urn:schema:base',
|
||||
definitions: {
|
||||
hello: { type: 'string' }
|
||||
},
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: '#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const refSchema = {
|
||||
$id: 'urn:schema:ref',
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: 'urn:schema:base#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const endpointSchema = {
|
||||
schema: {
|
||||
$id: 'urn:schema:endpoint',
|
||||
$ref: 'urn:schema:ref'
|
||||
}
|
||||
}
|
||||
|
||||
const schemaMap = {
|
||||
[base.$id]: base,
|
||||
[refSchema.$id]: refSchema
|
||||
}
|
||||
|
||||
const factory = StandaloneValidator({
|
||||
readMode: false,
|
||||
storeFunction(routeOpts, schemaValidationCode) {
|
||||
expectType<RouteDefinition>(routeOpts)
|
||||
expectType<string>(schemaValidationCode)
|
||||
}
|
||||
})
|
||||
expectAssignable<ValidatorFactory>(factory)
|
||||
|
||||
const compiler = factory(schemaMap)
|
||||
expectAssignable<ValidatorCompiler>(compiler)
|
||||
expectAssignable<Function>(compiler(endpointSchema))
|
||||
}
|
||||
|
||||
{
|
||||
const base = {
|
||||
$id: 'urn:schema:base',
|
||||
definitions: {
|
||||
hello: { type: 'string' }
|
||||
},
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: '#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const refSchema = {
|
||||
$id: 'urn:schema:ref',
|
||||
type: 'object',
|
||||
properties: {
|
||||
hello: { $ref: 'urn:schema:base#/definitions/hello' }
|
||||
}
|
||||
}
|
||||
|
||||
const endpointSchema = {
|
||||
schema: {
|
||||
$id: 'urn:schema:endpoint',
|
||||
$ref: 'urn:schema:ref'
|
||||
}
|
||||
}
|
||||
|
||||
const schemaMap = {
|
||||
[base.$id]: base,
|
||||
[refSchema.$id]: refSchema
|
||||
}
|
||||
const factory = StandaloneValidator({
|
||||
readMode: true,
|
||||
restoreFunction(routeOpts) {
|
||||
expectType<RouteDefinition>(routeOpts)
|
||||
return {} as ValidateFunction
|
||||
}
|
||||
})
|
||||
expectAssignable<ValidatorFactory>(factory)
|
||||
|
||||
const compiler = factory(schemaMap)
|
||||
expectAssignable<ValidatorCompiler>(compiler)
|
||||
expectType<AnyValidateFunction<any>>(compiler(endpointSchema))
|
||||
}
|
||||
8
backend/node_modules/@fastify/cors/.editorconfig
generated
vendored
Normal file
8
backend/node_modules/@fastify/cors/.editorconfig
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = false
|
||||
insert_final_newline = false
|
||||
5
backend/node_modules/@fastify/cors/.gitattributes
generated
vendored
Normal file
5
backend/node_modules/@fastify/cors/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Set the default behavior, in case people don't have core.autocrlf set
|
||||
* text=auto
|
||||
|
||||
# Require Unix line endings
|
||||
* text eol=lf
|
||||
16
backend/node_modules/@fastify/cors/.github/dependabot.yml
generated
vendored
Normal file
16
backend/node_modules/@fastify/cors/.github/dependabot.yml
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
open-pull-requests-limit: 10
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: tap
|
||||
update-types: ["version-update:semver-major"]
|
||||
21
backend/node_modules/@fastify/cors/.github/stale.yml
generated
vendored
Normal file
21
backend/node_modules/@fastify/cors/.github/stale.yml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 15
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- "discussion"
|
||||
- "feature request"
|
||||
- "bug"
|
||||
- "help wanted"
|
||||
- "plugin suggestion"
|
||||
- "good first issue"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
23
backend/node_modules/@fastify/cors/.github/workflows/ci.yml
generated
vendored
Normal file
23
backend/node_modules/@fastify/cors/.github/workflows/ci.yml
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- next
|
||||
- 'v*'
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'docs/**'
|
||||
- '*.md'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3
|
||||
with:
|
||||
lint: true
|
||||
license-check: true
|
||||
4
backend/node_modules/@fastify/cors/.taprc
generated
vendored
Normal file
4
backend/node_modules/@fastify/cors/.taprc
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
ts: false
|
||||
jsx: false
|
||||
coverage: true
|
||||
flow: true
|
||||
21
backend/node_modules/@fastify/cors/LICENSE
generated
vendored
Normal file
21
backend/node_modules/@fastify/cors/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Fastify
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
169
backend/node_modules/@fastify/cors/README.md
generated
vendored
Normal file
169
backend/node_modules/@fastify/cors/README.md
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
# @fastify/cors
|
||||
|
||||

|
||||
[](https://www.npmjs.com/package/@fastify/cors)
|
||||
[](https://standardjs.com/)
|
||||
|
||||
|
||||
`@fastify/cors` enables the use of [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) in a Fastify application.
|
||||
|
||||
## Install
|
||||
```
|
||||
npm i @fastify/cors
|
||||
```
|
||||
|
||||
### Compatibility
|
||||
|
||||
| Plugin version | Fastify version |
|
||||
| -------------- |---------------- |
|
||||
| `^8.0.0` | `^4.0.0` |
|
||||
| `^7.0.0` | `^3.0.0` |
|
||||
| `^3.0.0` | `^2.0.0` |
|
||||
| `^1.0.0` | `^1.0.0` |
|
||||
|
||||
|
||||
Please note that if a Fastify version is out of support, then so are the corresponding version(s) of this plugin
|
||||
in the table above.
|
||||
See [Fastify's LTS policy](https://github.com/fastify/fastify/blob/main/docs/Reference/LTS.md) for more details.
|
||||
|
||||
## Usage
|
||||
Require `@fastify/cors` and register it as any other plugin, it will add an `onRequest` hook and a [wildcard options route](https://github.com/fastify/fastify/issues/326#issuecomment-411360862).
|
||||
```js
|
||||
import Fastify from 'fastify'
|
||||
import cors from '@fastify/cors'
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(cors, {
|
||||
// put your options here
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 3000 })
|
||||
```
|
||||
You can use it as is without passing any option or you can configure it as explained below.
|
||||
### Options
|
||||
* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. The value of origin could be of different types:
|
||||
- `Boolean` - set `origin` to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), or set it to `false` to disable CORS.
|
||||
- `String` - set `origin` to a specific origin. For example if you set it to `"http://example.com"` only requests from "http://example.com" will be allowed. The special `*` value (default) allows any origin.
|
||||
- `RegExp` - set `origin` to a regular expression pattern that will be used to test the request origin. If it is a match, the request origin will be reflected. For example, the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
|
||||
- `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
|
||||
- `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback as a second (which expects the signature `err [Error | null], origin`), where `origin` is a non-function value of the origin option. *Async-await* and promises are supported as well. The Fastify instance is bound to function call and you may access via `this`. For example:
|
||||
```js
|
||||
origin: (origin, cb) => {
|
||||
const hostname = new URL(origin).hostname
|
||||
if(hostname === "localhost"){
|
||||
// Request from localhost will pass
|
||||
cb(null, true)
|
||||
return
|
||||
}
|
||||
// Generate an error on other origins, disabling access
|
||||
cb(new Error("Not allowed"), false)
|
||||
}
|
||||
```
|
||||
* `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
|
||||
* `hook`: See the section `Custom Fastify hook name` (default: `onRequest`)
|
||||
* `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: `'Content-Type,Authorization'`) or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
|
||||
* `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: `'Content-Range,X-Content-Range'`) or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
|
||||
* `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
|
||||
* `maxAge`: Configures the **Access-Control-Max-Age** CORS header. In seconds. Set to an integer to pass the header, otherwise it is omitted.
|
||||
* `cacheControl`: Configures the **Cache-Control** header for CORS preflight responses. Set to an integer to pass the header as `Cache-Control: max-age=${cacheControl}`, or set to a string to pass the header as `Cache-Control: ${cacheControl}` (fully define the header value), otherwise the header is omitted.
|
||||
* `preflightContinue`: Pass the CORS preflight response to the route handler (default: `false`).
|
||||
* `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
|
||||
* `preflight`: if needed you can entirely disable preflight by passing `false` here (default: `true`).
|
||||
* `strictPreflight`: Enforces strict requirement of the CORS preflight request headers (**Access-Control-Request-Method** and **Origin**) as defined by the [W3C CORS specification](https://www.w3.org/TR/2020/SPSD-cors-20200602/#resource-preflight-requests) (the current [fetch living specification](https://fetch.spec.whatwg.org/) does not define server behavior for missing headers). Preflight requests without the required headers will result in 400 errors when set to `true` (default: `true`).
|
||||
* `hideOptionsRoute`: hide options route from the documentation built using [@fastify/swagger](https://github.com/fastify/fastify-swagger) (default: `true`).
|
||||
|
||||
### Configuring CORS Asynchronously
|
||||
|
||||
```js
|
||||
const fastify = require('fastify')()
|
||||
|
||||
fastify.register(require('@fastify/cors'), (instance) => {
|
||||
return (req, callback) => {
|
||||
const corsOptions = {
|
||||
// This is NOT recommended for production as it enables reflection exploits
|
||||
origin: true
|
||||
};
|
||||
|
||||
// do not include CORS headers for requests from localhost
|
||||
if (/^localhost$/m.test(req.headers.origin)) {
|
||||
corsOptions.origin = false
|
||||
}
|
||||
|
||||
// callback expects two parameters: error and options
|
||||
callback(null, corsOptions)
|
||||
}
|
||||
})
|
||||
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
})
|
||||
|
||||
fastify.listen({ port: 3000 })
|
||||
```
|
||||
|
||||
### Custom Fastify hook name
|
||||
|
||||
By default, `@fastify/cors` adds a `onRequest` hook where the validation and header injection are executed. This can be customized by passing `hook` in the options. Valid values are `onRequest`, `preParsing`, `preValidation`, `preHandler`, `preSerialization`, and `onSend`.
|
||||
|
||||
```js
|
||||
import Fastify from 'fastify'
|
||||
import cors from '@fastify/cors'
|
||||
|
||||
const fastify = Fastify()
|
||||
await fastify.register(cors, {
|
||||
hook: 'preHandler',
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
|
||||
await fastify.listen({ port: 3000 })
|
||||
```
|
||||
|
||||
When configuring CORS asynchronously, an object with `delegator` key is expected:
|
||||
|
||||
```js
|
||||
const fastify = require('fastify')()
|
||||
|
||||
fastify.register(require('@fastify/cors'), {
|
||||
hook: 'preHandler',
|
||||
delegator: (req, callback) => {
|
||||
const corsOptions = {
|
||||
// This is NOT recommended for production as it enables reflection exploits
|
||||
origin: true
|
||||
};
|
||||
|
||||
// do not include CORS headers for requests from localhost
|
||||
if (/^localhost$/m.test(req.headers.origin)) {
|
||||
corsOptions.origin = false
|
||||
}
|
||||
|
||||
// callback expects two parameters: error and options
|
||||
callback(null, corsOptions)
|
||||
},
|
||||
})
|
||||
|
||||
fastify.register(async function (fastify) {
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ hello: 'world' })
|
||||
})
|
||||
})
|
||||
|
||||
fastify.listen({ port: 3000 })
|
||||
```
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
The code is a port for Fastify of [`expressjs/cors`](https://github.com/expressjs/cors).
|
||||
|
||||
## License
|
||||
|
||||
Licensed under [MIT](./LICENSE).<br/>
|
||||
[`expressjs/cors` license](https://github.com/expressjs/cors/blob/master/LICENSE)
|
||||
17
backend/node_modules/@fastify/cors/bench.js
generated
vendored
Normal file
17
backend/node_modules/@fastify/cors/bench.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
const fastify = require('fastify')()
|
||||
|
||||
fastify.register((instance, opts, next) => {
|
||||
instance.register(require('./index'))
|
||||
instance.get('/fastify', (req, reply) => reply.send('ok'))
|
||||
next()
|
||||
})
|
||||
|
||||
fastify.register((instance, opts, next) => {
|
||||
instance.use(require('cors')())
|
||||
instance.get('/express', (req, reply) => reply.send('ok'))
|
||||
next()
|
||||
})
|
||||
|
||||
fastify.listen({ port: 3000 })
|
||||
15
backend/node_modules/@fastify/cors/benchmark/package.json
generated
vendored
Normal file
15
backend/node_modules/@fastify/cors/benchmark/package.json
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "benchmark",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "vary.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"vary": "^1.1.2"
|
||||
}
|
||||
}
|
||||
34
backend/node_modules/@fastify/cors/benchmark/vary.js
generated
vendored
Normal file
34
backend/node_modules/@fastify/cors/benchmark/vary.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
'use strict'
|
||||
|
||||
const benchmark = require('benchmark')
|
||||
const vary = require('vary')
|
||||
const createAddFieldnameToVary = require('../vary').createAddFieldnameToVary
|
||||
|
||||
const replyMock = (header) => ({
|
||||
getHeader () { return header },
|
||||
setHeader () { },
|
||||
header () { }
|
||||
})
|
||||
|
||||
const addAcceptToVary = createAddFieldnameToVary('Accept')
|
||||
const addWildcardToVary = createAddFieldnameToVary('*')
|
||||
const addAcceptEncodingToVary = createAddFieldnameToVary('Accept-Encoding')
|
||||
const addXFooToVary = createAddFieldnameToVary('X-Foo')
|
||||
|
||||
new benchmark.Suite()
|
||||
.add('vary - field to undefined', function () { vary(replyMock(undefined), 'Accept-Encoding') }, { minSamples: 100 })
|
||||
.add('vary - field to *', function () { vary(replyMock('*'), 'Accept-Encoding') }, { minSamples: 100 })
|
||||
.add('vary - * to field', function () { vary(replyMock('Accept-Encoding'), '*') }, { minSamples: 100 })
|
||||
.add('vary - field to empty', function () { vary(replyMock(''), 'Accept-Encoding') }, { minSamples: 100 })
|
||||
.add('vary - fields string to empty', function () { vary(replyMock(''), 'Accept') }, { minSamples: 100 })
|
||||
.add('vary - field to fields', function () { vary(replyMock('Accept, Accept-Encoding, Accept-Language'), 'X-Foo') }, { minSamples: 100 })
|
||||
|
||||
.add('cors - field to undefined', function () { addAcceptEncodingToVary(replyMock(undefined)) }, { minSamples: 100 })
|
||||
.add('cors - field to *', function () { addAcceptEncodingToVary(replyMock('*')) }, { minSamples: 100 })
|
||||
.add('cors - * to field', function () { addWildcardToVary(replyMock('Accept-Encoding')) }, { minSamples: 100 })
|
||||
.add('cors - field to empty', function () { addAcceptEncodingToVary(replyMock('')) }, { minSamples: 100 })
|
||||
.add('cors - fields string to empty', function () { addAcceptToVary(replyMock('')) }, { minSamples: 100 })
|
||||
.add('cors - field to fields', function () { addXFooToVary(replyMock('Accept, Accept-Encoding, Accept-Language')) }, { minSamples: 100 })
|
||||
|
||||
.on('cycle', function onCycle (event) { console.log(String(event.target)) })
|
||||
.run({ async: false })
|
||||
307
backend/node_modules/@fastify/cors/index.js
generated
vendored
Normal file
307
backend/node_modules/@fastify/cors/index.js
generated
vendored
Normal file
@@ -0,0 +1,307 @@
|
||||
'use strict'
|
||||
|
||||
const fp = require('fastify-plugin')
|
||||
const {
|
||||
addAccessControlRequestHeadersToVaryHeader,
|
||||
addOriginToVaryHeader
|
||||
} = require('./vary')
|
||||
|
||||
const defaultOptions = {
|
||||
origin: '*',
|
||||
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
hook: 'onRequest',
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 204,
|
||||
credentials: false,
|
||||
exposedHeaders: null,
|
||||
allowedHeaders: null,
|
||||
maxAge: null,
|
||||
preflight: true,
|
||||
strictPreflight: true
|
||||
}
|
||||
|
||||
const validHooks = [
|
||||
'onRequest',
|
||||
'preParsing',
|
||||
'preValidation',
|
||||
'preHandler',
|
||||
'preSerialization',
|
||||
'onSend'
|
||||
]
|
||||
|
||||
const hookWithPayload = [
|
||||
'preSerialization',
|
||||
'preParsing',
|
||||
'onSend'
|
||||
]
|
||||
|
||||
function validateHook (value, next) {
|
||||
if (validHooks.indexOf(value) !== -1) {
|
||||
return
|
||||
}
|
||||
next(new TypeError('@fastify/cors: Invalid hook option provided.'))
|
||||
}
|
||||
|
||||
function fastifyCors (fastify, opts, next) {
|
||||
fastify.decorateRequest('corsPreflightEnabled', false)
|
||||
|
||||
let hideOptionsRoute = true
|
||||
if (typeof opts === 'function') {
|
||||
handleCorsOptionsDelegator(opts, fastify, { hook: defaultOptions.hook }, next)
|
||||
} else if (opts.delegator) {
|
||||
const { delegator, ...options } = opts
|
||||
handleCorsOptionsDelegator(delegator, fastify, options, next)
|
||||
} else {
|
||||
if (opts.hideOptionsRoute !== undefined) hideOptionsRoute = opts.hideOptionsRoute
|
||||
const corsOptions = normalizeCorsOptions(opts)
|
||||
validateHook(corsOptions.hook, next)
|
||||
if (hookWithPayload.indexOf(corsOptions.hook) !== -1) {
|
||||
fastify.addHook(corsOptions.hook, function handleCors (req, reply, payload, next) {
|
||||
addCorsHeadersHandler(fastify, corsOptions, req, reply, next)
|
||||
})
|
||||
} else {
|
||||
fastify.addHook(corsOptions.hook, function handleCors (req, reply, next) {
|
||||
addCorsHeadersHandler(fastify, corsOptions, req, reply, next)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// The preflight reply must occur in the hook. This allows fastify-cors to reply to
|
||||
// preflight requests BEFORE possible authentication plugins. If the preflight reply
|
||||
// occurred in this handler, other plugins may deny the request since the browser will
|
||||
// remove most headers (such as the Authentication header).
|
||||
//
|
||||
// This route simply enables fastify to accept preflight requests.
|
||||
fastify.options('*', { schema: { hide: hideOptionsRoute } }, (req, reply) => {
|
||||
if (!req.corsPreflightEnabled) {
|
||||
// Do not handle preflight requests if the origin option disabled CORS
|
||||
reply.callNotFound()
|
||||
return
|
||||
}
|
||||
|
||||
reply.send()
|
||||
})
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
function handleCorsOptionsDelegator (optionsResolver, fastify, opts, next) {
|
||||
const hook = (opts && opts.hook) || defaultOptions.hook
|
||||
validateHook(hook, next)
|
||||
if (optionsResolver.length === 2) {
|
||||
if (hookWithPayload.indexOf(hook) !== -1) {
|
||||
fastify.addHook(hook, function handleCors (req, reply, payload, next) {
|
||||
handleCorsOptionsCallbackDelegator(optionsResolver, fastify, req, reply, next)
|
||||
})
|
||||
} else {
|
||||
fastify.addHook(hook, function handleCors (req, reply, next) {
|
||||
handleCorsOptionsCallbackDelegator(optionsResolver, fastify, req, reply, next)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (hookWithPayload.indexOf(hook) !== -1) {
|
||||
// handle delegator based on Promise
|
||||
fastify.addHook(hook, function handleCors (req, reply, payload, next) {
|
||||
const ret = optionsResolver(req)
|
||||
if (ret && typeof ret.then === 'function') {
|
||||
ret.then(options => addCorsHeadersHandler(fastify, normalizeCorsOptions(options, true), req, reply, next)).catch(next)
|
||||
return
|
||||
}
|
||||
next(new Error('Invalid CORS origin option'))
|
||||
})
|
||||
} else {
|
||||
// handle delegator based on Promise
|
||||
fastify.addHook(hook, function handleCors (req, reply, next) {
|
||||
const ret = optionsResolver(req)
|
||||
if (ret && typeof ret.then === 'function') {
|
||||
ret.then(options => addCorsHeadersHandler(fastify, normalizeCorsOptions(options, true), req, reply, next)).catch(next)
|
||||
return
|
||||
}
|
||||
next(new Error('Invalid CORS origin option'))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleCorsOptionsCallbackDelegator (optionsResolver, fastify, req, reply, next) {
|
||||
optionsResolver(req, (err, options) => {
|
||||
if (err) {
|
||||
next(err)
|
||||
} else {
|
||||
addCorsHeadersHandler(fastify, normalizeCorsOptions(options, true), req, reply, next)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./types').FastifyCorsOptions} opts
|
||||
*/
|
||||
function normalizeCorsOptions (opts, dynamic) {
|
||||
const corsOptions = { ...defaultOptions, ...opts }
|
||||
if (Array.isArray(opts.origin) && opts.origin.indexOf('*') !== -1) {
|
||||
corsOptions.origin = '*'
|
||||
}
|
||||
if (Number.isInteger(corsOptions.cacheControl)) {
|
||||
// integer numbers are formatted this way
|
||||
corsOptions.cacheControl = `max-age=${corsOptions.cacheControl}`
|
||||
} else if (typeof corsOptions.cacheControl !== 'string') {
|
||||
// strings are applied directly and any other value is ignored
|
||||
corsOptions.cacheControl = null
|
||||
}
|
||||
corsOptions.dynamic = dynamic || false
|
||||
return corsOptions
|
||||
}
|
||||
|
||||
function addCorsHeadersHandler (fastify, options, req, reply, next) {
|
||||
if ((typeof options.origin !== 'string' && options.origin !== false) || options.dynamic) {
|
||||
// Always set Vary header for non-static origin option
|
||||
// https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches
|
||||
addOriginToVaryHeader(reply)
|
||||
}
|
||||
|
||||
const resolveOriginOption = typeof options.origin === 'function' ? resolveOriginWrapper(fastify, options.origin) : (_, cb) => cb(null, options.origin)
|
||||
|
||||
resolveOriginOption(req, (error, resolvedOriginOption) => {
|
||||
if (error !== null) {
|
||||
return next(error)
|
||||
}
|
||||
|
||||
// Disable CORS and preflight if false
|
||||
if (resolvedOriginOption === false) {
|
||||
return next()
|
||||
}
|
||||
|
||||
// Falsy values are invalid
|
||||
if (!resolvedOriginOption) {
|
||||
return next(new Error('Invalid CORS origin option'))
|
||||
}
|
||||
|
||||
addCorsHeaders(req, reply, resolvedOriginOption, options)
|
||||
|
||||
if (req.raw.method === 'OPTIONS' && options.preflight === true) {
|
||||
// Strict mode enforces the required headers for preflight
|
||||
if (options.strictPreflight === true && (!req.headers.origin || !req.headers['access-control-request-method'])) {
|
||||
reply.status(400).type('text/plain').send('Invalid Preflight Request')
|
||||
return
|
||||
}
|
||||
|
||||
req.corsPreflightEnabled = true
|
||||
|
||||
addPreflightHeaders(req, reply, options)
|
||||
|
||||
if (!options.preflightContinue) {
|
||||
// Do not call the hook callback and terminate the request
|
||||
// Safari (and potentially other browsers) need content-length 0,
|
||||
// for 204 or they just hang waiting for a body
|
||||
reply
|
||||
.code(options.optionsSuccessStatus)
|
||||
.header('Content-Length', '0')
|
||||
.send()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return next()
|
||||
})
|
||||
}
|
||||
|
||||
function addCorsHeaders (req, reply, originOption, corsOptions) {
|
||||
const origin = getAccessControlAllowOriginHeader(req.headers.origin, originOption)
|
||||
// In the case of origin not allowed the header is not
|
||||
// written in the response.
|
||||
// https://github.com/fastify/fastify-cors/issues/127
|
||||
if (origin) {
|
||||
reply.header('Access-Control-Allow-Origin', origin)
|
||||
}
|
||||
|
||||
if (corsOptions.credentials) {
|
||||
reply.header('Access-Control-Allow-Credentials', 'true')
|
||||
}
|
||||
|
||||
if (corsOptions.exposedHeaders !== null) {
|
||||
reply.header(
|
||||
'Access-Control-Expose-Headers',
|
||||
Array.isArray(corsOptions.exposedHeaders) ? corsOptions.exposedHeaders.join(', ') : corsOptions.exposedHeaders
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function addPreflightHeaders (req, reply, corsOptions) {
|
||||
reply.header(
|
||||
'Access-Control-Allow-Methods',
|
||||
Array.isArray(corsOptions.methods) ? corsOptions.methods.join(', ') : corsOptions.methods
|
||||
)
|
||||
|
||||
if (corsOptions.allowedHeaders === null) {
|
||||
addAccessControlRequestHeadersToVaryHeader(reply)
|
||||
const reqAllowedHeaders = req.headers['access-control-request-headers']
|
||||
if (reqAllowedHeaders !== undefined) {
|
||||
reply.header('Access-Control-Allow-Headers', reqAllowedHeaders)
|
||||
}
|
||||
} else {
|
||||
reply.header(
|
||||
'Access-Control-Allow-Headers',
|
||||
Array.isArray(corsOptions.allowedHeaders) ? corsOptions.allowedHeaders.join(', ') : corsOptions.allowedHeaders
|
||||
)
|
||||
}
|
||||
|
||||
if (corsOptions.maxAge !== null) {
|
||||
reply.header('Access-Control-Max-Age', String(corsOptions.maxAge))
|
||||
}
|
||||
|
||||
if (corsOptions.cacheControl) {
|
||||
reply.header('Cache-Control', corsOptions.cacheControl)
|
||||
}
|
||||
}
|
||||
|
||||
function resolveOriginWrapper (fastify, origin) {
|
||||
return function (req, cb) {
|
||||
const result = origin.call(fastify, req.headers.origin, cb)
|
||||
|
||||
// Allow for promises
|
||||
if (result && typeof result.then === 'function') {
|
||||
result.then(res => cb(null, res), cb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getAccessControlAllowOriginHeader (reqOrigin, originOption) {
|
||||
if (typeof originOption === 'string') {
|
||||
// fixed or any origin ('*')
|
||||
return originOption
|
||||
}
|
||||
|
||||
// reflect origin
|
||||
return isRequestOriginAllowed(reqOrigin, originOption) ? reqOrigin : false
|
||||
}
|
||||
|
||||
function isRequestOriginAllowed (reqOrigin, allowedOrigin) {
|
||||
if (Array.isArray(allowedOrigin)) {
|
||||
for (let i = 0; i < allowedOrigin.length; ++i) {
|
||||
if (isRequestOriginAllowed(reqOrigin, allowedOrigin[i])) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
} else if (typeof allowedOrigin === 'string') {
|
||||
return reqOrigin === allowedOrigin
|
||||
} else if (allowedOrigin instanceof RegExp) {
|
||||
allowedOrigin.lastIndex = 0
|
||||
return allowedOrigin.test(reqOrigin)
|
||||
} else {
|
||||
return !!allowedOrigin
|
||||
}
|
||||
}
|
||||
|
||||
const _fastifyCors = fp(fastifyCors, {
|
||||
fastify: '4.x',
|
||||
name: '@fastify/cors'
|
||||
})
|
||||
|
||||
/**
|
||||
* These export configurations enable JS and TS developers
|
||||
* to consumer fastify in whatever way best suits their needs.
|
||||
*/
|
||||
module.exports = _fastifyCors
|
||||
module.exports.fastifyCors = _fastifyCors
|
||||
module.exports.default = _fastifyCors
|
||||
59
backend/node_modules/@fastify/cors/package.json
generated
vendored
Normal file
59
backend/node_modules/@fastify/cors/package.json
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "@fastify/cors",
|
||||
"version": "9.0.1",
|
||||
"description": "Fastify CORS",
|
||||
"main": "index.js",
|
||||
"type": "commonjs",
|
||||
"types": "types/index.d.ts",
|
||||
"scripts": {
|
||||
"coverage": "tap --cov --coverage-report=html test",
|
||||
"lint": "standard",
|
||||
"lint:fix": "standard --fix",
|
||||
"test": "npm run test:unit && npm run test:typescript",
|
||||
"test:typescript": "tsd",
|
||||
"test:unit": "tap test/*.test.js"
|
||||
},
|
||||
"keywords": [
|
||||
"fastify",
|
||||
"cors",
|
||||
"headers",
|
||||
"access",
|
||||
"control"
|
||||
],
|
||||
"author": "Tomas Della Vedova - @delvedor (http://delved.org)",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fastify/fastify-cors.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/fastify/fastify-cors/issues"
|
||||
},
|
||||
"homepage": "https://github.com/fastify/fastify-cors#readme",
|
||||
"devDependencies": {
|
||||
"@fastify/pre-commit": "^2.0.2",
|
||||
"@types/node": "^20.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.4.1",
|
||||
"@typescript-eslint/parser": "^6.4.0",
|
||||
"cors": "^2.8.5",
|
||||
"fastify": "^4.0.0-rc.2",
|
||||
"standard": "^17.0.0",
|
||||
"tap": "16.3.9",
|
||||
"tsd": "^0.30.0",
|
||||
"typescript": "^5.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastify-plugin": "^4.0.0",
|
||||
"mnemonist": "0.39.6"
|
||||
},
|
||||
"tsd": {
|
||||
"directory": "test"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
941
backend/node_modules/@fastify/cors/test/cors.test.js
generated
vendored
Normal file
941
backend/node_modules/@fastify/cors/test/cors.test.js
generated
vendored
Normal file
@@ -0,0 +1,941 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const { createReadStream, statSync, readFileSync } = require('node:fs')
|
||||
const Fastify = require('fastify')
|
||||
const cors = require('../')
|
||||
const { resolve } = require('node:path')
|
||||
|
||||
test('Should add cors headers', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should add cors headers when payload is a stream', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors)
|
||||
const filePath = resolve(__dirname, __filename)
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
const stream = createReadStream(filePath)
|
||||
reply
|
||||
.type('application/json')
|
||||
.header('Content-Length', statSync(filePath).size)
|
||||
.send(stream)
|
||||
})
|
||||
|
||||
const fileContent = readFileSync(filePath, 'utf-8')
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, fileContent)
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'content-length': statSync(filePath).size
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should add cors headers (custom values)', t => {
|
||||
t.plan(10)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, {
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123,
|
||||
cacheControl: 321
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, woo',
|
||||
'access-control-max-age': '123',
|
||||
'cache-control': 'max-age=321',
|
||||
'content-length': '0'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'content-length': '2'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support dynamic config (callback)', t => {
|
||||
t.plan(16)
|
||||
|
||||
const configs = [{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123,
|
||||
cacheControl: 456
|
||||
}, {
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321,
|
||||
cacheControl: '456'
|
||||
}]
|
||||
|
||||
const fastify = Fastify()
|
||||
let requestId = 0
|
||||
const configDelegation = function (req, cb) {
|
||||
// request should have id
|
||||
t.ok(req.id)
|
||||
// request should not have send
|
||||
t.notOk(req.send)
|
||||
const config = configs[requestId]
|
||||
requestId++
|
||||
if (config) {
|
||||
cb(null, config)
|
||||
} else {
|
||||
cb(new Error('ouch'))
|
||||
}
|
||||
}
|
||||
fastify.register(cors, () => configDelegation)
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'content-length': '2',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'sample.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'zoo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, foo',
|
||||
'access-control-max-age': '321',
|
||||
'cache-control': '456',
|
||||
'content-length': '0',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support dynamic config (Promise)', t => {
|
||||
t.plan(23)
|
||||
|
||||
const configs = [{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123,
|
||||
cacheControl: 456
|
||||
}, {
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321,
|
||||
cacheControl: true // Invalid value should be ignored
|
||||
}, {
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321,
|
||||
cacheControl: 'public, max-age=456'
|
||||
}]
|
||||
|
||||
const fastify = Fastify()
|
||||
let requestId = 0
|
||||
const configDelegation = function (req) {
|
||||
// request should have id
|
||||
t.ok(req.id)
|
||||
// request should not have send
|
||||
t.notOk(req.send)
|
||||
const config = configs[requestId]
|
||||
requestId++
|
||||
if (config) {
|
||||
return Promise.resolve(config)
|
||||
} else {
|
||||
return Promise.reject(new Error('ouch'))
|
||||
}
|
||||
}
|
||||
fastify.register(cors, () => configDelegation)
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'content-length': '2',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'sample.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'sample.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'zoo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, foo',
|
||||
'access-control-max-age': '321',
|
||||
'content-length': '0',
|
||||
vary: 'Origin'
|
||||
})
|
||||
t.equal(res.headers['cache-control'], undefined, 'cache-control omitted (invalid value)')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'sample.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'zoo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, foo',
|
||||
'access-control-max-age': '321',
|
||||
'cache-control': 'public, max-age=456', // cache-control included (custom string)
|
||||
'content-length': '0',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support dynamic config. (Invalid function)', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, () => (a, b, c) => {})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (valid origin)', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = function (header, cb) {
|
||||
t.equal(header, 'example.com')
|
||||
t.same(this, fastify)
|
||||
cb(null, true)
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (not valid origin)', t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = (header, cb) => {
|
||||
t.equal(header, 'example.com')
|
||||
cb(null, false)
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.same(res.headers, {
|
||||
'content-length': '2',
|
||||
'content-type': 'text/plain; charset=utf-8',
|
||||
connection: 'keep-alive',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (errored)', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = (header, cb) => {
|
||||
t.equal(header, 'example.com')
|
||||
cb(new Error('ouch'))
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (invalid result)', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = (header, cb) => {
|
||||
t.equal(header, 'example.com')
|
||||
cb(null, undefined)
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (valid origin - promises)', t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = (header, cb) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
t.equal(header, 'example.com')
|
||||
resolve(true)
|
||||
})
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (not valid origin - promises)', t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = (header, cb) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
t.equal(header, 'example.com')
|
||||
resolve(false)
|
||||
})
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.same(res.headers, {
|
||||
'content-length': '2',
|
||||
'content-type': 'text/plain; charset=utf-8',
|
||||
connection: 'keep-alive',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Dynamic origin resolution (errored - promises)', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
const origin = (header, cb) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
t.equal(header, 'example.com')
|
||||
reject(new Error('ouch'))
|
||||
})
|
||||
}
|
||||
fastify.register(cors, { origin })
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should reply 404 without cors headers when origin is false', t => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, {
|
||||
origin: false,
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 404)
|
||||
t.equal(res.payload, '{"message":"Route OPTIONS:/ not found","error":"Not Found","statusCode":404}')
|
||||
t.same(res.headers, {
|
||||
'content-length': '76',
|
||||
'content-type': 'application/json; charset=utf-8',
|
||||
connection: 'keep-alive'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.same(res.headers, {
|
||||
'content-length': '2',
|
||||
'content-type': 'text/plain; charset=utf-8',
|
||||
connection: 'keep-alive'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Server error if origin option is falsy but not false', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: '' })
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 500)
|
||||
t.same(res.json(), { statusCode: 500, error: 'Internal Server Error', message: 'Invalid CORS origin option' })
|
||||
t.same(res.headers, {
|
||||
'content-length': '89',
|
||||
'content-type': 'application/json; charset=utf-8',
|
||||
connection: 'keep-alive'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Allow only request from a specific origin', t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: 'other.io' })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'example.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'other.io'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
})
|
||||
|
||||
test('Allow only request from multiple specific origin', t => {
|
||||
t.plan(9)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: ['other.io', 'example.com'] })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'other.io' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'other.io',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'foo.com' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
vary: 'Origin'
|
||||
})
|
||||
t.equal(res.headers['access-control-allow-origin'], undefined)
|
||||
})
|
||||
})
|
||||
|
||||
test('Allow only request from a specific origin using regex', t => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: /(?:example|other)\.com/giu })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
// .test was previously used, which caused 2 consecutive requests to return
|
||||
// different results with global (e.g. /g) regexes. Therefore, check this
|
||||
// twice to check consistency
|
||||
for (let i = 0; i < 2; i++) {
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: { origin: 'https://www.example.com/' }
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'https://www.example.com/',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('Disable preflight', t => {
|
||||
t.plan(7)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { preflight: false })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/hello'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 404)
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should always add vary header to `Origin` for reflected origin', t => {
|
||||
t.plan(12)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: true })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
// Invalid Preflight
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 400)
|
||||
t.equal(res.payload, 'Invalid Preflight Request')
|
||||
t.match(res.headers, {
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
// Valid Preflight
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
// Other Route
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should always add vary header to `Origin` for reflected origin (vary is array)', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
// Mock getHeader function
|
||||
fastify.decorateReply('getHeader', (name) => ['foo', 'bar'])
|
||||
|
||||
fastify.register(cors, { origin: true })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
vary: 'foo, bar, Origin'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Allow only request from with specific headers', t => {
|
||||
t.plan(8)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, {
|
||||
allowedHeaders: 'foo',
|
||||
exposedHeaders: 'bar'
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-headers': 'foo'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-expose-headers': 'bar'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support wildcard config /1', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: '*' })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.equal(res.headers['access-control-allow-origin'], '*')
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support wildcard config /2', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { origin: ['*'] })
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.equal(res.headers['access-control-allow-origin'], '*')
|
||||
})
|
||||
})
|
||||
706
backend/node_modules/@fastify/cors/test/hooks.test.js
generated
vendored
Normal file
706
backend/node_modules/@fastify/cors/test/hooks.test.js
generated
vendored
Normal file
@@ -0,0 +1,706 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const Fastify = require('fastify')
|
||||
const kFastifyContext = require('fastify/lib/symbols').kRouteContext
|
||||
const cors = require('..')
|
||||
|
||||
test('Should error on invalid hook option', async (t) => {
|
||||
t.plan(1)
|
||||
|
||||
const fastify = Fastify()
|
||||
t.rejects(fastify.register(cors, { hook: 'invalid' }), new TypeError('@fastify/cors: Invalid hook option provided.'))
|
||||
})
|
||||
|
||||
test('Should set hook onRequest if hook option is not set', async (t) => {
|
||||
t.plan(10)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest.length, 1)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing, null)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
})
|
||||
|
||||
test('Should set hook onRequest if hook option is set to onRequest', async (t) => {
|
||||
t.plan(10)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'onRequest'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest.length, 1)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing, null)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
})
|
||||
|
||||
test('Should set hook preParsing if hook option is set to preParsing', async (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preParsing'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest, null)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing.length, 1)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
test('Should set hook preValidation if hook option is set to preValidation', async (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preValidation'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest, null)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing, null)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation.length, 1)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
test('Should set hook preParsing if hook option is set to preParsing', async (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preParsing'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest, null)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing.length, 1)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
test('Should set hook preHandler if hook option is set to preHandler', async (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preHandler'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest, null)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler.length, 1)
|
||||
t.equal(request[kFastifyContext].preParsing, null)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
test('Should set hook onSend if hook option is set to onSend', async (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'onSend'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest, null)
|
||||
t.equal(request[kFastifyContext].onSend.length, 1)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing, null)
|
||||
t.equal(request[kFastifyContext].preSerialization, null)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
test('Should set hook preSerialization if hook option is set to preSerialization', async (t) => {
|
||||
t.plan(11)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preSerialization'
|
||||
})
|
||||
|
||||
fastify.addHook('onResponse', (request, reply, done) => {
|
||||
t.equal(request[kFastifyContext].onError, null)
|
||||
t.equal(request[kFastifyContext].onRequest, null)
|
||||
t.equal(request[kFastifyContext].onSend, null)
|
||||
t.equal(request[kFastifyContext].preHandler, null)
|
||||
t.equal(request[kFastifyContext].preParsing, null)
|
||||
t.equal(request[kFastifyContext].preSerialization.length, 1)
|
||||
t.equal(request[kFastifyContext].preValidation, null)
|
||||
done()
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send({ nonString: true })
|
||||
})
|
||||
|
||||
await fastify.ready()
|
||||
|
||||
const res = await fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
})
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, '{"nonString":true}')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
|
||||
test('Should support custom hook with dynamic config', t => {
|
||||
t.plan(16)
|
||||
|
||||
const configs = [{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123
|
||||
}, {
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321
|
||||
}]
|
||||
|
||||
const fastify = Fastify()
|
||||
let requestId = 0
|
||||
const configDelegation = function (req, cb) {
|
||||
// request should have id
|
||||
t.ok(req.id)
|
||||
// request should not have send
|
||||
t.notOk(req.send)
|
||||
const config = configs[requestId]
|
||||
requestId++
|
||||
if (config) {
|
||||
cb(null, config)
|
||||
} else {
|
||||
cb(new Error('ouch'))
|
||||
}
|
||||
}
|
||||
fastify.register(cors, {
|
||||
hook: 'preHandler',
|
||||
delegator: configDelegation
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'content-length': '2',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'sample.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'zoo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, foo',
|
||||
'access-control-max-age': '321',
|
||||
'content-length': '0',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support custom hook with dynamic config (callback)', t => {
|
||||
t.plan(16)
|
||||
|
||||
const configs = [{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123
|
||||
}, {
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321
|
||||
}]
|
||||
|
||||
const fastify = Fastify()
|
||||
let requestId = 0
|
||||
const configDelegation = function (req, cb) {
|
||||
// request should have id
|
||||
t.ok(req.id)
|
||||
// request should not have send
|
||||
t.notOk(req.send)
|
||||
const config = configs[requestId]
|
||||
requestId++
|
||||
if (config) {
|
||||
cb(null, config)
|
||||
} else {
|
||||
cb(new Error('ouch'))
|
||||
}
|
||||
}
|
||||
fastify.register(cors, {
|
||||
hook: 'preParsing',
|
||||
delegator: configDelegation
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'content-length': '2',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'sample.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'zoo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, foo',
|
||||
'access-control-max-age': '321',
|
||||
'content-length': '0',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support custom hook with dynamic config (Promise)', t => {
|
||||
t.plan(16)
|
||||
|
||||
const configs = [{
|
||||
origin: 'example.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['foo', 'bar'],
|
||||
allowedHeaders: ['baz', 'woo'],
|
||||
maxAge: 123
|
||||
}, {
|
||||
origin: 'sample.com',
|
||||
methods: 'GET',
|
||||
credentials: true,
|
||||
exposedHeaders: ['zoo', 'bar'],
|
||||
allowedHeaders: ['baz', 'foo'],
|
||||
maxAge: 321
|
||||
}]
|
||||
|
||||
const fastify = Fastify()
|
||||
let requestId = 0
|
||||
const configDelegation = function (req) {
|
||||
// request should have id
|
||||
t.ok(req.id)
|
||||
// request should not have send
|
||||
t.notOk(req.send)
|
||||
const config = configs[requestId]
|
||||
requestId++
|
||||
if (config) {
|
||||
return Promise.resolve(config)
|
||||
} else {
|
||||
return Promise.reject(new Error('ouch'))
|
||||
}
|
||||
}
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preParsing',
|
||||
delegator: configDelegation
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'example.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'foo, bar',
|
||||
'content-length': '2',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': 'sample.com',
|
||||
'access-control-allow-credentials': 'true',
|
||||
'access-control-expose-headers': 'zoo, bar',
|
||||
'access-control-allow-methods': 'GET',
|
||||
'access-control-allow-headers': 'baz, foo',
|
||||
'access-control-max-age': '321',
|
||||
'content-length': '0',
|
||||
vary: 'Origin'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support custom hook with dynamic config (Promise), but should error /1', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
const configDelegation = function () {
|
||||
return false
|
||||
}
|
||||
|
||||
fastify.register(cors, {
|
||||
hook: 'preParsing',
|
||||
delegator: configDelegation
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 500)
|
||||
t.equal(res.payload, '{"statusCode":500,"error":"Internal Server Error","message":"Invalid CORS origin option"}')
|
||||
t.match(res.headers, {
|
||||
'content-length': '89'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support custom hook with dynamic config (Promise), but should error /2', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
const configDelegation = function () {
|
||||
return false
|
||||
}
|
||||
|
||||
fastify.register(cors, {
|
||||
delegator: configDelegation
|
||||
})
|
||||
|
||||
fastify.get('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 500)
|
||||
t.equal(res.payload, '{"statusCode":500,"error":"Internal Server Error","message":"Invalid CORS origin option"}')
|
||||
t.match(res.headers, {
|
||||
'content-length': '89'
|
||||
})
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'GET',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 500)
|
||||
})
|
||||
})
|
||||
435
backend/node_modules/@fastify/cors/test/preflight.test.js
generated
vendored
Normal file
435
backend/node_modules/@fastify/cors/test/preflight.test.js
generated
vendored
Normal file
@@ -0,0 +1,435 @@
|
||||
'use strict'
|
||||
|
||||
const { test } = require('tap')
|
||||
const Fastify = require('fastify')
|
||||
const cors = require('../')
|
||||
|
||||
test('Should reply to preflight requests', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should add access-control-allow-headers to response if preflight req has access-control-request-headers', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-headers': 'x-requested-with',
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
'access-control-allow-headers': 'x-requested-with',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should reply to preflight requests with custom status code', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { optionsSuccessStatus: 200 })
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should be able to override preflight response with a route', t => {
|
||||
t.plan(5)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { preflightContinue: true })
|
||||
|
||||
fastify.options('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
// Only the base cors headers and no preflight headers
|
||||
'access-control-allow-origin': '*'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
})
|
||||
|
||||
test('Should reply to all options requests', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/hello',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support a prefix for preflight requests', t => {
|
||||
t.plan(6)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register((instance, opts, next) => {
|
||||
instance.register(cors)
|
||||
next()
|
||||
}, { prefix: '/subsystem' })
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/hello'
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 404)
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/subsystem/hello',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('hide options route by default', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onRoute', (route) => {
|
||||
if (route.method === 'OPTIONS' && route.url === '*') {
|
||||
t.equal(route.schema.hide, true)
|
||||
}
|
||||
})
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.ready(err => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('show options route', t => {
|
||||
t.plan(2)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.addHook('onRoute', (route) => {
|
||||
if (route.method === 'OPTIONS' && route.url === '*') {
|
||||
t.equal(route.schema.hide, false)
|
||||
}
|
||||
})
|
||||
fastify.register(cors, { hideOptionsRoute: false })
|
||||
|
||||
fastify.ready(err => {
|
||||
t.error(err)
|
||||
})
|
||||
})
|
||||
|
||||
test('Allow only request from with specific methods', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { methods: ['GET', 'POST'] })
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-methods': 'GET, POST'
|
||||
})
|
||||
t.notMatch(res.headers, { vary: 'Origin' })
|
||||
})
|
||||
})
|
||||
|
||||
test('Should reply with 400 error to OPTIONS requests missing origin header when default strictPreflight', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors)
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400)
|
||||
t.equal(res.payload, 'Invalid Preflight Request')
|
||||
})
|
||||
})
|
||||
|
||||
test('Should reply with 400 to OPTIONS requests when missing Access-Control-Request-Method header when default strictPreflight', t => {
|
||||
t.plan(3)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, {
|
||||
strictPreflight: true
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
t.equal(res.statusCode, 400)
|
||||
t.equal(res.payload, 'Invalid Preflight Request')
|
||||
})
|
||||
})
|
||||
|
||||
test('Should reply to all preflight requests when strictPreflight is disabled', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { strictPreflight: false })
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/'
|
||||
// No access-control-request-method or origin headers
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Default empty 200 response with preflightContinue on OPTIONS routes', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { preflightContinue: true })
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/doesnotexist',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Can override preflight response with preflightContinue', t => {
|
||||
t.plan(4)
|
||||
|
||||
const fastify = Fastify()
|
||||
fastify.register(cors, { preflightContinue: true })
|
||||
|
||||
fastify.options('/', (req, reply) => {
|
||||
reply.send('ok')
|
||||
})
|
||||
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 200)
|
||||
t.equal(res.payload, 'ok')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Should support ongoing prefix ', t => {
|
||||
t.plan(12)
|
||||
|
||||
const fastify = Fastify()
|
||||
|
||||
fastify.register(async (instance) => {
|
||||
instance.register(cors)
|
||||
}, { prefix: '/prefix' })
|
||||
|
||||
// support prefixed route
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/prefix',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
|
||||
// support prefixed route without / continue
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/prefixfoo',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
|
||||
// support prefixed route with / continue
|
||||
fastify.inject({
|
||||
method: 'OPTIONS',
|
||||
url: '/prefix/foo',
|
||||
headers: {
|
||||
'access-control-request-method': 'GET',
|
||||
origin: 'example.com'
|
||||
}
|
||||
}, (err, res) => {
|
||||
t.error(err)
|
||||
delete res.headers.date
|
||||
t.equal(res.statusCode, 204)
|
||||
t.equal(res.payload, '')
|
||||
t.match(res.headers, {
|
||||
'access-control-allow-origin': '*',
|
||||
'access-control-allow-methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
||||
vary: 'Access-Control-Request-Headers',
|
||||
'content-length': '0'
|
||||
})
|
||||
})
|
||||
})
|
||||
229
backend/node_modules/@fastify/cors/test/vary.test.js
generated
vendored
Normal file
229
backend/node_modules/@fastify/cors/test/vary.test.js
generated
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
'use strict'
|
||||
|
||||
const test = require('tap').test
|
||||
const createAddFieldnameToVary = require('../vary').createAddFieldnameToVary
|
||||
const parse = require('../vary').parse
|
||||
|
||||
test('Should set * even if we set a specific field', t => {
|
||||
t.plan(1)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return '*'
|
||||
},
|
||||
header (name, value) {
|
||||
t.fail('Should not be here')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test('Should set * even if we set a specific field', t => {
|
||||
t.plan(2)
|
||||
|
||||
const addWildcardToVary = createAddFieldnameToVary('*')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return 'Origin'
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, '*')
|
||||
}
|
||||
}
|
||||
|
||||
addWildcardToVary(replyMock)
|
||||
})
|
||||
|
||||
test('Should set * when field contains a *', t => {
|
||||
t.plan(3)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return ['Origin', '*', 'Access-Control-Request-Headers']
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, '*')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test('Should concat vary values', t => {
|
||||
t.plan(3)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return 'Access-Control-Request-Headers'
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, 'Access-Control-Request-Headers, Origin')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test('Should concat vary values ignoring consecutive commas', t => {
|
||||
t.plan(3)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return ' Access-Control-Request-Headers,Access-Control-Request-Method'
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, ' Access-Control-Request-Headers,Access-Control-Request-Method, Origin')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test('Should concat vary values ignoring whitespace', t => {
|
||||
t.plan(3)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return ' Access-Control-Request-Headers ,Access-Control-Request-Method'
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, ' Access-Control-Request-Headers ,Access-Control-Request-Method, Origin')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test('Should set the field as value for vary if no vary is defined', t => {
|
||||
t.plan(2)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return undefined
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, 'Origin')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
})
|
||||
|
||||
test('Should set * as value for vary if vary contains *', t => {
|
||||
t.plan(2)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return 'Accept,*'
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, '*')
|
||||
}
|
||||
}
|
||||
|
||||
addOriginToVary(replyMock)
|
||||
})
|
||||
|
||||
test('Should set Accept-Encoding as value for vary if vary is empty string', t => {
|
||||
t.plan(2)
|
||||
|
||||
const addAcceptEncodingToVary = createAddFieldnameToVary('Accept-Encoding')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return ''
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, 'Accept-Encoding')
|
||||
}
|
||||
}
|
||||
|
||||
addAcceptEncodingToVary(replyMock)
|
||||
})
|
||||
|
||||
test('Should have no issues with values containing dashes', t => {
|
||||
t.plan(2)
|
||||
|
||||
const addXFooToVary = createAddFieldnameToVary('X-Foo')
|
||||
const replyMock = {
|
||||
value: 'Accept-Encoding',
|
||||
getHeader (name) {
|
||||
return this.value
|
||||
},
|
||||
header (name, value) {
|
||||
t.same(name, 'Vary')
|
||||
t.same(value, 'Accept-Encoding, X-Foo')
|
||||
this.value = value
|
||||
}
|
||||
}
|
||||
|
||||
addXFooToVary(replyMock)
|
||||
addXFooToVary(replyMock)
|
||||
})
|
||||
|
||||
test('Should ignore the header as value for vary if it is already in vary', t => {
|
||||
t.plan(1)
|
||||
|
||||
const addOriginToVary = createAddFieldnameToVary('Origin')
|
||||
const replyMock = {
|
||||
getHeader (name) {
|
||||
return 'Origin'
|
||||
},
|
||||
header (name, value) {
|
||||
t.fail('Should not be here')
|
||||
}
|
||||
}
|
||||
addOriginToVary(replyMock)
|
||||
addOriginToVary(replyMock)
|
||||
t.pass()
|
||||
})
|
||||
|
||||
test('parse', t => {
|
||||
t.plan(18)
|
||||
t.same(parse(''), [])
|
||||
t.same(parse('a'), ['a'])
|
||||
t.same(parse('a,b'), ['a', 'b'])
|
||||
t.same(parse(' a,b'), ['a', 'b'])
|
||||
t.same(parse('a,b '), ['a', 'b'])
|
||||
t.same(parse('a,b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('A,b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a,b,c,'), ['a', 'b', 'c'])
|
||||
t.same(parse('a,b,c, '), ['a', 'b', 'c'])
|
||||
t.same(parse(',a,b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse(' ,a,b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a,,b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a,,,b,,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a, b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a, b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a, , b,c'), ['a', 'b', 'c'])
|
||||
t.same(parse('a, , b,c'), ['a', 'b', 'c'])
|
||||
|
||||
// one for the cache
|
||||
t.same(parse('A,b,c'), ['a', 'b', 'c'])
|
||||
})
|
||||
|
||||
test('createAddFieldnameToVary', t => {
|
||||
t.plan(2)
|
||||
t.same(typeof createAddFieldnameToVary('valid-header'), 'function')
|
||||
t.throws(() => createAddFieldnameToVary('invalid:header'), TypeError, 'Field contains invalid characters.')
|
||||
})
|
||||
116
backend/node_modules/@fastify/cors/types/index.d.ts
generated
vendored
Normal file
116
backend/node_modules/@fastify/cors/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import { FastifyInstance, FastifyPluginCallback, FastifyRequest } from 'fastify';
|
||||
|
||||
type OriginCallback = (err: Error | null, origin: ValueOrArray<OriginType>) => void;
|
||||
type OriginType = string | boolean | RegExp;
|
||||
type ValueOrArray<T> = T | ArrayOfValueOrArray<T>;
|
||||
|
||||
interface ArrayOfValueOrArray<T> extends Array<ValueOrArray<T>> {
|
||||
}
|
||||
|
||||
type FastifyCorsPlugin = FastifyPluginCallback<
|
||||
NonNullable<fastifyCors.FastifyCorsOptions> | fastifyCors.FastifyCorsOptionsDelegate
|
||||
>;
|
||||
|
||||
type FastifyCorsHook =
|
||||
| 'onRequest'
|
||||
| 'preParsing'
|
||||
| 'preValidation'
|
||||
| 'preHandler'
|
||||
| 'preSerialization'
|
||||
| 'onSend'
|
||||
|
||||
declare namespace fastifyCors {
|
||||
export type OriginFunction = (origin: string | undefined, callback: OriginCallback) => void;
|
||||
|
||||
export interface FastifyCorsOptions {
|
||||
/**
|
||||
* Configures the Lifecycle Hook.
|
||||
*/
|
||||
hook?: FastifyCorsHook;
|
||||
|
||||
/**
|
||||
* Configures the delegate function.
|
||||
*/
|
||||
delegator?: FastifyCorsOptionsDelegate;
|
||||
|
||||
/**
|
||||
* Configures the Access-Control-Allow-Origin CORS header.
|
||||
*/
|
||||
origin?: ValueOrArray<OriginType> | fastifyCors.OriginFunction;
|
||||
/**
|
||||
* Configures the Access-Control-Allow-Credentials CORS header.
|
||||
* Set to true to pass the header, otherwise it is omitted.
|
||||
*/
|
||||
credentials?: boolean;
|
||||
/**
|
||||
* Configures the Access-Control-Expose-Headers CORS header.
|
||||
* Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range')
|
||||
* or an array (ex: ['Content-Range', 'X-Content-Range']).
|
||||
* If not specified, no custom headers are exposed.
|
||||
*/
|
||||
exposedHeaders?: string | string[];
|
||||
/**
|
||||
* Configures the Access-Control-Allow-Headers CORS header.
|
||||
* Expects a comma-delimited string (ex: 'Content-Type,Authorization')
|
||||
* or an array (ex: ['Content-Type', 'Authorization']). If not
|
||||
* specified, defaults to reflecting the headers specified in the
|
||||
* request's Access-Control-Request-Headers header.
|
||||
*/
|
||||
allowedHeaders?: string | string[];
|
||||
/**
|
||||
* Configures the Access-Control-Allow-Methods CORS header.
|
||||
* Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: ['GET', 'PUT', 'POST']).
|
||||
*/
|
||||
methods?: string | string[];
|
||||
/**
|
||||
* Configures the Access-Control-Max-Age CORS header.
|
||||
* Set to an integer to pass the header, otherwise it is omitted.
|
||||
*/
|
||||
maxAge?: number;
|
||||
/**
|
||||
* Configures the Cache-Control header for CORS preflight responses.
|
||||
* Set to an integer to pass the header as `Cache-Control: max-age=${cacheControl}`,
|
||||
* or set to a string to pass the header as `Cache-Control: ${cacheControl}` (fully define
|
||||
* the header value), otherwise the header is omitted.
|
||||
*/
|
||||
cacheControl?: number | string;
|
||||
/**
|
||||
* Pass the CORS preflight response to the route handler (default: false).
|
||||
*/
|
||||
preflightContinue?: boolean;
|
||||
/**
|
||||
* Provides a status code to use for successful OPTIONS requests,
|
||||
* since some legacy browsers (IE11, various SmartTVs) choke on 204.
|
||||
*/
|
||||
optionsSuccessStatus?: number;
|
||||
/**
|
||||
* Pass the CORS preflight response to the route handler (default: false).
|
||||
*/
|
||||
preflight?: boolean;
|
||||
/**
|
||||
* Enforces strict requirement of the CORS preflight request headers (Access-Control-Request-Method and Origin).
|
||||
* Preflight requests without the required headers will result in 400 errors when set to `true` (default: `true`).
|
||||
*/
|
||||
strictPreflight?: boolean;
|
||||
/**
|
||||
* Hide options route from the documentation built using fastify-swagger (default: true).
|
||||
*/
|
||||
hideOptionsRoute?: boolean;
|
||||
}
|
||||
|
||||
export interface FastifyCorsOptionsDelegateCallback { (req: FastifyRequest, cb: (error: Error | null, corsOptions?: FastifyCorsOptions) => void): void }
|
||||
export interface FastifyCorsOptionsDelegatePromise { (req: FastifyRequest): Promise<FastifyCorsOptions> }
|
||||
export type FastifyCorsOptionsDelegate = FastifyCorsOptionsDelegateCallback | FastifyCorsOptionsDelegatePromise
|
||||
export type FastifyPluginOptionsDelegate<T = FastifyCorsOptionsDelegate> = (instance: FastifyInstance) => T;
|
||||
|
||||
export const fastifyCors: FastifyCorsPlugin
|
||||
export { fastifyCors as default };
|
||||
}
|
||||
|
||||
declare function fastifyCors(
|
||||
...params: Parameters<FastifyCorsPlugin>
|
||||
): ReturnType<FastifyCorsPlugin>;
|
||||
|
||||
export = fastifyCors;
|
||||
355
backend/node_modules/@fastify/cors/types/index.test-d.ts
generated
vendored
Normal file
355
backend/node_modules/@fastify/cors/types/index.test-d.ts
generated
vendored
Normal file
@@ -0,0 +1,355 @@
|
||||
import fastify, { FastifyRequest } from 'fastify'
|
||||
import { expectType } from 'tsd'
|
||||
import fastifyCors, {
|
||||
FastifyCorsOptions,
|
||||
FastifyCorsOptionsDelegate,
|
||||
FastifyCorsOptionsDelegatePromise,
|
||||
FastifyPluginOptionsDelegate,
|
||||
OriginFunction
|
||||
} from '..'
|
||||
|
||||
const app = fastify()
|
||||
|
||||
app.register(fastifyCors)
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: true,
|
||||
allowedHeaders: 'authorization,content-type',
|
||||
methods: 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
||||
credentials: true,
|
||||
exposedHeaders: 'authorization',
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: true,
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 'public, max-age=3500',
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: '*',
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: /\*/,
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: ['*', 'something'],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
const corsDelegate: OriginFunction = (origin, cb) => {
|
||||
if (origin === undefined || /localhost/.test(origin)) {
|
||||
cb(null, true)
|
||||
return
|
||||
}
|
||||
cb(new Error(), false)
|
||||
}
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: corsDelegate,
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: (origin, cb) => cb(null, true)
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: (origin, cb) => cb(null, '*')
|
||||
})
|
||||
|
||||
app.register(fastifyCors, {
|
||||
origin: (origin, cb) => cb(null, /\*/)
|
||||
})
|
||||
|
||||
const appHttp2 = fastify({ http2: true })
|
||||
|
||||
appHttp2.register(fastifyCors)
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: true,
|
||||
allowedHeaders: 'authorization,content-type',
|
||||
methods: 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
||||
credentials: true,
|
||||
exposedHeaders: 'authorization',
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: true,
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: '*',
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: /\*/,
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: ['*', 'something'],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
origin: (origin: string | undefined, cb: (err: Error | null, allow: boolean) => void) => {
|
||||
if (origin === undefined || /localhost/.test(origin)) {
|
||||
cb(null, true)
|
||||
return
|
||||
}
|
||||
cb(new Error(), false)
|
||||
},
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, (): FastifyCorsOptionsDelegate => (req, cb) => {
|
||||
cb(null, {
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, (): FastifyCorsOptionsDelegatePromise => (req) => {
|
||||
return Promise.resolve({
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
})
|
||||
|
||||
const delegate: FastifyPluginOptionsDelegate<FastifyCorsOptionsDelegatePromise> = () => async (req) => {
|
||||
return {
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 13000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
}
|
||||
}
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'onRequest'
|
||||
})
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preParsing'
|
||||
})
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preValidation'
|
||||
})
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preHandler'
|
||||
})
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preSerialization'
|
||||
})
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'onSend'
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preParsing',
|
||||
delegator: (req, cb) => {
|
||||
if (req.url.startsWith('/some-value')) {
|
||||
cb(new Error())
|
||||
}
|
||||
cb(null, {
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 12000,
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preParsing',
|
||||
delegator: async (req: FastifyRequest): Promise<FastifyCorsOptions> => {
|
||||
return {
|
||||
origin: [/\*/, /something/],
|
||||
allowedHeaders: ['authorization', 'content-type'],
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
credentials: true,
|
||||
exposedHeaders: ['authorization'],
|
||||
maxAge: 13000,
|
||||
cacheControl: 'public, max-age=3500',
|
||||
preflightContinue: false,
|
||||
optionsSuccessStatus: 200,
|
||||
preflight: false,
|
||||
strictPreflight: false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
appHttp2.register(fastifyCors, delegate)
|
||||
|
||||
appHttp2.register(fastifyCors, {
|
||||
hook: 'preParsing',
|
||||
origin: function (origin) {
|
||||
expectType<string|undefined>(origin)
|
||||
},
|
||||
})
|
||||
116
backend/node_modules/@fastify/cors/vary.js
generated
vendored
Normal file
116
backend/node_modules/@fastify/cors/vary.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
'use strict'
|
||||
|
||||
const LRUCache = require('mnemonist/lru-cache')
|
||||
|
||||
/**
|
||||
* Field Value Components
|
||||
* Most HTTP header field values are defined using common syntax
|
||||
* components (token, quoted-string, and comment) separated by
|
||||
* whitespace or specific delimiting characters. Delimiters are chosen
|
||||
* from the set of US-ASCII visual characters not allowed in a token
|
||||
* (DQUOTE and "(),/:;<=>?@[\]{}").
|
||||
*
|
||||
* field-name = token
|
||||
* token = 1*tchar
|
||||
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
|
||||
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
|
||||
* / DIGIT / ALPHA
|
||||
* ; any VCHAR, except delimiters
|
||||
*
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
|
||||
*/
|
||||
|
||||
const validFieldnameRE = /^[!#$%&'*+\-.^\w`|~]+$/u
|
||||
function validateFieldname (fieldname) {
|
||||
if (validFieldnameRE.test(fieldname) === false) {
|
||||
throw new TypeError('Fieldname contains invalid characters.')
|
||||
}
|
||||
}
|
||||
|
||||
function parse (header) {
|
||||
header = header.trim().toLowerCase()
|
||||
const result = []
|
||||
|
||||
if (header.length === 0) {
|
||||
// pass through
|
||||
} else if (header.indexOf(',') === -1) {
|
||||
result.push(header)
|
||||
} else {
|
||||
const il = header.length
|
||||
let i = 0
|
||||
let pos = 0
|
||||
let char
|
||||
|
||||
// tokenize the header
|
||||
for (i = 0; i < il; ++i) {
|
||||
char = header[i]
|
||||
// when we have whitespace set the pos to the next position
|
||||
if (char === ' ') {
|
||||
pos = i + 1
|
||||
// `,` is the separator of vary-values
|
||||
} else if (char === ',') {
|
||||
// if pos and current position are not the same we have a valid token
|
||||
if (pos !== i) {
|
||||
result.push(header.slice(pos, i))
|
||||
}
|
||||
// reset the positions
|
||||
pos = i + 1
|
||||
}
|
||||
}
|
||||
|
||||
if (pos !== i) {
|
||||
result.push(header.slice(pos, i))
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function createAddFieldnameToVary (fieldname) {
|
||||
const headerCache = new LRUCache(1000)
|
||||
|
||||
validateFieldname(fieldname)
|
||||
|
||||
return function (reply) {
|
||||
let header = reply.getHeader('Vary')
|
||||
|
||||
if (!header) {
|
||||
reply.header('Vary', fieldname)
|
||||
return
|
||||
}
|
||||
|
||||
if (header === '*') {
|
||||
return
|
||||
}
|
||||
|
||||
if (fieldname === '*') {
|
||||
reply.header('Vary', '*')
|
||||
return
|
||||
}
|
||||
|
||||
if (Array.isArray(header)) {
|
||||
header = header.join(', ')
|
||||
}
|
||||
|
||||
if (!headerCache.has(header)) {
|
||||
const vals = parse(header)
|
||||
|
||||
if (vals.indexOf('*') !== -1) {
|
||||
headerCache.set(header, '*')
|
||||
} else if (vals.indexOf(fieldname.toLowerCase()) === -1) {
|
||||
headerCache.set(header, header + ', ' + fieldname)
|
||||
} else {
|
||||
headerCache.set(header, null)
|
||||
}
|
||||
}
|
||||
const cached = headerCache.get(header)
|
||||
if (cached !== null) {
|
||||
reply.header('Vary', cached)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.createAddFieldnameToVary = createAddFieldnameToVary
|
||||
module.exports.addOriginToVaryHeader = createAddFieldnameToVary('Origin')
|
||||
module.exports.addAccessControlRequestHeadersToVaryHeader = createAddFieldnameToVary('Access-Control-Request-Headers')
|
||||
module.exports.parse = parse
|
||||
2
backend/node_modules/@fastify/error/.gitattributes
generated
vendored
Normal file
2
backend/node_modules/@fastify/error/.gitattributes
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Set default behavior to automatically convert line endings
|
||||
* text=auto eol=lf
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user