From c8058a98e69087d6df57dd8d3ccb5a178bd05cc4 Mon Sep 17 00:00:00 2001 From: jozzi Date: Sat, 15 Apr 2023 00:57:27 +0200 Subject: [PATCH 1/6] feat(docker): define docker-compose for postgres and mongo dbs --- docker-compose.yaml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 docker-compose.yaml diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..c02eacf --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,24 @@ +version: '3.8' + +name: adminjs-prisma + +services: + postgres: + image: postgres:latest + restart: always + environment: + POSTGRES_DB: example + POSTGRES_USER: root + POSTGRES_PASSWORD: example + ports: + - '5438:5432' + + mongo: # This image automatically creates a replica set required for transactions + image: prismagraphql/mongo-single-replica:4.4.3-bionic + restart: always + environment: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: example + MONGO_INITDB_DATABASE: example + ports: + - '27017:27017' From c241cab6efdb17a56b1cc797c828a0d4863cbcfa Mon Sep 17 00:00:00 2001 From: jozzi Date: Sat, 15 Apr 2023 01:00:19 +0200 Subject: [PATCH 2/6] feat(setup): added support for 2 DBS * created yarn scripts * prepared files structure to support 2 DBs --- .env.example | 2 + .gitignore | 2 +- package.json | 7 ++- spec/.mongo.prisma/schema.prisma | 46 +++++++++++++++++++ .../migration.sql | 0 .../schema.prisma | 6 +-- 6 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 .env.example create mode 100644 spec/.mongo.prisma/schema.prisma rename spec/{prisma => .postgres.prisma}/migrations/20211122063611_uuid_ossp_extension/migration.sql (100%) rename spec/{prisma => .postgres.prisma}/schema.prisma (86%) diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1fbf798 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +MONGO_DATABASE_URL="mongodb://root:example@localhost:27017/example?authSource=admin" +POSTGRESQL_DATABASE_URL="postgresql://root:example@localhost:5438/example?schema=public" diff --git a/.gitignore b/.gitignore index 0e6bf3e..fcb2012 100644 --- a/.gitignore +++ b/.gitignore @@ -160,4 +160,4 @@ types build lib .adminjs -/spec/prisma/migrations +/spec/prisma diff --git a/package.json b/package.json index beb7fc1..0e202a4 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,12 @@ "ts-node": "ts-node", "lint": "eslint './src/**/*.{ts,js}' './spec/**/*.{ts,js}' './example-app/**/*.{ts,js}' --ignore-pattern 'build' --ignore-pattern 'yarn.lock'", "check:all": "yarn lint && yarn test && yarn build", - "release": "semantic-release" + "release": "semantic-release", + "db:setup": "docker-compose up -d", + "db:migrate": "prisma migrate dev --name init", + "prisma:reset": "rm -rf spec/prisma", + "test:setup:mongo": "yarn prisma:reset && cp -r spec/.mongo.prisma spec/prisma && prisma generate", + "test:setup:postgresql": "yarn prisma:reset && cp -r spec/.postgres.prisma spec/prisma && yarn db:migrate && prisma generate" }, "repository": { "type": "git", diff --git a/spec/.mongo.prisma/schema.prisma b/spec/.mongo.prisma/schema.prisma new file mode 100644 index 0000000..5265a8b --- /dev/null +++ b/spec/.mongo.prisma/schema.prisma @@ -0,0 +1,46 @@ +datasource db { + provider = "mongodb" + url = env("MONGO_DATABASE_URL") +} + +generator client { + provider = "prisma-client-js" +} + +enum Status { + ACTIVE + REMOVED +} + +model Post { + id String @id @default(uuid()) @map("_id") + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + title String + content String? + someJson Json? @db.Json + status Status @default(ACTIVE) + published Boolean @default(false) + author User @relation(fields: [authorId], references: [id]) + authorId String +} + +model Profile { + id String @id @default(uuid()) @map("_id") + bio String? + user User @relation(fields: [userId], references: [id]) + userId String @unique +} + +model User { + id String @id @default(uuid()) @map("_id") + email String @unique + name String? + posts Post[] + profile Profile? +} + +model UuidExample { + id String @id @default(uuid()) @map("_id") + label String +} diff --git a/spec/prisma/migrations/20211122063611_uuid_ossp_extension/migration.sql b/spec/.postgres.prisma/migrations/20211122063611_uuid_ossp_extension/migration.sql similarity index 100% rename from spec/prisma/migrations/20211122063611_uuid_ossp_extension/migration.sql rename to spec/.postgres.prisma/migrations/20211122063611_uuid_ossp_extension/migration.sql diff --git a/spec/prisma/schema.prisma b/spec/.postgres.prisma/schema.prisma similarity index 86% rename from spec/prisma/schema.prisma rename to spec/.postgres.prisma/schema.prisma index 8827500..2586e47 100644 --- a/spec/prisma/schema.prisma +++ b/spec/.postgres.prisma/schema.prisma @@ -1,6 +1,6 @@ datasource db { provider = "postgresql" - url = env("DATABASE_URL") + url = env("POSTGRESQL_DATABASE_URL") } generator client { @@ -41,6 +41,6 @@ model User { } model UuidExample { - id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid - label String + id String @id @default(dbgenerated("uuid_generate_v4()")) @db.Uuid + label String } From 80846806304851fe60d9bddd3a9bf7eda5ce3f45 Mon Sep 17 00:00:00 2001 From: jozzi Date: Sat, 15 Apr 2023 01:01:18 +0200 Subject: [PATCH 3/6] fix(test): fix tests for multiple dbs --- spec/Resource.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/Resource.spec.ts b/spec/Resource.spec.ts index ebb1146..94172c6 100644 --- a/spec/Resource.spec.ts +++ b/spec/Resource.spec.ts @@ -8,6 +8,7 @@ describe('Resource', () => { let resource: Resource; let prisma: PrismaClient; let dmmf: DMMFClass; + let provider: string; const data = { name: 'Someone', @@ -17,6 +18,7 @@ describe('Resource', () => { beforeAll(async () => { prisma = new PrismaClient(); dmmf = ((prisma as any)._baseDmmf as DMMFClass); + provider = ((prisma as any)._engineConfig.activeProvider as string); }); beforeEach(async () => { @@ -43,7 +45,7 @@ describe('Resource', () => { describe('#databaseType', () => { it('returns database dialect', () => { - expect(resource.databaseType()).toEqual('postgresql'); + expect(resource.databaseType()).toEqual(provider); }); }); From a442e781d5cf11e743d9c09279ce0c795552cbbb Mon Sep 17 00:00:00 2001 From: jozzi Date: Sat, 15 Apr 2023 01:02:27 +0200 Subject: [PATCH 4/6] fix(mongo): fix for update action with mongoDB --- spec/Resource.spec.ts | 1 + src/Resource.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/Resource.spec.ts b/spec/Resource.spec.ts index 94172c6..b8bb561 100644 --- a/spec/Resource.spec.ts +++ b/spec/Resource.spec.ts @@ -98,6 +98,7 @@ describe('Resource', () => { const name = 'Michael'; await resource.update((record && record.id()) as string, { + ...record?.params, name, }); const recordInDb = await resource.findOne( diff --git a/src/Resource.ts b/src/Resource.ts index 3a4b334..74e94f1 100644 --- a/src/Resource.ts +++ b/src/Resource.ts @@ -169,7 +169,7 @@ export class Resource extends BaseResource { const key = property.path(); // eslint-disable-next-line no-continue - if (param === undefined) continue; + if (param === undefined || property.isId()) continue; const type = property.type(); const foreignColumnName = property.foreignColumnName(); From 98d52e72d008f16f7dcb1458fed0a05e35191774 Mon Sep 17 00:00:00 2001 From: jozzi Date: Sat, 15 Apr 2023 01:17:19 +0200 Subject: [PATCH 5/6] fix(ci): fix github workflow * fix test step in github workflow * add step to run mongo tests --- .github/workflows/push.yml | 52 +++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 7f90ce9..1070da4 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -22,13 +22,13 @@ jobs: if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install - test: - name: Test + test-postgres: + name: Tests with postgres runs-on: ubuntu-latest needs: setup env: NODE_ENV: test - DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/prisma_example_test?schema=public" + POSTGRESQL_DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/prisma_example_test?schema=public" services: postgres: image: postgres:10.8 @@ -59,14 +59,52 @@ jobs: run: yarn install - name: Lint run: yarn lint - - name: Migrate - run: npx prisma migrate dev + - name: Setup prisma for tests + run: yarn test:setup:postgresql - name: Test run: yarn test - + + test-mongo: + name: Tests with mongo + runs-on: ubuntu-latest + needs: setup + env: + NODE_ENV: test + MONGO_DATABASE_URL: "mongodb://root:example@localhost:27017/example?authSource=admin" + services: + mongo: + image: prismagraphql/mongo-single-replica:4.4.3-bionic + env: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: example + MONGO_INITDB_DATABASE: example + ports: + - 27017:27017 + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup + uses: actions/setup-node@v2 + with: + node-version: '14' + - uses: actions/cache@v1 + id: yarn-cache + with: + path: node_modules + key: ${{ runner.os }}-node_modules-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-node_modules- + - name: Install + if: steps.yarn-cache.outputs.cache-hit != 'true' + run: yarn install + - name: Setup prisma for tests + run: yarn test:setup:mongo + - name: Test + run: yarn test + publish: name: Publish - needs: test + needs: [test-mongo, test-postgres] runs-on: ubuntu-latest steps: - name: Checkout From 3a22f5ca3ba5274919dae6c698595c27735c0428 Mon Sep 17 00:00:00 2001 From: jozzi Date: Sat, 15 Apr 2023 01:57:48 +0200 Subject: [PATCH 6/6] fix: fix issue https://github.com/SoftwareBrothers/adminjs/issues/1452 --- spec/.mongo.prisma/schema.prisma | 11 ++++++----- spec/.postgres.prisma/schema.prisma | 11 ++++++----- spec/Resource.spec.ts | 12 ++++++++---- src/Property.ts | 2 +- src/Resource.ts | 2 +- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/spec/.mongo.prisma/schema.prisma b/spec/.mongo.prisma/schema.prisma index 5265a8b..aaace63 100644 --- a/spec/.mongo.prisma/schema.prisma +++ b/spec/.mongo.prisma/schema.prisma @@ -33,11 +33,12 @@ model Profile { } model User { - id String @id @default(uuid()) @map("_id") - email String @unique - name String? - posts Post[] - profile Profile? + id String @id @default(uuid()) @map("_id") + email String @unique + name String? + posts Post[] + profile Profile? + updatedAt DateTime @default(now()) @updatedAt } model UuidExample { diff --git a/spec/.postgres.prisma/schema.prisma b/spec/.postgres.prisma/schema.prisma index 2586e47..95d7702 100644 --- a/spec/.postgres.prisma/schema.prisma +++ b/spec/.postgres.prisma/schema.prisma @@ -33,11 +33,12 @@ model Profile { } model User { - id Int @id @default(autoincrement()) - email String @unique - name String? - posts Post[] - profile Profile? + id Int @id @default(autoincrement()) + email String @unique + name String? + posts Post[] + profile Profile? + updatedAt DateTime @default(now()) @updatedAt } model UuidExample { diff --git a/spec/Resource.spec.ts b/spec/Resource.spec.ts index b8bb561..a037d45 100644 --- a/spec/Resource.spec.ts +++ b/spec/Resource.spec.ts @@ -57,13 +57,13 @@ describe('Resource', () => { describe('#properties', () => { it('returns all the properties', () => { - expect(resource.properties()).toHaveLength(3); + expect(resource.properties()).toHaveLength(4); }); it('returns all properties with the correct position', () => { expect( resource.properties().map((property) => property.position()), - ).toEqual([0, 1, 2]); + ).toEqual([0, 1, 2, 3]); }); }); @@ -97,15 +97,19 @@ describe('Resource', () => { record = await resource.findOne(params.id); const name = 'Michael'; + jest.useFakeTimers().advanceTimersByTime(10000); await resource.update((record && record.id()) as string, { ...record?.params, name, }); + jest.useRealTimers() + const recordInDb = await resource.findOne( (record && record.id()) as string, ); expect(recordInDb && recordInDb.get('name')).toEqual(name); + expect(record?.get('updatedAt')).not.toEqual(recordInDb?.get('updatedAt')); }); }); @@ -122,7 +126,7 @@ describe('Resource', () => { const filter = new Filter(undefined, resource); filter.filters = { name: { path: 'name', value: params.name, property: resource.property('name') as BaseProperty }, - } + }; record = await resource.find(filter); expect(record[0] && record[0].get('name')).toEqual(data.name); @@ -138,7 +142,7 @@ describe('Resource', () => { const filter = new Filter(undefined, uuidResource); filter.filters = { id: { path: 'id', value: params.id, property: uuidResource.property('id') as BaseProperty }, - } + }; record = await uuidResource.find(filter); expect(record[0] && record[0].get('id')).toEqual(params.id); diff --git a/src/Property.ts b/src/Property.ts index 55a15f8..035d0e5 100644 --- a/src/Property.ts +++ b/src/Property.ts @@ -20,7 +20,7 @@ export class Property extends BaseProperty { } public isEditable(): boolean { - return !this.isId() && this.column.name !== 'createdAt' && this.column.name !== 'updatedAt'; + return !this.isId() && this.column.name !== 'createdAt' && !this.column.isUpdatedAt; } public isId(): boolean { diff --git a/src/Resource.ts b/src/Resource.ts index 74e94f1..b4925a8 100644 --- a/src/Resource.ts +++ b/src/Resource.ts @@ -169,7 +169,7 @@ export class Resource extends BaseResource { const key = property.path(); // eslint-disable-next-line no-continue - if (param === undefined || property.isId()) continue; + if (param === undefined || !property.isEditable()) continue; const type = property.type(); const foreignColumnName = property.foreignColumnName();