From c89f6268089b80b91bd0223d420ce8bbbe99d8df Mon Sep 17 00:00:00 2001 From: Syd Amir Date: Sat, 16 Apr 2022 22:34:35 +0430 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fixed=20schema=20and=20act=20enc?= =?UTF-8?q?apsulations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/acts/acts.ts | 265 ++++++++++++++++++------------------- src/acts/mod.ts | 6 + src/acts/types.ts | 35 +++++ src/deps.ts | 1 + src/lesan.ts | 24 ++++ src/mod.ts | 17 ++- src/models/context.ts | 28 ++-- src/models/inrelation.ts | 73 +++++----- src/models/mod.ts | 31 ++++- src/models/outrelation.ts | 80 ++++++----- src/models/pure.ts | 39 ++++-- src/models/relation.ts | 20 ++- src/models/schema.ts | 119 +++++++++-------- src/models/selectInp.ts | 33 +++-- src/models/selectStruct.ts | 176 ++++++++++++------------ src/models/types.ts | 7 +- src/odm/mod.ts | 78 ++++++----- src/server/mod.ts | 72 +++++----- src/types/mod.ts | 10 +- src/utils/checkWants.ts | 3 +- src/utils/serveLesan.ts | 178 +++++++++++++------------ 21 files changed, 733 insertions(+), 562 deletions(-) create mode 100644 src/acts/types.ts create mode 100644 src/lesan.ts diff --git a/src/acts/acts.ts b/src/acts/acts.ts index 26583b2b..364d61a5 100644 --- a/src/acts/acts.ts +++ b/src/acts/acts.ts @@ -1,6 +1,5 @@ -import { Struct } from "https://deno.land/x/lestruct/mod.ts"; -import { SchemasKey } from "../models/mod.ts"; -import { Body, throwError } from "../utils/mod.ts"; +import { throwError } from "../utils/mod.ts"; +import { Act, ActInp, Acts, Services } from "./types.ts"; // const actsSample = { // @@ -46,210 +45,198 @@ import { Body, throwError } from "../utils/mod.ts"; // }, // }; -export type ActFn = (body: Body) => any; +export const acts = (acts: Services) => { + type ServiceKeys = keyof typeof acts; -export interface Act { - validator: Struct; - fn: ActFn; -} - -export interface Acts { - dynamic: { - [key: string]: { - [key: string]: Act; - }; - }; - static: { - [key: string]: { - [key: string]: Act; - }; - }; -} - -export interface Services { - main: Acts; - [key: string]: Acts | string | undefined; -} - -const acts: Services = { - main: { - dynamic: {}, - static: {}, - }, -}; - -export interface ActInp { - type: "static" | "dynamic"; - schema: SchemasKey; - actName: string; - validator: Struct; - fn: ActFn; -} - -export const setAct: (actInp: ActInp) => void = ( + const setAct: (actInp: ActInp) => void = ( { type, schema, actName, validator, fn }, -) => { + ) => { if (!acts.main[type]) { - throw new Error(`Invalid type: ${type}`); + throw new Error(`Invalid type: ${type}`); } if (!acts.main[type][schema]) { - acts.main[type][schema] = {}; + acts.main[type][schema] = {}; } acts.main[type][schema][actName] = { - validator, - fn, + validator, + fn, }; -}; -export type ServiceKeys = keyof typeof acts; - -export const getDynamicActs = (serviceName?: ServiceKeys) => { - return (serviceName && acts[serviceName] - && (typeof acts[serviceName] !== "string")) - ? (acts[serviceName] as Acts).dynamic - : acts.main.dynamic; -}; - -export const getStaticActs = (serviceName?: ServiceKeys) => { - return (serviceName && acts[serviceName] - && (typeof acts[serviceName] !== "string")) - ? (acts[serviceName] as Acts).static - : acts.main.static; -}; - -export const getStaticKeys = (serviceName?: ServiceKeys) => { - return (serviceName && acts[serviceName] - && (typeof acts[serviceName] !== "string")) - ? Object.keys((acts[serviceName] as Acts).static) - : (serviceName === "main") - ? Object.keys(acts.main.static) - : throwError(`serviceName not valid : ${serviceName}`); -}; - -// TODO : check if acts[serviceName] === "string" should throw an error -export const getDynamicKeys = (serviceName: ServiceKeys) => { - return (serviceName && acts[serviceName] - && (typeof acts[serviceName] !== "string")) - ? Object.keys((acts[serviceName] as Acts).dynamic) - : (serviceName === "main") - ? Object.keys(acts.main.dynamic) - : throwError(`serviceName not valid : ${serviceName}`); -}; - -export const getServiceKeys = () => Object.keys(acts); - -export const getSchemaDynamicActs: ( - schema: SchemasKey, -) => { [key: string]: Act } = ( + }; + + const getDynamicActs = (serviceName?: ServiceKeys) => { + return (serviceName && acts[serviceName] && + (typeof acts[serviceName] !== "string")) + ? (acts[serviceName] as Acts).dynamic + : acts.main.dynamic; + }; + + const getStaticActs = (serviceName?: ServiceKeys) => { + return (serviceName && acts[serviceName] && + (typeof acts[serviceName] !== "string")) + ? (acts[serviceName] as Acts).static + : acts.main.static; + }; + + const getStaticKeys = (serviceName?: ServiceKeys) => { + return (serviceName && acts[serviceName] && + (typeof acts[serviceName] !== "string")) + ? Object.keys((acts[serviceName] as Acts).static) + : (serviceName === "main") + ? Object.keys(acts.main.static) + : throwError(`serviceName not valid : ${serviceName}`); + }; + + // TODO : check if acts[serviceName] === "string" should throw an error + const getDynamicKeys = (serviceName: ServiceKeys) => { + return (serviceName && acts[serviceName] && + (typeof acts[serviceName] !== "string")) + ? Object.keys((acts[serviceName] as Acts).dynamic) + : (serviceName === "main") + ? Object.keys(acts.main.dynamic) + : throwError(`serviceName not valid : ${serviceName}`); + }; + + const getServiceKeys = () => Object.keys(acts); + + const getSchemaDynamicActs: ( + schema: string, + ) => { [key: string]: Act } = ( schema, -) => { + ) => { if (!acts.main.dynamic[schema]) { - throw new Error(`Invalid schema: ${schema}`); + throw new Error(`Invalid schema: ${schema}`); } return acts.main.dynamic[schema]; -}; + }; -export const getSchemaStaticActs: (schema: string) => { [key: string]: Act } = ( + const getSchemaStaticActs: (schema: string) => { [key: string]: Act } = ( schema, -) => { + ) => { if (!acts.main.static[schema]) { - throw new Error(`Invalid schema: ${schema}`); + throw new Error(`Invalid schema: ${schema}`); } return acts.main.static[schema]; -}; + }; -export const getDynamicAct: ( - schema: SchemasKey, + const getDynamicAct: ( + schema: string, actName: string, -) => Act = (schema, actName) => { + ) => Act = (schema, actName) => { if (!acts.main.dynamic[schema]) { - throw new Error(`Invalid schema: ${schema}`); + throw new Error(`Invalid schema: ${schema}`); } if (!acts.main.dynamic[schema][actName]) { - throw new Error(`Invalid actName: ${actName}`); + throw new Error(`Invalid actName: ${actName}`); } return acts.main.dynamic[schema][actName]; -}; + }; -export const getStaticAct: ( + const getStaticAct: ( schema: string, actName: string, -) => Act = (schema, actName) => { + ) => Act = (schema, actName) => { if (!acts.main.static[schema]) { - throw new Error(`Invalid actName: ${actName}`); + throw new Error(`Invalid actName: ${actName}`); } if (!acts.main.static[schema][actName]) { - throw new Error(`Invalid actName: ${actName}`); + throw new Error(`Invalid actName: ${actName}`); } return acts.main.static[schema][actName]; -}; + }; -export const getActs = (type: "static" | "dynamic", schema: string) => { + const getActs = (type: "static" | "dynamic", schema: string) => { if (!acts.main[type]) { - throw new Error( - `Invalid action type: ${type} it just include dynamic and static`, - ); + throw new Error( + `Invalid action type: ${type} it just include dynamic and static`, + ); } if (!acts.main[type][schema]) { - throw new Error(`Invalid schema: ${schema}`); + throw new Error(`Invalid schema: ${schema}`); } return acts.main[type][schema]; -}; + }; -export const getActsKeys = ( + const getActsKeys = ( service: ServiceKeys, type: "static" | "dynamic", schema: string, -) => { + ) => { if (!acts[service] && typeof acts[service] === "string") { - throw new Error( - `Invalid service name: ${service} `, - ); + throw new Error( + `Invalid service name: ${service} `, + ); } if (!(acts[service] as Acts)[type]) { - throw new Error( - `Invalid action type: ${type} it just include dynamic and static`, - ); + throw new Error( + `Invalid action type: ${type} it just include dynamic and static`, + ); } if (!(acts[service] as Acts)[type][schema]) { - throw new Error(`Invalid schema: ${schema}`); + throw new Error(`Invalid schema: ${schema}`); } return Object.keys((acts[service] as Acts)[type][schema]); -}; + }; -export const getAct = ( + const getAct = ( service: ServiceKeys, type: "static" | "dynamic", schema: string, actName: string, -) => { + ) => { if (!acts[service] && typeof acts[service] === "string") { - throw new Error( - `Invalid service name: ${service} `, - ); + throw new Error( + `Invalid service name: ${service} `, + ); } if (!(acts[service] as Acts)[type]) { - throw new Error( - `Invalid action type: ${type} it just include dynamic and static`, - ); + throw new Error( + `Invalid action type: ${type} it just include dynamic and static`, + ); } if (!(acts[service] as Acts)[type][schema]) { - throw new Error(`Invalid schema: ${schema}`); + throw new Error(`Invalid schema: ${schema}`); } if (!(acts[service] as Acts)[type][schema][actName]) { - throw new Error(`Invalid action name: ${actName}`); + throw new Error(`Invalid action name: ${actName}`); } return (acts[service] as Acts)[type][schema][actName]; -}; + }; + + const getAtcsWithServices = () => acts; -export const getAtcsWithServices = () => acts; + const getMainActs = () => acts.main; -export const setService: (serviceName: string, service: Acts | string) => void = (serviceName, service) => { + const setService: (serviceName: string, service: Acts | string) => void = ( + serviceName, + service, + ) => { acts[serviceName] = service; -}; + }; -export const getService: (serviceName: ServiceKeys) => void = (serviceName) => { + const getService: (serviceName: ServiceKeys) => void = (serviceName) => { if (!acts[serviceName]) { - throw new Error(`Invalid serviceName: ${serviceName}`); + throw new Error(`Invalid serviceName: ${serviceName}`); } return acts[serviceName]; + }; + + return { + setAct, + getDynamicActs, + getStaticActs, + getStaticKeys, + getDynamicKeys, + getServiceKeys, + getSchemaDynamicActs, + getSchemaStaticActs, + getDynamicAct, + getStaticAct, + getActs, + getActsKeys, + getAct, + getAtcsWithServices, + getMainActs, + setService, + getService, + }; }; diff --git a/src/acts/mod.ts b/src/acts/mod.ts index 5f435538..8e83b810 100644 --- a/src/acts/mod.ts +++ b/src/acts/mod.ts @@ -1 +1,7 @@ +// import { acts } from "./acts.ts"; + export * from "./acts.ts"; +export * from "./types.ts"; + +// const generatedServices = acts().getAtcsWithServices(); +// export type ServiceKeys = keyof typeof generatedServices; diff --git a/src/acts/types.ts b/src/acts/types.ts new file mode 100644 index 00000000..3d7fbd76 --- /dev/null +++ b/src/acts/types.ts @@ -0,0 +1,35 @@ +import { Struct } from "../deps.ts"; +import { Body } from "../utils/mod.ts"; + +export type ActFn = (body: Body) => any; + +export interface Act { + validator: Struct; + fn: ActFn; +} + +export interface Acts { + dynamic: { + [key: string]: { + [key: string]: Act; + }; + }; + static: { + [key: string]: { + [key: string]: Act; + }; + }; +} + +export interface Services { + main: Acts; + [key: string]: Acts | string | undefined; +} + +export interface ActInp { + type: "static" | "dynamic"; + schema: string; + actName: string; + validator: Struct; + fn: ActFn; +} diff --git a/src/deps.ts b/src/deps.ts index c2f50264..86672813 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -1,2 +1,3 @@ +export { ensureDir } from "https://deno.land/std@0.135.0/fs/mod.ts"; export * from "https://deno.land/x/lestruct@v0.0.2/mod.ts"; export * from "https://deno.land/x/mongo@v0.29.3/mod.ts"; diff --git a/src/lesan.ts b/src/lesan.ts new file mode 100644 index 00000000..f23a1d39 --- /dev/null +++ b/src/lesan.ts @@ -0,0 +1,24 @@ +import { acts, Services } from "./acts/mod.ts"; +import { Model, schemas } from "./models/mod.ts"; +import { odm } from "./odm/mod.ts"; +import { lesanServer } from "./server/mod.ts"; +import { generateSchemTypes } from "./types/mod.ts"; + +export const lesan = () => { + const schemasObj: Record = {}; + + const actsObj: Services = { + main: { + dynamic: {}, + static: {}, + }, + }; + + return { + acts: { ...acts(actsObj) }, + schemas: { ...schemas(schemasObj) }, + odm: { ...odm() }, + runServer: lesanServer(schemasObj, actsObj), + generateSchemTypes: generateSchemTypes(schemasObj), + }; +}; diff --git a/src/mod.ts b/src/mod.ts index 4ce78d29..9b04e148 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -1,7 +1,12 @@ -export * from "./acts/mod.ts"; +// export * from "./acts/mod.ts"; +// export * from "./deps.ts"; +// export * from "./models/mod.ts"; +// export * from "./odm/mod.ts"; +// export * from "./server/mod.ts"; +// export * from "./types/mod.ts"; +// export * from "./utils/mod.ts"; + +export * from "./acts/types.ts"; export * from "./deps.ts"; -export * from "./models/mod.ts"; -export * from "./odm/mod.ts"; -export * from "./server/mod.ts"; -export * from "./types/mod.ts"; -export * from "./utils/mod.ts"; +export * from "./lesan.ts"; +export * from "./models/types.ts"; diff --git a/src/models/context.ts b/src/models/context.ts index 13825534..92df52a3 100644 --- a/src/models/context.ts +++ b/src/models/context.ts @@ -1,19 +1,23 @@ /// context type ---- export interface Context { - [key: string]: any + [key: string]: any; } -export let context: Context = {}; -export const getContextModel = () => context; +export const contextFns = () => { + let context: Context = {}; -export const addContexts = (con:Context) => { - context=con -}; + const getContextModel = () => context; -export const addContext =(con:Context)=>{ - context={...context,con} -} + const addContexts = (con: Context) => context = con; -export const addReqToContext = (con:Request)=>{ - context["Request"]=con -} + const addContext = (con: Context) => context = { ...context, con }; + + const addReqToContext = (con: Request) => context["Request"] = con; + + return { + getContextModel, + addContexts, + addContext, + addReqToContext, + }; +}; diff --git a/src/models/inrelation.ts b/src/models/inrelation.ts index 053f6ad0..3c21b085 100644 --- a/src/models/inrelation.ts +++ b/src/models/inrelation.ts @@ -1,37 +1,48 @@ -import { getSchemas } from "./schema.ts"; +import { ISchema } from "./mod.ts"; +import { schemaFns } from "./schema.ts"; import { InRelation } from "./types.ts"; -const schemas = getSchemas(); +export const inrelationFns = (schemasObj: ISchema) => { + const addInrelations = ( + { schemaName, inrelation }: { + schemaName: string; + inrelation: Record; + }, + ) => { + const schemas = schemaFns(schemasObj).getSchemas(); + const schema = schemas[schemaName]; + if (!schema) { + throw new Error(`Schema ${schemaName} does not exist`); + } + schema.inrelation = inrelation; + }; -export const addInrelations = ( - { schemaName, inrelation }: { - schemaName: string; - inrelation: Record; - }, -) => { - const schema = schemas[schemaName]; - if (!schema) { - throw new Error(`Schema ${schemaName} does not exist`); - } - schema.inrelation = inrelation; -}; + const addOneInRelation = ( + { schemaName, inrelationName, type }: { + schemaName: string; + inrelationName: string; + type: "one" | "many"; + }, + ) => { + const schemas = schemaFns(schemasObj).getSchemas(); + const schema = schemas[schemaName]; + if (!schema) { + throw new Error(`Schema ${schemaName} does not exist`); + } + schema.inrelation = { + ...schema.inrelation, + [inrelationName]: { schemaName, type }, + }; + }; -export const addOneInRelation = ( - { schemaName, inrelationName, type }: { - schemaName: string; - inrelationName: string; - type: "one" | "many"; - }, -) => { - const schema = schemas[schemaName]; - if (!schema) { - throw new Error(`Schema ${schemaName} does not exist`); - } - schema.inrelation = { - ...schema.inrelation, - [inrelationName]: { schemaName, type }, + const getInrelations = (schemaName: string) => { + const schemas = schemaFns(schemasObj).getSchemas(); + schemas[schemaName].inrelation; }; -}; -export const getInrelations = (schemaName: string) => - schemas[schemaName].inrelation; + return { + addInrelations, + addOneInRelation, + getInrelations, + }; +}; diff --git a/src/models/mod.ts b/src/models/mod.ts index 8090cf00..e7a86cde 100644 --- a/src/models/mod.ts +++ b/src/models/mod.ts @@ -1,7 +1,26 @@ -export * from "./inrelation.ts"; -export * from "./outrelation.ts"; -export * from "./pure.ts"; -export * from "./relation.ts"; -export * from "./schema.ts"; -export * from "./selectStruct.ts"; +import { contextFns } from "./context.ts"; +import { inrelationFns } from "./inrelation.ts"; +import { outrelationFns } from "./outrelation.ts"; +import { pureFns } from "./pure.ts"; +import { relationFns } from "./relation.ts"; +import { schemaFns } from "./schema.ts"; +import { selectStructFns } from "./selectStruct.ts"; +import { Model } from "./types.ts"; + export * from "./types.ts"; + +// const generatedSchema = schemaFns().getSchemas(); +// export type SchemasKey = keyof typeof generatedSchema; + +export type ISchema = Record; +export const schemas = (schemas: ISchema) => { + return { + ...schemaFns(schemas), + ...inrelationFns(schemas), + ...contextFns(), + ...outrelationFns(schemas), + ...pureFns(schemas), + ...relationFns(schemas), + ...selectStructFns(schemas), + }; +}; diff --git a/src/models/outrelation.ts b/src/models/outrelation.ts index 4ec85791..6e925fa7 100644 --- a/src/models/outrelation.ts +++ b/src/models/outrelation.ts @@ -1,41 +1,51 @@ -import { getSchemas } from "./schema.ts"; +import { ISchema } from "./mod.ts"; +import { schemaFns } from "./schema.ts"; import { OutRelation } from "./types.ts"; -const schemas = getSchemas(); - -export const addOneOutRelation = ( - { schemaName, outrelationName, number, sort }: { - schemaName: string; - outrelationName: string; - number: number; - sort: { - field: string; - order: "asc" | "desc"; +export const outrelationFns = (schemasObj: ISchema) => { + const addOneOutRelation = ( + { schemaName, outrelationName, number, sort }: { + schemaName: string; + outrelationName: string; + number: number; + sort: { + field: string; + order: "asc" | "desc"; + }; + }, + ) => { + const schemas = schemaFns(schemasObj).getSchemas(); + const schema = schemas[schemaName]; + if (!schema) { + throw new Error(`Schema ${schemaName} does not exist`); + } + schema.outrelation = { + ...schema.outrelation, + [outrelationName]: { schemaName, number, sort }, }; - }, -) => { - const schema = schemas[schemaName]; - if (!schema) { - throw new Error(`Schema ${schemaName} does not exist`); - } - schema.outrelation = { - ...schema.outrelation, - [outrelationName]: { schemaName, number, sort }, }; -}; -export const addOutRelations = ( - { schemaName, outrelation }: { - schemaName: string; - outrelation: Record; - }, -) => { - const schema = schemas[schemaName]; - if (!schema) { - throw new Error(`Schema ${schemaName} does not exist`); - } - schema.outrelation = outrelation; -}; + const addOutRelations = ( + { schemaName, outrelation }: { + schemaName: string; + outrelation: Record; + }, + ) => { + const schema = schemaFns(schemasObj).getSchemas()[schemaName]; + if (!schema) { + throw new Error(`Schema ${schemaName} does not exist`); + } + schema.outrelation = outrelation; + }; -export const getOutRelations = (schemaName: string) => - schemas[schemaName].outrelation; + const getOutRelations = (schemaName: string) => { + const schemas = schemaFns(schemasObj).getSchemas(); + return schemas[schemaName].outrelation; + }; + + return { + addOneOutRelation, + addOutRelations, + getOutRelations, + }; +}; diff --git a/src/models/pure.ts b/src/models/pure.ts index 216d77ae..826f479b 100644 --- a/src/models/pure.ts +++ b/src/models/pure.ts @@ -1,20 +1,33 @@ -import { getSchemas, SchemasKey } from "./schema.ts"; +import { ISchema } from "./mod.ts"; +import { schemaFns } from "./schema.ts"; import { PureModel } from "./types.ts"; -const schemas = getSchemas(); +export const pureFns = (schemasObj: ISchema) => { + const addPureModel = (name: string, pureModel: PureModel) => { + const schemas = schemaFns(schemasObj).getSchemas(); + return schemas[name] = { + pure: pureModel, + inrelation: {}, + outrelation: {}, + }; -export const addPureModel = (name: string, pureModel: PureModel) => { - schemas[name] = { - pure: pureModel, - inrelation: {}, - outrelation: {}, + // schemas[name].pure = pureModel; }; - // schemas[name].pure = pureModel; -}; -export const getPureModel = (name: SchemasKey) => schemas[name].pure; + const getPureModel = (name: string) => { + const schemas = schemaFns(schemasObj).getSchemas(); + return schemas[name]?.pure; + }; -export const getPureModelByNameAndKey = (name: string, key: string) => { - const pureModel = schemas[name].pure[key]; - return pureModel; + const getPureModelByNameAndKey = (name: string, key: string) => { + const schemas = schemaFns(schemasObj).getSchemas(); + const pureModel = schemas[name].pure[key]; + return pureModel; + }; + + return { + addPureModel, + getPureModel, + getPureModelByNameAndKey, + }; }; diff --git a/src/models/relation.ts b/src/models/relation.ts index 12720614..4a69aa44 100644 --- a/src/models/relation.ts +++ b/src/models/relation.ts @@ -1,8 +1,16 @@ -import { getSchemas, SchemasKey } from "./schema.ts"; +import { ISchema } from "./mod.ts"; +import { schemaFns } from "./schema.ts"; -const schemas = getSchemas(); +export const relationFns = (schemasObjs: ISchema) => { + const getRelation = ( + name: string, + relationType: "inrelation" | "outrelation", + ) => { + const schemas = schemaFns(schemasObjs).getSchemas(); + return schemas[name][relationType]; + }; -export const getRelation = ( - name: SchemasKey, - relationType: "inrelation" | "outrelation", -) => schemas[name][relationType]; + return { + getRelation, + }; +}; diff --git a/src/models/schema.ts b/src/models/schema.ts index 660ed8ab..fb8226d1 100644 --- a/src/models/schema.ts +++ b/src/models/schema.ts @@ -1,69 +1,80 @@ -import { array, assign, object } from "https://deno.land/x/lestruct/mod.ts"; +import { array, assign, object } from "../deps.ts"; import { Model } from "./types.ts"; -const schemas: Record = {}; +export const schemaFns = (schemas: Record) => { + // const schema1 = {} + const getSchemas = () => schemas; -export type SchemasKey = keyof typeof schemas; + const getSchema = (schemaName: string) => { + const schema = schemas[schemaName]; -export const getSchemas = () => schemas; + if (!schema) { + throw new Error(`Schema ${schemaName} not found`); + } + return schema; + }; -export const getSchema = (schemaName: SchemasKey) => { - const schema = schemas[schemaName]; + const getPureSchema = (schemaName: string) => { + const schema = schemas[schemaName]; - if (!schema) { - throw new Error(`Schema ${schemaName} not found`); - } - return schema; -}; + if (!schema) { + throw new Error(`Schema ${schemaName} not found`); + } + return schema.pure; + }; -export const getPureSchema = (schemaName: SchemasKey) => { - const schema = schemas[schemaName]; + const getPureFromInRel = (schemaName: string) => { + const schema = getSchema(schemaName); + let pureSchemas = {}; + for (const property in schema.inrelation) { + // console.log(`${property}: ${object[property]}`); + pureSchemas = { + ...pureSchemas, + [property]: schema.inrelation[property].type === "one" + ? object(schemas[schema.inrelation[property].schemaName]?.pure) + : array( + object(schemas[schema.inrelation[property].schemaName]?.pure), + ), + }; + } + return pureSchemas; + }; - if (!schema) { - throw new Error(`Schema ${schemaName} not found`); - } - return schema.pure; -}; + const getPureFromOutRel = (schemaName: string) => { + const schema = getSchema(schemaName); + let pureSchemas = {}; + for (const property in schema.outrelation) { + // console.log(`${property}: ${object[property]}`); + pureSchemas = { + ...pureSchemas, + [property]: array( + object(schemas[schema.outrelation[property].schemaName]?.pure), + ), + }; + } + return pureSchemas; + }; -export const getPureFromInRel = (schemaName: SchemasKey) => { - const schema = getSchema(schemaName); - let pureSchemas = {}; - for (const property in schema.inrelation) { - // console.log(`${property}: ${object[property]}`); - pureSchemas = { - ...pureSchemas, - [property]: schema.inrelation[property].type === "one" - ? object(schemas[schema.inrelation[property].schemaName]?.pure) - : array(object(schemas[schema.inrelation[property].schemaName]?.pure)), + const createEmbedded = (schemaName: string) => { + return { + ...getPureFromInRel(schemaName), + ...getPureFromOutRel(schemaName), }; - } - return pureSchemas; -}; + }; -export const getPureFromOutRel = (schemaName: SchemasKey) => { - const schema = getSchema(schemaName); - let pureSchemas = {}; - for (const property in schema.outrelation) { - // console.log(`${property}: ${object[property]}`); - pureSchemas = { - ...pureSchemas, - [property]: array( - object(schemas[schema.outrelation[property].schemaName]?.pure), - ), - }; - } - return pureSchemas; -}; + const createStruct = (schemaName: string) => { + const schema = getSchema(schemaName); -export const createEmbedded = (schemaName: SchemasKey) => { - return { - ...getPureFromInRel(schemaName), - ...getPureFromOutRel(schemaName), + return assign(object(schema.pure), object(createEmbedded(schemaName))); }; -}; -export const createStruct = (schemaName: SchemasKey) => { - const schema = getSchema(schemaName); - - return assign(object(schema.pure), object(createEmbedded(schemaName))); + return { + getSchemas, + getSchema, + getPureSchema, + getPureFromInRel, + getPureFromOutRel, + createEmbedded, + createStruct, + }; }; diff --git a/src/models/selectInp.ts b/src/models/selectInp.ts index 49b51dd1..03ea7072 100644 --- a/src/models/selectInp.ts +++ b/src/models/selectInp.ts @@ -1,29 +1,28 @@ - import { number, object } from "https://deno.land/x/lestruct@v0.0.2/mod.ts"; -import { getSchema, SchemasKey } from "./mod.ts"; - +import { ISchema, schemas } from "./mod.ts"; export type Type = Record; - -const selectInp=(schema:SchemasKey)=>{ - const foundedSchema = getSchema(schema); - let returnObj : Type = {}; +const selectInp = (schema: string, schemasObj: ISchema) => { + const foundedSchema = schemas(schemasObj).getSchema(schema); + let returnObj: Type = {}; for (const property in foundedSchema.inrelation) { - returnObj=object({ + returnObj = object({ ...returnObj, - [property]: selectInp(foundedSchema.inrelation[property].schemaName)|| number - }) + [property]: + selectInp(foundedSchema.inrelation[property].schemaName, schemasObj) || + number, + }); } for (const property in foundedSchema.outrelation) { - returnObj=object({ + returnObj = object({ ...returnObj, - [property]: selectInp(foundedSchema.outrelation[property].schemaName)|| number - }) + [property]: + selectInp(foundedSchema.outrelation[property].schemaName, schemasObj) || + number, + }); } - - return returnObj -} - + return returnObj; +}; diff --git a/src/models/selectStruct.ts b/src/models/selectStruct.ts index a42f69b4..f5df9093 100644 --- a/src/models/selectStruct.ts +++ b/src/models/selectStruct.ts @@ -1,106 +1,116 @@ -import { enums, object, optional } from "https://deno.land/x/lestruct/mod.ts"; import { ObjectSchema } from "https://deno.land/x/lestruct@v0.0.2/src/utils.ts"; -import { getPureModel, getSchema, SchemasKey } from "./mod.ts"; +import { enums, object, optional } from "../deps.ts"; +import { ISchema } from "./mod.ts"; +import { pureFns } from "./pure.ts"; +import { schemaFns } from "./schema.ts"; export type Iterate = Record; -export const fieldType = optional(enums([0, 1])); +export const selectStructFns = (schemasObj: ISchema) => { + const fieldType = optional(enums([0, 1])); -export const decreaseIterate = (depth: Iterate) => { - for (const key in depth) { - // comments recursive becuase of decrease just first level and proccess every level on its fns - // typeof depth[key] === "number" ? depth[key]-- : decreaseIterate(depth[key]); + const decreaseIterate = (depth: Iterate) => { + for (const key in depth) { + // comments recursive becuase of decrease just first level and proccess every level on its fns + // typeof depth[key] === "number" ? depth[key]-- : decreaseIterate(depth[key]); - (typeof depth[key] === "number") && depth[key]--; - } - return depth; -}; + (typeof depth[key] === "number") && depth[key]--; + } + return depth; + }; -type CheckRelation = (depth: Iterate, relation: string) => boolean; -export const checkRelation: CheckRelation = (depth, relation) => - depth && (typeof depth[relation] === "object" || depth[relation] > -1); + type CheckRelation = (depth: Iterate, relation: string) => boolean; + const checkRelation: CheckRelation = (depth, relation) => + depth && (typeof depth[relation] === "object" || depth[relation] > -1); -export const selectStruct = ( - schema: SchemasKey, - depth: number | T = 2, -): any => { - const pureSchema = getPureModel(schema); - let returnObj = {}; - for (const property in pureSchema) { - // console.log(`${property}: ${object[property]}`); - returnObj = { - ...returnObj, - [property]: fieldType, - }; - } - - const iterateRelation = ( - schema: SchemasKey, - depth: number, - pureObj: Record, - ) => { - let returnObj = { ...pureObj }; - const foundedSchema = getSchema(schema); - for (const property in foundedSchema.inrelation) { + const selectStruct = ( + schema: string, + depth: number | T = 2, + ): any => { + const pureSchema = pureFns(schemasObj).getPureModel(schema); + let returnObj = {}; + for (const property in pureSchema) { + // console.log(`${property}: ${object[property]}`); returnObj = { ...returnObj, - [property]: selectStruct( - foundedSchema.inrelation[property].schemaName, - depth, - ), + [property]: fieldType, }; } - for (const property in foundedSchema.outrelation) { - returnObj = { - ...returnObj, - [property]: selectStruct( - foundedSchema.outrelation[property].schemaName, - depth, - ), - }; - } - - return optional(object(returnObj as ObjectSchema)); - }; - - const numberDepth = (depth: number, pureObj: Record) => { - depth--; - return depth > -1 - ? iterateRelation(schema, depth, pureObj) - : optional(object(pureObj)); - }; - const objectDepth = (depth: any, pureObj: Record) => { - depth = decreaseIterate(depth); - - const foundedSchema = getSchema(schema); - for (const property in foundedSchema.inrelation) { - checkRelation(depth, property) && - (pureObj = { - ...pureObj, + const iterateRelation = ( + schema: string, + depth: number, + pureObj: Record, + ) => { + let returnObj = { ...pureObj }; + const foundedSchema = schemaFns(schemasObj).getSchema(schema); + for (const property in foundedSchema.inrelation) { + returnObj = { + ...returnObj, [property]: selectStruct( foundedSchema.inrelation[property].schemaName, - depth[property], + depth, ), - }); - } - for (const property in foundedSchema.outrelation) { - checkRelation(depth, property) && - (pureObj = { - ...pureObj, + }; + } + for (const property in foundedSchema.outrelation) { + returnObj = { + ...returnObj, [property]: selectStruct( foundedSchema.outrelation[property].schemaName, - depth[property], + depth, ), - }); - } + }; + } - return optional(object(pureObj)); - }; + return optional(object(returnObj as ObjectSchema)); + }; + + const numberDepth = (depth: number, pureObj: Record) => { + depth--; + return depth > -1 + ? iterateRelation(schema, depth, pureObj) + : optional(object(pureObj)); + }; - const completeObj = typeof depth === "number" - ? numberDepth(depth, returnObj) - : objectDepth(depth, returnObj); + const objectDepth = (depth: any, pureObj: Record) => { + depth = decreaseIterate(depth); - return completeObj; + const foundedSchema = schemaFns(schemasObj).getSchema(schema); + for (const property in foundedSchema.inrelation) { + checkRelation(depth, property) && + (pureObj = { + ...pureObj, + [property]: selectStruct( + foundedSchema.inrelation[property].schemaName, + depth[property], + ), + }); + } + for (const property in foundedSchema.outrelation) { + checkRelation(depth, property) && + (pureObj = { + ...pureObj, + [property]: selectStruct( + foundedSchema.outrelation[property].schemaName, + depth[property], + ), + }); + } + + return optional(object(pureObj)); + }; + + const completeObj = typeof depth === "number" + ? numberDepth(depth, returnObj) + : objectDepth(depth, returnObj); + + return completeObj; + }; + return { + fieldType, + decreaseIterate, + checkRelation, + selectStruct, + }; }; diff --git a/src/models/types.ts b/src/models/types.ts index b9d33f04..f6eaf112 100644 --- a/src/models/types.ts +++ b/src/models/types.ts @@ -1,17 +1,16 @@ -import { Struct } from "https://deno.land/x/lestruct/mod.ts"; -import { SchemasKey } from "./mod.ts"; +import { Struct } from "../deps.ts"; export interface PureModel { [key: string]: Struct; } export interface InRelation { - schemaName: SchemasKey; + schemaName: string; type: "one" | "many"; } export interface OutRelation { - schemaName: SchemasKey; + schemaName: string; number: number; sort: { field: string; order: "asc" | "desc" }; } diff --git a/src/odm/mod.ts b/src/odm/mod.ts index 95ebcde4..dda95399 100644 --- a/src/odm/mod.ts +++ b/src/odm/mod.ts @@ -1,44 +1,52 @@ import { Bson, Database } from "../deps.ts"; -import { SchemasKey } from "../mod.ts"; -let mongoDb: Database; +export const odm = () => { + let mongoDb: Database; + const setDb = (db: Database) => mongoDb = db; -export const setDb = (db: Database) => mongoDb = db; + const getDbClinet = () => mongoDb; -export const getDbClinet = () => mongoDb; + const findData = async ( + collection: string, + query: Bson.Document, + ) => { + const db = getDbClinet(); + const result = await db.collection(collection).find(query).toArray(); + return result; + }; -export const findData = async ( - collection: SchemasKey, - query: Bson.Document, -) => { - const db = getDbClinet(); - const result = await db.collection(collection).find(query).toArray(); - return result; -}; + const createData = async ( + collection: string, + query: Bson.Document, + ) => { + const db = getDbClinet(); + const result = await db.collection(collection).find(query).toArray(); + return result; + }; -export const createData = async ( - collection: SchemasKey, - query: Bson.Document, -) => { - const db = getDbClinet(); - const result = await db.collection(collection).find(query).toArray(); - return result; -}; + const updateData = async ( + collection: string, + query: Bson.Document, + ) => { + const db = getDbClinet(); + const result = await db.collection(collection).find(query).toArray(); + return result; + }; -export const updateData = async ( - collection: SchemasKey, - query: Bson.Document, -) => { - const db = getDbClinet(); - const result = await db.collection(collection).find(query).toArray(); - return result; -}; + const deleteData = async ( + collection: string, + query: Bson.Document, + ) => { + const db = getDbClinet(); + const result = await db.collection(collection).find(query).toArray(); + return result; + }; -export const deleteData = async ( - collection: SchemasKey, - query: Bson.Document, -) => { - const db = getDbClinet(); - const result = await db.collection(collection).find(query).toArray(); - return result; + return { + setDb, + findData, + createData, + updateData, + deleteData, + }; }; diff --git a/src/server/mod.ts b/src/server/mod.ts index 7609f3fa..5f989bf4 100644 --- a/src/server/mod.ts +++ b/src/server/mod.ts @@ -1,37 +1,47 @@ import { serve } from "https://deno.land/std@0.128.0/http/server.ts"; +import { Services } from "../acts/mod.ts"; import { Database } from "../deps.ts"; -import { setDb } from "../mod.ts"; -import { serveLesan } from "../utils/mod.ts"; +import { ISchema } from "../models/mod.ts"; +import { odm } from "../odm/mod.ts"; +import { generateSchemTypes } from "../types/mod.ts"; +import { lesanFns } from "../utils/mod.ts"; import { runPlayground } from "./playground/mod.ts"; -export const runServer = async ( - { port, playground, db }: { - port: number; - playground: boolean; - db: Database; - }, -) => { - setDb(db); - const handler = async (request: Request): Promise => { - try { - // return request.method === "GET" - // ? await serveStatic(request) - // : await serveLesan(request); - return await serveLesan(request, port); - } catch (e) { - return new Response( - `Somthing has wrong =>> :: ${ - e.message || - "we do not know anything !!! sorry" - }`, - { status: 501 }, - ); - } - }; +const setDb = odm().setDb; + +export const lesanServer = (schemasObj: ISchema, actsObj: Services) => { + const runServer = async ( + { port, playground, db, typeGeneration }: { + port: number; + playground: boolean; + db: Database; + typeGeneration: boolean; + }, + ) => { + setDb(db); + typeGeneration && await generateSchemTypes(schemasObj); + const handler = async (request: Request): Promise => { + try { + // return request.method === "GET" + // ? await serveStatic(request) + // : await serveLesan(request); + return await lesanFns(actsObj).serveLesan(request, port); + } catch (e) { + return new Response( + `Somthing has wrong =>> :: ${ + e.message || + "we do not know anything !!! sorry" + }`, + { status: 501 }, + ); + } + }; - console.log( - `HTTP webserver running. Access it at: http://localhost:${port}/`, - ); - await serve(handler, { port }); - playground && runPlayground(); + console.log( + `HTTP webserver running. Access it at: http://localhost:${port}/`, + ); + await serve(handler, { port }); + playground && runPlayground(); + }; + return runServer; }; diff --git a/src/types/mod.ts b/src/types/mod.ts index 8b84d7fd..9c637344 100644 --- a/src/types/mod.ts +++ b/src/types/mod.ts @@ -1,7 +1,8 @@ -import { getSchemas } from "../mod.ts"; +import { ensureDir } from "../mod.ts"; +import { ISchema, schemas as schemaFns } from "../models/mod.ts"; -export const generateSchemTypes = () => { - const schemas = getSchemas(); +export const generateSchemTypes = async (schemasObj: ISchema) => { + const schemas = schemaFns(schemasObj).getSchemas(); let str = ""; @@ -25,5 +26,6 @@ export const generateSchemTypes = () => { } `; } - Deno.writeTextFileSync("./schemas.ts", str); + await ensureDir("./declarations"); + await Deno.writeTextFile("./declarations/selectInp.ts", str); }; diff --git a/src/utils/checkWants.ts b/src/utils/checkWants.ts index 490c31d7..c367247c 100644 --- a/src/utils/checkWants.ts +++ b/src/utils/checkWants.ts @@ -1,4 +1,3 @@ -import { ServiceKeys } from "../mod.ts"; import { throwError } from "./mod.ts"; export interface Details { @@ -7,7 +6,7 @@ export interface Details { } export interface Body { - service?: ServiceKeys; + service?: string; contents: "dynamic" | "static"; wants: { model: string; diff --git a/src/utils/serveLesan.ts b/src/utils/serveLesan.ts index 40ff2d18..d51d586c 100644 --- a/src/utils/serveLesan.ts +++ b/src/utils/serveLesan.ts @@ -1,99 +1,109 @@ -import { assert, enums } from "https://deno.land/x/lestruct/mod.ts"; -import { - getAct, - getActsKeys, - getDynamicKeys, - getService, - getServiceKeys, - getStaticKeys, -} from "../mod.ts"; +import { acts, Services } from "../acts/mod.ts"; +import { assert, enums } from "../deps.ts"; import { Body, parsBody } from "./mod.ts"; -export const runAct = async (body: Body) => { - const bodyService = body.service || "main"; - const act = getAct( - bodyService, - body.contents, - body.wants.model, - body.wants.act, - ); - assert(body.details, act.validator); +export const lesanFns = (actsObj: Services) => { + const runAct = async (body: Body) => { + const bodyService = body.service || "main"; + const act = acts(actsObj).getAct( + bodyService, + body.contents, + body.wants.model, + body.wants.act, + ); + assert(body.details, act.validator); - return await act.fn(body); -}; - -const checkActs = async (body: Body) => { - const bodyService = body.service || "main"; - const actKeys = getActsKeys(bodyService, body.contents, body.wants.model); - const acts = enums(actKeys); - assert(body.wants.act, acts); + return await act.fn(body); + }; - return await runAct(body); -}; + const checkActs = async (body: Body) => { + const bodyService = body.service || "main"; + const actKeys = acts(actsObj).getActsKeys( + bodyService, + body.contents, + body.wants.model, + ); + const getedActs = enums(actKeys); + assert(body.wants.act, getedActs); -const checkModels = async (body: Body) => { - const bodyService = body.service || "main"; - const models = body.contents === "static" - ? enums(getStaticKeys(bodyService)) - : enums(getDynamicKeys(bodyService)); - assert(body.wants.model, models); + return await runAct(body); + }; - return await checkActs(body); -}; + const checkModels = async (body: Body) => { + const bodyService = body.service || "main"; + const models = body.contents === "static" + ? enums(acts(actsObj).getStaticKeys(bodyService)) + : enums(acts(actsObj).getDynamicKeys(bodyService)); + assert(body.wants.model, models); -const checkContetType = async (body: Body) => { - const content = enums(["dynamic", "static"]); - assert(body.contents, content); + return await checkActs(body); + }; - return await checkModels(body); -}; + const checkContetType = async (body: Body) => { + const content = enums(["dynamic", "static"]); + assert(body.contents, content); -async function postData(url = "", body: Body, headers = {}) { - // Default options are marked with * - const response = await fetch(url, { - method: "POST", // *GET, POST, PUT, DELETE, etc. - mode: "cors", // no-cors, *cors, same-origin - cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached - credentials: "same-origin", // include, *same-origin, omit - headers: { - "Content-Type": "application/json", - ...headers, - }, - redirect: "follow", // manual, *follow, error - referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url - body: JSON.stringify(body), // body data type must match "Content-Type" header - }); - return response.json(); // parses JSON response into native JavaScript objects -} + return await checkModels(body); + }; -// TODO: do not implement fetch completly it shoud be fetch data with the same req but change the req.body.service to main -const fetchService = async (headers: {}, body: Body, serviceValue: string) => { - const result = await postData( - serviceValue, - { ...body, service: "main" }, - headers, - ); - return result; -}; + async function postData(url = "", body: Body, headers = {}) { + // Default options are marked with * + const response = await fetch(url, { + method: "POST", // *GET, POST, PUT, DELETE, etc. + mode: "cors", // no-cors, *cors, same-origin + cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached + credentials: "same-origin", // include, *same-origin, omit + headers: { + "Content-Type": "application/json", + ...headers, + }, + redirect: "follow", // manual, *follow, error + referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url + body: JSON.stringify(body), // body data type must match "Content-Type" header + }); + return response.json(); // parses JSON response into native JavaScript objects + } -const checkServices = async (req: Request, port: number) => { - const body = (await parsBody(req, port)) as Body; - const serviceKeys = getServiceKeys(); - const servic = enums(serviceKeys); - const bodyService = body.service || "main"; - assert(bodyService, servic); - const serviceValue = getService(bodyService); - return typeof serviceValue === "string" - ? await fetchService(req.headers, body, serviceValue) - : await checkContetType(body); -}; + // TODO: do not implement fetch completly it shoud be fetch data with the same req but change the req.body.service to main + const fetchService = async ( + headers: {}, + body: Body, + serviceValue: string, + ) => { + const result = await postData( + serviceValue, + { ...body, service: "main" }, + headers, + ); + return result; + }; -export const serveLesan = async (req: Request, port: number) => { - const response = async () => { - return await checkServices(req, port); + const checkServices = async (req: Request, port: number) => { + const body = (await parsBody(req, port)) as Body; + const serviceKeys = acts(actsObj).getServiceKeys(); + const servic = enums(serviceKeys); + const bodyService = body.service || "main"; + assert(bodyService, servic); + const serviceValue = acts(actsObj).getService(bodyService); + return typeof serviceValue === "string" + ? await fetchService(req.headers, body, serviceValue) + : await checkContetType(body); }; - return new Response( - JSON.stringify({ body: await response(), success: true }), - ); + const serveLesan = async (req: Request, port: number) => { + const response = async () => { + return await checkServices(req, port); + }; + + return new Response( + JSON.stringify({ body: await response(), success: true }), + ); + }; + return { + runAct, + checkActs, + checkModels, + checkContetType, + serveLesan, + }; };