dynamodb-toolbox
Version:
Lightweight and type-safe query builder for DynamoDB and TypeScript.
81 lines (80 loc) • 3.13 kB
JavaScript
import { Parser } from '../../../schema/actions/parse/index.js';
import { parseStringPath } from '../../../schema/actions/utils/parseStringPath.js';
import { Path } from '../../../schema/actions/utils/path.js';
import { AnySchema } from '../../../schema/any/schema.js';
import { SchemaAction } from '../../../schema/index.js';
import { isInteger } from '../../../utils/validation/isInteger.js';
import { SubSchema } from './subSchema.js';
// TO IMPROVE: Type path as Path<SCHEMA> and return typed SubSchema
export class Finder extends SchemaAction {
search(path) {
return findSubSchemas(this.schema, parseStringPath(path));
}
}
Finder.actionName = 'finder';
export const findSubSchemas = (schema, path) => {
var _a;
const [pathHead, ...pathTail] = path;
if (pathHead === undefined) {
return [new SubSchema({ schema, formattedPath: new Path(), transformedPath: new Path() })];
}
switch (schema.type) {
case 'any': {
return [
new SubSchema({
schema: new AnySchema({}),
formattedPath: Path.fromArray(path),
transformedPath: Path.fromArray(path)
})
];
}
case 'null':
case 'boolean':
case 'number':
case 'string':
case 'binary':
case 'set':
return [];
case 'record': {
const keyAttribute = schema.keys;
let parsedKey;
try {
parsedKey = new Parser(keyAttribute).parse(pathHead);
}
catch {
return [];
}
return findSubSchemas(schema.elements, pathTail).map(({ schema, formattedPath, transformedPath }) => new SubSchema({
schema,
formattedPath: formattedPath.prepend(pathHead),
transformedPath: transformedPath.prepend(parsedKey)
}));
}
case 'item':
case 'map': {
const childAttribute = schema.attributes[pathHead];
if (!childAttribute) {
return [];
}
const transformedLocalPath = (_a = childAttribute.props.savedAs) !== null && _a !== void 0 ? _a : pathHead;
return findSubSchemas(childAttribute, pathTail).map(({ schema, formattedPath, transformedPath }) => new SubSchema({
schema,
formattedPath: formattedPath.prepend(pathHead),
transformedPath: transformedPath.prepend(transformedLocalPath)
}));
}
case 'list': {
if (!isInteger(pathHead)) {
return [];
}
return findSubSchemas(schema.elements, pathTail).map(({ schema, formattedPath, transformedPath }) => new SubSchema({
schema,
formattedPath: formattedPath.prepend(pathHead),
transformedPath: transformedPath.prepend(pathHead)
}));
}
case 'anyOf': {
return schema.elements.map(element => findSubSchemas(element, path)).flat();
}
}
};