From 750451ea73312d421aa8b8c62e2539f2cdfee80b Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Mon, 20 May 2024 22:46:56 +0200 Subject: [PATCH 1/8] refactor(domain): move the database schema next to business rules --- .yarnrc.yml | 2 + apps/core/package.json | 1 - apps/functions/code-embed/package.json | 1 - package.json | 3 +- packages/database/.env.template | 2 - packages/database/.eslintrc.json | 8 - packages/database/.gitignore | 4 - packages/database/README.md | 101 ------------- packages/database/__tests__/utils/id.test.ts | 21 --- packages/database/env.d.ts | 12 -- packages/database/index.ts | 11 -- packages/database/jest.config.ts | 15 -- packages/database/package.json | 31 ---- packages/database/prisma/schema.test.prisma | 122 --------------- packages/database/src/utils/id.ts | 7 - packages/database/tsconfig.json | 15 -- packages/database/tsconfig.prod.json | 9 -- packages/domain/.env.template | 9 +- packages/domain/.eslintrc.json | 4 +- packages/domain/.gitignore | 1 + packages/domain/README.md | 86 +++++++---- .../domain/__tests__/setup/global-setup.ts | 34 ----- packages/domain/__tests__/setup/test-setup.ts | 9 -- packages/domain/env.d.ts | 9 +- packages/domain/index.ts | 42 ++++-- packages/domain/jest.config.ts | 2 - packages/domain/package.json | 27 +++- .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../migration.sql | 0 .../prisma/migrations/migration_lock.toml | 0 .../{database => domain}/prisma/schema.prisma | 0 .../src/entities/folder.ts | 2 +- .../{database => domain}/src/entities/role.ts | 3 +- .../src/entities/session.ts | 2 +- .../src/entities/snippet.ts | 3 +- .../{database => domain}/src/entities/user.ts | 3 +- .../folders/dtos/create-folder-dto.test.ts | 5 +- .../src/folders/dtos/create-folder-dto.ts | 7 +- .../dtos/create-user-root-folder-dto.test.ts | 5 +- .../dtos/create-user-root-folder-dto.ts | 7 +- .../folders/dtos/update-folder-dto.test.ts | 7 +- .../src/folders/dtos/update-folder-dto.ts | 4 +- .../folders/folder.service.test.ts | 13 +- packages/domain/src/folders/folder.service.ts | 29 ++-- .../folders/utils/folders.test.ts | 7 +- packages/domain/src/folders/utils/folders.ts | 2 +- .../newsletters/newsletter.service.test.ts | 8 +- .../src/newsletters/newsletter.service.ts | 4 +- .../roles/dtos/create-role-dto.test.ts | 5 +- .../domain/src/roles/dtos/create-role-dto.ts | 7 +- packages/domain/src/roles/role.service.ts | 17 ++- .../sessions/dtos/create-session-dto.test.ts | 6 +- .../src/sessions/dtos/create-session-dto.ts | 8 +- .../sessions/session.service.test.ts | 14 +- .../domain/src/sessions/session.service.ts | 14 +- .../snippets/dtos/create-snippet-dto.test.ts | 9 +- .../src/snippets/dtos/create-snippet-dto.ts | 7 +- .../snippets/dtos/delete-snippet-dto.test.ts | 4 +- .../src/snippets/dtos/delete-snippet-dto.ts | 2 +- .../snippets/dtos/update-snippet-dto.test.ts | 7 +- .../src/snippets/dtos/update-snippet-dto.ts | 4 +- .../snippets/snippet.service.test.ts | 10 +- .../domain/src/snippets/snippet.service.ts | 25 ++-- .../users/dtos/create-user-dto.test.ts | 5 +- .../domain/src/users/dtos/create-user-dto.ts | 8 +- .../users/dtos/update-user-dto.test.ts | 7 +- .../domain/src/users/dtos/update-user-dto.ts | 4 +- .../users/user.service.test.ts | 10 +- packages/domain/src/users/user.service.ts | 26 ++-- packages/domain/src/utils/id.test.ts | 17 +++ packages/domain/src/utils/id.ts | 6 + .../src => domain/src/utils}/prisma.ts | 14 +- packages/domain/tests/database.mjs | 25 ++++ .../setup/test-utils.ts => tests/helpers.ts} | 26 ++-- packages/domain/tsconfig.json | 5 +- packages/domain/tsconfig.prod.json | 3 +- packages/embed/package.json | 1 - yarn.lock | 141 +++++++++++++++--- 87 files changed, 464 insertions(+), 672 deletions(-) delete mode 100644 packages/database/.env.template delete mode 100644 packages/database/.eslintrc.json delete mode 100644 packages/database/.gitignore delete mode 100644 packages/database/README.md delete mode 100644 packages/database/__tests__/utils/id.test.ts delete mode 100644 packages/database/env.d.ts delete mode 100644 packages/database/index.ts delete mode 100644 packages/database/jest.config.ts delete mode 100644 packages/database/package.json delete mode 100644 packages/database/prisma/schema.test.prisma delete mode 100644 packages/database/src/utils/id.ts delete mode 100644 packages/database/tsconfig.json delete mode 100644 packages/database/tsconfig.prod.json delete mode 100644 packages/domain/__tests__/setup/global-setup.ts delete mode 100644 packages/domain/__tests__/setup/test-setup.ts rename packages/{database => domain}/prisma/migrations/20220417203053_create_roles_and_users_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220503205537_create_folders_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220503211115_create_snippets_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220603235600_add_unique_constraint_on_folder_name/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220608214738_create_sessions_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220611062432_add_password_to_users_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220611065002_update_oauth_provider_in_users_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220730081611_add_line_highlight_in_snippet_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20220730133457_add_theme_in_snippet_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20221020204120_add_path_in_folders_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/20221030113708_add_content_html_in_snippets_table/migration.sql (100%) rename packages/{database => domain}/prisma/migrations/migration_lock.toml (100%) rename packages/{database => domain}/prisma/schema.prisma (100%) rename packages/{database => domain}/src/entities/folder.ts (64%) rename packages/{database => domain}/src/entities/role.ts (54%) rename packages/{database => domain}/src/entities/session.ts (64%) rename packages/{database => domain}/src/entities/snippet.ts (53%) rename packages/{database => domain}/src/entities/user.ts (53%) rename packages/domain/{__tests__/services => src}/folders/dtos/create-folder-dto.test.ts (94%) rename packages/domain/{__tests__/services => src}/folders/dtos/create-user-root-folder-dto.test.ts (81%) rename packages/domain/{__tests__/services => src}/folders/dtos/update-folder-dto.test.ts (82%) rename packages/domain/{__tests__/services => src}/folders/folder.service.test.ts (97%) rename packages/domain/{__tests__/services => src}/folders/utils/folders.test.ts (81%) rename packages/domain/{__tests__/services => src}/newsletters/newsletter.service.test.ts (87%) rename packages/domain/{__tests__/services => src}/roles/dtos/create-role-dto.test.ts (83%) rename packages/domain/{__tests__/services => src}/sessions/dtos/create-session-dto.test.ts (76%) rename packages/domain/{__tests__/services => src}/sessions/session.service.test.ts (83%) rename packages/domain/{__tests__/services => src}/snippets/dtos/create-snippet-dto.test.ts (85%) rename packages/domain/{__tests__/services => src}/snippets/dtos/delete-snippet-dto.test.ts (74%) rename packages/domain/{__tests__/services => src}/snippets/dtos/update-snippet-dto.test.ts (90%) rename packages/domain/{__tests__/services => src}/snippets/snippet.service.test.ts (97%) rename packages/domain/{__tests__/services => src}/users/dtos/create-user-dto.test.ts (94%) rename packages/domain/{__tests__/services => src}/users/dtos/update-user-dto.test.ts (91%) rename packages/domain/{__tests__/services => src}/users/user.service.test.ts (96%) create mode 100644 packages/domain/src/utils/id.test.ts create mode 100644 packages/domain/src/utils/id.ts rename packages/{database/src => domain/src/utils}/prisma.ts (52%) create mode 100755 packages/domain/tests/database.mjs rename packages/domain/{__tests__/setup/test-utils.ts => tests/helpers.ts} (91%) diff --git a/.yarnrc.yml b/.yarnrc.yml index 03726422..9ae2f11a 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,5 +1,7 @@ compressionLevel: mixed +defaultSemverRangePrefix: "" + httpRetry: 30 nodeLinker: node-modules diff --git a/apps/core/package.json b/apps/core/package.json index 51b97460..a5280e74 100644 --- a/apps/core/package.json +++ b/apps/core/package.json @@ -16,7 +16,6 @@ }, "dependencies": { "@graphql-tools/schema": "10.0.3", - "@snipcode/database": "workspace:*", "@snipcode/domain": "workspace:*", "@snipcode/embed": "workspace:*", "@snipcode/logger": "workspace:*", diff --git a/apps/functions/code-embed/package.json b/apps/functions/code-embed/package.json index b8e7ebd0..8bc7eb7e 100644 --- a/apps/functions/code-embed/package.json +++ b/apps/functions/code-embed/package.json @@ -19,7 +19,6 @@ "node": ">=16.14.0" }, "dependencies": { - "@snipcode/database": "workspace:*", "@snipcode/embed": "workspace:*", "shiki": "^0.11.1" }, diff --git a/package.json b/package.json index 2878a486..0bd6044f 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "cache:disable": "turbo unlink" }, "workspaces": [ - "packages/database", "packages/domain", "packages/embed", "packages/front", @@ -67,5 +66,5 @@ "turbo": "1.13.0", "typescript": "5.4.3" }, - "packageManager": "yarn@4.2.1" + "packageManager": "yarn@4.2.2" } diff --git a/packages/database/.env.template b/packages/database/.env.template deleted file mode 100644 index 2299991d..00000000 --- a/packages/database/.env.template +++ /dev/null @@ -1,2 +0,0 @@ -DATABASE_URL="mysql://root:@127.0.0.1:3311/snipcode" -SHADOW_DATABASE_URL="mysql://root:secret@127.0.0.1:3312/snipcode" diff --git a/packages/database/.eslintrc.json b/packages/database/.eslintrc.json deleted file mode 100644 index 88cacee6..00000000 --- a/packages/database/.eslintrc.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "ignorePatterns": ["jest.config.ts", "dist"], - "parserOptions": { - "ecmaVersion": 2021, - "sourceType": "module", - "project": "tsconfig.json" - } -} diff --git a/packages/database/.gitignore b/packages/database/.gitignore deleted file mode 100644 index 32e47a2c..00000000 --- a/packages/database/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -dist -.env -.env.test diff --git a/packages/database/README.md b/packages/database/README.md deleted file mode 100644 index 8f962466..00000000 --- a/packages/database/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# Snipcode Database - -This package contains all the entities and data access layer that can be used in the Backend or Lambda functions. -We use Prisma as the ORM to create database migrations and entities. - -## Tech Stack -* Node.js -* Typescript -* [Prisma](https://www.prisma.io/) - -## Prerequisites -Make sure you have this tools installed before running the project -* Node.js 18+ -* Yarn -* [PlanetScale CLI](https://planetscale.com/cli) - -## Set up the project -Delete the existing folders output from build commands -```shell -yarn clean -``` -Install node modules -````shell -yarn install -```` - -Create the .env file from the template -```shell -cp .env.template .env -# open .env file and update it with your local environment configuration -nano .env -``` - -### Connect to the local database locally -This project uses PlanetScale for database and to connect to the database locally, -you must authenticate first (Ask the credentials to [@tericcabrel](https://github.com/tericcabrel)). -Once authenticated from the terminal, execute the commands below on two separate terminals. -```shell -# On a terminal -yarn db:dev -# On a second terminal (only necessary if you update the prisma schema) -yarn db:shadow -``` - -The shadow database run on Docker, so don't forget to stop it when you don't need it -```shell -yarn db:shadow:stop -``` - -### Run the database migration, generate Prisma types and seed the database with default data -```shell -yarn db:generate -yarn db:migrate:dev -yarn db:seed -``` - -### Generate a database migration -To generate a database migration, we run the command below: -```shell -yarn db:migrate:dev --name -``` -Once done, make a copy of the file `prisma/schema.prisma` to `prisma/schema.test.prisma`. - -Open the copied file and remove the line `shadowDatabaseUrl = env("SHADOW_DATABASE_URL")`. - -This action is required to make the test executions easier in the package **domain (packages/domain)**. - -### Others Prisma commands -- Reset the database without seeding: `db:reset:dev` -- Reset the database with seeding: `db:reset:dev:seed` -- Open Prisma Studio to browse your DB: `db:view` -- Lint the Prisma schema file: `db:format` - -### Create a deployment request -To publish the database schema changes in production, you must create a deployment request. Run the command below to do that -```shell -yarn db:deploy:create -``` - -Build the package to generate types declaration required to provide autocompletion while using the functions in the core or Lambda functions -```bash -yarn build -``` -A `dist` folder will be generated. - -## Running tests -Run the command below to run all the tests -```shell -yarn test -``` -To run a specific test file, append the filename after the command -```shell -yarn test id.test.ts -``` - -## Lint the project -ESLint and Prettier are used to normalize the code style across the project. -Linting the code make sure there is no error -```shell -yarn lint -``` diff --git a/packages/database/__tests__/utils/id.test.ts b/packages/database/__tests__/utils/id.test.ts deleted file mode 100644 index f4aff428..00000000 --- a/packages/database/__tests__/utils/id.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { dbId } from '../../index'; - -describe('Test Database ID generator', () => { - test('generate a valid id', () => { - const id = dbId.generate(); - - expect(dbId.isValid(id)).toEqual(true); - }); - - test('detect invalid id', () => { - const invalidId = 'myinvalidid'; - - expect(dbId.isValid(invalidId)).toEqual(false); - }); - - test('detect invalid id', () => { - const validId = 'cl1fny73o0000e7czbglkhv0p'; - - expect(dbId.isValid(validId)).toEqual(true); - }); -}); diff --git a/packages/database/env.d.ts b/packages/database/env.d.ts deleted file mode 100644 index df521717..00000000 --- a/packages/database/env.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -export type EnvironmentVariables = { - DATABASE_URL: string; - NODE_ENV: string; -}; - -declare global { - namespace NodeJS { - type ProcessEnv = EnvironmentVariables; - } -} - -export {}; diff --git a/packages/database/index.ts b/packages/database/index.ts deleted file mode 100644 index d273725e..00000000 --- a/packages/database/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Folder from './src/entities/folder'; -import Role, { RoleName } from './src/entities/role'; -import Session from './src/entities/session'; -import Snippet, { SnippetVisibility } from './src/entities/snippet'; -import User, { OauthProvider } from './src/entities/user'; -import prisma, { PrismaClient } from './src/prisma'; -import dbId from './src/utils/id'; - -export { prisma as dbClient, PrismaClient }; -export { dbId }; -export type { Role, RoleName, User, OauthProvider, Folder, Session, Snippet, SnippetVisibility }; diff --git a/packages/database/jest.config.ts b/packages/database/jest.config.ts deleted file mode 100644 index 956e1edc..00000000 --- a/packages/database/jest.config.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { Config } from '@jest/types'; - -const config: Config.InitialOptions = { - roots: ['.'], - preset: 'ts-jest', - testMatch: ['**/?(*.)+(spec|test).[jt]s'], - testEnvironment: 'node', - clearMocks: true, - maxWorkers: 1, - snapshotFormat: { - "printBasicPrototype": false - }, -}; - -export default config; diff --git a/packages/database/package.json b/packages/database/package.json deleted file mode 100644 index aa27c441..00000000 --- a/packages/database/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "@snipcode/database", - "version": "1.0.0", - "private": true, - "description": "This package contains all the entities and data access layer", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "license": "MIT", - "scripts": { - "prebuild": "yarn db:generate", - "build": "tsc --project tsconfig.prod.json", - "clean": "rm -rf .turbo dist", - "lint": "eslint src index.ts", - "test": "jest", - "db:dev": "pscale connect snipcode dev --port 3311", - "db:shadow": "docker run -d --rm -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=snipcode --name snipcode-shadow-db -p 3312:3306 mysql:8.0.34", - "db:shadow:stop": "docker kill snipcode-shadow-db && docker container prune -f", - "db:deploy:create": "pscale deploy-request create snipcode dev", - "db:generate": "prisma generate --schema=./prisma/schema.prisma", - "db:migrate:dev": "prisma migrate dev", - "db:reset:dev": "prisma migrate reset --skip-seed", - "db:reset:dev:seed": "prisma migrate reset", - "db:view": "prisma studio", - "db:format": "prisma format", - "db:seed": "prisma db seed" - }, - "dependencies": { - "@prisma/client": "5.11.0", - "cuid": "3.0.0" - } -} diff --git a/packages/database/prisma/schema.test.prisma b/packages/database/prisma/schema.test.prisma deleted file mode 100644 index 01b6603c..00000000 --- a/packages/database/prisma/schema.test.prisma +++ /dev/null @@ -1,122 +0,0 @@ -generator client { - provider = "prisma-client-js" - previewFeatures = [] - binaryTargets = ["native", "linux-musl", "rhel-openssl-1.0.x"] -} - -datasource db { - provider = "mysql" - url = env("DATABASE_URL") - relationMode = "prisma" -} - -enum RoleName { - user - admin -} - -enum OauthProvider { - email - github - google - stackoverflow -} - -enum SnippetVisibility { - public - private -} - -model Role { - id String @id @db.VarChar(50) - name RoleName @unique - level Int - description String? @db.VarChar(200) - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - User User[] - - @@map("roles") -} - -model User { - id String @id @db.VarChar(50) - email String @unique @db.VarChar(100) - password String? @db.VarChar(100) - username String? @db.VarChar(50) - name String @db.VarChar(50) - timezone String? @db.VarChar(50) - isEnabled Boolean @default(false) @map("is_enabled") @db.TinyInt - pictureUrl String? @map("picture_url") @db.VarChar(255) - roleId String @map("role_id") @db.VarChar(50) - oauthProvider OauthProvider - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - role Role @relation(fields: [roleId], references: [id], onDelete: Restrict) - folders Folder[] - snippets Snippet[] - sessions Session[] - - @@index([username]) - @@index([roleId]) - @@map("users") -} - -model Folder { - id String @id @db.VarChar(50) - userId String @map("user_id") @db.VarChar(50) - parentId String? @map("parent_id") - name String @db.VarChar(255) - path String? @db.Text - isFavorite Boolean @default(false) @map("is_favorite") - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - parent Folder? @relation(name: "parent_folder", fields: [parentId], references: [id], onDelete: NoAction, onUpdate: NoAction) - subFolders Folder[] @relation("parent_folder") - snippets Snippet[] - - @@index([name]) - @@index([isFavorite]) - @@index([userId]) - @@index([parentId]) - @@unique([userId, parentId, name], name: "folder_name_unique_constraint") - @@map("folders") -} - -model Snippet { - id String @id @db.VarChar(50) - userId String @map("user_id") @db.VarChar(50) - folderId String @map("folder_id") - name String @db.VarChar(255) - content String @db.Text - contentHtml String? @db.Text @map("content_html") - language String @db.VarChar(20) - size Int @default(0) @db.Int - visibility SnippetVisibility @default(public) - description String? @db.Text - lineHighlight String? @db.Text @map("line_highlight") - theme String @db.VarChar(20) - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") - user User @relation(fields: [userId], references: [id], onDelete: Restrict) - folder Folder @relation(fields: [folderId], references: [id], onDelete: Cascade) - - @@index([name]) - @@index([userId]) - @@index([folderId]) - @@index([language]) - @@index([visibility]) - @@map("snippets") -} - -model Session { - id String @id @default(cuid()) - token String @unique - userId String @map("user_id") - expires DateTime - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@index([userId]) - @@map("sessions") -} diff --git a/packages/database/src/utils/id.ts b/packages/database/src/utils/id.ts deleted file mode 100644 index 73064f34..00000000 --- a/packages/database/src/utils/id.ts +++ /dev/null @@ -1,7 +0,0 @@ -import cuid, { isCuid } from 'cuid'; - -const generate = () => cuid(); - -const isValid = (id: string) => isCuid(id); - -export default { generate, isValid }; diff --git a/packages/database/tsconfig.json b/packages/database/tsconfig.json deleted file mode 100644 index e2f2ebc7..00000000 --- a/packages/database/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/tsconfig", - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "./dist", - "declaration": true, - "composite": true, - "sourceMap": false - }, - "files": ["env.d.ts"], - "include": ["src", "__tests__", "index.ts"], - "exclude": [ - "node_modules" - ] -} diff --git a/packages/database/tsconfig.prod.json b/packages/database/tsconfig.prod.json deleted file mode 100644 index e8c5afe2..00000000 --- a/packages/database/tsconfig.prod.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "sourceMap": false - }, - "exclude": [ - "__tests__" - ] -} diff --git a/packages/domain/.env.template b/packages/domain/.env.template index 60b58406..db8a53bf 100644 --- a/packages/domain/.env.template +++ b/packages/domain/.env.template @@ -1,6 +1,3 @@ -DATABASE_URL="mysql://root:secret@127.0.0.1:3313/snipcode" -MYSQL_ROOT_PASSWORD=secret -MYSQL_DATABASE=snipcode -MYSQL_PORT=3313 -NODE_ENV=test -ADMIN_PASSWORD=admin_password +DATABASE_URL="mysql://root:@127.0.0.1:3311/core-db" +SHADOW_DATABASE_URL="mysql://root:secret@127.0.0.1:3312/snipcode" +TEST_DATABASE_URL="mysql://root:secret@127.0.0.1:3313/snipcode" diff --git a/packages/domain/.eslintrc.json b/packages/domain/.eslintrc.json index 9a46147c..e17f70bb 100644 --- a/packages/domain/.eslintrc.json +++ b/packages/domain/.eslintrc.json @@ -1,8 +1,8 @@ { "ignorePatterns": ["jest.config.ts"], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": ["./packages/domain/tsconfig.json", "tsconfig.json"] } } diff --git a/packages/domain/.gitignore b/packages/domain/.gitignore index 4001f4f0..0c152fa2 100644 --- a/packages/domain/.gitignore +++ b/packages/domain/.gitignore @@ -1,4 +1,5 @@ node_modules dist .env +.env.test coverage diff --git a/packages/domain/README.md b/packages/domain/README.md index 6cee6b89..c190d226 100644 --- a/packages/domain/README.md +++ b/packages/domain/README.md @@ -1,71 +1,99 @@ # Snipcode Domain -This package contains all the business logic of the project +This package contains: +* The entities and data access layer that can be used in the Backend. +* The business logic of the project +* The database migrations and entities managed by the ORM Prisma -## Tech Stack -* Node.js -* TypeScript ## Prerequisites Make sure you have this tools installed before running the project * Node.js 20+ -* Yarn +* Yarn 4 * Docker +* [The PlanetScale CLI](https://planetscale.com/cli) ## Set up the project Delete the existing folders output from build commands ```shell yarn clean ``` -Install node modules + +Install the Node modules ````shell yarn install ```` + Create the .env file from the template. This file is useful for test executions, so you don't have to edit any properties in the file. ```shell cp .env.template .env ``` -Build the package to generate types declaration required to provide autocompletion while using the functions in the core or web applications -```bash -yarn build +### Connect to the local database locally +This project uses PlanetScale as the database.
+To connect to the database locally, you must authenticate first (Ask the credentials to [@tericcabrel](https://github.com/tericcabrel)).
+Once authenticated from the terminal, execute the commands below on two separate terminals. +```shell +# On a first terminal +yarn db:dev +# On a second terminal (only necessary if you update the prisma schema) +yarn db:shadow ``` -A `dist` folder will be generated. -## Running tests -If you are running tests that require a database, you must start one with Docker. - -Start the Docker database +The shadow database runs on Docker, you can stop it when you don't need it ```shell -yarn db:test +yarn db:shadow:stop ``` -If you want to stop the Docker database + +### Run the database migration, generate Prisma types and seed the database with default data ```shell -yarn db:test:stop +yarn db:generate +yarn db:migrate +yarn db:seed ``` -Run the migration to load the database schema + +### Generate a database migration +To create a database migration that generate the SQL file, run the command below: ```shell -yarn db:test:migration +yarn db:migrate --name ``` -There are three command to run tests where each command has a specific purpose: -- `yarn test:unit`: use this command when you want to test unit functions with no external dependencies (db, message broker, etc...) +### Others Prisma commands +- Reset the database without seeding: `db:reset` +- Reset the database with seeding: `db:reset:seed` +- Open Prisma Studio to browse your database: `db:view` +- Lint the Prisma schema file: `db:format` +### Create a deployment request +To publish the database schema changes in production, you must create a deployment request. Run the command below to do that +```shell +yarn db:deploy:create +``` + +Build the package to generate types declaration required to provide autocompletion while using the functions in the core or Lambda functions +```bash +yarn build +``` +A `dist` folder will be generated. -- `yarn test`: use this command to run functions that require database or not. Every time you run a test, the migration will be executed against the database - (in the jest global setup) which add 5-10 seconds on test execution time. This command runs inside the CI Pipeline. +## Running tests +The command to run tests starts a Docker container of a MySQL database, it is required to execute functional tests. +After the container has started, we execute the database migration or reset all the database tables. -- `yarn test:db:local`: This command run functions that require database or not but, it doesn't execute the migration before running the test, so it is faster than the former. -However, ensure you ran `yarn db:test:migration` before to +Run command below to execute tests +```shell +yarn test +``` To run a specific test file, append the filename after the command: ```shell yarn test user.service.test.ts -# or -yarn test:unit user.service.test.ts -# or -yarn test:db:local user.service.test.ts +``` + +Run the command below to stop the Docker container for the database +```shell +yarn db:test:stop ``` ## Lint the project diff --git a/packages/domain/__tests__/setup/global-setup.ts b/packages/domain/__tests__/setup/global-setup.ts deleted file mode 100644 index de0e1aaa..00000000 --- a/packages/domain/__tests__/setup/global-setup.ts +++ /dev/null @@ -1,34 +0,0 @@ -// This file is executed once in the worker before executing each test file. -import { execSync } from 'child_process'; -import * as path from 'path'; - -import { getEnv } from '@snipcode/utils'; -import dotenv from 'dotenv'; - -dotenv.config(); - -const databaseUser = 'root'; -const databasePassword = getEnv('MYSQL_ROOT_PASSWORD'); -const databaseName = getEnv('MYSQL_DATABASE'); -const databasePort = getEnv('MYSQL_PORT'); -const isRunningLocally = process.env.IS_LOCAL === 'true'; - -/* - * This file is executed by Jest before running any tests. - * We drop the database and re-create it from migrations every time. - */ -export default async () => { - if (!process.env.TEST_WITH_DB) { - return; - } - - const databaseURL = `mysql://${databaseUser}:${databasePassword}@127.0.0.1:${databasePort}/${databaseName}`; - - if (!isRunningLocally) { - const prismaSchemaPath = `${path.resolve(__dirname, '../../../database/prisma')}/schema.test.prisma`; - - const command = `DATABASE_URL=${databaseURL} npx prisma migrate dev --schema=${prismaSchemaPath}`; - - execSync(command); - } -}; diff --git a/packages/domain/__tests__/setup/test-setup.ts b/packages/domain/__tests__/setup/test-setup.ts deleted file mode 100644 index adf7a673..00000000 --- a/packages/domain/__tests__/setup/test-setup.ts +++ /dev/null @@ -1,9 +0,0 @@ -// This file is executed once in the worker before executing each test file. - -jest.setTimeout(10000); - -// eslint-disable-next-line @typescript-eslint/no-empty-function -beforeAll(async () => {}); - -// eslint-disable-next-line @typescript-eslint/no-empty-function -afterAll(async () => {}); diff --git a/packages/domain/env.d.ts b/packages/domain/env.d.ts index 12427709..aff7859e 100644 --- a/packages/domain/env.d.ts +++ b/packages/domain/env.d.ts @@ -1,12 +1,7 @@ export type EnvironmentVariables = { - ADMIN_PASSWORD: string; - IS_LOCAL: string; - MYSQL_DATABASE: string; - MYSQL_PORT: string; - MYSQL_ROOT_PASSWORD: string; + DATABASE_URL: string; NODE_ENV: string; - PASSWORD_SALT: string; - TEST_WITH_DB: string; + TEST_DATABASE_URL: string; }; declare global { diff --git a/packages/domain/index.ts b/packages/domain/index.ts index 1b00c81d..f8c6ab5c 100644 --- a/packages/domain/index.ts +++ b/packages/domain/index.ts @@ -1,19 +1,29 @@ -import CreateFolderDto from './src/folders/dtos/create-folder-dto'; -import CreateUserRootFolderDto from './src/folders/dtos/create-user-root-folder-dto'; -import UpdateFolderDto from './src/folders/dtos/update-folder-dto'; -import FolderService from './src/folders/folder.service'; -import NewsletterService from './src/newsletters/newsletter.service'; -import CreateRoleDto from './src/roles/dtos/create-role-dto'; -import RoleService from './src/roles/role.service'; -import CreateSessionDto from './src/sessions/dtos/create-session-dto'; -import SessionService from './src/sessions/session.service'; -import CreateSnippetDto from './src/snippets/dtos/create-snippet-dto'; -import DeleteSnippetDto from './src/snippets/dtos/delete-snippet-dto'; -import UpdateSnippetDto from './src/snippets/dtos/update-snippet-dto'; -import SnippetService from './src/snippets/snippet.service'; -import CreateUserDto from './src/users/dtos/create-user-dto'; -import UpdateUserDto from './src/users/dtos/update-user-dto'; -import UserService from './src/users/user.service'; +import { Folder } from './src/entities/folder'; +import { Role, RoleName } from './src/entities/role'; +import { Session } from './src/entities/session'; +import { Snippet, SnippetVisibility } from './src/entities/snippet'; +import { OauthProvider, User } from './src/entities/user'; +import { CreateFolderDto } from './src/folders/dtos/create-folder-dto'; +import { CreateUserRootFolderDto } from './src/folders/dtos/create-user-root-folder-dto'; +import { UpdateFolderDto } from './src/folders/dtos/update-folder-dto'; +import { FolderService } from './src/folders/folder.service'; +import { NewsletterService } from './src/newsletters/newsletter.service'; +import { CreateRoleDto } from './src/roles/dtos/create-role-dto'; +import { RoleService } from './src/roles/role.service'; +import { CreateSessionDto } from './src/sessions/dtos/create-session-dto'; +import { SessionService } from './src/sessions/session.service'; +import { CreateSnippetDto } from './src/snippets/dtos/create-snippet-dto'; +import { DeleteSnippetDto } from './src/snippets/dtos/delete-snippet-dto'; +import { UpdateSnippetDto } from './src/snippets/dtos/update-snippet-dto'; +import { SnippetService } from './src/snippets/snippet.service'; +import { CreateUserDto } from './src/users/dtos/create-user-dto'; +import { UpdateUserDto } from './src/users/dtos/update-user-dto'; +import { UserService } from './src/users/user.service'; +import { dbID } from './src/utils/id'; + +export { dbID }; +export { PrismaClient, prisma as dbClient } from './src/utils/prisma'; +export type { Role, RoleName, User, OauthProvider, Folder, Session, Snippet, SnippetVisibility }; const roleService = new RoleService(); const userService = new UserService(); diff --git a/packages/domain/jest.config.ts b/packages/domain/jest.config.ts index 2d06042f..27dc4ea5 100644 --- a/packages/domain/jest.config.ts +++ b/packages/domain/jest.config.ts @@ -10,8 +10,6 @@ const config: Config.InitialOptions = { snapshotFormat: { printBasicPrototype: false, }, - globalSetup: './__tests__/setup/global-setup.ts', - setupFilesAfterEnv: ['./__tests__/setup/test-setup.ts'], coverageDirectory: 'coverage', collectCoverage: false, // When set to true, coverage is performed even if coverage flag isn't provided collectCoverageFrom: ['src/**/*.ts', '!src/index.ts'], diff --git a/packages/domain/package.json b/packages/domain/package.json index f61bab43..08737144 100644 --- a/packages/domain/package.json +++ b/packages/domain/package.json @@ -2,7 +2,7 @@ "name": "@snipcode/domain", "version": "1.0.0", "private": true, - "description": "This package contains all the business logic of the project", + "description": "This package contains the database definition and the business logic of the project", "main": "dist/index.js", "types": "dist/index.d.ts", "license": "MIT", @@ -10,15 +10,23 @@ "build": "tsc --project tsconfig.prod.json", "clean": "rm -rf .turbo dist", "lint": "eslint --fix", - "db:test": "docker run -d --rm -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=snipcode --name snipcode-test-db -p 3313:3306 mysql:8.0.34", + "db:dev:create": "pscale branch create core-db dev", + "db:dev:connect": "pscale connect core-db dev --port 3311", + "db:shadow": "docker run -d --rm -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=snipcode --name snipcode-shadow-db -p 3312:3306 mysql:8.0.34", + "db:shadow:stop": "docker kill snipcode-shadow-db && docker container prune -f", + "db:deploy:create": "pscale deploy-request create core-db dev", + "db:generate": "prisma generate", + "db:migrate": "prisma migrate dev", + "db:reset": "prisma migrate reset --skip-seed", + "db:reset:seed": "prisma migrate reset", + "db:view": "prisma studio", + "db:format": "prisma format", + "db:seed": "prisma db seed", "db:test:stop": "docker container kill snipcode-test-db && docker container prune -f", - "db:test:migration": "npx prisma migrate dev --schema=../database/prisma/schema.test.prisma", - "test": "TEST_WITH_DB=true IS_LOCAL=false jest", - "test:unit": "jest", - "test:db:local": "TEST_WITH_DB=true IS_LOCAL=true jest" + "test": "NODE_ENV=test zx tests/database.mjs && jest" }, "dependencies": { - "@snipcode/database": "workspace:*", + "@bugsnag/cuid": "3.1.1", "@snipcode/utils": "workspace:*", "axios": "1.6.8", "bcryptjs": "2.4.3", @@ -26,7 +34,10 @@ }, "devDependencies": { "@ngneat/falso": "7.2.0", + "@prisma/client": "5.14.0", "@types/bcryptjs": "2.4.6", - "nock": "13.5.4" + "nock": "13.5.4", + "prisma": "5.14.0", + "zx": "8.0.2" } } diff --git a/packages/database/prisma/migrations/20220417203053_create_roles_and_users_table/migration.sql b/packages/domain/prisma/migrations/20220417203053_create_roles_and_users_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220417203053_create_roles_and_users_table/migration.sql rename to packages/domain/prisma/migrations/20220417203053_create_roles_and_users_table/migration.sql diff --git a/packages/database/prisma/migrations/20220503205537_create_folders_table/migration.sql b/packages/domain/prisma/migrations/20220503205537_create_folders_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220503205537_create_folders_table/migration.sql rename to packages/domain/prisma/migrations/20220503205537_create_folders_table/migration.sql diff --git a/packages/database/prisma/migrations/20220503211115_create_snippets_table/migration.sql b/packages/domain/prisma/migrations/20220503211115_create_snippets_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220503211115_create_snippets_table/migration.sql rename to packages/domain/prisma/migrations/20220503211115_create_snippets_table/migration.sql diff --git a/packages/database/prisma/migrations/20220603235600_add_unique_constraint_on_folder_name/migration.sql b/packages/domain/prisma/migrations/20220603235600_add_unique_constraint_on_folder_name/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220603235600_add_unique_constraint_on_folder_name/migration.sql rename to packages/domain/prisma/migrations/20220603235600_add_unique_constraint_on_folder_name/migration.sql diff --git a/packages/database/prisma/migrations/20220608214738_create_sessions_table/migration.sql b/packages/domain/prisma/migrations/20220608214738_create_sessions_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220608214738_create_sessions_table/migration.sql rename to packages/domain/prisma/migrations/20220608214738_create_sessions_table/migration.sql diff --git a/packages/database/prisma/migrations/20220611062432_add_password_to_users_table/migration.sql b/packages/domain/prisma/migrations/20220611062432_add_password_to_users_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220611062432_add_password_to_users_table/migration.sql rename to packages/domain/prisma/migrations/20220611062432_add_password_to_users_table/migration.sql diff --git a/packages/database/prisma/migrations/20220611065002_update_oauth_provider_in_users_table/migration.sql b/packages/domain/prisma/migrations/20220611065002_update_oauth_provider_in_users_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220611065002_update_oauth_provider_in_users_table/migration.sql rename to packages/domain/prisma/migrations/20220611065002_update_oauth_provider_in_users_table/migration.sql diff --git a/packages/database/prisma/migrations/20220730081611_add_line_highlight_in_snippet_table/migration.sql b/packages/domain/prisma/migrations/20220730081611_add_line_highlight_in_snippet_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220730081611_add_line_highlight_in_snippet_table/migration.sql rename to packages/domain/prisma/migrations/20220730081611_add_line_highlight_in_snippet_table/migration.sql diff --git a/packages/database/prisma/migrations/20220730133457_add_theme_in_snippet_table/migration.sql b/packages/domain/prisma/migrations/20220730133457_add_theme_in_snippet_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20220730133457_add_theme_in_snippet_table/migration.sql rename to packages/domain/prisma/migrations/20220730133457_add_theme_in_snippet_table/migration.sql diff --git a/packages/database/prisma/migrations/20221020204120_add_path_in_folders_table/migration.sql b/packages/domain/prisma/migrations/20221020204120_add_path_in_folders_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20221020204120_add_path_in_folders_table/migration.sql rename to packages/domain/prisma/migrations/20221020204120_add_path_in_folders_table/migration.sql diff --git a/packages/database/prisma/migrations/20221030113708_add_content_html_in_snippets_table/migration.sql b/packages/domain/prisma/migrations/20221030113708_add_content_html_in_snippets_table/migration.sql similarity index 100% rename from packages/database/prisma/migrations/20221030113708_add_content_html_in_snippets_table/migration.sql rename to packages/domain/prisma/migrations/20221030113708_add_content_html_in_snippets_table/migration.sql diff --git a/packages/database/prisma/migrations/migration_lock.toml b/packages/domain/prisma/migrations/migration_lock.toml similarity index 100% rename from packages/database/prisma/migrations/migration_lock.toml rename to packages/domain/prisma/migrations/migration_lock.toml diff --git a/packages/database/prisma/schema.prisma b/packages/domain/prisma/schema.prisma similarity index 100% rename from packages/database/prisma/schema.prisma rename to packages/domain/prisma/schema.prisma diff --git a/packages/database/src/entities/folder.ts b/packages/domain/src/entities/folder.ts similarity index 64% rename from packages/database/src/entities/folder.ts rename to packages/domain/src/entities/folder.ts index 61598ca1..b5dbffb9 100644 --- a/packages/database/src/entities/folder.ts +++ b/packages/domain/src/entities/folder.ts @@ -1,3 +1,3 @@ import { Folder } from '@prisma/client'; -export default Folder; +export { Folder }; diff --git a/packages/database/src/entities/role.ts b/packages/domain/src/entities/role.ts similarity index 54% rename from packages/database/src/entities/role.ts rename to packages/domain/src/entities/role.ts index 809b90b6..a3922675 100644 --- a/packages/database/src/entities/role.ts +++ b/packages/domain/src/entities/role.ts @@ -1,4 +1,3 @@ import { Role, RoleName } from '@prisma/client'; -export { RoleName }; -export default Role; +export { RoleName, Role }; diff --git a/packages/database/src/entities/session.ts b/packages/domain/src/entities/session.ts similarity index 64% rename from packages/database/src/entities/session.ts rename to packages/domain/src/entities/session.ts index 38bef425..f4b0c628 100644 --- a/packages/database/src/entities/session.ts +++ b/packages/domain/src/entities/session.ts @@ -1,3 +1,3 @@ import { Session } from '@prisma/client'; -export default Session; +export { Session }; diff --git a/packages/database/src/entities/snippet.ts b/packages/domain/src/entities/snippet.ts similarity index 53% rename from packages/database/src/entities/snippet.ts rename to packages/domain/src/entities/snippet.ts index d17abec7..b111abd8 100644 --- a/packages/database/src/entities/snippet.ts +++ b/packages/domain/src/entities/snippet.ts @@ -1,4 +1,3 @@ import { Snippet, SnippetVisibility } from '@prisma/client'; -export { SnippetVisibility }; -export default Snippet; +export { SnippetVisibility, Snippet }; diff --git a/packages/database/src/entities/user.ts b/packages/domain/src/entities/user.ts similarity index 53% rename from packages/database/src/entities/user.ts rename to packages/domain/src/entities/user.ts index 4e544ad4..ebcc5d2c 100644 --- a/packages/database/src/entities/user.ts +++ b/packages/domain/src/entities/user.ts @@ -1,4 +1,3 @@ import { OauthProvider, User } from '@prisma/client'; -export { OauthProvider }; -export default User; +export { OauthProvider, User }; diff --git a/packages/domain/__tests__/services/folders/dtos/create-folder-dto.test.ts b/packages/domain/src/folders/dtos/create-folder-dto.test.ts similarity index 94% rename from packages/domain/__tests__/services/folders/dtos/create-folder-dto.test.ts rename to packages/domain/src/folders/dtos/create-folder-dto.test.ts index 0e7656d2..a60ba572 100644 --- a/packages/domain/__tests__/services/folders/dtos/create-folder-dto.test.ts +++ b/packages/domain/src/folders/dtos/create-folder-dto.test.ts @@ -1,6 +1,5 @@ -import { Folder } from '@snipcode/database'; - -import { CreateFolderDto } from '../../../../index'; +import { CreateFolderDto } from './create-folder-dto'; +import { Folder } from '../../entities/folder'; describe('Test Create Folder DTO', () => { it('should create a valid folder object', () => { diff --git a/packages/domain/src/folders/dtos/create-folder-dto.ts b/packages/domain/src/folders/dtos/create-folder-dto.ts index e364f638..13e072f0 100644 --- a/packages/domain/src/folders/dtos/create-folder-dto.ts +++ b/packages/domain/src/folders/dtos/create-folder-dto.ts @@ -1,4 +1,5 @@ -import { Folder, dbId } from '@snipcode/database'; +import { Folder } from '../../entities/folder'; +import { dbID } from '../../utils/id'; type Input = { name: string; @@ -6,11 +7,11 @@ type Input = { userId: string; }; -export default class CreateFolderDto { +export class CreateFolderDto { private readonly folderId: string; constructor(private _input: Input) { - this.folderId = dbId.generate(); + this.folderId = dbID.generate(); } get name(): string { diff --git a/packages/domain/__tests__/services/folders/dtos/create-user-root-folder-dto.test.ts b/packages/domain/src/folders/dtos/create-user-root-folder-dto.test.ts similarity index 81% rename from packages/domain/__tests__/services/folders/dtos/create-user-root-folder-dto.test.ts rename to packages/domain/src/folders/dtos/create-user-root-folder-dto.test.ts index 3b490001..2a9f7f47 100644 --- a/packages/domain/__tests__/services/folders/dtos/create-user-root-folder-dto.test.ts +++ b/packages/domain/src/folders/dtos/create-user-root-folder-dto.test.ts @@ -1,6 +1,5 @@ -import { Folder } from '@snipcode/database'; - -import { CreateUserRootFolderDto } from '../../../../index'; +import { CreateUserRootFolderDto } from './create-user-root-folder-dto'; +import { Folder } from '../../entities/folder'; describe('Test Create User Root Folder DTO', () => { it('should create a valid folder object', () => { diff --git a/packages/domain/src/folders/dtos/create-user-root-folder-dto.ts b/packages/domain/src/folders/dtos/create-user-root-folder-dto.ts index 50d9b810..793a7b89 100644 --- a/packages/domain/src/folders/dtos/create-user-root-folder-dto.ts +++ b/packages/domain/src/folders/dtos/create-user-root-folder-dto.ts @@ -1,10 +1,11 @@ -import { Folder, dbId } from '@snipcode/database'; +import { Folder } from '../../entities/folder'; +import { dbID } from '../../utils/id'; -export default class CreateUserRootFolderDto { +export class CreateUserRootFolderDto { private readonly folderId: string; constructor(private _userId: string) { - this.folderId = dbId.generate(); + this.folderId = dbID.generate(); } toFolder(): Folder { diff --git a/packages/domain/__tests__/services/folders/dtos/update-folder-dto.test.ts b/packages/domain/src/folders/dtos/update-folder-dto.test.ts similarity index 82% rename from packages/domain/__tests__/services/folders/dtos/update-folder-dto.test.ts rename to packages/domain/src/folders/dtos/update-folder-dto.test.ts index b3016cf3..4130bef0 100644 --- a/packages/domain/__tests__/services/folders/dtos/update-folder-dto.test.ts +++ b/packages/domain/src/folders/dtos/update-folder-dto.test.ts @@ -1,7 +1,6 @@ -import { Folder } from '@snipcode/database'; - -import { UpdateFolderDto } from '../../../../index'; -import { createTestFolderDto, generateTestId } from '../../../setup/test-utils'; +import { UpdateFolderDto } from './update-folder-dto'; +import { createTestFolderDto, generateTestId } from '../../../tests/helpers'; +import { Folder } from '../../entities/folder'; describe('Test Update Folder DTO', () => { it('should return the folder to update', () => { diff --git a/packages/domain/src/folders/dtos/update-folder-dto.ts b/packages/domain/src/folders/dtos/update-folder-dto.ts index b151709d..b076a7f3 100644 --- a/packages/domain/src/folders/dtos/update-folder-dto.ts +++ b/packages/domain/src/folders/dtos/update-folder-dto.ts @@ -1,4 +1,4 @@ -import { Folder } from '@snipcode/database'; +import { Folder } from '../../entities/folder'; type Input = { creatorId: string; @@ -6,7 +6,7 @@ type Input = { name: string; }; -export default class UpdateFolderDto { +export class UpdateFolderDto { constructor(private _input: Input) {} get name(): string { diff --git a/packages/domain/__tests__/services/folders/folder.service.test.ts b/packages/domain/src/folders/folder.service.test.ts similarity index 97% rename from packages/domain/__tests__/services/folders/folder.service.test.ts rename to packages/domain/src/folders/folder.service.test.ts index 688bbc05..fee5a665 100644 --- a/packages/domain/__tests__/services/folders/folder.service.test.ts +++ b/packages/domain/src/folders/folder.service.test.ts @@ -1,8 +1,8 @@ -import { Folder } from '@snipcode/database'; import SnipcodeError, { errors, generateRandomId } from '@snipcode/utils'; -import { CreateUserRootFolderDto, folderService, roleService } from '../../../index'; -import CreateFolderDto from '../../../src/folders/dtos/create-folder-dto'; +import { CreateFolderDto } from './dtos/create-folder-dto'; +import { CreateUserRootFolderDto } from './dtos/create-user-root-folder-dto'; +import { FolderService } from './folder.service'; import { createManyTestFolders, createTestFolderDto, @@ -11,7 +11,12 @@ import { deleteTestFoldersById, deleteTestUsersById, updateTestFolderDto, -} from '../../setup/test-utils'; +} from '../../tests/helpers'; +import { Folder } from '../entities/folder'; +import { RoleService } from '../roles/role.service'; + +const roleService = new RoleService(); +const folderService = new FolderService(); describe('Test Folder service', () => { beforeAll(async () => { diff --git a/packages/domain/src/folders/folder.service.ts b/packages/domain/src/folders/folder.service.ts index e3347715..9f87fe70 100644 --- a/packages/domain/src/folders/folder.service.ts +++ b/packages/domain/src/folders/folder.service.ts @@ -1,16 +1,17 @@ -import { Folder, dbClient } from '@snipcode/database'; import SnipcodeError, { errors } from '@snipcode/utils'; -import CreateFolderDto from './dtos/create-folder-dto'; -import CreateUserRootFolderDto from './dtos/create-user-root-folder-dto'; -import UpdateFolderDto from './dtos/update-folder-dto'; +import { CreateFolderDto } from './dtos/create-folder-dto'; +import { CreateUserRootFolderDto } from './dtos/create-user-root-folder-dto'; +import { UpdateFolderDto } from './dtos/update-folder-dto'; import { isFoldersContainRoot } from './utils/folders'; +import { Folder } from '../entities/folder'; +import { prisma } from '../utils/prisma'; -export default class FolderService { +export class FolderService { async createUserRootFolder(dto: CreateUserRootFolderDto): Promise { const input = dto.toFolder(); - return dbClient.folder.create({ + return prisma.folder.create({ data: { id: input.id, name: input.name, @@ -35,7 +36,7 @@ export default class FolderService { const parentFolder = await this.findById(createFolderDto.parentFolderId); - return dbClient.folder.create({ + return prisma.folder.create({ data: { id: input.id, name: input.name, @@ -47,11 +48,11 @@ export default class FolderService { } async findUserFolders(userId: string): Promise { - return dbClient.folder.findMany({ orderBy: { name: 'asc' }, where: { userId } }); + return prisma.folder.findMany({ orderBy: { name: 'asc' }, where: { userId } }); } async findById(id: string): Promise { - const folder = await dbClient.folder.findUnique({ where: { id } }); + const folder = await prisma.folder.findUnique({ where: { id } }); if (!folder) { throw new SnipcodeError(errors.FOLDER_NOT_FOUND(id), 'FOLDER_NOT_FOUND'); @@ -83,7 +84,7 @@ export default class FolderService { } async deleteMany(folderIds: string[], userId: string): Promise { - const foldersToDelete = await dbClient.folder.findMany({ + const foldersToDelete = await prisma.folder.findMany({ where: { id: { in: folderIds, @@ -98,7 +99,7 @@ export default class FolderService { const ids = foldersToDelete.map((folder) => folder.id); - await dbClient.folder.deleteMany({ + await prisma.folder.deleteMany({ where: { id: { in: ids, @@ -116,7 +117,7 @@ export default class FolderService { return []; } - const parentFoldersOrdered = await dbClient.folder.findMany({ + const parentFoldersOrdered = await prisma.folder.findMany({ orderBy: { createdAt: 'asc', }, @@ -156,7 +157,7 @@ export default class FolderService { const input = updateFolderDto.toFolder(folder); - return dbClient.folder.update({ + return prisma.folder.update({ data: { name: input.name, }, @@ -175,7 +176,7 @@ export default class FolderService { } private findFolderSubFolders(folderId: string, userId: string): Promise { - return dbClient.folder.findMany({ + return prisma.folder.findMany({ where: { parentId: folderId, userId, diff --git a/packages/domain/__tests__/services/folders/utils/folders.test.ts b/packages/domain/src/folders/utils/folders.test.ts similarity index 81% rename from packages/domain/__tests__/services/folders/utils/folders.test.ts rename to packages/domain/src/folders/utils/folders.test.ts index 384720c3..0ea1c133 100644 --- a/packages/domain/__tests__/services/folders/utils/folders.test.ts +++ b/packages/domain/src/folders/utils/folders.test.ts @@ -1,7 +1,6 @@ -import { Folder } from '@snipcode/database'; - -import { isFoldersContainRoot } from '../../../../src/folders/utils/folders'; -import { createTestFolderDto, generateTestId } from '../../../setup/test-utils'; +import { isFoldersContainRoot } from './folders'; +import { createTestFolderDto, generateTestId } from '../../../tests/helpers'; +import { Folder } from '../../entities/folder'; describe('Test folders utilities', () => { it('should assert the folders contain the root folder', () => { diff --git a/packages/domain/src/folders/utils/folders.ts b/packages/domain/src/folders/utils/folders.ts index 3afe9604..f21da7a0 100644 --- a/packages/domain/src/folders/utils/folders.ts +++ b/packages/domain/src/folders/utils/folders.ts @@ -1,4 +1,4 @@ -import { Folder } from '@snipcode/database'; +import { Folder } from '../../entities/folder'; export const isFoldersContainRoot = (folders: Folder[]): boolean => { return folders.some((folder) => folder.parentId === null); diff --git a/packages/domain/__tests__/services/newsletters/newsletter.service.test.ts b/packages/domain/src/newsletters/newsletter.service.test.ts similarity index 87% rename from packages/domain/__tests__/services/newsletters/newsletter.service.test.ts rename to packages/domain/src/newsletters/newsletter.service.test.ts index 0a48327d..5f778f5b 100644 --- a/packages/domain/__tests__/services/newsletters/newsletter.service.test.ts +++ b/packages/domain/src/newsletters/newsletter.service.test.ts @@ -1,7 +1,7 @@ import SnipcodeError from '@snipcode/utils'; import nock from 'nock'; -import NewsletterService from '../../../src/newsletters/newsletter.service'; +import { NewsletterService } from './newsletter.service'; const newsletterService = new NewsletterService({ apiKey: 'apiKey', @@ -56,7 +56,7 @@ describe('Test the newsletter service', () => { // WHEN // THEN - const catchErrorsFormatted = { + const caughtErrorsFormatted = { data: { message: 'Wrong api key provided!', }, @@ -66,7 +66,9 @@ describe('Test the newsletter service', () => { await expect(async () => { await newsletterService.subscribe(emailToSubscribe, tags); - }).rejects.toThrow(new SnipcodeError(JSON.stringify(catchErrorsFormatted, null, 2), 'NEWSLETTER_SUBSCRIBE_FAILED')); + }).rejects.toThrow( + new SnipcodeError(JSON.stringify(caughtErrorsFormatted, null, 2), 'NEWSLETTER_SUBSCRIBE_FAILED'), + ); nock.cleanAll(); }); diff --git a/packages/domain/src/newsletters/newsletter.service.ts b/packages/domain/src/newsletters/newsletter.service.ts index a032d868..ba0a42f0 100644 --- a/packages/domain/src/newsletters/newsletter.service.ts +++ b/packages/domain/src/newsletters/newsletter.service.ts @@ -1,9 +1,9 @@ import axios, { AxiosInstance } from 'axios'; -import { handleRequestError } from '../utils/axios-error'; import { NewsletterOption, SubscribeData, SubscribeInput } from './types'; +import { handleRequestError } from '../utils/axios-error'; -export default class NewsletterService { +export class NewsletterService { private httpClient: AxiosInstance = axios.create(); private readonly options: NewsletterOption; diff --git a/packages/domain/__tests__/services/roles/dtos/create-role-dto.test.ts b/packages/domain/src/roles/dtos/create-role-dto.test.ts similarity index 83% rename from packages/domain/__tests__/services/roles/dtos/create-role-dto.test.ts rename to packages/domain/src/roles/dtos/create-role-dto.test.ts index a04259f6..28a84fbc 100644 --- a/packages/domain/__tests__/services/roles/dtos/create-role-dto.test.ts +++ b/packages/domain/src/roles/dtos/create-role-dto.test.ts @@ -1,6 +1,5 @@ -import { Role } from '@snipcode/database'; - -import { CreateRoleDto } from '../../../../index'; +import { CreateRoleDto } from './create-role-dto'; +import { Role } from '../../entities/role'; describe('Test Create Role DTO', () => { it('should return a valid role object', () => { diff --git a/packages/domain/src/roles/dtos/create-role-dto.ts b/packages/domain/src/roles/dtos/create-role-dto.ts index faa09e36..61dee7c4 100644 --- a/packages/domain/src/roles/dtos/create-role-dto.ts +++ b/packages/domain/src/roles/dtos/create-role-dto.ts @@ -1,4 +1,5 @@ -import { Role, RoleName, dbId } from '@snipcode/database'; +import { Role, RoleName } from '../../entities/role'; +import { dbID } from '../../utils/id'; type Input = { description: string | null; @@ -6,11 +7,11 @@ type Input = { name: RoleName; }; -export default class CreateRoleDto { +export class CreateRoleDto { private readonly roleId: string; constructor(private _input: Input) { - this.roleId = dbId.generate(); + this.roleId = dbID.generate(); } get name(): RoleName { diff --git a/packages/domain/src/roles/role.service.ts b/packages/domain/src/roles/role.service.ts index 860ec117..d7d7ddbe 100644 --- a/packages/domain/src/roles/role.service.ts +++ b/packages/domain/src/roles/role.service.ts @@ -1,9 +1,10 @@ -import { Role, RoleName, dbClient } from '@snipcode/database'; import SnipcodeError, { errors } from '@snipcode/utils'; -import CreateRoleDto from './dtos/create-role-dto'; +import { CreateRoleDto } from './dtos/create-role-dto'; +import { Role, RoleName } from '../entities/role'; +import { prisma } from '../utils/prisma'; -export default class RoleService { +export class RoleService { async loadRoles(): Promise { const roleAdminDto = new CreateRoleDto({ description: 'can do everything in the application', @@ -13,12 +14,12 @@ export default class RoleService { const roleUserDto = new CreateRoleDto({ description: "can't do everything", level: 100, name: 'user' }); const promises = [roleAdminDto, roleUserDto].map(async (roleDto) => { - const role = await dbClient.role.findUnique({ where: { name: roleDto.name } }); + const role = await prisma.role.findUnique({ where: { name: roleDto.name } }); if (!role) { const input = roleDto.toRole(); - return dbClient.role.create({ + return prisma.role.create({ data: { description: input.description, id: input.id, @@ -35,7 +36,7 @@ export default class RoleService { } async findByName(name: RoleName): Promise { - const role = await dbClient.role.findUnique({ where: { name } }); + const role = await prisma.role.findUnique({ where: { name } }); if (!role) { throw new SnipcodeError(errors.ROLE_USER_NOT_FOUND, 'ROLE_USER_NOT_FOUND'); @@ -45,10 +46,10 @@ export default class RoleService { } async findById(id: string): Promise { - return dbClient.role.findUnique({ where: { id } }); + return prisma.role.findUnique({ where: { id } }); } async findAll(): Promise { - return dbClient.role.findMany({ orderBy: { level: 'desc' } }); + return prisma.role.findMany({ orderBy: { level: 'desc' } }); } } diff --git a/packages/domain/__tests__/services/sessions/dtos/create-session-dto.test.ts b/packages/domain/src/sessions/dtos/create-session-dto.test.ts similarity index 76% rename from packages/domain/__tests__/services/sessions/dtos/create-session-dto.test.ts rename to packages/domain/src/sessions/dtos/create-session-dto.test.ts index 7d7424f2..4958db78 100644 --- a/packages/domain/__tests__/services/sessions/dtos/create-session-dto.test.ts +++ b/packages/domain/src/sessions/dtos/create-session-dto.test.ts @@ -1,8 +1,8 @@ -import { Session } from '@snipcode/database'; import { isValidUUIDV4 } from '@snipcode/utils'; -import { CreateSessionDto } from '../../../../index'; -import { generateTestId } from '../../../setup/test-utils'; +import { CreateSessionDto } from './create-session-dto'; +import { generateTestId } from '../../../tests/helpers'; +import { Session } from '../../entities/session'; describe('Test Create Session DTO', () => { it('should return a valid role object', () => { diff --git a/packages/domain/src/sessions/dtos/create-session-dto.ts b/packages/domain/src/sessions/dtos/create-session-dto.ts index 87054758..1202414f 100644 --- a/packages/domain/src/sessions/dtos/create-session-dto.ts +++ b/packages/domain/src/sessions/dtos/create-session-dto.ts @@ -1,17 +1,19 @@ -import { Session, dbId } from '@snipcode/database'; import { generateRandomId } from '@snipcode/utils'; +import { Session } from '../../entities/session'; +import { dbID } from '../../utils/id'; + type Input = { expireDate: Date; userId: string; }; -export default class CreateSessionDto { +export class CreateSessionDto { private readonly sessionId: string; private readonly token: string; constructor(private _input: Input) { - this.sessionId = dbId.generate(); + this.sessionId = dbID.generate(); this.token = generateRandomId(); } diff --git a/packages/domain/__tests__/services/sessions/session.service.test.ts b/packages/domain/src/sessions/session.service.test.ts similarity index 83% rename from packages/domain/__tests__/services/sessions/session.service.test.ts rename to packages/domain/src/sessions/session.service.test.ts index f2f20b9b..d784f4f4 100644 --- a/packages/domain/__tests__/services/sessions/session.service.test.ts +++ b/packages/domain/src/sessions/session.service.test.ts @@ -1,12 +1,8 @@ -import { Session } from '@snipcode/database'; - -import { sessionService } from '../../../index'; -import { - createTestSession, - createTestSessionDto, - deleteTestUserSessions, - generateTestId, -} from '../../setup/test-utils'; +import { SessionService } from './session.service'; +import { createTestSession, createTestSessionDto, deleteTestUserSessions, generateTestId } from '../../tests/helpers'; +import { Session } from '../entities/session'; + +const sessionService = new SessionService(); describe('Test Session Service', function () { it('should create a session', async () => { diff --git a/packages/domain/src/sessions/session.service.ts b/packages/domain/src/sessions/session.service.ts index 0494da49..07ad3182 100644 --- a/packages/domain/src/sessions/session.service.ts +++ b/packages/domain/src/sessions/session.service.ts @@ -1,12 +1,12 @@ -import { Session, dbClient } from '@snipcode/database'; +import { CreateSessionDto } from './dtos/create-session-dto'; +import { Session } from '../entities/session'; +import { prisma } from '../utils/prisma'; -import CreateSessionDto from './dtos/create-session-dto'; - -export default class SessionService { +export class SessionService { async create(createSessionDto: CreateSessionDto): Promise { const input = createSessionDto.toSession(); - return dbClient.session.create({ + return prisma.session.create({ data: { expires: input.expires, id: input.id, @@ -17,10 +17,10 @@ export default class SessionService { } async deleteUserSessions(userId: string): Promise { - await dbClient.session.deleteMany({ where: { userId } }); + await prisma.session.deleteMany({ where: { userId } }); } async findByToken(token: string): Promise { - return dbClient.session.findUnique({ where: { token } }); + return prisma.session.findUnique({ where: { token } }); } } diff --git a/packages/domain/__tests__/services/snippets/dtos/create-snippet-dto.test.ts b/packages/domain/src/snippets/dtos/create-snippet-dto.test.ts similarity index 85% rename from packages/domain/__tests__/services/snippets/dtos/create-snippet-dto.test.ts rename to packages/domain/src/snippets/dtos/create-snippet-dto.test.ts index 8f01de92..3623e828 100644 --- a/packages/domain/__tests__/services/snippets/dtos/create-snippet-dto.test.ts +++ b/packages/domain/src/snippets/dtos/create-snippet-dto.test.ts @@ -1,7 +1,6 @@ -import { Snippet } from '@snipcode/database'; - -import CreateSessionDto from '../../../../src/snippets/dtos/create-snippet-dto'; -import { generateTestId } from '../../../setup/test-utils'; +import { CreateSnippetDto } from './create-snippet-dto'; +import { generateTestId } from '../../../tests/helpers'; +import { Snippet } from '../../entities/snippet'; describe('Test Create Snippet DTO', () => { it('should return a valid snippet', () => { @@ -9,7 +8,7 @@ describe('Test Create Snippet DTO', () => { const userId = generateTestId(); // GIVEN - const dto = new CreateSessionDto({ + const dto = new CreateSnippetDto({ content: 'import React from "react";\n\nexport const App = () => {\n\n\treturn(\n\t\t
Hello
\n\t);\n};', contentHighlighted: 'import React from "react";\n\nexport const App = () => {\n\n\treturn(\n\t\t
Hello
\n\t);\n}; highlighted', diff --git a/packages/domain/src/snippets/dtos/create-snippet-dto.ts b/packages/domain/src/snippets/dtos/create-snippet-dto.ts index 63fcab32..05a12182 100644 --- a/packages/domain/src/snippets/dtos/create-snippet-dto.ts +++ b/packages/domain/src/snippets/dtos/create-snippet-dto.ts @@ -1,4 +1,5 @@ -import { Snippet, SnippetVisibility, dbId } from '@snipcode/database'; +import { Snippet, SnippetVisibility } from '../../entities/snippet'; +import { dbID } from '../../utils/id'; type Input = { content: string; @@ -13,11 +14,11 @@ type Input = { visibility: SnippetVisibility; }; -export default class CreateSnippetDto { +export class CreateSnippetDto { private readonly snippetId: string; constructor(private _input: Input) { - this.snippetId = dbId.generate(); + this.snippetId = dbID.generate(); } get folderId(): string { diff --git a/packages/domain/__tests__/services/snippets/dtos/delete-snippet-dto.test.ts b/packages/domain/src/snippets/dtos/delete-snippet-dto.test.ts similarity index 74% rename from packages/domain/__tests__/services/snippets/dtos/delete-snippet-dto.test.ts rename to packages/domain/src/snippets/dtos/delete-snippet-dto.test.ts index 0cd07441..16ea4597 100644 --- a/packages/domain/__tests__/services/snippets/dtos/delete-snippet-dto.test.ts +++ b/packages/domain/src/snippets/dtos/delete-snippet-dto.test.ts @@ -1,5 +1,5 @@ -import DeleteSnippetDto from '../../../../src/snippets/dtos/delete-snippet-dto'; -import { generateTestId } from '../../../setup/test-utils'; +import { DeleteSnippetDto } from './delete-snippet-dto'; +import { generateTestId } from '../../../tests/helpers'; describe('Test Delete Snippet DTO', () => { it('should have the right property defined', () => { diff --git a/packages/domain/src/snippets/dtos/delete-snippet-dto.ts b/packages/domain/src/snippets/dtos/delete-snippet-dto.ts index af31d31a..1d7f38c6 100644 --- a/packages/domain/src/snippets/dtos/delete-snippet-dto.ts +++ b/packages/domain/src/snippets/dtos/delete-snippet-dto.ts @@ -3,7 +3,7 @@ type Input = { snippetId: string; }; -export default class DeleteSnippetDto { +export class DeleteSnippetDto { constructor(private _input: Input) {} get snippetId(): string { diff --git a/packages/domain/__tests__/services/snippets/dtos/update-snippet-dto.test.ts b/packages/domain/src/snippets/dtos/update-snippet-dto.test.ts similarity index 90% rename from packages/domain/__tests__/services/snippets/dtos/update-snippet-dto.test.ts rename to packages/domain/src/snippets/dtos/update-snippet-dto.test.ts index cbfde05c..9f37be3e 100644 --- a/packages/domain/__tests__/services/snippets/dtos/update-snippet-dto.test.ts +++ b/packages/domain/src/snippets/dtos/update-snippet-dto.test.ts @@ -1,7 +1,6 @@ -import { Snippet } from '@snipcode/database'; - -import { UpdateSnippetDto } from '../../../../index'; -import { createTestSnippetDto, generateTestId } from '../../../setup/test-utils'; +import { UpdateSnippetDto } from './update-snippet-dto'; +import { createTestSnippetDto, generateTestId } from '../../../tests/helpers'; +import { Snippet } from '../../entities/snippet'; describe('Test Update Snippet DTO', () => { it('should have the right property defined to update the snippet', () => { diff --git a/packages/domain/src/snippets/dtos/update-snippet-dto.ts b/packages/domain/src/snippets/dtos/update-snippet-dto.ts index 5849eaf1..466cba2f 100644 --- a/packages/domain/src/snippets/dtos/update-snippet-dto.ts +++ b/packages/domain/src/snippets/dtos/update-snippet-dto.ts @@ -1,4 +1,4 @@ -import { Snippet, SnippetVisibility } from '@snipcode/database'; +import { Snippet, SnippetVisibility } from '../../entities/snippet'; type Input = { content: string; @@ -13,7 +13,7 @@ type Input = { visibility: SnippetVisibility; }; -export default class UpdateSnippetDto { +export class UpdateSnippetDto { constructor(private _input: Input) {} get name(): string { diff --git a/packages/domain/__tests__/services/snippets/snippet.service.test.ts b/packages/domain/src/snippets/snippet.service.test.ts similarity index 97% rename from packages/domain/__tests__/services/snippets/snippet.service.test.ts rename to packages/domain/src/snippets/snippet.service.test.ts index bb98e62d..db811a00 100644 --- a/packages/domain/__tests__/services/snippets/snippet.service.test.ts +++ b/packages/domain/src/snippets/snippet.service.test.ts @@ -1,7 +1,6 @@ -import { Snippet } from '@snipcode/database'; import SnipcodeError, { errors, generateRandomId } from '@snipcode/utils'; -import { roleService, snippetService } from '../../../index'; +import { SnippetService } from './snippet.service'; import { createTestSnippet, createTestSnippetDto, @@ -11,7 +10,12 @@ import { deleteTestSnippetsById, deleteTestUsersById, updateTestSnippetDto, -} from '../../setup/test-utils'; +} from '../../tests/helpers'; +import { Snippet } from '../entities/snippet'; +import { RoleService } from '../roles/role.service'; + +const snippetService = new SnippetService(); +const roleService = new RoleService(); describe('Test Snippet service', () => { beforeAll(async () => { diff --git a/packages/domain/src/snippets/snippet.service.ts b/packages/domain/src/snippets/snippet.service.ts index 30338ced..9932ac98 100644 --- a/packages/domain/src/snippets/snippet.service.ts +++ b/packages/domain/src/snippets/snippet.service.ts @@ -1,9 +1,10 @@ -import { Snippet, SnippetVisibility, dbClient } from '@snipcode/database'; import SnipcodeError, { errors } from '@snipcode/utils'; -import CreateSnippetDto from './dtos/create-snippet-dto'; -import DeleteSnippetDto from './dtos/delete-snippet-dto'; -import UpdateSnippetDto from './dtos/update-snippet-dto'; +import { CreateSnippetDto } from './dtos/create-snippet-dto'; +import { DeleteSnippetDto } from './dtos/delete-snippet-dto'; +import { UpdateSnippetDto } from './dtos/update-snippet-dto'; +import { Snippet, SnippetVisibility } from '../entities/snippet'; +import { prisma } from '../utils/prisma'; const MAX_ITEM_PER_PAGE = 50; @@ -12,7 +13,7 @@ const sortMethodMap: Record<'recently_updated' | 'recently_created', 'createdAt' recently_updated: 'updatedAt', }; -export default class SnippetService { +export class SnippetService { async create(createSnippetDto: CreateSnippetDto): Promise { const isSnippetExist = await this.isSnippetExistInFolder(createSnippetDto.folderId, createSnippetDto.name); @@ -22,7 +23,7 @@ export default class SnippetService { const input = createSnippetDto.toSnippet(); - return dbClient.snippet.create({ + return prisma.snippet.create({ data: { content: input.content, contentHtml: input.contentHtml, @@ -41,7 +42,7 @@ export default class SnippetService { } async findById(id: string): Promise { - const snippet = await dbClient.snippet.findUnique({ where: { id } }); + const snippet = await prisma.snippet.findUnique({ where: { id } }); if (!snippet) { throw new SnipcodeError(errors.SNIPPET_NOT_FOUND(id), 'SNIPPET_NOT_FOUND'); @@ -51,11 +52,11 @@ export default class SnippetService { } async findByUser(userId: string): Promise { - return dbClient.snippet.findMany({ orderBy: { createdAt: 'desc' }, where: { userId } }); + return prisma.snippet.findMany({ orderBy: { createdAt: 'desc' }, where: { userId } }); } async findByFolder(folderId: string, visibility?: SnippetVisibility): Promise { - return dbClient.snippet.findMany({ + return prisma.snippet.findMany({ orderBy: { createdAt: 'desc' }, where: { folderId, @@ -77,7 +78,7 @@ export default class SnippetService { // If the use has 20 we fetch 21 which help to know if there still more in the table const limitPlusOne = limit + 1; - const snippets = await dbClient.snippet.findMany({ + const snippets = await prisma.snippet.findMany({ orderBy: { [sortMethodMap[sortMethod]]: 'desc' }, take: limitPlusOne, where: { @@ -108,7 +109,7 @@ export default class SnippetService { throw new SnipcodeError(errors.CANT_EDIT_SNIPPET(deleteSnippetDto.creatorId, snippet.id), 'CANT_EDIT_SNIPPET'); } - await dbClient.snippet.delete({ where: { id: deleteSnippetDto.snippetId } }); + await prisma.snippet.delete({ where: { id: deleteSnippetDto.snippetId } }); } async isSnippetExistInFolder(folderId: string, snippetName: string): Promise { @@ -134,7 +135,7 @@ export default class SnippetService { const input = updateSnippetDto.toSnippet(snippet); - return dbClient.snippet.update({ + return prisma.snippet.update({ data: { content: input.content, contentHtml: input.contentHtml, diff --git a/packages/domain/__tests__/services/users/dtos/create-user-dto.test.ts b/packages/domain/src/users/dtos/create-user-dto.test.ts similarity index 94% rename from packages/domain/__tests__/services/users/dtos/create-user-dto.test.ts rename to packages/domain/src/users/dtos/create-user-dto.test.ts index 7d4701f4..81067f50 100644 --- a/packages/domain/__tests__/services/users/dtos/create-user-dto.test.ts +++ b/packages/domain/src/users/dtos/create-user-dto.test.ts @@ -1,6 +1,5 @@ -import { User } from '@snipcode/database'; - -import { CreateUserDto } from '../../../../index'; +import { CreateUserDto } from './create-user-dto'; +import { User } from '../../entities/user'; describe('Test Create User DTO', () => { it('should return a valid user object without password', () => { diff --git a/packages/domain/src/users/dtos/create-user-dto.ts b/packages/domain/src/users/dtos/create-user-dto.ts index bda46066..96d4ff62 100644 --- a/packages/domain/src/users/dtos/create-user-dto.ts +++ b/packages/domain/src/users/dtos/create-user-dto.ts @@ -1,6 +1,6 @@ -import { OauthProvider, User, dbId } from '@snipcode/database'; - +import { OauthProvider, User } from '../../entities/user'; import { hashPassword } from '../../utils/helpers'; +import { dbID } from '../../utils/id'; type Input = { email: string; @@ -13,14 +13,14 @@ type Input = { username: string | null; }; -export default class CreateUserDto { +export class CreateUserDto { readonly hashedPassword: string | null; private readonly userId: string; private enabled = false; constructor(private _input: Input) { - this.userId = dbId.generate(); + this.userId = dbID.generate(); this.hashedPassword = this._input.password ? hashPassword(this._input.password) : null; } diff --git a/packages/domain/__tests__/services/users/dtos/update-user-dto.test.ts b/packages/domain/src/users/dtos/update-user-dto.test.ts similarity index 91% rename from packages/domain/__tests__/services/users/dtos/update-user-dto.test.ts rename to packages/domain/src/users/dtos/update-user-dto.test.ts index c42c6f4f..06a662e9 100644 --- a/packages/domain/__tests__/services/users/dtos/update-user-dto.test.ts +++ b/packages/domain/src/users/dtos/update-user-dto.test.ts @@ -1,7 +1,6 @@ -import { User } from '@snipcode/database'; - -import { UpdateUserDto } from '../../../../index'; -import { createTestUserDto, generateTestId } from '../../../setup/test-utils'; +import { UpdateUserDto } from './update-user-dto'; +import { createTestUserDto, generateTestId } from '../../../tests/helpers'; +import { User } from '../../entities/user'; describe('Test Update User DTO', () => { it('should return the user to update', () => { diff --git a/packages/domain/src/users/dtos/update-user-dto.ts b/packages/domain/src/users/dtos/update-user-dto.ts index 50a62ae3..135f2745 100644 --- a/packages/domain/src/users/dtos/update-user-dto.ts +++ b/packages/domain/src/users/dtos/update-user-dto.ts @@ -1,4 +1,4 @@ -import { OauthProvider, User } from '@snipcode/database'; +import { OauthProvider, User } from '../../entities/user'; type Input = { name: string; @@ -8,7 +8,7 @@ type Input = { timezone: string | null; }; -export default class UpdateUserDto { +export class UpdateUserDto { private enabled = false; constructor(private _input: Input) {} diff --git a/packages/domain/__tests__/services/users/user.service.test.ts b/packages/domain/src/users/user.service.test.ts similarity index 96% rename from packages/domain/__tests__/services/users/user.service.test.ts rename to packages/domain/src/users/user.service.test.ts index cdbc3be0..3bb4c988 100644 --- a/packages/domain/__tests__/services/users/user.service.test.ts +++ b/packages/domain/src/users/user.service.test.ts @@ -1,14 +1,18 @@ -import { User } from '@snipcode/database'; import SnipcodeError, { errors, generateRandomId } from '@snipcode/utils'; -import { roleService, userService } from '../../../index'; +import { UserService } from './user.service'; import { createTestUser, createTestUserDto, deleteTestUsersById, findTestRole, updateTestUserDto, -} from '../../setup/test-utils'; +} from '../../tests/helpers'; +import { User } from '../entities/user'; +import { RoleService } from '../roles/role.service'; + +const roleService = new RoleService(); +const userService = new UserService(); describe('Test User service', () => { beforeAll(async () => { diff --git a/packages/domain/src/users/user.service.ts b/packages/domain/src/users/user.service.ts index 1af3d7f8..9ff2440b 100644 --- a/packages/domain/src/users/user.service.ts +++ b/packages/domain/src/users/user.service.ts @@ -1,13 +1,15 @@ -import { Role, User, dbClient } from '@snipcode/database'; import SnipcodeError, { errors } from '@snipcode/utils'; import bcrypt from 'bcryptjs'; import { generateFromEmail } from 'unique-username-generator'; -import CreateUserRootFolderDto from '../folders/dtos/create-user-root-folder-dto'; -import CreateUserDto from './dtos/create-user-dto'; -import UpdateUserDto from './dtos/update-user-dto'; +import { CreateUserDto } from './dtos/create-user-dto'; +import { UpdateUserDto } from './dtos/update-user-dto'; +import { Role } from '../entities/role'; +import { User } from '../entities/user'; +import { CreateUserRootFolderDto } from '../folders/dtos/create-user-root-folder-dto'; +import { prisma } from '../utils/prisma'; -export default class UserService { +export class UserService { async create(createUserDto: CreateUserDto): Promise { const user = await this.findByEmail(createUserDto.email); @@ -21,7 +23,7 @@ export default class UserService { const input = createUserDto.toUser(); - return dbClient.user.create({ + return prisma.user.create({ data: { email: input.email, id: input.id, @@ -40,7 +42,7 @@ export default class UserService { async update(currentUser: User, updateUserDto: UpdateUserDto): Promise { const input = updateUserDto.toUser(currentUser); - return dbClient.user.update({ + return prisma.user.update({ data: { isEnabled: input.isEnabled, name: input.name, @@ -76,7 +78,7 @@ export default class UserService { const userInput = userAdminDto.toUser(); - const user = await dbClient.user.create({ + const user = await prisma.user.create({ data: { email: userInput.email, id: userInput.id, @@ -95,7 +97,7 @@ export default class UserService { const folderInput = createUserRootFolderDto.toFolder(); - await dbClient.folder.create({ + await prisma.folder.create({ data: { id: folderInput.id, name: folderInput.name, @@ -106,11 +108,11 @@ export default class UserService { } async findByEmail(email: string): Promise { - return dbClient.user.findUnique({ where: { email } }); + return prisma.user.findUnique({ where: { email } }); } async findById(id: string): Promise { - return dbClient.user.findUnique({ where: { id } }); + return prisma.user.findUnique({ where: { id } }); } async login(email: string, password: string): Promise { @@ -138,7 +140,7 @@ export default class UserService { return generateFromEmail(email, 3); } - const user = await dbClient.user.findFirst({ + const user = await prisma.user.findFirst({ where: { username, }, diff --git a/packages/domain/src/utils/id.test.ts b/packages/domain/src/utils/id.test.ts new file mode 100644 index 00000000..4c71c268 --- /dev/null +++ b/packages/domain/src/utils/id.test.ts @@ -0,0 +1,17 @@ +import { dbID } from './id'; + +describe('Test Database ID generator', () => { + test('generate a valid id', () => { + const id = dbID.generate(); + + expect(dbID.isValid(id)).toEqual(true); + }); + + test.each([ + ['myinvalidid', false], + ['111111111111', false], + ['cl1fny73o0000e7czbglkhv0p', true], + ])('detect validity of id %s', (id, expected) => { + expect(dbID.isValid(id)).toEqual(expected); + }); +}); diff --git a/packages/domain/src/utils/id.ts b/packages/domain/src/utils/id.ts new file mode 100644 index 00000000..daa27d46 --- /dev/null +++ b/packages/domain/src/utils/id.ts @@ -0,0 +1,6 @@ +import cuid, { isCuid } from '@bugsnag/cuid'; + +export const dbID = { + generate: () => cuid(), + isValid: (id: string) => isCuid(id), +}; diff --git a/packages/database/src/prisma.ts b/packages/domain/src/utils/prisma.ts similarity index 52% rename from packages/database/src/prisma.ts rename to packages/domain/src/utils/prisma.ts index 3a8009f6..eef71154 100644 --- a/packages/database/src/prisma.ts +++ b/packages/domain/src/utils/prisma.ts @@ -8,14 +8,20 @@ declare global { let prisma: PrismaClient; if (process.env.NODE_ENV === 'production') { - prisma = new PrismaClient({ log: ['query'] }); + prisma = new PrismaClient(); } else { if (!global.prisma) { - global.prisma = new PrismaClient(); + global.prisma = new PrismaClient({ + datasources: { + db: { + url: process.env.NODE_ENV === 'test' ? process.env.TEST_DATABASE_URL : process.env.DATABASE_URL, + }, + }, + // log: ['query'], + }); } // eslint-disable-next-line prefer-destructuring prisma = global.prisma; } -export { Prisma, PrismaClient }; -export default prisma; +export { Prisma, PrismaClient, prisma }; diff --git a/packages/domain/tests/database.mjs b/packages/domain/tests/database.mjs new file mode 100755 index 00000000..17f7cf0e --- /dev/null +++ b/packages/domain/tests/database.mjs @@ -0,0 +1,25 @@ +#!/usr/bin/env zx + +import { $, sleep } from 'zx'; + +const MYSQL_DATABASE = 'snipcode'; +const CONTAINER_NAME = 'snipcode-test-db'; + +if (!process.env.CI) { + console.log('Create the test database if necessary'); + + try { + await $`docker ps | grep ${CONTAINER_NAME}`; + } catch (error) { + // Container not found, creating a new one. + await $`docker run -d --rm --name ${CONTAINER_NAME} -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=${MYSQL_DATABASE} -p 3313:3306 mysql:8.0.34`; + + await sleep(9000); // Wait for 9 seconds the container to initialize + } + + process.env.DATABASE_URL = `mysql://root:secret@127.0.0.1:3313/${MYSQL_DATABASE}`; + + // Reset database and apply all migrations + await $`yarn prisma migrate reset --force`; +} + diff --git a/packages/domain/__tests__/setup/test-utils.ts b/packages/domain/tests/helpers.ts similarity index 91% rename from packages/domain/__tests__/setup/test-utils.ts rename to packages/domain/tests/helpers.ts index 78be564b..286f99b1 100644 --- a/packages/domain/__tests__/setup/test-utils.ts +++ b/packages/domain/tests/helpers.ts @@ -1,4 +1,5 @@ import { randEmail, randFullName, randImg, randNumber, randTimeZone, randUserName, randWord } from '@ngneat/falso'; + import { Folder, OauthProvider, @@ -9,18 +10,17 @@ import { SnippetVisibility, User, dbClient, - dbId, -} from '@snipcode/database'; - -import { CreateUserDto } from '../../index'; -import CreateFolderDto from '../../src/folders/dtos/create-folder-dto'; -import CreateUserRootFolderDto from '../../src/folders/dtos/create-user-root-folder-dto'; -import UpdateFolderDto from '../../src/folders/dtos/update-folder-dto'; -import CreateSessionDto from '../../src/sessions/dtos/create-session-dto'; -import CreateSnippetDto from '../../src/snippets/dtos/create-snippet-dto'; -import DeleteSnippetDto from '../../src/snippets/dtos/delete-snippet-dto'; -import UpdateSnippetDto from '../../src/snippets/dtos/update-snippet-dto'; -import UpdateUserDto from '../../src/users/dtos/update-user-dto'; + dbID, +} from '../index'; +import { CreateFolderDto } from '../src/folders/dtos/create-folder-dto'; +import { CreateUserRootFolderDto } from '../src/folders/dtos/create-user-root-folder-dto'; +import { UpdateFolderDto } from '../src/folders/dtos/update-folder-dto'; +import { CreateSessionDto } from '../src/sessions/dtos/create-session-dto'; +import { CreateSnippetDto } from '../src/snippets/dtos/create-snippet-dto'; +import { DeleteSnippetDto } from '../src/snippets/dtos/delete-snippet-dto'; +import { UpdateSnippetDto } from '../src/snippets/dtos/update-snippet-dto'; +import { CreateUserDto } from '../src/users/dtos/create-user-dto'; +import { UpdateUserDto } from '../src/users/dtos/update-user-dto'; type CreateManyTestFoldersArgs = { folderNames: string[]; @@ -143,7 +143,7 @@ export const createManyTestFolders = async ({ return Promise.all(promises); }; -export const generateTestId = (): string => dbId.generate(); +export const generateTestId = (): string => dbID.generate(); export const createTestFolderDto = (args?: { name?: string; parentId?: string; userId?: string }): CreateFolderDto => { return new CreateFolderDto({ diff --git a/packages/domain/tsconfig.json b/packages/domain/tsconfig.json index 98d309cf..450fe1ec 100644 --- a/packages/domain/tsconfig.json +++ b/packages/domain/tsconfig.json @@ -7,14 +7,11 @@ "sourceMap": true }, "files": ["env.d.ts"], - "include": ["src", "__tests__", "index.ts"], + "include": ["src", "tests", "index.ts"], "exclude": [ "node_modules" ], "references": [ - { - "path": "../../packages/database" - }, { "path": "../../packages/utils" } diff --git a/packages/domain/tsconfig.prod.json b/packages/domain/tsconfig.prod.json index e8c5afe2..fd20e465 100644 --- a/packages/domain/tsconfig.prod.json +++ b/packages/domain/tsconfig.prod.json @@ -4,6 +4,7 @@ "sourceMap": false }, "exclude": [ - "__tests__" + "tests", + "**/*.test.ts" ] } diff --git a/packages/embed/package.json b/packages/embed/package.json index 7eef4f25..92a5a47a 100644 --- a/packages/embed/package.json +++ b/packages/embed/package.json @@ -19,7 +19,6 @@ "test": "jest" }, "devDependencies": { - "@snipcode/database": "workspace:*", "@types/express": "4.17.21", "express": "4.19.1", "nodemon": "2.0.22", diff --git a/yarn.lock b/yarn.lock index 2aa6c764..62f5842e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1668,6 +1668,13 @@ __metadata: languageName: node linkType: hard +"@bugsnag/cuid@npm:3.1.1": + version: 3.1.1 + resolution: "@bugsnag/cuid@npm:3.1.1" + checksum: 10/7a556bd8a166079e71872244c13f206a7d7e08b47ffa06bb712c04897144ab776ba25aaa63ea8b8e8cf7b3e973d41982bd6ac5d3544af9c988f4ef96bc86f6a3 + languageName: node + linkType: hard + "@changesets/apply-release-plan@npm:^7.0.0": version: 7.0.0 resolution: "@changesets/apply-release-plan@npm:7.0.0" @@ -4206,15 +4213,15 @@ __metadata: languageName: node linkType: hard -"@prisma/client@npm:5.11.0": - version: 5.11.0 - resolution: "@prisma/client@npm:5.11.0" +"@prisma/client@npm:5.14.0": + version: 5.14.0 + resolution: "@prisma/client@npm:5.14.0" peerDependencies: prisma: "*" peerDependenciesMeta: prisma: optional: true - checksum: 10/f59ef5a762f0fe82a6507f0f7a3b522bc25d85fd61ea85b68c221708c5742979e23783deb90816f1a1d7a1365061e69ad067bf44a7e78006a2bf04d0c236d66d + checksum: 10/7023b1423fd0083ec14fa5e50fa2507a40c3981a0c412143e9b2ebd9f88b137e5aecc0533bf8406c1122c75071a78bbaee8b37db826ab3a4b689ad1f004dddfe languageName: node linkType: hard @@ -4225,6 +4232,13 @@ __metadata: languageName: node linkType: hard +"@prisma/debug@npm:5.14.0": + version: 5.14.0 + resolution: "@prisma/debug@npm:5.14.0" + checksum: 10/d1afd73075a4753b49cce8b1dfc8c2a20d88624d2570abd4baf24a1353e24dad3c0b55db7b4055c70e76545c6f172dfd0a54d58d2dc827a93b1bde04c2f3b5aa + languageName: node + linkType: hard + "@prisma/engines-version@npm:5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102": version: 5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102 resolution: "@prisma/engines-version@npm:5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" @@ -4232,6 +4246,13 @@ __metadata: languageName: node linkType: hard +"@prisma/engines-version@npm:5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48": + version: 5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48 + resolution: "@prisma/engines-version@npm:5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48" + checksum: 10/88dece13c407aff3177970b761bd332a06abda9d0d0a8e5a628f8580ee52ac3ff1a06f52cdf7876e6b9823f2bf2b8e8d34890fa2eb237e98a59c1dc5ae73f9bf + languageName: node + linkType: hard + "@prisma/engines@npm:5.11.0": version: 5.11.0 resolution: "@prisma/engines@npm:5.11.0" @@ -4244,6 +4265,18 @@ __metadata: languageName: node linkType: hard +"@prisma/engines@npm:5.14.0": + version: 5.14.0 + resolution: "@prisma/engines@npm:5.14.0" + dependencies: + "@prisma/debug": "npm:5.14.0" + "@prisma/engines-version": "npm:5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48" + "@prisma/fetch-engine": "npm:5.14.0" + "@prisma/get-platform": "npm:5.14.0" + checksum: 10/d9677a3a6c53c6f96644f3fccb5903e7234758edc38e8d9632a5282ab9e979e6e8c8b892f8a920937e8ae6da5535a9a35cc66b9c5ecbe83375e738f0e49ac699 + languageName: node + linkType: hard + "@prisma/fetch-engine@npm:5.11.0": version: 5.11.0 resolution: "@prisma/fetch-engine@npm:5.11.0" @@ -4255,6 +4288,17 @@ __metadata: languageName: node linkType: hard +"@prisma/fetch-engine@npm:5.14.0": + version: 5.14.0 + resolution: "@prisma/fetch-engine@npm:5.14.0" + dependencies: + "@prisma/debug": "npm:5.14.0" + "@prisma/engines-version": "npm:5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48" + "@prisma/get-platform": "npm:5.14.0" + checksum: 10/81af34764e42771c5377e6d1d4b6ff9642ac59b56bcbea5ba8cd7a415dfbc0c030490e8ad84bc73bc4685d3adc2dcd2a524e79c5fa4a9d7ef9eabd6b1def99b1 + languageName: node + linkType: hard + "@prisma/get-platform@npm:5.11.0": version: 5.11.0 resolution: "@prisma/get-platform@npm:5.11.0" @@ -4264,6 +4308,15 @@ __metadata: languageName: node linkType: hard +"@prisma/get-platform@npm:5.14.0": + version: 5.14.0 + resolution: "@prisma/get-platform@npm:5.14.0" + dependencies: + "@prisma/debug": "npm:5.14.0" + checksum: 10/b0b0db492916466d42dd5e6460e8c7f0f8a11f4eb14ad7e89c4e011c7d53c37a3ca44563f4cca8a3af7e7501ae96f15eb454524c0069e1eb9f15f8ba5b1824fc + languageName: node + linkType: hard + "@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": version: 1.1.2 resolution: "@protobufjs/aspromise@npm:1.1.2" @@ -5345,7 +5398,6 @@ __metadata: resolution: "@snipcode/code-embed@workspace:apps/functions/code-embed" dependencies: "@serverless/typescript": "npm:3.21.0" - "@snipcode/database": "workspace:*" "@snipcode/embed": "workspace:*" "@types/aws-lambda": "npm:8.10.136" esbuild: "npm:0.20.2" @@ -5368,7 +5420,6 @@ __metadata: "@graphql-codegen/typescript": "npm:4.0.6" "@graphql-codegen/typescript-resolvers": "npm:4.0.6" "@graphql-tools/schema": "npm:10.0.3" - "@snipcode/database": "workspace:*" "@snipcode/domain": "workspace:*" "@snipcode/embed": "workspace:*" "@snipcode/logger": "workspace:*" @@ -5386,27 +5437,21 @@ __metadata: languageName: unknown linkType: soft -"@snipcode/database@workspace:*, @snipcode/database@workspace:packages/database": - version: 0.0.0-use.local - resolution: "@snipcode/database@workspace:packages/database" - dependencies: - "@prisma/client": "npm:5.11.0" - cuid: "npm:3.0.0" - languageName: unknown - linkType: soft - "@snipcode/domain@workspace:*, @snipcode/domain@workspace:packages/domain": version: 0.0.0-use.local resolution: "@snipcode/domain@workspace:packages/domain" dependencies: + "@bugsnag/cuid": "npm:3.1.1" "@ngneat/falso": "npm:7.2.0" - "@snipcode/database": "workspace:*" + "@prisma/client": "npm:5.14.0" "@snipcode/utils": "workspace:*" "@types/bcryptjs": "npm:2.4.6" axios: "npm:1.6.8" bcryptjs: "npm:2.4.3" nock: "npm:13.5.4" + prisma: "npm:5.14.0" unique-username-generator: "npm:1.3.0" + zx: "npm:8.0.2" languageName: unknown linkType: soft @@ -5414,7 +5459,6 @@ __metadata: version: 0.0.0-use.local resolution: "@snipcode/embed@workspace:packages/embed" dependencies: - "@snipcode/database": "workspace:*" "@types/express": "npm:4.17.21" express: "npm:4.19.1" nodemon: "npm:2.0.22" @@ -5861,6 +5905,16 @@ __metadata: languageName: node linkType: hard +"@types/fs-extra@npm:^11.0.4": + version: 11.0.4 + resolution: "@types/fs-extra@npm:11.0.4" + dependencies: + "@types/jsonfile": "npm:*" + "@types/node": "npm:*" + checksum: 10/acc4c1eb0cde7b1f23f3fe6eb080a14832d8fa9dc1761aa444c5e2f0f6b6fa657ed46ebae32fb580a6700fc921b6165ce8ac3e3ba030c3dd15f10ad4dd4cae98 + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.3": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -5968,6 +6022,15 @@ __metadata: languageName: node linkType: hard +"@types/jsonfile@npm:*": + version: 6.1.4 + resolution: "@types/jsonfile@npm:6.1.4" + dependencies: + "@types/node": "npm:*" + checksum: 10/309fda20eb5f1cf68f2df28931afdf189c5e7e6bec64ac783ce737bb98908d57f6f58757ad5da9be37b815645a6f914e2d4f3ac66c574b8fe1ba6616284d0e97 + languageName: node + linkType: hard + "@types/keyv@npm:^3.1.4": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" @@ -6037,6 +6100,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:>=20.12.5": + version: 20.12.12 + resolution: "@types/node@npm:20.12.12" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 10/e3945da0a3017bdc1f88f15bdfb823f526b2a717bd58d4640082d6eb0bd2794b5c99bfb914b9e9324ec116dce36066990353ed1c777e8a7b0641f772575793c4 + languageName: node + linkType: hard + "@types/node@npm:^10.1.0": version: 10.17.60 resolution: "@types/node@npm:10.17.60" @@ -8854,13 +8926,6 @@ __metadata: languageName: node linkType: hard -"cuid@npm:3.0.0": - version: 3.0.0 - resolution: "cuid@npm:3.0.0" - checksum: 10/c6d614250c438d5422998f5b1916474a3591316cdb48ff9b0e0e2c750d8a383737dda71436bfc8ed13ba1363c5d1c2255505aa45b602f309bceec6fb504e70bf - languageName: node - linkType: hard - "d@npm:1, d@npm:^1.0.1": version: 1.0.1 resolution: "d@npm:1.0.1" @@ -15517,6 +15582,17 @@ __metadata: languageName: node linkType: hard +"prisma@npm:5.14.0": + version: 5.14.0 + resolution: "prisma@npm:5.14.0" + dependencies: + "@prisma/engines": "npm:5.14.0" + bin: + prisma: build/index.js + checksum: 10/90184937495e1366923d5a4c55626072556472ea6aa76f31ce85cc4f1be0875d978a3311c2a872e28861790cf20a182a1c3925b311ed645d2a11d241bc8c2574 + languageName: node + linkType: hard + "proc-log@npm:^3.0.0": version: 3.0.0 resolution: "proc-log@npm:3.0.0" @@ -19423,3 +19499,20 @@ __metadata: checksum: 10/33bd5ee7017656c2ad728b5d4ba510e15bd65ce1ec180c5bbdc7a5f063256353ec482e6a2bc74de7515219d8494147924b9aae16e63fdaaf37cdf7d1ee8df125 languageName: node linkType: hard + +"zx@npm:8.0.2": + version: 8.0.2 + resolution: "zx@npm:8.0.2" + dependencies: + "@types/fs-extra": "npm:^11.0.4" + "@types/node": "npm:>=20.12.5" + dependenciesMeta: + "@types/fs-extra": + optional: true + "@types/node": + optional: true + bin: + zx: build/cli.js + checksum: 10/189e83f6f4ce9ca13a41db522bbe8314bdc416653edc542f496659ddc91faac5f51f0512a03e991c36f00e936b94e25d1da0e6658b6ba600f9738837fe596382 + languageName: node + linkType: hard From 2db671f83980fbdbe7393730faf6e0bf48f19d1c Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Tue, 21 May 2024 22:05:09 +0200 Subject: [PATCH 2/8] chore(core): build the docker image without esbuild --- apps/core/.dockerignore | 211 ++++++++++++++++++ apps/core/.eslintrc.json | 12 +- apps/core/Dockerfile | 52 ++++- apps/core/env.d.ts | 1 + apps/core/src/configs/env.ts | 1 + apps/core/src/configs/http-client.ts | 6 +- apps/core/src/index.ts | 2 +- .../authentication/handlers/github.ts | 6 +- apps/core/src/types/models.ts | 3 - apps/core/src/utils/auth/session.ts | 3 +- apps/functions/code-embed/.eslintrc.json | 7 +- .../src/functions/renderer/handler.ts | 2 +- apps/web/.eslintrc.json | 5 +- packages/domain/.eslintrc.json | 9 +- packages/embed/.eslintrc.json | 16 +- packages/embed/package.json | 2 + .../src/renderer/content/html-generator.ts | 2 +- packages/embed/src/renderer/index.ts | 2 +- packages/embed/src/server/index.ts | 2 +- packages/front/.eslintrc.json | 14 +- packages/logger/.eslintrc.json | 12 +- packages/utils/.eslintrc.json | 11 +- 22 files changed, 335 insertions(+), 46 deletions(-) create mode 100644 apps/core/.dockerignore delete mode 100644 apps/core/src/types/models.ts diff --git a/apps/core/.dockerignore b/apps/core/.dockerignore new file mode 100644 index 00000000..660dc985 --- /dev/null +++ b/apps/core/.dockerignore @@ -0,0 +1,211 @@ +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Node template +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + diff --git a/apps/core/.eslintrc.json b/apps/core/.eslintrc.json index 08a84c23..62039869 100644 --- a/apps/core/.eslintrc.json +++ b/apps/core/.eslintrc.json @@ -1,8 +1,14 @@ { - "ignorePatterns": ["graphql.d.ts", "jest.config.ts"], + "ignorePatterns": [ + "graphql.d.ts", + "jest.config.ts" + ], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./apps/core/tsconfig.json", + "tsconfig.json" + ] } } diff --git a/apps/core/Dockerfile b/apps/core/Dockerfile index 0ffd8711..8c3e0c4e 100644 --- a/apps/core/Dockerfile +++ b/apps/core/Dockerfile @@ -10,35 +10,67 @@ RUN corepack enable && yarn set version berry RUN yarn install -RUN npx prisma generate --schema=./packages/database/prisma/schema.prisma +RUN npx prisma generate --schema=./packages/domain/prisma/schema.prisma -WORKDIR /app/apps/core +RUN yarn build --filter=...@snipcode/core -RUN yarn build:prod FROM node:20-alpine as schema-builder WORKDIR /app -COPY --chown=node:node --from=builder /app/packages/database/prisma/schema.prisma ./app/prisma/ +COPY --chown=node:node --from=builder /app/packages/domain/prisma/schema.prisma ./app/prisma/ # Generate the Prisma query engine for Node Alpine RUN npx prisma generate --schema=./app/prisma/schema.prisma -FROM node:20-alpine AS snipcode +FROM node:20-alpine AS runner + +ARG APP_VERSION="1.0.0" ENV NODE_ENV=production +ENV APP_VERSION=${APP_VERSION} WORKDIR /app -COPY --chown=node:node --from=builder /app/apps/core/build/index.js ./ +RUN corepack enable && yarn set version berry + +COPY --chown=node:node --from=builder /app/package.json . +COPY --chown=node:node --from=builder /app/.yarnrc.yml . + +COPY --chown=node:node --from=builder /app/apps/core/dist/src ./apps/core/src +COPY --chown=node:node --from=builder /app/apps/core/package.json ./apps/core + +COPY --chown=node:node --from=builder /app/packages/domain/package.json ./packages/domain/package.json +COPY --chown=node:node --from=builder /app/packages/domain/dist ./packages/domain/dist +COPY --chown=node:node --from=builder /app/packages/domain/node_modules/.prisma ./packages/domain/node_modules/.prisma + +COPY --chown=node:node --from=builder /app/packages/utils/package.json ./packages/utils/package.json +COPY --chown=node:node --from=builder /app/packages/utils/dist ./packages/utils/dist + +COPY --chown=node:node --from=builder /app/packages/embed/package.json ./packages/embed/package.json +COPY --chown=node:node --from=builder /app/packages/embed/dist ./packages/embed/dist + +COPY --chown=node:node --from=builder /app/packages/logger/package.json ./packages/logger/package.json +COPY --chown=node:node --from=builder /app/packages/logger/dist ./packages/logger/dist + +# COPY --chown=node:node --from=builder /app/packages/domain/package.json ./node_modules/@snipcode/domain/package.json +# COPY --chown=node:node --from=builder /app/packages/domain/dist ./node_modules/@snipcode/domain/dist +# COPY --chown=node:node --from=builder /app/packages/domain/node_modules/.prisma ./node_modules/@snipcode/domain/node_modules/.prisma + + +RUN yarn install +# RUN yarn workspaces focus # && yarn cache clean -COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client/schema.prisma ./ -COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client/libquery_engine-linux-musl.so.node ./ +# COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client/schema.prisma ./node_modules/.prisma/client +# COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client/libquery_engine-linux-musl.so.node ./node_modules/.prisma/client +# COPY --chown=node:node --from=schema-builder /app/node_modules/@prisma/client ./packages/domain/node_modules/@prisma/client +# COPY --chown=node:node --from=schema-builder /app/node_modules/@prisma/client ./node_modules/@prisma/client -RUN yarn init -y +# RUN rm -rf ./packages/domain/node_modules/@prisma/client +COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client ./packages/domain/node_modules/.prisma/client EXPOSE 7501 -CMD ["node", "index.js"] +CMD ["node", "apps/core/src/index.js"] diff --git a/apps/core/env.d.ts b/apps/core/env.d.ts index 6ef75241..b694eb34 100644 --- a/apps/core/env.d.ts +++ b/apps/core/env.d.ts @@ -1,5 +1,6 @@ export type EnvironmentVariables = { ADMIN_PASSWORD: string; + APP_VERSION: string; CONVERTKIT_API_KEY: string; CONVERTKIT_FORM_ID: string; CONVERTKIT_TAG_ID: string; diff --git a/apps/core/src/configs/env.ts b/apps/core/src/configs/env.ts index ff31e23c..331ad404 100644 --- a/apps/core/src/configs/env.ts +++ b/apps/core/src/configs/env.ts @@ -7,6 +7,7 @@ dotenv.config({ override: true }); export const env: AppEnvironmentVariables = { ADMIN_PASSWORD: getEnv('ADMIN_PASSWORD'), + APP_VERSION: getEnv('APP_VERSION'), CONVERTKIT_API_KEY: getEnv('CONVERTKIT_API_KEY'), CONVERTKIT_FORM_ID: getEnv('CONVERTKIT_FORM_ID'), CONVERTKIT_TAG_ID: getEnv('CONVERTKIT_TAG_ID'), diff --git a/apps/core/src/configs/http-client.ts b/apps/core/src/configs/http-client.ts index 0cd83a6d..0a0748a4 100644 --- a/apps/core/src/configs/http-client.ts +++ b/apps/core/src/configs/http-client.ts @@ -2,9 +2,9 @@ import axios from 'axios'; import { logger } from './logger'; -const client = axios.create(); +const httpClient = axios.create(); -client.interceptors.response.use( +httpClient.interceptors.response.use( (res) => res, (err) => { const { @@ -19,4 +19,4 @@ client.interceptors.response.use( }, ); -export default client; +export { httpClient }; diff --git a/apps/core/src/index.ts b/apps/core/src/index.ts index 93215df1..55dca0df 100644 --- a/apps/core/src/index.ts +++ b/apps/core/src/index.ts @@ -1,6 +1,6 @@ import http from 'http'; -import { dbClient } from '@snipcode/database'; +import { dbClient } from '@snipcode/domain'; import express from 'express'; import { env } from './configs/env'; diff --git a/apps/core/src/resources/authentication/handlers/github.ts b/apps/core/src/resources/authentication/handlers/github.ts index f9d62565..afbeefda 100644 --- a/apps/core/src/resources/authentication/handlers/github.ts +++ b/apps/core/src/resources/authentication/handlers/github.ts @@ -1,4 +1,4 @@ -import { User } from '@snipcode/database'; +import { User } from '@snipcode/domain'; import { CreateUserDto, CreateUserRootFolderDto, @@ -12,7 +12,7 @@ import { AxiosRequestConfig } from 'axios'; import { Response } from 'express'; import { env } from '../../../configs/env'; -import httpClient from '../../../configs/http-client'; +import { httpClient } from '../../../configs/http-client'; import { logger } from '../../../configs/logger'; import { GitHubUserResponse } from '../../../types/auth'; import { ExpressRequestQuery } from '../../../types/common'; @@ -118,7 +118,7 @@ export const authenticateWithGitHub = async (req: ExpressRequestQuery<{ code: st const session = await createUserSession(createdUser.id); return res.redirect(authSuccessURL(session.token)); - } catch (e: any) { + } catch (e: unknown) { logger.error(e); return res.redirect(env.WEB_AUTH_ERROR_URL); diff --git a/apps/core/src/types/models.ts b/apps/core/src/types/models.ts deleted file mode 100644 index 8ee49deb..00000000 --- a/apps/core/src/types/models.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Folder, Role, Session, Snippet, User } from '@snipcode/database'; - -export type { User, Role, Folder, Session, Snippet }; diff --git a/apps/core/src/utils/auth/session.ts b/apps/core/src/utils/auth/session.ts index 659ed5f6..0fd04a29 100644 --- a/apps/core/src/utils/auth/session.ts +++ b/apps/core/src/utils/auth/session.ts @@ -1,5 +1,4 @@ -import { Session } from '@snipcode/database'; -import { CreateSessionDto, sessionService } from '@snipcode/domain'; +import { CreateSessionDto, Session, sessionService } from '@snipcode/domain'; import { addDayToDate } from '@snipcode/utils'; import { env } from '../../configs/env'; diff --git a/apps/functions/code-embed/.eslintrc.json b/apps/functions/code-embed/.eslintrc.json index 88a25c05..ec993be0 100644 --- a/apps/functions/code-embed/.eslintrc.json +++ b/apps/functions/code-embed/.eslintrc.json @@ -1,8 +1,11 @@ { "ignorePatterns": [], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./apps/functions/code-embed/tsconfig.json", + "tsconfig.json" + ] } } diff --git a/apps/functions/code-embed/src/functions/renderer/handler.ts b/apps/functions/code-embed/src/functions/renderer/handler.ts index 1cc786e0..312e54c0 100644 --- a/apps/functions/code-embed/src/functions/renderer/handler.ts +++ b/apps/functions/code-embed/src/functions/renderer/handler.ts @@ -1,4 +1,4 @@ -import { dbClient } from '@snipcode/database'; +import { dbClient } from '@snipcode/domain'; import { renderSnippetToHtml } from '@snipcode/embed'; import { APIGatewayProxyEvent, APIGatewayProxyResult, Handler } from 'aws-lambda'; diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json index 949ef77b..fc13c564 100644 --- a/apps/web/.eslintrc.json +++ b/apps/web/.eslintrc.json @@ -9,7 +9,10 @@ "parserOptions": { "ecmaVersion": 2021, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./apps/web/tsconfig.json", + "tsconfig.json" + ] }, "rules": { "camelcase": "off", diff --git a/packages/domain/.eslintrc.json b/packages/domain/.eslintrc.json index e17f70bb..28d98e69 100644 --- a/packages/domain/.eslintrc.json +++ b/packages/domain/.eslintrc.json @@ -1,8 +1,13 @@ { - "ignorePatterns": ["jest.config.ts"], + "ignorePatterns": [ + "jest.config.ts" + ], "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": ["./packages/domain/tsconfig.json", "tsconfig.json"] + "project": [ + "./packages/domain/tsconfig.json", + "tsconfig.json" + ] } } diff --git a/packages/embed/.eslintrc.json b/packages/embed/.eslintrc.json index 88a252d3..3180a793 100644 --- a/packages/embed/.eslintrc.json +++ b/packages/embed/.eslintrc.json @@ -1,8 +1,18 @@ { - "ignorePatterns": ["dist", "build", "tsup.config.ts", "env.d.ts", "src/server/public", "jest.config.ts"], + "ignorePatterns": [ + "dist", + "build", + "tsup.config.ts", + "env.d.ts", + "src/server/public", + "jest.config.ts" + ], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./packages/embed/tsconfig.json", + "tsconfig.json" + ] } } diff --git a/packages/embed/package.json b/packages/embed/package.json index 92a5a47a..4858abc2 100644 --- a/packages/embed/package.json +++ b/packages/embed/package.json @@ -3,6 +3,8 @@ "version": "1.1.3", "private": true, "description": "Build the script and style assets for code snippet rendering in an embed.", + "main": "dist/index.js", + "types": "dist/index.d.ts", "repository": " https://github.com/tericcabrel/snipcode.git", "author": "Eric Cabrel TIOGO ", "license": "MIT", diff --git a/packages/embed/src/renderer/content/html-generator.ts b/packages/embed/src/renderer/content/html-generator.ts index ede60c81..76195fe0 100644 --- a/packages/embed/src/renderer/content/html-generator.ts +++ b/packages/embed/src/renderer/content/html-generator.ts @@ -1,4 +1,4 @@ -import { Snippet } from '@snipcode/database'; +import { Snippet } from '@snipcode/domain'; import { Lang } from 'shiki'; import { generateLineHighlightOptions, parseHTMLSnippetCode } from './utils'; diff --git a/packages/embed/src/renderer/index.ts b/packages/embed/src/renderer/index.ts index b64322cf..f8528da4 100644 --- a/packages/embed/src/renderer/index.ts +++ b/packages/embed/src/renderer/index.ts @@ -1,4 +1,4 @@ -import { Snippet } from '@snipcode/database'; +import { Snippet } from '@snipcode/domain'; import { generateNoSnippetHtmlContent, generateSnippetHtmlContent } from './content/html-generator'; import { generateHTMLPreview } from './content/preview-template'; diff --git a/packages/embed/src/server/index.ts b/packages/embed/src/server/index.ts index 5dfa42f9..f1d042fd 100644 --- a/packages/embed/src/server/index.ts +++ b/packages/embed/src/server/index.ts @@ -1,7 +1,7 @@ import http from 'http'; import path from 'path'; -import { dbClient } from '@snipcode/database'; +import { dbClient } from '@snipcode/domain'; import dotenv from 'dotenv'; import express from 'express'; diff --git a/packages/front/.eslintrc.json b/packages/front/.eslintrc.json index d6c43957..2528d03c 100644 --- a/packages/front/.eslintrc.json +++ b/packages/front/.eslintrc.json @@ -1,8 +1,16 @@ { - "ignorePatterns": ["postcss.config.js", "tailwind.config.js", "jest.config.ts", "generated.ts"], + "ignorePatterns": [ + "postcss.config.js", + "tailwind.config.js", + "jest.config.ts", + "generated.ts" + ], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./packages/logger/tsconfig.json", + "tsconfig.json" + ] } } diff --git a/packages/logger/.eslintrc.json b/packages/logger/.eslintrc.json index 88cacee6..11c078c7 100644 --- a/packages/logger/.eslintrc.json +++ b/packages/logger/.eslintrc.json @@ -1,8 +1,14 @@ { - "ignorePatterns": ["jest.config.ts", "dist"], + "ignorePatterns": [ + "jest.config.ts", + "dist" + ], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./packages/logger/tsconfig.json", + "tsconfig.json" + ] } } diff --git a/packages/utils/.eslintrc.json b/packages/utils/.eslintrc.json index 9a46147c..5db16dcb 100644 --- a/packages/utils/.eslintrc.json +++ b/packages/utils/.eslintrc.json @@ -1,8 +1,13 @@ { - "ignorePatterns": ["jest.config.ts"], + "ignorePatterns": [ + "jest.config.ts" + ], "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": "tsconfig.json" + "project": [ + "./packages/utils/tsconfig.json", + "tsconfig.json" + ] } } From a00e7ae8e884e5cc43b5784dcfb7698cfd53ad6c Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Tue, 21 May 2024 23:44:05 +0200 Subject: [PATCH 3/8] chore(core): optimize the docker build --- apps/core/Dockerfile | 22 +++++----------------- apps/core/package.json | 2 +- packages/domain/package.json | 2 +- yarn.lock | 2 +- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/apps/core/Dockerfile b/apps/core/Dockerfile index 8c3e0c4e..6658e3a1 100644 --- a/apps/core/Dockerfile +++ b/apps/core/Dockerfile @@ -22,8 +22,9 @@ WORKDIR /app COPY --chown=node:node --from=builder /app/packages/domain/prisma/schema.prisma ./app/prisma/ # Generate the Prisma query engine for Node Alpine -RUN npx prisma generate --schema=./app/prisma/schema.prisma - +RUN npx prisma generate --schema=./app/prisma/schema.prisma && \ + rm ./node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node +# https://www.prisma.io/docs/orm/reference/prisma-schema-reference#binarytargets-options FROM node:20-alpine AS runner @@ -44,7 +45,6 @@ COPY --chown=node:node --from=builder /app/apps/core/package.json ./apps/core COPY --chown=node:node --from=builder /app/packages/domain/package.json ./packages/domain/package.json COPY --chown=node:node --from=builder /app/packages/domain/dist ./packages/domain/dist -COPY --chown=node:node --from=builder /app/packages/domain/node_modules/.prisma ./packages/domain/node_modules/.prisma COPY --chown=node:node --from=builder /app/packages/utils/package.json ./packages/utils/package.json COPY --chown=node:node --from=builder /app/packages/utils/dist ./packages/utils/dist @@ -55,21 +55,9 @@ COPY --chown=node:node --from=builder /app/packages/embed/dist ./packages/embed/ COPY --chown=node:node --from=builder /app/packages/logger/package.json ./packages/logger/package.json COPY --chown=node:node --from=builder /app/packages/logger/dist ./packages/logger/dist -# COPY --chown=node:node --from=builder /app/packages/domain/package.json ./node_modules/@snipcode/domain/package.json -# COPY --chown=node:node --from=builder /app/packages/domain/dist ./node_modules/@snipcode/domain/dist -# COPY --chown=node:node --from=builder /app/packages/domain/node_modules/.prisma ./node_modules/@snipcode/domain/node_modules/.prisma - - -RUN yarn install -# RUN yarn workspaces focus # && yarn cache clean - -# COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client/schema.prisma ./node_modules/.prisma/client -# COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client/libquery_engine-linux-musl.so.node ./node_modules/.prisma/client -# COPY --chown=node:node --from=schema-builder /app/node_modules/@prisma/client ./packages/domain/node_modules/@prisma/client -# COPY --chown=node:node --from=schema-builder /app/node_modules/@prisma/client ./node_modules/@prisma/client +RUN yarn workspaces focus --all --production && yarn cache clean --all -# RUN rm -rf ./packages/domain/node_modules/@prisma/client -COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client ./packages/domain/node_modules/.prisma/client +COPY --chown=node:node --from=schema-builder /app/node_modules/.prisma/client ./node_modules/.prisma/client EXPOSE 7501 diff --git a/apps/core/package.json b/apps/core/package.json index a5280e74..63149857 100644 --- a/apps/core/package.json +++ b/apps/core/package.json @@ -24,6 +24,7 @@ "apollo-server-express": "3.13.0", "axios": "1.6.8", "cors": "2.8.5", + "dotenv": "16.4.5", "express": "4.19.1", "graphql": "16.8.1" }, @@ -33,7 +34,6 @@ "@graphql-codegen/typescript-resolvers": "4.0.6", "@types/cors": "2.8.17", "@types/express": "4.17.21", - "esbuild": "0.20.2", "nodemon": "3.1.0" } } diff --git a/packages/domain/package.json b/packages/domain/package.json index 08737144..7824e9d3 100644 --- a/packages/domain/package.json +++ b/packages/domain/package.json @@ -27,6 +27,7 @@ }, "dependencies": { "@bugsnag/cuid": "3.1.1", + "@prisma/client": "5.14.0", "@snipcode/utils": "workspace:*", "axios": "1.6.8", "bcryptjs": "2.4.3", @@ -34,7 +35,6 @@ }, "devDependencies": { "@ngneat/falso": "7.2.0", - "@prisma/client": "5.14.0", "@types/bcryptjs": "2.4.6", "nock": "13.5.4", "prisma": "5.14.0", diff --git a/yarn.lock b/yarn.lock index 62f5842e..f0344c31 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5430,7 +5430,7 @@ __metadata: apollo-server-express: "npm:3.13.0" axios: "npm:1.6.8" cors: "npm:2.8.5" - esbuild: "npm:0.20.2" + dotenv: "npm:16.4.5" express: "npm:4.19.1" graphql: "npm:16.8.1" nodemon: "npm:3.1.0" From 2bf375ee0bc91cdf16c7e0b75d08504300509996 Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Tue, 21 May 2024 23:50:57 +0200 Subject: [PATCH 4/8] docs(app): create the changelog --- .changeset/itchy-cars-yell.md | 8 ++++++++ package.json | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 .changeset/itchy-cars-yell.md diff --git a/.changeset/itchy-cars-yell.md b/.changeset/itchy-cars-yell.md new file mode 100644 index 00000000..5ad32f58 --- /dev/null +++ b/.changeset/itchy-cars-yell.md @@ -0,0 +1,8 @@ +--- +"@snipcode/domain": minor +"@snipcode/core": minor +"@snipcode/code-embed": patch +"@snipcode/embed": patch +--- + +Merge the database schema and the application business rules into a single package diff --git a/package.json b/package.json index 0bd6044f..a69b4110 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "format": "prettier --write \"**/*.{ts,tsx,md}\"", "cache:login": "turbo login", "cache:link": "turbo link", - "cache:disable": "turbo unlink" + "cache:disable": "turbo unlink", + "pre-release": "changeset" }, "workspaces": [ "packages/domain", From 02cc6e6ea365bc175a7053a64f8d858b5f1672eb Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Wed, 22 May 2024 00:05:29 +0200 Subject: [PATCH 5/8] build(app): fix lint errors in the ci --- apps/core/.eslintrc.json | 4 ++-- apps/functions/code-embed/.eslintrc.json | 4 ++-- apps/web/.eslintrc.json | 4 ++-- packages/embed/.eslintrc.json | 4 ++-- packages/front/.eslintrc.json | 4 ++-- packages/logger/.eslintrc.json | 4 ++-- packages/utils/.eslintrc.json | 4 ++-- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/core/.eslintrc.json b/apps/core/.eslintrc.json index 62039869..08c7f1ff 100644 --- a/apps/core/.eslintrc.json +++ b/apps/core/.eslintrc.json @@ -7,8 +7,8 @@ "ecmaVersion": 2023, "sourceType": "module", "project": [ - "./apps/core/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./apps/core/tsconfig.json" ] } } diff --git a/apps/functions/code-embed/.eslintrc.json b/apps/functions/code-embed/.eslintrc.json index ec993be0..d2d0f88b 100644 --- a/apps/functions/code-embed/.eslintrc.json +++ b/apps/functions/code-embed/.eslintrc.json @@ -4,8 +4,8 @@ "ecmaVersion": 2023, "sourceType": "module", "project": [ - "./apps/functions/code-embed/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./apps/functions/code-embed/tsconfig.json" ] } } diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json index fc13c564..898adf02 100644 --- a/apps/web/.eslintrc.json +++ b/apps/web/.eslintrc.json @@ -10,8 +10,8 @@ "ecmaVersion": 2021, "sourceType": "module", "project": [ - "./apps/web/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./apps/web/tsconfig.json" ] }, "rules": { diff --git a/packages/embed/.eslintrc.json b/packages/embed/.eslintrc.json index 3180a793..8d6e2c62 100644 --- a/packages/embed/.eslintrc.json +++ b/packages/embed/.eslintrc.json @@ -11,8 +11,8 @@ "ecmaVersion": 2023, "sourceType": "module", "project": [ - "./packages/embed/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./packages/embed/tsconfig.json" ] } } diff --git a/packages/front/.eslintrc.json b/packages/front/.eslintrc.json index 2528d03c..f77f15f4 100644 --- a/packages/front/.eslintrc.json +++ b/packages/front/.eslintrc.json @@ -9,8 +9,8 @@ "ecmaVersion": 2023, "sourceType": "module", "project": [ - "./packages/logger/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./packages/logger/tsconfig.json" ] } } diff --git a/packages/logger/.eslintrc.json b/packages/logger/.eslintrc.json index 11c078c7..54f7e7cb 100644 --- a/packages/logger/.eslintrc.json +++ b/packages/logger/.eslintrc.json @@ -7,8 +7,8 @@ "ecmaVersion": 2023, "sourceType": "module", "project": [ - "./packages/logger/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./packages/logger/tsconfig.json" ] } } diff --git a/packages/utils/.eslintrc.json b/packages/utils/.eslintrc.json index 5db16dcb..501534d9 100644 --- a/packages/utils/.eslintrc.json +++ b/packages/utils/.eslintrc.json @@ -6,8 +6,8 @@ "ecmaVersion": 2023, "sourceType": "module", "project": [ - "./packages/utils/tsconfig.json", - "tsconfig.json" + "tsconfig.json", + "./packages/utils/tsconfig.json" ] } } From e236ba212319ec780614a8c3b671c5167c80762b Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Wed, 22 May 2024 00:38:23 +0200 Subject: [PATCH 6/8] build(app): fix lint errors in the ci --- packages/domain/.eslintrc.json | 7 +++---- packages/domain/src/utils/axios-error.ts | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/domain/.eslintrc.json b/packages/domain/.eslintrc.json index 28d98e69..dfdb1a26 100644 --- a/packages/domain/.eslintrc.json +++ b/packages/domain/.eslintrc.json @@ -1,13 +1,12 @@ { + "root": true, + "extends": "../../.eslintrc.json", "ignorePatterns": [ "jest.config.ts" ], "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "./packages/domain/tsconfig.json", - "tsconfig.json" - ] + "project": "tsconfig.json" } } diff --git a/packages/domain/src/utils/axios-error.ts b/packages/domain/src/utils/axios-error.ts index 873065eb..dda190e4 100644 --- a/packages/domain/src/utils/axios-error.ts +++ b/packages/domain/src/utils/axios-error.ts @@ -8,5 +8,7 @@ export const handleRequestError = (errorCode: ErrorCode) => (error: AxiosError) status: error.response?.status, }; + console.log(errorInfo); + throw new SnipcodeError(JSON.stringify(errorInfo, null, 2), errorCode); }; From 8b8c58bf6bbd8b1f0a5180a19eac8501a336307d Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Wed, 22 May 2024 00:53:41 +0200 Subject: [PATCH 7/8] build(app): fix lint errors in the ci --- apps/core/.eslintrc.json | 7 +++---- apps/functions/code-embed/.eslintrc.json | 7 +++---- apps/web/.eslintrc.json | 14 ++++++++------ packages/domain/src/utils/axios-error.ts | 2 -- packages/embed/.eslintrc.json | 7 +++---- packages/front/.eslintrc.json | 7 +++---- packages/logger/.eslintrc.json | 7 +++---- packages/utils/.eslintrc.json | 7 +++---- 8 files changed, 26 insertions(+), 32 deletions(-) diff --git a/apps/core/.eslintrc.json b/apps/core/.eslintrc.json index 08c7f1ff..ae4ccc97 100644 --- a/apps/core/.eslintrc.json +++ b/apps/core/.eslintrc.json @@ -1,4 +1,6 @@ { + "root": true, + "extends": "../../.eslintrc.json", "ignorePatterns": [ "graphql.d.ts", "jest.config.ts" @@ -6,9 +8,6 @@ "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./apps/core/tsconfig.json" - ] + "project": "tsconfig.json" } } diff --git a/apps/functions/code-embed/.eslintrc.json b/apps/functions/code-embed/.eslintrc.json index d2d0f88b..604d2139 100644 --- a/apps/functions/code-embed/.eslintrc.json +++ b/apps/functions/code-embed/.eslintrc.json @@ -1,11 +1,10 @@ { + "root": true, + "extends": "../../../.eslintrc.json", "ignorePatterns": [], "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./apps/functions/code-embed/tsconfig.json" - ] + "project": "tsconfig.json" } } diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json index 898adf02..3703e973 100644 --- a/apps/web/.eslintrc.json +++ b/apps/web/.eslintrc.json @@ -1,18 +1,20 @@ { "plugins": [], - "extends": ["next", "next/core-web-vitals"], + "root": true, + "extends": [ + "next", + "next/core-web-vitals", + "../../.eslintrc.json" + ], "settings": { "next": { "rootDir": "." } }, "parserOptions": { - "ecmaVersion": 2021, + "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./apps/web/tsconfig.json" - ] + "project": "tsconfig.json" }, "rules": { "camelcase": "off", diff --git a/packages/domain/src/utils/axios-error.ts b/packages/domain/src/utils/axios-error.ts index dda190e4..873065eb 100644 --- a/packages/domain/src/utils/axios-error.ts +++ b/packages/domain/src/utils/axios-error.ts @@ -8,7 +8,5 @@ export const handleRequestError = (errorCode: ErrorCode) => (error: AxiosError) status: error.response?.status, }; - console.log(errorInfo); - throw new SnipcodeError(JSON.stringify(errorInfo, null, 2), errorCode); }; diff --git a/packages/embed/.eslintrc.json b/packages/embed/.eslintrc.json index 8d6e2c62..90eb5d03 100644 --- a/packages/embed/.eslintrc.json +++ b/packages/embed/.eslintrc.json @@ -1,4 +1,6 @@ { + "root": true, + "extends": "../../.eslintrc.json", "ignorePatterns": [ "dist", "build", @@ -10,9 +12,6 @@ "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./packages/embed/tsconfig.json" - ] + "project": "tsconfig.json" } } diff --git a/packages/front/.eslintrc.json b/packages/front/.eslintrc.json index f77f15f4..40b7f34b 100644 --- a/packages/front/.eslintrc.json +++ b/packages/front/.eslintrc.json @@ -1,4 +1,6 @@ { + "root": true, + "extends": "../../.eslintrc.json", "ignorePatterns": [ "postcss.config.js", "tailwind.config.js", @@ -8,9 +10,6 @@ "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./packages/logger/tsconfig.json" - ] + "project": "tsconfig.json" } } diff --git a/packages/logger/.eslintrc.json b/packages/logger/.eslintrc.json index 54f7e7cb..c142468b 100644 --- a/packages/logger/.eslintrc.json +++ b/packages/logger/.eslintrc.json @@ -1,4 +1,6 @@ { + "root": true, + "extends": "../../.eslintrc.json", "ignorePatterns": [ "jest.config.ts", "dist" @@ -6,9 +8,6 @@ "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./packages/logger/tsconfig.json" - ] + "project": "tsconfig.json" } } diff --git a/packages/utils/.eslintrc.json b/packages/utils/.eslintrc.json index 501534d9..dfdb1a26 100644 --- a/packages/utils/.eslintrc.json +++ b/packages/utils/.eslintrc.json @@ -1,13 +1,12 @@ { + "root": true, + "extends": "../../.eslintrc.json", "ignorePatterns": [ "jest.config.ts" ], "parserOptions": { "ecmaVersion": 2023, "sourceType": "module", - "project": [ - "tsconfig.json", - "./packages/utils/tsconfig.json" - ] + "project": "tsconfig.json" } } From 5dc2b0d65f7fee307e4d0a1dcd535b30116fff9d Mon Sep 17 00:00:00 2001 From: Eric Cabrel TIOGO Date: Wed, 22 May 2024 12:21:28 +0200 Subject: [PATCH 8/8] build(app): fix build errors in the ci --- .github/actions/install-dependencies/action.yml | 2 +- .github/workflows/build-release.yml | 4 +++- .github/workflows/build.yml | 8 +++++--- .github/workflows/deploy-frontend.yml | 2 +- apps/core/README.md | 8 ++++---- apps/core/tsconfig.json | 3 --- apps/functions/code-embed/scripts/setup-layer.sh | 2 +- package.json | 3 +-- packages/embed/README.md | 2 +- packages/embed/package.json | 1 + packages/embed/tsconfig.json | 5 +++++ turbo.json | 2 +- yarn.lock | 1 + 13 files changed, 25 insertions(+), 18 deletions(-) diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index d7674ba3..87db778c 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -24,7 +24,7 @@ runs: shell: bash run: | corepack enable - yarn set version 4.2.1 + yarn set version 4.2.2 - name: Install projects dependencies shell: bash diff --git a/.github/workflows/build-release.yml b/.github/workflows/build-release.yml index f047614f..45cf25af 100644 --- a/.github/workflows/build-release.yml +++ b/.github/workflows/build-release.yml @@ -46,7 +46,9 @@ jobs: run: sudo systemctl start mysql.service - name: Run tests - run: yarn test + run: | + yarn prisma migrate dev --schema=packages/domain/prisma/schema.prisma + yarn test version: runs-on: ubuntu-latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fbffa449..02daf328 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: MYSQL_DATABASE: test MYSQL_PORT: 3306 DATABASE_URL: mysql://root:root@127.0.0.1:3306/test - ADMIN_PASSWORD: admin_password + TEST_DATABASE_URL: mysql://root:root@127.0.0.1:3306/test CONVERTKIT_API_KEY: api_key CONVERTKIT_FORM_ID: form_id outputs: @@ -43,7 +43,9 @@ jobs: run: sudo systemctl start mysql.service - name: Run tests - run: yarn test + run: | + yarn prisma migrate dev --schema=packages/domain/prisma/schema.prisma + yarn test preview-frontend: runs-on: ubuntu-latest @@ -56,7 +58,7 @@ jobs: - name: Install Yarn 4 run: | corepack enable - yarn set version 4.2.1 + yarn set version 4.2.2 - name: Install Vercel CLI run: npm install --global vercel@latest diff --git a/.github/workflows/deploy-frontend.yml b/.github/workflows/deploy-frontend.yml index 204a3d93..63093618 100644 --- a/.github/workflows/deploy-frontend.yml +++ b/.github/workflows/deploy-frontend.yml @@ -22,7 +22,7 @@ jobs: - name: Install Yarn 4 run: | corepack enable - yarn set version 4.2.1 + yarn set version 4.2.2 - name: Install Vercel CLI run: npm install --global vercel@latest diff --git a/apps/core/README.md b/apps/core/README.md index 89ea66f3..55de104b 100644 --- a/apps/core/README.md +++ b/apps/core/README.md @@ -1,12 +1,12 @@ # Snipcode Core -This is the core backend of Snipcode. All the business logic behind this application is implemented here. +This is the backend of Snipcode, containing the business logics related to . ## Tech Stack * Node.js -* Typescript +* TypeScript * GraphQL -* MySQL 8 through PlanetScale +* MySQL * Prisma ## Prerequisites @@ -15,13 +15,13 @@ Make sure you have this tools installed before running the project * NPM or Yarn * Docker * AWS CLI v2 +* MySQL 8 on PlanetScale ## Packages dependencies We use Yarn workspace to create packages we can share with other applications. These packages are located in the folder `packages`, so you might need to change the code of one or many packages to implement a feature. Here are the packages used in this project: -* [@snipcode/database](../../packages/database) * [@snipcode/domain](../../packages/domain) * [@snipcode/logger](../../packages/logger) * [@snipcode/utils](../../packages/utils) diff --git a/apps/core/tsconfig.json b/apps/core/tsconfig.json index 192dafc8..9d32a654 100644 --- a/apps/core/tsconfig.json +++ b/apps/core/tsconfig.json @@ -23,8 +23,5 @@ { "path": "../../packages/domain" }, - { - "path": "../../packages/database" - } ] } diff --git a/apps/functions/code-embed/scripts/setup-layer.sh b/apps/functions/code-embed/scripts/setup-layer.sh index db1e129f..25f1b45d 100755 --- a/apps/functions/code-embed/scripts/setup-layer.sh +++ b/apps/functions/code-embed/scripts/setup-layer.sh @@ -8,7 +8,7 @@ mkdir -p layers/shiki-layer/nodejs/node_modules cd ../../.. -yarn workspace @snipcode/database db:generate +yarn workspace @snipcode/domain db:generate cp -r node_modules/.prisma apps/functions/code-embed/layers/prisma-layer/nodejs/node_modules diff --git a/package.json b/package.json index a69b4110..96bfab82 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,10 @@ "scripts": { "build": "turbo run build", "build:prod": "turbo run build:prod", - "build:backend": "turbo run build --filter=!@snipcode/web", "dev": "turbo run dev --no-cache --parallel --continue", "lint": "turbo run lint", "test": "turbo run test", - "clean": "turbo run clean && rm -rf .turbo", + "clean": "turbo run clean --force && rm -rf .turbo", "format": "prettier --write \"**/*.{ts,tsx,md}\"", "cache:login": "turbo login", "cache:link": "turbo link", diff --git a/packages/embed/README.md b/packages/embed/README.md index 4e42ea45..46a2a61a 100644 --- a/packages/embed/README.md +++ b/packages/embed/README.md @@ -33,7 +33,7 @@ nano .env Start the database locally ```shell -yarn workspace @snipcode/database db:dev +yarn workspace @snipcode/domain db:dev ``` ## Start the watcher for the CSS and JS diff --git a/packages/embed/package.json b/packages/embed/package.json index 4858abc2..3d4b350f 100644 --- a/packages/embed/package.json +++ b/packages/embed/package.json @@ -21,6 +21,7 @@ "test": "jest" }, "devDependencies": { + "@snipcode/domain": "workspace:*", "@types/express": "4.17.21", "express": "4.19.1", "nodemon": "2.0.22", diff --git a/packages/embed/tsconfig.json b/packages/embed/tsconfig.json index e68cd4e8..6836d362 100644 --- a/packages/embed/tsconfig.json +++ b/packages/embed/tsconfig.json @@ -14,5 +14,10 @@ "include": ["src", "__tests__", "index.ts"], "exclude": [ "node_modules" + ], + "references": [ + { + "path": "../../packages/domain" + } ] } diff --git a/turbo.json b/turbo.json index 5f94c6ab..aa568ee4 100644 --- a/turbo.json +++ b/turbo.json @@ -38,7 +38,7 @@ "DATABASE_URL" ] }, - "@snipcode/database#build": { + "@snipcode/domain#build": { "dependsOn": [ "^build", "prebuild" diff --git a/yarn.lock b/yarn.lock index f0344c31..26749a1c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5459,6 +5459,7 @@ __metadata: version: 0.0.0-use.local resolution: "@snipcode/embed@workspace:packages/embed" dependencies: + "@snipcode/domain": "workspace:*" "@types/express": "npm:4.17.21" express: "npm:4.19.1" nodemon: "npm:2.0.22"