UNPKG

@fjell/lib

Version:

Server-side Library for Fjell

698 lines (670 loc) 22.7 kB
var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; // src/errors.ts import { abbrevIK } from "@fjell/core"; var LibError = class _LibError extends Error { operation; coordinate; constructor(message, operation, coordinate, options) { super(`${message} - ${coordinate} - ${operation}`, options); this.operation = operation; this.coordinate = coordinate; if (Error.captureStackTrace) { Error.captureStackTrace(this, _LibError); } } }; var NotFoundError = class extends LibError { key; constructor(operation, coordinate, key, options) { super(`Item not found for key - ${abbrevIK(key)}`, operation, coordinate, options); this.key = key; } }; var NotUpdatedError = class extends LibError { key; constructor(operation, coordinate, key, options) { super(`Item not updated for key ${abbrevIK(key)}`, operation, coordinate, options); this.key = key; } }; var ValidationError = class extends LibError { constructor(message, operation, coordinate, options) { super(`Validation failed: ${message}`, operation, coordinate, options); } }; var CreateValidationError = class extends ValidationError { constructor(parameters, coordinate, options) { super( `Create Validation Failed: ${JSON.stringify(parameters)}`, "create", coordinate, options ); } }; var UpdateValidationError = class extends ValidationError { constructor(parameters, coordinate, options) { super( `Update Validation Failed: ${JSON.stringify(parameters)}`, "update", coordinate, options ); } }; var RemoveValidationError = class extends ValidationError { constructor(parameters, coordinate, options) { const keyInfo = parameters.key ? `key: ${abbrevIK(parameters.key)}` : "key: undefined"; super( `Remove Validation Failed: ${keyInfo}`, "remove", coordinate, options ); } }; var UpdateError = class extends LibError { constructor(parameters, coordinate, options) { const keyInfo = parameters.key ? `key: ${abbrevIK(parameters.key)}` : "key: undefined"; super( `Update Failed: ${keyInfo}`, "update", coordinate, options ); } }; var RemoveError = class extends LibError { constructor(parameters, coordinate, options) { const keyInfo = parameters.key ? `key: ${abbrevIK(parameters.key)}` : "key: undefined"; super( `Remove Failed: ${keyInfo}`, "remove", coordinate, options ); } }; var HookError = class extends LibError { constructor(message, operation, coordinate, options) { super(`${message}`, operation, coordinate, options); } }; // src/logger.ts import Logging from "@fjell/logging"; var LibLogger = Logging.getLogger("@fjell/lib"); var logger_default = LibLogger; // src/Library.ts import { createInstance as createBaseInstance } from "@fjell/registry"; var logger = logger_default.get("Library"); var createLibrary = (registry, coordinate, operations, options) => { logger.debug("createLibrary", { coordinate, operations, registry, options }); const baseInstance = createBaseInstance(registry, coordinate); return { ...baseInstance, operations, options: options || {} }; }; var isLibrary = (library) => { return library !== null && library !== void 0 && library.coordinate !== void 0 && library.operations !== void 0 && library.options !== void 0 && library.registry !== void 0; }; // src/LibraryFactory.ts var logger2 = logger_default.get("InstanceFactory"); var createLibraryFactory = (operations, options) => { return (coordinate, context) => { logger2.debug("Creating lib instance", { coordinate, registry: context.registry, operations, options }); return createLibrary(context.registry, coordinate, operations, options); }; }; // src/ops/all.ts var logger3 = logger_default.get("library", "ops", "all"); var wrapAllOperation = (toWrap, options, coordinate, registry) => { const all = async (itemQuery, locations) => { logger3.default("getAllOperation", { itemQuery, locations }); const items = await toWrap.all(itemQuery, locations); logger3.default("getAllOperation: %j", { items }); return items; }; return all; }; // src/ops/create.ts var logger4 = logger_default.get("library", "ops", "create"); var wrapCreateOperation = (toWrap, options, coordinate, registry) => { const libOptions = options; const create = async (item, options2) => { logger4.default("create", { item, options: options2 }); let itemToCreate = item; itemToCreate = await runPreCreateHook(itemToCreate, options2); await validateCreate(itemToCreate, options2); let createdItem = await toWrap.create(itemToCreate, options2); createdItem = await runPostCreateHook(createdItem); logger4.default("created item: %j", { createdItem }); return createdItem; }; async function runPreCreateHook(item, options2) { let itemToCreate = item; if (libOptions?.hooks?.preCreate) { try { logger4.default("Running preCreate hook", { item: itemToCreate, options: options2 }); itemToCreate = await libOptions.hooks.preCreate(itemToCreate, options2); } catch (error) { throw new HookError( "Error in preCreate", "create", coordinate, { cause: error } ); } } else { logger4.default("No preCreate hook found, returning."); } return itemToCreate; } async function runPostCreateHook(createdItem) { if (libOptions?.hooks?.postCreate) { try { logger4.default("Running postCreate hook", { item: createdItem }); createdItem = await libOptions.hooks.postCreate(createdItem); } catch (error) { throw new HookError( "Error in postCreate", "create", coordinate, { cause: error } ); } } else { logger4.default("No postCreate hook found, returning."); } return createdItem; } async function validateCreate(item, options2) { if (!libOptions?.validators?.onCreate) { logger4.default("No validator found for create, returning."); return; } try { logger4.default("Validating create", { item, options: options2 }); const isValid = await libOptions.validators.onCreate(item, options2); if (!isValid) { throw new CreateValidationError( { item, options: options2 }, coordinate, { cause: new Error("Invalid item") } ); } } catch (error) { throw new CreateValidationError( { item, options: options2 }, coordinate, { cause: error } ); } } return create; }; // src/ops/find.ts var logger5 = logger_default.get("library", "ops", "find"); var wrapFindOperation = (toWrap, options, coordinate, registry) => { const { finders } = options || {}; const find = async (finder, finderParams, locations) => { logger5.default("find", { finder, finderParams, locations }); if (!finders?.[finder]) { throw new Error(`Finder ${finder} not found in definition for ${coordinate.toString()}`); } const foundItems = await toWrap.find(finder, finderParams, locations); logger5.default("found items: %j", { foundItems }); return foundItems; }; return find; }; // src/ops/findOne.ts var logger6 = logger_default.get("library", "ops", "one"); var wrapFindOneOperation = (toWrap, options, coordinate, registry) => { const findOne = async (finder, finderParams, locations) => { logger6.default("find", { finder, finderParams, locations }); const foundItems = await toWrap.findOne(finder, finderParams, locations); logger6.default("found items: %j", { foundItems }); return foundItems; }; return findOne; }; // src/ops/get.ts var logger7 = logger_default.get("library", "ops", "get"); var wrapGetOperation = (toWrap, options, coordinate, registry) => { const get = async (key) => { logger7.default("get", { key }); const item = await toWrap.get(key); logger7.default("get: %j", { item }); return item; }; return get; }; // src/ops/one.ts var logger8 = logger_default.get("library", "ops", "one"); var wrapOneOperation = (toWrap, options, coordinate, registry) => { const one = async (itemQuery, locations = []) => { logger8.default("one", { itemQuery, locations }); const item = await toWrap.one(itemQuery, locations); logger8.default("one: %j", { item }); return item; }; return one; }; // src/ops/remove.ts var logger9 = logger_default.get("library", "ops", "remove"); var wrapRemoveOperation = (toWrap, options, coordinate, registry) => { const remove = async (key) => { logger9.default("Removing item", { key }); await runPreRemoveHook(key); await validateRemove(key); const item = await toWrap.remove(key); if (!item) { throw new RemoveError({ key }, coordinate); } await runPostRemoveHook(item); logger9.default("removed item: %j", { item }); return item; }; async function runPreRemoveHook(key) { if (options?.hooks?.preRemove) { try { logger9.default("Running preRemove hook", { key }); await options.hooks.preRemove(key); } catch (error) { throw new HookError("preRemove", "remove", coordinate, { cause: error }); } } else { logger9.default("No preRemove hook found, returning."); } } async function runPostRemoveHook(item) { if (options?.hooks?.postRemove) { try { logger9.default("Running postRemove hook", { item }); await options.hooks.postRemove(item); } catch (error) { throw new HookError("postRemove", "remove", coordinate, { cause: error }); } } else { logger9.default("No postRemove hook found, returning."); } } async function validateRemove(key) { if (!options?.validators?.onRemove) { logger9.default("No validator found for remove, returning."); return; } try { logger9.default("Validating remove", { key }); const isValid = await options.validators.onRemove(key); if (!isValid) { throw new RemoveValidationError( { key }, coordinate, { cause: new Error("Error validating remove") } ); } } catch (error) { throw new RemoveValidationError( { key }, coordinate, { cause: error } ); } } return remove; }; // src/ops/update.ts var logger10 = logger_default.get("library", "ops", "update"); var wrapUpdateOperation = (toWrap, options, coordinate, registry) => { const update = async (key, item) => { logger10.default("update", { key, item }); let itemToUpdate = item; itemToUpdate = await runPreUpdateHook(key, itemToUpdate); await validateUpdate(key, itemToUpdate); try { logger10.default("Updating item", { key, item: itemToUpdate }); let updatedItem = await toWrap.update(key, itemToUpdate); updatedItem = await runPostUpdateHook(updatedItem); logger10.default("updated item: %j", { updatedItem }); return updatedItem; } catch (error) { throw new UpdateError( { key, item: itemToUpdate }, coordinate, { cause: error } ); } }; async function runPreUpdateHook(key, itemToUpdate) { logger10.debug("Running Pre Update Hook"); if (options?.hooks?.preUpdate) { try { logger10.default("Running preUpdate hook", { key, item: itemToUpdate }); itemToUpdate = await options.hooks.preUpdate(key, itemToUpdate); } catch (error) { throw new HookError( "Error in preUpdate", "update", coordinate, { cause: error } ); } } else { logger10.default("No preUpdate hook found, returning."); } return itemToUpdate; } async function runPostUpdateHook(updatedItem) { logger10.debug("Running Post Update Hook"); if (options?.hooks?.postUpdate) { try { logger10.default("Running postUpdate hook", { item: updatedItem }); updatedItem = await options.hooks.postUpdate(updatedItem); } catch (error) { throw new HookError( "Error in postUpdate", "update", coordinate, { cause: error } ); } } else { logger10.default("No postUpdate hook found, returning."); } return updatedItem; } async function validateUpdate(key, itemToUpdate) { logger10.debug("Validating update"); if (!options?.validators?.onUpdate) { logger10.default("No validator found for update, returning."); return; } try { logger10.debug("Validating update", { key, item: itemToUpdate }); const isValid = await options.validators.onUpdate(key, itemToUpdate); if (!isValid) { throw new UpdateValidationError( { key, item: itemToUpdate }, coordinate, { cause: new Error("Invalid item") } ); } } catch (error) { throw new UpdateValidationError( { key, item: itemToUpdate }, coordinate, { cause: error } ); } } return update; }; // src/ops/upsert.ts var logger11 = logger_default.get("ops", "upsert"); var wrapUpsertOperation = (ops, registry) => { const retrieveOrCreateWithKey = async (key, itemProperties) => { let item = null; try { logger11.default("Retrieving Item by Key", { key }); item = await ops.get(key); } catch (error) { if (error instanceof NotFoundError) { logger11.default("Item not found, creating new item", { key }); item = await ops.create(itemProperties, { key }); } else { throw error; } } return item; }; const upsert = async (key, itemProperties) => { let item = null; item = await retrieveOrCreateWithKey(key, itemProperties); logger11.debug("Updating Item", { key: item.key, itemProperties }); item = await ops.update(item.key, itemProperties); logger11.default("updated item: %j", { item }); return item; }; return upsert; }; // src/ops/action.ts var logger12 = logger_default.get("library", "ops", "action"); var wrapActionOperation = (toWrap, options, coordinate, registry) => { const { actions } = options || {}; const action = async (key, actionKey, actionParams) => { logger12.debug("action", { key, actionKey, actionParams }); if (!actions?.[actionKey]) { throw new Error(`Action ${actionKey} not found in definition`); } const actionMethod = actions[actionKey]; const item = await toWrap.get(key); return actionMethod(item, actionParams); }; return action; }; // src/ops/facet.ts var logger13 = logger_default.get("library", "ops", "facet"); var wrapFacetOperation = (toWrap, options, coordinate, registry) => { const { facets } = options || {}; const facet = async (key, facetKey, facetParams) => { logger13.debug("facet for item key: %j, facet key: %s, params: %j", key, facetKey, facetParams); if (!facets?.[facetKey]) { throw new Error(`Facet ${facetKey} not found in definition for ${coordinate.toString()}`); } const facetMethod = facets[facetKey]; logger13.debug("Getting Item for Facet by key: %j", key); const item = await toWrap.get(key); return facetMethod(item, facetParams); }; return facet; }; // src/ops/allAction.ts var logger14 = logger_default.get("library", "ops", "allAction"); var wrapAllActionOperation = (toWrap, options, coordinate, registry) => { const { allActions } = options || {}; const allAction = async (allActionKey, allActionParams, locations) => { logger14.debug("allAction", { allActionKey, allActionParams, locations }); if (!allActions?.[allActionKey]) { throw new Error(`AllAction ${allActionKey} not found in definition`); } const allActionMethod = allActions[allActionKey]; return allActionMethod(allActionParams, locations); }; return allAction; }; // src/ops/allFacet.ts var logger15 = logger_default.get("library", "ops", "allFacet"); var wrapAllFacetOperation = (toWrap, options, coordinate, registry) => { const { allFacets } = options || {}; const allFacet = async (allFacetKey, allFacetParams, locations) => { logger15.debug("allFacet", { allFacetKey, allFacetParams, locations }); if (!allFacets?.[allFacetKey]) { throw new Error(`AllFacet ${allFacetKey} not found in definition`); } const allFacetMethod = allFacets[allFacetKey]; return allFacetMethod(allFacetParams, locations); }; return allFacet; }; // src/Operations.ts var logger16 = logger_default.get("Operations"); var wrapOperations = (toWrap, options, coordinate, registry) => { const operations = {}; operations.all = wrapAllOperation(toWrap, options, coordinate, registry); operations.one = wrapOneOperation(toWrap, options, coordinate, registry); operations.create = wrapCreateOperation(toWrap, options, coordinate, registry); operations.update = wrapUpdateOperation(toWrap, options, coordinate, registry); operations.get = wrapGetOperation(toWrap, options, coordinate, registry); operations.remove = wrapRemoveOperation(toWrap, options, coordinate, registry); operations.find = wrapFindOperation(toWrap, options, coordinate, registry); operations.findOne = wrapFindOneOperation(toWrap, options, coordinate, registry); operations.upsert = wrapUpsertOperation(operations, registry); operations.action = wrapActionOperation(toWrap, options, coordinate, registry); operations.facet = wrapFacetOperation(toWrap, options, coordinate, registry); operations.allAction = wrapAllActionOperation(toWrap, options, coordinate, registry); operations.allFacet = wrapAllFacetOperation(toWrap, options, coordinate, registry); operations.finders = { ...toWrap.finders, ...options.finders }; operations.actions = { ...toWrap.actions, ...options.actions }; operations.facets = { ...toWrap.facets, ...options.facets }; operations.allActions = { ...toWrap.allActions, ...options.allActions }; operations.allFacets = { ...toWrap.allFacets, ...options.allFacets }; return operations; }; var createReadOnlyOperations = (toWrap) => { logger16.debug("createReadOnlyOperations", { toWrap }); const create = async (item, options) => { logger16.warning("create", "Cannot Create in a ReadOnly Library, Returning Empty Item"); return {}; }; const update = async (key, item) => { logger16.warning("update", "Cannot Update in a ReadOnly Library, Returning Empty Item"); return {}; }; const upsert = async (key, itemProperties, locations) => { logger16.warning("upsert", "Cannot Upsert in a ReadOnly Library, Returning Empty Item"); return {}; }; const remove = async (key) => { logger16.warning("remove", "Cannot Remove in a ReadOnly Library, Returning Empty Item"); return {}; }; return { ...toWrap, create, update, upsert, remove }; }; // src/Options.ts import deepmerge from "deepmerge"; var logger17 = logger_default.get("Options"); var createDefaultOptions = () => { logger17.debug("createDefaultOptions"); function clearAggs(item) { delete item.aggs; return item; } return { hooks: { // TODO: "We need to figure out how to make this an array of hooks..." preCreate: async (item, options) => { const retItem = clearAggs(item); return retItem; }, // TODO: "We need to figure out how to make this an array of hooks..." preUpdate: async (key, item) => { const retItem = clearAggs(item); return retItem; } } }; }; var createOptions = (options) => { const defaultOptions = createDefaultOptions(); return deepmerge(defaultOptions, options ?? {}); }; // src/Registry.ts import { createRegistry as createBaseRegistry } from "@fjell/registry"; var logger18 = logger_default.get("LibRegistry"); var createRegistryFactory = () => { return (type, registryHub) => { if (type !== "lib") { throw new Error(`LibRegistryFactory can only create 'lib' type registries, got: ${type}`); } logger18.debug("Creating lib registry", { type, registryHub }); const baseRegistry = createBaseRegistry(type, registryHub); return baseRegistry; }; }; var createRegistry = (registryHub) => { const baseRegistry = createBaseRegistry("lib", registryHub); return { ...baseRegistry }; }; // src/primary/index.ts var primary_exports = {}; __export(primary_exports, { createLibrary: () => createLibrary2, wrapOperations: () => wrapOperations2 }); // src/primary/Library.ts var logger19 = logger_default.get("primary", "Instance"); var createLibrary2 = (registry, coordinate, operations, options) => { logger19.debug("createLibrary", { coordinate, operations, registry, options }); const library = createLibrary(registry, coordinate, operations, options); if (!library) { return library; } return { ...library, operations }; }; // src/primary/Operations.ts var logger20 = logger_default.get("primary", "Operations"); var wrapOperations2 = (toWrap, options, coordinate, registry) => { logger20.debug("wrapOperations", { toWrap, options, coordinate, registry }); return { ...wrapOperations(toWrap, options, coordinate, registry) }; }; // src/contained/index.ts var contained_exports = {}; __export(contained_exports, { createLibrary: () => createLibrary3, createOptions: () => createOptions2, wrapOperations: () => wrapOperations3 }); // src/contained/Library.ts var createLibrary3 = (parent, registry, coordinate, operations, options) => { const library = createLibrary(registry, coordinate, operations, options); return { ...library, parent }; }; // src/contained/Operations.ts var wrapOperations3 = (toWrap, options, coordinate, registry) => { const operations = wrapOperations(toWrap, options, coordinate, registry); return { ...operations }; }; // src/contained/Options.ts var createOptions2 = (libOptions) => { const options = createOptions(libOptions); return { ...options }; }; export { contained_exports as Contained, CreateValidationError, HookError, LibError, NotFoundError, NotUpdatedError, primary_exports as Primary, RemoveError, RemoveValidationError, UpdateError, UpdateValidationError, ValidationError, createDefaultOptions, createLibrary, createLibraryFactory, createOptions, createReadOnlyOperations, createRegistry, createRegistryFactory, isLibrary, wrapOperations }; //# sourceMappingURL=index.js.map