Skip to content

Commit 15cad84

Browse files
committed
fix isEmpty check to ignore ObjectId
1 parent 4d7031b commit 15cad84

File tree

17 files changed

+69
-26
lines changed

17 files changed

+69
-26
lines changed

docusaurus/docs/vulcan-fire/mongo.md

+6
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,16 @@ Vulcan Next already does it for you in the `api/graphql` API route.
1717

1818
- Use `GraphqlObjectId` as the `typeName` for every unique identifier in your schemas.
1919

20+
Server to client: this is not strictly needed when queriying document, because ObjectId will serialize to String anyway.
21+
Client to server: this is needed when filtering or when mutating document, the scalar will convert the string back to an `ObjectId`,
22+
which is necessary for your search queries or your mutations to work correctly
23+
2024
**If you encounter issues with filtering**, you might have forgotten to add this `typeName`.
2125

2226
Example:
2327
```js
28+
import { GraphqlObjectId } from "@vulcanjs/mongo-apollo"
29+
...
2430
schema: {
2531
_id: {
2632
type: String,
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* GraphQL type for a Mongo ObjectId
3+
*
4+
* Use as "typeName" in your Vulcan schema for _id, userId, or any field with relations via ids
5+
*/
6+
export const GraphQLObjectIdTypeName = "GraphQLObjectId";
7+
/**
8+
* Alias for GraphQLObjectId
9+
*/
10+
export const MongoId = GraphQLObjectIdTypeName;

packages/mongo-apollo/index.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1 @@
1-
export * from "./addDefaultMongoConnector";
2-
export * from "./createMongooseDataSource";
3-
4-
export * from "./objectIdScalar";
1+
export * from "./graphqlObjectId";

packages/mongo-apollo/package.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@
88
],
99
"type": "module",
1010
"exports": {
11-
".": "./dist/index.js"
11+
".": "./dist/index.js",
12+
"./server": "./dist/server/index.js"
1213
},
1314
"types": "./dist/index.d.ts",
15+
"typesVersions": {
16+
"*": {
17+
"server": [
18+
"./dist/server/index.d.ts"
19+
]
20+
}
21+
},
1422
"author": "eric-burel <[email protected]>",
1523
"homepage": "https://github.com/VulcanJS/vulcan-npm#readme",
1624
"license": "MIT",

packages/mongo-apollo/server/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from "./addDefaultMongoConnector";
2+
export * from "./createMongooseDataSource";
3+
4+
export * from "./objectIdScalar";

packages/mongo-apollo/objectIdScalar.ts packages/mongo-apollo/server/objectIdScalar.ts

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
// @see https://github.com/CaptorAB/graphql-objectid-scalar
22
import { GraphQLObjectId } from "graphql-objectid-scalar";
3-
4-
/**
5-
* GraphQL type for a Mongo ObjectId
6-
*
7-
* Use as "typeName" in your Vulcan schema for _id, userId, or any field with relations via ids
8-
*/
9-
export const GraphqlObjectId = "GraphQLObjectId";
3+
import { GraphQLObjectIdTypeName } from "../graphqlObjectId";
104

115
/**
126
* NOTE: the type is ObjectID to be consistent with GraphQL "ID" type
137
* Be careful with the casing
148
*/
159
export const objectIdTypeDefs = `
16-
scalar ${GraphqlObjectId}
10+
scalar ${GraphQLObjectIdTypeName}
1711
1812
# Inspired by the String_Selector
1913
input GraphQLObjectId_Selector {
20-
_eq: ${GraphQLObjectId}
21-
_in: [${GraphQLObjectId}!]
14+
_eq: ${GraphQLObjectIdTypeName}
15+
_in: [${GraphQLObjectIdTypeName}!]
2216
_is_null: Boolean
23-
_neq: ${GraphqlObjectId}
17+
_neq: ${GraphQLObjectIdTypeName}
2418
}
2519
`;
2620

packages/mongo-apollo/tsup.config.ts

+7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ const commonConfig = {
1010
tsconfig: path.resolve(__dirname, "./tsconfig.build.json"),
1111
};
1212
export default defineConfig([
13+
{
14+
entry: ["server/index.ts"],
15+
...commonConfig,
16+
// NOTE: it means CJS will be .js and ESM will be .mjs
17+
format: ["esm"],
18+
outDir: "dist/server",
19+
},
1320
{
1421
entry: ["index.ts"],
1522
...commonConfig,

packages/utils/string.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -356,4 +356,6 @@ export const isEmptyOrUndefined = (value) =>
356356
typeof value === "undefined" ||
357357
value === null ||
358358
value === "" ||
359-
(typeof value === "object" && isEmpty(value) && !(value instanceof Date));
359+
(typeof value === "object" &&
360+
isEmpty(value) &&
361+
!String(value.constructor).match("Object()"));

starters/next/src/core/models.server.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const models = [User, SampleModel];
66

77
// Add default connectors and dataSources creators for models that may miss some
88
// @see https://www.apollographql.com/docs/apollo-server/data/data-sources
9-
import { addDefaultMongoConnector } from "@vulcanjs/mongo-apollo";
9+
import { addDefaultMongoConnector } from "@vulcanjs/mongo-apollo/server";
1010
addDefaultMongoConnector(models);
1111

1212
export default models;

starters/next/src/pages/api/graphql.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ import { connectToAppDbMiddleware } from "~/core/server/middlewares/mongoAppConn
2525
* You may remove it if you prefer string ids (as Meteor does)
2626
* @see https://stackoverflow.com/questions/27896979/difference-between-storing-an-objectid-and-its-string-form-in-mongodb
2727
*/
28-
import { objectIdTypeDefs, objectIdResolvers } from "@vulcanjs/mongo-apollo";
28+
import {
29+
objectIdTypeDefs,
30+
objectIdResolvers,
31+
} from "@vulcanjs/mongo-apollo/server";
2932

3033
/**
3134
* Generate basic CRUD resolvers with Vulcan Fire

starters/next/src/pages/vn/admin/crud/[modelName].tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ export default function CrudPage({ modelName }) {
5454
const model = getCurrentModel(modelName);
5555

5656
// Read
57-
const documentsRawResult = useMulti({ model });
57+
const documentsRawResult = useMulti<any>({
58+
model,
59+
//input: { filter: { _id: { _eq: "" } } },
60+
});
5861
const documentsResult = documentsRawResult.documents || [];
5962

6063
// Select
@@ -100,7 +103,7 @@ export default function CrudPage({ modelName }) {
100103
{
101104
<List>
102105
{documentsResult.map((document) => (
103-
<ListItem key={document.id}>
106+
<ListItem key={document._id}>
104107
<ItemCard document={document} model={model} />
105108
</ListItem>
106109
))}

starters/next/src/vulcan-demo/models/sampleModel.ts

+4
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,20 @@ import {
99
VulcanGraphqlSchema,
1010
} from "@vulcanjs/graphql";
1111
import { User } from "~/account/models/user";
12+
import { MongoId } from "@vulcanjs/mongo-apollo";
1213

1314
export const schema: VulcanGraphqlSchema = {
1415
/** Unique id of the document in the database. You'll want to leave this field as is. */
1516
_id: {
17+
typeName: MongoId,
1618
type: String,
1719
optional: true,
1820
canRead: ["guests", "anyone"],
1921
},
2022
/** _id of the user that created the document. This special field is used to handle the "ownership" of the document. */
2123
userId: {
2224
type: String,
25+
typeName: MongoId,
2326
optional: true,
2427
canRead: ["guests", "anyone"],
2528
// This means you can resolve the "user" field when fetching for "samples"
@@ -54,6 +57,7 @@ export const schema: VulcanGraphqlSchema = {
5457
// this may make data fetching easier in the frontend (the client can know the relation)
5558
demoRelationFieldUserId: {
5659
type: String,
60+
typeName: MongoId,
5761
optional: true,
5862
relation: {
5963
fieldName: "resolvedFieldFromRelation",

test/integration/server/filtering.test.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { MongoMemoryServer } from "mongodb-memory-server"; // @see https://githu
1515
import { buildDefaultQueryResolvers } from "@vulcanjs/graphql/server";
1616
import { createGraphqlModelServer } from "@vulcanjs/graphql/server";
1717
import { createMongooseConnector } from "@vulcanjs/mongo";
18-
import { GraphqlObjectId } from "../../../packages/mongo-apollo";
18+
import { MongoId } from "@vulcanjs/mongo-apollo";
1919
import { makeApolloServer } from "./utils/server";
2020

2121
// Init an in-memory Mongo server
@@ -45,7 +45,7 @@ const Contributor = createGraphqlModelServer({
4545
schema: {
4646
_id: {
4747
type: String,
48-
typeName: GraphqlObjectId,
48+
typeName: MongoId,
4949
optional: true,
5050
canRead: ["anyone"],
5151
canCreate: ["anyone"],
@@ -78,7 +78,7 @@ const Repository = createGraphqlModelServer({
7878
schema: {
7979
_id: {
8080
type: String,
81-
typeName: GraphqlObjectId,
81+
typeName: MongoId,
8282
optional: true,
8383
canRead: ["anyone"],
8484
canCreate: ["anyone"],
@@ -87,6 +87,7 @@ const Repository = createGraphqlModelServer({
8787
},
8888
userId: {
8989
type: String,
90+
typeName: MongoId,
9091
optional: true,
9192
canRead: ["anyone"],
9293
},
@@ -100,7 +101,7 @@ const Repository = createGraphqlModelServer({
100101
},
101102
contributorId: {
102103
type: String,
103-
typeName: GraphqlObjectId,
104+
typeName: MongoId,
104105
// You will be able to query the "contributor" field of any "repository" object
105106
relation: {
106107
fieldName: "contributor",

test/integration/server/utils/server.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import { contextFromReq } from "./context";
99
import { ApolloServer } from "apollo-server-express";
1010

1111
import { mergeResolvers, mergeTypeDefs } from "@graphql-tools/merge";
12-
import { objectIdTypeDefs, objectIdResolvers } from "@vulcanjs/mongo-apollo";
12+
import {
13+
objectIdTypeDefs,
14+
objectIdResolvers,
15+
} from "@vulcanjs/mongo-apollo/server";
1316

1417
// Demo Apollo server
1518
export const makeApolloServer = async (models: Array<VulcanGraphqlModel>) => {

typedoc.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = {
1515
"packages/mongo/index.ts",
1616
"packages/mongo/client/index.ts",
1717
"packages/mongo-apollo/index.ts",
18+
"packages/mongo-apollo/server/index.ts",
1819
"packages/permissions/index.ts",
1920
"packages/react-hooks/index.ts",
2021
"packages/react-i18n/index.ts",

0 commit comments

Comments
 (0)