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

"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
});
};