diff --git a/.gitignore b/.gitignore index 63ef3c421..e4faa8489 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ dist .vscode/settings.json .env.local .npmcache +coverage diff --git a/package.json b/package.json index 6360691c7..735071575 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/language/package.json b/packages/language/package.json index ea7f3c5e6..a58e7072b 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/next/jest.config.ts b/packages/next/jest.config.ts new file mode 100644 index 000000000..917cf52f6 --- /dev/null +++ b/packages/next/jest.config.ts @@ -0,0 +1,29 @@ +/* + * For a detailed explanation regarding each configuration property and type check, visit: + * https://jestjs.io/docs/configuration + */ + +export default { + // Automatically clear mock calls, instances, contexts and results before every test + clearMocks: true, + + // Indicates whether the coverage information should be collected while executing the test + collectCoverage: true, + + // The directory where Jest should output its coverage files + coverageDirectory: 'tests/coverage', + + // An array of regexp pattern strings used to skip coverage collection + coveragePathIgnorePatterns: ['/node_modules/', '/tests/'], + + // Indicates which provider should be used to instrument code for coverage + coverageProvider: 'v8', + + // A list of reporter names that Jest uses when writing coverage reports + coverageReporters: ['json', 'text', 'lcov', 'clover'], + + // A map from regular expressions to paths to transformers + transform: { '^.+\\.tsx?$': 'ts-jest' }, + + testTimeout: 300000, +}; diff --git a/packages/next/package.json b/packages/next/package.json index 1ff67e5ed..68dde4cdc 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/next", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "displayName": "ZenStack Next.js integration", "description": "ZenStack Next.js integration", "homepage": "https://zenstack.dev", @@ -25,13 +25,20 @@ }, "dependencies": { "@zenstackhq/runtime": "workspace:*", - "superjson": "^1.11.0" + "@zenstackhq/testtools": "workspace:*", + "tmp": "^0.2.1" }, "devDependencies": { + "@types/jest": "^29.4.0", "@types/react": "^18.0.26", + "@types/supertest": "^2.0.12", "copyfiles": "^2.4.1", + "jest": "^29.4.3", "react": "^17.0.2 || ^18", "rimraf": "^3.0.2", + "superjson": "^1.11.0", + "supertest": "^6.3.3", + "ts-jest": "^29.0.5", "typescript": "^4.9.4" } } diff --git a/packages/next/src/request-handler.ts b/packages/next/src/request-handler.ts index 6f24a0780..8ab725f9d 100644 --- a/packages/next/src/request-handler.ts +++ b/packages/next/src/request-handler.ts @@ -94,6 +94,7 @@ async function handleRequest( return; } args = unmarshal(req.body, options.useSuperJson); + // TODO: upsert's status code should be conditional resCode = 201; break; @@ -112,7 +113,7 @@ async function handleRequest( case 'update': case 'updateMany': - if (req.method !== 'PUT') { + if (req.method !== 'PUT' && req.method !== 'PATCH') { res.status(400).send({ error: 'invalid http method' }); return; } @@ -130,10 +131,14 @@ async function handleRequest( default: res.status(400).send({ error: `unknown method name: ${op}` }); - break; + return; } try { + if (!prisma[model]) { + res.status(400).send({ error: `unknown model name: ${model}` }); + return; + } const result = await prisma[model][dbOp](args); res.status(resCode).send(marshal(result, options.useSuperJson)); } catch (err) { @@ -146,12 +151,14 @@ async function handleRequest( rejectedByPolicy: true, code: err.code, message: err.message, + reason: err.meta?.reason, }); } else { res.status(400).send({ prisma: true, code: err.code, message: err.message, + reason: err.meta?.reason, }); } } else if (isPrismaClientUnknownRequestError(err) || isPrismaClientValidationError(err)) { diff --git a/packages/next/tests/request-handler.test.ts b/packages/next/tests/request-handler.test.ts new file mode 100644 index 000000000..fb56fecc7 --- /dev/null +++ b/packages/next/tests/request-handler.test.ts @@ -0,0 +1,222 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { loadSchema } from '@zenstackhq/testtools'; +import { createServer, RequestListener } from 'http'; +import { apiResolver } from 'next/dist/server/api-utils/node'; +import superjson from 'superjson'; +import request from 'supertest'; +import { requestHandler, RequestHandlerOptions } from '../src/'; + +function makeTestClient(apiPath: string, options: RequestHandlerOptions, queryArgs?: unknown) { + const pathParts = apiPath.split('/').filter((p) => p); + + const query = { + path: pathParts, + ...(queryArgs ? { q: superjson.stringify(queryArgs) } : {}), + }; + + const handler = requestHandler(options); + + const listener: RequestListener = (req, res) => { + return apiResolver( + req, + res, + query, + handler, + { + previewModeEncryptionKey: '', + previewModeId: '', + previewModeSigningKey: '', + }, + false + ); + }; + + return request(createServer(listener)); +} + +describe('request handler tests', () => { + let origDir: string; + + beforeEach(() => { + origDir = process.cwd(); + }); + + afterEach(() => { + process.chdir(origDir); + }); + + it('simple crud', async () => { + const model = ` +model M { + id String @id @default(cuid()) + value Int +} + `; + + const { prisma } = await loadSchema(model); + + await makeTestClient('/m/create', { getPrisma: () => prisma }) + .post('/') + .send({ data: { id: '1', value: 1 } }) + .expect(201) + .expect((resp) => { + expect(resp.body.json.value).toBe(1); + }); + + await makeTestClient('/m/findUnique', { getPrisma: () => prisma }, { where: { id: '1' } }) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json.value).toBe(1); + }); + + await makeTestClient('/m/findFirst', { getPrisma: () => prisma }, { where: { id: '1' } }) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json.value).toBe(1); + }); + + await makeTestClient('/m/findMany', { getPrisma: () => prisma }, {}) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json).toHaveLength(1); + }); + + await makeTestClient('/m/update', { getPrisma: () => prisma }) + .put('/') + .send({ where: { id: '1' }, data: { value: 2 } }) + .expect(200) + .expect((resp) => { + expect(resp.body.json.value).toBe(2); + }); + + await makeTestClient('/m/updateMany', { getPrisma: () => prisma }) + .put('/') + .send({ data: { value: 4 } }) + .expect(200) + .expect((resp) => { + expect(resp.body.json.count).toBe(1); + }); + + await makeTestClient('/m/upsert', { getPrisma: () => prisma }) + .post('/') + .send({ where: { id: '2' }, create: { id: '2', value: 2 }, update: { value: 3 } }) + .expect(201) + .expect((resp) => { + expect(resp.body.json.value).toBe(2); + }); + + await makeTestClient('/m/upsert', { getPrisma: () => prisma }) + .post('/') + .send({ where: { id: '2' }, create: { id: '2', value: 2 }, update: { value: 3 } }) + .expect(201) + .expect((resp) => { + expect(resp.body.json.value).toBe(3); + }); + + await makeTestClient('/m/count', { getPrisma: () => prisma }, { where: { id: '1' } }) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json).toBe(1); + }); + + await makeTestClient('/m/count', { getPrisma: () => prisma }, {}) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json).toBe(2); + }); + + await makeTestClient('/m/aggregate', { getPrisma: () => prisma }, { _sum: { value: true } }) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json._sum.value).toBe(7); + }); + + await makeTestClient('/m/groupBy', { getPrisma: () => prisma }, { by: ['id'], _sum: { value: true } }) + .get('/') + .expect(200) + .expect((resp) => { + const data = resp.body.json; + expect(data).toHaveLength(2); + expect(data.find((item: any) => item.id === '1')._sum.value).toBe(4); + expect(data.find((item: any) => item.id === '2')._sum.value).toBe(3); + }); + + await makeTestClient('/m/delete', { getPrisma: () => prisma }, { where: { id: '1' } }) + .del('/') + .expect(200); + expect(await prisma.m.count()).toBe(1); + + await makeTestClient('/m/deleteMany', { getPrisma: () => prisma }, {}) + .del('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json.count).toBe(1); + }); + expect(await prisma.m.count()).toBe(0); + }); + + it('access policy crud', async () => { + const model = ` +model M { + id String @id @default(cuid()) + value Int + + @@allow('create', true) + @@allow('read', value > 0) + @@allow('update', future().value > 1) + @@allow('delete', value > 2) +} + `; + + const { withPresets } = await loadSchema(model); + + await makeTestClient('/m/create', { getPrisma: () => withPresets() }) + .post('/m/create') + .send({ data: { value: 0 } }) + .expect(403) + .expect((resp) => { + expect(resp.body.reason).toBe('RESULT_NOT_READABLE'); + }); + + await makeTestClient('/m/create', { getPrisma: () => withPresets() }) + .post('/') + .send({ data: { id: '1', value: 1 } }) + .expect(201); + + await makeTestClient('/m/findMany', { getPrisma: () => withPresets() }) + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body.json).toHaveLength(1); + }); + + await makeTestClient('/m/update', { getPrisma: () => withPresets() }) + .put('/') + .send({ where: { id: '1' }, data: { value: 0 } }) + .expect(403); + + await makeTestClient('/m/update', { getPrisma: () => withPresets() }) + .put('/') + .send({ where: { id: '1' }, data: { value: 2 } }) + .expect(200); + + await makeTestClient('/m/delete', { getPrisma: () => withPresets() }, { where: { id: '1' } }) + .del('/') + .expect(403); + + await makeTestClient('/m/update', { getPrisma: () => withPresets() }) + .put('/') + .send({ where: { id: '1' }, data: { value: 3 } }) + .expect(200); + + await makeTestClient('/m/delete', { getPrisma: () => withPresets() }, { where: { id: '1' } }) + .del('/') + .expect(200); + }); +}); diff --git a/packages/plugins/react/package.json b/packages/plugins/react/package.json index 8358e9c37..6f7988c36 100644 --- a/packages/plugins/react/package.json +++ b/packages/plugins/react/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/react", "displayName": "ZenStack plugin and runtime for ReactJS", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "description": "ZenStack plugin and runtime for ReactJS", "main": "index.js", "repository": { diff --git a/packages/plugins/react/src/react-hooks-generator.ts b/packages/plugins/react/src/react-hooks-generator.ts index 65b65c984..cca0a6e34 100644 --- a/packages/plugins/react/src/react-hooks-generator.ts +++ b/packages/plugins/react/src/react-hooks-generator.ts @@ -35,7 +35,7 @@ function wrapReadbackErrorCheck(code: string) { return `try { ${code} } catch (err: any) { - if (err.info?.prisma && err.info?.code === 'P2004' && err.info?.extra === 'RESULT_NOT_READABLE') { + if (err.info?.prisma && err.info?.code === 'P2004' && err.info?.reason === 'RESULT_NOT_READABLE') { // unable to readback data return undefined; } else { diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 3411bed37..6757d8718 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 7bd63985f..21d07c273 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", diff --git a/packages/runtime/src/enhancements/policy/handler.ts b/packages/runtime/src/enhancements/policy/handler.ts index 63d8d51c6..03a4e37f1 100644 --- a/packages/runtime/src/enhancements/policy/handler.ts +++ b/packages/runtime/src/enhancements/policy/handler.ts @@ -289,7 +289,7 @@ export class PolicyProxyHandler implements Pr const result = await this.utils.readWithCheck(this.model, readArgs); if (result.length === 0) { this.logger.warn(`${action} result cannot be read back`); - throw this.utils.deniedByPolicy(this.model, operation, 'RESULT_NOT_READABLE'); + throw this.utils.deniedByPolicy(this.model, operation, 'result is not allowed to be read back'); } else if (result.length > 1) { throw this.utils.unknownError('write unexpected resulted in multiple readback entities'); } diff --git a/packages/runtime/src/enhancements/policy/policy-utils.ts b/packages/runtime/src/enhancements/policy/policy-utils.ts index 5c2af1714..892638753 100644 --- a/packages/runtime/src/enhancements/policy/policy-utils.ts +++ b/packages/runtime/src/enhancements/policy/policy-utils.ts @@ -647,7 +647,7 @@ export class PolicyUtil { deniedByPolicy(model: string, operation: PolicyOperationKind, extra?: string) { return new PrismaClientKnownRequestError( `denied by policy: ${model} entities failed '${operation}' check${extra ? ', ' + extra : ''}`, - { clientVersion: getVersion(), code: 'P2004' } + { clientVersion: getVersion(), code: 'P2004', meta: { reason: 'RESULT_NOT_READABLE' } } ); } diff --git a/packages/runtime/src/error.ts b/packages/runtime/src/error.ts index ecde96a8d..0c8119cb1 100644 --- a/packages/runtime/src/error.ts +++ b/packages/runtime/src/error.ts @@ -1,5 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -export function isPrismaClientKnownRequestError(err: any): err is { code: string; message: string } { +export function isPrismaClientKnownRequestError( + err: any +): err is { code: string; message: string; meta?: Record } { return err.__proto__.constructor.name === 'PrismaClientKnownRequestError'; } diff --git a/packages/schema/package.json b/packages/schema/package.json index 7a890fe6b..92132cec5 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "A toolkit for building secure CRUD apps with Next.js + Typescript", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "author": { "name": "ZenStack Team" }, diff --git a/packages/schema/src/cli/index.ts b/packages/schema/src/cli/index.ts index 471f6e666..17557638b 100644 --- a/packages/schema/src/cli/index.ts +++ b/packages/schema/src/cli/index.ts @@ -32,9 +32,12 @@ export const initAction = async ( export const generateAction = async (options: { schema: string; packageManager: PackageManagers | undefined; + dependencyCheck: boolean; }): Promise => { - checkRequiredPackage('prisma', requiredPrismaVersion); - checkRequiredPackage('@prisma/client', requiredPrismaVersion); + if (options.dependencyCheck) { + checkRequiredPackage('prisma', requiredPrismaVersion); + checkRequiredPackage('@prisma/client', requiredPrismaVersion); + } await telemetry.trackSpan( 'cli:command:start', 'cli:command:complete', @@ -90,6 +93,8 @@ export function createProgram() { 'pnpm', ]); + const noDependencyCheck = new Option('--no-dependency-check', 'do not check if dependencies are installed'); + program .command('init') .description('Initialize an existing project for ZenStack.') @@ -105,9 +110,10 @@ export function createProgram() { program .command('generate') - .description('Generates RESTful API and Typescript client for your data model.') + .description('Run code generation.') .addOption(schemaOption) .addOption(pmOption) + .addOption(noDependencyCheck) .action(generateAction); return program; } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index e4a455ffa..2fd87c73f 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { diff --git a/packages/testtools/.eslintrc.json b/packages/testtools/.eslintrc.json new file mode 100644 index 000000000..0a913e874 --- /dev/null +++ b/packages/testtools/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": ["@typescript-eslint"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ] +} diff --git a/packages/testtools/LICENSE b/packages/testtools/LICENSE new file mode 120000 index 000000000..30cff7403 --- /dev/null +++ b/packages/testtools/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/packages/testtools/README.md b/packages/testtools/README.md new file mode 100644 index 000000000..40164a988 --- /dev/null +++ b/packages/testtools/README.md @@ -0,0 +1 @@ +# ZenStack Test Tools diff --git a/packages/testtools/package.json b/packages/testtools/package.json new file mode 100644 index 000000000..89630581f --- /dev/null +++ b/packages/testtools/package.json @@ -0,0 +1,33 @@ +{ + "name": "@zenstackhq/testtools", + "version": "1.0.0-alpha.48", + "description": "ZenStack Test Tools", + "main": "index.js", + "publishConfig": { + "directory": "dist", + "linkDirectory": true + }, + "scripts": { + "clean": "rimraf dist", + "lint": "eslint src --ext ts", + "build": "pnpm lint && pnpm clean && tsc && copyfiles ./package.json ./LICENSE ./README.md dist && copyfiles -u 1 src/package.template.json src/.npmrc.template dist", + "watch": "tsc --watch", + "prepublishOnly": "pnpm build" + }, + "keywords": [], + "author": "", + "license": "MIT", + "dependencies": { + "@prisma/client": "^4.7.0", + "@zenstackhq/runtime": "workspace:*", + "tmp": "^0.2.1" + }, + "devDependencies": { + "@types/node": "^18.14.2", + "@types/tmp": "^0.2.3", + "copyfiles": "^2.4.1", + "prisma": "~4.7.0", + "rimraf": "^3.0.2", + "typescript": "^4.9.5" + } +} diff --git a/packages/testtools/src/.npmrc.template b/packages/testtools/src/.npmrc.template new file mode 100644 index 000000000..14f2c2865 --- /dev/null +++ b/packages/testtools/src/.npmrc.template @@ -0,0 +1 @@ +cache=/.npmcache diff --git a/packages/testtools/src/index.ts b/packages/testtools/src/index.ts new file mode 100644 index 000000000..e27a6e2f5 --- /dev/null +++ b/packages/testtools/src/index.ts @@ -0,0 +1 @@ +export * from './schema'; diff --git a/packages/testtools/src/package.template.json b/packages/testtools/src/package.template.json new file mode 100644 index 000000000..ef8723f55 --- /dev/null +++ b/packages/testtools/src/package.template.json @@ -0,0 +1,20 @@ +{ + "name": "test-run", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@prisma/client": "^4.0.0", + "@zenstackhq/runtime": "file:/packages/runtime/dist", + "prisma": "^4.0.0", + "typescript": "^4.9.3", + "zenstack": "file:/packages/schema/dist", + "zod": "^3.19.1" + } +} diff --git a/tests/integration/utils/utils.ts b/packages/testtools/src/schema.ts similarity index 56% rename from tests/integration/utils/utils.ts rename to packages/testtools/src/schema.ts index 5751f9022..d990c0e2e 100644 --- a/tests/integration/utils/utils.ts +++ b/packages/testtools/src/schema.ts @@ -1,12 +1,50 @@ -import { AuthUser, DbOperations, withOmit, withPassword, withPolicy, withPresets } from '@zenstackhq/runtime'; +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { withOmit, withPassword, withPolicy, withPresets, type AuthUser, type DbOperations } from '@zenstackhq/runtime'; import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; +import tmp from 'tmp'; -export const MODEL_PRELUDE = ` +export type WeakDbOperations = { + [key in keyof DbOperations]: (...args: any[]) => Promise; +}; + +export type WeakDbClientContract = Record & { + $on(eventType: any, callback: (event: any) => void): void; + $use(cb: any): void; + $disconnect: () => Promise; + $transaction: (input: ((tx: WeakDbClientContract) => Promise) | any[], options?: any) => Promise; + $queryRaw: (query: TemplateStringsArray, ...args: any[]) => Promise; + $executeRaw: (query: TemplateStringsArray, ...args: any[]) => Promise; + $extends: (args: any) => WeakDbClientContract; +}; + +export function run(cmd: string, env?: Record, cwd?: string) { + execSync(cmd, { + stdio: 'pipe', + encoding: 'utf-8', + env: { ...process.env, DO_NOT_TRACK: '1', ...env }, + cwd, + }); +} + +function getWorkspaceRoot(start: string) { + let curr = start; + while (curr && curr !== '/') { + if (fs.existsSync(path.join(curr, 'pnpm-workspace.yaml'))) { + return curr; + } else { + curr = path.dirname(curr); + } + } + return undefined; +} + +const MODEL_PRELUDE = ` datasource db { provider = 'sqlite' - url = 'file:./operations.db' + url = 'file:./test.db' } generator js { @@ -26,44 +64,32 @@ plugin policy { } `; -export function run(cmd: string, env?: Record, cwd?: string) { - execSync(cmd, { - stdio: 'pipe', - encoding: 'utf-8', - env: { ...process.env, DO_NOT_TRACK: '1', ...env }, - cwd, - }); +export async function loadSchemaFromFile(schemaFile: string) { + const content = fs.readFileSync(schemaFile, { encoding: 'utf-8' }); + return loadSchema(content); } -export type WeakDbClientContract = Record & { - $on(eventType: any, callback: (event: any) => void): void; - $use(cb: any): void; - $disconnect: () => Promise; - $transaction: (input: ((tx: WeakDbClientContract) => Promise) | any[], options?: any) => Promise; - $queryRaw: (query: TemplateStringsArray, ...args: any[]) => Promise; - $executeRaw: (query: TemplateStringsArray, ...args: any[]) => Promise; - $extends: (args: any) => WeakDbClientContract; -}; +export async function loadSchema(schema: string) { + const { name: workDir } = tmp.dirSync(); -export type WeakDbOperations = { - [key in keyof DbOperations]: (...args: any[]) => Promise; -}; + const root = getWorkspaceRoot(__dirname); + if (!root) { + throw new Error('Could not find workspace root'); + } + console.log('Workspace root:', root); -export async function loadPrismaFromModelFile(testName: string, modelFile: string) { - const content = fs.readFileSync(modelFile, { encoding: 'utf-8' }); - return loadPrisma(testName, content); -} + const pkgContent = fs.readFileSync(path.join(__dirname, 'package.template.json'), { encoding: 'utf-8' }); + fs.writeFileSync(path.join(workDir, 'package.json'), pkgContent.replaceAll('', root)); -export async function loadPrisma(testName: string, model: string) { - const workDir = path.resolve('test-run/cases', testName); - if (fs.existsSync(workDir)) { - fs.rmSync(workDir, { recursive: true, force: true }); - } - fs.mkdirSync(workDir, { recursive: true }); + const npmrcContent = fs.readFileSync(path.join(__dirname, '.npmrc.template'), { encoding: 'utf-8' }); + fs.writeFileSync(path.join(workDir, '.npmrc'), npmrcContent.replaceAll('', root)); + + console.log('Workdir:', workDir); process.chdir(workDir); - fs.writeFileSync('schema.zmodel', model); - run('npx zenstack generate'); + fs.writeFileSync('schema.zmodel', `${MODEL_PRELUDE}\n${schema}`); + run('npm install'); + run('npx zenstack generate --no-dependency-check'); run('npx prisma db push'); const PrismaClient = require(path.join(workDir, '.prisma')).PrismaClient; diff --git a/packages/testtools/tsconfig.json b/packages/testtools/tsconfig.json new file mode 100644 index 000000000..f6dff1942 --- /dev/null +++ b/packages/testtools/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "CommonJS", + "lib": ["ESNext", "DOM"], + "sourceMap": true, + "outDir": "dist", + "strict": true, + "noUnusedLocals": true, + "noImplicitReturns": true, + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "resolveJsonModule": true, + "strictPropertyInitialization": false, + "paths": {} + }, + "include": ["src/**/*.ts"], + "exclude": ["dist", "node_modules"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c62b8d24d..a7d3a8c9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,23 +28,37 @@ importers: packages/next: specifiers: + '@types/jest': ^29.4.0 '@types/react': ^18.0.26 + '@types/supertest': ^2.0.12 '@zenstackhq/runtime': workspace:* + '@zenstackhq/testtools': workspace:* copyfiles: ^2.4.1 + jest: ^29.4.3 next: ^12.3.1 || ^13 react: ^17.0.2 || ^18 rimraf: ^3.0.2 superjson: ^1.11.0 + supertest: ^6.3.3 + tmp: ^0.2.1 + ts-jest: ^29.0.5 typescript: ^4.9.4 dependencies: '@zenstackhq/runtime': link:../runtime/dist - next: 12.3.1_biqbaboplfbrettd7655fr4n2y - superjson: 1.11.0 + '@zenstackhq/testtools': link:../testtools/dist + next: 12.3.1_672uxklweod7ene3nqtsh262ca + tmp: 0.2.1 devDependencies: + '@types/jest': 29.4.0 '@types/react': 18.0.26 + '@types/supertest': 2.0.12 copyfiles: 2.4.1 + jest: 29.4.3 react: 18.2.0 rimraf: 3.0.2 + superjson: 1.11.0 + supertest: 6.3.3 + ts-jest: 29.0.5_itrzs5lisv6omhzjwqg6f7v6de typescript: 4.9.4 publishDirectory: dist @@ -286,6 +300,30 @@ importers: typescript: 4.9.4 publishDirectory: dist + packages/testtools: + specifiers: + '@prisma/client': ^4.7.0 + '@types/node': ^18.14.2 + '@types/tmp': ^0.2.3 + '@zenstackhq/runtime': workspace:* + copyfiles: ^2.4.1 + prisma: ~4.7.0 + rimraf: ^3.0.2 + tmp: ^0.2.1 + typescript: ^4.9.5 + dependencies: + '@prisma/client': 4.7.1_prisma@4.7.0 + '@zenstackhq/runtime': link:../runtime/dist + tmp: 0.2.1 + devDependencies: + '@types/node': 18.14.2 + '@types/tmp': 0.2.3 + copyfiles: 2.4.1 + prisma: 4.7.0 + rimraf: 3.0.2 + typescript: 4.9.5 + publishDirectory: dist + tests/integration: specifiers: '@prisma/client': ^4.7.0 @@ -299,6 +337,7 @@ importers: '@zenstackhq/next': workspace:* '@zenstackhq/react': workspace:* '@zenstackhq/runtime': workspace:* + '@zenstackhq/testtools': workspace:* '@zenstackhq/trpc': workspace:* bcryptjs: ^2.4.3 decimal.js: ^10.4.2 @@ -320,6 +359,7 @@ importers: dependencies: '@prisma/client': 4.7.1_prisma@4.7.0 '@types/node': 14.18.29 + '@zenstackhq/testtools': link:../../packages/testtools/dist bcryptjs: 2.4.3 decimal.js: 10.4.2 sleep-promise: 9.1.0 @@ -357,7 +397,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 - dev: true /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} @@ -373,7 +412,6 @@ packages: /@babel/compat-data/7.20.5: resolution: {integrity: sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==} engines: {node: '>=6.9.0'} - dev: true /@babel/core/7.19.3: resolution: {integrity: sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==} @@ -419,7 +457,6 @@ packages: semver: 6.3.0 transitivePeerDependencies: - supports-color - dev: true /@babel/generator/7.19.5: resolution: {integrity: sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==} @@ -446,7 +483,6 @@ packages: '@babel/types': 7.20.5 '@jridgewell/gen-mapping': 0.3.2 jsesc: 2.5.2 - dev: true /@babel/helper-compilation-targets/7.19.3_@babel+core@7.19.3: resolution: {integrity: sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==} @@ -472,12 +508,10 @@ packages: '@babel/helper-validator-option': 7.18.6 browserslist: 4.21.4 semver: 6.3.0 - dev: true /@babel/helper-environment-visitor/7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-function-name/7.19.0: resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} @@ -485,21 +519,18 @@ packages: dependencies: '@babel/template': 7.18.10 '@babel/types': 7.20.5 - dev: true /@babel/helper-hoist-variables/7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.5 - dev: true /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.5 - dev: true /@babel/helper-module-transforms/7.19.0: resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==} @@ -531,7 +562,6 @@ packages: '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color - dev: true /@babel/helper-plugin-utils/7.19.0: resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} @@ -555,19 +585,16 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.5 - dev: true /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.5 - dev: true /@babel/helper-string-parser/7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier/7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} @@ -576,7 +603,6 @@ packages: /@babel/helper-validator-option/7.18.6: resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} engines: {node: '>=6.9.0'} - dev: true /@babel/helpers/7.19.4: resolution: {integrity: sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==} @@ -598,7 +624,6 @@ packages: '@babel/types': 7.20.5 transitivePeerDependencies: - supports-color - dev: true /@babel/highlight/7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} @@ -630,7 +655,6 @@ packages: hasBin: true dependencies: '@babel/types': 7.20.5 - dev: true /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.19.3: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} @@ -914,7 +938,6 @@ packages: '@babel/code-frame': 7.18.6 '@babel/parser': 7.20.5 '@babel/types': 7.20.5 - dev: true /@babel/traverse/7.19.4: resolution: {integrity: sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==} @@ -968,7 +991,6 @@ packages: globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true /@babel/types/7.19.4: resolution: {integrity: sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==} @@ -986,7 +1008,6 @@ packages: '@babel/helper-string-parser': 7.19.4 '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 - dev: true /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1314,7 +1335,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 jest-message-util: 29.0.3 jest-util: 29.0.3 @@ -1326,13 +1347,25 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 jest-message-util: 29.2.1 jest-util: 29.2.1 slash: 3.0.0 dev: true + /@jest/console/29.4.3: + resolution: {integrity: sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + chalk: 4.1.2 + jest-message-util: 29.4.3 + jest-util: 29.4.3 + slash: 3.0.0 + dev: true + /@jest/core/29.0.3_ts-node@10.9.1: resolution: {integrity: sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1347,14 +1380,14 @@ packages: '@jest/test-result': 29.0.3 '@jest/transform': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.4.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.0.0 - jest-config: 29.0.3_sfpnjnnyjha3fwltwg26xa3eti + jest-config: 29.0.3_jboh4c3iv3wxuja4m36ecyac7e jest-haste-map: 29.0.3 jest-message-util: 29.0.3 jest-regex-util: 29.0.0 @@ -1389,14 +1422,14 @@ packages: '@jest/test-result': 29.2.1 '@jest/transform': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.5.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.2.0 - jest-config: 29.2.1_sfpnjnnyjha3fwltwg26xa3eti + jest-config: 29.2.1_jboh4c3iv3wxuja4m36ecyac7e jest-haste-map: 29.2.1 jest-message-util: 29.2.1 jest-regex-util: 29.2.0 @@ -1417,13 +1450,55 @@ packages: - ts-node dev: true + /@jest/core/29.4.3: + resolution: {integrity: sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 29.4.3 + '@jest/reporters': 29.4.3 + '@jest/test-result': 29.4.3 + '@jest/transform': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.7.1 + exit: 0.1.2 + graceful-fs: 4.2.10 + jest-changed-files: 29.4.3 + jest-config: 29.4.3_@types+node@18.14.2 + jest-haste-map: 29.4.3 + jest-message-util: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.4.3 + jest-resolve-dependencies: 29.4.3 + jest-runner: 29.4.3 + jest-runtime: 29.4.3 + jest-snapshot: 29.4.3 + jest-util: 29.4.3 + jest-validate: 29.4.3 + jest-watcher: 29.4.3 + micromatch: 4.0.5 + pretty-format: 29.4.3 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + /@jest/environment/29.0.3: resolution: {integrity: sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/fake-timers': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-mock: 29.0.3 dev: true @@ -1433,7 +1508,7 @@ packages: dependencies: '@jest/fake-timers': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-mock: 29.2.1 dev: true @@ -1443,10 +1518,20 @@ packages: dependencies: '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.18 + '@types/node': 18.14.2 jest-mock: 29.3.1 dev: true + /@jest/environment/29.4.3: + resolution: {integrity: sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/fake-timers': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + jest-mock: 29.4.3 + dev: true + /@jest/expect-utils/29.0.3: resolution: {integrity: sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1468,6 +1553,13 @@ packages: jest-get-type: 29.2.0 dev: true + /@jest/expect-utils/29.4.3: + resolution: {integrity: sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.4.3 + dev: true + /@jest/expect/29.0.3: resolution: {integrity: sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1498,13 +1590,23 @@ packages: - supports-color dev: true + /@jest/expect/29.4.3: + resolution: {integrity: sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.4.3 + jest-snapshot: 29.4.3 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/fake-timers/29.0.3: resolution: {integrity: sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.0.3 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-message-util: 29.0.3 jest-mock: 29.0.3 jest-util: 29.0.3 @@ -1516,7 +1618,7 @@ packages: dependencies: '@jest/types': 29.2.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-message-util: 29.2.1 jest-mock: 29.2.1 jest-util: 29.2.1 @@ -1528,12 +1630,24 @@ packages: dependencies: '@jest/types': 29.3.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.11.18 + '@types/node': 18.14.2 jest-message-util: 29.3.1 jest-mock: 29.3.1 jest-util: 29.3.1 dev: true + /@jest/fake-timers/29.4.3: + resolution: {integrity: sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + '@sinonjs/fake-timers': 10.0.2 + '@types/node': 18.14.2 + jest-message-util: 29.4.3 + jest-mock: 29.4.3 + jest-util: 29.4.3 + dev: true + /@jest/globals/29.2.1: resolution: {integrity: sha512-Z4EejYPP1OPVq2abk1+9urAwJqkgw5jB2UJGlPjb5ZwzPQF8WLMcigKEfFzZb2OHhEVPP0RZD0/DbVTY1R6iQA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1558,6 +1672,18 @@ packages: - supports-color dev: true + /@jest/globals/29.4.3: + resolution: {integrity: sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.4.3 + '@jest/expect': 29.4.3 + '@jest/types': 29.4.3 + jest-mock: 29.4.3 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/reporters/29.0.3: resolution: {integrity: sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1573,7 +1699,7 @@ packages: '@jest/transform': 29.0.3 '@jest/types': 29.0.3 '@jridgewell/trace-mapping': 0.3.16 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -1611,7 +1737,7 @@ packages: '@jest/transform': 29.2.1 '@jest/types': 29.2.1 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -1633,6 +1759,43 @@ packages: - supports-color dev: true + /@jest/reporters/29.4.3: + resolution: {integrity: sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.4.3 + '@jest/test-result': 29.4.3 + '@jest/transform': 29.4.3 + '@jest/types': 29.4.3 + '@jridgewell/trace-mapping': 0.3.17 + '@types/node': 18.14.2 + chalk: 4.1.2 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + jest-message-util: 29.4.3 + jest-util: 29.4.3 + jest-worker: 29.4.3 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.0.1 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/schemas/29.0.0: resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1640,6 +1803,13 @@ packages: '@sinclair/typebox': 0.24.47 dev: true + /@jest/schemas/29.4.3: + resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.25.24 + dev: true + /@jest/source-map/29.0.0: resolution: {integrity: sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1658,6 +1828,15 @@ packages: graceful-fs: 4.2.10 dev: true + /@jest/source-map/29.4.3: + resolution: {integrity: sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + callsites: 3.1.0 + graceful-fs: 4.2.10 + dev: true + /@jest/test-result/29.0.3: resolution: {integrity: sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1678,6 +1857,16 @@ packages: collect-v8-coverage: 1.0.1 dev: true + /@jest/test-result/29.4.3: + resolution: {integrity: sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.4.3 + '@jest/types': 29.4.3 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 + dev: true + /@jest/test-sequencer/29.0.3: resolution: {integrity: sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1698,6 +1887,16 @@ packages: slash: 3.0.0 dev: true + /@jest/test-sequencer/29.4.3: + resolution: {integrity: sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.4.3 + graceful-fs: 4.2.10 + jest-haste-map: 29.4.3 + slash: 3.0.0 + dev: true + /@jest/transform/29.0.3: resolution: {integrity: sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1767,6 +1966,29 @@ packages: - supports-color dev: true + /@jest/transform/29.4.3: + resolution: {integrity: sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.20.5 + '@jest/types': 29.4.3 + '@jridgewell/trace-mapping': 0.3.17 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.10 + jest-haste-map: 29.4.3 + jest-regex-util: 29.4.3 + jest-util: 29.4.3 + micromatch: 4.0.5 + pirates: 4.0.5 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/types/29.0.3: resolution: {integrity: sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -1774,7 +1996,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 '@types/yargs': 17.0.12 chalk: 4.1.2 dev: true @@ -1786,7 +2008,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -1798,7 +2020,19 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.18 + '@types/node': 18.14.2 + '@types/yargs': 17.0.13 + chalk: 4.1.2 + dev: true + + /@jest/types/29.4.3: + resolution: {integrity: sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.4.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 18.14.2 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true @@ -1809,7 +2043,6 @@ packages: dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/gen-mapping/0.3.2: resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} @@ -1818,21 +2051,17 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.14 '@jridgewell/trace-mapping': 0.3.17 - dev: true /@jridgewell/resolve-uri/3.1.0: resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/set-array/1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true /@jridgewell/trace-mapping/0.3.16: resolution: {integrity: sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==} @@ -1846,7 +2075,6 @@ packages: dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 - dev: true /@jridgewell/trace-mapping/0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -2218,12 +2446,28 @@ packages: resolution: {integrity: sha512-J4Xw0xYK4h7eC34MNOPQi6IkNxGRck6n4VJpWDzXIFVTW8I/D43Gf+NfWz/v/7NHlzWOPd3+T4PJ4OqklQ2u7A==} dev: true + /@sinclair/typebox/0.25.24: + resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} + dev: true + /@sinonjs/commons/1.8.3: resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} dependencies: type-detect: 4.0.8 dev: true + /@sinonjs/commons/2.0.0: + resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers/10.0.2: + resolution: {integrity: sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==} + dependencies: + '@sinonjs/commons': 2.0.0 + dev: true + /@sinonjs/fake-timers/9.1.2: resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} dependencies: @@ -2314,7 +2558,7 @@ packages: /@types/cross-spawn/6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.14.2 dev: false /@types/debug/4.1.7: @@ -2327,13 +2571,13 @@ packages: resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} dependencies: '@types/jsonfile': 6.1.1 - '@types/node': 18.11.18 + '@types/node': 18.14.2 dev: true /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.14.2 dev: true /@types/is-ci/3.0.0: @@ -2372,6 +2616,13 @@ packages: pretty-format: 29.2.1 dev: true + /@types/jest/29.4.0: + resolution: {integrity: sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==} + dependencies: + expect: 29.4.3 + pretty-format: 29.4.3 + dev: true + /@types/json-schema/7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true @@ -2379,7 +2630,7 @@ packages: /@types/jsonfile/6.1.1: resolution: {integrity: sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.14.2 dev: true /@types/minimist/1.2.2: @@ -2401,12 +2652,8 @@ packages: resolution: {integrity: sha512-Y6S38pFr04yb13qqHf8uk1nHE3lXgQ30WZbv1mLliV9pt0NjvqdWttLcrOYLnXbOafknVYRHZGoMSpR9UwfYow==} dev: true - /@types/node/18.11.13: - resolution: {integrity: sha512-IASpMGVcWpUsx5xBOrxMj7Bl8lqfuTY7FKAnPmu5cHkfQVWF8GulWS1jbRqA934qZL35xh5xN/+Xe/i26Bod4w==} - dev: true - - /@types/node/18.11.18: - resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} + /@types/node/18.14.2: + resolution: {integrity: sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==} /@types/normalize-package-data/2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -2463,7 +2710,7 @@ packages: resolution: {integrity: sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==} dependencies: '@types/cookiejar': 2.1.2 - '@types/node': 18.11.13 + '@types/node': 18.14.2 dev: true /@types/supertest/2.0.12: @@ -2836,6 +3083,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /asap/2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true + /astral-regex/2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -2850,6 +3101,10 @@ packages: resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} dev: false + /asynckit/0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} @@ -2903,6 +3158,24 @@ packages: - supports-color dev: true + /babel-jest/29.4.3_@babel+core@7.20.5: + resolution: {integrity: sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.20.5 + '@jest/transform': 29.4.3 + '@types/babel__core': 7.1.19 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.4.3_@babel+core@7.20.5 + chalk: 4.1.2 + graceful-fs: 4.2.10 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /babel-plugin-istanbul/6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} @@ -2936,6 +3209,16 @@ packages: '@types/babel__traverse': 7.18.2 dev: true + /babel-plugin-jest-hoist/29.4.3: + resolution: {integrity: sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.20.5 + '@types/babel__core': 7.1.19 + '@types/babel__traverse': 7.18.2 + dev: true + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.19.3: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: @@ -2998,6 +3281,17 @@ packages: babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 dev: true + /babel-preset-jest/29.4.3_@babel+core@7.20.5: + resolution: {integrity: sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + babel-plugin-jest-hoist: 29.4.3 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 + dev: true + /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -3064,7 +3358,6 @@ packages: electron-to-chromium: 1.4.284 node-releases: 2.0.6 update-browserslist-db: 1.0.10_browserslist@4.21.4 - dev: true /bs-logger/0.2.6: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} @@ -3380,6 +3673,13 @@ packages: engines: {node: '>=0.1.90'} dev: false + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + /command-line-args/5.2.1: resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} engines: {node: '>=4.0.0'} @@ -3418,6 +3718,10 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: false + /component-emitter/1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + /compress-commons/4.1.1: resolution: {integrity: sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==} engines: {node: '>= 10'} @@ -3457,18 +3761,20 @@ packages: /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true /convert-source-map/2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true + /cookiejar/2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + dev: true + /copy-anything/3.0.3: resolution: {integrity: sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw==} engines: {node: '>=12.13'} dependencies: is-what: 4.1.8 - dev: false /copyfiles/2.4.1: resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} @@ -3674,6 +3980,11 @@ packages: slash: 3.0.0 dev: false + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -3689,6 +4000,13 @@ packages: engines: {node: '>=8'} dev: true + /dezalgo/1.0.4: + resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} + dependencies: + asap: 2.0.6 + wrappy: 1.0.2 + dev: true + /diff-sequences/29.0.0: resolution: {integrity: sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3704,6 +4022,11 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /diff-sequences/29.4.3: + resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /diff/4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -3762,13 +4085,17 @@ packages: /electron-to-chromium/1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} - dev: true /emittery/0.10.2: resolution: {integrity: sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==} engines: {node: '>=12'} dev: true + /emittery/0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + /emoji-regex/8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4079,7 +4406,6 @@ packages: /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} - dev: true /escape-string-regexp/1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} @@ -4380,6 +4706,17 @@ packages: jest-util: 29.3.1 dev: true + /expect/29.4.3: + resolution: {integrity: sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.4.3 + jest-get-type: 29.4.3 + jest-matcher-utils: 29.4.3 + jest-message-util: 29.4.3 + jest-util: 29.4.3 + dev: true + /extendable-error/0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} dev: true @@ -4419,6 +4756,10 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: true + /fast-safe-stringify/2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: true + /fast-write-atomic/0.2.1: resolution: {integrity: sha512-WvJe06IfNYlr+6cO3uQkdKdy3Cb1LlCJSF8zRs2eT8yuhdbSlR9nIt+TgQ92RUxiRrQm+/S7RARnMfCs5iuAjw==} dev: false @@ -4516,6 +4857,24 @@ packages: is-callable: 1.2.7 dev: true + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /formidable/2.1.2: + resolution: {integrity: sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==} + dependencies: + dezalgo: 1.0.4 + hexoid: 1.0.0 + once: 1.4.0 + qs: 6.11.0 + dev: true + /fp-ts/2.13.1: resolution: {integrity: sha512-0eu5ULPS2c/jsa1lGFneEFFEdTbembJv8e4QKXeVJ3lm/5hyve06dlKZrpxmMwJt6rYen7sxmHHK2CLaXvWuWQ==} dev: false @@ -4606,7 +4965,6 @@ packages: /gensync/1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - dev: true /get-caller-file/2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} @@ -4674,7 +5032,6 @@ packages: /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - dev: true /globals/13.17.0: resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==} @@ -4787,6 +5144,11 @@ packages: tslib: 2.4.1 dev: false + /hexoid/1.0.0: + resolution: {integrity: sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==} + engines: {node: '>=8'} + dev: true + /hosted-git-info/2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -5100,7 +5462,6 @@ packages: /is-what/4.1.8: resolution: {integrity: sha512-yq8gMao5upkPoGEU9LsB2P+K3Kt8Q3fQFCGyNCWOAnJAMzEXVV9drYb0TXr42TTliLLhKIBvulgAXgtLLnwzGA==} engines: {node: '>=12.13'} - dev: false /is-windows/1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} @@ -5198,6 +5559,14 @@ packages: p-limit: 3.1.0 dev: true + /jest-changed-files/29.4.3: + resolution: {integrity: sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + p-limit: 3.1.0 + dev: true + /jest-circus/29.0.3: resolution: {integrity: sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5206,7 +5575,7 @@ packages: '@jest/expect': 29.0.3 '@jest/test-result': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -5233,7 +5602,7 @@ packages: '@jest/expect': 29.2.1 '@jest/test-result': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -5252,6 +5621,33 @@ packages: - supports-color dev: true + /jest-circus/29.4.3: + resolution: {integrity: sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.4.3 + '@jest/expect': 29.4.3 + '@jest/test-result': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 29.4.3 + jest-matcher-utils: 29.4.3 + jest-message-util: 29.4.3 + jest-runtime: 29.4.3 + jest-snapshot: 29.4.3 + jest-util: 29.4.3 + p-limit: 3.1.0 + pretty-format: 29.4.3 + slash: 3.0.0 + stack-utils: 2.0.5 + transitivePeerDependencies: + - supports-color + dev: true + /jest-cli/29.0.3_johvxhudwcpndp4mle25vwrlq4: resolution: {integrity: sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5308,7 +5704,35 @@ packages: - ts-node dev: true - /jest-config/29.0.3_johvxhudwcpndp4mle25vwrlq4: + /jest-cli/29.4.3: + resolution: {integrity: sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.4.3 + '@jest/test-result': 29.4.3 + '@jest/types': 29.4.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.10 + import-local: 3.1.0 + jest-config: 29.4.3 + jest-util: 29.4.3 + jest-validate: 29.4.3 + prompts: 2.4.2 + yargs: 17.6.2 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /jest-config/29.0.3_jboh4c3iv3wxuja4m36ecyac7e: resolution: {integrity: sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5323,7 +5747,7 @@ packages: '@babel/core': 7.19.3 '@jest/test-sequencer': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 14.18.29 + '@types/node': 18.14.2 babel-jest: 29.0.3_@babel+core@7.19.3 chalk: 4.1.2 ci-info: 3.4.0 @@ -5348,7 +5772,7 @@ packages: - supports-color dev: true - /jest-config/29.0.3_sfpnjnnyjha3fwltwg26xa3eti: + /jest-config/29.0.3_johvxhudwcpndp4mle25vwrlq4: resolution: {integrity: sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5363,7 +5787,7 @@ packages: '@babel/core': 7.19.3 '@jest/test-sequencer': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 14.18.29 babel-jest: 29.0.3_@babel+core@7.19.3 chalk: 4.1.2 ci-info: 3.4.0 @@ -5428,7 +5852,7 @@ packages: - supports-color dev: true - /jest-config/29.2.1_sfpnjnnyjha3fwltwg26xa3eti: + /jest-config/29.2.1_jboh4c3iv3wxuja4m36ecyac7e: resolution: {integrity: sha512-EV5F1tQYW/quZV2br2o88hnYEeRzG53Dfi6rSG3TZBuzGQ6luhQBux/RLlU5QrJjCdq3LXxRRM8F1LP6DN1ycA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5443,7 +5867,7 @@ packages: '@babel/core': 7.20.5 '@jest/test-sequencer': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 babel-jest: 29.2.1_@babel+core@7.20.5 chalk: 4.1.2 ci-info: 3.5.0 @@ -5468,6 +5892,83 @@ packages: - supports-color dev: true + /jest-config/29.4.3: + resolution: {integrity: sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.20.5 + '@jest/test-sequencer': 29.4.3 + '@jest/types': 29.4.3 + babel-jest: 29.4.3_@babel+core@7.20.5 + chalk: 4.1.2 + ci-info: 3.7.1 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.4.3 + jest-environment-node: 29.4.3 + jest-get-type: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.4.3 + jest-runner: 29.4.3 + jest-util: 29.4.3 + jest-validate: 29.4.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.4.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-config/29.4.3_@types+node@18.14.2: + resolution: {integrity: sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.20.5 + '@jest/test-sequencer': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + babel-jest: 29.4.3_@babel+core@7.20.5 + chalk: 4.1.2 + ci-info: 3.7.1 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.4.3 + jest-environment-node: 29.4.3 + jest-get-type: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.4.3 + jest-runner: 29.4.3 + jest-util: 29.4.3 + jest-validate: 29.4.3 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.4.3 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /jest-diff/29.0.3: resolution: {integrity: sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5498,6 +5999,16 @@ packages: pretty-format: 29.3.1 dev: true + /jest-diff/29.4.3: + resolution: {integrity: sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.4.3 + jest-get-type: 29.4.3 + pretty-format: 29.4.3 + dev: true + /jest-docblock/29.0.0: resolution: {integrity: sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5512,6 +6023,13 @@ packages: detect-newline: 3.1.0 dev: true + /jest-docblock/29.4.3: + resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + /jest-each/29.0.3: resolution: {integrity: sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5534,6 +6052,17 @@ packages: pretty-format: 29.2.1 dev: true + /jest-each/29.4.3: + resolution: {integrity: sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + chalk: 4.1.2 + jest-get-type: 29.4.3 + jest-util: 29.4.3 + pretty-format: 29.4.3 + dev: true + /jest-environment-node/29.0.3: resolution: {integrity: sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5541,7 +6070,7 @@ packages: '@jest/environment': 29.0.3 '@jest/fake-timers': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-mock: 29.0.3 jest-util: 29.0.3 dev: true @@ -5553,11 +6082,23 @@ packages: '@jest/environment': 29.2.1 '@jest/fake-timers': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-mock: 29.2.1 jest-util: 29.2.1 dev: true + /jest-environment-node/29.4.3: + resolution: {integrity: sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.4.3 + '@jest/fake-timers': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + jest-mock: 29.4.3 + jest-util: 29.4.3 + dev: true + /jest-fetch-mock/3.0.3: resolution: {integrity: sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==} dependencies: @@ -5577,13 +6118,18 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /jest-get-type/29.4.3: + resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /jest-haste-map/29.0.3: resolution: {integrity: sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.0.3 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.13 + '@types/node': 18.14.2 anymatch: 3.1.2 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -5602,7 +6148,7 @@ packages: dependencies: '@jest/types': 29.2.1 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.13 + '@types/node': 18.14.2 anymatch: 3.1.2 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -5621,7 +6167,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.18 + '@types/node': 18.14.2 anymatch: 3.1.2 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -5634,6 +6180,25 @@ packages: fsevents: 2.3.2 dev: true + /jest-haste-map/29.4.3: + resolution: {integrity: sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + '@types/graceful-fs': 4.1.5 + '@types/node': 18.14.2 + anymatch: 3.1.2 + fb-watchman: 2.0.2 + graceful-fs: 4.2.10 + jest-regex-util: 29.4.3 + jest-util: 29.4.3 + jest-worker: 29.4.3 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /jest-leak-detector/29.0.3: resolution: {integrity: sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5650,6 +6215,14 @@ packages: pretty-format: 29.2.1 dev: true + /jest-leak-detector/29.4.3: + resolution: {integrity: sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.4.3 + pretty-format: 29.4.3 + dev: true + /jest-matcher-utils/29.0.3: resolution: {integrity: sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5680,6 +6253,16 @@ packages: pretty-format: 29.3.1 dev: true + /jest-matcher-utils/29.4.3: + resolution: {integrity: sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.4.3 + jest-get-type: 29.4.3 + pretty-format: 29.4.3 + dev: true + /jest-message-util/29.0.3: resolution: {integrity: sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5725,12 +6308,27 @@ packages: stack-utils: 2.0.5 dev: true + /jest-message-util/29.4.3: + resolution: {integrity: sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 29.4.3 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 29.4.3 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + /jest-mock/29.0.3: resolution: {integrity: sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 dev: true /jest-mock/29.2.1: @@ -5738,7 +6336,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-util: 29.2.1 dev: true @@ -5747,10 +6345,19 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.18 + '@types/node': 18.14.2 jest-util: 29.3.1 dev: true + /jest-mock/29.4.3: + resolution: {integrity: sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + jest-util: 29.4.3 + dev: true + /jest-pnp-resolver/1.2.2_jest-resolve@29.0.3: resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} engines: {node: '>=6'} @@ -5775,6 +6382,18 @@ packages: jest-resolve: 29.2.1 dev: true + /jest-pnp-resolver/1.2.2_jest-resolve@29.4.3: + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.4.3 + dev: true + /jest-regex-util/29.0.0: resolution: {integrity: sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5785,6 +6404,11 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true + /jest-regex-util/29.4.3: + resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /jest-resolve-dependencies/29.0.3: resolution: {integrity: sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5805,6 +6429,16 @@ packages: - supports-color dev: true + /jest-resolve-dependencies/29.4.3: + resolution: {integrity: sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.4.3 + jest-snapshot: 29.4.3 + transitivePeerDependencies: + - supports-color + dev: true + /jest-resolve/29.0.3: resolution: {integrity: sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5835,6 +6469,21 @@ packages: slash: 3.0.0 dev: true + /jest-resolve/29.4.3: + resolution: {integrity: sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.10 + jest-haste-map: 29.4.3 + jest-pnp-resolver: 1.2.2_jest-resolve@29.4.3 + jest-util: 29.4.3 + jest-validate: 29.4.3 + resolve: 1.22.1 + resolve.exports: 2.0.0 + slash: 3.0.0 + dev: true + /jest-runner/29.0.3: resolution: {integrity: sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5844,7 +6493,7 @@ packages: '@jest/test-result': 29.0.3 '@jest/transform': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 emittery: 0.10.2 graceful-fs: 4.2.10 @@ -5873,7 +6522,7 @@ packages: '@jest/test-result': 29.2.1 '@jest/transform': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 emittery: 0.10.2 graceful-fs: 4.2.10 @@ -5893,6 +6542,35 @@ packages: - supports-color dev: true + /jest-runner/29.4.3: + resolution: {integrity: sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.4.3 + '@jest/environment': 29.4.3 + '@jest/test-result': 29.4.3 + '@jest/transform': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.10 + jest-docblock: 29.4.3 + jest-environment-node: 29.4.3 + jest-haste-map: 29.4.3 + jest-leak-detector: 29.4.3 + jest-message-util: 29.4.3 + jest-resolve: 29.4.3 + jest-runtime: 29.4.3 + jest-util: 29.4.3 + jest-watcher: 29.4.3 + jest-worker: 29.4.3 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + /jest-runtime/29.0.3: resolution: {integrity: sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5904,7 +6582,7 @@ packages: '@jest/test-result': 29.0.3 '@jest/transform': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -5934,7 +6612,7 @@ packages: '@jest/test-result': 29.2.1 '@jest/transform': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -5953,6 +6631,36 @@ packages: - supports-color dev: true + /jest-runtime/29.4.3: + resolution: {integrity: sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.4.3 + '@jest/fake-timers': 29.4.3 + '@jest/globals': 29.4.3 + '@jest/source-map': 29.4.3 + '@jest/test-result': 29.4.3 + '@jest/transform': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + chalk: 4.1.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-haste-map: 29.4.3 + jest-message-util: 29.4.3 + jest-mock: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.4.3 + jest-snapshot: 29.4.3 + jest-util: 29.4.3 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /jest-snapshot/29.0.3: resolution: {integrity: sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6049,12 +6757,44 @@ packages: - supports-color dev: true + /jest-snapshot/29.4.3: + resolution: {integrity: sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.20.5 + '@babel/generator': 7.20.5 + '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.5 + '@babel/traverse': 7.20.5 + '@babel/types': 7.20.5 + '@jest/expect-utils': 29.4.3 + '@jest/transform': 29.4.3 + '@jest/types': 29.4.3 + '@types/babel__traverse': 7.18.2 + '@types/prettier': 2.7.2 + babel-preset-current-node-syntax: 1.0.1_@babel+core@7.20.5 + chalk: 4.1.2 + expect: 29.4.3 + graceful-fs: 4.2.10 + jest-diff: 29.4.3 + jest-get-type: 29.4.3 + jest-haste-map: 29.4.3 + jest-matcher-utils: 29.4.3 + jest-message-util: 29.4.3 + jest-util: 29.4.3 + natural-compare: 1.4.0 + pretty-format: 29.4.3 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + dev: true + /jest-util/29.0.3: resolution: {integrity: sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 ci-info: 3.4.0 graceful-fs: 4.2.10 @@ -6066,7 +6806,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 chalk: 4.1.2 ci-info: 3.5.0 graceful-fs: 4.2.10 @@ -6078,7 +6818,19 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.18 + '@types/node': 18.14.2 + chalk: 4.1.2 + ci-info: 3.7.1 + graceful-fs: 4.2.10 + picomatch: 2.3.1 + dev: true + + /jest-util/29.4.3: + resolution: {integrity: sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + '@types/node': 18.14.2 chalk: 4.1.2 ci-info: 3.7.1 graceful-fs: 4.2.10 @@ -6109,13 +6861,25 @@ packages: pretty-format: 29.2.1 dev: true + /jest-validate/29.4.3: + resolution: {integrity: sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.4.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.4.3 + leven: 3.1.0 + pretty-format: 29.4.3 + dev: true + /jest-watcher/29.0.3: resolution: {integrity: sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/test-result': 29.0.3 '@jest/types': 29.0.3 - '@types/node': 18.11.13 + '@types/node': 18.14.2 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 @@ -6129,7 +6893,7 @@ packages: dependencies: '@jest/test-result': 29.2.1 '@jest/types': 29.2.1 - '@types/node': 18.11.13 + '@types/node': 18.14.2 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 @@ -6137,11 +6901,25 @@ packages: string-length: 4.0.2 dev: true + /jest-watcher/29.4.3: + resolution: {integrity: sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.4.3 + '@jest/types': 29.4.3 + '@types/node': 18.14.2 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.4.3 + string-length: 4.0.2 + dev: true + /jest-worker/29.0.3: resolution: {integrity: sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.11.13 + '@types/node': 18.14.2 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -6150,7 +6928,7 @@ packages: resolution: {integrity: sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.11.13 + '@types/node': 18.14.2 jest-util: 29.2.1 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -6160,12 +6938,22 @@ packages: resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.11.18 + '@types/node': 18.14.2 jest-util: 29.3.1 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true + /jest-worker/29.4.3: + resolution: {integrity: sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 18.14.2 + jest-util: 29.4.3 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + /jest/29.0.3_johvxhudwcpndp4mle25vwrlq4: resolution: {integrity: sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6206,6 +6994,26 @@ packages: - ts-node dev: true + /jest/29.4.3: + resolution: {integrity: sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 29.4.3 + '@jest/types': 29.4.3 + import-local: 3.1.0 + jest-cli: 29.4.3 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + /js-sdsl/4.1.5: resolution: {integrity: sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==} dev: true @@ -6232,7 +7040,6 @@ packages: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} hasBin: true - dev: true /json-parse-even-better-errors/2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -6255,7 +7062,6 @@ packages: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - dev: true /jsonfile/4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} @@ -6514,6 +7320,11 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} + /methods/1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + /micromatch/4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -6521,12 +7332,30 @@ packages: braces: 3.0.2 picomatch: 2.3.1 + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + /mime/1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} hasBin: true dev: true + /mime/2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + dev: true + /mimic-fn/2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -6669,7 +7498,6 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - dev: true /next/12.3.1_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==} @@ -6755,7 +7583,6 @@ packages: /node-releases/2.0.6: resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} - dev: true /noms/0.0.0: resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} @@ -7106,6 +7933,15 @@ packages: react-is: 18.2.0 dev: true + /pretty-format/29.4.3: + resolution: {integrity: sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.4.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + dev: true + /printj/1.3.1: resolution: {integrity: sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==} engines: {node: '>=0.8'} @@ -7373,6 +8209,11 @@ packages: engines: {node: '>=10'} dev: true + /resolve.exports/2.0.0: + resolution: {integrity: sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==} + engines: {node: '>=10'} + dev: true + /resolve/1.22.1: resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} hasBin: true @@ -7743,6 +8584,23 @@ packages: dependencies: '@babel/core': 7.20.5 react: 18.2.0 + + /superagent/8.0.9: + resolution: {integrity: sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA==} + engines: {node: '>=6.4.0 <13 || >=14'} + dependencies: + component-emitter: 1.3.0 + cookiejar: 2.1.4 + debug: 4.3.4 + fast-safe-stringify: 2.1.1 + form-data: 4.0.0 + formidable: 2.1.2 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.11.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color dev: true /superjson/1.11.0: @@ -7750,7 +8608,6 @@ packages: engines: {node: '>=10'} dependencies: copy-anything: 3.0.3 - dev: false /superjson/1.12.1: resolution: {integrity: sha512-HMTj43zvwW5bD+JCZCvFf4DkZQCmiLTen4C+W1Xogj0SPOpnhxsriogM04QmBVGH5b3kcIIOr6FqQ/aoIDx7TQ==} @@ -7759,6 +8616,16 @@ packages: copy-anything: 3.0.3 dev: false + /supertest/6.3.3: + resolution: {integrity: sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA==} + engines: {node: '>=6.4.0'} + dependencies: + methods: 1.1.2 + superagent: 8.0.9 + transitivePeerDependencies: + - supports-color + dev: true + /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -7920,7 +8787,6 @@ packages: /to-fast-properties/2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} - dev: true /to-regex-range/5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} @@ -8010,6 +8876,40 @@ packages: yargs-parser: 21.1.1 dev: true + /ts-jest/29.0.5_itrzs5lisv6omhzjwqg6f7v6de: + resolution: {integrity: sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@babel/core': 7.20.5 + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.4.3 + jest-util: 29.4.3 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.3.8 + typescript: 4.9.4 + yargs-parser: 21.1.1 + dev: true + /ts-morph/16.0.0: resolution: {integrity: sha512-jGNF0GVpFj0orFw55LTsQxVYEUOCWBAbR5Ls7fTYE5pQsbW18ssTb/6UXx/GYAEjS+DQTp8VoTw0vqYMiaaQuw==} dependencies: @@ -8225,6 +9125,12 @@ packages: hasBin: true dev: true + /typescript/4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + /typical/4.0.0: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} @@ -8294,7 +9200,6 @@ packages: browserslist: 4.21.4 escalade: 3.1.1 picocolors: 1.0.0 - dev: true /upper-case-first/2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} diff --git a/tests/integration/package.json b/tests/integration/package.json index 821e067ff..9b6e995a8 100644 --- a/tests/integration/package.json +++ b/tests/integration/package.json @@ -41,6 +41,7 @@ "bcryptjs": "^2.4.3", "decimal.js": "^10.4.2", "sleep-promise": "^9.1.0", - "superjson": "^1.11.0" + "superjson": "^1.11.0", + "@zenstackhq/testtools": "workspace:*" } } diff --git a/tests/integration/test-run/package-lock.json b/tests/integration/test-run/package-lock.json index 4c60ce50c..7d60d335a 100644 --- a/tests/integration/test-run/package-lock.json +++ b/tests/integration/test-run/package-lock.json @@ -126,7 +126,7 @@ }, "../../../packages/runtime/dist": { "name": "@zenstackhq/runtime", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "license": "MIT", "dependencies": { "@types/bcryptjs": "^2.4.2", @@ -160,7 +160,7 @@ }, "../../../packages/schema/dist": { "name": "zenstack", - "version": "1.0.0-alpha.45", + "version": "1.0.0-alpha.48", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/tests/integration/tests/e2e/prisma-methods.test.ts b/tests/integration/tests/e2e/prisma-methods.test.ts index 2cae859d9..b7eb65b6e 100644 --- a/tests/integration/tests/e2e/prisma-methods.test.ts +++ b/tests/integration/tests/e2e/prisma-methods.test.ts @@ -1,16 +1,13 @@ import { AuthUser } from '@zenstackhq/runtime'; -import { loadPrisma, MODEL_PRELUDE, run, WeakDbClientContract } from '../../utils'; +import { loadSchema, run, WeakDbClientContract } from '@zenstackhq/testtools'; describe('Prisma Methods Tests', () => { let getDb: (user?: AuthUser) => WeakDbClientContract; let prisma: WeakDbClientContract; beforeAll(async () => { - const { withPresets, prisma: _prisma } = await loadPrisma( - 'prisma-methods', + const { withPresets, prisma: _prisma } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(cuid()) value Int diff --git a/tests/integration/tests/e2e/todo-presets.test.ts b/tests/integration/tests/e2e/todo-presets.test.ts index 953ea0402..c12238631 100644 --- a/tests/integration/tests/e2e/todo-presets.test.ts +++ b/tests/integration/tests/e2e/todo-presets.test.ts @@ -1,15 +1,14 @@ import { AuthUser } from '@zenstackhq/runtime'; +import { loadSchemaFromFile, run, type WeakDbClientContract } from '@zenstackhq/testtools'; import { compareSync } from 'bcryptjs'; import path from 'path'; -import { WeakDbClientContract, loadPrismaFromModelFile, run } from '../../utils'; describe('Todo Presets Tests', () => { let getDb: (user?: AuthUser) => WeakDbClientContract; let prisma: WeakDbClientContract; beforeAll(async () => { - const { withPresets, prisma: _prisma } = await loadPrismaFromModelFile( - 'todo-presets', + const { withPresets, prisma: _prisma } = await loadSchemaFromFile( path.join(__dirname, '../schema/todo.zmodel') ); getDb = withPresets; diff --git a/tests/integration/tests/e2e/type-coverage.test.ts b/tests/integration/tests/e2e/type-coverage.test.ts index 856a639cf..51a46b714 100644 --- a/tests/integration/tests/e2e/type-coverage.test.ts +++ b/tests/integration/tests/e2e/type-coverage.test.ts @@ -1,18 +1,15 @@ import { AuthUser } from '@zenstackhq/runtime'; +import { loadSchema, run, type WeakDbClientContract } from '@zenstackhq/testtools'; import Decimal from 'decimal.js'; import superjson from 'superjson'; -import { loadPrisma, MODEL_PRELUDE, run, WeakDbClientContract } from '../../utils'; describe('Type Coverage Tests', () => { let getDb: (user?: AuthUser) => WeakDbClientContract; let prisma: WeakDbClientContract; beforeAll(async () => { - const { withPresets, prisma: _prisma } = await loadPrisma( - 'type-coverate', + const { withPresets, prisma: _prisma } = await loadSchema( ` - ${MODEL_PRELUDE} - model Foo { id String @id @default(cuid()) diff --git a/tests/integration/tests/nextjs/generation.test.ts b/tests/integration/tests/nextjs/generation.test.ts index 435dc6b25..81ea407ae 100644 --- a/tests/integration/tests/nextjs/generation.test.ts +++ b/tests/integration/tests/nextjs/generation.test.ts @@ -1,7 +1,7 @@ +import { run } from '@zenstackhq/testtools'; import fs from 'fs'; import fse from 'fs-extra'; import path from 'path'; -import { run } from '../../utils'; describe('React Hooks Generation Tests', () => { let origDir: string; diff --git a/tests/integration/tests/schema/todo.zmodel b/tests/integration/tests/schema/todo.zmodel index 001e78dd0..d56717eb8 100644 --- a/tests/integration/tests/schema/todo.zmodel +++ b/tests/integration/tests/schema/todo.zmodel @@ -2,27 +2,6 @@ * Sample model for a collaborative Todo app */ -datasource db { - provider = 'sqlite' - url = 'file:./todo.db' -} - -generator js { - provider = 'prisma-client-js' - output = '../.prisma' -} - -plugin meta { - provider = '@zenstack/model-meta' - output = '.zenstack' -} - -plugin policy { - provider = '@zenstack/access-policy' - output = '.zenstack' -} - - /* * Model for a space in which users can collaborate on Lists and Todos */ @@ -32,7 +11,6 @@ model Space { updatedAt DateTime @updatedAt name String @length(4, 50) slug String @unique @length(4, 16) - owner User? @relation(fields: [ownerId], references: [id]) ownerId String? members SpaceUser[] @@ -58,12 +36,11 @@ model SpaceUser { id String @id @default(uuid()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - space Space @relation(fields:[spaceId], references: [id], onDelete: Cascade) + space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) spaceId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String role String - @@unique([userId, spaceId]) // require login @@ -100,7 +77,7 @@ model User { @@allow('read', spaces?[space.members?[user == auth()]]) // full access by oneself - @@allow('all', auth() == this) + @@allow('all', auth() == this) } /* @@ -132,7 +109,7 @@ model List { @@allow('update', owner == auth()&& space.members?[user == auth()] && future().owner == owner) // can be deleted by owner - @@allow('delete', owner == auth()) + @@allow('delete', owner == auth()) } /* diff --git a/tests/integration/tests/trpc/generation.test.ts b/tests/integration/tests/trpc/generation.test.ts index e6a12dda8..ae2098d28 100644 --- a/tests/integration/tests/trpc/generation.test.ts +++ b/tests/integration/tests/trpc/generation.test.ts @@ -1,7 +1,7 @@ +import { run } from '@zenstackhq/testtools'; import fs from 'fs'; import fse from 'fs-extra'; import path from 'path'; -import { run } from '../../utils'; describe('tRPC Routers Generation Tests', () => { let origDir: string; diff --git a/tests/integration/tests/with-omit/with-omit.test.ts b/tests/integration/tests/with-omit/with-omit.test.ts index 57e69128c..03e39142e 100644 --- a/tests/integration/tests/with-omit/with-omit.test.ts +++ b/tests/integration/tests/with-omit/with-omit.test.ts @@ -1,9 +1,8 @@ -import { MODEL_PRELUDE, loadPrisma } from '../../utils/utils'; +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; describe('Omit test', () => { let origDir: string; - const suite = 'omit'; beforeAll(async () => { origDir = path.resolve('.'); @@ -14,11 +13,8 @@ describe('Omit test', () => { }); it('omit tests', async () => { - const { withOmit } = await loadPrisma( - `${suite}/test`, + const { withOmit } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(cuid()) password String @omit diff --git a/tests/integration/tests/with-password/with-password.test.ts b/tests/integration/tests/with-password/with-password.test.ts index 1e74bc700..f0502e5e4 100644 --- a/tests/integration/tests/with-password/with-password.test.ts +++ b/tests/integration/tests/with-password/with-password.test.ts @@ -1,10 +1,9 @@ +import { loadSchema } from '@zenstackhq/testtools'; import { compareSync } from 'bcryptjs'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils/utils'; import path from 'path'; describe('Password test', () => { let origDir: string; - const suite = 'password'; beforeAll(async () => { origDir = path.resolve('.'); @@ -15,11 +14,8 @@ describe('Password test', () => { }); it('password tests', async () => { - const { withPassword } = await loadPrisma( - `${suite}/test`, + const { withPassword } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(cuid()) password String @password(saltLength: 16) diff --git a/tests/integration/tests/with-policy/auth.test.ts b/tests/integration/tests/with-policy/auth.test.ts index 2987a156f..ac74f451b 100644 --- a/tests/integration/tests/with-policy/auth.test.ts +++ b/tests/integration/tests/with-policy/auth.test.ts @@ -1,6 +1,5 @@ -import { PrismaClientValidationError } from '@prisma/client/runtime'; +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy:undefined user', () => { let origDir: string; @@ -15,11 +14,8 @@ describe('With Policy:undefined user', () => { }); it('undefined user with string id', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/undefined user with string id`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(uuid()) } @@ -42,11 +38,8 @@ describe('With Policy:undefined user', () => { }); it('undefined user with string id more', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/undefined user with string id more`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(uuid()) } @@ -69,11 +62,8 @@ describe('With Policy:undefined user', () => { }); it('undefined user with int id', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/undefined user with int id`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id Int @id @default(autoincrement()) } @@ -96,11 +86,8 @@ describe('With Policy:undefined user', () => { }); it('undefined user compared with field', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/undefined user compared with field`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(uuid()) posts Post[] @@ -135,11 +122,8 @@ describe('With Policy:undefined user', () => { }); it('undefined user compared with field more', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/undefined user compared with field more`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(uuid()) posts Post[] @@ -173,11 +157,8 @@ describe('With Policy:undefined user', () => { }); it('undefined user non-id field', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/undefined user non-id field`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(uuid()) posts Post[] diff --git a/tests/integration/tests/with-policy/deep-nested.test.ts b/tests/integration/tests/with-policy/deep-nested.test.ts index 7cda78959..bf2b9a8e0 100644 --- a/tests/integration/tests/with-policy/deep-nested.test.ts +++ b/tests/integration/tests/with-policy/deep-nested.test.ts @@ -1,13 +1,11 @@ +import { loadSchema, type WeakDbClientContract } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, WeakDbClientContract, loadPrisma } from '../../utils'; describe('With Policy:deep nested', () => { let origDir: string; const suite = 'deep-nested'; const model = ` - ${MODEL_PRELUDE} - // M1 - M2 - M3 // -* M4 model M1 { @@ -68,7 +66,7 @@ describe('With Policy:deep nested', () => { }); beforeEach(async () => { - const { withPolicy } = await loadPrisma(`${suite}/shared`, model); + const { withPolicy } = await loadSchema(model); db = withPolicy(); }); diff --git a/tests/integration/tests/with-policy/empty-policy.test.ts b/tests/integration/tests/with-policy/empty-policy.test.ts index e540213f7..d2e4095e2 100644 --- a/tests/integration/tests/with-policy/empty-policy.test.ts +++ b/tests/integration/tests/with-policy/empty-policy.test.ts @@ -1,9 +1,8 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy:empty policy', () => { let origDir: string; - const suite = 'empty-policy'; beforeAll(async () => { origDir = path.resolve('.'); @@ -14,11 +13,8 @@ describe('With Policy:empty policy', () => { }); it('direct operations', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/direct operations`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) } @@ -57,11 +53,8 @@ describe('With Policy:empty policy', () => { }); it('to-many write', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/to-many write`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -91,11 +84,8 @@ describe('With Policy:empty policy', () => { }); it('to-one write', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested write to-one`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? diff --git a/tests/integration/tests/with-policy/field-validation.test.ts b/tests/integration/tests/with-policy/field-validation.test.ts index aeaf218e3..38925653d 100644 --- a/tests/integration/tests/with-policy/field-validation.test.ts +++ b/tests/integration/tests/with-policy/field-validation.test.ts @@ -1,15 +1,12 @@ -import { MODEL_PRELUDE, WeakDbClientContract, loadPrisma, run } from '../../utils'; +import { loadSchema, run, WeakDbClientContract } from '@zenstackhq/testtools'; describe('With Policy: field validation', () => { let db: WeakDbClientContract; let prisma: WeakDbClientContract; beforeAll(async () => { - const { withPolicy, prisma: _prisma } = await loadPrisma( - 'field-validation', + const { withPolicy, prisma: _prisma } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(cuid()) password String @length(8, 16) diff --git a/tests/integration/tests/with-policy/multi-field-unique.test.ts b/tests/integration/tests/with-policy/multi-field-unique.test.ts index d9c02b4e2..a6629357c 100644 --- a/tests/integration/tests/with-policy/multi-field-unique.test.ts +++ b/tests/integration/tests/with-policy/multi-field-unique.test.ts @@ -1,5 +1,5 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma, run } from '../../utils'; describe('With Policy: multi-field unique', () => { let origDir: string; @@ -14,11 +14,8 @@ describe('With Policy: multi-field unique', () => { }); it('toplevel crud test unnamed constraint', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/toplevel-crud-unnamed`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) a String @@ -47,11 +44,8 @@ describe('With Policy: multi-field unique', () => { }); it('toplevel crud test named constraint', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/toplevel-crud-named`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) a String @@ -80,11 +74,8 @@ describe('With Policy: multi-field unique', () => { }); it('nested crud test', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested-crud`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] diff --git a/tests/integration/tests/with-policy/nested-to-many.test.ts b/tests/integration/tests/with-policy/nested-to-many.test.ts index eb27961da..a3ae19dfb 100644 --- a/tests/integration/tests/with-policy/nested-to-many.test.ts +++ b/tests/integration/tests/with-policy/nested-to-many.test.ts @@ -1,5 +1,5 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy:nested to-many', () => { let origDir: string; @@ -14,11 +14,8 @@ describe('With Policy:nested to-many', () => { }); it('create simple', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/create`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -84,11 +81,8 @@ describe('With Policy:nested to-many', () => { }); it('update simple', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/update`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -161,11 +155,8 @@ describe('With Policy:nested to-many', () => { }); it('update with create', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/update with create`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -221,11 +212,8 @@ describe('With Policy:nested to-many', () => { }); it('update with delete', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/update with delete`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -315,11 +303,8 @@ describe('With Policy:nested to-many', () => { }); it('create with nested read', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/create with nested read`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) value Int @@ -412,11 +397,8 @@ describe('With Policy:nested to-many', () => { }); it('update with nested read', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/update with nested read`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] diff --git a/tests/integration/tests/with-policy/nested-to-one.test.ts b/tests/integration/tests/with-policy/nested-to-one.test.ts index 6a7b565da..8eff681d5 100644 --- a/tests/integration/tests/with-policy/nested-to-one.test.ts +++ b/tests/integration/tests/with-policy/nested-to-one.test.ts @@ -1,5 +1,5 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy:nested to-one', () => { let origDir: string; @@ -14,11 +14,8 @@ describe('With Policy:nested to-one', () => { }); it('create and update tests', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/create and update`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? @@ -77,11 +74,8 @@ describe('With Policy:nested to-one', () => { }); it('nested create', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested create`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? @@ -135,11 +129,8 @@ describe('With Policy:nested to-one', () => { }); it('nested delete', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested delete`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? @@ -204,11 +195,8 @@ describe('With Policy:nested to-one', () => { }); it('nested relation delete', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested relation delete`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model User { id String @id @default(uuid()) m1 M1? diff --git a/tests/integration/tests/with-policy/post-update.test.ts b/tests/integration/tests/with-policy/post-update.test.ts index 2919c24da..73d21713b 100644 --- a/tests/integration/tests/with-policy/post-update.test.ts +++ b/tests/integration/tests/with-policy/post-update.test.ts @@ -1,5 +1,5 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy: post update', () => { let origDir: string; @@ -14,11 +14,8 @@ describe('With Policy: post update', () => { }); it('simple allow', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/simple-allow`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) value Int @@ -37,11 +34,8 @@ describe('With Policy: post update', () => { }); it('simple deny', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/simple-deny`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) value Int @@ -60,11 +54,8 @@ describe('With Policy: post update', () => { }); it('mixed pre and post', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/mixed`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) value Int @@ -86,11 +77,8 @@ describe('With Policy: post update', () => { }); it('nested to-many', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested-to-many`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -148,11 +136,8 @@ describe('With Policy: post update', () => { }); it('nested to-one', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested-to-one`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? @@ -204,11 +189,8 @@ describe('With Policy: post update', () => { }); it('nested select', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/nested-select`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? @@ -258,11 +240,8 @@ describe('With Policy: post update', () => { }); it('deep nesting', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/deep-nesting`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? diff --git a/tests/integration/tests/with-policy/relation-to-many-filter.test.ts b/tests/integration/tests/with-policy/relation-to-many-filter.test.ts index 3f5ed91c1..ae1749237 100644 --- a/tests/integration/tests/with-policy/relation-to-many-filter.test.ts +++ b/tests/integration/tests/with-policy/relation-to-many-filter.test.ts @@ -1,5 +1,5 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy: relation to-many filter', () => { let origDir: string; @@ -14,8 +14,6 @@ describe('With Policy: relation to-many filter', () => { }); const model = ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2[] @@ -48,7 +46,7 @@ describe('With Policy: relation to-many filter', () => { `; it('some filter', async () => { - const { withPolicy } = await loadPrisma(`${suite}/some-filter`, model); + const { withPolicy } = await loadSchema(model); const db = withPolicy(); @@ -166,7 +164,7 @@ describe('With Policy: relation to-many filter', () => { }); it('none filter', async () => { - const { withPolicy } = await loadPrisma(`${suite}/none-filter`, model); + const { withPolicy } = await loadSchema(model); const db = withPolicy(); @@ -284,7 +282,7 @@ describe('With Policy: relation to-many filter', () => { }); it('every filter', async () => { - const { withPolicy } = await loadPrisma(`${suite}/every-filter`, model); + const { withPolicy } = await loadSchema(model); const db = withPolicy(); diff --git a/tests/integration/tests/with-policy/relation-to-one-filter.test.ts b/tests/integration/tests/with-policy/relation-to-one-filter.test.ts index 9e27f5ca9..0eacdf38c 100644 --- a/tests/integration/tests/with-policy/relation-to-one-filter.test.ts +++ b/tests/integration/tests/with-policy/relation-to-one-filter.test.ts @@ -1,5 +1,5 @@ +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; -import { MODEL_PRELUDE, loadPrisma } from '../../utils'; describe('With Policy: relation to-one filter', () => { let origDir: string; @@ -14,8 +14,6 @@ describe('With Policy: relation to-one filter', () => { }); const model = ` - ${MODEL_PRELUDE} - model M1 { id String @id @default(uuid()) m2 M2? @@ -48,7 +46,7 @@ describe('With Policy: relation to-one filter', () => { `; it('is filter', async () => { - const { withPolicy } = await loadPrisma(`${suite}/is-filter`, model); + const { withPolicy } = await loadSchema(model); const db = withPolicy(); @@ -155,7 +153,7 @@ describe('With Policy: relation to-one filter', () => { }); it('isNot filter', async () => { - const { withPolicy } = await loadPrisma(`${suite}/isNot-filter`, model); + const { withPolicy } = await loadSchema(model); const db = withPolicy(); @@ -264,7 +262,7 @@ describe('With Policy: relation to-one filter', () => { }); it('direct object filter', async () => { - const { withPolicy } = await loadPrisma(`${suite}/direct-object-filter`, model); + const { withPolicy } = await loadSchema(model); const db = withPolicy(); diff --git a/tests/integration/tests/with-policy/todo-sample.test.ts b/tests/integration/tests/with-policy/todo-sample.test.ts index 7ae4e3233..6c34f1079 100644 --- a/tests/integration/tests/with-policy/todo-sample.test.ts +++ b/tests/integration/tests/with-policy/todo-sample.test.ts @@ -1,16 +1,13 @@ import { AuthUser } from '@zenstackhq/runtime'; +import { loadSchemaFromFile, run, type WeakDbClientContract } from '@zenstackhq/testtools'; import path from 'path'; -import { WeakDbClientContract, loadPrismaFromModelFile, run } from '../../utils'; describe('Todo Policy Tests', () => { let getDb: (user?: AuthUser) => WeakDbClientContract; let prisma: WeakDbClientContract; beforeAll(async () => { - const { withPolicy, prisma: _prisma } = await loadPrismaFromModelFile( - 'todo-policy', - path.join(__dirname, '../schema/todo.zmodel') - ); + const { withPolicy, prisma: _prisma } = await loadSchemaFromFile(path.join(__dirname, '../schema/todo.zmodel')); getDb = withPolicy; prisma = _prisma; }); diff --git a/tests/integration/tests/with-policy/toplevel-operations.test.ts b/tests/integration/tests/with-policy/toplevel-operations.test.ts index 32f053b98..72171315f 100644 --- a/tests/integration/tests/with-policy/toplevel-operations.test.ts +++ b/tests/integration/tests/with-policy/toplevel-operations.test.ts @@ -1,4 +1,4 @@ -import { MODEL_PRELUDE, loadPrisma } from '../../utils/utils'; +import { loadSchema } from '@zenstackhq/testtools'; import path from 'path'; describe('With Policy:toplevel operations', () => { @@ -14,11 +14,8 @@ describe('With Policy:toplevel operations', () => { }); it('read tests', async () => { - const { withPolicy, prisma } = await loadPrisma( - `${suite}/read`, + const { withPolicy, prisma } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) value Int @@ -66,11 +63,8 @@ describe('With Policy:toplevel operations', () => { }); it('write tests', async () => { - const { withPolicy } = await loadPrisma( - `${suite}/write`, + const { withPolicy } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) value Int @@ -155,11 +149,8 @@ describe('With Policy:toplevel operations', () => { }); it('delete tests', async () => { - const { withPolicy, prisma } = await loadPrisma( - `${suite}/delete`, + const { withPolicy, prisma } = await loadSchema( ` - ${MODEL_PRELUDE} - model Model { id String @id @default(uuid()) value Int