functional-models 3.10.0 → 3.11.0
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/cjs/errors.cjs +38 -0
- package/cjs/errors.cjs.map +7 -0
- package/cjs/index.cjs +2426 -0
- package/cjs/index.cjs.map +7 -0
- package/cjs/lib.cjs +431 -0
- package/cjs/lib.cjs.map +7 -0
- package/cjs/models.cjs +571 -0
- package/cjs/models.cjs.map +7 -0
- package/cjs/orm/index.cjs +1765 -0
- package/cjs/orm/index.cjs.map +7 -0
- package/cjs/orm/internal-libs.cjs +136 -0
- package/cjs/orm/internal-libs.cjs.map +7 -0
- package/cjs/orm/libs.cjs +88 -0
- package/cjs/orm/libs.cjs.map +7 -0
- package/cjs/orm/models.cjs +1027 -0
- package/cjs/orm/models.cjs.map +7 -0
- package/cjs/orm/properties.cjs +989 -0
- package/cjs/orm/properties.cjs.map +7 -0
- package/cjs/orm/query.cjs +376 -0
- package/cjs/orm/query.cjs.map +7 -0
- package/cjs/orm/types.cjs +59 -0
- package/cjs/orm/types.cjs.map +7 -0
- package/cjs/orm/validation.cjs +301 -0
- package/cjs/orm/validation.cjs.map +7 -0
- package/cjs/properties.cjs +998 -0
- package/cjs/properties.cjs.map +7 -0
- package/cjs/serialization.cjs +75 -0
- package/cjs/serialization.cjs.map +7 -0
- package/cjs/types.cjs +65 -0
- package/cjs/types.cjs.map +7 -0
- package/cjs/utils.cjs +187 -0
- package/cjs/utils.cjs.map +7 -0
- package/cjs/validation.cjs +431 -0
- package/cjs/validation.cjs.map +7 -0
- package/errors.js +3 -4
- package/errors.js.map +1 -1
- package/index.d.ts +13 -13
- package/index.js +13 -52
- package/index.js.map +1 -1
- package/lib.d.ts +2 -2
- package/lib.js +45 -65
- package/lib.js.map +1 -1
- package/models.d.ts +1 -1
- package/models.js +22 -30
- package/models.js.map +1 -1
- package/orm/index.d.ts +9 -9
- package/orm/index.js +9 -48
- package/orm/index.js.map +1 -1
- package/orm/internal-libs.js +7 -11
- package/orm/internal-libs.js.map +1 -1
- package/orm/libs.d.ts +1 -1
- package/orm/libs.js +8 -16
- package/orm/libs.js.map +1 -1
- package/orm/models.d.ts +2 -2
- package/orm/models.js +20 -26
- package/orm/models.js.map +1 -1
- package/orm/properties.d.ts +22 -22
- package/orm/properties.js +26 -36
- package/orm/properties.js.map +1 -1
- package/orm/query.d.ts +1 -1
- package/orm/query.js +31 -52
- package/orm/query.js.map +1 -1
- package/orm/types.d.ts +1 -1
- package/orm/types.js +7 -10
- package/orm/types.js.map +1 -1
- package/orm/validation.d.ts +2 -2
- package/orm/validation.js +5 -13
- package/orm/validation.js.map +1 -1
- package/package.json +50 -65
- package/properties.d.ts +21 -21
- package/properties.js +65 -94
- package/properties.js.map +1 -1
- package/serialization.d.ts +1 -1
- package/serialization.js +3 -9
- package/serialization.js.map +1 -1
- package/types.js +4 -6
- package/types.js.map +1 -1
- package/utils.d.ts +2 -1
- package/utils.js +8 -23
- package/utils.js.map +1 -1
- package/validation.d.ts +1 -1
- package/validation.js +19 -50
- package/validation.js.map +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/orm/index.ts", "../../../src/orm/query.ts", "../../../src/orm/types.ts", "../../../src/orm/validation.ts", "../../../src/orm/properties.ts", "../../../src/types.ts", "../../../src/properties.ts", "../../../node_modules/uuid/dist-node/stringify.js", "../../../node_modules/uuid/dist-node/rng.js", "../../../node_modules/uuid/dist-node/v4.js", "../../../src/validation.ts", "../../../src/utils.ts", "../../../src/lib.ts", "../../../src/orm/internal-libs.ts", "../../../src/orm/models.ts", "../../../src/models.ts", "../../../src/serialization.ts", "../../../src/errors.ts"],
|
|
4
|
+
"sourcesContent": ["export * as query from './query.js'\nexport * as validation from './validation.js'\nexport * as properties from './properties.js'\nexport * as types from './types.js'\n\nexport * from './models.js'\nexport * from './validation.js'\nexport * from './properties.js'\nexport * from './types.js'\nexport * from './query.js'\n", "import merge from 'lodash/merge.js'\nimport omit from 'lodash/omit.js'\nimport {\n AllowableEqualitySymbols,\n BooleanQuery,\n BuilderV2Link,\n DatastoreValueType,\n DatesAfterQuery,\n DatesBeforeQuery,\n EqualitySymbol,\n InnerBuilderV2,\n MaxMatchStatement,\n OrmSearch,\n PaginationQuery,\n PropertyOptions,\n PropertyQuery,\n Query,\n QueryBuilder,\n QueryTokens,\n SortOrder,\n SortStatement,\n SubBuilderFunction,\n} from './types.js'\n\nconst THREE = 3\n\nconst _objectize = <T>(key: string, value: T) => {\n return value\n ? {\n [key]: value,\n }\n : {}\n}\n\nconst _additionalLink = (data: OrmSearch): InnerBuilderV2 & BuilderV2Link => {\n const inner = _builderV2(data)\n const partialLink = omit(_link(data), ['and', 'or'])\n // @ts-ignore\n return {\n ...inner,\n ...partialLink,\n }\n}\n\nconst _link = (data: OrmSearch): BuilderV2Link => {\n return {\n and: () => {\n return _queryBuilder({ ...data, query: data.query.concat('AND') })\n },\n or: () => {\n return _queryBuilder({ ...data, query: data.query.concat('OR') })\n },\n compile: () => {\n return data\n },\n take: (num: number) => {\n return _additionalLink({ ...data, take: take(num) })\n },\n sort: (key: string, order = SortOrder.asc) => {\n return _additionalLink({ ...data, sort: sort(key, order) })\n },\n pagination: (value: any) => {\n return _additionalLink({ ...data, page: pagination(value) })\n },\n }\n}\n\nconst _canCompile = (obj: any): obj is { compile: () => OrmSearch } => {\n return Boolean(obj.compile)\n}\n\nconst _builderV2 = (data: OrmSearch): InnerBuilderV2 => {\n const _myProperty = (name: string, value: any, options?: PropertyOptions) => {\n // @ts-ignore\n const p = property(name, value, options)\n return _link(merge(data, { query: data.query.concat(p) }))\n }\n\n const complex = (subBuilderFunc: SubBuilderFunction) => {\n const subBuilder = _queryBuilder()\n const result = subBuilderFunc(subBuilder)\n if (_canCompile(result)) {\n const queryTokens: [readonly QueryTokens[]] = [result.compile().query]\n return _link(\n merge(data, {\n query: data.query.concat(queryTokens),\n })\n )\n }\n // @ts-ignore\n return _link(merge(data, { query: data.query.concat([result.query]) }))\n }\n\n const thisDatesBefore = (\n key: string,\n jsDate: Date | string,\n { valueType = DatastoreValueType.date, equalToAndBefore = true } = {}\n ) => {\n const p = datesBefore(key, jsDate, { valueType, equalToAndBefore })\n return _link(merge(data, { query: data.query.concat(p) }))\n }\n\n const thisDatesAfter = (\n key: string,\n jsDate: Date | string,\n { valueType = DatastoreValueType.date, equalToAndAfter = true } = {}\n ) => {\n const p = datesAfter(key, jsDate, { valueType, equalToAndAfter })\n return _link(merge(data, { query: data.query.concat(p) }))\n }\n\n return {\n datesBefore: thisDatesBefore,\n datesAfter: thisDatesAfter,\n complex,\n property: _myProperty,\n }\n}\n\nconst _queryBuilder = (\n data: Partial<OrmSearch> | undefined = undefined\n): QueryBuilder => {\n const theData = merge(\n {\n query: [],\n },\n data\n )\n const builder = _builderV2(theData)\n const linkData = _additionalLink(theData)\n // @ts-ignore\n return {\n ...builder,\n ...linkData,\n compile: () => {\n return {\n ..._objectize('take', theData.take),\n ..._objectize('sort', theData.sort),\n ..._objectize('page', theData.page),\n query: [],\n } as OrmSearch\n },\n }\n}\n\n/**\n * Creates a property query.\n * @param key - The property's name/key/column to match on\n * @param value - The value to match\n * @param options - Additional options for changing this property query.\n */\nconst property = (\n key: string,\n value: any,\n options: PropertyOptions = {}\n): PropertyQuery => {\n const {\n equalitySymbol = EqualitySymbol.eq,\n caseSensitive,\n startsWith,\n endsWith,\n includes,\n type,\n } = options\n const typeToUse = type || DatastoreValueType.string\n if (!AllowableEqualitySymbols.includes(equalitySymbol)) {\n throw new Error(`${equalitySymbol} is not a valid symbol`)\n }\n if (\n equalitySymbol !== EqualitySymbol.eq &&\n equalitySymbol !== EqualitySymbol.ne &&\n typeToUse === DatastoreValueType.string\n ) {\n throw new Error(`Cannot use a non = symbol for a string type`)\n }\n\n const propertyEntry: PropertyQuery = {\n type: 'property',\n key,\n value,\n valueType: typeToUse,\n equalitySymbol,\n options: {\n ..._objectize('caseSensitive', caseSensitive),\n ..._objectize('startsWith', startsWith),\n ..._objectize('endsWith', endsWith),\n ..._objectize('includes', includes),\n },\n }\n return propertyEntry\n}\n\n/**\n * Limits the number of results to the provided count.\n * @param max - The maximum results to find\n */\nconst take = (max: number): MaxMatchStatement => {\n const parsed = parseInt(`${max}`, 10)\n if (Number.isNaN(parsed)) {\n throw new Error(`Number \"${max}\" is not integerable`)\n }\n return parsed\n}\n\n/**\n * Creates a sort query\n * @param key - The key to sort on\n * @param order - The order of the sort.\n */\nconst sort = (\n key: string,\n order: SortOrder | undefined = SortOrder.asc\n): SortStatement => {\n if (order !== SortOrder.asc && order !== SortOrder.dsc) {\n throw new Error('Sort must be either asc or dsc')\n }\n return {\n key,\n order,\n }\n}\n\n/**\n * Creates a pagination query.\n * @param value - Anything\n */\nconst pagination = (value: any): PaginationQuery => {\n return value\n}\n\n/**\n * Creates a query that looks at dated objects after the given date.\n * @param key - The property's key\n * @param jsDate - The date value being examined\n * @param options - Additional options\n */\nconst datesAfter = (\n key: string,\n jsDate: Date | string,\n options: { valueType: DatastoreValueType; equalToAndAfter: boolean } = {\n valueType: DatastoreValueType.date,\n equalToAndAfter: true,\n }\n): DatesAfterQuery => {\n const { valueType = DatastoreValueType.date, equalToAndAfter = true } =\n options\n return {\n type: 'datesAfter',\n key,\n date: isDate(jsDate) ? jsDate.toISOString() : jsDate,\n valueType,\n options: {\n equalToAndAfter,\n },\n }\n}\n\n/**\n * Determines if the object is a Date\n * @param obj - Date or string\n */\nconst isDate = (obj: Date | string): obj is Date => {\n // @ts-ignore\n return Boolean(obj.toISOString)\n}\n\n/**\n * Creates a search query that looks at dates before the given date.\n * @param key - The property's key\n * @param jsDate - The date value being examined.\n * @param options - Additional options\n */\nconst datesBefore = (\n key: string,\n jsDate: Date | string,\n options: { valueType: DatastoreValueType; equalToAndBefore: boolean } = {\n valueType: DatastoreValueType.date,\n equalToAndBefore: true,\n }\n): DatesBeforeQuery => {\n const { valueType = DatastoreValueType.date, equalToAndBefore = true } =\n options\n return {\n type: 'datesBefore',\n key,\n date: isDate(jsDate) ? jsDate.toISOString() : jsDate,\n valueType,\n options: {\n equalToAndBefore,\n },\n }\n}\n\n/**\n * Creates a builder that can create search queries.\n * This is a structured way to build search queries.\n */\nconst queryBuilder = (): QueryBuilder => {\n return _queryBuilder()\n}\n\n/**\n * Determines if the token is an Orm Property based statement\n * @param value\n */\nconst isPropertyBasedQuery = (value: any): value is Query => {\n if (!value || !value.type) {\n return false\n }\n return (\n value.type === 'property' ||\n value.type === 'datesBefore' ||\n value.type === 'datesAfter'\n )\n}\n\n/**\n * Determines if the value is a boolean\n * @param value - The value to examine.\n */\nconst isALinkToken = (value: any): value is BooleanQuery => {\n if (!value) {\n return false\n }\n if (typeof value !== 'string') {\n return false\n }\n value = value.toLowerCase()\n return value === 'and' || value === 'or'\n}\n\n/**\n * Creates an AND\n */\nconst and = () => 'AND'\n\n/**\n * Creates an OR\n */\nconst or = () => 'OR'\n\n/**\n * A helper query that is text based.\n * @param key - The property key/name\n * @param value - The value to match\n * @param options - Additional text based options\n */\nconst textQuery = (\n key: string,\n value: string | undefined | null,\n options?: Omit<Partial<PropertyOptions>, 'type' | 'equalitySymbol'>\n) =>\n property(\n key,\n value,\n Object.assign({}, options, {\n equalitySymbol: undefined,\n type: DatastoreValueType.string,\n })\n )\n\n/**\n * A helper query that is number based.\n * @param key - The property key/name\n * @param value - The value to match\n * @param equalitySymbol - A matching symbol for the number\n */\nconst numberQuery = (\n key: string,\n value: number | string | undefined | null,\n equalitySymbol: EqualitySymbol = EqualitySymbol.eq\n) =>\n property(key, value, {\n equalitySymbol,\n type: DatastoreValueType.number,\n })\n\n/**\n * A helper query that is for boolean values.\n * @param key - The property key/name\n * @param value - The value to match\n */\nconst booleanQuery = (key: string, value: boolean | undefined | null) =>\n property(key, value, {\n type: DatastoreValueType.boolean,\n equalitySymbol: EqualitySymbol.eq,\n })\n\n/**\n * A useful utility for processing {@link QueryTokens} with a {@link DatastoreAdapter}\n * Takes the first 3 values (property, LINK, property) and then shifts the list left by 2, so that it can create another property, LINK, property\n * @param data - The list of values\n */\nconst threeitize = <T>(data: T[]): T[][] => {\n if (data.length === 0 || data.length === 1) {\n return []\n }\n if (data.length % 2 === 0) {\n throw new Error('Must be an odd number of 3 or greater.')\n }\n const three = data.slice(0, THREE)\n const rest = data.slice(2)\n const moreThrees = threeitize(rest)\n return [three, ...moreThrees]\n}\n\nconst _validateTokenTypes = (token: QueryTokens) => {\n if (Array.isArray(token)) {\n token.forEach(_validateTokenTypes)\n return\n }\n if (isPropertyBasedQuery(token)) {\n return\n }\n if (isALinkToken(token)) {\n return\n }\n throw new Error(`Unknown token type ${token}`)\n}\n\nconst _validateTokenStructure = (o: QueryTokens[]) => {\n const first = o[0]\n if (first === 'AND' || first === 'OR') {\n throw new Error('Cannot have AND or OR at the very start.')\n }\n const last = o[o.length - 1]\n if (last === 'AND' || last === 'OR') {\n throw new Error('Cannot have AND or OR at the very end.')\n }\n if (o.every(x => x !== 'AND' && x !== 'OR')) {\n o.every(_validateArrayOrQuery)\n return\n }\n const totalLinks = o.filter(x => x === 'AND' || x === 'OR')\n const nonLinks = o.filter(x => x !== 'AND' && x !== 'OR')\n if (totalLinks.length !== nonLinks.length - 1) {\n throw new Error('Must separate each statement with an AND or OR')\n }\n // eslint-disable-next-line functional/immutable-data\n const threes = threeitize(o).reverse()\n threes.forEach(([a, l, b]) => {\n if (l !== 'AND' && l !== 'OR') {\n // @ts-ignore\n if (isPropertyBasedQuery(l)) {\n throw new Error('Must have AND/OR between property queries')\n }\n throw new Error('Must have AND/OR between nested queries')\n }\n _validateArrayOrQuery(a)\n _validateArrayOrQuery(b)\n })\n return\n}\n\nconst _validateArrayOrQuery = (o: QueryTokens) => {\n if (Array.isArray(o)) {\n _validateTokenStructure(o)\n return\n }\n if (isPropertyBasedQuery(o)) {\n return\n }\n throw new Error('Order of link tokens and queries invalid')\n}\n\nconst validateOrmSearch = (search: OrmSearch) => {\n if (Array.isArray(search.query) === false) {\n throw new Error(`Query must be an array`)\n }\n if (search.query.length < 1) {\n return\n }\n _validateTokenTypes(search.query)\n _validateTokenStructure(search.query)\n}\n\nexport {\n queryBuilder,\n take,\n pagination,\n sort,\n property,\n and,\n or,\n isALinkToken,\n isPropertyBasedQuery,\n datesBefore,\n datesAfter,\n textQuery,\n numberQuery,\n booleanQuery,\n threeitize,\n validateOrmSearch,\n}\n", "import {\n Arrayable,\n DataValue,\n Maybe,\n ModelInstance,\n ModelType,\n DataDescription,\n PrimaryKeyType,\n MinimalModelDefinition,\n PropertyConfig,\n ValidatorContext,\n ToObjectResult,\n ModelInstanceFetcher,\n ModelFactoryOptions,\n CreateParams,\n PropertyType,\n CanBeNullableType,\n} from '../types.js'\n\n/**\n * Equals symbols for doing database matching\n */\nexport enum EqualitySymbol {\n // Equals\n eq = '=',\n // Less than\n lt = '<',\n // Equal to or less than\n lte = '<=',\n // Greater than\n gt = '>',\n // Equal to or greater than\n gte = '>=',\n // Not equal to\n ne = '!=',\n}\n\n/**\n * The value types that map to database types.\n */\nexport enum DatastoreValueType {\n string = 'string',\n number = 'number',\n date = 'date',\n object = 'object',\n boolean = 'boolean',\n}\n\n/**\n * A list of allowable equality symbols.\n */\nexport const AllowableEqualitySymbols = Object.values(EqualitySymbol)\n\n/**\n * A function that can save.\n */\ntype SaveMethod<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = <TData extends DataDescription>(\n /**\n * An instance to save\n */\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n) => Promise<\n OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n>\n\n/**\n * A method that can delete\n */\ntype DeleteMethod<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = <TData extends DataDescription>(\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n) => Promise<void>\n\n/**\n * A function that allows overriding the save functionality for a specific model.\n */\nexport type SaveOverride<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = <TData extends DataDescription>(\n existingSave: SaveMethod<TModelExtensions, TModelInstanceExtensions>,\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n) => Promise<\n OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n>\n\n/**\n * A function that allows overriding the delete functionality for a specific model.\n */\nexport type DeleteOverride<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = <TData extends DataDescription>(\n existingDelete: DeleteMethod<TModelExtensions, TModelInstanceExtensions>,\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n) => Promise<void>\n\n/**\n * A result of an ORM search.\n * @interface\n */\nexport type OrmSearchResult<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * A list of instances\n */\n instances: readonly OrmModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >[]\n /**\n * An optional page value. The exact structure is provided by the datastore itself.\n */\n page?: any\n}>\n\n/**\n * ORM based ModelFactory extensions.\n * @interface\n */\nexport type OrmModelFactoryOptionsExtensions<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * Optional: The save function to override.\n */\n save?: SaveOverride<TModelExtensions, TModelInstanceExtensions>\n /**\n * Optional: The delete function to override.\n */\n delete?: DeleteOverride<TModelExtensions, TModelInstanceExtensions>\n}>\n\n/**\n * Extensions to the Model type\n * @interface\n */\nexport type OrmModelExtensions<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * Save the model\n * @param instance - The instance to save.\n */\n save: <TData extends DataDescription>(\n instance: OrmModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ) => Promise<\n OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n >\n /**\n * Deletes an instance by its id.\n * @param id - The id to delete\n */\n delete: (id: PrimaryKeyType) => Promise<void>\n /**\n * Attempts to get an instance by its id\n * @param primaryKey\n */\n retrieve: <TData extends DataDescription>(\n primaryKey: PrimaryKeyType\n ) => Promise<\n Maybe<OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>>\n >\n /**\n * Searches instances by the provided search query\n * @param query\n */\n search: <TData extends DataDescription>(\n query: OrmSearch\n ) => Promise<\n OrmSearchResult<\n TData,\n OrmModel<TData, TModelExtensions, TModelInstanceExtensions>\n >\n >\n /**\n * Searches for a single instance with the given query.\n * @param query\n */\n searchOne: <TData extends DataDescription>(\n query: Omit<OrmSearch, 'take'>\n ) => Promise<\n | OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n | undefined\n >\n /**\n * Creates and saves an instance. An optimization in some databases\n * @param query\n */\n createAndSave: <TData extends DataDescription>(\n data: OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n ) => Promise<\n OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n >\n /**\n * Inserts multiple objects at once. Can often see great optimizations in some databases.\n * @param query\n */\n bulkInsert: <TData extends DataDescription>(\n instances: readonly OrmModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >[]\n ) => Promise<void>\n /**\n * Deletes multiple instances at once.\n * @param instances\n */\n bulkDelete: <TData extends DataDescription>(\n keysOrInstances:\n | readonly OrmModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >[]\n | readonly PrimaryKeyType[]\n ) => Promise<void>\n /**\n * Counts the number of models saved in the database.\n */\n count: () => Promise<number>\n}>\n\n/**\n * Instance overrides that give it ORM functions.\n * @interface\n */\nexport type OrmModelInstanceExtensions<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * Save this model.\n */\n save: <TData extends DataDescription>() => Promise<\n OrmModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n >\n /**\n * Delete this model.\n */\n delete: () => Promise<void>\n}>\n\n/**\n * ORM based configurations for a model.\n * @interface\n */\ntype OrmModelConfigurations = Readonly<{\n /**\n * Validator that there is only a single value in the datastore that has the properties given.\n * Example:\n * [\"name\", \"text\"]\n * This will make sure that there can only be a single row in the database that has a unique combination of name and text.\n */\n uniqueTogether?: readonly string[]\n}>\n\n/**\n * A minimum orm model definition\n * @interface\n */\nexport type MinimumOrmModelDefinition<TData extends DataDescription> =\n MinimalModelDefinition<TData> & OrmModelConfigurations\n\n/**\n * A model factory that produces ORM based models.\n *\n */\nexport type OrmModelFactory<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n TModelOptionsExtensions extends object = object,\n> = <TData extends DataDescription>(\n /**\n * The model definition for the model\n */\n modelDef: MinimumOrmModelDefinition<TData>,\n /**\n * Additional options for this model.\n */\n options?: ModelFactoryOptions<\n TData,\n OrmModelFactoryOptionsExtensions<\n TModelExtensions,\n TModelInstanceExtensions\n > &\n TModelOptionsExtensions\n >\n) => OrmModel<TData, TModelExtensions, TModelInstanceExtensions>\n\n/**\n * A search result from a datastore\n * @interface\n */\nexport type DatastoreSearchResult<T extends DataDescription> = Readonly<{\n /**\n * An array of objects that represent the data from the datastore.\n */\n instances: readonly ToObjectResult<T>[]\n /**\n * Any pagination information.\n */\n page?: any\n}>\n\n/**\n * A model that has ORM functions attached.\n * @interface\n */\nexport type OrmModel<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = ModelType<\n TData,\n OrmModelExtensions<TModelExtensions, TModelInstanceExtensions>,\n OrmModelInstanceExtensions<TModelExtensions, TModelInstanceExtensions>\n>\n\n/**\n * A Model Instance with ORM functions attached.\n * @interface\n */\nexport type OrmModelInstance<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = ModelInstance<\n TData,\n OrmModelExtensions<TModelExtensions, TModelInstanceExtensions>,\n OrmModelInstanceExtensions<TModelExtensions, TModelInstanceExtensions>\n>\n\n/**\n * An interface that describes a datastore. By implementing this interface, databases can be swapped.\n * @interface\n */\nexport type DatastoreAdapter = Readonly<{\n /**\n * Saving a model.\n * @param instance\n */\n save: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n ) => Promise<ToObjectResult<TData>>\n /**\n * Deleting an instance.\n * @param model\n * @param id\n */\n delete: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n model: OrmModel<TData, TModelExtensions, TModelInstanceExtensions>,\n id: PrimaryKeyType\n ) => Promise<void>\n /**\n * Attempts to retrieves an instance.\n * @param model\n * @param primaryKey\n */\n retrieve: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n model: OrmModel<TData, TModelExtensions, TModelInstanceExtensions>,\n primaryKey: PrimaryKeyType\n ) => Promise<Maybe<ToObjectResult<TData>>>\n /**\n * Searches for instances by a query.\n * @param model\n * @param query\n */\n search: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n model: OrmModel<TData, TModelExtensions, TModelInstanceExtensions>,\n query: OrmSearch\n ) => Promise<DatastoreSearchResult<TData>>\n /**\n * Optional: An optimized bulkInsert function. (Highly recommended)\n * @param model\n * @param instances\n */\n bulkInsert?: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n model: OrmModel<TData, TModelExtensions, TModelInstanceExtensions>,\n instances: readonly ModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >[]\n ) => Promise<void>\n /**\n * Optional: An optimized bulkDelete function. (Highly recommended)\n * @param model\n * @param keysOrInstances\n */\n bulkDelete?: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n model: OrmModel<TData, TModelExtensions, TModelInstanceExtensions>,\n keys: readonly PrimaryKeyType[]\n ) => Promise<void>\n /**\n * Optional: An optimized createAndSave function.\n * @param instance\n */\n createAndSave?: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n ) => Promise<ToObjectResult<TData>>\n /**\n * Optional: An optimized counting function. Highly recommended.\n * @param model\n */\n count?: <\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n >(\n model: OrmModel<TData, TModelExtensions, TModelInstanceExtensions>\n ) => Promise<number>\n}>\n\n/**\n * A search that describes a property and its value.\n * @interface\n */\nexport type PropertyQuery = Readonly<{\n /**\n * Distinguishes this as a property query.\n */\n type: 'property'\n /**\n * The property's key\n */\n key: string\n /**\n * The value to search for.\n */\n value: any\n /**\n * The type of database value.\n */\n valueType: DatastoreValueType\n /**\n * How the value should be compared.\n */\n equalitySymbol: EqualitySymbol\n /**\n * Options for additional matching.\n */\n options: PropertyOptions\n}>\n\n/**\n * A property search for a string value.\n */\nexport type StringPropertyQuery = PropertyQuery & {\n valueType: DatastoreValueType.string\n equalitySymbol: EqualitySymbol.eq | EqualitySymbol.ne\n options: PropertyOptions\n}\n\n/**\n * A search that looks at dated objects after the given date.\n * @interface\n */\nexport type DatesAfterQuery = Readonly<{\n /**\n * Distinguishes this query\n */\n type: 'datesAfter'\n /**\n * The property's key\n */\n key: string\n /**\n * The date value being examined.\n */\n date: string\n /**\n * The database type.\n */\n valueType: DatastoreValueType\n /**\n * Options for additional searching\n */\n options: {\n /**\n * Should this search be equalsTo as well as after?\n */\n equalToAndAfter: boolean\n }\n}>\n\n/**\n * A search query that looks at dates before the given date.\n * @interface\n */\nexport type DatesBeforeQuery = Readonly<{\n /**\n * Distinguishes this query\n */\n type: 'datesBefore'\n /**\n * The property's key.\n */\n key: string\n /**\n * The date value being examined.\n */\n date: string\n /**\n * The database value type.\n */\n valueType: DatastoreValueType\n /**\n * Options for additional searching\n */\n options: {\n /**\n * Should this search be equalsTo as well as before?\n */\n equalToAndBefore: boolean\n }\n}>\n\n/**\n * Additional configurations for ORM based properties.\n * @interface\n */\nexport type OrmPropertyConfig<T extends Arrayable<DataValue>> =\n PropertyConfig<T> &\n Readonly<{\n /**\n * Validator: Checks to make sure that there is only one instance in a datastore that has this property's value.\n * NOTE: The value is a property KEY. Not true or false.\n */\n unique?: string\n }>\n\n/**\n * Additional context that is provided for ORM based instance.\n * @interface\n */\nexport type OrmValidatorContext = Readonly<{\n /**\n * IMPORTANT: Sometimes you do not want to do any ORM based validation because of speed.\n * This disables any orm based validation, and only runs non-orm validation.\n */\n noOrmValidation?: boolean\n}> &\n ValidatorContext\n\n/**\n * Options for a property query.\n */\nexport type PropertyOptions = {\n /**\n * Is this a case sensitive search?\n */\n caseSensitive?: boolean\n /**\n * Is the value a startsWith query?\n */\n startsWith?: boolean\n /**\n * Is the value a endsWith query?\n */\n endsWith?: boolean\n /**\n * Is the value a includes query?\n */\n includes?: boolean\n /**\n * The type of value\n */\n type?: DatastoreValueType\n /**\n * An equality symbol.\n */\n equalitySymbol?: EqualitySymbol\n}\n\n/**\n * An object that has both an Orm Model Factory (that can make Orm Models) as well as a loaded fetcher\n * that can retrieve referenced models as needed. See {@see \"functional-models.ModelReference\"}\n * @interface\n */\nexport type Orm = {\n /**\n * A model factory that can produce {@link OrmModel}\n */\n Model: OrmModelFactory\n /**\n * A fetcher for use with Model References\n */\n fetcher: ModelInstanceFetcher<OrmModelExtensions, OrmModelInstanceExtensions>\n}\n\n/**\n * The sort order.\n */\nexport enum SortOrder {\n asc = 'asc',\n dsc = 'dsc',\n}\n\n/**\n * The number of instances to receive back from a query.\n */\nexport type MaxMatchStatement = number\n\n/**\n * Defines how a sort should happen. Which column and what order.\n * @interface\n */\nexport type SortStatement = {\n /**\n * The property's key/name. Also could be a \"column\"\n */\n key: string\n /**\n * Ascending or Descending sort.\n */\n order: SortOrder\n}\n\n/**\n * Pagination can be anything.\n */\nexport type PaginationQuery = any\n\n/**\n * A query to a search function.\n * @interface\n */\nexport type OrmSearch = {\n /**\n * Optional: A number of max records to return.\n */\n take?: MaxMatchStatement\n /**\n * Optional: Sorting.\n */\n sort?: SortStatement\n /**\n * Optional: Pagination information\n */\n page?: PaginationQuery\n /**\n * Optional: Querying tokens.\n */\n query: readonly QueryTokens[]\n}\n\n/**\n * Statements that make up the meat of QueryTokens\n */\nexport type Query =\n | PropertyQuery\n | DatesAfterQuery\n | DatesBeforeQuery\n | StringPropertyQuery\n\n/**\n * A token type that links two queries together.\n */\nexport type BooleanQuery = 'AND' | 'OR'\n\n/**\n * A generic structure of querys.\n */\nexport type QueryTokens =\n | readonly QueryTokens[][]\n | readonly QueryTokens[]\n | BooleanQuery\n | Query\n\n/**\n * Builder functions that are not property related.\n * @interface\n */\ntype NonQueryBuilder = Readonly<{\n /**\n * Creates a pagination.\n * @param value - Can be anything\n */\n pagination: (value: any) => BuilderV2Link & InnerBuilderV2\n /**\n * Creates a sort.\n * @param key - The key to sort on\n * @param sortOrder - The order to sort by. Defaults to ascending.\n */\n sort: (key: string, sortOrder?: SortOrder) => BuilderV2Link & InnerBuilderV2\n /**\n * Maximum number of elements to return.\n * @param count - The count\n */\n take: (count: number) => BuilderV2Link & InnerBuilderV2\n /**\n * Compiles the builder into a search query.\n */\n compile: () => OrmSearch\n}>\n\n/**\n * An in between or ending type to a builder creating a SearchQuery\n * @interface\n */\nexport type BuilderV2Link = NonQueryBuilder &\n Readonly<{\n /**\n * Links together two or more {@link Query} or complex queries.\n */\n and: () => QueryBuilder\n /**\n * Links together two or more {@link Query} or complex queries.\n */\n or: () => QueryBuilder\n }>\n\n/**\n * A function that can either take a builder or raw QueryTokens[] and create a sub-query.\n * @param builder - Can be either a BuilderV2 or a hand written Query\n **/\nexport type SubBuilderFunction = (\n builder: QueryBuilder\n) => Omit<OrmSearch, 'take' | 'sort' | 'page'> | (QueryBuilder | BuilderV2Link)\n\n/**\n * A search builder is a structured way to create a complex query.\n * @interface\n */\nexport type QueryBuilder = InnerBuilderV2 & NonQueryBuilder\n\n/**\n * A builder for version 3.0 search queries.\n * @interface\n */\nexport type InnerBuilderV2 = {\n /**\n * Creates a query that has nested property queries.\n * @param subBuilderFunc - A function that can return a Builder\n */\n complex: (subBuilderFunc: SubBuilderFunction) => BuilderV2Link\n /**\n * Searches for elements that are after the given date.\n * NOTE: It can be very important to set the valueType to either string or Date depending on what datastore you are using.\n * @param key - The property name/key to use.\n * @param jsDate - The date to search.\n * @param options - Additional options.\n */\n datesAfter: (\n key: string,\n jsDate: Date | string,\n options?: { valueType?: DatastoreValueType; equalToAndAfter?: boolean }\n ) => BuilderV2Link\n /**\n * Searches for elements that are before the given date.\n * NOTE: It can be very important to set the valueType to either string or Date depending on what datastore you are using.\n * @param key - The property name/key to use.\n * @param jsDate - The date to search.\n * @param options - Additional options.\n */\n datesBefore: (\n key: string,\n jsDate: Date | string,\n options?: { valueType?: DatastoreValueType; equalToAndBefore?: boolean }\n ) => BuilderV2Link\n /**\n * Search a value\n * @param key - The property name/key to use.\n * @param value - The value to match.\n * @param options - Additional options.\n */\n property: (\n key: string,\n value: any,\n options?: Partial<PropertyOptions>\n ) => BuilderV2Link\n}\n\n/**\n * The types of primary key properties.\n */\nexport type PrimaryKeyPropertyType =\n | PropertyType.UniqueId\n | PropertyType.Text\n | PropertyType.Integer\n\n/**\n * A function that can generate a primary key for a model.\n * @param model - The model to generate a primary key for.\n * @returns A promise that resolves to the primary key.\n */\nexport type PrimaryKeyGenerator = <\n TValue extends PrimaryKeyType,\n TData extends DataDescription,\n>(\n value: TValue,\n modelData: CreateParams<TData>,\n instance: ModelInstance<TData>\n) => Promise<PrimaryKeyType>\n\n/**\n * A property that represents a key in a database.\n * By default it is a \"uuid\" type, but if you want to use an arbitrary string, or an integer type you can set the `dataType` property.\n * @interface\n */\nexport type DatabaseKeyPropertyConfig<\n TValue extends CanBeNullableType<PrimaryKeyType> = PrimaryKeyType,\n> = PropertyConfig<TValue> &\n Readonly<{\n /**\n * Sets the type of the key.\n * @default PrimaryKeyDataType.Uuid\n */\n dataType?: PrimaryKeyPropertyType\n /**\n * If true, the key will be automatically generated if not provided. Only applies to uuids and integers\n * @default true\n */\n auto?: boolean\n /**\n * Optional: A custom primary key generator function to use for models. If the property type is UniqueId (default) then this will produce random UUID. If the property type is a number, a random number will be generated.\n * If using a SQL-like database that uses numbers, its HIGHLY recommended to get a number from the database itself.\n */\n primaryKeyGenerator?: PrimaryKeyGenerator\n }>\n", "import flow from 'lodash/flow.js'\nimport {\n PropertyValidatorComponentAsync,\n DataDescription,\n PrimaryKeyType,\n ComponentValidationErrorResponse,\n JsonAble,\n ModelValidatorComponent,\n} from '../types.js'\nimport { queryBuilder } from './query.js'\nimport {\n OrmSearch,\n OrmValidatorContext,\n OrmModel,\n OrmModelExtensions,\n OrmModelInstanceExtensions,\n} from './types.js'\n\nconst _doUniqueCheck = async <T extends DataDescription>(\n query: OrmSearch,\n model: OrmModel<T>,\n instanceData: T | JsonAble,\n buildErrorMessage: () => ComponentValidationErrorResponse\n): Promise<ComponentValidationErrorResponse> => {\n const results = await model.search(query)\n const resultsLength = results.instances.length\n // There is nothing stored with this value.\n if (resultsLength < 1) {\n return undefined\n }\n const ids: readonly PrimaryKeyType[] = await Promise.all(\n results.instances.map((x: any) => x.getPrimaryKey())\n )\n // We have our match by id.\n // @ts-ignore\n const instanceId = instanceData[model.getModelDefinition().primaryKeyName]\n if (ids.length === 1 && ids[0] === instanceId) {\n return undefined\n }\n if (ids.length > 1) {\n // This is a weird but possible case where there is more than one item. We don't want to error\n // if the instance we are checking is already in the datastore.\n if (ids.find(x => x === instanceId)) {\n return undefined\n }\n }\n return buildErrorMessage()\n}\n\n/**\n * A validator that ensures that there is only one instance stored, that has a unique combination of values.\n * @param propertyKeyArray - An array of property names that create the unique match.\n */\nconst uniqueTogether = <T extends DataDescription>(\n propertyKeyArray: readonly string[]\n): ModelValidatorComponent<\n T,\n OrmModelExtensions,\n OrmModelInstanceExtensions\n> => {\n const _uniqueTogether = async (\n model: OrmModel<T>,\n instanceData: T | JsonAble,\n options: OrmValidatorContext\n ) => {\n if (options?.noOrmValidation) {\n return undefined\n }\n const properties = propertyKeyArray.map(key => {\n // @ts-ignore\n return [key, instanceData[key]]\n })\n const query = flow(\n properties.map(([key, value], index) => {\n return b => {\n // We only want to do an 'and' if there is another property.\n if (index + 1 >= properties.length) {\n return b.property(key, value, { caseSensitive: false })\n }\n return b.property(key, value, { caseSensitive: false }).and()\n }\n })\n )(queryBuilder().take(2)).compile()\n return _doUniqueCheck<T>(query, model, instanceData, () => {\n return propertyKeyArray.length > 1\n ? `${propertyKeyArray.join(\n ','\n )} must be unique together. Another instance found.`\n : `${propertyKeyArray[0]} must be unique. Another instance found.`\n })\n }\n return _uniqueTogether\n}\n\n/**\n * Validates that a stored instance is the only one that has a value for a specific property.\n * This only validates before the instance goes into the datastore.\n * @param propertyKey - The property key to check.\n */\nconst unique = <T extends DataDescription>(\n propertyKey: string\n): PropertyValidatorComponentAsync<\n T,\n OrmModelExtensions,\n OrmModelInstanceExtensions\n> => {\n const _unique: PropertyValidatorComponentAsync<\n T,\n OrmModelExtensions,\n OrmModelInstanceExtensions\n > = (value, model, instanceData, options) => {\n return uniqueTogether<T>([propertyKey])(model, instanceData, options)\n }\n return _unique\n}\n\n/**\n * Creates a base orm context.\n * @param noOrmValidation - Determines if the validation process should ignore any ORM related validation. (If you don't want to do a database query for a specific validation).\n */\nconst buildOrmValidatorContext = ({\n noOrmValidation = false,\n}): OrmValidatorContext => ({\n noOrmValidation,\n})\n\nexport { unique, uniqueTogether, buildOrmValidatorContext }\n", "import merge from 'lodash/merge.js'\nimport identity from 'lodash/identity.js'\nimport {\n PrimaryKeyType,\n DateValueType,\n PropertyConfig,\n Arrayable,\n DataValue,\n MaybeFunction,\n ModelType,\n DataDescription,\n ModelInstance,\n CreateParams,\n PropertyType,\n CanBeNullableType,\n} from '../types.js'\nimport {\n DatetimeProperty,\n IntegerProperty,\n TextProperty,\n UuidProperty,\n} from '../properties.js'\nimport { unique } from './validation.js'\nimport { OrmPropertyConfig, DatabaseKeyPropertyConfig } from './types.js'\nimport { getPrimaryKeyGenerator } from './internal-libs.js'\n\nconst _defaultPropertyConfig = {\n unique: undefined,\n}\n\n/**\n * A property that automatically updates whenever the model instance is saved.\n * @param config\n */\nexport const LastModifiedDateProperty = <\n T extends CanBeNullableType<DateValueType> = DateValueType,\n>(\n config: PropertyConfig<T> = {}\n) => {\n const additionalMetadata = { lastModifiedUpdateMethod: () => new Date() }\n return DatetimeProperty<T>(config, additionalMetadata)\n}\n\n/**\n * A property that represents a foreign key to another model in a database.\n * By default it is a \"uuid\" type, but if you want to use an arbitrary string, or an integer type you can set the `dataType` property.\n * NOTE: auto is ignored in config.\n * @param config - Additional configurations.\n */\nexport const ForeignKeyProperty = <\n TValue extends PrimaryKeyType,\n TModel extends DataDescription,\n>(\n model: MaybeFunction<ModelType<TModel>>,\n config: Omit<\n DatabaseKeyPropertyConfig<TValue>,\n 'auto' | 'primaryKeyGenerator'\n > = {}\n) => {\n const _getModel = () => {\n if (typeof model === 'function') {\n return model()\n }\n return model\n }\n\n const _getProperty = () => {\n if (config.dataType === PropertyType.UniqueId) {\n return UuidProperty(\n merge(config as DatabaseKeyPropertyConfig<string>, {\n autoNow: false,\n })\n )\n }\n if (config.dataType === PropertyType.Integer) {\n return IntegerProperty(config as DatabaseKeyPropertyConfig<number>)\n }\n return TextProperty(config as DatabaseKeyPropertyConfig<string>)\n }\n const property = _getProperty()\n return merge(property, {\n getReferencedId: (instanceValues: TValue) => {\n return instanceValues\n },\n getReferencedModel: _getModel,\n })\n}\n\n/**\n * A property that represents a primary key in a database.\n * By default it is a \"uuid\" type, but if you want to use an arbitrary string, or an integer type you can set the `dataType` property.\n * Includes an optional primaryKeyGenerator function that can be used to generate a primary key. This can allow primary keys that are generated at runtime, or grabbed from a database.\n * @param config - Additional configurations.\n * @returns\n */\nexport const PrimaryKeyProperty = <\n TValue extends CanBeNullableType<PrimaryKeyType> = PrimaryKeyType,\n>(\n config: DatabaseKeyPropertyConfig<TValue> = {}\n) => {\n const _getProperty = () => {\n const auto = config.auto === undefined ? true : config.auto ? true : false\n const lazyLoadMethod = (\n value: TValue,\n modelData: CreateParams<any>,\n instance: ModelInstance<any>\n ) => {\n if (config.primaryKeyGenerator) {\n // @ts-ignore\n return config.primaryKeyGenerator(value, modelData, instance)\n }\n if (auto) {\n // @ts-ignore\n return getPrimaryKeyGenerator(config)(value, modelData, instance)\n }\n return value\n }\n\n if (config.dataType === PropertyType.UniqueId) {\n return UuidProperty(\n merge(config as DatabaseKeyPropertyConfig<string>, {\n autoNow: auto,\n lazyLoadMethod,\n })\n )\n }\n if (config.dataType === PropertyType.Integer) {\n return IntegerProperty(\n merge(config as DatabaseKeyPropertyConfig<number>, {\n lazyLoadMethod,\n })\n )\n }\n return TextProperty(\n merge(config as DatabaseKeyPropertyConfig<string>, {\n lazyLoadMethod,\n })\n )\n }\n return _getProperty()\n}\n\n/**\n * Creates an orm based property config.\n * @param config - Additional configurations.\n */\nexport const ormPropertyConfig = <T extends Arrayable<DataValue>>(\n config: OrmPropertyConfig<T> = _defaultPropertyConfig\n): PropertyConfig<T> => {\n return merge(config, {\n validators: [\n ...(config.validators ? config.validators : []),\n config.unique ? unique(config.unique) : null,\n ].filter(identity),\n })\n}\n", "import * as openapi from 'openapi-types'\nimport { ZodObject, ZodType } from 'zod'\n\nexport type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never }\n\nexport type XOR<T, U> = T | U extends object\n ? (Without<T, U> & U) | (Without<U, T> & T)\n : T | U\n\n/**\n * A function that returns the value, or just the value\n */\ntype MaybeFunction<T> = T | (() => T)\n\n/**\n * The data or a promise that returns the data\n */\ntype MaybePromise<T> = T | Promise<T>\n\n/**\n * The value or null\n */\ntype Nullable<T> = T | null\n\n/**\n * The value, or undefined\n */\ntype Maybe<T> = T | undefined\n\n/**\n * The value or an array of the types of value\n */\ntype Arrayable<T> = T | readonly T[]\n\n/**\n * A JSON compliant object.\n */\ntype JsonObj = Readonly<{\n [s: string]: JsonAble | null | undefined\n}>\n\n/**\n * A description of valid json values.\n */\ntype JsonAble =\n | Arrayable<JsonObj>\n | readonly (number | string | boolean)[]\n | readonly JsonAble[]\n | number\n | string\n | boolean\n | null\n | undefined\n\n/**\n * This is a fully Json compliant version of a DataDescription\n */\ntype JsonifiedData<T extends DataDescription> = {\n readonly [P in keyof T]: JsonAble\n}\n\n/**\n * Removes promises from every property of an object.\n */\ntype RemovePromises<T extends object> = {\n // @ts-ignore\n [K in keyof T as T[K] extends Promise<any> ? K : never]: Awaited<T[K]>\n} & {\n [K in keyof T as T[K] extends Promise<any> ? never : K]: T[K]\n}\n\n/**\n * The types that are allowed in a choice.\n */\ntype ChoiceTypes = null | string | number | boolean\n\n/**\n * A Model Reference that is only string|number|undefined|null\n */\ntype FlattenModelReferences<TData extends DataDescription> = {\n [K in keyof TData as TData[K] extends ModelInstance<any>\n ? never\n : K]: TData[K]\n} & {\n [K in keyof TData as TData[K] extends ModelInstance<TData>\n ? K\n : never]: PrimaryKeyType\n}\n\n/**\n * The result of a \"toObj()\" call. See {@link ModelInstance.toObj}\n * This is guaranteed to be JSON compliant.\n */\ntype ToObjectResult<TData extends DataDescription> = RemovePromises<\n FlattenModelReferences<TData>\n>\n\n/**\n * A function that will provide a JSON compliant representation of the data.\n * Useful for saving in a database, or sending out over a network.\n */\ntype ToObjectFunction<TData extends DataDescription> = <\n R extends TData | JsonifiedData<TData> = JsonifiedData<TData>,\n>() => Promise<ToObjectResult<R>>\n\n/**\n * Getter functions that provide access to the value of a property of an instance.\n */\ntype PropertyGetters<TData extends DataDescription> = {\n readonly [PropertyKey in keyof Required<TData>]: () => TData[PropertyKey]\n}\n\n/**\n * The most basic description of data supported by this framework.\n * This includes all of JSON and additional functionality for referenced models.\n */\ntype DataDescription = Readonly<{\n [s: string]:\n | Promise<PrimaryKeyType>\n | Arrayable<number>\n | Arrayable<string>\n | Arrayable<boolean>\n | Arrayable<null>\n | Arrayable<DataDescription>\n | Arrayable<Date>\n | Arrayable<undefined>\n | ModelReferenceType<any>\n | Arrayable<JsonAble>\n}>\n\nexport type CanBeNullableType<T extends DataValue> = XOR<\n T | undefined | null,\n T\n>\n\n/**\n * These are the allowable types for setting a property of data to.\n */\ntype DataValue = MaybePromise<\n | Arrayable<JsonAble>\n | (() => DataValue) // A lazy function that provides a value.\n | Arrayable<null>\n | Arrayable<undefined>\n | Arrayable<Date>\n | Arrayable<DataDescription>\n>\n\n/**\n * Additional context to a validation. Sometimes there are other validation information needed than what can be provided within a model itself.\n */\ntype ValidatorContext = Readonly<Record<string, any>>\n\n/**\n * A collection of errors for a property or model.\n */\ntype ValidationErrors = readonly string[]\n\n/**\n * The response to a validation attempt of a model at the lowest level. Something is bad (a string), or its good (undefined)\n */\ntype ComponentValidationErrorResponse = string | undefined\n\n/**\n * The errors across an entire model. Contains both overall errors, as well as individualized property errors.\n */\ntype ModelErrors<TData extends DataDescription> = {\n readonly [Property in keyof Partial<TData>]: ValidationErrors\n} & Readonly<{ overall?: ValidationErrors }>\n\n/**\n * The most flexible representation of a Property Validator.\n * @param value - The raw value being evaluated\n * @param model - The model (e.g. for datastore lookups). Use model.create(data) if you need an instance.\n * @param instanceData - An already JSONified version of the model. This is a convenience so toObj() does not need to be called so frequently.\n * @param context - Additional outside context to help with validation. (Most cases this is unused)\n */\ntype PropertyValidatorComponentTypeAdvanced<\n TValue,\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = (\n value: TValue,\n model: ModelType<TData, TModelExtensions, TModelInstanceExtensions>,\n instanceData: ToObjectResult<TData>,\n context: ValidatorContext\n) => ComponentValidationErrorResponse\n\n/**\n * A Property Validator that does not use Promises\n */\ntype PropertyValidatorComponentSync<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = PropertyValidatorComponentTypeAdvanced<\n any,\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n>\n\n/**\n * A simple property validator that just looks at the value.\n * @param value - A single value to validate\n */\ntype ValuePropertyValidatorComponent<TValue extends Arrayable<DataValue>> = (\n value: TValue\n) => ComponentValidationErrorResponse\n\n/**\n * A property validator that returns a promise.\n * @param value - The value to validate\n * @param model - The model (e.g. for datastore lookups). Use model.create(data) if you need an instance.\n * @param instanceData - The jsonified version of the data\n * @param context - Additional context to validate against.\n */\ntype PropertyValidatorComponentAsync<\n TData extends DataDescription,\n TModelExtensions extends object,\n TModelInstanceExtensions extends object,\n> = (\n value: Arrayable<DataValue>,\n model: ModelType<TData, TModelExtensions, TModelInstanceExtensions>,\n instanceData: ToObjectResult<TData>,\n context: ValidatorContext\n) => Promise<ComponentValidationErrorResponse>\n\n/**\n * A property validator that is either Sync or Async.\n */\ntype PropertyValidatorComponent<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> =\n | PropertyValidatorComponentSync<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n | PropertyValidatorComponentAsync<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n\n/**\n * The validator for an entire property. This is composed of multiple underlying validators that all get executed and then assembled together.\n * @param model - The model (the instance's model). Use model.create(data) if you need an instance.\n * @param instanceData - The instance data to compare\n * @param context - Additional context for validating.\n */\ntype PropertyValidator<TData extends DataDescription> = (\n model: ModelType<TData>,\n instanceData: ToObjectResult<TData>,\n context: ValidatorContext\n) => Promise<ValidationErrors>\n\n/**\n * The component of a Model Validator. These are combined to create a single model validator.\n * @param model - The model. Use model.create(data) if you need an instance.\n * @param instanceData - The JSONified version of the model.\n * @param context - Additional context to assist with validating.\n */\ntype ModelValidatorComponent<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = (\n model: ModelType<TData, TModelExtensions, TModelInstanceExtensions>,\n instanceData: ToObjectResult<TData>,\n context: ValidatorContext\n) => Promise<ComponentValidationErrorResponse>\n\n/**\n * A function that will get the value of a property.\n * Depending on what the property is, it'll either be a primitive value\n * or it'll be a referenced model.\n */\ntype ValueGetter<\n /**\n * The type of value\n */\n TValue extends Arrayable<DataValue>,\n /**\n * The value existing within a specific type of data.\n */\n TData extends DataDescription = DataDescription,\n /**\n * Any additional model extensions.\n */\n TModelExtensions extends object = object,\n /**\n * Any additional model instance extensions.\n */\n TModelInstanceExtensions extends object = object,\n> = () => MaybePromise<\n TValue | ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n>\n\n/**\n * An instance of a property. This is used to describe a property in depth as well as provide functionality like validating values.\n * @interface\n */\ntype PropertyInstance<\n /**\n * The type of value that the property represents.\n */\n TValue extends Arrayable<DataValue>,\n /**\n * The data that the property sits within.\n */\n TData extends DataDescription = DataDescription,\n /**\n * Any additional model extensions.\n */\n TModelExtensions extends object = object,\n /**\n * Any additional model instance extensions.\n */\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * Gets the configuration passed into the property constructor.\n */\n getConfig: () => object\n /**\n * Gets available choices for limiting the value of this property.\n */\n getChoices: () => readonly ChoiceTypes[]\n /**\n * If there is a default value\n */\n getDefaultValue: () => TValue | undefined\n /**\n * If there is a constant value that never changes. (This is used above all else).\n */\n getConstantValue: () => TValue | undefined\n /**\n * Gets the ValueType of the property. Unless custom properties are used, the value is a {@link PropertyType}.\n * Otherwise the value could be string for custom types.\n */\n getPropertyType: () => PropertyType | string\n /**\n * Creates a value getter.\n * @param value - The type of value\n * @param modelData - The type of data.\n * @param modelInstance - An instance of the model that has the data.\n */\n createGetter: (\n value: TValue,\n modelData: TData,\n modelInstance: ModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ) => ValueGetter<TValue, TData, TModelExtensions, TModelInstanceExtensions>\n /**\n * Function that exposes a zod schema for this property.\n */\n getZod: () => ZodType<TValue>\n /**\n * Gets a validator for the property. This is not normally used.\n * Instead for validation look at {@link ModelInstance.validate}\n * @param valueGetter - The getter for the value.\n */\n getValidator: (\n valueGetter: ValueGetter<\n TValue,\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ) => PropertyValidator<TData>\n}>\n\n/**\n * A list of properties that make up a model.\n */\ntype PropertiesList<TData extends DataDescription> = {\n readonly [P in keyof TData as TData[P] extends Arrayable<DataValue>\n ? P\n : never]: PropertyInstance<any>\n}\n\n/**\n * An extends a Property to add additional functions helpful for dealing with\n * referenced models.\n */\ninterface ModelReferencePropertyInstance<\n TData extends DataDescription,\n TProperty extends Arrayable<DataValue>,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> extends PropertyInstance<TProperty> {\n /**\n * Gets the id (foreign key) of the referenced model.\n * @param instanceValues - The ModelReference. (key, data, or instance)\n */\n readonly getReferencedId: (\n instanceValues: ModelReferenceType<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ) => Maybe<PrimaryKeyType>\n\n /**\n * Gets reference's model\n */\n readonly getReferencedModel: () => ModelType<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n}\n\n/**\n * A property of a model that references another model instance.\n * This is a basic implementation of a \"foreign key\".\n * The value of this property can be either a key type (string|number), or a model instance, or the model data itself. It depends on the ModelInstanceFetcher.\n */\ntype ModelReferenceType<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = MaybePromise<\n | TData\n | ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n | ToObjectResult<TData>\n | PrimaryKeyType\n>\n\n/**\n * Common property validator choices.\n * @interface\n */\ntype CommonValidators = Readonly<{\n /**\n * Is this property required?\n */\n required?: boolean\n /**\n * Can the property only be an integer?\n */\n isInteger?: boolean\n /**\n * Can the property only be a number?\n */\n isNumber?: boolean\n /**\n * Can the property only be a string?\n */\n isString?: boolean\n /**\n * Is the property an array of values?\n */\n isArray?: boolean\n /**\n * Is the property only true or false?\n */\n isBoolean?: boolean\n}>\n\n/**\n * Standard configuration options for properties.\n * @interface\n */\ntype PropertyConfigOptions<TValue extends Arrayable<DataValue>> = Readonly<\n Partial<{\n /**\n * A type override to override the property type of a property.\n */\n typeOverride: PropertyType | string\n /**\n * A default value if one is never given.\n */\n defaultValue: TValue\n /**\n * Determines if this value needs to go through denormalization.\n */\n isDenormalized: boolean\n /**\n * The value of the property (if provided)\n */\n value: TValue\n /**\n * Possible limiting choices of what the property can be.\n */\n choices: readonly ChoiceTypes[]\n /**\n * A lazy loading method, which will only run when the value is actually retrieved.\n * IMPORTANT: Do not include promises as part of this because they are not thread safe.\n * @param value - The current value\n * @param modelData - The models current data\n */\n lazyLoadMethod: <TData extends DataDescription>(\n value: TValue,\n modelData: CreateParams<TData>\n ) => TValue\n /**\n * A thread safe (Atomic) version of lazyLoadMethod. Use this for all lazy loadings that requires Promises.\n * @param value - The current value\n * @param modelData - The models current data.\n */\n lazyLoadMethodAtomic: <TData extends DataDescription>(\n value: TValue,\n modelData: CreateParams<TData>\n ) => Promise<TValue>\n /**\n * An optional function that can select a \"part\" of the value to return.\n * @param instanceValue\n */\n valueSelector: (instanceValue: MaybePromise<TValue>) => TValue\n /**\n * Additional validators for the property.\n */\n validators: readonly PropertyValidatorComponent<any>[]\n /**\n * An optional zod schema for this property. If provided, it will be used as an\n * override for the generated schema.\n */\n zod?: ZodType<any>\n /**\n * A short human readable description of the property for documentation.\n */\n description?: string\n /**\n * The maximum length of the value. (Drives validation)\n */\n maxLength: number\n /**\n * The minimum length of the value. (Drives validation)\n */\n minLength: number\n /**\n * The maximum size of the value. (Drives validation)\n */\n maxValue: number\n /**\n * The minimum size of the value. (Drives validation)\n */\n minValue: number\n /**\n * If the value should be created automatically. Used in date creation.\n */\n autoNow: boolean\n /**\n * If you are using ModelReferences, this is required.\n * A fetcher used for getting model references.\n * This configuration item is used within the {@link AdvancedModelReferenceProperty} and any other property\n * that is lazy loading (atomically) models.\n */\n fetcher: ModelInstanceFetcher\n }>\n>\n\n/**\n * A function that has the ability to fetch an instance of a model.\n * This is the backbone that provides the \"ModelReference\" functionality.\n * This is useful downstream for building ORMs and other systems that require\n * hydrating \"foreign key\" models.\n * @param model - The model type that is being fetched.\n * @param primaryKey - The primary key of the desired data.\n */\ntype ModelInstanceFetcher<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = <TData extends DataDescription>(\n model: ModelType<TData, TModelExtensions, TModelInstanceExtensions>,\n primaryKey: PrimaryKeyType\n) =>\n | Promise<\n | TData\n | ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n | ToObjectResult<TData>\n >\n | Promise<null>\n | Promise<undefined>\n\n/**\n * The configurations for a property.\n */\ntype PropertyConfig<TValue extends Arrayable<DataValue>> =\n | (PropertyConfigOptions<TValue> & CommonValidators)\n | undefined\n\n/**\n * Depending on your system a primary key is either a string or a number.\n */\ntype PrimaryKeyType = string | number\n\n/**\n * A function that has the ability to build models. (The models themselves, not instances of models)\n * This is actually a \"factory of model factories\" but we're just calling it a ModelFactory.\n *\n * IMPORTANT:\n * If you want to override and create extended Models/ModelInstances this is the place to do it.\n * Create your own ModelFactory that adds additional functionality.\n * For expanding a Model, you can just add it to the overall object. that {@link ModelFactory} produces.\n *\n * For expanding a ModelInstance, you will want to wrap the \"create()\" function of {@link ModelType}\n *\n * @param modelDefinition - The minimal model definitions needed.\n * @param options - Additional model options.\n */\ntype ModelFactory<\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n TModelFactoryOptionsExtensions extends object = object,\n> = <TData extends DataDescription>(\n modelDefinition: MinimalModelDefinition<TData>,\n options?: ModelFactoryOptions<TData, TModelFactoryOptionsExtensions>\n) => ModelType<TData, TModelExtensions, TModelInstanceExtensions>\n\n/**\n * Input parameters to a model's create function.\n */\ntype CreateParams<\n TData extends DataDescription,\n IgnoreProperties extends string = '',\n> = Omit<TData | RemovePromises<TData>, IgnoreProperties>\n\n/**\n * Higher Level Methods associated with a model based API. CRUDS\n */\nenum ApiMethod {\n create = 'create',\n retrieve = 'retrieve',\n update = 'update',\n delete = 'delete',\n search = 'search',\n}\n\n/**\n * Basic REST information for a model.\n * @interface\n */\ntype RestInfo = {\n /**\n * The endpoint (not including the base domain). This format can include \":id\" to describe a specific instance id.\n * Example: /api/v2/whatever-i-want/model/:id\n * The following are the defaults by API method:\n * create: '/namespace/app',\n * retrieve: '/namespace/app/id',\n * update: '/namespace/app/id',\n * delete: '/namespace/app/id',\n * search: '/namespace/app/search',\n */\n endpoint: string\n /**\n * Security descriptions\n */\n security: openapi.OpenAPIV3_1.SecurityRequirementObject\n /**\n * The HTTP Method. The following are the defaults used:\n * create: post,\n * retrieve: get,\n * update: put,\n * delete: delete,\n * search: post,\n */\n method: openapi.OpenAPIV3_1.HttpMethods\n}\n\n/**\n * A minimum input for a RestInfo.\n */\ntype RestInfoMinimum = {\n security?: openapi.OpenAPIV3_1.SecurityRequirementObject\n} & Omit<RestInfo, 'security'>\n\n/**\n * Functional API documentation for a given model. This allows the automatic creation of tools and documentation such as OpenApi specs.\n * This uses the standard \"CRUDS\" api methods that you might see on any API involving a model.\n * Create, Retrieve, Update, Delete, Search\n * @interface\n */\ntype ApiInfo = {\n /**\n * If true, no api information should be published. This means, that no code-generation tool should produce\n * any api code/documentation as it relates to this model. If you want partial publishing, look at \"onlyPublish\"\n */\n noPublish: boolean\n /**\n * Similar to noPublish, but granular. This will only publish the methods shown. If noPublish is provided,\n * this will be empty. If onlyPublish is empty, and noPublish is false, then all methods will be published.\n */\n onlyPublish: readonly ApiMethod[]\n /**\n * A description of each Api method to its rest info.\n * If this is not manually overrided then defaults are used for each.\n */\n rest: Record<ApiMethod, RestInfo>\n /**\n * Create normally can support bulk inserts (more than one). If this property is true, create will only handle \"one\" model at a time.\n */\n createOnlyOne: boolean\n}\n\n/**\n * An {@link ApiInfo} that has only part of RestInfo completed. (useful for overriding defaults)\n * @interface\n */\ntype ApiInfoPartialRest = Readonly<{\n rest: Partial<Record<ApiMethod, RestInfoMinimum>>\n}> &\n Omit<ApiInfo, 'rest'>\n\n/**\n * Expressively defines metadata for a given model.\n * @interface\n */\ntype ModelDefinition<TData extends DataDescription> = Readonly<{\n /**\n * The primary name for the model and instances of the model. This should be a name for multiple of the model instances.\n */\n pluralName: string\n /**\n * The name that this model exists within, such as an app. This is used to combine with the pluralName to create\n * a unique name across a system that it is used in.\n *\n * Recommended:\n * If you are creating reusable libraries/packages for people, we recommend using the name of the package itself.\n * Example: \"@my-scoped-package/name\"\n *\n * If you are creating this model to be used locally, just use the \"app\" name that the model corresponds to.\n * Example: \"auth\"\n *\n * The namespace is also used in the auto-generation of {@link RestInfo.endpoint}. If you want to design the endpoint so that it looks/reads/flows better then consider overriding the endpoint yourself.\n */\n namespace: string\n /**\n * The properties that make up the model.\n */\n properties: PropertiesList<Required<TData>>\n /**\n * The name of the property that has the unique id for the model. Used to uniquely identify instances of this model vs other ones.\n */\n primaryKeyName: string\n /**\n * Validators of the overall model (rather than properties)\n */\n modelValidators: readonly ModelValidatorComponent<TData>[]\n /**\n * The name for a model/instance where there is one of them.\n */\n singularName: string\n /**\n * A text used for displaying the name of the model in a UI.\n */\n displayName: string\n /**\n * A helpful human-readable description that explains what the model is and what it is used for.\n */\n description: string\n /**\n * The raw api information provided in. When looking for a fleshed out version of this data\n * look at {@link ModelType.getApiInfo}\n */\n api?: Partial<ApiInfoPartialRest>\n /**\n * A zod schema for the model.\n */\n schema: ZodObject<DataDescription>\n}>\n\n/**\n * The most minimum information needed to create a model.\n * @interface\n */\ntype MinimalModelDefinition<TData extends DataDescription> = Partial<\n ModelDefinition<TData>\n> & {\n namespace: string\n pluralName: string\n properties: PropertiesList<Required<TData>>\n}\n\n/**\n * Represents a Model. A Model creates instances (ModelInstance) as well as describes generally about the data. (ModelDefinition).\n * @typeParam TData - The type of data\n * @typeParam TModelExtensions - Extensions on the model.\n * @typeParam TModelInstanceExtensions - Extensions on the instances produced by this model.\n * @interface\n */\ntype ModelType<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * This is a unique name combining namespace + pluralName. This can be used as a key to uniquely identify\n * this model across an entire system.\n * Example:\n * pluralName=MyModels\n * namespace=@my-package/namespace\n *\n * Return: '@my-package/namespace/MyModels'\n */\n getName: () => string\n /**\n * Gets the metadata that describes the model.\n */\n getModelDefinition: () => ModelDefinition<TData>\n /**\n * Gets the primary key of instance data. This helpful method shortcuts having to figure out the primaryKey's name\n * and then reaching inside the instance data to get the primary key.\n * @param instanceData The underlying instance data that has the primary key.\n */\n getPrimaryKey: (instanceData: TData | ToObjectResult<TData>) => PrimaryKeyType\n /**\n * Gets the Api Information on the model.\n *\n * This will take what is manually provided via the ModelDefinition and autopopulate everything that is possible\n * with default values, or values that make sense based on the ApiInformation provided.\n */\n getApiInfo: () => Required<ApiInfo>\n /**\n * Creates an instance of this model with the data that is provided.\n *\n * @typeParam IgnorePrimaryKey - One or more properties to ignore type restrictions on. This is extremely useful for primaryKeys that have not been created yet, or other generated properties (that are required instead of optional).\n * @param data - The data that makes up an instance of the model.\n * NOTE: A tradeoff was made between supporting the DataDescription vs a ToObjectReturn<DataDescription>. One or the other could be supported, but not both.\n * In order to support executing create() while passing in data that comes from \".toObj()\" we recommend using that case feature of toObj().\n */\n create: <IgnoreProperties extends string = ''>(\n data: CreateParams<TData, IgnoreProperties>\n ) => ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n}> &\n TModelExtensions\n\n/**\n * A function that can provide a model reference.\n */\ntype ModelReferenceFunctions = Record<string, () => Maybe<PrimaryKeyType>>\n\n/**\n * Records of Property name to Validator.\n */\ntype PropertyValidators<TData extends DataDescription> = Readonly<\n Record<string, PropertyValidator<TData>>\n>\n\n/**\n * An instance of a Model. This \"wrapper\" fully embodies the power of the framework, and provides the most enrichment of a single piece of a data possible.\n * @typeParam TData - The type of data\n * @typeParam TModelExtensions - Extensions on the overall model.\n * @typeParam TModelInstanceExtensions - Extensions on all instances of a model.\n * @interface\n */\ntype ModelInstance<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = Readonly<{\n /**\n * Gets the value of individual properties on the instance.\n * These are memoized.\n */\n get: PropertyGetters<TData>\n /**\n * Gets all model references that this instance may have as record of property name to function getter.\n *\n */\n getReferences: () => ModelReferenceFunctions\n /**\n * Gets a basic representation of the data.\n * This function is memoized.\n */\n toObj: ToObjectFunction<TData>\n /**\n * Gets the primary key of the instance (without having to know the primary key name).\n */\n getPrimaryKey: () => PrimaryKeyType\n /**\n * Gets the validators for this model instance.\n */\n getValidators: () => PropertyValidators<TData>\n /**\n * Runs validation against this instance.\n * This function is memoized.\n * @param options\n */\n validate: (options?: object) => Promise<ModelErrors<TData> | undefined>\n /**\n * Gets the model that backs this instance.\n */\n getModel: () => ModelType<TData, TModelExtensions, TModelInstanceExtensions>\n}> &\n TModelInstanceExtensions\n\n/**\n * A callback function for receiving when a new model has been created.\n * @param instance - A newly created model instance.\n */\ntype ModelCreatedCallback<\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = (\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n) => void\n\n/**\n * Options to pass into model generation.\n * @interface\n */\ntype ModelFactoryOptions<\n TData extends DataDescription,\n TModelFactoryOptionsExtensions extends object = object,\n> = Record<string, any> &\n Readonly<{\n /**\n * 1 or more (array) of callback functions for when models get created.\n */\n instanceCreatedCallback?: Arrayable<ModelCreatedCallback<TData>>\n }> &\n TModelFactoryOptionsExtensions\n\n/**\n * A function that can calculate a denormalized value. This is very useful for property values that have very complicated and often expensive calculations (but should be calculated once).\n * NOTE: The data that comes in (to be normalized) via the modelData, is the raw data passed into create(). If other functions must fire to create values, they will not be present. Example: Foreign keys.\n * @param modelData - The model's data as it was passed into the create() function.\n * @param modelInstance - The instance that the model corresponds with\n */\ntype CalculateDenormalization<\n TValue extends CanBeNullableType<DataValue>,\n TData extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n> = (\n modelData: CreateParams<TData>,\n modelInstance: ModelInstance<\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n) => MaybePromise<TValue | undefined>\n\n/**\n * Higher level value types that describe what the value of a property is.\n * These values can be used to generate expressive APIs as well as GUI elements.\n */\nenum PropertyType {\n UniqueId = 'UniqueId',\n Date = 'Date',\n Datetime = 'Datetime',\n Array = 'Array',\n ModelReference = 'ModelReference',\n Integer = 'Integer',\n Text = 'Text',\n BigText = 'BigText',\n Number = 'Number',\n Object = 'Object',\n Email = 'Email',\n Boolean = 'Boolean',\n}\n\n/**\n * The most primitive data types that can be used.\n */\nenum PrimitiveValueType {\n boolean = 'boolean',\n string = 'string',\n object = 'object',\n number = 'number',\n integer = 'integer',\n}\n\n/**\n * Dates can either be a Date or a string\n */\ntype DateValueType = Date | string\n\n/**\n * A useful type for setting the props object of a Model constructor.\n */\ntype ModelConstructorProps = Readonly<{\n Model: ModelFactory\n}>\n\n/**\n * A useful type for setting the props object of a Model constructor that has model references that need a fetcher\n */\ntype ModelWithReferencesConstructorProps = ModelConstructorProps &\n Readonly<{\n fetcher: ModelInstanceFetcher\n }>\n\nexport {\n PrimitiveValueType,\n PropertyType,\n MaybeFunction,\n Maybe,\n MaybePromise,\n Nullable,\n Arrayable,\n JsonAble,\n ToObjectFunction,\n ToObjectResult,\n ModelInstance,\n ModelType,\n PropertyValidatorComponent,\n PropertyValidatorComponentSync,\n PropertyValidatorComponentAsync,\n PropertyValidator,\n ModelValidatorComponent,\n PropertyInstance,\n PropertyConfig,\n DataValue,\n ValueGetter,\n ModelReferenceType,\n ModelDefinition,\n ModelFactoryOptions,\n ModelReferencePropertyInstance,\n PropertyGetters,\n PropertyValidators,\n PropertyValidatorComponentTypeAdvanced,\n DataDescription,\n ModelReferenceFunctions,\n ModelErrors,\n PrimaryKeyType,\n ModelFactory,\n ModelInstanceFetcher,\n CreateParams,\n ValidatorContext,\n ValuePropertyValidatorComponent,\n ValidationErrors,\n ComponentValidationErrorResponse,\n JsonifiedData,\n JsonObj,\n CalculateDenormalization,\n PropertiesList,\n MinimalModelDefinition,\n ChoiceTypes,\n PropertyConfigOptions,\n CommonValidators,\n DateValueType,\n ApiInfo,\n RestInfo,\n ApiMethod,\n RemovePromises,\n FlattenModelReferences,\n ApiInfoPartialRest,\n RestInfoMinimum,\n ModelConstructorProps,\n ModelWithReferencesConstructorProps,\n}\n", "import merge from 'lodash/merge.js'\nimport get from 'lodash/get.js'\nimport { v4 as uuidv4 } from 'uuid'\nimport { ZodType } from 'zod'\nimport {\n arrayType,\n createPropertyValidator,\n isType,\n isValidUuid,\n maxNumber,\n meetsRegex,\n minNumber,\n optionalValidator,\n referenceTypeMatch,\n} from './validation.js'\nimport { createHeadAndTail, memoizeAsync, memoizeSync } from './utils.js'\nimport {\n ModelReferenceType,\n ModelInstance,\n Maybe,\n PrimaryKeyType,\n ModelType,\n PropertyInstance,\n DataValue,\n PropertyConfig,\n ValueGetter,\n MaybeFunction,\n Arrayable,\n PropertyValidator,\n ModelReferencePropertyInstance,\n DataDescription,\n JsonAble,\n JsonifiedData,\n CalculateDenormalization,\n PropertyType,\n DateValueType,\n PrimitiveValueType,\n CanBeNullableType,\n} from './types.js'\nimport {\n getValueForModelInstance,\n getValueForReferencedModel,\n isReferencedProperty,\n getCommonTextValidators,\n getCommonNumberValidators,\n mergeValidators,\n isModelInstance,\n createZodForProperty,\n} from './lib.js'\n\nconst MAX_YEAR = 3000\nconst EMAIL_REGEX =\n /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/u\n\n/**\n * The base function that creates a fully loaded instance of a property. All standard issue properties use this function.\n * @param propertyType - The property's value type.\n * @param config - Configurations\n * @param additionalMetadata - Additional metadata that you want to add to a given property.\n * @typeParam TValue - The typescript value that the property produces.\n * @typeParam TData - The DataDescription that this property instance belongs to.\n * @typeParam TModelExtensions - Any additional model extensions\n * @typeParam TModelInstanceExtensions - Any additional model instance extensions\n */\nexport const Property = <\n TValue extends Arrayable<DataValue>,\n TData extends DataDescription = DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n>(\n propertyType: PropertyType | string,\n config: PropertyConfig<TValue> = {},\n additionalMetadata = {}\n): PropertyInstance<\n TValue,\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n> => {\n if (!propertyType && !config?.typeOverride) {\n throw new Error(`Property type must be provided.`)\n }\n if (config?.typeOverride) {\n propertyType = config.typeOverride\n }\n\n const getConstantValue = () =>\n (config?.value !== undefined ? config.value : undefined) as TValue\n\n const getDefaultValue = () =>\n (config?.defaultValue !== undefined\n ? config.defaultValue\n : undefined) as TValue\n\n const getChoices = () => config?.choices || []\n\n const lazyLoadMethod = config?.lazyLoadMethod || false\n\n const valueSelector = config?.valueSelector || (x => x)\n if (typeof valueSelector !== 'function') {\n throw new Error(`valueSelector must be a function`)\n }\n\n const createGetter = (\n instanceValue: TValue,\n modelData: TData,\n instance: ModelInstance<TData, TModelExtensions, TModelInstanceExtensions>\n ): ValueGetter<TValue, TData, TModelExtensions, TModelInstanceExtensions> => {\n const constantValue = getConstantValue()\n if (constantValue !== undefined) {\n return () => constantValue\n }\n const defaultValue = getDefaultValue()\n if (\n defaultValue !== undefined &&\n (instanceValue === null || instanceValue === undefined)\n ) {\n return () => defaultValue\n }\n\n const method = lazyLoadMethod\n ? lazyLoadMethod\n : config.lazyLoadMethodAtomic\n ? memoizeAsync(config.lazyLoadMethodAtomic)\n : typeof instanceValue === 'function'\n ? (instanceValue as () => TValue)\n : () => instanceValue\n const valueGetter: ValueGetter<\n TValue,\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n > = memoizeSync(() => {\n // @ts-ignore\n const result: TValue | Promise<TValue> = method(\n instanceValue,\n modelData,\n // @ts-ignore\n instance\n )\n return valueSelector(result)\n })\n return valueGetter\n }\n\n const getValidator = (\n valueGetter: ValueGetter<\n TValue,\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ) => {\n const validator = createPropertyValidator(valueGetter, config)\n const _propertyValidatorWrapper: PropertyValidator<\n TData\n // eslint-disable-next-line functional/prefer-tacit\n > = async (model, instanceData, propertyConfiguration) => {\n return validator(model, instanceData, propertyConfiguration)\n }\n return _propertyValidatorWrapper\n }\n\n // Build a zod schema for this property. If a zod schema is provided in the\n // config it will be used as an override.\n const getZod = (): ZodType<TValue> => {\n const provided = (config as any)?.zod\n if (provided) {\n return provided as ZodType<TValue>\n }\n\n return createZodForProperty(propertyType, config)()\n }\n\n const propertyInstance: PropertyInstance<\n TValue,\n TData,\n TModelExtensions,\n TModelInstanceExtensions\n > = {\n ...additionalMetadata,\n getConfig: () => config || {},\n getChoices,\n getDefaultValue,\n getConstantValue,\n getPropertyType: () => propertyType,\n createGetter,\n getZod,\n getValidator,\n }\n return propertyInstance\n}\n\n/**\n * Config object for a date property\n */\ntype DatePropertyConfig<T extends Arrayable<DataValue>> = {\n /**\n * A function that can format the date into a string.\n * Can use date-fns, moment, or any other function.\n * @param date - The date will be a date object\n * @param format - The format property passed in if provided.\n */\n formatFunction?: (date: Date, format?: string) => string\n /**\n * The format the date should be in. This is a framework agnostic format, and should be based on your format function.\n * NOTE: If a formatFunction is not provided, this is completely ignored. For dates YYYY-MM-DD is the default and for Datetimes it is ISOString()\n */\n format?: string\n} & PropertyConfig<T>\n\n/**\n * Determines if the value is a Date object.\n * @param value Any value\n */\nconst isDate = (value: any): value is Date => {\n if (value === null) {\n return false\n }\n return typeof value === 'object' && value.toISOString\n}\n\n/**\n * A Property for Dates. Supports both strings and Date objects.\n * This does NOT include time information.\n * @param config - A configuration that enables overriding of date formatting\n * @param additionalMetadata\n */\nexport const DateProperty = <\n T extends CanBeNullableType<DateValueType> = DateValueType,\n>(\n config: DatePropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Date,\n merge(\n {\n lazyLoadMethod: (value: Arrayable<DataValue>) => {\n if (isDate(value)) {\n if (config.formatFunction) {\n return config.formatFunction(value, config.format)\n }\n return value.toISOString().split('T')[0]\n }\n if (!value && config?.autoNow) {\n const date = new Date()\n if (config.formatFunction) {\n return config.formatFunction(date, config.format)\n }\n return date.toISOString().split('T')[0]\n }\n return value\n },\n },\n config\n ),\n additionalMetadata\n )\n\n/**\n * A property for Date AND Times. Supports both strings and Date Objects.\n * @param config - A configuration that enables overriding of date and time formatting\n * @param additionalMetadata\n */\nexport const DatetimeProperty = <\n T extends CanBeNullableType<DateValueType> = DateValueType,\n>(\n config: DatePropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Datetime,\n merge(\n {\n lazyLoadMethod: (value: Arrayable<DataValue>) => {\n if (isDate(value)) {\n if (config.formatFunction) {\n return config.formatFunction(value, config.format)\n }\n return value.toISOString()\n }\n if (!value && config?.autoNow) {\n const date = new Date()\n if (config.formatFunction) {\n return config.formatFunction(date, config.format)\n }\n return date.toISOString()\n }\n return value\n },\n },\n config\n ),\n additionalMetadata\n )\n\n/**\n * A property that has an array of sub values.\n * @param config\n * @param additionalMetadata\n */\nexport const ArrayProperty = <\n T extends CanBeNullableType<DataValue> = DataValue,\n>(\n config = {},\n additionalMetadata = {}\n) =>\n Property<readonly T[]>(\n PropertyType.Array,\n {\n defaultValue: [],\n ...config,\n isArray: true,\n },\n additionalMetadata\n )\n\n/**\n * A property that is an array, but only of a single value type. This is an {@link ArrayProperty} but with a validator for the type.\n * @param valueType - The type. (Only supports primitive data types, no objects)\n * @param config\n * @param additionalMetadata\n */\nexport const SingleTypeArrayProperty = <\n TValue extends Omit<PrimitiveValueType, 'object'>,\n>(\n valueType: TValue,\n config = {},\n additionalMetadata = {}\n) =>\n Property<readonly TValue[]>(\n PropertyType.Array,\n {\n defaultValue: [],\n ...config,\n isArray: true,\n validators: mergeValidators(\n config,\n // @ts-ignore\n arrayType(valueType)\n ),\n },\n additionalMetadata\n )\n\n/**\n * A property that has simple objects. These must be JSON compliant. These are validated.\n * @param config\n * @param additionalMetadata\n */\nexport const ObjectProperty = <\n TObject extends CanBeNullableType<\n Readonly<Record<string, JsonAble>>\n > = Readonly<Record<string, JsonAble>>,\n>(\n config = {},\n additionalMetadata = {}\n) =>\n Property<TObject>(\n PropertyType.Object,\n merge(config, {\n validators: mergeValidators(config, isType('object')),\n }),\n additionalMetadata\n )\n\n/**\n * A simple text property. If it's possible to put ALOT of text in this field consider using the {@link BigTextProperty}\n * @param config - Additional Configurations\n * @param additionalMetadata - Additional Metadata\n */\nexport const TextProperty = <T extends CanBeNullableType<string> = string>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Text,\n merge(config, {\n isString: true,\n // @ts-ignore\n validators: mergeValidators(config, ...getCommonTextValidators(config)),\n }),\n additionalMetadata\n )\n\n/**\n * A property for large blocks of strings.\n * @param config - Additional configurations\n * @param additionalMetadata - Additional metadata\n */\nexport const BigTextProperty = <T extends CanBeNullableType<string> = string>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.BigText,\n merge(config, {\n isString: true,\n validators: mergeValidators(\n config,\n ...getCommonTextValidators<T>(config)\n ),\n }),\n additionalMetadata\n )\n\n/**\n * A property that houses integers. No floats allowed.\n * @param config\n * @param additionalMetadata\n */\nexport const IntegerProperty = <T extends CanBeNullableType<number> = number>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Integer,\n merge(config, {\n isInteger: true,\n validators: mergeValidators(\n config,\n ...getCommonNumberValidators<T>(config)\n ),\n }),\n additionalMetadata\n )\n\n/**\n * An integer property that represents a year. NOTE: This is exclusively focused on a year in a modern context.\n * Validates from 0 to 3000\n * @param config\n * @param additionalMetadata\n */\nexport const YearProperty = <T extends CanBeNullableType<number> = number>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Integer,\n merge(config, {\n isInteger: true,\n validators: mergeValidators(\n config,\n ...getCommonNumberValidators(config),\n minNumber(0),\n maxNumber(MAX_YEAR)\n ),\n }),\n additionalMetadata\n )\n\n/**\n * A property for numbers. This could be integers or float values.\n * @param config\n * @param additionalMetadata\n */\nexport const NumberProperty = <T extends CanBeNullableType<number> = number>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Number,\n merge(config, {\n isNumber: true,\n validators: mergeValidators(config, ...getCommonNumberValidators(config)),\n }),\n additionalMetadata\n )\n\n/**\n * A property that has a fixed value that can never be changed. Can be useful for things like embedding the name of a model into JSONified objects.\n * @param valueType - The value type for this property.\n * @param value - The value to fix.\n * @param config\n * @param additionalMetadata\n */\nexport const ConstantValueProperty = <\n TDataValue extends CanBeNullableType<\n Arrayable<DataValue>\n > = Arrayable<DataValue>,\n>(\n valueType: PropertyType | string,\n value: TDataValue,\n config: PropertyConfig<TDataValue> = {},\n additionalMetadata = {}\n) =>\n Property<TDataValue>(\n valueType,\n merge(config, {\n value,\n }),\n additionalMetadata\n )\n\n/**\n * A property that encapsulates email addresses. Provides validation for making sure an email is valid.\n * @param config\n * @param additionalMetadata\n */\nexport const EmailProperty = <T extends CanBeNullableType<string> = string>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n TextProperty<T>(\n merge(config, {\n type: PropertyType.Email,\n validators: mergeValidators(config, meetsRegex(EMAIL_REGEX)),\n }),\n additionalMetadata\n )\n\n/**\n * A property that has a true or false value.\n * @param config\n * @param additionalMetadata\n */\nexport const BooleanProperty = <T extends CanBeNullableType<boolean> = boolean>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Boolean,\n merge(config, {\n isBoolean: true,\n }),\n additionalMetadata\n )\n\n/**\n * A property that is used for Primary Keys. If no value is provided a UUID is automatically created.\n * This property has required on it.\n * @param config - Additional configurations. NOTE: required is ALWAYS true.\n * @param additionalMetadata - Any additional metadata.\n */\nexport const PrimaryKeyUuidProperty = <\n T extends CanBeNullableType<string> = string,\n>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.UniqueId,\n merge(config, {\n required: true,\n isString: true,\n validators: mergeValidators(config, isValidUuid),\n lazyLoadMethod: (value: Arrayable<DataValue>) => {\n if (!value) {\n return uuidv4()\n }\n return value\n },\n }),\n additionalMetadata\n )\n\n/**\n * A property that has a uuid.\n * This property has required on it.\n * If you want it to automatically create a uuid add { autoNow: true } to the config.\n * @param config - Additional configurations.\n * @param additionalMetadata - Any additional metadata.\n */\nexport const UuidProperty = <T extends CanBeNullableType<string> = string>(\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.UniqueId,\n merge(config, {\n isString: true,\n validators: mergeValidators(\n config,\n config.required ? isValidUuid : optionalValidator(isValidUuid)\n ),\n lazyLoadMethod: (value: Arrayable<DataValue>) => {\n if (!value) {\n if (config.autoNow) {\n return uuidv4()\n }\n }\n return value\n },\n }),\n additionalMetadata\n )\n\n/**\n * A property that has a reference to another model instance. A \"Foreign Key\" if you will.\n * For full functionality a {@link ModelInstanceFetcher} must be provided in the config.\n * This property has complex functionalities.\n *\n * When a model calls \"instance.get.whatever()\" to get the value of a ModelReferenceProperty, it uses the model fetcher\n * to retrieve the model. (Could be saved elsewhere, or a database). When the promise is awaited, the value returned\n * is a ModelInstance object.\n *\n * However, when `toObj()` is called on that same instance, only the primary key value is returned. This is so that\n * when you call `toObj()` on the main instance, the \"foreign key\" gets filled in.\n *\n * This is useful for a save function with an ORM.\n * @param model - Either the model itself or a function that creates the model when needed (lazy).\n * @param config\n * @param additionalMetadata\n */\nexport const ModelReferenceProperty = <T extends DataDescription>(\n model: MaybeFunction<ModelType<T>>,\n config: PropertyConfig<ModelReferenceType<T>> = {},\n additionalMetadata = {}\n) => AdvancedModelReferenceProperty<T>(model, config, additionalMetadata)\n\n/**\n * The full implementation of a ModelReference, useful for typing certain extended functionalities.\n * For a full description see {@link ModelReferenceProperty}\n * @param model - A model or a function that returns the model.\n * @param config\n * @param additionalMetadata\n */\nexport const AdvancedModelReferenceProperty = <\n T extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n>(\n model: MaybeFunction<\n ModelType<T, TModelExtensions, TModelInstanceExtensions>\n >,\n config: PropertyConfig<\n ModelReferenceType<T, TModelExtensions, TModelInstanceExtensions>\n > = {},\n additionalMetadata = {}\n) => {\n if (!model) {\n throw new Error('Must include the referenced model')\n }\n\n const _getModel = () => {\n if (typeof model === 'function') {\n return model()\n }\n return model\n }\n\n // @ts-ignore\n const validator = referenceTypeMatch(model)\n const validators = mergeValidators(config, validator)\n\n const _getId =\n (\n instanceValues: ModelReferenceType<\n T,\n ModelType<T, TModelExtensions, TModelInstanceExtensions>\n >\n ) =>\n (): Maybe<PrimaryKeyType> => {\n if (!instanceValues) {\n return undefined\n }\n if (typeof instanceValues === 'number') {\n return instanceValues\n }\n if (typeof instanceValues === 'string') {\n return instanceValues\n }\n if (\n (\n instanceValues as ModelInstance<\n T,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ).getPrimaryKey\n ) {\n return (\n instanceValues as ModelInstance<\n T,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ).getPrimaryKey()\n }\n\n const theModel = _getModel()\n const primaryKey = theModel.getModelDefinition().primaryKeyName\n\n // @ts-ignore\n return (instanceValues as JsonifiedData<T>)[primaryKey] as PrimaryKeyType\n }\n\n const lazyLoadMethodAtomic = async (\n instanceValues: ModelReferenceType<\n T,\n TModelExtensions,\n TModelInstanceExtensions\n >\n ) => {\n const valueIsModelInstance = isModelInstance(instanceValues)\n\n const _getInstanceReturn = (objToUse: ModelReferenceType<T>) => {\n // We need to determine if the object we just got is an actual model instance to determine if we need to make one.\n const objIsModelInstance = isModelInstance(objToUse)\n const instance = objIsModelInstance\n ? objToUse\n : // @ts-ignore\n _getModel().create(objToUse as JsonifiedData<T>)\n // We are replacing the toObj function, because the reference type in the end should be the primary key when serialized.\n return merge({}, instance, {\n toObj: memoizeAsync(_getId(instanceValues)),\n })\n }\n\n // @ts-ignore\n if (valueIsModelInstance) {\n return _getInstanceReturn(instanceValues)\n }\n\n // TypedJson?\n const theModel = _getModel()\n const primaryKey = theModel.getModelDefinition().primaryKeyName\n if (get(instanceValues, primaryKey)) {\n return _getInstanceReturn(instanceValues)\n }\n\n if (config?.fetcher) {\n const id = await _getId(instanceValues)()\n const model = _getModel()\n if (id !== null && id !== undefined) {\n const obj = await config.fetcher(model, id)\n return _getInstanceReturn(obj as ModelReferenceType<T>)\n }\n return null\n }\n return _getId(instanceValues)()\n }\n\n const p: ModelReferencePropertyInstance<\n T,\n ModelReferenceType<T, TModelExtensions, TModelInstanceExtensions>,\n TModelExtensions,\n TModelInstanceExtensions\n > = merge(\n Property<ModelReferenceType<T, TModelExtensions, TModelInstanceExtensions>>(\n PropertyType.ModelReference,\n merge({}, config, {\n validators,\n lazyLoadMethodAtomic,\n }),\n additionalMetadata\n ),\n {\n getReferencedId: (\n instanceValues: ModelReferenceType<\n T,\n ModelType<T, TModelExtensions, TModelInstanceExtensions>\n >\n ) => _getId(instanceValues)(),\n getReferencedModel: _getModel,\n }\n )\n return p\n}\n\n/**\n * A property for Denormalizing. This represents a complex value that has been simplified for ease of use.\n * One common use is for creating \"Display Values\" in a GUI. This process can be extremely expensive, such as having to\n * get selected values 2 or 3 Foreign Keys deep.\n *\n * This property allows passing in a calculate function that will only be executed once, and only if there is no value, and then only when asked.\n *\n * To recalculate the value, you need to run the calculate function on the property itself, passing in new model data.\n * @param propertyType - A property type.\n * @param calculate - A function for calculating the denormalized value.\n * @param config - A Config\n * @param additionalMetadata _ Any additional metadata.\n */\nexport const DenormalizedProperty = <\n TValue extends CanBeNullableType<DataValue>,\n T extends DataDescription,\n>(\n propertyType: string,\n calculate: CalculateDenormalization<TValue, T>,\n config: PropertyConfig<TValue> = {},\n additionalMetadata = {}\n) => {\n const property = Property<TValue>(\n propertyType,\n merge(config, {\n isDenormalized: true,\n lazyLoadMethodAtomic: async (\n value: string | undefined,\n modelData: T,\n modelInstance: ModelInstance<T, any>\n ) => {\n if (value !== undefined) {\n return value\n }\n return calculate(modelData, modelInstance)\n },\n }),\n additionalMetadata\n )\n return merge(property, {\n calculate,\n })\n}\n\n/**\n * A Denormalized Property that is for text.\n * @param calculate - A function that can get a string\n * @param config - Any configs\n * @param additionalMetadata - Optional Metadata\n */\nexport const DenormalizedTextProperty = <\n T extends DataDescription,\n TData extends CanBeNullableType<string> = string,\n>(\n calculate: CalculateDenormalization<TData, T>,\n config: PropertyConfig<TData> = {},\n additionalMetadata = {}\n) =>\n DenormalizedProperty<TData, T>(\n PropertyType.Text,\n calculate,\n merge(config, {\n isString: true,\n validators: mergeValidators<TData>(\n config,\n ...getCommonTextValidators<TData>(config)\n ),\n }),\n additionalMetadata\n )\n\n/**\n * A Denormalized Property that is for numbers.\n * @param calculate - A function that can get a string\n * @param config - Any configs\n * @param additionalMetadata - Optional Metadata\n */\nexport const DenormalizedNumberProperty = <\n T extends DataDescription,\n TData extends CanBeNullableType<number> = number,\n>(\n calculate: CalculateDenormalization<TData, T>,\n config: PropertyConfig<TData> = {},\n additionalMetadata = {}\n) =>\n DenormalizedProperty<TData, T>(\n PropertyType.Number,\n calculate,\n merge(config, {\n isNumber: true,\n validators: mergeValidators(config, ...getCommonNumberValidators(config)),\n }),\n additionalMetadata\n )\n\n/**\n * A Denormalized Property that is for integers.\n * @param calculate - A function that can get a string\n * @param config - Any configs\n * @param additionalMetadata - Optional Metadata\n */\nexport const DenormalizedIntegerProperty = <\n T extends DataDescription,\n TData extends CanBeNullableType<number> = number,\n>(\n calculate: CalculateDenormalization<TData, T>,\n config: PropertyConfig<TData> = {},\n additionalMetadata = {}\n) =>\n DenormalizedProperty<TData, T>(\n PropertyType.Integer,\n calculate,\n merge(config, {\n isInteger: true,\n validators: mergeValidators(config, ...getCommonNumberValidators(config)),\n }),\n additionalMetadata\n )\n\n/**\n * An id that is naturally formed by other properties within a model.\n * Instead of having a \"globally unique\" id the model is unique because the composition of values of properties.\n * @param propertyKeys A list (in order) of property keys needed to make the id. These keys can take nested paths\n * if a property is an object, array, or even a model instance object. Example: 'nested.path.here'.\n * Note: If ANY of the properties are undefined, the key becomes undefined. This is to ensure key structure integrity.\n * Additionally, if the property key points to a referenced model 1 of 2 things will happen.\n * 1. If the key is not nested (Example: model.myReferenceObj) then the key to the referenced model will be used.\n * 2. If the key IS nested (Example: model.myReferenceObj.name) then the instance will be retrieved and then the\n * property for that model instance is used.\n * @param joiner A string that will be passed to \".join()\" for creating a single string.\n * @param config\n * @param additionalMetadata\n */\nexport const NaturalIdProperty = <T extends CanBeNullableType<string> = string>(\n propertyKeys: readonly string[],\n joiner: string,\n config: PropertyConfig<T> = {},\n additionalMetadata = {}\n) =>\n Property<T>(\n PropertyType.Text,\n merge(config, {\n isString: true,\n validators: mergeValidators(config, ...getCommonTextValidators(config)),\n lazyLoadMethodAtomic: async (\n value: string | undefined,\n model: DataDescription,\n modelInstance: ModelInstance<any>\n ) => {\n const data = await propertyKeys.reduce(async (accP, key) => {\n const acc = await accP\n const [head] = createHeadAndTail(key.split('.'), '.')\n const value = await (isReferencedProperty(modelInstance, head)\n ? getValueForReferencedModel(modelInstance, key)\n : getValueForModelInstance(modelInstance, key))\n return acc.concat(value)\n }, Promise.resolve([]))\n // If any of these values are not set, we do not want to have a value at all.\n if (data.some(value => value === undefined)) {\n return undefined\n }\n return data.join(joiner)\n },\n }),\n additionalMetadata\n )\n", "import validate from './validate.js';\nconst byteToHex = [];\nfor (let i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).slice(1));\n}\nexport function unsafeStringify(arr, offset = 0) {\n return (byteToHex[arr[offset + 0]] +\n byteToHex[arr[offset + 1]] +\n byteToHex[arr[offset + 2]] +\n byteToHex[arr[offset + 3]] +\n '-' +\n byteToHex[arr[offset + 4]] +\n byteToHex[arr[offset + 5]] +\n '-' +\n byteToHex[arr[offset + 6]] +\n byteToHex[arr[offset + 7]] +\n '-' +\n byteToHex[arr[offset + 8]] +\n byteToHex[arr[offset + 9]] +\n '-' +\n byteToHex[arr[offset + 10]] +\n byteToHex[arr[offset + 11]] +\n byteToHex[arr[offset + 12]] +\n byteToHex[arr[offset + 13]] +\n byteToHex[arr[offset + 14]] +\n byteToHex[arr[offset + 15]]).toLowerCase();\n}\nfunction stringify(arr, offset = 0) {\n const uuid = unsafeStringify(arr, offset);\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n return uuid;\n}\nexport default stringify;\n", "const rnds8 = new Uint8Array(16);\nexport default function rng() {\n return crypto.getRandomValues(rnds8);\n}\n", "import rng from './rng.js';\nimport { unsafeStringify } from './stringify.js';\nfunction v4(options, buf, offset) {\n if (!buf && !options && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n return _v4(options, buf, offset);\n}\nfunction _v4(options, buf, offset) {\n options = options || {};\n const rnds = options.random ?? options.rng?.() ?? rng();\n if (rnds.length < 16) {\n throw new Error('Random bytes length must be >= 16');\n }\n rnds[6] = (rnds[6] & 0x0f) | 0x40;\n rnds[8] = (rnds[8] & 0x3f) | 0x80;\n if (buf) {\n offset = offset || 0;\n if (offset < 0 || offset + 16 > buf.length) {\n throw new RangeError(`UUID byte range ${offset}:${offset + 15} is out of buffer bounds`);\n }\n for (let i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n return buf;\n }\n return unsafeStringify(rnds);\n}\nexport default v4;\n", "import isEmpty from 'lodash/isEmpty.js'\nimport merge from 'lodash/merge.js'\nimport flatMap from 'lodash/flatMap.js'\nimport get from 'lodash/get.js'\nimport {\n DataDescription,\n ModelInstance,\n ModelType,\n ModelValidatorComponent,\n PropertyValidatorComponent,\n PropertyValidatorComponentSync,\n PropertyValidator,\n PropertyConfig,\n PropertyValidators,\n ValueGetter,\n Arrayable,\n DataValue,\n ModelErrors,\n ValidatorContext,\n ValuePropertyValidatorComponent,\n ValidationErrors,\n MaybeFunction,\n PropertyValidatorComponentTypeAdvanced,\n PrimitiveValueType,\n ToObjectResult,\n} from './types.js'\nimport { flowFindFirst } from './utils.js'\n\nconst multiValidator = <T extends Arrayable<DataValue>>(\n validators: ValuePropertyValidatorComponent<T>[]\n): ValuePropertyValidatorComponent<T> => {\n const flow = flowFindFirst<T, string>(\n validators as ((t: T) => undefined | string)[]\n )\n return flow as ValuePropertyValidatorComponent<T>\n}\n\nconst filterEmpty = <T>(\n array: readonly (T | undefined | null)[]\n): readonly T[] => {\n return array.filter(x => x) as readonly T[]\n}\n\nconst _trueOrError =\n <T extends Arrayable<DataValue>>(\n method: (t: T) => boolean,\n error: string\n ): ValuePropertyValidatorComponent<T> =>\n (value: T) => {\n if (method(value) === false) {\n return error\n }\n return undefined\n }\n\nconst _typeOrError =\n <T extends Arrayable<DataValue>>(\n type: string,\n errorMessage: string\n ): ValuePropertyValidatorComponent<T> =>\n (value: T) => {\n if (typeof value !== type) {\n return errorMessage\n }\n return undefined\n }\n\nconst isType =\n <T extends Arrayable<DataValue>>(\n type: string\n ): ValuePropertyValidatorComponent<T> =>\n (value: T) => {\n // @ts-ignore\n return _typeOrError(type, `Must be a ${type}`)(value)\n }\nconst isNumber = isType<number>('number')\nconst isInteger = _trueOrError<number>(Number.isInteger, 'Must be an integer')\n\nconst isObject = multiValidator<object>([\n isType<object>('object'),\n x => (Array.isArray(x) ? 'Must be an object, but got an array' : undefined),\n])\nconst isBoolean = isType<boolean>('boolean')\nconst isString = isType<string>('string')\nconst isArray = _trueOrError<readonly DataValue[]>(\n (v: any) => Array.isArray(v),\n 'Value is not an array'\n)\n\nconst PRIMITIVE_TO_SPECIAL_TYPE_VALIDATOR: Record<\n PrimitiveValueType,\n ValuePropertyValidatorComponent<any>\n> = {\n [PrimitiveValueType.boolean]: isBoolean,\n [PrimitiveValueType.string]: isString,\n [PrimitiveValueType.integer]: isInteger,\n [PrimitiveValueType.number]: isNumber,\n [PrimitiveValueType.object]: isObject,\n}\n\nconst arrayType =\n <TValue extends DataValue>(\n type: PrimitiveValueType\n ): ValuePropertyValidatorComponent<readonly TValue[]> =>\n (value: readonly TValue[]) => {\n const arrayError = isArray(value)\n if (arrayError) {\n return arrayError\n }\n const validator = PRIMITIVE_TO_SPECIAL_TYPE_VALIDATOR[type] || isType(type)\n return (value as readonly []).reduce(\n (acc: string | undefined, v: DataValue) => {\n if (acc) {\n return acc\n }\n\n return validator(v)\n },\n undefined\n )\n }\n\nconst meetsRegex =\n <TValue extends DataValue>(\n regex: string | RegExp,\n flags?: string,\n errorMessage = 'Format was invalid'\n ): ValuePropertyValidatorComponent<TValue> =>\n (value: TValue) => {\n const reg = new RegExp(regex, flags)\n // @ts-ignore\n return _trueOrError((v: string) => reg.test(v), errorMessage)(value)\n }\n\nconst choices =\n <T extends DataValue>(\n choiceArray: readonly T[]\n ): ValuePropertyValidatorComponent<T> =>\n (value: T | readonly T[]) => {\n if (Array.isArray(value)) {\n const bad = value.find(v => !choiceArray.includes(v))\n if (bad) {\n return `${bad} is not a valid choice`\n }\n } else {\n if (!choiceArray.includes(value as T)) {\n return `${value} is not a valid choice`\n }\n }\n return undefined\n }\n\nconst isDate: ValuePropertyValidatorComponent<Date> = (value: Date) => {\n if (!value) {\n return 'Date value is empty'\n }\n if (!value.toISOString) {\n return 'Value is not a date'\n }\n return undefined\n}\n\nconst isRequired: ValuePropertyValidatorComponent<any> = (value?: any) => {\n if (value === true || value === false) {\n return undefined\n }\n // @ts-ignore\n if (isNumber(value) === undefined) {\n return undefined\n }\n const empty = isEmpty(value)\n if (empty) {\n // @ts-ignore\n if (isDate(value)) {\n return 'A value is required'\n }\n }\n return undefined\n}\n\nconst maxNumber =\n (max: number): ValuePropertyValidatorComponent<number> =>\n (value: number) => {\n // @ts-ignore\n const numberError = isNumber(value)\n if (numberError) {\n return numberError\n }\n if (value && value > max) {\n return `The maximum is ${max}`\n }\n return undefined\n }\n\nconst minNumber =\n (min: number): ValuePropertyValidatorComponent<number> =>\n (value: number) => {\n // @ts-ignore\n const numberError = isNumber(value)\n if (numberError) {\n return numberError\n }\n if (value && value < min) {\n return `The minimum is ${min}`\n }\n return undefined\n }\n\nconst maxTextLength =\n (max: number): ValuePropertyValidatorComponent<string> =>\n (value: string) => {\n // @ts-ignore\n const stringError = isString(value)\n if (stringError) {\n return stringError\n }\n if (value && value.length > max) {\n return `The maximum length is ${max}`\n }\n return undefined\n }\n\nconst minTextLength =\n (min: number): ValuePropertyValidatorComponent<string> =>\n (value: string) => {\n // @ts-ignore\n const stringError = isString(value)\n if (stringError) {\n return stringError\n }\n if (value && value.length < min) {\n return `The minimum length is ${min}`\n }\n return undefined\n }\n\nconst aggregateValidator = <T extends DataDescription>(\n value: any,\n methodOrMethods:\n | PropertyValidatorComponent<T>\n | readonly PropertyValidatorComponent<T>[]\n): PropertyValidator<T> => {\n const toDo = Array.isArray(methodOrMethods)\n ? methodOrMethods\n : [methodOrMethods]\n\n const _aggregativeValidator: PropertyValidator<T> = async (\n model: ModelType<T>,\n instanceData: ToObjectResult<T>,\n propertyConfiguration: ValidatorContext\n ) => {\n const values = await Promise.all(\n toDo.map(method => {\n return method(value, model, instanceData, propertyConfiguration)\n })\n )\n return filterEmpty(values)\n }\n return _aggregativeValidator\n}\n\nconst emptyValidator = () => undefined\n\nconst _boolChoice =\n <T extends DataDescription>(\n method: (configValue: any) => PropertyValidatorComponentSync<T>\n ) =>\n (configValue: any) => {\n const func = method(configValue)\n const validatorWrapper: PropertyValidatorComponentSync<T> = func\n return validatorWrapper\n }\n\ntype MethodConfigDict<T extends DataDescription> = Readonly<{\n [s: string]: (config: any) => PropertyValidatorComponentSync<T>\n}>\n\nconst simpleFuncWrap =\n <T extends DataDescription>(validator: PropertyValidatorComponentSync<T>) =>\n () => {\n return validator\n }\n\nconst includeOrDont =\n <T extends DataDescription>(\n method: () => PropertyValidatorComponentSync<T>\n ) =>\n (configValue: any) => {\n if (configValue === false) {\n return emptyValidator\n }\n const func = method()\n const validatorWrapper: PropertyValidatorComponentSync<T> = func\n return validatorWrapper\n }\n\nconst CONFIG_TO_VALIDATE_METHOD = <\n T extends DataDescription,\n>(): MethodConfigDict<T> => ({\n required: includeOrDont(simpleFuncWrap(isRequired)),\n isInteger: _boolChoice<T>(simpleFuncWrap(isInteger)),\n isNumber: _boolChoice<T>(simpleFuncWrap(isNumber)),\n isString: _boolChoice<T>(simpleFuncWrap(isString)),\n isArray: _boolChoice<T>(simpleFuncWrap(isArray)),\n isBoolean: _boolChoice<T>(simpleFuncWrap(isBoolean)),\n choices: _boolChoice<T>(choices),\n})\n\nconst createPropertyValidator = <\n TValue extends Arrayable<DataValue>,\n T extends DataDescription = DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n>(\n valueGetter: ValueGetter<\n TValue,\n T,\n TModelExtensions,\n TModelInstanceExtensions\n >,\n config: PropertyConfig<TValue>\n): PropertyValidator<T> => {\n const _propertyValidator = async (\n model: ModelType<T>,\n instanceData: ToObjectResult<T>,\n propertyConfiguration: ValidatorContext\n ): Promise<ValidationErrors> => {\n return Promise.resolve().then(async () => {\n const configToValidateMethod = CONFIG_TO_VALIDATE_METHOD<T>()\n if (!config) {\n config = {}\n }\n const validators: readonly PropertyValidatorComponent<T>[] = [\n ...Object.entries(config).map(([key, value]) => {\n const method = configToValidateMethod[key]\n if (method) {\n return method(value)\n }\n return emptyValidator\n }),\n ...(config.validators ? config.validators : []),\n ].filter(x => x) as PropertyValidatorComponent<T>[]\n const value = await valueGetter()\n const isRequiredValue = config.required\n ? true\n : validators.includes(isRequired)\n if (!value && !isRequiredValue) {\n return []\n }\n const validator = aggregateValidator(value, validators)\n const errors = await validator(model, instanceData, propertyConfiguration)\n return [...new Set(flatMap(errors))]\n })\n }\n return _propertyValidator\n}\n\nconst createModelValidator = <\n T extends DataDescription,\n TModelExtensions extends object = object,\n TModelInstanceExtensions extends object = object,\n>(\n validators: PropertyValidators<T>,\n modelValidators?: readonly ModelValidatorComponent<\n T,\n TModelExtensions,\n TModelInstanceExtensions\n >[]\n) => {\n const _modelValidator = async (\n instance: ModelInstance<T, TModelExtensions, TModelInstanceExtensions>,\n propertyConfiguration: ValidatorContext\n ): Promise<ModelErrors<T> | undefined> => {\n return Promise.resolve().then(async () => {\n if (!instance) {\n throw new Error(`Instance cannot be empty`)\n }\n const model = instance.getModel()\n const keysAndFunctions = Object.entries(validators)\n const instanceData = await instance.toObj<T>()\n const propertyValidationErrors = await Promise.all(\n keysAndFunctions.map(async ([key, validator]) => {\n return [\n key,\n await validator(model, instanceData, propertyConfiguration),\n ]\n })\n )\n const modelValidationErrors = (\n await Promise.all(\n modelValidators\n ? modelValidators.map(validator => {\n return validator(model, instanceData, propertyConfiguration)\n })\n : []\n )\n ).filter(x => x) as readonly string[]\n const propertyErrors = propertyValidationErrors\n .filter(([, errors]) => Boolean(errors) && errors.length > 0)\n .reduce((acc, [key, errors]) => {\n return merge(acc, { [String(key)]: errors })\n }, {} as ModelErrors<T>)\n const final =\n modelValidationErrors.length > 0\n ? merge(propertyErrors, { overall: modelValidationErrors })\n : propertyErrors\n if (isEmpty(final)) {\n return undefined\n }\n return final\n })\n }\n return _modelValidator\n}\n\nconst isValid = <T extends DataDescription>(errors: ModelErrors<T>) => {\n return Object.keys(errors).length < 1\n}\n\nconst referenceTypeMatch = (\n referencedModel: MaybeFunction<ModelType<any>>\n): PropertyValidatorComponentTypeAdvanced<\n ModelInstance<any, any, any>,\n any\n> => {\n return (value?: ModelInstance<any, any, any>) => {\n const theType = typeof value\n switch (theType) {\n case 'string':\n case 'number':\n case 'undefined':\n return undefined\n default:\n break\n }\n if (value === null) {\n return undefined\n }\n // This needs to stay here, as it delays the creation long enough for\n // self referencing types.\n const model =\n typeof referencedModel === 'function'\n ? referencedModel()\n : referencedModel\n // Assumption: By the time this is received, value === a model instance.\n const eModel = model.getName()\n const aModel = value.getModel().getName()\n if (eModel !== aModel) {\n return `Model should be ${eModel} instead, received ${aModel}`\n }\n return undefined\n }\n}\n\n/**\n * A validator that can validate an entire object.\n *\n * @param required - If this object is required.\n * @param keyToValidators - An object that has a dotted path key to the property to validate, and one or more validators for it.\n */\nconst objectValidator = <T extends object>({\n required,\n keyToValidators,\n}: {\n required?: boolean\n keyToValidators: Record<\n string,\n | ValuePropertyValidatorComponent<any>\n | ValuePropertyValidatorComponent<any>[]\n >\n}): ValuePropertyValidatorComponent<T> => {\n return (obj: T) => {\n if (!obj) {\n if (required) {\n return 'Must include a value'\n }\n return undefined\n }\n const isNotObj = isObject(obj)\n if (isNotObj) {\n return isNotObj\n }\n return (\n Object.entries(keyToValidators)\n .reduce((acc, [key, validator]) => {\n const theValidator = Array.isArray(validator)\n ? multiValidator(validator)\n : (validator as ValuePropertyValidatorComponent<any>)\n const value = get(obj, key)\n const error = theValidator(value)\n if (error) {\n return acc.concat(`${key}: ${error}`)\n }\n return acc\n }, [] as string[])\n .join(', ') || undefined\n )\n }\n}\n\nconst optionalValidator = <T extends Arrayable<DataValue>>(\n validator: ValuePropertyValidatorComponent<T>\n): ValuePropertyValidatorComponent<T> => {\n return (v: T | undefined): string | undefined => {\n if (v === undefined || v === null) {\n return undefined\n }\n return validator(v)\n }\n}\n\nconst UUID_VALIDATOR =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/iu\n\nconst isValidUuid: ValuePropertyValidatorComponent<string> = (uuid: string) => {\n const stringError = isString(uuid)\n if (stringError) {\n return stringError\n }\n return meetsRegex<string>(UUID_VALIDATOR, 'g', 'Invalid UUID format')(uuid)\n}\n\nexport {\n isNumber,\n isBoolean,\n isString,\n isInteger,\n isType,\n isDate,\n isArray,\n isRequired,\n maxNumber,\n minNumber,\n choices,\n maxTextLength,\n minTextLength,\n meetsRegex,\n aggregateValidator,\n emptyValidator,\n createPropertyValidator,\n createModelValidator,\n arrayType,\n isValid,\n referenceTypeMatch,\n multiValidator,\n isObject,\n objectValidator,\n optionalValidator,\n isValidUuid,\n}\n", "import AsyncLock from 'async-lock'\nimport { v4 as uuidv4 } from 'uuid'\n// @ts-ignore\nimport getRandomValuesFunc from 'get-random-values'\n\nconst getRandomValues = (): Uint8Array => {\n const array = new Uint8Array(1)\n if (typeof window !== 'undefined') {\n if (window.crypto) {\n return window.crypto.getRandomValues(array)\n }\n // @ts-ignore\n if (window.msCrypto) {\n // @ts-ignore\n return window.msCrypto.getRandomValues(array)\n }\n }\n\n return getRandomValuesFunc(array)\n}\n\nconst toTitleCase = (string: string) => {\n return `${string.slice(0, 1).toUpperCase()}${string.slice(1)}`\n}\n\nconst loweredTitleCase = (string: string) => {\n return `${string.slice(0, 1).toLowerCase()}${string.slice(1)}`\n}\n\nconst isPromise = <T>(something: any): something is Promise<T> => {\n if (something?.then) {\n return true\n }\n return false\n}\n\nenum PluralEndings {\n ves = 'fe',\n ies = 'y',\n i = 'us',\n zes = 'ze',\n ses = 's',\n es = 'e',\n s = '',\n}\nconst _singularizingRe = new RegExp(\n `(${Object.keys(PluralEndings).join('|')})$`,\n 'u'\n)\n\nconst singularize = (word: string) => {\n // @ts-ignore\n return word.replace(_singularizingRe, r => PluralEndings[r])\n}\n\nconst createHeadAndTail = (values: readonly string[], joiner: string) => {\n const head = values[0]\n const tail = values.slice(1).join(joiner)\n return [head, tail]\n}\n\nconst flowFindFirst =\n <T, TResult>(funcs: ((t: T) => undefined | TResult)[]) =>\n (input: T) => {\n return funcs.reduce((acc: undefined | TResult, func) => {\n if (acc) {\n return acc\n }\n return func(input)\n }, undefined) as string | TResult\n }\n\nconst memoizeSync = <T, A extends Array<any>>(method: (...args: A) => T) => {\n /* eslint-disable functional/no-let */\n let value: any = undefined\n let called = false\n return (...args: A): T => {\n if (!called) {\n called = true\n value = method(...args)\n }\n\n return value\n }\n /* eslint-enable functional/no-let */\n}\n\nconst memoizeAsync = <T, A extends Array<any>>(method: (...args: A) => T) => {\n const key = uuidv4()\n const lock = new AsyncLock()\n /* eslint-disable functional/no-let */\n let value: any = undefined\n let called = false\n return async (...args: A): Promise<T> => {\n return lock.acquire(key, async () => {\n if (!called) {\n called = true\n value = await method(...args)\n }\n\n return value\n })\n }\n /* eslint-enable functional/no-let */\n}\n\nconst createUuid = uuidv4\n\nexport {\n getRandomValues,\n loweredTitleCase,\n toTitleCase,\n isPromise,\n createHeadAndTail,\n singularize,\n flowFindFirst,\n memoizeSync,\n memoizeAsync,\n createUuid,\n}\n", "import { OpenAPIV3 } from 'openapi-types'\nimport kebabCase from 'lodash/kebabCase.js'\nimport flow from 'lodash/flow.js'\nimport merge from 'lodash/merge.js'\nimport get from 'lodash/get.js'\nimport { z, ZodType } from 'zod'\nimport {\n ApiInfo,\n ApiInfoPartialRest,\n ApiMethod,\n Arrayable,\n DataDescription,\n DataValue,\n ModelInstance,\n PrimaryKeyType,\n PropertyConfig,\n CanBeNullableType,\n PropertyValidatorComponent,\n PropertyValidatorComponentTypeAdvanced,\n RestInfo,\n RestInfoMinimum,\n} from './types.js'\nimport { createHeadAndTail } from './utils.js'\nimport {\n emptyValidator,\n maxNumber,\n maxTextLength,\n minNumber,\n minTextLength,\n} from './validation.js'\nimport HttpMethods = OpenAPIV3.HttpMethods\n\nconst NULL_ENDPOINT = 'NULL'\nconst NULL_METHOD = HttpMethods.HEAD\nconst ID_KEY = ':id'\n\nconst getValueForReferencedModel = async (\n modelInstance: ModelInstance<any>,\n path: string\n): Promise<PrimaryKeyType | any> => {\n const [head, tail] = createHeadAndTail(path.split('.'), '.')\n // If there are no nested keys, just return the reference id.\n if (!tail) {\n return modelInstance.getReferences()[head]()\n }\n const modelReference = await modelInstance.get[head]()\n if (modelReference.toObj) {\n const [nestedHead, nestedTail] = createHeadAndTail(tail.split('.'), '.')\n const value = await modelReference.get[nestedHead]()\n if (nestedTail) {\n return get(value, nestedTail)\n }\n return value\n }\n return get(modelReference, tail)\n}\n\nconst getValueForModelInstance = async (\n modelInstance: ModelInstance<any>,\n path: string\n): Promise<PrimaryKeyType | any> => {\n const [head, tail] = createHeadAndTail(path.split('.'), '.')\n const value = await modelInstance.get[head]()\n return tail ? get(value, tail) : value\n}\n\nconst isReferencedProperty = (\n modelInstance: ModelInstance<any>,\n key: string\n) => {\n return modelInstance.getReferences()[key]\n}\n\nconst getCommonTextValidators = <T extends CanBeNullableType<string> = string>(\n config: PropertyConfig<T>\n): readonly PropertyValidatorComponent<any>[] => {\n return [\n getValidatorFromConfigElseEmpty(config?.maxLength, maxTextLength),\n getValidatorFromConfigElseEmpty(config?.minLength, minTextLength),\n ]\n}\n\nconst getValidatorFromConfigElseEmpty = <\n T extends DataDescription,\n TValue extends DataValue,\n>(\n input: TValue | undefined,\n\n validatorGetter: (t: TValue) => PropertyValidatorComponent<T>\n): PropertyValidatorComponent<T> => {\n if (input !== undefined) {\n const validator = validatorGetter(input)\n return validator\n }\n return emptyValidator\n}\n\nconst getCommonNumberValidators = <\n T extends CanBeNullableType<number> = number,\n>(\n config: PropertyConfig<T>\n): readonly PropertyValidatorComponent<any>[] => {\n return [\n getValidatorFromConfigElseEmpty(config?.minValue, minNumber),\n getValidatorFromConfigElseEmpty(config?.maxValue, maxNumber),\n ]\n}\n\nconst mergeValidators = <\n TValue extends Arrayable<CanBeNullableType<DataValue>> = Arrayable<DataValue>,\n>(\n config: PropertyConfig<TValue> | undefined,\n ...validators: readonly (\n | PropertyValidatorComponent<any>\n | PropertyValidatorComponentTypeAdvanced<any, any>\n )[]\n): PropertyValidatorComponent<any>[] => {\n return [...validators, ...(config?.validators ? config.validators : [])]\n}\n\nconst isModelInstance = (obj: any): obj is ModelInstance<any, any> => {\n // @ts-ignore\n return Boolean(obj && obj.getPrimaryKey)\n}\n\nconst getModelName = (namespace: string, pluralName: string) => {\n return `${namespace}/${pluralName}`\n}\n\nconst parseModelName = (modelName: string) => {\n const parts = modelName.split('/')\n // eslint-disable-next-line functional/immutable-data\n const pluralName = parts.pop()\n const namespace = parts.join('/')\n return { namespace, pluralName }\n}\n\nconst buildValidEndpoint = (...components: readonly string[]) => {\n const suffix = components\n .map(x => {\n if (x === ID_KEY) {\n return x\n }\n return kebabCase(x)\n })\n .map(s => s.toLowerCase())\n .join('/')\n return `/${suffix}`\n}\n\nconst _generateRestInfo =\n (method: HttpMethods, withId: boolean, ...additional: readonly string[]) =>\n (pluralName: string, namespace: string) =>\n (existing?: RestInfoMinimum): RestInfo => {\n if (existing) {\n return {\n // Default add security, then override it.\n security: {},\n ...existing,\n }\n }\n const endpoint = withId\n ? buildValidEndpoint(namespace, pluralName, ID_KEY)\n : buildValidEndpoint(namespace, pluralName, ...additional)\n return {\n method,\n endpoint,\n // We cannot auto create security.\n security: {},\n }\n }\n\nconst _apiMethodToRestInfoGenerator = {\n [ApiMethod.create]: _generateRestInfo(HttpMethods.POST, false),\n [ApiMethod.retrieve]: _generateRestInfo(HttpMethods.GET, true),\n [ApiMethod.update]: _generateRestInfo(HttpMethods.PUT, true),\n [ApiMethod.delete]: _generateRestInfo(HttpMethods.DELETE, true),\n [ApiMethod.search]: _generateRestInfo(HttpMethods.POST, false, 'search'),\n}\n\nconst getNullRestInfo = () => {\n return {\n endpoint: NULL_ENDPOINT,\n method: NULL_METHOD,\n security: {},\n }\n}\n\nconst _fillOutRestInfo = (\n pluralName: string,\n namespace: string,\n partial: Partial<ApiInfoPartialRest> | undefined,\n nullRest: Record<ApiMethod, RestInfo>\n) => {\n const finishedRestInfo: Record<ApiMethod, RestInfo> = Object.entries(\n ApiMethod\n ).reduce(\n (acc, [, method]) => {\n const existing =\n partial && partial.rest && partial.rest[method]\n ? partial.rest[method]\n : undefined\n const restInfo = _apiMethodToRestInfoGenerator[method](\n pluralName,\n namespace\n )(existing)\n return merge(acc, {\n [method]: restInfo,\n })\n },\n nullRest as Record<ApiMethod, RestInfo>\n )\n return {\n noPublish: false,\n onlyPublish: [],\n rest: finishedRestInfo,\n createOnlyOne: partial?.createOnlyOne || false,\n }\n}\n\nconst populateApiInformation = (\n pluralName: string,\n namespace: string,\n partial: Partial<ApiInfoPartialRest> | undefined\n): Readonly<Required<ApiInfo>> => {\n const nullRest = {\n delete: getNullRestInfo(),\n search: getNullRestInfo(),\n update: getNullRestInfo(),\n retrieve: getNullRestInfo(),\n create: getNullRestInfo(),\n }\n\n if (!partial) {\n return _fillOutRestInfo(pluralName, namespace, partial, nullRest)\n }\n // Are we not going to publish at all? All \"nulled\" out.\n if (partial.noPublish) {\n return {\n onlyPublish: [],\n noPublish: true,\n rest: nullRest,\n createOnlyOne: false,\n }\n }\n\n const rest: Partial<Record<ApiMethod, RestInfoMinimum>> = partial.rest || {}\n // Should we only publish some but not all?\n if (partial.onlyPublish && partial.onlyPublish.length > 0) {\n return partial.onlyPublish.reduce(\n (acc, method) => {\n const restInfo = _apiMethodToRestInfoGenerator[method](\n pluralName,\n namespace\n )(rest[method])\n return merge(acc, {\n rest: {\n [method]: restInfo,\n },\n })\n },\n {\n noPublish: false,\n onlyPublish: partial.onlyPublish,\n createOnlyOne: Boolean(partial.createOnlyOne),\n rest: nullRest,\n } as ApiInfo\n )\n }\n return _fillOutRestInfo(pluralName, namespace, partial, nullRest)\n}\n\n/**\n * Create a zod schema generator for a property given its type and config.\n * Returns a function that when called produces the zod schema.\n */\nconst createZodForProperty =\n (propertyType: any, config?: PropertyConfig<any>) => () => {\n const myConfig: PropertyConfig<any> = config || {}\n const provided = myConfig.zod\n if (provided) {\n return provided as ZodType<any>\n }\n\n const _getZodForPropertyType = (pt: any) => {\n if (myConfig.choices) {\n return z.enum(myConfig.choices as any)\n }\n switch (pt) {\n case 'UniqueId':\n return z.string()\n case 'Date':\n case 'Datetime':\n return z.union([z.string(), z.date()])\n case 'Integer':\n return z.number().int()\n case 'Number':\n return z.number()\n case 'Boolean':\n return z.boolean()\n case 'Array':\n return z.array(z.any())\n case 'Object':\n return z.object().loose()\n case 'Email':\n return z.email()\n case 'Text':\n case 'BigText':\n return z.string()\n case 'ModelReference':\n return z.union([z.string(), z.number()])\n default:\n return z.any()\n }\n }\n\n const baseSchema = _getZodForPropertyType(propertyType)\n const choices = (config as any)?.choices\n const schemaFromChoices =\n choices && Array.isArray(choices) && choices.length > 0\n ? z.union(choices.map((c: any) => z.literal(c)) as any)\n : baseSchema\n\n const finalSchema = flow([\n s =>\n typeof myConfig.minValue === 'number' ? s.min(myConfig.minValue) : s,\n s =>\n typeof myConfig.maxValue === 'number' ? s.max(myConfig.maxValue) : s,\n s =>\n typeof myConfig.minLength === 'number' ? s.min(myConfig.minLength) : s,\n s =>\n typeof myConfig.maxLength === 'number' ? s.max(myConfig.maxLength) : s,\n s =>\n myConfig.defaultValue !== undefined\n ? s.default(myConfig.defaultValue)\n : s,\n s => (myConfig.required ? s : s.optional()),\n // Attach description for Zod consumers and OpenAPI generators.\n s => {\n if (myConfig.description) {\n // zod's describe helps Zod introspection; some zod-openapi versions expect metadata via .meta or .openapi\n // Use .describe and also attach .meta with openapi description if available.\n if (typeof s.openapi === 'function') {\n return s.openapi({ description: myConfig.description })\n }\n return s.meta\n ? s.meta({ description: myConfig.description })\n : s.describe(myConfig.description)\n }\n return s\n },\n ])(schemaFromChoices)\n\n return finalSchema as ZodType<any>\n }\n\nexport {\n isReferencedProperty,\n getValueForModelInstance,\n getValueForReferencedModel,\n getCommonTextValidators,\n getValidatorFromConfigElseEmpty,\n getCommonNumberValidators,\n mergeValidators,\n isModelInstance,\n getModelName,\n buildValidEndpoint,\n populateApiInformation,\n NULL_ENDPOINT,\n NULL_METHOD,\n createZodForProperty,\n parseModelName,\n}\n", "import { PropertyType, PrimaryKeyType } from '../types.js'\nimport { createUuid, getRandomValues } from '../utils.js'\nimport {\n DatabaseKeyPropertyConfig,\n PrimaryKeyGenerator,\n PrimaryKeyPropertyType,\n} from './types.js'\n\nconst _getModelIdPropertyType = (\n config: DatabaseKeyPropertyConfig<any> = {}\n): PrimaryKeyPropertyType => {\n return config.dataType || PropertyType.UniqueId\n}\n\nexport const getPrimaryKeyGenerator = <TValue extends PrimaryKeyType>(\n config: DatabaseKeyPropertyConfig<TValue> = {}\n): PrimaryKeyGenerator => {\n const custom = config.primaryKeyGenerator\n if (custom) {\n return custom\n }\n const idType = _getModelIdPropertyType(config)\n switch (idType) {\n case PropertyType.Integer:\n return () => Promise.resolve(getRandomValues()[0]!)\n default: {\n return () => Promise.resolve(createUuid())\n }\n }\n}\n", "import merge from 'lodash/merge.js'\nimport { asyncMap } from 'modern-async'\nimport {\n ModelFactory,\n ModelInstanceFetcher,\n PrimaryKeyType,\n DataDescription,\n ModelInstance,\n CreateParams,\n PropertyInstance,\n ToObjectResult,\n ModelFactoryOptions,\n} from '../types.js'\nimport { Model as functionalModel } from '../models.js'\nimport { ValidationError } from '../errors.js'\nimport { uniqueTogether } from './validation.js'\nimport {\n OrmModelInstance,\n OrmModel,\n DatastoreAdapter,\n OrmSearch,\n OrmModelFactory,\n Orm,\n OrmModelExtensions,\n OrmModelInstanceExtensions,\n OrmModelFactoryOptionsExtensions,\n OrmSearchResult,\n MinimumOrmModelDefinition,\n} from './types.js'\nimport { queryBuilder } from './query.js'\n\n/**\n * Creates a structure that has an OrmModel and a fetcher\n * @param datastoreAdapter - A backing datastore.\n * @param Model - An optional underlying Model factory for using. Defaults to {@link Model}\n */\nconst createOrm = ({\n datastoreAdapter,\n Model = functionalModel,\n}: Readonly<{\n datastoreAdapter: DatastoreAdapter\n Model?: ModelFactory\n}>): Orm => {\n if (!datastoreAdapter) {\n throw new Error(`Must include a datastoreAdapter`)\n }\n\n const _retrievedObjToModel =\n <TData extends DataDescription>(model: OrmModel<TData>) =>\n (obj: ToObjectResult<TData>) => {\n return model.create(obj as unknown as CreateParams<TData, ''>)\n }\n\n // @ts-ignore\n const fetcher: ModelInstanceFetcher<\n OrmModelExtensions,\n OrmModelInstanceExtensions\n > = async <TData extends DataDescription>(\n model: OrmModel<TData>,\n id: PrimaryKeyType\n ) => {\n const x: Promise<OrmModelInstance<TData> | undefined> = retrieve<TData>(\n model,\n id\n )\n return x\n }\n\n const retrieve = async <T extends DataDescription>(\n model: OrmModel<T>,\n id: PrimaryKeyType\n ) => {\n const obj = await datastoreAdapter.retrieve(model, id)\n if (!obj) {\n return undefined\n }\n return _retrievedObjToModel<T>(model)(obj)\n }\n\n const _defaultOptions = <\n T extends DataDescription,\n >(): ModelFactoryOptions<T> => ({\n instanceCreatedCallback: undefined,\n })\n\n const _convertOptions = <T extends DataDescription>(\n options?: ModelFactoryOptions<T, OrmModelFactoryOptionsExtensions>\n ) => {\n const r: ModelFactoryOptions<T, OrmModelFactoryOptionsExtensions> = merge(\n {},\n _defaultOptions(),\n options\n )\n return r\n }\n\n const ThisModel: OrmModelFactory = <T extends DataDescription>(\n modelDefinition: MinimumOrmModelDefinition<T>,\n options?: ModelFactoryOptions<T, OrmModelFactoryOptionsExtensions>\n ) => {\n /*\n NOTE: We need access to the model AFTER its built, so we have to have this state variable.\n It has been intentionally decided that recreating the model each and every time for each database retrieve is\n too much cost to obtain \"functional purity\". This could always be reverted back.\n */\n // @ts-ignore\n // eslint-disable-next-line functional/no-let\n let model: OrmModel<T, OrmModelExtensions, OrmModelInstanceExtensions> =\n null\n const theOptions = _convertOptions(options)\n\n const search = <TOverride extends DataDescription>(\n ormQuery: OrmSearch\n ): Promise<OrmSearchResult<TOverride>> => {\n return datastoreAdapter.search(model, ormQuery).then(result => {\n // @ts-ignore\n const conversionFunc = _retrievedObjToModel<TOverride>(model)\n return {\n // @ts-ignore\n instances: result.instances.map(conversionFunc),\n page: result.page,\n }\n })\n }\n\n const searchOne = <TOverride extends DataDescription>(\n ormQuery: OrmSearch\n ) => {\n ormQuery = merge(ormQuery, { take: 1 })\n return search<TOverride>(ormQuery).then(({ instances }) => {\n return instances[0]\n })\n }\n\n const bulkInsert = async <TOverride extends DataDescription>(\n instances: readonly OrmModelInstance<TOverride>[]\n ) => {\n if (datastoreAdapter.bulkInsert) {\n // @ts-ignore\n await datastoreAdapter.bulkInsert<TOverride>(model, instances)\n return undefined\n }\n await asyncMap(instances, x => x.save())\n return undefined\n }\n\n const bulkDelete = async <TOverride extends DataDescription>(\n keysOrInstances:\n | readonly OrmModelInstance<TOverride>[]\n | readonly PrimaryKeyType[]\n ) => {\n const ids: readonly PrimaryKeyType[] =\n typeof keysOrInstances[0] === 'object'\n ? keysOrInstances.map(x =>\n (x as OrmModelInstance<TOverride>).getPrimaryKey()\n )\n : (keysOrInstances as readonly PrimaryKeyType[])\n if (datastoreAdapter.bulkDelete) {\n await datastoreAdapter.bulkDelete(model, ids)\n return undefined\n }\n await asyncMap(ids, id => model.delete(id))\n return undefined\n }\n\n const loadedRetrieve = <TOverride extends DataDescription>(\n id: PrimaryKeyType\n ) => {\n // @ts-ignore\n return retrieve<TOverride>(model, id)\n }\n\n const modelValidators = modelDefinition?.uniqueTogether\n ? (modelDefinition.modelValidators || []).concat(\n // @ts-ignore\n uniqueTogether(modelDefinition.uniqueTogether)\n )\n : modelDefinition.modelValidators\n\n const ormModelDefinition = merge({}, modelDefinition, {\n modelValidators,\n })\n\n const _updateLastModifiedIfExistsReturnNewObj = async <\n TOverride extends DataDescription,\n >(\n instance: ModelInstance<TOverride>\n ): Promise<OrmModelInstance<TOverride>> => {\n const hasLastModified = Object.entries(\n instance.getModel().getModelDefinition().properties\n ).filter(propertyEntry => {\n const property = propertyEntry[1] as PropertyInstance<any>\n return Boolean('lastModifiedUpdateMethod' in property)\n })[0]\n\n const doLastModified = async () => {\n const obj = await instance.toObj<TOverride>()\n const newInstance = model.create(\n // @ts-ignore\n merge(obj, {\n [hasLastModified[0]]:\n // @ts-ignore\n hasLastModified[1].lastModifiedUpdateMethod(),\n })\n )\n return newInstance\n }\n\n // @ts-ignore\n return hasLastModified ? doLastModified() : instance\n }\n\n const save = async <TOverride extends DataDescription>(\n instance: ModelInstance<TOverride>\n ): Promise<OrmModelInstance<TOverride>> => {\n return Promise.resolve().then(async () => {\n const newInstance =\n await _updateLastModifiedIfExistsReturnNewObj<TOverride>(instance)\n const invalid = await newInstance.validate()\n if (invalid) {\n throw new ValidationError(model.getName(), invalid)\n }\n const savedObj = await datastoreAdapter.save<TOverride>(newInstance)\n // @ts-ignore\n return _retrievedObjToModel<TOverride>(model)(savedObj)\n })\n }\n\n const createAndSave = async <TOverride extends DataDescription>(\n data: ModelInstance<TOverride>\n ): Promise<OrmModelInstance<TOverride>> => {\n if (datastoreAdapter.createAndSave) {\n const response = await datastoreAdapter.createAndSave<TOverride>(data)\n // @ts-ignore\n return _retrievedObjToModel<TOverride>(model)(response)\n }\n // @ts-ignore\n const instance = model.create(await data.toObj<TOverride>())\n return instance.save()\n }\n\n const deleteObj = (id: PrimaryKeyType) => {\n return Promise.resolve().then(async () => {\n await datastoreAdapter.delete(model, id)\n })\n }\n\n const _getSave = (\n instance: ModelInstance<T>\n ): (<TOverrides extends DataDescription>() => Promise<\n OrmModelInstance<TOverrides>\n >) => {\n // See if save has been overrided.\n if (theOptions.save !== undefined) {\n // @ts-ignore\n return () => theOptions.save(save, instance)\n }\n // @ts-ignore\n return () => save(instance)\n }\n\n const _getDelete = (instance: ModelInstance<T>) => {\n if (theOptions.delete) {\n // @ts-ignore\n return () => theOptions.delete(deleteObj, instance)\n }\n return () => deleteObj(instance.getPrimaryKey())\n }\n\n const instanceCreatedCallback = (instance: OrmModelInstance<T>) => {\n // @ts-ignore\n // eslint-disable-next-line functional/immutable-data\n instance.save = _getSave(instance)\n // @ts-ignore\n // eslint-disable-next-line functional/immutable-data\n instance.delete = _getDelete(instance)\n if (theOptions.instanceCreatedCallback) {\n const callbacks: readonly ((instance: OrmModelInstance<T>) => void)[] =\n Array.isArray(theOptions.instanceCreatedCallback)\n ? theOptions.instanceCreatedCallback\n : [theOptions.instanceCreatedCallback]\n callbacks.forEach(x => x(instance))\n }\n }\n\n // Absolutely do not put theOptions as the first argument. This first argument is what is modified,\n // therefore the instanceCreatedCallback keeps calling itself instead of wrapping.\n const overridedOptions: ModelFactoryOptions<\n T,\n OrmModelFactoryOptionsExtensions\n > = merge({}, theOptions, {\n instanceCreatedCallback: [instanceCreatedCallback],\n })\n\n const baseModel = Model<T>(ormModelDefinition, overridedOptions)\n const lowerLevelCreate = baseModel.create\n\n const _convertModelInstance = (\n instance: ModelInstance<T>\n ): OrmModelInstance<T> => {\n return merge(instance, {\n create,\n getModel: () => model,\n save: _getSave(instance),\n delete: _getDelete(instance),\n })\n }\n\n const create = <IgnoreProperties extends string = ''>(\n data: CreateParams<T, IgnoreProperties>\n ): OrmModelInstance<T> => {\n const result = lowerLevelCreate(data)\n return _convertModelInstance(result)\n }\n\n const _countRecursive = async (page = null): Promise<number> => {\n const results = await model.search(\n queryBuilder().pagination(page).compile()\n )\n const length1 = results.instances.length\n // Don't run it again if the page is the same as a previous run.\n if (results.page && results.page !== page) {\n const length2 = await _countRecursive(results.page)\n return length1 + length2\n }\n return length1\n }\n\n const count = async (): Promise<number> => {\n // NOTE: This is EXTREMELY inefficient. This should be\n // overrided by a dataProvider if at all possible.\n if (datastoreAdapter.count) {\n return datastoreAdapter.count<T>(model)\n }\n return _countRecursive()\n }\n\n model = merge(baseModel, {\n create,\n save,\n delete: deleteObj,\n retrieve: loadedRetrieve,\n search,\n searchOne,\n createAndSave,\n bulkInsert,\n bulkDelete,\n count,\n })\n return model\n }\n\n return {\n Model: ThisModel,\n fetcher,\n }\n}\n\nexport { createOrm }\n", "import merge from 'lodash/merge.js'\nimport z, { ZodObject, ZodType } from 'zod'\nimport { toJsonAble } from './serialization.js'\nimport { createModelValidator } from './validation.js'\nimport {\n CreateParams,\n DataDescription,\n MinimalModelDefinition,\n ModelDefinition,\n ModelErrors,\n ModelFactory,\n ModelInstance,\n ModelFactoryOptions,\n ModelReferenceType,\n ModelReferenceFunctions,\n ModelReferencePropertyInstance,\n ModelType,\n Nullable,\n PropertyGetters,\n PropertyInstance,\n PropertyValidators,\n RestInfo,\n ToObjectFunction,\n ModelInstanceFetcher,\n} from './types.js'\nimport {\n getModelName,\n NULL_ENDPOINT,\n NULL_METHOD,\n populateApiInformation,\n} from './lib.js'\nimport { memoizeAsync, memoizeSync, singularize, toTitleCase } from './utils.js'\n\nconst _defaultOptions = <\n T extends DataDescription,\n>(): ModelFactoryOptions<T> => ({\n instanceCreatedCallback: undefined,\n})\n\nconst _convertOptions = <T extends DataDescription>(\n options?: ModelFactoryOptions<T>\n) => {\n const r: ModelFactoryOptions<T> = merge({}, _defaultOptions(), options)\n return r\n}\n\nconst _addDescription = (\n schema: ZodObject<DataDescription>,\n description?: string\n) => {\n if (!description) {\n return schema\n }\n // @ts-ignore\n if (typeof schema.openapi === 'function') {\n // @ts-ignore\n return schema.openapi({ description: description })\n }\n return schema.meta\n ? schema.meta({ description: description })\n : schema.describe(description)\n}\n\nconst _createZod = <T extends DataDescription>(\n modelDefinition: MinimalModelDefinition<T>\n): ZodObject<DataDescription> => {\n if (modelDefinition.schema) {\n return _addDescription(modelDefinition.schema, modelDefinition.description)\n }\n const properties = Object.entries(modelDefinition.properties).reduce(\n (acc, [key, property]) => {\n const asProp = property as PropertyInstance<any>\n return merge(acc, {\n [key]: asProp.getZod(),\n })\n },\n {} as Record<string, ZodType>\n )\n const obj = z.object(properties) as ZodObject<DataDescription>\n return _addDescription(obj, modelDefinition.description)\n}\n\nconst _toModelDefinition = <T extends DataDescription>(\n minimal: MinimalModelDefinition<T>\n): ModelDefinition<T> => {\n return {\n singularName: singularize(minimal.pluralName),\n displayName: toTitleCase(minimal.pluralName),\n description: '',\n primaryKeyName: 'id',\n modelValidators: [],\n schema: _createZod(minimal),\n ...minimal,\n }\n}\n\nconst _validateModelDefinition = <T extends DataDescription>(\n modelDefinition: MinimalModelDefinition<T>\n) => {\n const primaryKeyName = modelDefinition.primaryKeyName || 'id'\n const primaryKeyProperty =\n // @ts-ignore\n modelDefinition.properties[primaryKeyName]\n if (!primaryKeyProperty) {\n throw new Error(`Property missing for primaryKey named ${primaryKeyName}`)\n }\n if (!modelDefinition.pluralName) {\n throw new Error(`Must include pluralName for model.`)\n }\n if (!modelDefinition.namespace) {\n throw new Error(`Must include namespace for model.`)\n }\n}\n\n/**\n * An out of the box ModelFactory that can create Models.\n * @param options - Any additional model options\n * @returns A simple Model function ready for creating models. See {@link ModelType}\n */\nconst Model: ModelFactory = <T extends DataDescription>(\n minimalModelDefinitions: MinimalModelDefinition<T>,\n options?: ModelFactoryOptions<T>\n): ModelType<T> => {\n _validateModelDefinition(minimalModelDefinitions)\n /*\n * This non-functional approach is specifically used to\n * allow instances to be able to refer back to its parent without\n * having to duplicate it for every instance.\n * This is set at the very end and returned, so it can be referenced\n * throughout instance methods.\n */\n // eslint-disable-next-line functional/no-let\n let model: Nullable<ModelType<T>> = null\n const theOptions = _convertOptions(options)\n const modelDefinition = _toModelDefinition(minimalModelDefinitions)\n\n const getPrimaryKeyName = () => modelDefinition.primaryKeyName\n const getPrimaryKey = (loadedInternals: any) => {\n const property = loadedInternals.get[getPrimaryKeyName()]\n return property()\n }\n\n const create = <IgnorePrimaryKeyName extends string = ''>(\n instanceValues: CreateParams<T, IgnorePrimaryKeyName>\n ) => {\n // eslint-disable-next-line functional/no-let\n let instance: Nullable<ModelInstance<T>> = null\n const startingInternals: Readonly<{\n get: PropertyGetters<T>\n validators: PropertyValidators<T>\n references: ModelReferenceFunctions\n }> = {\n get: {} as PropertyGetters<T> & Readonly<{ id: () => string }>,\n validators: {},\n references: {},\n }\n\n const prop: [string, PropertyInstance<any>][] = Object.entries(\n modelDefinition.properties\n )\n const loadedInternals = prop.reduce(\n (acc, [key, property]) => {\n const propertyGetter = memoizeSync(() =>\n property.createGetter(\n //@ts-ignore\n instanceValues[key],\n instanceValues,\n // NOTE: By the time it gets here, it has already been implemented.\n instance as ModelInstance<any>\n )()\n )\n const propertyValidator = property.getValidator(propertyGetter)\n const fleshedOutInstanceProperties = {\n get: {\n [key]: () => propertyGetter(),\n },\n validators: {\n [key]: propertyValidator,\n },\n }\n const asReferenced = property as ModelReferencePropertyInstance<\n any,\n any\n >\n const referencedProperty = asReferenced.getReferencedId\n ? {\n references: {\n [key]: () =>\n asReferenced.getReferencedId(\n // @ts-ignore\n instanceValues[key] as ModelReferenceType<any>\n ),\n },\n }\n : {}\n\n return merge(\n acc,\n fleshedOutInstanceProperties,\n referencedProperty\n ) as Readonly<{\n get: PropertyGetters<T>\n validators: PropertyValidators<T>\n references: ModelReferenceFunctions\n }>\n },\n startingInternals as Readonly<{\n get: PropertyGetters<T>\n validators: PropertyValidators<T>\n references: ModelReferenceFunctions\n }>\n )\n\n const getModel = () => model as ModelType<T>\n\n // We are casting this, because the output type is really complicated.\n // and memoizing this is very important.\n // @ts-ignore\n const toObj = memoizeAsync(() => {\n return toJsonAble(loadedInternals.get)()\n }) as ToObjectFunction<T>\n\n const validate = memoizeAsync((options = {}) => {\n return Promise.resolve().then(() => {\n return createModelValidator<T, ModelType<T>>(\n loadedInternals.validators,\n modelDefinition.modelValidators\n )(instance as ModelInstance<T>, options)\n }) as Promise<ModelErrors<T> | undefined>\n })\n\n const getReferences = () => loadedInternals.references\n const getValidators = () => loadedInternals.validators\n\n // @ts-ignore\n instance = {\n get: loadedInternals.get,\n getReferences,\n getValidators,\n getModel,\n toObj,\n getPrimaryKey: () => getPrimaryKey(loadedInternals),\n validate,\n } as ModelInstance<T>\n\n if (theOptions.instanceCreatedCallback) {\n const toCall = Array.isArray(theOptions.instanceCreatedCallback)\n ? theOptions.instanceCreatedCallback\n : [theOptions.instanceCreatedCallback]\n toCall.map(func => func(instance as ModelInstance<T>))\n }\n return instance\n }\n\n const getApiInfo = memoizeSync(() => {\n return populateApiInformation(\n modelDefinition.pluralName,\n modelDefinition.namespace,\n modelDefinition.api\n )\n })\n\n // This sets the model that is used by the instances later.\n model = {\n /**\n * Creates a model instance.\n */\n create,\n getName: () =>\n getModelName(modelDefinition.namespace, modelDefinition.pluralName),\n getModelDefinition: memoizeSync(() => modelDefinition),\n getPrimaryKey,\n getApiInfo,\n }\n return model as ModelType<T>\n}\n\n/**\n * A useful function for determining if a RestInfo found in an ApiInfo is \"null\" or not.\n * That is, whether it should be used and considered.\n * @param restInfo\n */\nconst isNullRestInfo = (restInfo: RestInfo): boolean => {\n return restInfo.method === NULL_METHOD && restInfo.endpoint === NULL_ENDPOINT\n}\n\n/**\n * A ModelInstanceFetcher that does not do anything. It always returns undefined.\n */\nconst noFetch: ModelInstanceFetcher = () => {\n return Promise.resolve(undefined)\n}\n\nexport { Model, isNullRestInfo, noFetch }\n", "import merge from 'lodash/merge.js'\nimport {\n PropertyGetters,\n JsonAble,\n ToObjectFunction,\n DataDescription,\n JsonifiedData,\n ModelInstance,\n ToObjectResult,\n} from './types.js'\n\nconst isModelInstance = (obj: any): obj is ModelInstance<any> => {\n return Boolean(obj.toObj)\n}\n\nconst _getValue = async (value: any): Promise<JsonAble | null> => {\n if (value === undefined) {\n return undefined\n }\n if (value === null) {\n return null\n }\n const type = typeof value\n const asFunction = value as (...args: any[]) => any\n if (type === 'function') {\n return _getValue(await asFunction())\n }\n // Nested Object\n if (isModelInstance(value)) {\n return _getValue(await value.toObj())\n }\n // Dates\n const asDate = value as Date\n if (type === 'object' && asDate.toISOString) {\n return _getValue(asDate.toISOString())\n }\n return value\n}\n\nconst toJsonAble =\n <T extends DataDescription>(\n keyToFunc: PropertyGetters<T>\n ): ToObjectFunction<T> =>\n <R extends T | JsonifiedData<T> = JsonifiedData<T>>(): Promise<\n ToObjectResult<R>\n > => {\n return Object.entries(keyToFunc).reduce(async (acc, [key, value]) => {\n const realAcc = await acc\n const trueValue = await _getValue(await value)\n if (trueValue === undefined) {\n return realAcc\n }\n return merge(realAcc, { [key]: trueValue })\n }, Promise.resolve({})) as Promise<ToObjectResult<R>>\n }\n\nexport { toJsonAble }\n", "/* eslint-disable functional/no-this-expressions */\n/* eslint-disable functional/no-classes */\nclass ValidationError extends Error {\n public modelName: string\n public keysToErrors: Record<string, readonly string[]>\n constructor(\n modelName: string,\n keysToErrors: Record<string, readonly string[]>\n ) {\n super(`${modelName} did not pass validation`)\n this.name = 'ValidationError'\n this.modelName = modelName\n this.keysToErrors = keysToErrors\n }\n}\n/* eslint-enable functional/no-this-expressions */\n/* eslint-enable functional/no-classes */\n\nexport { ValidationError }\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["EqualitySymbol", "DatastoreValueType", "SortOrder", "omit", "merge", "flow", "import_merge", "ApiMethod", "import_merge", "import_get", "import_merge", "getRandomValuesFunc", "PluralEndings", "AsyncLock", "flow", "isDate", "isEmpty", "value", "flatMap", "merge", "import_flow", "import_merge", "import_get", "kebabCase", "merge", "choices", "flow", "isDate", "merge", "isDate", "merge", "merge", "merge", "merge", "property", "identity", "import_merge", "import_merge", "import_zod", "import_merge", "isModelInstance", "merge", "merge", "property", "z", "options", "Model", "_defaultOptions", "_convertOptions", "merge", "property"]
|
|
7
|
+
}
|