@lde/search-api-graphql 0.20.2 → 0.20.3
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/dist/build-schema.d.ts.map +1 -1
- package/dist/build-schema.js +34 -9
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-schema.d.ts","sourceRoot":"","sources":["../src/build-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,aAAa,EAQd,MAAM,SAAS,CAAC;AACjB,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"build-schema.d.ts","sourceRoot":"","sources":["../src/build-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,aAAa,EAQd,MAAM,SAAS,CAAC;AACjB,OAAO,EAKL,KAAK,YAAY,EAEjB,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,aAAa,CAAC;AAkBrB,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AAGvB,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B;;sDAEkD;IAClD,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACjE;AAED;2EAC2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC;yCACqC;IACrC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;uBACmB;IACnB,QAAQ,CAAC,aAAa,CAAC,EAAE,CACvB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,KACnB,WAAW,CAAC;CAClB;AAED,MAAM,WAAW,yBAAyB;IACxC;;kEAE8D;IAC9D,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC7D,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC;;gDAE4C;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAkBD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,yBAA8B,GACtC,aAAa,CA6gBf;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAER"}
|
package/dist/build-schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GraphQLBoolean, GraphQLEnumType, GraphQLFloat, GraphQLInputObjectType, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLObjectType, GraphQLSchema, GraphQLString, printSchema, } from 'graphql';
|
|
2
|
-
import { AND_KEY, facetableFields, filterableFields, filterOn, filterOperatorFor, ID_FIELD, OR_KEY, isRangeFacet, nestedReferenceType, outputFields, pageForOffset, sortableFields, unixSecondsToIso, } from '@lde/search/adapter';
|
|
2
|
+
import { AND_KEY, DEFAULT_LABEL_FIELD, facetableFields, filterableFields, filterOn, filterOperatorFor, ID_FIELD, OR_KEY, isRangeFacet, labelFieldNameOf, nestedReferenceType, outputFields, pageForOffset, sortableFields, unixSecondsToIso, } from '@lde/search/adapter';
|
|
3
3
|
import { defaultLanguageOrder, toLanguageStrings, } from './language.js';
|
|
4
4
|
import { createFacetLoader } from './facet-batch.js';
|
|
5
5
|
const nonNullListOf = (type) => new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(type)));
|
|
@@ -21,7 +21,8 @@ function screamingSnake(name) {
|
|
|
21
21
|
export function buildGraphQLSchema(schema, options = {}) {
|
|
22
22
|
const languageOrder = options.languageOrder ?? defaultLanguageOrder;
|
|
23
23
|
const maxPerPage = options.maxPerPage ?? 100;
|
|
24
|
-
const
|
|
24
|
+
const rootTypesByName = new Map([...schema.values()].map((searchType) => [searchType.name, searchType]));
|
|
25
|
+
const rootTypeNames = new Set(rootTypesByName.keys());
|
|
25
26
|
for (const name of Object.keys(options.types ?? {})) {
|
|
26
27
|
if (!rootTypeNames.has(name)) {
|
|
27
28
|
throw new Error(`Options given for type “${name}”, which is not in the search schema.`);
|
|
@@ -121,6 +122,19 @@ export function buildGraphQLSchema(schema, options = {}) {
|
|
|
121
122
|
// and rejects duplicate names schema-wide.
|
|
122
123
|
const referenceTypes = new Map();
|
|
123
124
|
const takenTypeNames = new Set(rootTypeNames);
|
|
125
|
+
/** The label key each id-plus-label reference type was registered with; no
|
|
126
|
+
* entry for a surfaced inline one, which carries fields instead of a label. */
|
|
127
|
+
const labelKeys = new Map();
|
|
128
|
+
/** The key a reference serves its resolved label under: the name its label
|
|
129
|
+
* source declares that label field with, so the reference and the type it
|
|
130
|
+
* resolves against agree on the word. An id-only reference resolves no
|
|
131
|
+
* label, so it keeps the default. `searchSchema` guarantees the source is a
|
|
132
|
+
* declared Root Type. */
|
|
133
|
+
function labelKeyOf(field) {
|
|
134
|
+
return field.labelSource === undefined
|
|
135
|
+
? DEFAULT_LABEL_FIELD
|
|
136
|
+
: labelFieldNameOf(rootTypesByName.get(field.labelSource));
|
|
137
|
+
}
|
|
124
138
|
/**
|
|
125
139
|
* Register the GraphQL type one reference field is served as, once per
|
|
126
140
|
* referenced shape. A **surfaced inline** reference is served as the nested
|
|
@@ -131,9 +145,17 @@ export function buildGraphQLSchema(schema, options = {}) {
|
|
|
131
145
|
* stays the id-plus-label pair its strategy carries.
|
|
132
146
|
*/
|
|
133
147
|
function registerReferenceType(field, owner) {
|
|
134
|
-
if (field.kind !== 'reference' ||
|
|
135
|
-
|
|
136
|
-
|
|
148
|
+
if (field.kind !== 'reference' || field.ref === undefined) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (referenceTypes.has(field.ref.typeName)) {
|
|
152
|
+
// Fields sharing a `ref.typeName` share one emitted type, so they must
|
|
153
|
+
// agree on the word it serves its label under – otherwise which one wins
|
|
154
|
+
// would come down to declaration order.
|
|
155
|
+
const registered = labelKeys.get(field.ref.typeName);
|
|
156
|
+
if (registered !== undefined && registered !== labelKeyOf(field)) {
|
|
157
|
+
throw new Error(`Reference “${owner.name}.${field.name}” serves its label as “${labelKeyOf(field)}”, but “${field.ref.typeName}” is already served with “${registered}”; fields sharing a reference type must resolve labels from sources that agree on their labelField.`);
|
|
158
|
+
}
|
|
137
159
|
return;
|
|
138
160
|
}
|
|
139
161
|
const { typeName } = field.ref;
|
|
@@ -145,17 +167,20 @@ export function buildGraphQLSchema(schema, options = {}) {
|
|
|
145
167
|
}
|
|
146
168
|
takenTypeNames.add(graphQLName);
|
|
147
169
|
const nested = nestedReferenceType(schema, field);
|
|
170
|
+
if (nested === undefined) {
|
|
171
|
+
labelKeys.set(typeName, labelKeyOf(field));
|
|
172
|
+
}
|
|
148
173
|
referenceTypes.set(typeName, new GraphQLObjectType({
|
|
149
174
|
name: graphQLName,
|
|
150
175
|
// A thunk, so a Reference Type nesting another one resolves whatever
|
|
151
176
|
// the registration order is (the graph is acyclic by searchSchema).
|
|
152
177
|
fields: () => nested === undefined
|
|
153
178
|
? {
|
|
179
|
+
// The same word the label source declares its label field
|
|
180
|
+
// under (`label` by default): one resolved label, one name for
|
|
181
|
+
// it wherever it surfaces.
|
|
154
182
|
id: { type: new GraphQLNonNull(GraphQLString) },
|
|
155
|
-
|
|
156
|
-
// reference facet’s bucket carries: one resolved label, one
|
|
157
|
-
// name for it wherever it surfaces.
|
|
158
|
-
label: labelList((source) => source.label),
|
|
183
|
+
[labelKeyOf(field)]: labelList((source) => source.label),
|
|
159
184
|
}
|
|
160
185
|
: {
|
|
161
186
|
id: { type: GraphQLString },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/search-api-graphql",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.3",
|
|
4
4
|
"description": "Engine- and domain-agnostic GraphQL surface for @lde/search: builds an executable GraphQLSchema from a whole SearchSchema at runtime (no codegen) – one root query field per SearchType – served by generic resolvers over any SearchEngine – and serves it as a framework-agnostic fetch handler with a self-contained playground, SDL endpoint, CORS and depth/cost limits. You supply the schema and per-type typeNames; it names neither your domain nor your engine.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "git+https://github.com/ldelements/lde.git",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"@escape.tech/graphql-armor-cost-limit": "^2.4.3",
|
|
38
38
|
"@escape.tech/graphql-armor-max-depth": "^2.4.2",
|
|
39
39
|
"@graphql-yoga/render-graphiql": "^5.21.2",
|
|
40
|
-
"@lde/search": "^0.18.
|
|
40
|
+
"@lde/search": "^0.18.3",
|
|
41
41
|
"commander": "^15.0.0",
|
|
42
42
|
"dataloader": "^2.2.3",
|
|
43
43
|
"graphql": "^16.9.0",
|