Skip to content

Commit

Permalink
feat: add mongoose 7 compatibility (by @meabed)
Browse files Browse the repository at this point in the history
* chore: fix mongoose 7 compatibility

* chore: fix mongoose 7 compatibility

* chore: format

* chore: fix import

* chore: fix validate

* chore: fix validate

* chore: update package.json

* chore: update mongoose and typescript

* chore: fix validate

* chore: fix test

* chore: fix test

* chore: fix test

* chore: fix test

* chore: update dependencies

* chore: update dependencies

* chore: fix typescript

* chore: fix typescript

* chore: update github actions

* chore: update github actions

* chore: update github actions

* fix: update jest

* chore: update jest, release and github actions

* chore: github actions

* chore: update test
  • Loading branch information
meabed authored Mar 2, 2023
1 parent 91cdfd0 commit 0dcc2c2
Show file tree
Hide file tree
Showing 13 changed files with 2,404 additions and 4,007 deletions.
34 changes: 25 additions & 9 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,22 @@ on: [push, pull_request]
jobs:
tests:
runs-on: ubuntu-latest
permissions:
packages: write
contents: write
strategy:
matrix:
node-version: [14.x, 16.x]
node-version: [14.x, 16.x, 18.x]
steps:
- uses: actions/checkout@v2
- run: echo "🎉 The job was triggered by a ${{ github.event_name }} event."
- uses: styfle/[email protected]
with:
workflow_id: nodejs.yml
access_token: ${{ secrets.GITHUB_TOKEN }}
- uses: FranzDiebold/github-env-vars-action@v2
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install node_modules
Expand All @@ -23,10 +32,14 @@ jobs:
run: yarn test
env:
CI: true
- name: Testing with previous mongoose versions
run: yarn test-prev-vers
- name: Testing with previous mongoose versions 6
run: yarn test-prev-vers-6
env:
CI: true
- name: Testing with previous mongoose versions 5
run: yarn test-prev-vers-5
env:
CI: true
CI: true
- name: Send codecov.io stats
if: matrix.node-version == '14.x'
run: bash <(curl -s https://codecov.io/bash) || echo ''
Expand All @@ -35,18 +48,21 @@ jobs:
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/alpha' || github.ref == 'refs/heads/beta'
needs: [tests]
runs-on: ubuntu-latest
permissions:
packages: write
contents: write
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Use Node.js 14
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 14.x
- name: Install node_modules
run: yarn install
- name: Build
run: yarn build
- name: Semantic Release (publish to npm)
run: yarn semantic-release
run: npx semantic-release@19
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
Expand Down
40 changes: 20 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,33 @@
},
"homepage": "https://github.com/graphql-compose/graphql-compose-mongoose",
"dependencies": {
"dataloader": "^2.0.0",
"dataloader": "^2.2.2",
"graphql-compose-connection": "8.2.1",
"graphql-compose-pagination": "8.3.0"
},
"peerDependencies": {
"graphql-compose": "^7.21.4 || ^8.0.0 || ^9.0.0",
"mongoose": "^6.0.0 || ^5.0.0 || ^4.4.0"
"mongoose": "^7.0.0 || ^6.0.0 || ^5.0.0 || ^4.4.0"
},
"devDependencies": {
"@types/jest": "27.0.3",
"@typescript-eslint/eslint-plugin": "5.7.0",
"@typescript-eslint/parser": "5.7.0",
"eslint": "8.4.1",
"@types/jest": "28.1.8",
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/parser": "5.54.0",
"eslint": "8.35.0",
"eslint-config-airbnb-base": "15.0.0",
"eslint-config-prettier": "8.3.0",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-prettier": "4.0.0",
"graphql": "16.1.0",
"graphql-compose": "9.0.5",
"jest": "27.4.5",
"mongodb-memory-server": "8.0.4",
"mongoose": "6.1.2",
"prettier": "2.5.1",
"eslint-config-prettier": "8.6.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-prettier": "4.2.1",
"graphql": "16.6.0",
"graphql-compose": "9.0.10",
"jest": "28.1.3",
"mongodb-memory-server": "8.11.5",
"mongoose": "7.0.0",
"prettier": "2.8.4",
"request": "2.88.2",
"rimraf": "3.0.2",
"semantic-release": "18.0.1",
"ts-jest": "27.1.1",
"typescript": "4.5.4"
"rimraf": "4.1.3",
"ts-jest": "28.0.8",
"typescript": "4.9.5"
},
"scripts": {
"prepare": "tsc -p ./tsconfig.build.json",
Expand All @@ -65,6 +64,7 @@
"link": "yarn build && yarn link graphql-compose && yarn link graphql-compose-connection && yarn link graphql-compose-pagination && yarn link mongoose && yarn link",
"unlink": "rimraf node_modules && yarn install",
"semantic-release": "semantic-release",
"test-prev-vers": "yarn add [email protected] --dev --ignore-scripts && yarn coverage && git checkout HEAD -- package.json yarn.lock"
"test-prev-vers-6": "yarn add [email protected] --dev --ignore-scripts && yarn coverage && git checkout HEAD -- package.json yarn.lock",
"test-prev-vers-5": "yarn add [email protected] --dev --ignore-scripts && yarn coverage && git checkout HEAD -- package.json yarn.lock"
}
}
4 changes: 2 additions & 2 deletions src/composeMongoose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,14 @@ export type GenerateResolverType<TDoc extends Document, TContext = any> = {
// because first two args will be attached via bind() method at runtime:
// count = count.bind(undefined, model, tc);
[resolver in keyof typeof resolverFactory]: <TSource = any>(
opts?: Parameters<typeof resolverFactory[resolver]>[2]
opts?: Parameters<(typeof resolverFactory)[resolver]>[2]
) => // Also we should patch generics of the returned Resolver
// attach TContext TDoc from the code which will bind at runtime
// and allow user to attach TSource via generic at call
// For this case we are using `extends infer` construction
// it helps to extract any Generic from existed method
// and then construct new combined return type
typeof resolverFactory[resolver] extends (...args: any) => Resolver<any, any, infer TArgs, any>
(typeof resolverFactory)[resolver] extends (...args: any) => Resolver<any, any, infer TArgs, any>
? Resolver<TSource, TContext, TArgs, TDoc>
: any;
};
Expand Down
3 changes: 2 additions & 1 deletion src/fieldsConverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ export function deriveComplexType(field: MongooseFieldT): ComplexTypes {
return ComplexTypes.ARRAY;
} else if (field instanceof mongoose.Schema.Types.Mixed) {
return ComplexTypes.MIXED;
} else if (fieldType === 'ObjectID') {
} else if (fieldType === 'ObjectID' || fieldType === 'ObjectId') {
return ComplexTypes.REFERENCE;
} else if (fieldType === 'Decimal128') {
return ComplexTypes.DECIMAL;
Expand Down Expand Up @@ -317,6 +317,7 @@ export function scalarToGraphQL(field: MongooseFieldT): ComposeScalarType {
return 'Buffer';
case 'Boolean':
return 'Boolean';
case 'ObjectId':
case 'ObjectID':
return 'MongoID';
default:
Expand Down
13 changes: 7 additions & 6 deletions src/resolvers/__tests__/count-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { UserModel } from '../../__mocks__/userModel';
import { count } from '../count';
import { convertModelToGraphQL } from '../../fieldsConverter';
import { ExtendedResolveParams } from '..';
import { version } from 'mongoose';

beforeAll(() => UserModel.base.createConnection());
afterAll(() => UserModel.base.disconnect());
Expand Down Expand Up @@ -102,21 +103,21 @@ describe('count() ->', () => {
beforeQuery: (query: any, rp: ExtendedResolveParams) => {
expect(query).toHaveProperty('exec');
expect(rp.model).toBe(UserModel);

// modify query before execution
return query.limit(1);
},
});

expect(mongooseActions).toEqual([
[
'users',
'countDocuments',
{},
{
limit: 1,
},
],
version.startsWith('7')
? undefined
: {
limit: 1,
},
].filter(Boolean),
]);

expect(result).toBe(1);
Expand Down
8 changes: 7 additions & 1 deletion src/resolvers/__tests__/removeById-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import GraphQLMongoID from '../../types/MongoID';
import { convertModelToGraphQL } from '../../fieldsConverter';
import { ExtendedResolveParams } from '..';
import { testFieldConfig } from '../../utils/testHelpers';
import { version } from 'mongoose';

beforeAll(() => UserModel.base.createConnection());
afterAll(() => UserModel.base.disconnect());
Expand Down Expand Up @@ -187,7 +188,12 @@ describe('removeById() ->', () => {
const result = await removeById(UserModel, UserTC).resolve(resolveParams);

expect(mongooseActions).toEqual([
['users', 'findOne', { _id: user._id, gender: 'some' }, { projection: {} }],
[
'users',
'findOne',
{ _id: user._id, gender: 'some' },
version.startsWith('7') ? undefined : { projection: {} },
].filter(Boolean),
]);

expect(result).toBeNull();
Expand Down
2 changes: 1 addition & 1 deletion src/resolvers/helpers/filterOperators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const availableOperators = [
'exists',
] as const;

export type AllowedOperatorsName = typeof availableOperators[number];
export type AllowedOperatorsName = (typeof availableOperators)[number];

/**
* Customize operators filtering or disable it at all.
Expand Down
7 changes: 4 additions & 3 deletions src/resolvers/helpers/validate.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Error as MongooseError } from 'mongoose';
import type { Document } from 'mongoose';
import { version as MongooseVersion } from 'mongoose';
import { ValidationError } from '../../errors';

export type ValidationErrorData = {
Expand All @@ -19,9 +20,9 @@ export type ValidationsWithMessage = {
};

export async function validateDoc(doc: Document): Promise<ValidationsWithMessage | null> {
const validations: MongooseError.ValidationError | null = await new Promise((resolve) => {
doc.validate(resolve as any);
});
const validations: MongooseError.ValidationError | null = MongooseVersion.startsWith('7')
? doc.validateSync()
: await new Promise((resolve) => doc.validate(resolve as any));

return validations?.errors
? {
Expand Down
6 changes: 5 additions & 1 deletion src/resolvers/removeById.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ export function removeById<TSource = any, TContext = any, TDoc extends Document
doc = await resolveParams.beforeRecordMutate(doc, resolveParams);
}
if (doc) {
await doc.remove();
if ('remove' in doc && typeof doc.remove === 'function' && !doc.remove.length) {
await doc.remove();
} else {
await doc.deleteOne();
}

return {
record: doc,
Expand Down
10 changes: 9 additions & 1 deletion src/resolvers/removeMany.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,15 @@ export function removeMany<TSource = any, TContext = any, TDoc extends Document
resolveParams.query = resolveParams.query.deleteMany();
} else {
// old mongoose
resolveParams.query = resolveParams.query.remove();
if (
'remove' in resolveParams.query &&
typeof resolveParams.query.remove === 'function' &&
!resolveParams.query.remove.length
) {
resolveParams.query = resolveParams.query.remove();
} else {
resolveParams.query = resolveParams.query.deleteOne();
}
}

const res = await beforeQueryHelper(resolveParams);
Expand Down
7 changes: 5 additions & 2 deletions src/resolvers/removeOne.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,11 @@ export function removeOne<TSource = any, TContext = any, TDoc extends Document =
}

if (doc) {
await doc.remove();

if ('remove' in doc && typeof doc.remove === 'function' && !doc.remove.length) {
await doc.remove();
} else {
await doc.deleteOne();
}
return {
record: doc,
};
Expand Down
6 changes: 3 additions & 3 deletions src/utils/testHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ const FIELD = 'test_field';
interface TestOperationOpts {
schemaComposer: SchemaComposer<any>;
operation: string;
variables?: Record<string, any>;
variables?: any;
source?: Record<string, any>;
context?: Record<string, any>;
context?: any;
}

async function testOperation(opts: TestOperationOpts): Promise<ExecutionResult> {
Expand Down Expand Up @@ -73,7 +73,7 @@ export async function testFieldConfig<TSource = any, TContext = any, TArgs = any

function _getArgsForQuery(
fc: ObjectTypeComposerFieldConfigAsObjectDefinition<any, any, any> | Resolver<any, any, any>,
variables: Record<string, any> = {},
variables: any = {},
schemaComposer?: SchemaComposer<any>
): {
queryVars: string;
Expand Down
Loading

0 comments on commit 0dcc2c2

Please sign in to comment.