Assign user to workspace on signin
This commit is contained in:
@ -30,5 +30,8 @@ export const refreshAccessToken = async () => {
|
|||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const { accessToken } = await response.json();
|
const { accessToken } = await response.json();
|
||||||
localStorage.setItem('accessToken', accessToken);
|
localStorage.setItem('accessToken', accessToken);
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem('refreshToken');
|
||||||
|
localStorage.removeItem('accessToken');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -120,3 +120,24 @@ array_relationships:
|
|||||||
table:
|
table:
|
||||||
name: user_providers
|
name: user_providers
|
||||||
schema: auth
|
schema: auth
|
||||||
|
- name: workspace_member
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: user_id
|
||||||
|
table:
|
||||||
|
name: workspace_members
|
||||||
|
schema: public
|
||||||
|
event_triggers:
|
||||||
|
- name: user-created
|
||||||
|
definition:
|
||||||
|
enable_manual: false
|
||||||
|
insert:
|
||||||
|
columns: '*'
|
||||||
|
retry_conf:
|
||||||
|
interval_sec: 10
|
||||||
|
num_retries: 0
|
||||||
|
timeout_sec: 60
|
||||||
|
webhook: '{{HASURA_EVENT_HANDLER_URL}}'
|
||||||
|
headers:
|
||||||
|
- name: secret-header
|
||||||
|
value: secret
|
||||||
|
|||||||
@ -0,0 +1,3 @@
|
|||||||
|
table:
|
||||||
|
name: workspace_members
|
||||||
|
schema: public
|
||||||
@ -8,4 +8,5 @@
|
|||||||
- "!include auth_users.yaml"
|
- "!include auth_users.yaml"
|
||||||
- "!include public_companies.yaml"
|
- "!include public_companies.yaml"
|
||||||
- "!include public_people.yaml"
|
- "!include public_people.yaml"
|
||||||
|
- "!include public_workspace_members.yaml"
|
||||||
- "!include public_workspaces.yaml"
|
- "!include public_workspaces.yaml"
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
DROP TABLE "public"."workspace_members";
|
||||||
@ -0,0 +1 @@
|
|||||||
|
CREATE TABLE "public"."workspace_members" ("id" serial NOT NULL, "user_id" uuid NOT NULL, "workspace_id" integer NOT NULL, PRIMARY KEY ("id") , FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON UPDATE restrict ON DELETE restrict, FOREIGN KEY ("workspace_id") REFERENCES "public"."workspaces"("id") ON UPDATE restrict ON DELETE restrict, UNIQUE ("id"), UNIQUE ("user_id"));
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."workspace_members" add column "created_at" timestamptz
|
||||||
|
-- not null default now();
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."workspace_members" add column "created_at" timestamptz
|
||||||
|
not null default now();
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."workspace_members" add column "updated_at" timestamptz
|
||||||
|
-- not null default now();
|
||||||
|
--
|
||||||
|
-- CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||||
|
-- RETURNS TRIGGER AS $$
|
||||||
|
-- DECLARE
|
||||||
|
-- _new record;
|
||||||
|
-- BEGIN
|
||||||
|
-- _new := NEW;
|
||||||
|
-- _new."updated_at" = NOW();
|
||||||
|
-- RETURN _new;
|
||||||
|
-- END;
|
||||||
|
-- $$ LANGUAGE plpgsql;
|
||||||
|
-- CREATE TRIGGER "set_public_workspace_members_updated_at"
|
||||||
|
-- BEFORE UPDATE ON "public"."workspace_members"
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||||
|
-- COMMENT ON TRIGGER "set_public_workspace_members_updated_at" ON "public"."workspace_members"
|
||||||
|
-- IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
alter table "public"."workspace_members" add column "updated_at" timestamptz
|
||||||
|
not null default now();
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_updated_at"()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
DECLARE
|
||||||
|
_new record;
|
||||||
|
BEGIN
|
||||||
|
_new := NEW;
|
||||||
|
_new."updated_at" = NOW();
|
||||||
|
RETURN _new;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER "set_public_workspace_members_updated_at"
|
||||||
|
BEFORE UPDATE ON "public"."workspace_members"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE "public"."set_current_timestamp_updated_at"();
|
||||||
|
COMMENT ON TRIGGER "set_public_workspace_members_updated_at" ON "public"."workspace_members"
|
||||||
|
IS 'trigger to set value of column "updated_at" to current timestamp on row update';
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."workspace_members" add column "deleted_at" timestamptz
|
||||||
|
-- null;
|
||||||
|
--
|
||||||
|
-- CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_deleted_at"()
|
||||||
|
-- RETURNS TRIGGER AS $$
|
||||||
|
-- DECLARE
|
||||||
|
-- _new record;
|
||||||
|
-- BEGIN
|
||||||
|
-- _new := NEW;
|
||||||
|
-- _new."deleted_at" = NOW();
|
||||||
|
-- RETURN _new;
|
||||||
|
-- END;
|
||||||
|
-- $$ LANGUAGE plpgsql;
|
||||||
|
-- CREATE TRIGGER "set_public_workspace_members_deleted_at"
|
||||||
|
-- BEFORE UPDATE ON "public"."workspace_members"
|
||||||
|
-- FOR EACH ROW
|
||||||
|
-- EXECUTE PROCEDURE "public"."set_current_timestamp_deleted_at"();
|
||||||
|
-- COMMENT ON TRIGGER "set_public_workspace_members_deleted_at" ON "public"."workspace_members"
|
||||||
|
-- IS 'trigger to set value of column "deleted_at" to current timestamp on row update';
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
alter table "public"."workspace_members" add column "deleted_at" timestamptz
|
||||||
|
null;
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION "public"."set_current_timestamp_deleted_at"()
|
||||||
|
RETURNS TRIGGER AS $$
|
||||||
|
DECLARE
|
||||||
|
_new record;
|
||||||
|
BEGIN
|
||||||
|
_new := NEW;
|
||||||
|
_new."deleted_at" = NOW();
|
||||||
|
RETURN _new;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
CREATE TRIGGER "set_public_workspace_members_deleted_at"
|
||||||
|
BEFORE UPDATE ON "public"."workspace_members"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE PROCEDURE "public"."set_current_timestamp_deleted_at"();
|
||||||
|
COMMENT ON TRIGGER "set_public_workspace_members_deleted_at" ON "public"."workspace_members"
|
||||||
|
IS 'trigger to set value of column "deleted_at" to current timestamp on row update';
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."workspaces" add column "domain_name" text
|
||||||
|
-- null unique;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."workspaces" add column "domain_name" text
|
||||||
|
null unique;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
alter table "public"."workspaces" add constraint "workspaces_domain_name_key" unique (domain_name);
|
||||||
|
alter table "public"."workspaces" alter column "domain_name" drop not null;
|
||||||
|
alter table "public"."workspaces" add column "domain_name" text;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
alter table "public"."workspaces" drop column "domain_name" cascade;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
alter table "public"."workspaces" rename column "domain_name" to "name";
|
||||||
@ -0,0 +1 @@
|
|||||||
|
alter table "public"."workspaces" rename column "name" to "domain_name";
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."workspaces" add column "deleted_at" Timestamp
|
||||||
|
-- null;
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."workspaces" add column "deleted_at" Timestamp
|
||||||
|
null;
|
||||||
@ -1,6 +1,20 @@
|
|||||||
|
HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/hasura
|
||||||
|
HASURA_GRAPHQL_PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/default
|
||||||
|
HASURA_GRAPHQL_ADMIN_SECRET: secret
|
||||||
|
HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256", "key": "jwt-very-long-hard-to-guess-secret"}'
|
||||||
|
HASURA_EVENT_HANDLER_URL: http://twenty-server:3000/hasura/events
|
||||||
|
|
||||||
HASURA_AUTH_SERVER_URL: http://localhost:4000
|
HASURA_AUTH_SERVER_URL: http://localhost:4000
|
||||||
HASURA_AUTH_CLIENT_URL: http://localhost:3001/auth/callback
|
HASURA_AUTH_CLIENT_URL: http://localhost:3001/auth/callback
|
||||||
HASURA_AUTH_PROVIDER_GOOGLE_CLIENT_ID: REPLACE_ME
|
HASURA_AUTH_PROVIDER_GOOGLE_CLIENT_ID: REPLACE_ME
|
||||||
HASURA_AUTH_PROVIDER_GOOGLE_CLIENT_SECRET: REPLACE_ME
|
HASURA_AUTH_PROVIDER_GOOGLE_CLIENT_SECRET: REPLACE_ME
|
||||||
|
HASURA_AUTH_GRAPHQL_URL: http://twenty-hasura:8080/v1/graphql
|
||||||
|
|
||||||
FRONT_REACT_APP_API_URL=http://localhost:8080
|
FRONT_REACT_APP_API_URL=http://localhost:8080
|
||||||
FRONT_REACT_APP_AUTH_URL=http://localhost:4000
|
FRONT_REACT_APP_AUTH_URL=http://localhost:4000
|
||||||
|
|
||||||
|
SERVER_HASURA_EVENT_HANDLER_SECRET_HEADER: secret
|
||||||
|
SERVER_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/default
|
||||||
|
SERVER_HASURA_EVENT_HANDLER_SECRET_HEADER: secret
|
||||||
|
|
||||||
|
POSTGRES_PASSWORD=postgrespassword
|
||||||
@ -28,22 +28,24 @@ services:
|
|||||||
- "postgres"
|
- "postgres"
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/hasura
|
HASURA_GRAPHQL_METADATA_DATABASE_URL: ${HASURA_GRAPHQL_METADATA_DATABASE_URL}
|
||||||
HASURA_GRAPHQL_PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/default
|
HASURA_GRAPHQL_PG_DATABASE_URL: ${HASURA_GRAPHQL_PG_DATABASE_URL}
|
||||||
HASURA_GRAPHQL_ENABLE_CONSOLE: "false"
|
HASURA_GRAPHQL_ENABLE_CONSOLE: "false"
|
||||||
HASURA_GRAPHQL_DEV_MODE: "true"
|
HASURA_GRAPHQL_DEV_MODE: "true"
|
||||||
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
|
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
|
||||||
HASURA_GRAPHQL_ADMIN_SECRET: secret
|
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
|
||||||
HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256", "key": "jwt-very-long-hard-to-guess-secret"}'
|
HASURA_GRAPHQL_JWT_SECRET: ${HASURA_GRAPHQL_JWT_SECRET}
|
||||||
|
HASURA_EVENT_HANDLER_URL: ${HASURA_EVENT_HANDLER_URL}
|
||||||
hasura-auth:
|
hasura-auth:
|
||||||
image: nhost/hasura-auth:0.19.1
|
image: nhost/hasura-auth:0.19.1
|
||||||
ports:
|
ports:
|
||||||
- "4000:4000"
|
- "4000:4000"
|
||||||
environment:
|
environment:
|
||||||
HASURA_GRAPHQL_JWT_SECRET: '{"type":"HS256", "key": "jwt-very-long-hard-to-guess-secret"}'
|
HASURA_GRAPHQL_JWT_SECRET: ${HASURA_GRAPHQL_JWT_SECRET}
|
||||||
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/default
|
HASURA_GRAPHQL_DATABASE_URL: ${HASURA_GRAPHQL_PG_DATABASE_URL}
|
||||||
HASURA_GRAPHQL_GRAPHQL_URL: http://twenty-hasura:8080/v1/graphql
|
HASURA_GRAPHQL_GRAPHQL_URL: ${HASURA_AUTH_GRAPHQL_URL}
|
||||||
HASURA_GRAPHQL_ADMIN_SECRET: secret
|
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
|
||||||
|
AUTH_JWT_CUSTOM_CLAIMS: '{"workspace-id":"workspace_member.workspace_id"}'
|
||||||
npm_package_version: '0'
|
npm_package_version: '0'
|
||||||
AUTH_SMTP_HOST: mailhog
|
AUTH_SMTP_HOST: mailhog
|
||||||
AUTH_SMTP_PORT: 1025
|
AUTH_SMTP_PORT: 1025
|
||||||
@ -78,6 +80,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ../../server:/app/server
|
- ../../server:/app/server
|
||||||
- twenty_node_modules_server:/app/server/node_modules
|
- twenty_node_modules_server:/app/server/node_modules
|
||||||
|
environment:
|
||||||
|
HASURA_EVENT_HANDLER_SECRET_HEADER: ${SERVER_HASURA_EVENT_HANDLER_SECRET_HEADER}
|
||||||
|
SERVER_DATABASE_URL: ${SERVER_DATABASE_URL}
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
postgres:
|
postgres:
|
||||||
@ -85,7 +90,7 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- db_data:/var/lib/postgresql/data
|
- db_data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_PASSWORD: postgrespassword
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||||
ports:
|
ports:
|
||||||
- "5432:5432"
|
- "5432:5432"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@ -13,4 +13,4 @@ RUN npm install
|
|||||||
COPY ../../server .
|
COPY ../../server .
|
||||||
|
|
||||||
|
|
||||||
CMD ["npm", "run", "start"]
|
CMD ["npm", "run", "start:dev"]
|
||||||
217
server/package-lock.json
generated
217
server/package-lock.json
generated
@ -9,11 +9,13 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@golevelup/nestjs-hasura": "^3.0.2",
|
||||||
"@nestjs/common": "^9.0.0",
|
"@nestjs/common": "^9.0.0",
|
||||||
"@nestjs/core": "^9.0.0",
|
"@nestjs/core": "^9.0.0",
|
||||||
"@nestjs/platform-express": "^9.0.0",
|
"@nestjs/platform-express": "^9.0.0",
|
||||||
"@nestjs/serve-static": "^3.0.0",
|
"@nestjs/serve-static": "^3.0.0",
|
||||||
"@nestjs/terminus": "^9.2.2",
|
"@nestjs/terminus": "^9.2.2",
|
||||||
|
"@prisma/client": "^4.13.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^7.2.0"
|
"rxjs": "^7.2.0"
|
||||||
@ -33,6 +35,7 @@
|
|||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"jest": "28.1.3",
|
"jest": "28.1.3",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
|
"prisma": "^4.13.0",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
"supertest": "^6.1.3",
|
"supertest": "^6.1.3",
|
||||||
"ts-jest": "28.0.8",
|
"ts-jest": "28.0.8",
|
||||||
@ -853,6 +856,52 @@
|
|||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@golevelup/nestjs-common": {
|
||||||
|
"version": "1.4.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz",
|
||||||
|
"integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"nanoid": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@golevelup/nestjs-discovery": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@golevelup/nestjs-hasura": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-hasura/-/nestjs-hasura-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-xvRVIy8XBbxB0m2nVuwrYHLpy4QgDNZRXLKAseYHOQAlGha8Q1G5PZA656uY4XsXrz0Bl284RPBCXwWuPzcE1Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"@golevelup/nestjs-common": "^1.4.4",
|
||||||
|
"@golevelup/nestjs-discovery": "^3.0.0",
|
||||||
|
"@golevelup/nestjs-modules": "^0.6.1",
|
||||||
|
"@hasura/metadata": "^1.0.2",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"zod": "^3.3.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@golevelup/nestjs-modules": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==",
|
||||||
|
"dependencies": {
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^9.x",
|
||||||
|
"rxjs": "^7.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@hasura/metadata": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hasura/metadata/-/metadata-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-bVDwRWC7g/NfLVUwP8HBV07+37g07UAbF+XEujfRmgr8839sH7Q2iwa2M8oQFQXwg4dj5Sn+WRt4/UWXKN7naQ=="
|
||||||
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.7",
|
"version": "0.11.7",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
||||||
@ -1882,6 +1931,38 @@
|
|||||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@prisma/client": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-YaiiICcRB2hatxsbnfB66uWXjcRw3jsZdlAVxmx0cFcTc/Ad/sKdHCcWSnqyDX47vAewkjRFwiLwrOUjswVvmA==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/engines-version": "4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"prisma": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"prisma": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/engines": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-HrniowHRZXHuGT9XRgoXEaP2gJLXM5RMoItaY2PkjvuZ+iHc0Zjbm/302MB8YsPdWozAPHHn+jpFEcEn71OgPw==",
|
||||||
|
"devOptional": true,
|
||||||
|
"hasInstallScript": true
|
||||||
|
},
|
||||||
|
"node_modules/@prisma/engines-version": {
|
||||||
|
"version": "4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a.tgz",
|
||||||
|
"integrity": "sha512-fsQlbkhPJf08JOzKoyoD9atdUijuGBekwoOPZC3YOygXEml1MTtgXVpnUNchQlRSY82OQ6pSGQ9PxUe4arcSLQ=="
|
||||||
|
},
|
||||||
"node_modules/@sinclair/typebox": {
|
"node_modules/@sinclair/typebox": {
|
||||||
"version": "0.24.51",
|
"version": "0.24.51",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
||||||
@ -2708,8 +2789,7 @@
|
|||||||
"node_modules/argparse": {
|
"node_modules/argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/array-flatten": {
|
"node_modules/array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@ -5918,7 +5998,6 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argparse": "^2.0.1"
|
"argparse": "^2.0.1"
|
||||||
},
|
},
|
||||||
@ -6050,8 +6129,7 @@
|
|||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash.memoize": {
|
"node_modules/lodash.memoize": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
@ -6331,6 +6409,23 @@
|
|||||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/nanoid": {
|
||||||
|
"version": "3.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||||
|
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/ai"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"nanoid": "bin/nanoid.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/natural-compare": {
|
"node_modules/natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@ -6849,6 +6944,23 @@
|
|||||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prisma": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prisma/-/prisma-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-L9mqjnSmvWIRCYJ9mQkwCtj4+JDYYTdhoyo8hlsHNDXaZLh/b4hR0IoKIBbTKxZuyHQzLopb/+0Rvb69uGV7uA==",
|
||||||
|
"devOptional": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@prisma/engines": "4.13.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"prisma": "build/index.js",
|
||||||
|
"prisma2": "build/index.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
@ -8540,6 +8652,14 @@
|
|||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/zod": {
|
||||||
|
"version": "3.21.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
|
||||||
|
"integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/colinhacks"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -9166,6 +9286,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@golevelup/nestjs-common": {
|
||||||
|
"version": "1.4.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-common/-/nestjs-common-1.4.4.tgz",
|
||||||
|
"integrity": "sha512-NTjtOhHTMuGwiR3lmBQKKaRr++mHQEsh8AxtaH+/EWOYKMK2Cv/8duaH9MQ0hI3TwnouyaA5IRxYR1ZCUyNXOQ==",
|
||||||
|
"requires": {
|
||||||
|
"nanoid": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@golevelup/nestjs-discovery": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-discovery/-/nestjs-discovery-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZvkXtobTKxXB1LJanP/l6Z/Fing88IMBr3uabQpU2IWjfsstjh02qYDSU2cfD6CSmNldX5ewW5Pd+SdK2lU8Sw==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@golevelup/nestjs-hasura": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-hasura/-/nestjs-hasura-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-xvRVIy8XBbxB0m2nVuwrYHLpy4QgDNZRXLKAseYHOQAlGha8Q1G5PZA656uY4XsXrz0Bl284RPBCXwWuPzcE1Q==",
|
||||||
|
"requires": {
|
||||||
|
"@golevelup/nestjs-common": "^1.4.4",
|
||||||
|
"@golevelup/nestjs-discovery": "^3.0.0",
|
||||||
|
"@golevelup/nestjs-modules": "^0.6.1",
|
||||||
|
"@hasura/metadata": "^1.0.2",
|
||||||
|
"js-yaml": "^4.1.0",
|
||||||
|
"zod": "^3.3.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@golevelup/nestjs-modules": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@golevelup/nestjs-modules/-/nestjs-modules-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-E0STg8In8fhIivnGDJAA70+XLPHzK5bMTkCnif9FbZ8waTYDQ3T/QQL0h73k+CUFeznn1hmuEW14sNaE+8cd7w==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@hasura/metadata": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@hasura/metadata/-/metadata-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-bVDwRWC7g/NfLVUwP8HBV07+37g07UAbF+XEujfRmgr8839sH7Q2iwa2M8oQFQXwg4dj5Sn+WRt4/UWXKN7naQ=="
|
||||||
|
},
|
||||||
"@humanwhocodes/config-array": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.11.7",
|
"version": "0.11.7",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
||||||
@ -9878,6 +10040,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@prisma/client": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-YaiiICcRB2hatxsbnfB66uWXjcRw3jsZdlAVxmx0cFcTc/Ad/sKdHCcWSnqyDX47vAewkjRFwiLwrOUjswVvmA==",
|
||||||
|
"requires": {
|
||||||
|
"@prisma/engines-version": "4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@prisma/engines": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-HrniowHRZXHuGT9XRgoXEaP2gJLXM5RMoItaY2PkjvuZ+iHc0Zjbm/302MB8YsPdWozAPHHn+jpFEcEn71OgPw==",
|
||||||
|
"devOptional": true
|
||||||
|
},
|
||||||
|
"@prisma/engines-version": {
|
||||||
|
"version": "4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a",
|
||||||
|
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a.tgz",
|
||||||
|
"integrity": "sha512-fsQlbkhPJf08JOzKoyoD9atdUijuGBekwoOPZC3YOygXEml1MTtgXVpnUNchQlRSY82OQ6pSGQ9PxUe4arcSLQ=="
|
||||||
|
},
|
||||||
"@sinclair/typebox": {
|
"@sinclair/typebox": {
|
||||||
"version": "0.24.51",
|
"version": "0.24.51",
|
||||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
|
||||||
@ -10562,8 +10743,7 @@
|
|||||||
"argparse": {
|
"argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"array-flatten": {
|
"array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@ -12953,7 +13133,6 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^2.0.1"
|
"argparse": "^2.0.1"
|
||||||
}
|
}
|
||||||
@ -13050,8 +13229,7 @@
|
|||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"lodash.memoize": {
|
"lodash.memoize": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
@ -13260,6 +13438,11 @@
|
|||||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"nanoid": {
|
||||||
|
"version": "3.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||||
|
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
|
||||||
|
},
|
||||||
"natural-compare": {
|
"natural-compare": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||||
@ -13629,6 +13812,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prisma": {
|
||||||
|
"version": "4.13.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/prisma/-/prisma-4.13.0.tgz",
|
||||||
|
"integrity": "sha512-L9mqjnSmvWIRCYJ9mQkwCtj4+JDYYTdhoyo8hlsHNDXaZLh/b4hR0IoKIBbTKxZuyHQzLopb/+0Rvb69uGV7uA==",
|
||||||
|
"devOptional": true,
|
||||||
|
"requires": {
|
||||||
|
"@prisma/engines": "4.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"process-nextick-args": {
|
"process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
@ -14836,6 +15028,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"zod": {
|
||||||
|
"version": "3.21.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
|
||||||
|
"integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,11 +21,13 @@
|
|||||||
"test:e2e": "jest --config ./test/jest-e2e.json"
|
"test:e2e": "jest --config ./test/jest-e2e.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@golevelup/nestjs-hasura": "^3.0.2",
|
||||||
"@nestjs/common": "^9.0.0",
|
"@nestjs/common": "^9.0.0",
|
||||||
"@nestjs/core": "^9.0.0",
|
"@nestjs/core": "^9.0.0",
|
||||||
"@nestjs/platform-express": "^9.0.0",
|
"@nestjs/platform-express": "^9.0.0",
|
||||||
"@nestjs/serve-static": "^3.0.0",
|
"@nestjs/serve-static": "^3.0.0",
|
||||||
"@nestjs/terminus": "^9.2.2",
|
"@nestjs/terminus": "^9.2.2",
|
||||||
|
"@prisma/client": "^4.13.0",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"rxjs": "^7.2.0"
|
"rxjs": "^7.2.0"
|
||||||
@ -45,6 +47,7 @@
|
|||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"jest": "28.1.3",
|
"jest": "28.1.3",
|
||||||
"prettier": "^2.3.2",
|
"prettier": "^2.3.2",
|
||||||
|
"prisma": "^4.13.0",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
"supertest": "^6.1.3",
|
"supertest": "^6.1.3",
|
||||||
"ts-jest": "28.0.8",
|
"ts-jest": "28.0.8",
|
||||||
@ -69,5 +72,8 @@
|
|||||||
],
|
],
|
||||||
"coverageDirectory": "../coverage",
|
"coverageDirectory": "../coverage",
|
||||||
"testEnvironment": "node"
|
"testEnvironment": "node"
|
||||||
|
},
|
||||||
|
"prisma": {
|
||||||
|
"schema": "src/database/schema.prisma"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,10 +13,4 @@ describe('AppController', () => {
|
|||||||
|
|
||||||
appController = app.get<AppController>(AppController);
|
appController = app.get<AppController>(AppController);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('root', () => {
|
|
||||||
it('should return "Hello World!"', () => {
|
|
||||||
expect(appController.health()).toBe('Healthy!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,9 +4,4 @@ import { AppService } from './app.service';
|
|||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(private readonly appService: AppService) {}
|
constructor(private readonly appService: AppService) {}
|
||||||
|
|
||||||
@Get('/health')
|
|
||||||
health(): string {
|
|
||||||
return this.appService.health();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,20 @@ import { AppController } from './app.controller';
|
|||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { HealthController } from './health.controller';
|
import { HealthController } from './health.controller';
|
||||||
import { TerminusModule } from '@nestjs/terminus';
|
import { TerminusModule } from '@nestjs/terminus';
|
||||||
|
import { HasuraModule } from '@golevelup/nestjs-hasura';
|
||||||
|
import { UserService } from './user/user.service';
|
||||||
|
import { UserModule } from './user/user.module';
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [TerminusModule],
|
imports: [UserModule, TerminusModule, HasuraModule.forRoot(HasuraModule, {
|
||||||
|
webhookConfig: {
|
||||||
|
secretFactory: process.env.HASURA_EVENT_HANDLER_SECRET_HEADER,
|
||||||
|
secretHeader: 'secret-header',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
],
|
||||||
controllers: [AppController, HealthController],
|
controllers: [AppController, HealthController],
|
||||||
providers: [AppService],
|
providers: [AppService, UserService],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
8
server/src/database/prisma.module.ts
Normal file
8
server/src/database/prisma.module.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { PrismaService } from './prisma.service';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
providers: [PrismaService],
|
||||||
|
exports: [PrismaService],
|
||||||
|
})
|
||||||
|
export class PrismaModule {}
|
||||||
15
server/src/database/prisma.service.ts
Normal file
15
server/src/database/prisma.service.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
|
||||||
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PrismaService extends PrismaClient implements OnModuleInit {
|
||||||
|
async onModuleInit() {
|
||||||
|
await this.$connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
async enableShutdownHooks(app: INestApplication) {
|
||||||
|
this.$on('beforeExit', async () => {
|
||||||
|
await app.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
30
server/src/database/schema.prisma
Normal file
30
server/src/database/schema.prisma
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
generator client {
|
||||||
|
provider = "prisma-client-js"
|
||||||
|
}
|
||||||
|
|
||||||
|
datasource db {
|
||||||
|
provider = "postgresql"
|
||||||
|
url = env("SERVER_DATABASE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
model WorkspaceMember {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
deleted_at DateTime?
|
||||||
|
user_id String @unique
|
||||||
|
workspace_id Int
|
||||||
|
|
||||||
|
@@map("workspace_members")
|
||||||
|
}
|
||||||
|
|
||||||
|
model Workspace {
|
||||||
|
id Int @id @default(autoincrement())
|
||||||
|
created_at DateTime @default(now())
|
||||||
|
updated_at DateTime @updatedAt
|
||||||
|
deleted_at DateTime?
|
||||||
|
domain_name String @unique
|
||||||
|
display_name String
|
||||||
|
|
||||||
|
@@map("workspaces")
|
||||||
|
}
|
||||||
12
server/src/user/user.module.ts
Normal file
12
server/src/user/user.module.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { PrismaModule } from 'src/database/prisma.module';
|
||||||
|
import { UserRepository } from './user.repository';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
import { WorkspaceRepository } from './workspace.repository';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [PrismaModule],
|
||||||
|
providers: [UserRepository, UserService, WorkspaceRepository],
|
||||||
|
exports: [UserService, UserRepository, WorkspaceRepository],
|
||||||
|
})
|
||||||
|
export class UserModule {}
|
||||||
23
server/src/user/user.repository.ts
Normal file
23
server/src/user/user.repository.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Prisma, WorkspaceMember } from '@prisma/client';
|
||||||
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserRepository {
|
||||||
|
constructor(private prisma: PrismaService) {}
|
||||||
|
|
||||||
|
async upsertWorkspaceMember(params: { data: Prisma.WorkspaceMemberCreateInput }): Promise<WorkspaceMember> {
|
||||||
|
const { data } = params;
|
||||||
|
return this.prisma.workspaceMember.upsert({
|
||||||
|
where: {
|
||||||
|
user_id: data.user_id,
|
||||||
|
},
|
||||||
|
create: {
|
||||||
|
user_id: data.user_id,
|
||||||
|
workspace_id: data.workspace_id,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
18
server/src/user/user.service.spec.ts
Normal file
18
server/src/user/user.service.spec.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
|
describe('UserService', () => {
|
||||||
|
let service: UserService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [UserService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<UserService>(UserService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
40
server/src/user/user.service.ts
Normal file
40
server/src/user/user.service.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import { HasuraInsertEvent, TrackedHasuraEventHandler } from '@golevelup/nestjs-hasura';
|
||||||
|
import { UserRepository} from "./user.repository"
|
||||||
|
import { Injectable, Response } from '@nestjs/common';
|
||||||
|
import { WorkspaceRepository } from './workspace.repository';
|
||||||
|
import { response } from 'express';
|
||||||
|
|
||||||
|
interface User {
|
||||||
|
id: number;
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserService {
|
||||||
|
constructor(private repository: UserRepository, private workspaceRepository: WorkspaceRepository) {}
|
||||||
|
|
||||||
|
@TrackedHasuraEventHandler({
|
||||||
|
triggerName: 'user-created',
|
||||||
|
tableName: 'users',
|
||||||
|
schema: 'auth',
|
||||||
|
definition: { type: 'insert' },
|
||||||
|
})
|
||||||
|
async handleUserCreated(evt: HasuraInsertEvent<User>) {
|
||||||
|
const workspace = await this.workspaceRepository.findWorkspaceByDomainName(
|
||||||
|
{ where: { domain_name:evt.event.data.new.email.split('@')[1] }
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(workspace)
|
||||||
|
|
||||||
|
if (!workspace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspaceMember = await this.repository.upsertWorkspaceMember({
|
||||||
|
data: {
|
||||||
|
user_id: String(evt.event.data.new.id),
|
||||||
|
workspace_id: workspace.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
12
server/src/user/workspace.repository.ts
Normal file
12
server/src/user/workspace.repository.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import { Prisma, Workspace } from '@prisma/client';
|
||||||
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class WorkspaceRepository {
|
||||||
|
constructor(private prisma: PrismaService) {}
|
||||||
|
|
||||||
|
async findWorkspaceByDomainName(data: Prisma.WorkspaceFindUniqueArgs): Promise<Workspace> {
|
||||||
|
return this.prisma.workspace.findUnique(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user