You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.2 KiB
JavaScript
79 lines
2.2 KiB
JavaScript
1 year ago
|
"use strict";
|
||
|
|
||
|
// Simple data type to represent a query path and corresponding schema path tied together, because these are basically always used together, and it would bloat up the implementation code otherwise
|
||
|
|
||
|
function createInstance({ queryPath, schemaPath, queryObject, schemaObject, parent }) {
|
||
|
let self;
|
||
|
// eslint-disable-next-line no-return-assign
|
||
|
return self = {
|
||
|
queryPath: queryPath,
|
||
|
schemaPath: schemaPath,
|
||
|
query: queryObject,
|
||
|
schema: schemaObject,
|
||
|
child: function (queryKey) {
|
||
|
let newQueryPath = (queryKey != null)
|
||
|
? queryPath.concat([ queryKey ])
|
||
|
: queryPath;
|
||
|
|
||
|
let newQueryObject = (queryKey != null)
|
||
|
? queryObject[queryKey]
|
||
|
: queryObject;
|
||
|
|
||
|
// TODO: Is this correct even when the queryKey is null, and so we remain at the same object?
|
||
|
// $key is used for handling aliases
|
||
|
let effectiveSchemaKey = (newQueryObject?.$key != null)
|
||
|
? newQueryObject.$key
|
||
|
: queryKey;
|
||
|
|
||
|
let newSchemaPath = (effectiveSchemaKey != null)
|
||
|
? schemaPath.concat([ effectiveSchemaKey ])
|
||
|
: schemaPath;
|
||
|
|
||
|
let newSchemaObject = (effectiveSchemaKey != null)
|
||
|
? schemaObject[effectiveSchemaKey]
|
||
|
: schemaObject;
|
||
|
|
||
|
return createInstance({
|
||
|
queryPath: newQueryPath,
|
||
|
schemaPath: newSchemaPath,
|
||
|
queryObject: newQueryObject,
|
||
|
schemaObject: newSchemaObject,
|
||
|
parent: self
|
||
|
});
|
||
|
},
|
||
|
parent: parent,
|
||
|
override: function ({ query, schema }) {
|
||
|
return createInstance({
|
||
|
queryPath: queryPath,
|
||
|
schemaPath: schemaPath,
|
||
|
queryObject: query ?? queryObject,
|
||
|
schemaObject: schema ?? schemaObject,
|
||
|
// An override doesn't change the path, so the parent shouldn't change either
|
||
|
parent: self.parent
|
||
|
});
|
||
|
},
|
||
|
toPathString: function () {
|
||
|
return queryPath
|
||
|
.map((segment, i) => {
|
||
|
if (segment === schemaPath[i]) {
|
||
|
return segment;
|
||
|
} else {
|
||
|
// This is used for representing aliases, showing the original schema key in brackets
|
||
|
return `${segment} [${schemaPath[i]}]`;
|
||
|
}
|
||
|
})
|
||
|
.join(" -> ");
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
module.exports = function createCursor({ query, schema }) {
|
||
|
return createInstance({
|
||
|
queryPath: [],
|
||
|
schemaPath: [],
|
||
|
queryObject: query,
|
||
|
schemaObject: schema,
|
||
|
parent: undefined
|
||
|
});
|
||
|
};
|