UNPKG

datum-focus

Version:

Data shape, model, metadata, JSON, JSON Schema, GraphQL, MongoDB query and aggregations, iterator generators

194 lines (171 loc) 7.5 kB
import { Query } from "sift"; import { v4 as guid } from "uuid"; import { KnownRecord } from "../record"; import { Guid } from "../string"; import { Model } from "../model"; export type K = { _id: Guid }; export const entity = <T extends {}>(record: T): Entity<T> => ({ _id: guid(), ...record, }); export const collonize = <T extends {}>( records: T[] ): Record<Guid, Entity<T>> => records.reduce((coll, record) => { const ntt = entity(record); return Object.assign(coll, { [ntt._id]: ntt }); }, {}); export type Entity<T extends {}> = { _id: string; } & T; export type StoreResult<T extends {} = KnownRecord> = K & { data?: T | null; rescode?: ResultCode; message?: string; }; export interface Repository<T extends {} = KnownRecord> { readonly model: Model<T>; count: Promise<number>; create(record: T): Promise<StoreResult<T>>; delete(_id: string): Promise<StoreResult<T>>; find(_id: string): Promise<StoreResult<T>>; select(query?: Query<T>): Promise<AsyncIterable<Entity<T>>>; update(entity: Entity<Partial<T>>): Promise<StoreResult<T>>; } export interface BatchRepository<T extends {} = KnownRecord> { readonly model: Model<T>; count: Promise<number>; batchCreate(records: T[]): Promise<StoreResult<T>[]>; batchDelete(ids: string[]): Promise<StoreResult<T>[]>; batchFind(ids: string[]): Promise<AsyncIterable<Entity<T>>>; batchUpdate(entities: Entity<Partial<T>>[]): Promise<StoreResult<T>[]>; } /*** 2×× SUCCESS ***/ export const RESULT_CODE__OK = 200; export const RESULT_CODE__CREATED = 201; export const RESULT_CODE__ACCEPTED = 202; export const HTTP_RESULT_CODE_203_NON_AUTHORITATIVE_INFORMATION = 203; export const HTTP_RESULT_CODE_204_NO_CONTENT = 204; export const HTTP_RESULT_CODE_205_RESET_CONTENT = 205; export const HTTP_RESULT_CODE_206_PARTIAL_CONTENT = 206; export const HTTP_RESULT_CODE_207_MULTI_STATUS = 207; export const HTTP_RESULT_CODE_208_ALREADY_REPORTED = 208; export const HTTP_RESULT_CODE_226_IM_USED = 226; /*** 3×× REDIRECTION ***/ export const HTTP_RESULT_CODE_300_MULTIPLE_CHOICES = 300; export const HTTP_RESULT_CODE_301_MOVED_PERMANENTLY = 301; export const HTTP_RESULT_CODE_302_FOUND = 302; export const HTTP_RESULT_CODE_303_SEE_OTHER = 303; export const HTTP_RESULT_CODE_304_NOT_MODIFIED = 304; export const HTTP_RESULT_CODE_305_USE_PROXY = 305; export const HTTP_RESULT_CODE_307_TEMPORARY_REDIRECT = 307; export const HTTP_RESULT_CODE_308_PERMANENT_REDIRECT = 308; /*** 4×× CLIENT ERROR ***/ export const RESULT_CODE__BAD_REQUEST = 400; export const RESULT_CODE__UNAUTHORIZED = 401; export const HTTP_RESULT_CODE_402_PAYMENT_REQUIRED = 402; export const RESULT_CODE__FORBIDDEN = 403; export const RESULT_CODE__NOT_FOUND = 404; export const HTTP_RESULT_CODE_405_METHOD_NOT_ALLOWED = 405; export const RESULT_CODE__NOT_ACCEPTABLE = 406; export const HTTP_RESULT_CODE_407_PROXY_AUTHENTICATION_REQUIRED = 407; export const HTTP_RESULT_CODE_408_REQUEST_TIMEOUT = 408; export const RESULT_CODE_CONFLICT = 409; export const HTTP_RESULT_CODE_410_GONE = 410; export const HTTP_RESULT_CODE_411_LENGTH_REQUIRED = 411; export const HTTP_RESULT_CODE_412_PRECONDITION_FAILED = 412; export const HTTP_RESULT_CODE_413_PAYLOAD_TOO_LARGE = 413; export const HTTP_RESULT_CODE_414_REQUEST_URI_TOO_LONG = 414; export const HTTP_RESULT_CODE_415_UNSUPPORTED_MEDIA_TYPE = 415; export const HTTP_RESULT_CODE_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416; export const HTTP_RESULT_CODE_417_EXPECTATION_FAILED = 417; export const HTTP_RESULT_CODE_418_IM_A_TEAPOT = 418; export const HTTP_RESULT_CODE_421_MISDIRECTED_REQUEST = 421; export const RESULT_CODE__UNPROCESSABLE_ENTITY = 422; export const RESULT_CODE__LOCKED = 423; export const HTTP_RESULT_CODE_424_FAILED_DEPENDENCY = 424; export const HTTP_RESULT_CODE_426_UPGRADE_REQUIRED = 426; export const RESULT_CODE__PRECONDITION_REQUIRED = 428; export const RESULT_CODE__TOO_MANY_REQUESTS = 429; export const HTTP_RESULT_CODE_431_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; export const HTTP_RESULT_CODE_444_CONNECTION_CLOSED_WITHOUT_RESPONSE = 444; export const HTTP_RESULT_CODE_451_UNAVAILABLE_FOR_LEGAL_REASONS = 451; export const HTTP_RESULT_CODE_499_CLIENT_CLOSED_REQUEST = 499; /*** 5×× SERVER ERROR ***/ export const HTTP_RESULT_CODE_500_INTERNAL_SERVER_ERROR = 500; export const RESULT_CODE__NOT_IMPLEMENTED = 501; export const HTTP_RESULT_CODE_502_BAD_GATEWAY = 502; export const RESULT_CODE__SERVICE_UNAVAILABLE = 503; export const HTTP_RESULT_CODE_504_GATEWAY_TIMEOUT = 504; export const HTTP_RESULT_CODE_505_HTTP_VERSION_NOT_SUPPORTED = 505; export const HTTP_RESULT_CODE_506_VARIANT_ALSO_NEGOTIATES = 506; export const RESULT_CODE__INSUFFICIENT_STORAGE = 507; export const HTTP_RESULT_CODE_508_LOOP_DETECTED = 508; export const HTTP_RESULT_CODE_510_NOT_EXTENDED = 510; export const HTTP_RESULT_CODE_511_NETWORK_AUTHENTICATION_REQUIRED = 511; export const HTTP_RESULT_CODE_599_NETWORK_CONNECTTIMEOUT_ERROR = 599; export const RESULT_CODES = [ /*** 2×× SUCCESS ***/ RESULT_CODE__OK, RESULT_CODE__CREATED, RESULT_CODE__ACCEPTED, HTTP_RESULT_CODE_203_NON_AUTHORITATIVE_INFORMATION, HTTP_RESULT_CODE_204_NO_CONTENT, HTTP_RESULT_CODE_205_RESET_CONTENT, HTTP_RESULT_CODE_206_PARTIAL_CONTENT, HTTP_RESULT_CODE_207_MULTI_STATUS, HTTP_RESULT_CODE_208_ALREADY_REPORTED, HTTP_RESULT_CODE_226_IM_USED, /*** 3×× REDIRECTION ***/ HTTP_RESULT_CODE_300_MULTIPLE_CHOICES, HTTP_RESULT_CODE_301_MOVED_PERMANENTLY, HTTP_RESULT_CODE_302_FOUND, HTTP_RESULT_CODE_303_SEE_OTHER, HTTP_RESULT_CODE_304_NOT_MODIFIED, /*** 4×× CLIENT ERROR ***/ RESULT_CODE__BAD_REQUEST, RESULT_CODE__UNAUTHORIZED, RESULT_CODE__FORBIDDEN, RESULT_CODE__NOT_FOUND, HTTP_RESULT_CODE_405_METHOD_NOT_ALLOWED, RESULT_CODE__NOT_ACCEPTABLE, HTTP_RESULT_CODE_407_PROXY_AUTHENTICATION_REQUIRED, HTTP_RESULT_CODE_408_REQUEST_TIMEOUT, RESULT_CODE_CONFLICT, HTTP_RESULT_CODE_410_GONE, HTTP_RESULT_CODE_411_LENGTH_REQUIRED, HTTP_RESULT_CODE_412_PRECONDITION_FAILED, HTTP_RESULT_CODE_413_PAYLOAD_TOO_LARGE, HTTP_RESULT_CODE_414_REQUEST_URI_TOO_LONG, HTTP_RESULT_CODE_415_UNSUPPORTED_MEDIA_TYPE, HTTP_RESULT_CODE_416_REQUESTED_RANGE_NOT_SATISFIABLE, HTTP_RESULT_CODE_417_EXPECTATION_FAILED, HTTP_RESULT_CODE_418_IM_A_TEAPOT, HTTP_RESULT_CODE_421_MISDIRECTED_REQUEST, RESULT_CODE__UNPROCESSABLE_ENTITY, RESULT_CODE__LOCKED, HTTP_RESULT_CODE_424_FAILED_DEPENDENCY, HTTP_RESULT_CODE_426_UPGRADE_REQUIRED, RESULT_CODE__PRECONDITION_REQUIRED, RESULT_CODE__TOO_MANY_REQUESTS, HTTP_RESULT_CODE_431_REQUEST_HEADER_FIELDS_TOO_LARGE, HTTP_RESULT_CODE_444_CONNECTION_CLOSED_WITHOUT_RESPONSE, HTTP_RESULT_CODE_451_UNAVAILABLE_FOR_LEGAL_REASONS, HTTP_RESULT_CODE_499_CLIENT_CLOSED_REQUEST, /*** 5×× SERVER ERROR ***/ HTTP_RESULT_CODE_500_INTERNAL_SERVER_ERROR, RESULT_CODE__NOT_IMPLEMENTED, HTTP_RESULT_CODE_502_BAD_GATEWAY, RESULT_CODE__SERVICE_UNAVAILABLE, HTTP_RESULT_CODE_504_GATEWAY_TIMEOUT, HTTP_RESULT_CODE_505_HTTP_VERSION_NOT_SUPPORTED, HTTP_RESULT_CODE_506_VARIANT_ALSO_NEGOTIATES, RESULT_CODE__INSUFFICIENT_STORAGE, HTTP_RESULT_CODE_508_LOOP_DETECTED, HTTP_RESULT_CODE_510_NOT_EXTENDED, HTTP_RESULT_CODE_511_NETWORK_AUTHENTICATION_REQUIRED, HTTP_RESULT_CODE_599_NETWORK_CONNECTTIMEOUT_ERROR, ] as const; export type ResultCode = typeof RESULT_CODES[number]; export type HttpResultCodeMap<T> = Record<ResultCode, T>; export type HttpResultCodeSet<T> = Partial<HttpResultCodeMap<T>>;