@kubun/graphql 0.15.0 → 0.17.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.
package/lib/schema.d.ts CHANGED
@@ -108,6 +108,8 @@ export declare class SchemaBuilder {
108
108
  _getDefinitions(): SharedDefinitions;
109
109
  _getReference(path: string, parentName?: string): GraphQLOutputType;
110
110
  _getReferenceSchema(id: string): TypeModel;
111
+ _getInputObject(key: string): GraphQLInputObjectType;
112
+ _getType(key: string): GraphQLOutputType;
111
113
  _getReferenceInput(path: string, isPartial: boolean, parentName?: string): GraphQLInputType;
112
114
  _buildSharedDefinitions(): SharedDefinitions;
113
115
  _buildDocument(id: string): GraphQLObjectType<DocumentNode, Context> | GraphQLInterfaceType;
package/lib/schema.js CHANGED
@@ -434,7 +434,11 @@ export class SchemaBuilder {
434
434
  // Extract inverse relations
435
435
  for (const [fieldName, meta] of Object.entries(model.fieldsMeta)){
436
436
  if (meta.type === 'document' && meta.model != null) {
437
- const relationRefID = getReferenceID(model.schema.properties[fieldName]?.$ref);
437
+ const relationRef = model.schema.properties[fieldName]?.$ref;
438
+ if (relationRef == null) {
439
+ throw new Error(`Field ${fieldName} not found on model ${modelIDstring}`);
440
+ }
441
+ const relationRefID = getReferenceID(relationRef);
438
442
  const isList = this._getReferenceSchema(relationRefID).type === 'array';
439
443
  const relationID = getGlobalID(meta.model, modelID).toString();
440
444
  this._relationsTo[relationID] ??= {};
@@ -537,7 +541,7 @@ export class SchemaBuilder {
537
541
  this._buildDocument(id);
538
542
  const name = this._aliases[id];
539
543
  const filterArg = {
540
- type: this._inputObjects[`${id}-filter`]
544
+ type: this._getInputObject(`${id}-filter`)
541
545
  };
542
546
  queryFields[`all${name}`] = {
543
547
  type: this._types[`${id}-connection`],
@@ -545,7 +549,7 @@ export class SchemaBuilder {
545
549
  ...connectionArgs,
546
550
  filter: filterArg,
547
551
  orderBy: {
548
- type: toList(this._inputObjects[`${id}-order`])
552
+ type: toList(this._getInputObject(`${id}-order`))
549
553
  },
550
554
  search: {
551
555
  type: GraphQLString
@@ -563,7 +567,11 @@ export class SchemaBuilder {
563
567
  ][0];
564
568
  if (firstModelID != null) {
565
569
  const someConnectionType = this._types[`${firstModelID}-connection`];
566
- const pageInfoType = someConnectionType.getFields().pageInfo.type;
570
+ const pageInfoField = someConnectionType.getFields().pageInfo;
571
+ if (pageInfoField == null) {
572
+ throw new Error('Connection type is missing the pageInfo field');
573
+ }
574
+ const pageInfoType = pageInfoField.type;
567
575
  const searchResultEdge = new GraphQLObjectType({
568
576
  name: 'SearchResultEdge',
569
577
  fields: ()=>({
@@ -641,6 +649,9 @@ export class SchemaBuilder {
641
649
  const edges = [];
642
650
  for(let j = 0; j < page.length; j++){
643
651
  const r = page[j];
652
+ if (r == null) {
653
+ continue;
654
+ }
644
655
  const node = docMap.get(r.documentID);
645
656
  if (node != null) {
646
657
  // Cursor = hits consumed through this position, so the next page
@@ -658,7 +669,7 @@ export class SchemaBuilder {
658
669
  pageInfo: {
659
670
  hasNextPage,
660
671
  hasPreviousPage: offset > 0,
661
- startCursor: edges.length > 0 ? edges[0].cursor : null,
672
+ startCursor: edges.length > 0 ? edges[0]?.cursor ?? null : null,
662
673
  endCursor: page.length > 0 ? encodeSearchCursor(endOffset) : null
663
674
  }
664
675
  };
@@ -1074,6 +1085,20 @@ export class SchemaBuilder {
1074
1085
  }
1075
1086
  return schema;
1076
1087
  }
1088
+ _getInputObject(key) {
1089
+ const input = this._inputObjects[key];
1090
+ if (input == null) {
1091
+ throw new Error(`Could not find input object: ${key}`);
1092
+ }
1093
+ return input;
1094
+ }
1095
+ _getType(key) {
1096
+ const type = this._types[key];
1097
+ if (type == null) {
1098
+ throw new Error(`Could not find type: ${key}`);
1099
+ }
1100
+ return type;
1101
+ }
1077
1102
  _getReferenceInput(path, isPartial, parentName = '') {
1078
1103
  const id = getReferenceID(path);
1079
1104
  const schema = this._getReferenceSchema(id);
@@ -1176,10 +1201,10 @@ export class SchemaBuilder {
1176
1201
  args: {
1177
1202
  ...connectionArgs,
1178
1203
  filter: {
1179
- type: this._inputObjects[`${id}-filter`]
1204
+ type: this._getInputObject(`${id}-filter`)
1180
1205
  },
1181
1206
  orderBy: {
1182
- type: toList(this._inputObjects[`${id}-order`])
1207
+ type: toList(this._getInputObject(`${id}-order`))
1183
1208
  }
1184
1209
  },
1185
1210
  resolve: async (owner, args, ctx)=>{
@@ -1341,13 +1366,13 @@ export class SchemaBuilder {
1341
1366
  type: new GraphQLNonNull(toOuputList(groupedAggregateType)),
1342
1367
  args: {
1343
1368
  groupBy: {
1344
- type: new GraphQLNonNull(toList(this._inputObjects[`${id}-group-by`]))
1369
+ type: new GraphQLNonNull(toList(this._getInputObject(`${id}-group-by`)))
1345
1370
  },
1346
1371
  having: {
1347
- type: this._inputObjects[`${id}-having`]
1372
+ type: this._getInputObject(`${id}-having`)
1348
1373
  },
1349
1374
  orderBy: {
1350
- type: toList(this._inputObjects[`${id}-group-order`])
1375
+ type: toList(this._getInputObject(`${id}-group-order`))
1351
1376
  },
1352
1377
  limit: {
1353
1378
  type: GraphQLInt
@@ -1396,7 +1421,7 @@ export class SchemaBuilder {
1396
1421
  name: `Create${name}`,
1397
1422
  inputFields: ()=>({
1398
1423
  data: {
1399
- type: new GraphQLNonNull(this._inputObjects[id])
1424
+ type: new GraphQLNonNull(this._getInputObject(id))
1400
1425
  },
1401
1426
  transactionID: {
1402
1427
  type: GraphQLID
@@ -1405,7 +1430,7 @@ export class SchemaBuilder {
1405
1430
  outputFields: ()=>({
1406
1431
  ...definitions.queryFields,
1407
1432
  document: {
1408
- type: this._types[id]
1433
+ type: this._getType(id)
1409
1434
  }
1410
1435
  }),
1411
1436
  mutateAndGetPayload: async (input, ctx, info)=>{
@@ -1425,7 +1450,7 @@ export class SchemaBuilder {
1425
1450
  name: `Set${name}`,
1426
1451
  inputFields: ()=>({
1427
1452
  data: {
1428
- type: new GraphQLNonNull(this._inputObjects[id])
1453
+ type: new GraphQLNonNull(this._getInputObject(id))
1429
1454
  },
1430
1455
  transactionID: {
1431
1456
  type: GraphQLID
@@ -1434,7 +1459,7 @@ export class SchemaBuilder {
1434
1459
  outputFields: ()=>({
1435
1460
  ...definitions.queryFields,
1436
1461
  document: {
1437
- type: this._types[id]
1462
+ type: this._getType(id)
1438
1463
  }
1439
1464
  }),
1440
1465
  mutateAndGetPayload: async (input, ctx, info)=>{
@@ -1462,7 +1487,7 @@ export class SchemaBuilder {
1462
1487
  type: new GraphQLNonNull(toList(PatchOperation))
1463
1488
  },
1464
1489
  from: {
1465
- type: this._inputObjects[`${id}-update`]
1490
+ type: this._getInputObject(`${id}-update`)
1466
1491
  },
1467
1492
  transactionID: {
1468
1493
  type: GraphQLID
@@ -1471,7 +1496,7 @@ export class SchemaBuilder {
1471
1496
  outputFields: ()=>({
1472
1497
  ...definitions.queryFields,
1473
1498
  document: {
1474
- type: this._types[id]
1499
+ type: this._getType(id)
1475
1500
  }
1476
1501
  }),
1477
1502
  mutateAndGetPayload: async (input, ctx, info)=>{
@@ -1737,14 +1762,14 @@ export class SchemaBuilder {
1737
1762
  this._types[`${id}-grouped-aggregate`] = groupedAggregateType;
1738
1763
  // Map a scalar to its existing value-filter input by name (IntValueFilter etc.).
1739
1764
  const valueFilterFor = (scalar)=>{
1740
- return this._inputObjects[`${scalar.name}ValueFilter`];
1765
+ return this._getInputObject(`${scalar.name}ValueFilter`);
1741
1766
  };
1742
1767
  // Having: each op maps its eligible fields to the value filter matching the op's
1743
1768
  // scalar. Sum keeps each numeric field's own scalar; average is always Float;
1744
1769
  // min/max keep each field's own scalar (Int / Float / String).
1745
1770
  const havingFields = {
1746
1771
  count: {
1747
- type: this._inputObjects.IntValueFilter
1772
+ type: this._getInputObject('IntValueFilter')
1748
1773
  }
1749
1774
  };
1750
1775
  if (sumType != null && avgType != null) {
@@ -1755,7 +1780,7 @@ export class SchemaBuilder {
1755
1780
  type: valueFilterFor(field.type)
1756
1781
  };
1757
1782
  havingAvgFields[key] = {
1758
- type: this._inputObjects.FloatValueFilter
1783
+ type: this._getInputObject('FloatValueFilter')
1759
1784
  };
1760
1785
  }
1761
1786
  const havingSum = new GraphQLInputObjectType({
@@ -2281,7 +2306,7 @@ export class SchemaBuilder {
2281
2306
  const scalar = this._buildScalar(id, schema, refParentName);
2282
2307
  const knownFilter = VALUE_FILTER_INPUT_TYPES[scalar.name];
2283
2308
  if (knownFilter != null) {
2284
- return this._inputObjects[knownFilter];
2309
+ return this._getInputObject(knownFilter);
2285
2310
  }
2286
2311
  const filter = isEnumType(scalar) ? createEnumValueFilterInput(scalar) : createScalarValueFilterInput(scalar, {
2287
2312
  stringBacked: true
@@ -2289,7 +2314,7 @@ export class SchemaBuilder {
2289
2314
  if (this._inputObjects[filter.name] == null) {
2290
2315
  this._inputObjects[filter.name] = filter;
2291
2316
  }
2292
- return this._inputObjects[filter.name];
2317
+ return this._getInputObject(filter.name);
2293
2318
  }
2294
2319
  _buildReferenceOrderByInput(path, parentName = '') {
2295
2320
  const id = getReferenceID(path);
@@ -2312,7 +2337,7 @@ export class SchemaBuilder {
2312
2337
  const name = this._aliases[id] ?? pascalCase(parentName + (schema.title ?? ''));
2313
2338
  const fields = isDocument ? {
2314
2339
  _owner: {
2315
- type: this._inputObjects.AccountValueFilter
2340
+ type: this._getInputObject('AccountValueFilter')
2316
2341
  }
2317
2342
  } : {};
2318
2343
  for (const [key, value] of Object.entries(schema.properties)){
@@ -2335,13 +2360,13 @@ export class SchemaBuilder {
2335
2360
  type: objectInput
2336
2361
  },
2337
2362
  and: {
2338
- type: toList(this._inputObjects[inputID])
2363
+ type: toList(this._getInputObject(inputID))
2339
2364
  },
2340
2365
  or: {
2341
- type: toList(this._inputObjects[inputID])
2366
+ type: toList(this._getInputObject(inputID))
2342
2367
  },
2343
2368
  not: {
2344
- type: this._inputObjects[inputID]
2369
+ type: this._getInputObject(inputID)
2345
2370
  }
2346
2371
  })
2347
2372
  });
@@ -2387,6 +2412,9 @@ export class SchemaBuilder {
2387
2412
  return existing;
2388
2413
  }
2389
2414
  const model = this._record[id];
2415
+ if (model == null) {
2416
+ throw new Error(`Model ${id} not found`);
2417
+ }
2390
2418
  const name = this._aliases[id];
2391
2419
  this._inputObjects[inputID] = new GraphQLInputObjectType({
2392
2420
  name: `With${relationFieldName}${name}Input`,
@@ -2504,10 +2532,10 @@ export class SchemaBuilder {
2504
2532
  args: {
2505
2533
  ...connectionArgs,
2506
2534
  filter: {
2507
- type: this._inputObjects[`${relationID}-filter`]
2535
+ type: this._getInputObject(`${relationID}-filter`)
2508
2536
  },
2509
2537
  orderBy: {
2510
- type: toList(this._inputObjects[`${relationID}-order`])
2538
+ type: toList(this._getInputObject(`${relationID}-order`))
2511
2539
  }
2512
2540
  },
2513
2541
  resolve: (doc, args, ctx)=>{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubun/graphql",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "keywords": [],
5
5
  "license": "see LICENSE.md",
6
6
  "sideEffects": false,
@@ -15,10 +15,10 @@
15
15
  "LICENSE.md"
16
16
  ],
17
17
  "dependencies": {
18
- "@kubun/hlc": "^0.15.0",
19
- "@kubun/id": "^0.15.0",
20
- "@kubun/logger": "^0.15.0",
21
- "@kubun/protocol": "^0.15.0",
18
+ "@kubun/hlc": "^0.17.0",
19
+ "@kubun/id": "^0.17.0",
20
+ "@kubun/logger": "^0.17.0",
21
+ "@kubun/protocol": "^0.17.0",
22
22
  "@sozai/async": "^0.2.1",
23
23
  "@sozai/codec": "^0.4.0",
24
24
  "@sozai/event": "^0.1.3",
@@ -32,11 +32,11 @@
32
32
  "devDependencies": {
33
33
  "@kokuin/capability": "^0.3.0",
34
34
  "@kokuin/token": "^0.5.0",
35
- "@kubun/db": "^0.15.0",
36
- "@kubun/db-better-sqlite": "^0.15.0",
37
- "@kubun/scalars": "^0.15.0",
38
- "@kubun/store-graph": "^0.15.0",
39
- "@kubun/test-utils": "^0.13.0"
35
+ "@kubun/db": "^0.17.0",
36
+ "@kubun/db-better-sqlite": "^0.17.0",
37
+ "@kubun/scalars": "^0.17.0",
38
+ "@kubun/store-graph": "^0.17.0",
39
+ "@kubun/test-utils": "^0.0.0"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"
@@ -44,8 +44,8 @@
44
44
  "scripts": {
45
45
  "build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
46
46
  "build:clean": "del lib",
47
- "build:js": "swc src -d ./lib --config-file ../../node_modules/@kigu/dev/swc.json --strip-leading-paths",
48
- "build:types": "tsc --emitDeclarationOnly --skipLibCheck",
47
+ "build:js": "del 'lib/**/*.js' && swc src -d ./lib --config-file ../../node_modules/@kigu/dev/swc.json --strip-leading-paths",
48
+ "build:types": "del 'lib/**/*.d.ts' 'lib/**/*.d.ts.map' && tsc --emitDeclarationOnly --skipLibCheck",
49
49
  "build:types:ci": "tsc --emitDeclarationOnly --declarationMap false",
50
50
  "test": "pnpm run test:types && pnpm run test:unit",
51
51
  "test:types": "tsc --noEmit -p tsconfig.test.json",