diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..34ed4500d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "npm.packageManager": "pnpm", + "eslint.packageManager": "pnpm" +} diff --git a/packages/internal/package.json b/packages/internal/package.json index 0a43eea65..dfbbb72bb 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/internal", - "version": "0.1.18", + "version": "0.1.20", "description": "ZenStack internal runtime library", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/packages/internal/src/handler/data/handler.ts b/packages/internal/src/handler/data/handler.ts index 9d8c9271f..9cea70d64 100644 --- a/packages/internal/src/handler/data/handler.ts +++ b/packages/internal/src/handler/data/handler.ts @@ -55,7 +55,7 @@ export default class DataHandler implements RequestHandler { break; } } catch (err: any) { - console.error(`Error handling ${method} ${model}: ${err}`); + console.log(`Error handling ${method} ${model}: ${err}`); if (err instanceof RequestHandlerError) { switch (err.code) { case ServerErrorCode.DENIED_BY_POLICY: @@ -76,11 +76,18 @@ export default class DataHandler implements RequestHandler { message: err.message, }); } - } else if (err.code && PRISMA_ERROR_MAPPING[err.code]) { - res.status(400).send({ - code: PRISMA_ERROR_MAPPING[err.code], - message: 'database access error', - }); + } else if (err.code) { + if (PRISMA_ERROR_MAPPING[err.code]) { + res.status(400).send({ + code: PRISMA_ERROR_MAPPING[err.code], + message: 'database access error', + }); + } else { + res.status(400).send({ + code: 'PRISMA:' + err.code, + message: 'an unhandled Prisma error occurred', + }); + } } else { console.error( `An unknown error occurred: ${JSON.stringify(err)}` @@ -110,7 +117,7 @@ export default class DataHandler implements RequestHandler { if (id) { if (processedArgs.where) { processedArgs.where = { - AND: [args.where, { id }], + AND: [processedArgs.where, { id }], }; } else { processedArgs.where = { id }; @@ -127,13 +134,7 @@ export default class DataHandler implements RequestHandler { } console.log(`Finding ${model}:\n${JSON.stringify(processedArgs)}`); - await this.queryProcessor.postProcess( - model, - processedArgs, - r, - 'read', - context - ); + await this.queryProcessor.postProcess(model, r, 'read', context); res.status(200).send(r); } @@ -190,13 +191,7 @@ export default class DataHandler implements RequestHandler { return created; }); - await this.queryProcessor.postProcess( - model, - processedArgs, - r, - 'create', - context - ); + await this.queryProcessor.postProcess(model, r, 'create', context); res.status(201).send(r); } @@ -265,13 +260,7 @@ export default class DataHandler implements RequestHandler { return updated; }); - await this.queryProcessor.postProcess( - model, - updateArgs, - r, - 'update', - context - ); + await this.queryProcessor.postProcess(model, r, 'update', context); res.status(200).send(r); } @@ -307,13 +296,7 @@ export default class DataHandler implements RequestHandler { console.log(`Deleting ${model}:\n${JSON.stringify(delArgs)}`); const db = (this.service.db as any)[model]; const r = await db.delete(delArgs); - await this.queryProcessor.postProcess( - model, - delArgs, - r, - 'delete', - context - ); + await this.queryProcessor.postProcess(model, r, 'delete', context); res.status(200).send(r); } @@ -334,7 +317,7 @@ export default class DataHandler implements RequestHandler { context ); console.log( - `Finding to-be-deleted ${model}:\n${JSON.stringify(readArgs)}` + `Finding pre-operation ${model}:\n${JSON.stringify(readArgs)}` ); const read = await db.findFirst(readArgs); if (!read) { diff --git a/packages/internal/src/handler/data/query-processor.ts b/packages/internal/src/handler/data/query-processor.ts index f2dc77679..5ac3e5118 100644 --- a/packages/internal/src/handler/data/query-processor.ts +++ b/packages/internal/src/handler/data/query-processor.ts @@ -31,6 +31,12 @@ export class QueryProcessor { } if (r.include || r.select) { + if (r.include && r.select) { + throw Error( + 'Passing both "include" and "select" at the same level of query is not supported' + ); + } + // "include" and "select" are mutually exclusive const selector = r.include ? 'include' : 'select'; for (const [field, value] of Object.entries(r[selector])) { @@ -59,11 +65,129 @@ export class QueryProcessor { return r; } + private async getToOneFieldInfo( + model: string, + fieldName: string, + fieldValue: any + ) { + if ( + !!fieldValue && + !Array.isArray(fieldValue) && + typeof fieldValue === 'object' && + typeof fieldValue.id == 'string' + ) { + return null; + } + + const fieldInfo = await this.service.resolveField(model, fieldName); + if (!fieldInfo || fieldInfo.isArray) { + return null; + } + + return fieldInfo; + } + + private async collectRelationFields( + model: string, + data: any, + map: Map + ) { + for (const [fieldName, fieldValue] of Object.entries(data)) { + const val: any = fieldValue; + const fieldInfo = await this.getToOneFieldInfo( + model, + fieldName, + fieldValue + ); + if (!fieldInfo) { + continue; + } + + if (!map.has(fieldInfo.type)) { + map.set(fieldInfo.type, []); + } + map.get(fieldInfo.type)!.push(val.id); + + // recurse into field value + this.collectRelationFields(fieldInfo.type, val, map); + } + } + + private async checkIdsAgainstPolicy( + relationFieldMap: Map, + operation: PolicyOperationKind, + context: QueryContext + ) { + const promises = Array.from(relationFieldMap.entries()).map( + async ([model, ids]) => { + const args = { + select: { id: true }, + where: { + id: { in: ids }, + }, + }; + + const processedArgs = this.processQueryArgs( + model, + args, + operation, + context, + true + ); + + const checkedIds: Array<{ id: string }> = await this.service.db[ + model + ].findMany(processedArgs); + return [model, checkedIds.map((r) => r.id)] as [ + string, + string[] + ]; + } + ); + return new Map(await Promise.all(promises)); + } + + private async sanitizeData( + model: string, + data: any, + validatedIds: Map + ) { + for (const [fieldName, fieldValue] of Object.entries(data)) { + const fieldInfo = await this.getToOneFieldInfo( + model, + fieldName, + fieldValue + ); + if (!fieldInfo) { + continue; + } + const fv = fieldValue as { id: string }; + const valIds = validatedIds.get(fieldInfo.type); + + if (!valIds || !valIds.includes(fv.id)) { + console.log( + `Deleting field ${fieldName} from ${model}#${data.id}, because field value #${fv.id} failed policy check` + ); + delete data[fieldName]; + } + + await this.sanitizeData(fieldInfo.type, fieldValue, validatedIds); + } + } + async postProcess( model: string, - queryArgs: any, data: any, operation: PolicyOperationKind, context: QueryContext - ) {} + ) { + const relationFieldMap = new Map(); + await this.collectRelationFields(model, data, relationFieldMap); + const validatedIds = await this.checkIdsAgainstPolicy( + relationFieldMap, + operation, + context + ); + await this.sanitizeData(model, data, validatedIds); + } } diff --git a/packages/schema/package.json b/packages/schema/package.json index 2d4d8645d..e8b24ac4e 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -2,7 +2,7 @@ "name": "zenstack", "displayName": "ZenStack CLI and Language Tools", "description": "ZenStack CLI and Language Tools", - "version": "0.1.38", + "version": "0.1.40", "engines": { "vscode": "^1.56.0" }, diff --git a/packages/schema/src/generator/index.ts b/packages/schema/src/generator/index.ts index f93a29266..6af644a8d 100644 --- a/packages/schema/src/generator/index.ts +++ b/packages/schema/src/generator/index.ts @@ -31,9 +31,17 @@ export class ZenStackGenerator { new PrismaGenerator(), new ServiceGenerator(), new ReactHooksGenerator(), - new NextAuthGenerator(), ]; + try { + require('next-auth'); + generators.push(new NextAuthGenerator()); + } catch { + console.warn( + 'Next-auth module is not installed, skipping generating adapter.' + ); + } + for (const generator of generators) { await generator.generate(context); } diff --git a/packages/schema/src/generator/service/index.ts b/packages/schema/src/generator/service/index.ts index 7bade7384..4f45d2f6a 100644 --- a/packages/schema/src/generator/service/index.ts +++ b/packages/schema/src/generator/service/index.ts @@ -1,5 +1,5 @@ import { Context, Generator } from '../types'; -import { Project, StructureKind } from 'ts-morph'; +import { Project, StructureKind, VariableDeclarationKind } from 'ts-morph'; import * as path from 'path'; import colors from 'colors'; import { INTERNAL_PACKAGE } from '../constants'; @@ -41,6 +41,15 @@ export default class ServiceGenerator implements Generator { .addBody() .setBodyText('return this._prisma;'); + sf.addVariableStatement({ + declarationKind: VariableDeclarationKind.Let, + declarations: [ + { + name: 'guardModule', + type: 'any', + }, + ], + }); cls .addMethod({ name: 'resolveField', @@ -57,8 +66,10 @@ export default class ServiceGenerator implements Generator { ], }) .addBody().setBodyText(` - const module: any = await import('./query/guard'); - return module._fieldMapping?.[model]?.[field]; + if (!guardModule) { + guardModule = await import('./query/guard'); + } + return guardModule._fieldMapping?.[model]?.[field]; `); cls diff --git a/packages/schema/src/language-server/zmodel-linker.ts b/packages/schema/src/language-server/zmodel-linker.ts index d2c32ab45..9931caa24 100644 --- a/packages/schema/src/language-server/zmodel-linker.ts +++ b/packages/schema/src/language-server/zmodel-linker.ts @@ -176,14 +176,14 @@ export class ZModelLinker extends DefaultLinker { document: LangiumDocument, extraScopes: ScopeProvider[] ) { - this.resolve(node.left, document, extraScopes); - this.resolve(node.right, document, extraScopes); switch (node.operator) { // TODO: support arithmetics? // case '+': // case '-': // case '*': // case '/': + // this.resolve(node.left, document, extraScopes); + // this.resolve(node.right, document, extraScopes); // this.resolveToBuiltinTypeOrDecl(node, 'Int'); // break; @@ -195,6 +195,8 @@ export class ZModelLinker extends DefaultLinker { case '!=': case '&&': case '||': + this.resolve(node.left, document, extraScopes); + this.resolve(node.right, document, extraScopes); this.resolveToBuiltinTypeOrDecl(node, 'Boolean'); break; diff --git a/packages/schema/tests/schema/parser.test.ts b/packages/schema/tests/schema/parser.test.ts index 0aa16b783..c4efb76b5 100644 --- a/packages/schema/tests/schema/parser.test.ts +++ b/packages/schema/tests/schema/parser.test.ts @@ -192,8 +192,8 @@ describe('Basic Tests', () => { b Int c Boolean - @@deny(!c) - @@deny(a < 0) + @@deny('all', !c) + @@deny('all', a < 0) // @@deny(a + b < 10) } `; @@ -201,24 +201,24 @@ describe('Basic Tests', () => { const model = doc.declarations[0] as DataModel; const attrs = model.attributes; - expect(attrs[0].args[0].value.$type).toBe(UnaryExpr); - expect((attrs[0].args[0].value as UnaryExpr).operand.$type).toBe( + expect(attrs[0].args[1].value.$type).toBe(UnaryExpr); + expect((attrs[0].args[1].value as UnaryExpr).operand.$type).toBe( ReferenceExpr ); - expect(attrs[1].args[0].value.$type).toBe(BinaryExpr); - expect((attrs[1].args[0].value as BinaryExpr).left.$type).toBe( + expect(attrs[1].args[1].value.$type).toBe(BinaryExpr); + expect((attrs[1].args[1].value as BinaryExpr).left.$type).toBe( ReferenceExpr ); - expect((attrs[1].args[0].value as BinaryExpr).right.$type).toBe( + expect((attrs[1].args[1].value as BinaryExpr).right.$type).toBe( LiteralExpr ); - expect(attrs[1].args[0].value.$type).toBe(BinaryExpr); - expect((attrs[1].args[0].value as BinaryExpr).left.$type).toBe( + expect(attrs[1].args[1].value.$type).toBe(BinaryExpr); + expect((attrs[1].args[1].value as BinaryExpr).left.$type).toBe( ReferenceExpr ); - expect((attrs[1].args[0].value as BinaryExpr).right.$type).toBe( + expect((attrs[1].args[1].value as BinaryExpr).right.$type).toBe( LiteralExpr ); @@ -235,9 +235,9 @@ describe('Basic Tests', () => { b Int // @@deny(a + b * 2 > 0) // @@deny((a + b) * 2 > 0) - @@deny(a > 0 && b < 0) - @@deny(a >= 0 && b <= 0) - @@deny(a == 0 || b != 0) + @@deny('all', a > 0 && b < 0) + @@deny('all', a >= 0 && b <= 0) + @@deny('all', a == 0 || b != 0) } `; @@ -335,8 +335,8 @@ describe('Basic Tests', () => { a Int b Int c N[] - @@deny(foo(a, b)) - @@deny(bar(c)) + @@deny('all', foo(a, b)) + @@deny('all', bar(c)) } model N { @@ -363,15 +363,15 @@ describe('Basic Tests', () => { expect(bar.params[0].type.reference?.ref?.name).toBe('N'); expect(bar.params[0].type.array).toBeTruthy(); - expect(model.attributes[0].args[0].value.$type).toBe(InvocationExpr); + expect(model.attributes[0].args[1].value.$type).toBe(InvocationExpr); }); it('member access', async () => { const content = ` model M { a N - @@deny(a.x.y < 0) - @@deny(foo(a)) + @@deny('all', a.x.y < 0) + @@deny('all', foo(a)) } model N { @@ -392,8 +392,8 @@ describe('Basic Tests', () => { it('collection predicate', async () => { const content = ` model M { - a N[] - @@deny(a?[x < 0]) + n N[] + @@deny('all', n?[x < 0]) } model N { @@ -402,4 +402,22 @@ describe('Basic Tests', () => { `; await loadModel(content); }); + + it('collection predicate chained', async () => { + const content = ` + model M { + n N[] + @@deny('all', n?[p?[x < 0]]) + } + + model N { + p P[] + } + + model P { + x Int + } + `; + await loadModel(content); + }); }); diff --git a/packages/schema/tests/schema/sample-todo.test.ts b/packages/schema/tests/schema/sample-todo.test.ts index c2c4e42e0..8700b6580 100644 --- a/packages/schema/tests/schema/sample-todo.test.ts +++ b/packages/schema/tests/schema/sample-todo.test.ts @@ -3,9 +3,12 @@ import * as fs from 'fs'; describe('Basic Tests', () => { it('sample todo schema', async () => { - const content = fs.readFileSync('../../samples/todo/schema.zmodel', { - encoding: 'utf-8', - }); + const content = fs.readFileSync( + '../../samples/todo/zenstack/schema.zmodel', + { + encoding: 'utf-8', + } + ); await loadModel(content); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad33ab959..c6a4831bd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,6 +117,33 @@ importers: tsconfig-paths-jest: 0.0.1 typescript: 4.8.3 + tests/integration: + specifiers: + '@types/jest': ^29.0.3 + '@types/node': ^14.18.29 + '@types/supertest': ^2.0.12 + '@types/tmp': ^0.2.3 + jest: ^29.0.3 + next: ^12.3.1 + supertest: ^6.3.0 + tmp: ^0.2.1 + ts-jest: ^29.0.1 + ts-node: ^10.9.1 + typescript: ^4.6.2 + dependencies: + '@types/node': 14.18.29 + devDependencies: + '@types/jest': 29.0.3 + '@types/supertest': 2.0.12 + '@types/tmp': 0.2.3 + jest: 29.0.3_johvxhudwcpndp4mle25vwrlq4 + next: 12.3.1_6tziyx3dehkoeijunclpkpolha + supertest: 6.3.0 + tmp: 0.2.1 + ts-jest: 29.0.1_poggjixajg6vd6yquly7s7dsj4 + ts-node: 10.9.1_ck2axrxkiif44rdbzjywaqjysa + typescript: 4.8.3 + packages: /@ampproject/remapping/2.2.0: @@ -758,7 +785,6 @@ packages: /@next/env/12.3.1: resolution: {integrity: sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==} - dev: false /@next/swc-android-arm-eabi/12.3.1: resolution: {integrity: sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==} @@ -766,7 +792,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: false optional: true /@next/swc-android-arm64/12.3.1: @@ -775,7 +800,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: false optional: true /@next/swc-darwin-arm64/12.3.1: @@ -784,7 +808,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@next/swc-darwin-x64/12.3.1: @@ -793,7 +816,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@next/swc-freebsd-x64/12.3.1: @@ -802,7 +824,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm-gnueabihf/12.3.1: @@ -811,7 +832,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm64-gnu/12.3.1: @@ -820,7 +840,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm64-musl/12.3.1: @@ -829,7 +848,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-x64-gnu/12.3.1: @@ -838,7 +856,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-x64-musl/12.3.1: @@ -847,7 +864,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-win32-arm64-msvc/12.3.1: @@ -856,7 +872,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@next/swc-win32-ia32-msvc/12.3.1: @@ -865,7 +880,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@next/swc-win32-x64-msvc/12.3.1: @@ -874,7 +888,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@nodelib/fs.scandir/2.1.5: @@ -1093,7 +1106,6 @@ packages: resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==} dependencies: tslib: 2.4.0 - dev: false /@tootallnate/once/2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} @@ -1157,6 +1169,10 @@ packages: /@types/bcryptjs/2.4.2: resolution: {integrity: sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==} + /@types/cookiejar/2.1.2: + resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==} + dev: true + /@types/cross-spawn/6.0.2: resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} dependencies: @@ -1208,7 +1224,6 @@ packages: /@types/node/14.18.29: resolution: {integrity: sha512-LhF+9fbIX4iPzhsRLpK5H7iPdvW8L4IwGciXQIOEcuF62+9nw/VQVsOViAOOGxY3OlOKGLFv0sWwJXdwQeTn6A==} - dev: true /@types/node/16.11.62: resolution: {integrity: sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ==} @@ -1230,6 +1245,19 @@ packages: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: true + /@types/superagent/4.1.15: + resolution: {integrity: sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ==} + dependencies: + '@types/cookiejar': 2.1.2 + '@types/node': 16.11.62 + dev: true + + /@types/supertest/2.0.12: + resolution: {integrity: sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ==} + dependencies: + '@types/superagent': 4.1.15 + dev: true + /@types/tmp/0.2.3: resolution: {integrity: sha512-dDZH/tXzwjutnuk4UacGgFRwV+JSLaXL1ikvidfJprkb7L9Nx1njcRHHmi3Dsvt7pgqqTEeucQuOrWHPFgzVHA==} dev: true @@ -1509,6 +1537,10 @@ packages: engines: {node: '>=8'} 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'} @@ -1518,6 +1550,10 @@ packages: resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} dev: true + /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'} @@ -1674,6 +1710,13 @@ packages: ieee754: 1.2.1 dev: true + /call-bind/1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.3 + dev: true + /callsites/3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1867,6 +1910,13 @@ packages: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + /commander/7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} @@ -1886,6 +1936,10 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} dev: true + /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'} @@ -1926,6 +1980,10 @@ packages: /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + /cookiejar/2.1.3: + resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==} + dev: true + /core-util-is/1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true @@ -2017,11 +2075,23 @@ packages: slash: 3.0.0 dev: true + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + /detect-newline/3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} dev: true + /dezalgo/1.0.3: + resolution: {integrity: sha512-K7i4zNfT2kgQz3GylDw40ot9GAE47sFZ9EXHFSPP6zONLgH6kWXE0KWJchkbQJLBkRazq4APwZ4OwiFFlT95OQ==} + 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} @@ -2293,6 +2363,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: true @@ -2358,6 +2432,24 @@ packages: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} 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.0.1: + resolution: {integrity: sha512-rjTMNbp2BpfQShhFbR3Ruk3qk2y9jKpvMW78nJgx8QKtxjDVrwbZG+wvDOmVbifHyOUOQJXxqEy6r0faRrPzTQ==} + dependencies: + dezalgo: 1.0.3 + hexoid: 1.0.0 + once: 1.4.0 + qs: 6.9.3 + dev: true + /fp-ts/2.12.3: resolution: {integrity: sha512-8m0XvW8kZbfnJOA4NvSVXu95mLbPf4LQGwQyqVukIYS4KzSNJiyKSmuZUmbVHteUi6MGkAJGPb0goPZqI+Tsqg==} dev: true @@ -2420,6 +2512,14 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true + /get-intrinsic/1.1.3: + resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + /get-package-type/0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -2490,6 +2590,11 @@ packages: engines: {node: '>=8'} dev: true + /has-symbols/1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + /has-yarn/2.1.0: resolution: {integrity: sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==} engines: {node: '>=8'} @@ -2517,6 +2622,11 @@ packages: tslib: 2.4.0 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==} dev: true @@ -3357,7 +3467,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: false /lower-case/2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -3396,6 +3505,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'} @@ -3403,6 +3517,24 @@ 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/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'} @@ -3446,7 +3578,6 @@ packages: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: false /natural-compare/1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -3500,7 +3631,6 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - dev: false /no-case/3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -3549,6 +3679,10 @@ packages: path-key: 3.1.1 dev: true + /object-inspect/1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + /once/1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -3755,7 +3889,6 @@ packages: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: false /prelude-ls/1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -3808,6 +3941,18 @@ packages: engines: {node: '>=6'} dev: true + /qs/6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /qs/6.9.3: + resolution: {integrity: sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==} + engines: {node: '>=0.6'} + dev: true + /queue-lit/1.4.0: resolution: {integrity: sha512-l1+4YHm4vHWpCnvTg8JMsnPETmPvLGWhqjvNOc8TSbqscGplHVSWXOxybA3vYeMNNIR9Z1PQt85U+S3wFJX2uQ==} dev: true @@ -3823,7 +3968,6 @@ packages: loose-envify: 1.4.0 react: 18.2.0 scheduler: 0.23.0 - dev: false /react-is/18.2.0: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} @@ -3834,7 +3978,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: false /read-pkg-up/7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -3990,7 +4133,6 @@ packages: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 - dev: false /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} @@ -4032,6 +4174,14 @@ packages: resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} dev: true + /side-channel/1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + object-inspect: 1.12.2 + dev: true + /signal-exit/3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true @@ -4073,7 +4223,6 @@ packages: /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: false /source-map-support/0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} @@ -4197,7 +4346,35 @@ packages: dependencies: '@babel/core': 7.19.3 react: 18.2.0 - dev: false + + /superagent/8.0.2: + resolution: {integrity: sha512-QtYZ9uaNAMexI7XWl2vAXAh0j4q9H7T0WVEI/y5qaUB3QLwxo+voUgCQ217AokJzUTIVOp0RTo7fhZrwhD7A2Q==} + engines: {node: '>=6.4.0 <13 || >=14'} + deprecated: Please use v8.0.0 until https://github.com/visionmedia/superagent/issues/1743 is resolved + dependencies: + component-emitter: 1.3.0 + cookiejar: 2.1.3 + debug: 4.3.4 + fast-safe-stringify: 2.1.1 + form-data: 4.0.0 + formidable: 2.0.1 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.11.0 + semver: 7.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /supertest/6.3.0: + resolution: {integrity: sha512-QgWju1cNoacP81Rv88NKkQ4oXTzGg0eNZtOoxp1ROpbS4OHY/eK5b8meShuFtdni161o5X0VQvgo7ErVyKK+Ow==} + engines: {node: '>=6.4.0'} + dependencies: + methods: 1.1.2 + superagent: 8.0.2 + transitivePeerDependencies: + - supports-color + dev: true /supports-color/5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} @@ -4547,7 +4724,6 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: react: 18.2.0 - dev: false /util-deprecate/1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 9a36b4056..2d80ade63 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - 'packages/*' + - 'tests/*' diff --git a/samples/todo/package-lock.json b/samples/todo/package-lock.json index b332ff4fa..1be9d349b 100644 --- a/samples/todo/package-lock.json +++ b/samples/todo/package-lock.json @@ -10,7 +10,6 @@ "dependencies": { "@heroicons/react": "^2.0.12", "@prisma/client": "^4.4.0", - "@zenstackhq/internal": "^0.1.18", "@zenstackhq/runtime": "latest", "daisyui": "^2.31.0", "moment": "^2.29.4", @@ -33,7 +32,7 @@ "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "typescript": "^4.6.2", - "zenstack": "latest" + "zenstack": "^0.1.40" } }, "node_modules/@babel/code-frame": { @@ -721,9 +720,9 @@ } }, "node_modules/@zenstackhq/internal": { - "version": "0.1.18", - "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.18.tgz", - "integrity": "sha512-M+hd3/aEhZ2grOe5FJETN1aA2mKutg7gfPW9eA2iIu0OtwvS1VdS+h7BgmU0rVk/SkuO0qW07r6fJKMr+Okaug==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.19.tgz", + "integrity": "sha512-2b4dkGq1NJRUfEoLXprqSDFKHgI2y4vHb+z0iwc/llRqTCHU/BmqneTn+W28ckq4rh6E/eRor5qRobfGLoWUYA==", "dependencies": { "bcryptjs": "^2.4.3", "deepcopy": "^2.1.0", @@ -4510,12 +4509,12 @@ } }, "node_modules/zenstack": { - "version": "0.1.32", - "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.1.32.tgz", - "integrity": "sha512-xu/248b/PzV8AEwEfL1rpXcNMAcf9wTCIOC6xkurrl4Cba/J1DxFdsLvmJEg88lJlNplNSUAjdD4zMnWhVdEpA==", + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.1.40.tgz", + "integrity": "sha512-aemTRc97FJghdcbLsjSmUtRMRHd81mLDibVFA+0FP0jpbcloPNus986bbZCaIj92DqqpCzJYkyelNuNkvMht6Q==", "dev": true, "dependencies": { - "@zenstackhq/internal": "0.1.9", + "@zenstackhq/internal": "0.1.19", "change-case": "^4.1.2", "chevrotain": "^9.1.0", "colors": "^1.4.0", @@ -4535,22 +4534,6 @@ "engines": { "vscode": "^1.56.0" } - }, - "node_modules/zenstack/node_modules/@zenstackhq/internal": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.9.tgz", - "integrity": "sha512-OIwUkfHoK7zNa8EWiveyIAa8KOngcXfuYpi//r/kkjS238wLbnf5CCElx4KKp4zKCeWd1urhb6nstcN6HBjtwg==", - "dev": true, - "dependencies": { - "bcryptjs": "^2.4.3", - "deepcopy": "^2.1.0", - "swr": "^1.3.0" - }, - "peerDependencies": { - "next": "12.3.1", - "react": "^17.0.2 || ^18", - "react-dom": "^17.0.2 || ^18" - } } }, "dependencies": { @@ -5012,9 +4995,9 @@ } }, "@zenstackhq/internal": { - "version": "0.1.18", - "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.18.tgz", - "integrity": "sha512-M+hd3/aEhZ2grOe5FJETN1aA2mKutg7gfPW9eA2iIu0OtwvS1VdS+h7BgmU0rVk/SkuO0qW07r6fJKMr+Okaug==", + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.19.tgz", + "integrity": "sha512-2b4dkGq1NJRUfEoLXprqSDFKHgI2y4vHb+z0iwc/llRqTCHU/BmqneTn+W28ckq4rh6E/eRor5qRobfGLoWUYA==", "requires": { "bcryptjs": "^2.4.3", "deepcopy": "^2.1.0", @@ -7755,12 +7738,12 @@ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "zenstack": { - "version": "0.1.32", - "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.1.32.tgz", - "integrity": "sha512-xu/248b/PzV8AEwEfL1rpXcNMAcf9wTCIOC6xkurrl4Cba/J1DxFdsLvmJEg88lJlNplNSUAjdD4zMnWhVdEpA==", + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.1.40.tgz", + "integrity": "sha512-aemTRc97FJghdcbLsjSmUtRMRHd81mLDibVFA+0FP0jpbcloPNus986bbZCaIj92DqqpCzJYkyelNuNkvMht6Q==", "dev": true, "requires": { - "@zenstackhq/internal": "0.1.9", + "@zenstackhq/internal": "0.1.19", "change-case": "^4.1.2", "chevrotain": "^9.1.0", "colors": "^1.4.0", @@ -7773,19 +7756,6 @@ "vscode-languageclient": "^7.0.0", "vscode-languageserver": "^7.0.0", "vscode-uri": "^3.0.2" - }, - "dependencies": { - "@zenstackhq/internal": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.9.tgz", - "integrity": "sha512-OIwUkfHoK7zNa8EWiveyIAa8KOngcXfuYpi//r/kkjS238wLbnf5CCElx4KKp4zKCeWd1urhb6nstcN6HBjtwg==", - "dev": true, - "requires": { - "bcryptjs": "^2.4.3", - "deepcopy": "^2.1.0", - "swr": "^1.3.0" - } - } } } } diff --git a/samples/todo/zenstack/schema.zmodel b/samples/todo/zenstack/schema.zmodel index c9666a738..0919be87a 100644 --- a/samples/todo/zenstack/schema.zmodel +++ b/samples/todo/zenstack/schema.zmodel @@ -76,8 +76,8 @@ model User { // can be created by anyone, even not logged in @@allow('create', true) - // can be read by users sharing any space - @@allow('read', spaces?[auth() == user]) + // can be read by current user or users sharing any space + @@allow('read', auth() == this || spaces?[space.members?[user == auth()]]) // can only be updated and deleted by himeself @@allow('update,delete', auth() == this) diff --git a/tests/integration/.gitignore b/tests/integration/.gitignore new file mode 100644 index 000000000..3dc37c4ed --- /dev/null +++ b/tests/integration/.gitignore @@ -0,0 +1 @@ +.npmcache diff --git a/tests/integration/jest.config.ts b/tests/integration/jest.config.ts new file mode 100644 index 000000000..bc5e7d68d --- /dev/null +++ b/tests/integration/jest.config.ts @@ -0,0 +1,13 @@ +/* + * 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, + + // A map from regular expressions to paths to transformers + transform: { '^.+\\.tsx?$': 'ts-jest' }, + + testTimeout: 30000, +}; diff --git a/tests/integration/package-lock.json b/tests/integration/package-lock.json new file mode 100644 index 000000000..8db8dfef8 --- /dev/null +++ b/tests/integration/package-lock.json @@ -0,0 +1,1081 @@ +{ + "name": "integration", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "integration", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@types/node": "^14.18.29" + }, + "devDependencies": { + "@types/jest": "^29.0.3", + "@types/supertest": "^2.0.12", + "@types/tmp": "^0.2.3", + "jest": "^29.0.3", + "next": "^12.3.1", + "supertest": "^6.3.0", + "tmp": "^0.2.1", + "ts-jest": "^29.0.1", + "ts-node": "^10.9.1", + "typescript": "^4.6.2" + } + }, + "../../node_modules/.pnpm/@types+jest@29.0.3/node_modules/@types/jest": { + "version": "29.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "../../node_modules/.pnpm/@types+node@14.18.29/node_modules/@types/node": { + "version": "14.18.29", + "license": "MIT" + }, + "../../node_modules/.pnpm/@types+supertest@2.0.12/node_modules/@types/supertest": { + "version": "2.0.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/superagent": "*" + } + }, + "../../node_modules/.pnpm/@types+tmp@0.2.3/node_modules/@types/tmp": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "../../node_modules/.pnpm/jest@29.0.3_johvxhudwcpndp4mle25vwrlq4/node_modules/jest": { + "version": "29.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.0.3", + "@jest/types": "^29.0.3", + "import-local": "^3.0.2", + "jest-cli": "^29.0.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "devDependencies": { + "@tsd/typescript": "~4.8.2", + "tsd-lite": "^0.6.0" + }, + "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 + } + } + }, + "../../node_modules/.pnpm/next@12.3.1_6tziyx3dehkoeijunclpkpolha/node_modules/next": { + "version": "12.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/env": "12.3.1", + "@swc/helpers": "0.4.11", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.14", + "styled-jsx": "5.0.7", + "use-sync-external-store": "1.2.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "devDependencies": { + "@ampproject/toolbox-optimizer": "2.8.3", + "@babel/code-frame": "7.12.11", + "@babel/core": "7.18.0", + "@babel/eslint-parser": "7.18.2", + "@babel/generator": "7.18.0", + "@babel/plugin-proposal-class-properties": "7.14.5", + "@babel/plugin-proposal-export-namespace-from": "7.14.5", + "@babel/plugin-proposal-numeric-separator": "7.14.5", + "@babel/plugin-proposal-object-rest-spread": "7.14.7", + "@babel/plugin-syntax-bigint": "7.8.3", + "@babel/plugin-syntax-dynamic-import": "7.8.3", + "@babel/plugin-syntax-import-assertions": "7.16.7", + "@babel/plugin-syntax-jsx": "7.14.5", + "@babel/plugin-transform-modules-commonjs": "7.18.0", + "@babel/plugin-transform-runtime": "7.18.0", + "@babel/preset-env": "7.18.0", + "@babel/preset-react": "7.14.5", + "@babel/preset-typescript": "7.17.12", + "@babel/runtime": "7.15.4", + "@babel/traverse": "7.18.0", + "@babel/types": "7.18.0", + "@edge-runtime/primitives": "1.1.0-beta.31", + "@hapi/accept": "5.0.2", + "@napi-rs/cli": "2.7.0", + "@napi-rs/triples": "1.1.0", + "@next/polyfill-module": "12.3.1", + "@next/polyfill-nomodule": "12.3.1", + "@next/react-dev-overlay": "12.3.1", + "@next/react-refresh-utils": "12.3.1", + "@next/swc": "12.3.1", + "@segment/ajv-human-errors": "2.1.2", + "@taskr/clear": "1.1.0", + "@taskr/esnext": "1.1.0", + "@taskr/watch": "1.1.0", + "@types/amphtml-validator": "1.0.0", + "@types/babel__code-frame": "7.0.2", + "@types/babel__core": "7.1.12", + "@types/babel__generator": "7.6.2", + "@types/babel__template": "7.4.0", + "@types/babel__traverse": "7.11.0", + "@types/bytes": "3.1.1", + "@types/ci-info": "2.0.0", + "@types/compression": "0.0.36", + "@types/content-disposition": "0.5.4", + "@types/content-type": "1.1.3", + "@types/cookie": "0.3.3", + "@types/cross-spawn": "6.0.0", + "@types/debug": "4.1.5", + "@types/fresh": "0.5.0", + "@types/glob": "7.1.1", + "@types/jsonwebtoken": "8.3.7", + "@types/lodash": "4.14.149", + "@types/lodash.curry": "4.1.6", + "@types/lru-cache": "5.1.0", + "@types/micromatch": "4.0.2", + "@types/node-fetch": "2.6.1", + "@types/path-to-regexp": "1.7.0", + "@types/react": "16.9.17", + "@types/react-dom": "16.9.4", + "@types/react-is": "16.7.1", + "@types/semver": "7.3.1", + "@types/send": "0.14.4", + "@types/tar": "4.0.3", + "@types/text-table": "0.2.1", + "@types/ua-parser-js": "0.7.36", + "@types/uuid": "8.3.1", + "@types/webpack-sources1": "npm:@types/webpack-sources@0.1.5", + "@types/ws": "8.2.0", + "@vercel/ncc": "0.34.0", + "@vercel/nft": "0.22.1", + "acorn": "8.5.0", + "ajv": "8.11.0", + "amphtml-validator": "1.0.35", + "arg": "4.1.0", + "assert": "2.0.0", + "async-retry": "1.2.3", + "async-sema": "3.0.0", + "babel-plugin-transform-define": "2.0.0", + "babel-plugin-transform-react-remove-prop-types": "0.4.24", + "browserify-zlib": "0.2.0", + "browserslist": "4.20.2", + "buffer": "5.6.0", + "bytes": "3.1.1", + "chalk": "2.4.2", + "ci-info": "watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540", + "cli-select": "1.1.2", + "comment-json": "3.0.3", + "compression": "1.7.4", + "conf": "5.0.0", + "constants-browserify": "1.0.0", + "content-disposition": "0.5.3", + "content-type": "1.0.4", + "cookie": "0.4.1", + "cross-spawn": "6.0.5", + "crypto-browserify": "3.12.0", + "cssnano-simple": "3.0.1", + "debug": "4.1.1", + "devalue": "2.0.1", + "domain-browser": "4.19.0", + "edge-runtime": "1.1.0-beta.31", + "events": "3.3.0", + "find-cache-dir": "3.3.1", + "find-up": "4.1.0", + "fresh": "0.5.2", + "get-orientation": "1.1.2", + "glob": "7.1.7", + "gzip-size": "5.1.1", + "http-proxy": "1.18.1", + "https-browserify": "1.0.0", + "icss-utils": "5.1.0", + "ignore-loader": "0.1.2", + "image-size": "1.0.0", + "is-docker": "2.0.0", + "is-wsl": "2.2.0", + "jest-worker": "27.0.0-next.5", + "json5": "2.2.1", + "jsonwebtoken": "8.5.1", + "loader-utils2": "npm:loader-utils@2.0.0", + "loader-utils3": "npm:loader-utils@3.1.3", + "lodash.curry": "4.1.1", + "lru-cache": "5.1.1", + "micromatch": "4.0.4", + "mini-css-extract-plugin": "2.4.3", + "nanoid": "3.1.32", + "native-url": "0.3.4", + "neo-async": "2.6.1", + "node-fetch": "2.6.7", + "node-html-parser": "5.3.3", + "ora": "4.0.4", + "os-browserify": "0.3.0", + "p-limit": "3.1.0", + "path-browserify": "1.0.1", + "path-to-regexp": "6.1.0", + "postcss-flexbugs-fixes": "5.0.2", + "postcss-modules-extract-imports": "3.0.0", + "postcss-modules-local-by-default": "4.0.0", + "postcss-modules-scope": "3.0.0", + "postcss-modules-values": "4.0.0", + "postcss-preset-env": "7.4.3", + "postcss-safe-parser": "6.0.0", + "postcss-scss": "4.0.3", + "postcss-value-parser": "4.2.0", + "process": "0.11.10", + "punycode": "2.1.1", + "querystring-es3": "0.2.1", + "raw-body": "2.4.1", + "react-is": "17.0.2", + "react-refresh": "0.12.0", + "react-server-dom-webpack": "0.0.0-experimental-8951c5fc9-20220915", + "regenerator-runtime": "0.13.4", + "sass-loader": "12.4.0", + "schema-utils2": "npm:schema-utils@2.7.1", + "schema-utils3": "npm:schema-utils@3.0.0", + "semver": "7.3.2", + "send": "0.17.1", + "setimmediate": "1.0.5", + "source-map": "0.6.1", + "stream-browserify": "3.0.0", + "stream-http": "3.1.1", + "string_decoder": "1.3.0", + "string-hash": "1.1.3", + "strip-ansi": "6.0.0", + "tar": "6.1.11", + "taskr": "1.1.0", + "terser": "5.14.1", + "text-table": "0.2.0", + "timers-browserify": "2.0.12", + "tty-browserify": "0.0.1", + "ua-parser-js": "0.7.28", + "unistore": "3.4.1", + "util": "0.12.4", + "uuid": "8.3.2", + "vm-browserify": "1.1.2", + "watchpack": "2.4.0", + "web-vitals": "3.0.0", + "webpack": "5.74.0", + "webpack-sources1": "npm:webpack-sources@1.4.3", + "webpack-sources3": "npm:webpack-sources@3.2.3", + "ws": "8.2.3" + }, + "engines": { + "node": ">=12.22.0" + }, + "optionalDependencies": { + "@next/swc-android-arm-eabi": "12.3.1", + "@next/swc-android-arm64": "12.3.1", + "@next/swc-darwin-arm64": "12.3.1", + "@next/swc-darwin-x64": "12.3.1", + "@next/swc-freebsd-x64": "12.3.1", + "@next/swc-linux-arm-gnueabihf": "12.3.1", + "@next/swc-linux-arm64-gnu": "12.3.1", + "@next/swc-linux-arm64-musl": "12.3.1", + "@next/swc-linux-x64-gnu": "12.3.1", + "@next/swc-linux-x64-musl": "12.3.1", + "@next/swc-win32-arm64-msvc": "12.3.1", + "@next/swc-win32-ia32-msvc": "12.3.1", + "@next/swc-win32-x64-msvc": "12.3.1" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^6.0.0 || ^7.0.0", + "react": "^17.0.2 || ^18.0.0-0", + "react-dom": "^17.0.2 || ^18.0.0-0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "../../node_modules/.pnpm/supertest@6.3.0/node_modules/supertest": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "methods": "^1.1.2", + "superagent": "^8.0.0" + }, + "devDependencies": { + "body-parser": "^1.20.0", + "cookie-parser": "^1.4.6", + "eslint": "^8.18.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.26.0", + "express": "^4.18.1", + "mocha": "^10.0.0", + "nock": "^13.2.8", + "nyc": "^15.1.0", + "proxyquire": "^2.1.3", + "should": "^13.2.3" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "../../node_modules/.pnpm/tmp@0.2.1/node_modules/tmp": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "rimraf": "^3.0.0" + }, + "devDependencies": { + "eslint": "^6.3.0", + "eslint-plugin-mocha": "^6.1.1", + "istanbul": "^0.4.5", + "lerna-changelog": "^1.0.1", + "mocha": "^6.2.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "../../node_modules/.pnpm/ts-jest@29.0.1_poggjixajg6vd6yquly7s7dsj4/node_modules/ts-jest": { + "version": "29.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.1", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "devDependencies": { + "@commitlint/cli": "17.x", + "@commitlint/config-angular": "^17.1.0", + "@jest/transform": "^29.0.3", + "@jest/types": "^29.0.3", + "@types/babel__core": "7.x", + "@types/cross-spawn": "latest", + "@types/fs-extra": "latest", + "@types/js-yaml": "latest", + "@types/lodash.camelcase": "4.x", + "@types/lodash.memoize": "4.x", + "@types/lodash.set": "4.x", + "@types/micromatch": "4.x", + "@types/node": "17.0.35", + "@types/node-fetch": "^3.0.3", + "@types/react": "18.x", + "@types/rimraf": "^3.0.2", + "@types/semver": "latest", + "@types/yargs": "latest", + "@types/yargs-parser": "21.x", + "@typescript-eslint/eslint-plugin": "^5.37.0", + "@typescript-eslint/parser": "^5.37.0", + "babel-jest": "^29.0.3", + "conventional-changelog-cli": "2.x", + "cross-spawn": "latest", + "esbuild": "~0.15.7", + "eslint": "^8.23.1", + "eslint-config-prettier": "latest", + "eslint-plugin-import": "latest", + "eslint-plugin-jest": "latest", + "eslint-plugin-jsdoc": "latest", + "eslint-plugin-prefer-arrow": "latest", + "eslint-plugin-prettier": "latest", + "execa": "5.1.1", + "fs-extra": "10.x", + "glob": "^8.0.3", + "glob-gitignore": "latest", + "husky": "4.x", + "jest": "^29.0.3", + "jest-snapshot-serializer-raw": "^1.2.0", + "js-yaml": "latest", + "json-schema-to-typescript": "^11.0.2", + "lint-staged": "latest", + "lodash.camelcase": "^4.3.0", + "lodash.set": "^4.3.2", + "node-fetch": "^3.2.10", + "prettier": "^2.7.1", + "typescript": "~4.8.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "../../node_modules/.pnpm/ts-node@10.9.1_ck2axrxkiif44rdbzjywaqjysa/node_modules/ts-node": { + "version": "10.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.19.4", + "@swc/core": ">=1.2.205", + "@swc/wasm": ">=1.2.205", + "@types/diff": "^4.0.2", + "@types/lodash": "^4.14.151", + "@types/node": "13.13.5", + "@types/proper-lockfile": "^4.1.2", + "@types/proxyquire": "^1.3.28", + "@types/react": "^16.14.19", + "@types/rimraf": "^3.0.0", + "@types/semver": "^7.1.0", + "@yarnpkg/fslib": "^2.4.0", + "ava": "^3.15.0", + "axios": "^0.21.1", + "dprint": "^0.25.0", + "expect": "^27.0.2", + "get-stream": "^6.0.0", + "lodash": "^4.17.15", + "ntypescript": "^1.201507091536.1", + "nyc": "^15.0.1", + "outdent": "^0.8.0", + "proper-lockfile": "^4.1.2", + "proxyquire": "^2.0.0", + "react": "^16.14.0", + "rimraf": "^3.0.0", + "semver": "^7.1.3", + "throat": "^6.0.1", + "typedoc": "^0.22.10", + "typescript": "4.7.4", + "typescript-json-schema": "^0.53.0", + "util.promisify": "^1.0.1" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "../../node_modules/.pnpm/typescript@4.8.3/node_modules/typescript": { + "version": "4.8.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "devDependencies": { + "@octokit/rest": "latest", + "@types/chai": "latest", + "@types/convert-source-map": "latest", + "@types/fs-extra": "^9.0.13", + "@types/glob": "latest", + "@types/gulp": "^4.0.9", + "@types/gulp-concat": "latest", + "@types/gulp-newer": "latest", + "@types/gulp-rename": "latest", + "@types/gulp-sourcemaps": "latest", + "@types/merge2": "latest", + "@types/microsoft__typescript-etw": "latest", + "@types/minimatch": "latest", + "@types/minimist": "latest", + "@types/mkdirp": "latest", + "@types/mocha": "latest", + "@types/ms": "latest", + "@types/node": "latest", + "@types/node-fetch": "^2.6.2", + "@types/q": "latest", + "@types/source-map-support": "latest", + "@types/xml2js": "^0.4.11", + "@typescript-eslint/eslint-plugin": "^5.28.0", + "@typescript-eslint/parser": "^5.28.0", + "@typescript-eslint/utils": "^5.28.0", + "async": "latest", + "azure-devops-node-api": "^11.1.1", + "chai": "latest", + "chalk": "^4.1.2", + "convert-source-map": "latest", + "del": "6.1.1", + "diff": "^5.1.0", + "eslint": "8.17.0", + "eslint-formatter-autolinkable-stylish": "1.2.0", + "eslint-plugin-import": "2.26.0", + "eslint-plugin-jsdoc": "39.3.2", + "eslint-plugin-no-null": "1.0.2", + "fancy-log": "latest", + "fs-extra": "^9.1.0", + "glob": "latest", + "gulp": "^4.0.2", + "gulp-concat": "latest", + "gulp-insert": "latest", + "gulp-newer": "latest", + "gulp-rename": "latest", + "gulp-sourcemaps": "latest", + "merge2": "latest", + "minimist": "latest", + "mkdirp": "latest", + "mocha": "latest", + "mocha-fivemat-progress-reporter": "latest", + "ms": "^2.1.3", + "node-fetch": "^2.6.7", + "prex": "^0.4.7", + "q": "latest", + "source-map-support": "latest", + "typescript": "^4.5.5", + "vinyl": "latest", + "vinyl-sourcemaps-apply": "latest", + "xml2js": "^0.4.23" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/@types/jest": { + "resolved": "../../node_modules/.pnpm/@types+jest@29.0.3/node_modules/@types/jest", + "link": true + }, + "node_modules/@types/node": { + "resolved": "../../node_modules/.pnpm/@types+node@14.18.29/node_modules/@types/node", + "link": true + }, + "node_modules/@types/supertest": { + "resolved": "../../node_modules/.pnpm/@types+supertest@2.0.12/node_modules/@types/supertest", + "link": true + }, + "node_modules/@types/tmp": { + "resolved": "../../node_modules/.pnpm/@types+tmp@0.2.3/node_modules/@types/tmp", + "link": true + }, + "node_modules/jest": { + "resolved": "../../node_modules/.pnpm/jest@29.0.3_johvxhudwcpndp4mle25vwrlq4/node_modules/jest", + "link": true + }, + "node_modules/next": { + "resolved": "../../node_modules/.pnpm/next@12.3.1_6tziyx3dehkoeijunclpkpolha/node_modules/next", + "link": true + }, + "node_modules/supertest": { + "resolved": "../../node_modules/.pnpm/supertest@6.3.0/node_modules/supertest", + "link": true + }, + "node_modules/tmp": { + "resolved": "../../node_modules/.pnpm/tmp@0.2.1/node_modules/tmp", + "link": true + }, + "node_modules/ts-jest": { + "resolved": "../../node_modules/.pnpm/ts-jest@29.0.1_poggjixajg6vd6yquly7s7dsj4/node_modules/ts-jest", + "link": true + }, + "node_modules/ts-node": { + "resolved": "../../node_modules/.pnpm/ts-node@10.9.1_ck2axrxkiif44rdbzjywaqjysa/node_modules/ts-node", + "link": true + }, + "node_modules/typescript": { + "resolved": "../../node_modules/.pnpm/typescript@4.8.3/node_modules/typescript", + "link": true + } + }, + "dependencies": { + "@types/jest": { + "version": "file:../../node_modules/.pnpm/@types+jest@29.0.3/node_modules/@types/jest", + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/node": { + "version": "file:../../node_modules/.pnpm/@types+node@14.18.29/node_modules/@types/node" + }, + "@types/supertest": { + "version": "file:../../node_modules/.pnpm/@types+supertest@2.0.12/node_modules/@types/supertest", + "requires": { + "@types/superagent": "*" + } + }, + "@types/tmp": { + "version": "file:../../node_modules/.pnpm/@types+tmp@0.2.3/node_modules/@types/tmp" + }, + "jest": { + "version": "file:../../node_modules/.pnpm/jest@29.0.3_johvxhudwcpndp4mle25vwrlq4/node_modules/jest", + "requires": { + "@jest/core": "^29.0.3", + "@jest/types": "^29.0.3", + "@tsd/typescript": "~4.8.2", + "import-local": "^3.0.2", + "jest-cli": "^29.0.3", + "tsd-lite": "^0.6.0" + } + }, + "next": { + "version": "file:../../node_modules/.pnpm/next@12.3.1_6tziyx3dehkoeijunclpkpolha/node_modules/next", + "requires": { + "@ampproject/toolbox-optimizer": "2.8.3", + "@babel/code-frame": "7.12.11", + "@babel/core": "7.18.0", + "@babel/eslint-parser": "7.18.2", + "@babel/generator": "7.18.0", + "@babel/plugin-proposal-class-properties": "7.14.5", + "@babel/plugin-proposal-export-namespace-from": "7.14.5", + "@babel/plugin-proposal-numeric-separator": "7.14.5", + "@babel/plugin-proposal-object-rest-spread": "7.14.7", + "@babel/plugin-syntax-bigint": "7.8.3", + "@babel/plugin-syntax-dynamic-import": "7.8.3", + "@babel/plugin-syntax-import-assertions": "7.16.7", + "@babel/plugin-syntax-jsx": "7.14.5", + "@babel/plugin-transform-modules-commonjs": "7.18.0", + "@babel/plugin-transform-runtime": "7.18.0", + "@babel/preset-env": "7.18.0", + "@babel/preset-react": "7.14.5", + "@babel/preset-typescript": "7.17.12", + "@babel/runtime": "7.15.4", + "@babel/traverse": "7.18.0", + "@babel/types": "7.18.0", + "@edge-runtime/primitives": "1.1.0-beta.31", + "@hapi/accept": "5.0.2", + "@napi-rs/cli": "2.7.0", + "@napi-rs/triples": "1.1.0", + "@next/env": "12.3.1", + "@next/polyfill-module": "12.3.1", + "@next/polyfill-nomodule": "12.3.1", + "@next/react-dev-overlay": "12.3.1", + "@next/react-refresh-utils": "12.3.1", + "@next/swc": "12.3.1", + "@next/swc-android-arm-eabi": "12.3.1", + "@next/swc-android-arm64": "12.3.1", + "@next/swc-darwin-arm64": "12.3.1", + "@next/swc-darwin-x64": "12.3.1", + "@next/swc-freebsd-x64": "12.3.1", + "@next/swc-linux-arm-gnueabihf": "12.3.1", + "@next/swc-linux-arm64-gnu": "12.3.1", + "@next/swc-linux-arm64-musl": "12.3.1", + "@next/swc-linux-x64-gnu": "12.3.1", + "@next/swc-linux-x64-musl": "12.3.1", + "@next/swc-win32-arm64-msvc": "12.3.1", + "@next/swc-win32-ia32-msvc": "12.3.1", + "@next/swc-win32-x64-msvc": "12.3.1", + "@segment/ajv-human-errors": "2.1.2", + "@swc/helpers": "0.4.11", + "@taskr/clear": "1.1.0", + "@taskr/esnext": "1.1.0", + "@taskr/watch": "1.1.0", + "@types/amphtml-validator": "1.0.0", + "@types/babel__code-frame": "7.0.2", + "@types/babel__core": "7.1.12", + "@types/babel__generator": "7.6.2", + "@types/babel__template": "7.4.0", + "@types/babel__traverse": "7.11.0", + "@types/bytes": "3.1.1", + "@types/ci-info": "2.0.0", + "@types/compression": "0.0.36", + "@types/content-disposition": "0.5.4", + "@types/content-type": "1.1.3", + "@types/cookie": "0.3.3", + "@types/cross-spawn": "6.0.0", + "@types/debug": "4.1.5", + "@types/fresh": "0.5.0", + "@types/glob": "7.1.1", + "@types/jsonwebtoken": "8.3.7", + "@types/lodash": "4.14.149", + "@types/lodash.curry": "4.1.6", + "@types/lru-cache": "5.1.0", + "@types/micromatch": "4.0.2", + "@types/node-fetch": "2.6.1", + "@types/path-to-regexp": "1.7.0", + "@types/react": "16.9.17", + "@types/react-dom": "16.9.4", + "@types/react-is": "16.7.1", + "@types/semver": "7.3.1", + "@types/send": "0.14.4", + "@types/tar": "4.0.3", + "@types/text-table": "0.2.1", + "@types/ua-parser-js": "0.7.36", + "@types/uuid": "8.3.1", + "@types/webpack-sources1": "npm:@types/webpack-sources@0.1.5", + "@types/ws": "8.2.0", + "@vercel/ncc": "0.34.0", + "@vercel/nft": "0.22.1", + "acorn": "8.5.0", + "ajv": "8.11.0", + "amphtml-validator": "1.0.35", + "arg": "4.1.0", + "assert": "2.0.0", + "async-retry": "1.2.3", + "async-sema": "3.0.0", + "babel-plugin-transform-define": "2.0.0", + "babel-plugin-transform-react-remove-prop-types": "0.4.24", + "browserify-zlib": "0.2.0", + "browserslist": "4.20.2", + "buffer": "5.6.0", + "bytes": "3.1.1", + "caniuse-lite": "^1.0.30001406", + "chalk": "2.4.2", + "ci-info": "watson/ci-info#f43f6a1cefff47fb361c88cf4b943fdbcaafe540", + "cli-select": "1.1.2", + "comment-json": "3.0.3", + "compression": "1.7.4", + "conf": "5.0.0", + "constants-browserify": "1.0.0", + "content-disposition": "0.5.3", + "content-type": "1.0.4", + "cookie": "0.4.1", + "cross-spawn": "6.0.5", + "crypto-browserify": "3.12.0", + "cssnano-simple": "3.0.1", + "debug": "4.1.1", + "devalue": "2.0.1", + "domain-browser": "4.19.0", + "edge-runtime": "1.1.0-beta.31", + "events": "3.3.0", + "find-cache-dir": "3.3.1", + "find-up": "4.1.0", + "fresh": "0.5.2", + "get-orientation": "1.1.2", + "glob": "7.1.7", + "gzip-size": "5.1.1", + "http-proxy": "1.18.1", + "https-browserify": "1.0.0", + "icss-utils": "5.1.0", + "ignore-loader": "0.1.2", + "image-size": "1.0.0", + "is-docker": "2.0.0", + "is-wsl": "2.2.0", + "jest-worker": "27.0.0-next.5", + "json5": "2.2.1", + "jsonwebtoken": "8.5.1", + "loader-utils2": "npm:loader-utils@2.0.0", + "loader-utils3": "npm:loader-utils@3.1.3", + "lodash.curry": "4.1.1", + "lru-cache": "5.1.1", + "micromatch": "4.0.4", + "mini-css-extract-plugin": "2.4.3", + "nanoid": "3.1.32", + "native-url": "0.3.4", + "neo-async": "2.6.1", + "node-fetch": "2.6.7", + "node-html-parser": "5.3.3", + "ora": "4.0.4", + "os-browserify": "0.3.0", + "p-limit": "3.1.0", + "path-browserify": "1.0.1", + "path-to-regexp": "6.1.0", + "postcss": "8.4.14", + "postcss-flexbugs-fixes": "5.0.2", + "postcss-modules-extract-imports": "3.0.0", + "postcss-modules-local-by-default": "4.0.0", + "postcss-modules-scope": "3.0.0", + "postcss-modules-values": "4.0.0", + "postcss-preset-env": "7.4.3", + "postcss-safe-parser": "6.0.0", + "postcss-scss": "4.0.3", + "postcss-value-parser": "4.2.0", + "process": "0.11.10", + "punycode": "2.1.1", + "querystring-es3": "0.2.1", + "raw-body": "2.4.1", + "react-is": "17.0.2", + "react-refresh": "0.12.0", + "react-server-dom-webpack": "0.0.0-experimental-8951c5fc9-20220915", + "regenerator-runtime": "0.13.4", + "sass-loader": "12.4.0", + "schema-utils2": "npm:schema-utils@2.7.1", + "schema-utils3": "npm:schema-utils@3.0.0", + "semver": "7.3.2", + "send": "0.17.1", + "setimmediate": "1.0.5", + "source-map": "0.6.1", + "stream-browserify": "3.0.0", + "stream-http": "3.1.1", + "string_decoder": "1.3.0", + "string-hash": "1.1.3", + "strip-ansi": "6.0.0", + "styled-jsx": "5.0.7", + "tar": "6.1.11", + "taskr": "1.1.0", + "terser": "5.14.1", + "text-table": "0.2.0", + "timers-browserify": "2.0.12", + "tty-browserify": "0.0.1", + "ua-parser-js": "0.7.28", + "unistore": "3.4.1", + "use-sync-external-store": "1.2.0", + "util": "0.12.4", + "uuid": "8.3.2", + "vm-browserify": "1.1.2", + "watchpack": "2.4.0", + "web-vitals": "3.0.0", + "webpack": "5.74.0", + "webpack-sources1": "npm:webpack-sources@1.4.3", + "webpack-sources3": "npm:webpack-sources@3.2.3", + "ws": "8.2.3" + } + }, + "supertest": { + "version": "file:../../node_modules/.pnpm/supertest@6.3.0/node_modules/supertest", + "requires": { + "body-parser": "^1.20.0", + "cookie-parser": "^1.4.6", + "eslint": "^8.18.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.26.0", + "express": "^4.18.1", + "methods": "^1.1.2", + "mocha": "^10.0.0", + "nock": "^13.2.8", + "nyc": "^15.1.0", + "proxyquire": "^2.1.3", + "should": "^13.2.3", + "superagent": "^8.0.0" + } + }, + "tmp": { + "version": "file:../../node_modules/.pnpm/tmp@0.2.1/node_modules/tmp", + "requires": { + "eslint": "^6.3.0", + "eslint-plugin-mocha": "^6.1.1", + "istanbul": "^0.4.5", + "lerna-changelog": "^1.0.1", + "mocha": "^6.2.0", + "rimraf": "^3.0.0" + } + }, + "ts-jest": { + "version": "file:../../node_modules/.pnpm/ts-jest@29.0.1_poggjixajg6vd6yquly7s7dsj4/node_modules/ts-jest", + "requires": { + "@commitlint/cli": "17.x", + "@commitlint/config-angular": "^17.1.0", + "@jest/transform": "^29.0.3", + "@jest/types": "^29.0.3", + "@types/babel__core": "7.x", + "@types/cross-spawn": "latest", + "@types/fs-extra": "latest", + "@types/js-yaml": "latest", + "@types/lodash.camelcase": "4.x", + "@types/lodash.memoize": "4.x", + "@types/lodash.set": "4.x", + "@types/micromatch": "4.x", + "@types/node": "17.0.35", + "@types/node-fetch": "^3.0.3", + "@types/react": "18.x", + "@types/rimraf": "^3.0.2", + "@types/semver": "latest", + "@types/yargs": "latest", + "@types/yargs-parser": "21.x", + "@typescript-eslint/eslint-plugin": "^5.37.0", + "@typescript-eslint/parser": "^5.37.0", + "babel-jest": "^29.0.3", + "bs-logger": "0.x", + "conventional-changelog-cli": "2.x", + "cross-spawn": "latest", + "esbuild": "~0.15.7", + "eslint": "^8.23.1", + "eslint-config-prettier": "latest", + "eslint-plugin-import": "latest", + "eslint-plugin-jest": "latest", + "eslint-plugin-jsdoc": "latest", + "eslint-plugin-prefer-arrow": "latest", + "eslint-plugin-prettier": "latest", + "execa": "5.1.1", + "fast-json-stable-stringify": "2.x", + "fs-extra": "10.x", + "glob": "^8.0.3", + "glob-gitignore": "latest", + "husky": "4.x", + "jest": "^29.0.3", + "jest-snapshot-serializer-raw": "^1.2.0", + "jest-util": "^29.0.0", + "js-yaml": "latest", + "json-schema-to-typescript": "^11.0.2", + "json5": "^2.2.1", + "lint-staged": "latest", + "lodash.camelcase": "^4.3.0", + "lodash.memoize": "4.x", + "lodash.set": "^4.3.2", + "make-error": "1.x", + "node-fetch": "^3.2.10", + "prettier": "^2.7.1", + "semver": "7.x", + "typescript": "~4.8.3", + "yargs-parser": "^21.0.1" + } + }, + "ts-node": { + "version": "file:../../node_modules/.pnpm/ts-node@10.9.1_ck2axrxkiif44rdbzjywaqjysa/node_modules/ts-node", + "requires": { + "@cspotcode/source-map-support": "^0.8.0", + "@microsoft/api-extractor": "^7.19.4", + "@swc/core": ">=1.2.205", + "@swc/wasm": ">=1.2.205", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "@types/diff": "^4.0.2", + "@types/lodash": "^4.14.151", + "@types/node": "13.13.5", + "@types/proper-lockfile": "^4.1.2", + "@types/proxyquire": "^1.3.28", + "@types/react": "^16.14.19", + "@types/rimraf": "^3.0.0", + "@types/semver": "^7.1.0", + "@yarnpkg/fslib": "^2.4.0", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "ava": "^3.15.0", + "axios": "^0.21.1", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "dprint": "^0.25.0", + "expect": "^27.0.2", + "get-stream": "^6.0.0", + "lodash": "^4.17.15", + "make-error": "^1.1.1", + "ntypescript": "^1.201507091536.1", + "nyc": "^15.0.1", + "outdent": "^0.8.0", + "proper-lockfile": "^4.1.2", + "proxyquire": "^2.0.0", + "react": "^16.14.0", + "rimraf": "^3.0.0", + "semver": "^7.1.3", + "throat": "^6.0.1", + "typedoc": "^0.22.10", + "typescript": "4.7.4", + "typescript-json-schema": "^0.53.0", + "util.promisify": "^1.0.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + } + }, + "typescript": { + "version": "file:../../node_modules/.pnpm/typescript@4.8.3/node_modules/typescript", + "requires": { + "@octokit/rest": "latest", + "@types/chai": "latest", + "@types/convert-source-map": "latest", + "@types/fs-extra": "^9.0.13", + "@types/glob": "latest", + "@types/gulp": "^4.0.9", + "@types/gulp-concat": "latest", + "@types/gulp-newer": "latest", + "@types/gulp-rename": "latest", + "@types/gulp-sourcemaps": "latest", + "@types/merge2": "latest", + "@types/microsoft__typescript-etw": "latest", + "@types/minimatch": "latest", + "@types/minimist": "latest", + "@types/mkdirp": "latest", + "@types/mocha": "latest", + "@types/ms": "latest", + "@types/node": "latest", + "@types/node-fetch": "^2.6.2", + "@types/q": "latest", + "@types/source-map-support": "latest", + "@types/xml2js": "^0.4.11", + "@typescript-eslint/eslint-plugin": "^5.28.0", + "@typescript-eslint/parser": "^5.28.0", + "@typescript-eslint/utils": "^5.28.0", + "async": "latest", + "azure-devops-node-api": "^11.1.1", + "chai": "latest", + "chalk": "^4.1.2", + "convert-source-map": "latest", + "del": "6.1.1", + "diff": "^5.1.0", + "eslint": "8.17.0", + "eslint-formatter-autolinkable-stylish": "1.2.0", + "eslint-plugin-import": "2.26.0", + "eslint-plugin-jsdoc": "39.3.2", + "eslint-plugin-no-null": "1.0.2", + "fancy-log": "latest", + "fs-extra": "^9.1.0", + "glob": "latest", + "gulp": "^4.0.2", + "gulp-concat": "latest", + "gulp-insert": "latest", + "gulp-newer": "latest", + "gulp-rename": "latest", + "gulp-sourcemaps": "latest", + "merge2": "latest", + "minimist": "latest", + "mkdirp": "latest", + "mocha": "latest", + "mocha-fivemat-progress-reporter": "latest", + "ms": "^2.1.3", + "node-fetch": "^2.6.7", + "prex": "^0.4.7", + "q": "latest", + "source-map-support": "latest", + "typescript": "^4.5.5", + "vinyl": "latest", + "vinyl-sourcemaps-apply": "latest", + "xml2js": "^0.4.23" + } + } + } +} diff --git a/tests/integration/package.json b/tests/integration/package.json new file mode 100644 index 000000000..f3e5a15fc --- /dev/null +++ b/tests/integration/package.json @@ -0,0 +1,27 @@ +{ + "name": "integration", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "jest" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/jest": "^29.0.3", + "@types/supertest": "^2.0.12", + "@types/tmp": "^0.2.3", + "jest": "^29.0.3", + "next": "^12.3.1", + "supertest": "^6.3.0", + "tmp": "^0.2.1", + "ts-jest": "^29.0.1", + "ts-node": "^10.9.1", + "typescript": "^4.6.2" + }, + "dependencies": { + "@types/node": "^14.18.29" + } +} diff --git a/tests/integration/tests/e2e.test.ts b/tests/integration/tests/e2e.test.ts new file mode 100644 index 000000000..4463139b4 --- /dev/null +++ b/tests/integration/tests/e2e.test.ts @@ -0,0 +1,532 @@ +import * as fs from 'fs'; +import { makeClient, run, setup } from './utils'; + +describe('E2E Tests', () => { + let workDir: string; + + beforeAll(async () => { + workDir = await setup(); + }); + + afterAll(() => { + if (workDir) { + fs.rmSync(workDir, { recursive: true, force: true }); + } + }); + + beforeEach(() => { + run('npx prisma migrate reset --schema ./zenstack/schema.prisma -f'); + }); + + it('user', async () => { + const userClient = makeClient('/api/data/User'); + const user1 = { + id: 'user1', + email: 'user1@zenstack.dev', + name: 'User 1', + }; + const user2 = { + id: 'user2', + email: 'user2@zenstack.dev', + name: 'User 2', + }; + const user1Client = makeClient('/api/data/User/user1', user1.id); + const user2Client = makeClient('/api/data/User/user2', user1.id); + + // create user1 + await userClient + .post('/') + .send({ + data: user1, + }) + .expect(201) + .expect((resp) => { + expect(resp.body).toEqual(expect.objectContaining(user1)); + }); + + const credClient = makeClient('/api/data/User', user1.id); + + // find + await credClient + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body).toEqual([expect.objectContaining(user1)]); + }); + + // get + await user1Client + .get('/') + .expect(200) + .expect((resp) => + expect(resp.body).toEqual(expect.objectContaining(user1)) + ); + await user2Client.get('/').expect(404); + + // create user2 + await userClient.post('/').send({ + data: user2, + }); + + // find with user1 should only get user1 + await credClient + .get('/') + .expect(200) + .expect((resp) => { + expect(resp.body).toHaveLength(1); + expect(resp.body).toEqual([expect.objectContaining(user1)]); + }); + + // get user2 as user1 + await user2Client.get('/').expect(404); + + // add both users into the same space + const spaceClient = makeClient('/api/data/Space', user1.id); + await spaceClient + .post('/') + .send({ + data: { + name: 'Space 1', + slug: 'space1', + members: { + create: [ + { + user: { connect: { id: user1.id } }, + role: 'USER', + }, + { + user: { connect: { id: user2.id } }, + role: 'USER', + }, + ], + }, + }, + }) + .expect(201); + + // now both user1 and user2 should be visible + await credClient + .get('/') + .expect((resp) => expect(resp.body).toHaveLength(2)); + await user2Client + .get('/') + .expect(200) + .expect((resp) => + expect(resp.body).toEqual(expect.objectContaining(user2)) + ); + + // update user2 as user1 + await user2Client + .put('/') + .send({ + data: { + name: 'hello', + }, + }) + .expect(403); + + // update user1 as user1 + await user1Client + .put('/') + .send({ + data: { + name: 'hello', + }, + }) + .expect(200) + .expect((resp) => expect(resp.body.name).toBe('hello')); + + // delete user2 as user1 + await user2Client.delete('/').expect(403); + + // delete user1 as user1 + await user1Client.delete('/').expect(200); + await user1Client.get('/').expect(404); + }); + + it('todo list', async () => { + await createSpaceAndUsers(); + + const listClient = makeClient('/api/data/List'); + await listClient + .post('/') + .send({ + data: { + id: 'list1', + title: 'List 1', + owner: { connect: { id: user1.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(403); + + const credClient = makeClient('/api/data/List', user1.id); + await credClient + .post('/') + .send({ + data: { + id: 'list1', + title: 'List 1', + owner: { connect: { id: user1.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(201); + + await credClient + .get('/') + .expect(200) + .expect((resp) => expect(resp.body).toHaveLength(1)); + + await listClient + .get('/') + .expect(200) + .expect((resp) => expect(resp.body).toHaveLength(0)); + + const list1Client = makeClient('/api/data/List/list1'); + await list1Client.get('/').expect(404); + + // accessible to owner + const list1CredClientUser1 = makeClient( + '/api/data/List/list1', + user1.id + ); + await list1CredClientUser1 + .get('/') + .expect(200) + .expect((resp) => + expect(resp.body).toEqual( + expect.objectContaining({ id: 'list1', title: 'List 1' }) + ) + ); + + // accessible to user in the space + const list1CredClientUser2 = makeClient( + '/api/data/List/list1', + user2.id + ); + await list1CredClientUser2.get('/').expect(200); + + // inaccessible to user not in the space + const list1CredClientUser3 = makeClient( + '/api/data/List/list1', + user3.id + ); + await list1CredClientUser3.get('/').expect(404); + + // make a private list + await credClient + .post('/') + .send({ + data: { + id: 'list2', + title: 'List 2', + private: true, + owner: { connect: { id: user1.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(201); + + // accessible to owner + const list2CredClientUser1 = makeClient( + '/api/data/List/list2', + user1.id + ); + await list2CredClientUser1.get('/').expect(200); + + // inaccessible to other user in the space + const list2CredClientUser2 = makeClient( + '/api/data/List/list2', + user2.id + ); + await list2CredClientUser2.get('/').expect(404); + + // create a list which doesn't match credential should fail + await credClient + .post('/') + .send({ + data: { + id: 'list3', + title: 'List 3', + owner: { connect: { id: user2.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(403); + + // create a list which doesn't match credential's space should fail + await credClient + .post('/') + .send({ + data: { + id: 'list3', + title: 'List 3', + owner: { connect: { id: user1.id } }, + space: { connect: { id: space2.id } }, + }, + }) + .expect(403); + + // update list + await list1CredClientUser1 + .put('/') + .send({ + data: { + title: 'List 1 updated', + }, + }) + .expect(200) + .expect((resp) => expect(resp.body.title).toBe('List 1 updated')); + + await list1CredClientUser2 + .put('/') + .send({ + data: { + title: 'List 1 updated', + }, + }) + .expect(403); + + // delete list + await list1CredClientUser2.delete('/').expect(403); + await list1CredClientUser1.delete('/').expect(200); + await list1CredClientUser1.get('/').expect(404); + }); + + it('todo', async () => { + await createSpaceAndUsers(); + + const listClient = makeClient('/api/data/List', user1.id); + await listClient + .post('/') + .send({ + data: { + id: 'list1', + title: 'List 1', + owner: { connect: { id: user1.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(201); + + const todoClientUser1 = makeClient('/api/data/Todo', user1.id); + const todoClientUser2 = makeClient('/api/data/Todo', user2.id); + + // create + await todoClientUser1 + .post('/') + .send({ + data: { + id: 'todo1', + title: 'Todo 1', + owner: { connect: { id: user1.id } }, + list: { + connect: { id: 'list1' }, + }, + }, + }) + .expect(201); + await todoClientUser2 + .post('/') + .send({ + data: { + id: 'todo2', + title: 'Todo 2', + owner: { connect: { id: user2.id } }, + list: { + connect: { id: 'list1' }, + }, + }, + }) + .expect(201); + + // read + await todoClientUser1 + .get('/') + .expect(200) + .expect((resp) => expect(resp.body).toHaveLength(2)); + await todoClientUser2 + .get('/') + .expect(200) + .expect((resp) => expect(resp.body).toHaveLength(2)); + + const todo1ClientUser1 = makeClient('/api/data/Todo/todo1', user1.id); + const todo2ClientUser1 = makeClient('/api/data/Todo/todo2', user1.id); + + // update, user in the same space can freely update + await todo1ClientUser1 + .put('/') + .send({ + data: { + title: 'Todo 1 updated', + }, + }) + .expect(200); + await todo2ClientUser1 + .put('/') + .send({ + data: { + title: 'Todo 2 updated', + }, + }) + .expect(200); + + // create a private list + await listClient + .post('/') + .send({ + data: { + id: 'list2', + private: true, + title: 'List 2', + owner: { connect: { id: user1.id } }, + space: { connect: { id: space1.id } }, + }, + }) + .expect(201); + + // create + await todoClientUser1 + .post('/') + .send({ + data: { + id: 'todo3', + title: 'Todo 3', + owner: { connect: { id: user1.id } }, + list: { + connect: { id: 'list2' }, + }, + }, + }) + .expect(201); + await todoClientUser2 + .post('/') + .send({ + data: { + id: 'todo4', + title: 'Todo 4', + owner: { connect: { id: user2.id } }, + list: { + connect: { id: 'list2' }, + }, + }, + }) + .expect(403); + + // update, only owner can update todo in a private list + const todo3ClientUser1 = makeClient('/api/data/Todo/todo3', user1.id); + const todo3ClientUser2 = makeClient('/api/data/Todo/todo3', user2.id); + await todo3ClientUser1 + .put('/') + .send({ + data: { + title: 'Todo 3 updated', + }, + }) + .expect(200); + await todo3ClientUser2 + .put('/') + .send({ + data: { + title: 'Todo 3 updated', + }, + }) + .expect(403); + }); +}); + +const user1 = { + id: 'user1', + email: 'user1@zenstack.dev', + name: 'User 1', +}; + +const user2 = { + id: 'user2', + email: 'user2@zenstack.dev', + name: 'User 2', +}; + +const user3 = { + id: 'user3', + email: 'user3@zenstack.dev', + name: 'User 3', +}; + +const space1 = { + id: 'space1', + name: 'Space 1', + slug: 'space1', +}; + +const space2 = { + id: 'space2', + name: 'Space 2', + slug: 'space2', +}; + +async function createSpaceAndUsers() { + const userClient = makeClient('/api/data/User'); + // create users + await userClient + .post('/') + .send({ + data: user1, + }) + .expect(201); + await userClient + .post('/') + .send({ + data: user2, + }) + .expect(201); + await userClient + .post('/') + .send({ + data: user3, + }) + .expect(201); + + // add user1 and user2 into space1 + const spaceClientUser1 = makeClient('/api/data/Space', user1.id); + await spaceClientUser1 + .post('/') + .send({ + data: { + ...space1, + members: { + create: [ + { + user: { connect: { id: user1.id } }, + role: 'ADMIN', + }, + { + user: { connect: { id: user2.id } }, + role: 'USER', + }, + ], + }, + }, + }) + .expect(201); + + // add user3 to space2 + const spaceClientUser3 = makeClient('/api/data/Space', user3.id); + await spaceClientUser3 + .post('/') + .send({ + data: { + ...space2, + members: { + create: [ + { + user: { connect: { id: user3.id } }, + role: 'ADMIN', + }, + ], + }, + }, + }) + .expect(201); +} diff --git a/tests/integration/tests/package-lock.template.json b/tests/integration/tests/package-lock.template.json new file mode 100644 index 000000000..ba3a52403 --- /dev/null +++ b/tests/integration/tests/package-lock.template.json @@ -0,0 +1,2043 @@ +{ + "name": "integration-test", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "integration-test", + "version": "1.0.0", + "dependencies": { + "@prisma/client": "^4.4.0", + "@zenstackhq/runtime": "^0.1.18", + "typescript": "^4.8.4", + "zenstack": "^0.1.40" + } + }, + "node_modules/@chevrotain/types": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-9.1.0.tgz", + "integrity": "sha512-3hbCD1CThkv9gnaSIPq0GUXwKni68e0ph6jIHwCvcWiQ4JB2xi8bFxBain0RF04qHUWuDjgnZLj4rLgimuGO+g==" + }, + "node_modules/@chevrotain/utils": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-9.1.0.tgz", + "integrity": "sha512-llLJZ8OAlZrjGlBvamm6Zdo/HmGAcCLq5gx7cSwUX8No+n/8ip+oaC4x33IdZIif8+Rh5dQUIZXmfbSghiOmNQ==" + }, + "node_modules/@next/env": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz", + "integrity": "sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==", + "peer": true + }, + "node_modules/@next/swc-android-arm-eabi": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.3.1.tgz", + "integrity": "sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-android-arm64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.3.1.tgz", + "integrity": "sha512-CmgU2ZNyBP0rkugOOqLnjl3+eRpXBzB/I2sjwcGZ7/Z6RcUJXK5Evz+N0ucOxqE4cZ3gkTeXtSzRrMK2mGYV8Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.1.tgz", + "integrity": "sha512-hT/EBGNcu0ITiuWDYU9ur57Oa4LybD5DOQp4f22T6zLfpoBMfBibPtR8XktXmOyFHrL/6FC2p9ojdLZhWhvBHg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.1.tgz", + "integrity": "sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-freebsd-x64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.3.1.tgz", + "integrity": "sha512-qcuUQkaBZWqzM0F1N4AkAh88lLzzpfE6ImOcI1P6YeyJSsBmpBIV8o70zV+Wxpc26yV9vpzb+e5gCyxNjKJg5Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm-gnueabihf": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.3.1.tgz", + "integrity": "sha512-diL9MSYrEI5nY2wc/h/DBewEDUzr/DqBjIgHJ3RUNtETAOB3spMNHvJk2XKUDjnQuluLmFMloet9tpEqU2TT9w==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.1.tgz", + "integrity": "sha512-o/xB2nztoaC7jnXU3Q36vGgOolJpsGG8ETNjxM1VAPxRwM7FyGCPHOMk1XavG88QZSQf+1r+POBW0tLxQOJ9DQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.1.tgz", + "integrity": "sha512-2WEasRxJzgAmP43glFNhADpe8zB7kJofhEAVNbDJZANp+H4+wq+/cW1CdDi8DqjkShPEA6/ejJw+xnEyDID2jg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.1.tgz", + "integrity": "sha512-JWEaMyvNrXuM3dyy9Pp5cFPuSSvG82+yABqsWugjWlvfmnlnx9HOQZY23bFq3cNghy5V/t0iPb6cffzRWylgsA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.1.tgz", + "integrity": "sha512-xoEWQQ71waWc4BZcOjmatuvPUXKTv6MbIFzpm4LFeCHsg2iwai0ILmNXf81rJR+L1Wb9ifEke2sQpZSPNz1Iyg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.1.tgz", + "integrity": "sha512-hswVFYQYIeGHE2JYaBVtvqmBQ1CppplQbZJS/JgrVI3x2CurNhEkmds/yqvDONfwfbttTtH4+q9Dzf/WVl3Opw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.1.tgz", + "integrity": "sha512-Kny5JBehkTbKPmqulr5i+iKntO5YMP+bVM8Hf8UAmjSMVo3wehyLVc9IZkNmcbxi+vwETnQvJaT5ynYBkJ9dWA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.1.tgz", + "integrity": "sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@prisma/client": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.4.0.tgz", + "integrity": "sha512-ciKOP246x1xwr04G9ajHlJ4pkmtu9Q6esVyqVBO0QJihaKQIUvbPjClp17IsRJyxqNpFm4ScbOc/s9DUzKHINQ==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines-version": "4.4.0-66.f352a33b70356f46311da8b00d83386dd9f145d6" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/engines": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.4.0.tgz", + "integrity": "sha512-Fpykccxlt9MHrAs/QpPGpI2nOiRxuLA+LiApgA59ibbf24YICZIMWd3SI2YD+q0IAIso0jCGiHhirAIbxK3RyQ==", + "hasInstallScript": true + }, + "node_modules/@prisma/engines-version": { + "version": "4.4.0-66.f352a33b70356f46311da8b00d83386dd9f145d6", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.4.0-66.f352a33b70356f46311da8b00d83386dd9f145d6.tgz", + "integrity": "sha512-P5v/PuEIJLYXZUZBvOLPqoyCW+m6StNqHdiR6te++gYVODpPdLakks5HVx3JaZIY+LwR02juJWFlwpc9Eog/ug==" + }, + "node_modules/@swc/helpers": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz", + "integrity": "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==", + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@ts-morph/common": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.17.0.tgz", + "integrity": "sha512-RMSSvSfs9kb0VzkvQ2NWobwnj7TxCA9vI/IjR9bDHqgAyVbu2T0DN4wiKVqomyDWqO7dPr/tErSfq7urQ1Q37g==", + "dependencies": { + "fast-glob": "^3.2.11", + "minimatch": "^5.1.0", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "peer": true + }, + "node_modules/@zenstackhq/internal": { + "version": "0.1.20", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.20.tgz", + "integrity": "sha512-SxPHz0MjIvXc3WzLF1kLZZOIFx8PFZ7Hw6W4u8Nf6JzHxi8X2q6opRJV/jVKhKlmqiRh8EXo8S9vyz9XLiVspA==", + "peer": true, + "dependencies": { + "bcryptjs": "^2.4.3", + "deepcopy": "^2.1.0", + "swr": "^1.3.0" + }, + "peerDependencies": { + "next": "12.3.1", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" + } + }, + "node_modules/@zenstackhq/runtime": { + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.1.18.tgz", + "integrity": "sha512-W6F0wkNb7kOyL8DRGXSEWkzdwUJEQIdWkvjSqh0Itdk+OAY66lDMKhKfbEmmlDxhurkoOJ4YQK6Qxj6UA+AjkQ==", + "peerDependencies": { + "@types/bcryptjs": "^2.4.2", + "@zenstackhq/internal": "^0.1.0", + "bcryptjs": "^2.4.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001420", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001420.tgz", + "integrity": "sha512-OnyeJ9ascFA9roEj72ok2Ikp7PHJTKubtEJIQ/VK3fdsS50q4KWy+Z5X0A1/GswEItKX0ctAp8n4SYDE7wTu6A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ], + "peer": true + }, + "node_modules/capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "dependencies": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/chevrotain": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-9.1.0.tgz", + "integrity": "sha512-A86/55so63HCfu0dgGg3j9u8uuuBOrSqly1OhBZxRu2x6sAKILLzfVjbGMw45kgier6lz45EzcjjWtTRgoT84Q==", + "dependencies": { + "@chevrotain/types": "^9.1.0", + "@chevrotain/utils": "^9.1.0", + "regexp-to-ast": "0.5.0" + } + }, + "node_modules/code-block-writer": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", + "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==" + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "node_modules/constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "node_modules/deepcopy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz", + "integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==", + "dependencies": { + "type-detect": "^4.0.8" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "dependencies": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true + }, + "node_modules/langium": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-0.4.0.tgz", + "integrity": "sha512-VDwbcSdd4Uzektou73gcuqSt1eJcizHWJic7ZGIkTQyBIiRTP66YvMlxLUUE9T9p4/lCZGwf9D8CCBc7RiXZ7A==", + "dependencies": { + "chevrotain": "^9.1.0", + "vscode-languageserver": "^7.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-uri": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "peer": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/next/-/next-12.3.1.tgz", + "integrity": "sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==", + "peer": true, + "dependencies": { + "@next/env": "12.3.1", + "@swc/helpers": "0.4.11", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.14", + "styled-jsx": "5.0.7", + "use-sync-external-store": "1.2.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=12.22.0" + }, + "optionalDependencies": { + "@next/swc-android-arm-eabi": "12.3.1", + "@next/swc-android-arm64": "12.3.1", + "@next/swc-darwin-arm64": "12.3.1", + "@next/swc-darwin-x64": "12.3.1", + "@next/swc-freebsd-x64": "12.3.1", + "@next/swc-linux-arm-gnueabihf": "12.3.1", + "@next/swc-linux-arm64-gnu": "12.3.1", + "@next/swc-linux-arm64-musl": "12.3.1", + "@next/swc-linux-x64-gnu": "12.3.1", + "@next/swc-linux-x64-musl": "12.3.1", + "@next/swc-win32-arm64-msvc": "12.3.1", + "@next/swc-win32-ia32-msvc": "12.3.1", + "@next/swc-win32-x64-msvc": "12.3.1" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^6.0.0 || ^7.0.0", + "react": "^17.0.2 || ^18.0.0-0", + "react-dom": "^17.0.2 || ^18.0.0-0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "node_modules/path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "peer": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "peer": true, + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prisma": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.4.0.tgz", + "integrity": "sha512-l/QKLmLcKJQFuc+X02LyICo0NWTUVaNNZ00jKJBqwDyhwMAhboD1FWwYV50rkH4Wls0RviAJSFzkC2ZrfawpfA==", + "hasInstallScript": true, + "dependencies": { + "@prisma/engines": "4.4.0" + }, + "bin": { + "prisma": "build/index.js", + "prisma2": "build/index.js" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/promisify": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/promisify/-/promisify-0.0.3.tgz", + "integrity": "sha512-CcBGsRhhq466fsZVyHfptuKqon6eih0CqMsJE0kWIIjbpVNEyDoaKLELm2WVs//W/WXRBHip+6xhTExTkHUwtA==", + "dependencies": { + "when": "" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz", + "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==", + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/swr": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz", + "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==", + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-morph": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-16.0.0.tgz", + "integrity": "sha512-jGNF0GVpFj0orFw55LTsQxVYEUOCWBAbR5Ls7fTYE5pQsbW18ssTb/6UXx/GYAEjS+DQTp8VoTw0vqYMiaaQuw==", + "dependencies": { + "@ts-morph/common": "~0.17.0", + "code-block-writer": "^11.0.3" + } + }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz", + "integrity": "sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageclient": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", + "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", + "dependencies": { + "minimatch": "^3.0.4", + "semver": "^7.3.4", + "vscode-languageserver-protocol": "3.16.0" + }, + "engines": { + "vscode": "^1.52.0" + } + }, + "node_modules/vscode-languageclient/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/vscode-languageclient/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/vscode-languageserver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", + "dependencies": { + "vscode-languageserver-protocol": "3.16.0" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", + "dependencies": { + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" + } + }, + "node_modules/vscode-languageserver-protocol/node_modules/vscode-jsonrpc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==", + "engines": { + "node": ">=8.0.0 || >=10.0.0" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.7.tgz", + "integrity": "sha512-bFJH7UQxlXT8kKeyiyu41r22jCZXG8kuuVVA33OEJn1diWOZK5n8zBSPZFHVBOu8kXZ6h0LIRhf5UnCo61J4Hg==" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + }, + "node_modules/vscode-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz", + "integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ==" + }, + "node_modules/when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/zenstack": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.1.40.tgz", + "integrity": "sha512-aemTRc97FJghdcbLsjSmUtRMRHd81mLDibVFA+0FP0jpbcloPNus986bbZCaIj92DqqpCzJYkyelNuNkvMht6Q==", + "dependencies": { + "@zenstackhq/internal": "0.1.19", + "change-case": "^4.1.2", + "chevrotain": "^9.1.0", + "colors": "^1.4.0", + "commander": "^8.0.0", + "langium": "^0.4.0", + "prisma": "^4.4.0", + "promisify": "^0.0.3", + "ts-morph": "^16.0.0", + "vscode-jsonrpc": "^8.0.2", + "vscode-languageclient": "^7.0.0", + "vscode-languageserver": "^7.0.0", + "vscode-uri": "^3.0.2" + }, + "bin": { + "zenstack": "bin/cli" + }, + "engines": { + "vscode": "^1.56.0" + } + }, + "node_modules/zenstack/node_modules/@zenstackhq/internal": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.19.tgz", + "integrity": "sha512-2b4dkGq1NJRUfEoLXprqSDFKHgI2y4vHb+z0iwc/llRqTCHU/BmqneTn+W28ckq4rh6E/eRor5qRobfGLoWUYA==", + "dependencies": { + "bcryptjs": "^2.4.3", + "deepcopy": "^2.1.0", + "swr": "^1.3.0" + }, + "peerDependencies": { + "next": "12.3.1", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" + } + } + }, + "dependencies": { + "@chevrotain/types": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-9.1.0.tgz", + "integrity": "sha512-3hbCD1CThkv9gnaSIPq0GUXwKni68e0ph6jIHwCvcWiQ4JB2xi8bFxBain0RF04qHUWuDjgnZLj4rLgimuGO+g==" + }, + "@chevrotain/utils": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-9.1.0.tgz", + "integrity": "sha512-llLJZ8OAlZrjGlBvamm6Zdo/HmGAcCLq5gx7cSwUX8No+n/8ip+oaC4x33IdZIif8+Rh5dQUIZXmfbSghiOmNQ==" + }, + "@next/env": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz", + "integrity": "sha512-9P9THmRFVKGKt9DYqeC2aKIxm8rlvkK38V1P1sRE7qyoPBIs8l9oo79QoSdPtOWfzkbDAVUqvbQGgTMsb8BtJg==", + "peer": true + }, + "@next/swc-android-arm-eabi": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-12.3.1.tgz", + "integrity": "sha512-i+BvKA8tB//srVPPQxIQN5lvfROcfv4OB23/L1nXznP+N/TyKL8lql3l7oo2LNhnH66zWhfoemg3Q4VJZSruzQ==", + "optional": true, + "peer": true + }, + "@next/swc-android-arm64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.3.1.tgz", + "integrity": "sha512-CmgU2ZNyBP0rkugOOqLnjl3+eRpXBzB/I2sjwcGZ7/Z6RcUJXK5Evz+N0ucOxqE4cZ3gkTeXtSzRrMK2mGYV8Q==", + "optional": true, + "peer": true + }, + "@next/swc-darwin-arm64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.3.1.tgz", + "integrity": "sha512-hT/EBGNcu0ITiuWDYU9ur57Oa4LybD5DOQp4f22T6zLfpoBMfBibPtR8XktXmOyFHrL/6FC2p9ojdLZhWhvBHg==", + "optional": true, + "peer": true + }, + "@next/swc-darwin-x64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.3.1.tgz", + "integrity": "sha512-9S6EVueCVCyGf2vuiLiGEHZCJcPAxglyckTZcEwLdJwozLqN0gtS0Eq0bQlGS3dH49Py/rQYpZ3KVWZ9BUf/WA==", + "optional": true, + "peer": true + }, + "@next/swc-freebsd-x64": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-freebsd-x64/-/swc-freebsd-x64-12.3.1.tgz", + "integrity": "sha512-qcuUQkaBZWqzM0F1N4AkAh88lLzzpfE6ImOcI1P6YeyJSsBmpBIV8o70zV+Wxpc26yV9vpzb+e5gCyxNjKJg5Q==", + "optional": true, + "peer": true + }, + "@next/swc-linux-arm-gnueabihf": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.3.1.tgz", + "integrity": "sha512-diL9MSYrEI5nY2wc/h/DBewEDUzr/DqBjIgHJ3RUNtETAOB3spMNHvJk2XKUDjnQuluLmFMloet9tpEqU2TT9w==", + "optional": true, + "peer": true + }, + "@next/swc-linux-arm64-gnu": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.3.1.tgz", + "integrity": "sha512-o/xB2nztoaC7jnXU3Q36vGgOolJpsGG8ETNjxM1VAPxRwM7FyGCPHOMk1XavG88QZSQf+1r+POBW0tLxQOJ9DQ==", + "optional": true, + "peer": true + }, + "@next/swc-linux-arm64-musl": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.3.1.tgz", + "integrity": "sha512-2WEasRxJzgAmP43glFNhADpe8zB7kJofhEAVNbDJZANp+H4+wq+/cW1CdDi8DqjkShPEA6/ejJw+xnEyDID2jg==", + "optional": true, + "peer": true + }, + "@next/swc-linux-x64-gnu": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.3.1.tgz", + "integrity": "sha512-JWEaMyvNrXuM3dyy9Pp5cFPuSSvG82+yABqsWugjWlvfmnlnx9HOQZY23bFq3cNghy5V/t0iPb6cffzRWylgsA==", + "optional": true, + "peer": true + }, + "@next/swc-linux-x64-musl": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.3.1.tgz", + "integrity": "sha512-xoEWQQ71waWc4BZcOjmatuvPUXKTv6MbIFzpm4LFeCHsg2iwai0ILmNXf81rJR+L1Wb9ifEke2sQpZSPNz1Iyg==", + "optional": true, + "peer": true + }, + "@next/swc-win32-arm64-msvc": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.3.1.tgz", + "integrity": "sha512-hswVFYQYIeGHE2JYaBVtvqmBQ1CppplQbZJS/JgrVI3x2CurNhEkmds/yqvDONfwfbttTtH4+q9Dzf/WVl3Opw==", + "optional": true, + "peer": true + }, + "@next/swc-win32-ia32-msvc": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.3.1.tgz", + "integrity": "sha512-Kny5JBehkTbKPmqulr5i+iKntO5YMP+bVM8Hf8UAmjSMVo3wehyLVc9IZkNmcbxi+vwETnQvJaT5ynYBkJ9dWA==", + "optional": true, + "peer": true + }, + "@next/swc-win32-x64-msvc": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.3.1.tgz", + "integrity": "sha512-W1ijvzzg+kPEX6LAc+50EYYSEo0FVu7dmTE+t+DM4iOLqgGHoW9uYSz9wCVdkXOEEMP9xhXfGpcSxsfDucyPkA==", + "optional": true, + "peer": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@prisma/client": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.4.0.tgz", + "integrity": "sha512-ciKOP246x1xwr04G9ajHlJ4pkmtu9Q6esVyqVBO0QJihaKQIUvbPjClp17IsRJyxqNpFm4ScbOc/s9DUzKHINQ==", + "requires": { + "@prisma/engines-version": "4.4.0-66.f352a33b70356f46311da8b00d83386dd9f145d6" + } + }, + "@prisma/engines": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.4.0.tgz", + "integrity": "sha512-Fpykccxlt9MHrAs/QpPGpI2nOiRxuLA+LiApgA59ibbf24YICZIMWd3SI2YD+q0IAIso0jCGiHhirAIbxK3RyQ==" + }, + "@prisma/engines-version": { + "version": "4.4.0-66.f352a33b70356f46311da8b00d83386dd9f145d6", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.4.0-66.f352a33b70356f46311da8b00d83386dd9f145d6.tgz", + "integrity": "sha512-P5v/PuEIJLYXZUZBvOLPqoyCW+m6StNqHdiR6te++gYVODpPdLakks5HVx3JaZIY+LwR02juJWFlwpc9Eog/ug==" + }, + "@swc/helpers": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz", + "integrity": "sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==", + "peer": true, + "requires": { + "tslib": "^2.4.0" + } + }, + "@ts-morph/common": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.17.0.tgz", + "integrity": "sha512-RMSSvSfs9kb0VzkvQ2NWobwnj7TxCA9vI/IjR9bDHqgAyVbu2T0DN4wiKVqomyDWqO7dPr/tErSfq7urQ1Q37g==", + "requires": { + "fast-glob": "^3.2.11", + "minimatch": "^5.1.0", + "mkdirp": "^1.0.4", + "path-browserify": "^1.0.1" + } + }, + "@types/bcryptjs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz", + "integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ==", + "peer": true + }, + "@zenstackhq/internal": { + "version": "0.1.20", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.20.tgz", + "integrity": "sha512-SxPHz0MjIvXc3WzLF1kLZZOIFx8PFZ7Hw6W4u8Nf6JzHxi8X2q6opRJV/jVKhKlmqiRh8EXo8S9vyz9XLiVspA==", + "peer": true, + "requires": { + "bcryptjs": "^2.4.3", + "deepcopy": "^2.1.0", + "swr": "^1.3.0" + } + }, + "@zenstackhq/runtime": { + "version": "0.1.18", + "resolved": "https://registry.npmjs.org/@zenstackhq/runtime/-/runtime-0.1.18.tgz", + "integrity": "sha512-W6F0wkNb7kOyL8DRGXSEWkzdwUJEQIdWkvjSqh0Itdk+OAY66lDMKhKfbEmmlDxhurkoOJ4YQK6Qxj6UA+AjkQ==", + "requires": {} + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==" + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "requires": { + "balanced-match": "^1.0.0" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "caniuse-lite": { + "version": "1.0.30001420", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001420.tgz", + "integrity": "sha512-OnyeJ9ascFA9roEj72ok2Ikp7PHJTKubtEJIQ/VK3fdsS50q4KWy+Z5X0A1/GswEItKX0ctAp8n4SYDE7wTu6A==", + "peer": true + }, + "capital-case": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", + "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "change-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", + "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", + "requires": { + "camel-case": "^4.1.2", + "capital-case": "^1.0.4", + "constant-case": "^3.0.4", + "dot-case": "^3.0.4", + "header-case": "^2.0.4", + "no-case": "^3.0.4", + "param-case": "^3.0.4", + "pascal-case": "^3.1.2", + "path-case": "^3.0.4", + "sentence-case": "^3.0.4", + "snake-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "chevrotain": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-9.1.0.tgz", + "integrity": "sha512-A86/55so63HCfu0dgGg3j9u8uuuBOrSqly1OhBZxRu2x6sAKILLzfVjbGMw45kgier6lz45EzcjjWtTRgoT84Q==", + "requires": { + "@chevrotain/types": "^9.1.0", + "@chevrotain/utils": "^9.1.0", + "regexp-to-ast": "0.5.0" + } + }, + "code-block-writer": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.3.tgz", + "integrity": "sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "constant-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", + "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case": "^2.0.2" + } + }, + "deepcopy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/deepcopy/-/deepcopy-2.1.0.tgz", + "integrity": "sha512-8cZeTb1ZKC3bdSCP6XOM1IsTczIO73fdqtwa2B0N15eAz7gmyhQo+mc5gnFuulsgN3vIQYmTgbmQVKalH1dKvQ==", + "requires": { + "type-detect": "^4.0.8" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + } + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "header-case": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", + "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", + "requires": { + "capital-case": "^1.0.4", + "tslib": "^2.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "peer": true + }, + "langium": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/langium/-/langium-0.4.0.tgz", + "integrity": "sha512-VDwbcSdd4Uzektou73gcuqSt1eJcizHWJic7ZGIkTQyBIiRTP66YvMlxLUUE9T9p4/lCZGwf9D8CCBc7RiXZ7A==", + "requires": { + "chevrotain": "^9.1.0", + "vscode-languageserver": "^7.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-uri": "^3.0.2" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "peer": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "peer": true + }, + "next": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/next/-/next-12.3.1.tgz", + "integrity": "sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==", + "peer": true, + "requires": { + "@next/env": "12.3.1", + "@next/swc-android-arm-eabi": "12.3.1", + "@next/swc-android-arm64": "12.3.1", + "@next/swc-darwin-arm64": "12.3.1", + "@next/swc-darwin-x64": "12.3.1", + "@next/swc-freebsd-x64": "12.3.1", + "@next/swc-linux-arm-gnueabihf": "12.3.1", + "@next/swc-linux-arm64-gnu": "12.3.1", + "@next/swc-linux-arm64-musl": "12.3.1", + "@next/swc-linux-x64-gnu": "12.3.1", + "@next/swc-linux-x64-musl": "12.3.1", + "@next/swc-win32-arm64-msvc": "12.3.1", + "@next/swc-win32-ia32-msvc": "12.3.1", + "@next/swc-win32-x64-msvc": "12.3.1", + "@swc/helpers": "0.4.11", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.14", + "styled-jsx": "5.0.7", + "use-sync-external-store": "1.2.0" + } + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "path-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", + "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "peer": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "postcss": { + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "peer": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "prisma": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-4.4.0.tgz", + "integrity": "sha512-l/QKLmLcKJQFuc+X02LyICo0NWTUVaNNZ00jKJBqwDyhwMAhboD1FWwYV50rkH4Wls0RviAJSFzkC2ZrfawpfA==", + "requires": { + "@prisma/engines": "4.4.0" + } + }, + "promisify": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/promisify/-/promisify-0.0.3.tgz", + "integrity": "sha512-CcBGsRhhq466fsZVyHfptuKqon6eih0CqMsJE0kWIIjbpVNEyDoaKLELm2WVs//W/WXRBHip+6xhTExTkHUwtA==", + "requires": { + "when": "" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "sentence-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", + "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3", + "upper-case-first": "^2.0.2" + } + }, + "snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "peer": true + }, + "styled-jsx": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz", + "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==", + "peer": true, + "requires": {} + }, + "swr": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz", + "integrity": "sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==", + "requires": {} + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-morph": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-16.0.0.tgz", + "integrity": "sha512-jGNF0GVpFj0orFw55LTsQxVYEUOCWBAbR5Ls7fTYE5pQsbW18ssTb/6UXx/GYAEjS+DQTp8VoTw0vqYMiaaQuw==", + "requires": { + "@ts-morph/common": "~0.17.0", + "code-block-writer": "^11.0.3" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" + }, + "upper-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", + "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "upper-case-first": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", + "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", + "requires": { + "tslib": "^2.0.3" + } + }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peer": true, + "requires": {} + }, + "vscode-jsonrpc": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz", + "integrity": "sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==" + }, + "vscode-languageclient": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz", + "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==", + "requires": { + "minimatch": "^3.0.4", + "semver": "^7.3.4", + "vscode-languageserver-protocol": "3.16.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "vscode-languageserver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz", + "integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==", + "requires": { + "vscode-languageserver-protocol": "3.16.0" + } + }, + "vscode-languageserver-protocol": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz", + "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==", + "requires": { + "vscode-jsonrpc": "6.0.0", + "vscode-languageserver-types": "3.16.0" + }, + "dependencies": { + "vscode-jsonrpc": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz", + "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==" + } + } + }, + "vscode-languageserver-textdocument": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.7.tgz", + "integrity": "sha512-bFJH7UQxlXT8kKeyiyu41r22jCZXG8kuuVVA33OEJn1diWOZK5n8zBSPZFHVBOu8kXZ6h0LIRhf5UnCo61J4Hg==" + }, + "vscode-languageserver-types": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz", + "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==" + }, + "vscode-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.6.tgz", + "integrity": "sha512-fmL7V1eiDBFRRnu+gfRWTzyPpNIHJTc4mWnFkwBUmO9U3KPgJAmTx7oxi2bl/Rh6HLdU7+4C9wlj0k2E4AdKFQ==" + }, + "when": { + "version": "3.7.8", + "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", + "integrity": "sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "zenstack": { + "version": "0.1.40", + "resolved": "https://registry.npmjs.org/zenstack/-/zenstack-0.1.40.tgz", + "integrity": "sha512-aemTRc97FJghdcbLsjSmUtRMRHd81mLDibVFA+0FP0jpbcloPNus986bbZCaIj92DqqpCzJYkyelNuNkvMht6Q==", + "requires": { + "@zenstackhq/internal": "0.1.19", + "change-case": "^4.1.2", + "chevrotain": "^9.1.0", + "colors": "^1.4.0", + "commander": "^8.0.0", + "langium": "^0.4.0", + "prisma": "^4.4.0", + "promisify": "^0.0.3", + "ts-morph": "^16.0.0", + "vscode-jsonrpc": "^8.0.2", + "vscode-languageclient": "^7.0.0", + "vscode-languageserver": "^7.0.0", + "vscode-uri": "^3.0.2" + }, + "dependencies": { + "@zenstackhq/internal": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@zenstackhq/internal/-/internal-0.1.19.tgz", + "integrity": "sha512-2b4dkGq1NJRUfEoLXprqSDFKHgI2y4vHb+z0iwc/llRqTCHU/BmqneTn+W28ckq4rh6E/eRor5qRobfGLoWUYA==", + "requires": { + "bcryptjs": "^2.4.3", + "deepcopy": "^2.1.0", + "swr": "^1.3.0" + } + } + } + } + } +} diff --git a/tests/integration/tests/package.template.json b/tests/integration/tests/package.template.json new file mode 100644 index 000000000..c264c34f0 --- /dev/null +++ b/tests/integration/tests/package.template.json @@ -0,0 +1,10 @@ +{ + "name": "integration-test", + "version": "1.0.0", + "dependencies": { + "@prisma/client": "^4.4.0", + "@zenstackhq/runtime": "^0.1.18", + "typescript": "^4.8.4", + "zenstack": "^0.1.40" + } +} diff --git a/tests/integration/tests/todo.zmodel b/tests/integration/tests/todo.zmodel new file mode 100644 index 000000000..eb52399e4 --- /dev/null +++ b/tests/integration/tests/todo.zmodel @@ -0,0 +1,116 @@ +/* +* Sample model for a collaborative Todo app +*/ + +datasource db { + provider = 'sqlite' + url = 'file:./test.db' +} + +model Space { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + name String @length(1, 100) + slug String @unique @length(1, 20) + members SpaceUser[] + lists List[] + + // require login + @@deny('all', auth() == null) + + // everyone can create a space + @@allow('create', true) + + // any user in the space can read the space + @@allow('read', members?[user == auth()]) + + // space admin can update and delete + @@allow('update,delete', members?[user == auth() && role == "ADMIN"]) +} + +model SpaceUser { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + 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 + @@deny('all', auth() == null) + + // space admin can create/update/delete + @@allow('create,update,delete', space.members?[user == auth() && role == "ADMIN"]) + + // user can read entries for spaces which he's a member of + @@allow('read', space.members?[user == auth()]) +} + +model User { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + email String @unique @email + emailVerified DateTime? + password String? + name String? @length(1, 100) + spaces SpaceUser[] + image String? @url + lists List[] + todos Todo[] + + // can be created by anyone, even not logged in + @@allow('create', true) + + // can be read by users sharing any space + @@allow('read', auth() == this || spaces?[space.members?[user == auth()]]) + + // can only be updated and deleted by himeself + @@allow('update,delete', auth() == this) +} + +model List { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) + spaceId String + owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) + ownerId String + title String @length(1, 20) + private Boolean @default(false) + todos Todo[] + + // require login + @@deny('all', auth() == null) + + // can be read by owner or space members (only if not private) + @@allow('read', owner == auth() || (space.members?[user == auth()] && !private)) + + // can be updated/deleted by owner with a valid space + @@allow('create,update,delete', owner == auth() && space.members?[user == auth()]) +} + +model Todo { + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade) + ownerId String + list List @relation(fields: [listId], references: [id], onDelete: Cascade) + listId String + title String + completedAt DateTime? + + // require login + @@deny('all', auth() == null) + + // owner has full access, also space members have full access (if the parent List is not private) + @@allow('all', list.owner == auth()) + @@allow('all', list.space.members?[user == auth()] && !list.private) +} diff --git a/tests/integration/tests/tsconfig.template.json b/tests/integration/tests/tsconfig.template.json new file mode 100644 index 000000000..18a6bedec --- /dev/null +++ b/tests/integration/tests/tsconfig.template.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + } +} diff --git a/tests/integration/tests/utils.ts b/tests/integration/tests/utils.ts new file mode 100644 index 000000000..97fe3df01 --- /dev/null +++ b/tests/integration/tests/utils.ts @@ -0,0 +1,130 @@ +import * as tmp from 'tmp'; +import { execSync } from 'child_process'; +import * as path from 'path'; +import * as fs from 'fs'; +import { createServer } from 'http'; +import { apiResolver } from 'next/dist/server/api-utils/node'; +import request from 'supertest'; +import { NextApiHandler } from 'next/types'; +import supertest from 'supertest'; + +export function run(cmd: string) { + execSync(cmd, { stdio: 'inherit', encoding: 'utf-8' }); +} + +export async function setup() { + const origDir = path.resolve('.'); + + const { name: workDir } = tmp.dirSync(); + console.log('Work dir:', workDir); + process.chdir(workDir); + + // const workDir = '/tmp/zen'; + // if (fs.existsSync(workDir)) { + // fs.rmSync(workDir, { recursive: true, force: true }); + // } + // fs.mkdirSync(workDir); + // process.chdir(workDir); + + const targetSchema = path.join(workDir, 'schema.zmodel'); + fs.copyFileSync(path.join(origDir, './tests/todo.zmodel'), targetSchema); + + fs.writeFileSync('.npmrc', `cache=${origDir}/.npmcache`); + fs.copyFileSync( + path.join(origDir, 'tests/package.template.json'), + path.join(workDir, 'package.json') + ); + fs.copyFileSync( + path.join(origDir, 'tests/package-lock.template.json'), + path.join(workDir, 'package-lock.json') + ); + + run('npm i typescript zenstack @zenstackhq/runtime'); + run(`npx zenstack generate ./schema.zmodel`); + run(`npx prisma migrate dev --schema ./zenstack/schema.prisma -n init`); + + fs.writeFileSync( + 'handler.ts', + ` + import { NextApiRequest, NextApiResponse } from 'next'; + import { type RequestHandlerOptions, requestHandler } from '@zenstackhq/runtime/server'; + import service from '@zenstackhq/runtime'; + + const options: RequestHandlerOptions = { + async getServerUser(req: NextApiRequest, res: NextApiResponse) { + if (req.cookies.userId) { + return { id: req.cookies.userId }; + } else { + return undefined; + } + }, + }; + export default requestHandler(service, options); + ` + ); + + fs.copyFileSync( + path.join(origDir, 'tests/tsconfig.template.json'), + path.join(workDir, 'tsconfig.json') + ); + run('npx tsc'); + + return workDir; +} + +export function makeClient(apiPath: string, userId?: string) { + const [api, ...pathParts] = apiPath.split('/').filter((p) => p); + if (api !== 'api') { + throw new Error('apiPath must start with /api'); + } + const query = { path: pathParts }; + const testClient = (handler: NextApiHandler) => + request( + createServer(async (req, res) => { + return apiResolver( + req, + res, + query, + handler, + { + previewModeEncryptionKey: '', + previewModeId: '', + previewModeSigningKey: '', + }, + false + ); + }) + ); + const handler = require(path.resolve('handler.js')); + const client = testClient(handler); + + const proxied = new Proxy(client, { + get( + target: supertest.SuperTest, + prop: string | symbol, + receiver: any + ) { + if (!userId) { + return Reflect.get(target, prop, receiver); + } + + switch (prop) { + case 'get': + case 'post': + case 'put': + case 'del': + case 'delete': + return (url: string) => { + // debugger; + return target[prop](url).set('Cookie', [ + `userId=${userId}`, + ]); + }; + default: + return Reflect.get(target, prop, receiver); + } + }, + }); + + return proxied; +} diff --git a/tests/integration/tsconfig.json b/tests/integration/tsconfig.json new file mode 100644 index 000000000..18a6bedec --- /dev/null +++ b/tests/integration/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es2016", + "module": "commonjs", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + } +}