@kubun/graphql 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/schema.js +96 -14
  2. package/package.json +14 -11
package/lib/schema.js CHANGED
@@ -105,7 +105,7 @@ function createEnumValueFilterInput(type) {
105
105
  }
106
106
  });
107
107
  }
108
- function createScalarValueFilterInput(type) {
108
+ function createScalarValueFilterInput(type, options = {}) {
109
109
  return new GraphQLInputObjectType({
110
110
  name: `${type.name}ValueFilter`,
111
111
  isOneOf: true,
@@ -136,6 +136,37 @@ function createScalarValueFilterInput(type) {
136
136
  },
137
137
  greaterThanOrEqualTo: {
138
138
  type
139
+ },
140
+ // Substring match only makes sense against string-backed scalars.
141
+ ...options.stringBacked ? {
142
+ contains: {
143
+ type: GraphQLString
144
+ }
145
+ } : {}
146
+ }
147
+ });
148
+ }
149
+ // Opaque identifiers (DID, DocumentID, AttachmentID): equality only, no ordering
150
+ // or substring match — the underlying strings are content-addressed, not text.
151
+ function createExactValueFilterInput(type) {
152
+ return new GraphQLInputObjectType({
153
+ name: `${type.name}ValueFilter`,
154
+ isOneOf: true,
155
+ fields: {
156
+ isNull: {
157
+ type: GraphQLBoolean
158
+ },
159
+ equalTo: {
160
+ type
161
+ },
162
+ notEqualTo: {
163
+ type
164
+ },
165
+ in: {
166
+ type: toList(type)
167
+ },
168
+ notIn: {
169
+ type: toList(type)
139
170
  }
140
171
  }
141
172
  });
@@ -159,6 +190,7 @@ const VALUE_FILTER_INPUTS = {
159
190
  }
160
191
  }
161
192
  }),
193
+ AttachmentIDValueFilter: createExactValueFilterInput(GraphQLAttachmentID),
162
194
  BooleanValueFilter: new GraphQLInputObjectType({
163
195
  name: 'BooleanValueFilter',
164
196
  isOneOf: true,
@@ -171,16 +203,26 @@ const VALUE_FILTER_INPUTS = {
171
203
  }
172
204
  }
173
205
  }),
206
+ DIDValueFilter: createExactValueFilterInput(GraphQLDID),
207
+ DocumentIDValueFilter: createExactValueFilterInput(GraphQLDocID),
174
208
  FloatValueFilter: createScalarValueFilterInput(GraphQLFloat),
175
209
  IntValueFilter: createScalarValueFilterInput(GraphQLInt),
176
- StringValueFilter: createScalarValueFilterInput(GraphQLString)
210
+ StringValueFilter: createScalarValueFilterInput(GraphQLString, {
211
+ stringBacked: true
212
+ })
177
213
  };
214
+ // Keyed by `scalar.name` (the GraphQL type name, e.g. "DID"), not the import
215
+ // binding — keying by binding name silently never matched here before, since
216
+ // scalars are looked up by `scalar.name`. `_owner` bypasses this map entirely
217
+ // (hardcoded to AccountValueFilter), so it is not listed here.
178
218
  const VALUE_FILTER_INPUT_TYPES = {
179
- GraphQLBoolean: 'BooleanValueFilter',
180
- GraphQLDID: 'AccountValueFilter',
181
- GraphQLFloat: 'FloatValueFilter',
182
- GraphQLInt: 'IntValueFilter',
183
- GraphQLString: 'StringValueFilter'
219
+ AttachmentID: 'AttachmentIDValueFilter',
220
+ Boolean: 'BooleanValueFilter',
221
+ DID: 'DIDValueFilter',
222
+ DocumentID: 'DocumentIDValueFilter',
223
+ Float: 'FloatValueFilter',
224
+ Int: 'IntValueFilter',
225
+ String: 'StringValueFilter'
184
226
  };
185
227
  const PatchSetOperation = new GraphQLInputObjectType({
186
228
  name: 'PatchSetOperation',
@@ -247,6 +289,26 @@ const OrderByDirection = new GraphQLEnumType({
247
289
  }
248
290
  }
249
291
  });
292
+ const ArrayPresence = new GraphQLEnumType({
293
+ name: 'ArrayPresence',
294
+ values: {
295
+ NULL: {
296
+ value: 'null'
297
+ },
298
+ NON_NULL: {
299
+ value: 'nonNull'
300
+ },
301
+ EMPTY: {
302
+ value: 'empty'
303
+ },
304
+ NON_EMPTY: {
305
+ value: 'nonEmpty'
306
+ },
307
+ NULL_OR_EMPTY: {
308
+ value: 'nullOrEmpty'
309
+ }
310
+ }
311
+ });
250
312
  const AccessRule = new GraphQLObjectType({
251
313
  name: 'AccessRule',
252
314
  fields: {
@@ -2161,16 +2223,34 @@ export class SchemaBuilder {
2161
2223
  if (schema.type === 'array') {
2162
2224
  const name = this._aliases[id] ?? pascalCase(parentName + schema.title);
2163
2225
  refParentName = name;
2164
- // const itemType = this._buildReferenceFilterInput(schema.items.$ref, schema.title)
2226
+ const itemID = getReferenceID(schema.items.$ref);
2227
+ const itemSchema = this._getReferenceSchema(itemID);
2228
+ // Membership ops need a scalar item type; array-of-object/array-of-array items
2229
+ // fall back to `isNull`-only filtering (no `_buildScalar` support for them).
2230
+ if (itemSchema.type === 'object' || itemSchema.type === 'array') {
2231
+ return new GraphQLInputObjectType({
2232
+ name: `${name}Filter`,
2233
+ isOneOf: true,
2234
+ fields: {
2235
+ isNull: {
2236
+ type: GraphQLBoolean
2237
+ }
2238
+ }
2239
+ });
2240
+ }
2241
+ const itemScalar = this._buildScalar(itemID, itemSchema, name);
2165
2242
  return new GraphQLInputObjectType({
2166
2243
  name: `${name}Filter`,
2167
2244
  isOneOf: true,
2168
2245
  fields: {
2169
- // DB does not support filtering on array values
2170
- // contains: { type: toList(itemType) },
2171
- // isEmpty: { type: GraphQLBoolean },
2172
- isNull: {
2173
- type: GraphQLBoolean
2246
+ includesAll: {
2247
+ type: toList(itemScalar)
2248
+ },
2249
+ includesAny: {
2250
+ type: toList(itemScalar)
2251
+ },
2252
+ presence: {
2253
+ type: ArrayPresence
2174
2254
  }
2175
2255
  }
2176
2256
  });
@@ -2180,7 +2260,9 @@ export class SchemaBuilder {
2180
2260
  if (knownFilter != null) {
2181
2261
  return this._inputObjects[knownFilter];
2182
2262
  }
2183
- const filter = isEnumType(scalar) ? createEnumValueFilterInput(scalar) : createScalarValueFilterInput(scalar);
2263
+ const filter = isEnumType(scalar) ? createEnumValueFilterInput(scalar) : createScalarValueFilterInput(scalar, {
2264
+ stringBacked: true
2265
+ });
2184
2266
  if (this._inputObjects[filter.name] == null) {
2185
2267
  this._inputObjects[filter.name] = filter;
2186
2268
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubun/graphql",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "keywords": [],
5
5
  "license": "see LICENSE.md",
6
6
  "sideEffects": false,
@@ -22,20 +22,23 @@
22
22
  "change-case": "^5.4.4",
23
23
  "graphql": "^16.14.2",
24
24
  "graphql-relay": "^0.10.2",
25
- "graphql-scalars": "^1.25.0",
25
+ "graphql-scalars": "^1.26.0",
26
26
  "multiformats": "^14.0.5",
27
- "@kubun/id": "^0.12.0",
28
27
  "@kubun/logger": "^0.12.0",
29
- "@kubun/protocol": "^0.12.0",
30
- "@kubun/hlc": "^0.12.0"
28
+ "@kubun/hlc": "^0.12.0",
29
+ "@kubun/id": "^0.12.0",
30
+ "@kubun/protocol": "^0.13.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@kokuin/capability": "^0.2.1",
34
- "@kokuin/token": "^0.3.0",
35
- "@kubun/db": "^0.12.0",
36
- "@kubun/store-graph": "^0.12.0",
37
- "@kubun/test-utils": "^0.12.0",
38
- "@kubun/db-better-sqlite": "^0.12.0"
33
+ "@kokuin/capability": "^0.2.2",
34
+ "@kokuin/token": "^0.4.0",
35
+ "@kubun/store-graph": "^0.13.0",
36
+ "@kubun/db-better-sqlite": "^0.12.1",
37
+ "@kubun/db": "^0.12.1",
38
+ "@kubun/test-utils": "^0.12.0"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
39
42
  },
40
43
  "scripts": {
41
44
  "build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",