@ez4/database 0.8.0 → 0.10.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.
@@ -0,0 +1,24 @@
1
+ import { IncorrectTypeError, InvalidTypeError, TypeError } from '@ez4/common/library';
2
+ export declare class InvalidRelationsTypeError extends InvalidTypeError {
3
+ constructor(fileName?: string);
4
+ }
5
+ export declare class IncorrectRelationsTypeError extends IncorrectTypeError {
6
+ schemaType: string;
7
+ constructor(schemaType: string, fileName?: string);
8
+ }
9
+ export declare class InvalidRelationTargetError extends TypeError {
10
+ relationSource: string;
11
+ constructor(relationSource: string, fileName?: string);
12
+ }
13
+ export declare class InvalidRelationTableError extends TypeError {
14
+ relationTable: string;
15
+ constructor(relationTable: string, fileName?: string);
16
+ }
17
+ export declare class InvalidRelationColumnError extends TypeError {
18
+ relationColumn: string;
19
+ constructor(relationColumn: string, fileName?: string);
20
+ }
21
+ export declare class InvalidRelationAliasError extends TypeError {
22
+ relationAlias: string;
23
+ constructor(relationAlias: string, fileName?: string);
24
+ }
package/dist/library.cjs CHANGED
@@ -1,68 +1,98 @@
1
- "use strict";var C=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var fe=Object.prototype.hasOwnProperty;var Te=(e,t)=>{for(var r in t)C(e,r,{get:t[r],enumerable:!0})},ue=(e,t,r,a)=>{if(t&&
2
- typeof t=="object"||typeof t=="function")for(let o of be(t))!fe.call(e,o)&&o!==r&&
3
- C(e,o,{get:()=>t[o],enumerable:!(a=de(t,o))||a.enumerable});return e};var ye=e=>ue(C({},"__esModule",{value:!0}),e);var Pe={};Te(Pe,{IncompleteHandlerError:()=>k,IncompleteServiceError:()=>x,IncompleteStreamError:()=>P,
4
- IncompleteTableError:()=>g,IncorrectIndexesTypeError:()=>I,IncorrectSchemaTypeError:()=>D,
5
- IncorrectStreamTypeError:()=>E,InvalidIndexReferenceError:()=>h,InvalidIndexTypeError:()=>M,
6
- InvalidIndexesTypeError:()=>S,InvalidSchemaTypeError:()=>v,InvalidStreamTypeError:()=>j,
7
- ServiceType:()=>A,getDatabaseServices:()=>V,getDatabaseTable:()=>F,getTableSchema:()=>R,
8
- isDatabaseService:()=>xe,registerTriggers:()=>De});module.exports=ye(Pe);var me=require("@ez4/common/library"),le=require("@ez4/schema/library"),ce=require("@ez4/project/library");var l=require("@ez4/common/library"),se=require("@ez4/reflection");var A="@ez4/database",xe=e=>e.type===A;var U=require("@ez4/common/library"),x=class extends U.IncompleteTypeError{constructor(t,r){
9
- super("Incomplete database service",t,r)}};var p=require("@ez4/common/library"),w=require("@ez4/reflection"),z=e=>(0,p.isClassDeclaration)(
10
- e)&&(0,p.hasHeritageType)(e,"Database.Service"),_=e=>(0,p.isModelDeclaration)(e)&&
11
- (0,p.hasHeritageType)(e,"Database.Table"),q=e=>(0,w.isTypeCallback)(e)||(0,w.isTypeFunction)(
12
- e),B=e=>(0,p.hasHeritageType)(e,"Database.Indexes"),G=e=>(0,p.hasHeritageType)(e,
13
- "Database.Schema"),J=e=>(0,p.hasHeritageType)(e,"Database.Stream");var u=require("@ez4/common/library"),y=require("@ez4/reflection");var K=require("@ez4/common/library"),g=class extends K.IncompleteTypeError{constructor(t,r){
14
- super("Incomplete database table",t,r)}};var d=require("@ez4/common/library"),S=class extends d.InvalidTypeError{constructor(t){
15
- super("Invalid table indexes type",void 0,"Database.Indexes",t)}},I=class extends d.IncorrectTypeError{constructor(r,a){
16
- super("Incorrect table indexes type",r,"Database.Indexes",a);this.schemaType=r}},
17
- M=class extends d.TypeError{constructor(r,a){super(`Invalid index type, ${r} mus\
18
- t follow one of the Index options.`,a);this.indexName=r}},h=class extends d.TypeError{constructor(r,a){
19
- super(`Invalid index reference, ${r} must be valid column.`,a);this.indexName=r}};var N=require("@ez4/reflection"),W=require("@ez4/common/library"),H=require("@ez4/schema/library");var O=require("@ez4/common/library"),v=class extends O.InvalidTypeError{constructor(t){
20
- super("Invalid table schema type",void 0,"Database.Schema",t)}},D=class extends O.IncorrectTypeError{constructor(r,a){
21
- super("Incorrect table schema type",r,"Database.Schema",a);this.schemaType=r}};var R=(e,t,r,a)=>{if(!(0,N.isTypeReference)(e))return Q(e,t,r,a);let o=r[e.path];
22
- return o?Q(o,t,r,a):null},Q=(e,t,r,a)=>(0,N.isTypeObject)(e)?(0,H.getObjectSchema)(
23
- e,r):(0,W.isModelDeclaration)(e)?G(e)?(0,H.getObjectSchema)(e,r):(a.push(new D(e.
24
- name,e.file)),null):(a.push(new v(t.file)),null);var c=require("@ez4/common/library"),b=require("@ez4/reflection");var Z=(e,t,r,a)=>{if(!(0,b.isTypeReference)(e))return X(e,t,a);let o=r[e.path];return o?
25
- X(o,t,a):null},X=(e,t,r)=>(0,b.isTypeObject)(e)?Y(e,(0,c.getObjectMembers)(e),r):
26
- (0,c.isModelDeclaration)(e)?B(e)?Y(e,(0,c.getModelMembers)(e),r):(r.push(new I(e.
27
- name,e.file)),null):(r.push(new S(t.file)),null),Y=(e,t,r)=>{let a={};for(let o of t){
28
- if(!(0,b.isModelProperty)(o)||o.inherited)continue;let s=o.name,i=(0,c.getPropertyString)(
29
- o);switch(i){case"primary":case"secondary":case"ttl":a[s]=i;break;default:return r.
30
- push(new M(s,e.file)),null}}return a};var m=require("@ez4/common/library"),T=require("@ez4/reflection");var f=require("@ez4/common/library"),P=class extends f.IncompleteTypeError{constructor(t,r){
31
- super("Incomplete table stream",t,r)}},j=class extends f.InvalidTypeError{constructor(t){
32
- super("Invalid table stream type",void 0,"Database.Stream",t)}},E=class extends f.IncorrectTypeError{constructor(r,a){
33
- super("Incorrect table stream type",r,"Database.Stream",a);this.streamType=r}};var L=require("@ez4/common/library"),k=class extends L.IncompleteTypeError{constructor(t,r){
34
- super("Incomplete stream handler",t,r)}};var ee=(e,t,r)=>{if(!q(e))return null;let a={},o=new Set(["name","file","change"]);
35
- return e.description&&(a.description=e.description),(a.name=e.name)&&o.delete("n\
36
- ame"),(a.file=e.file)&&o.delete("file"),e.parameters&&o.delete("change"),o.size===
37
- 0&&ge(a)?a:(r.push(new k([...o],e.file)),null)},ge=e=>!!e.name&&!!e.file;var ae=(e,t,r,a)=>{if(!(0,T.isTypeReference)(e))return re(e,t,r,a);let o=r[e.path];
38
- return o?re(o,t,r,a):null},Se=e=>!!e.handler,re=(e,t,r,a)=>(0,T.isTypeObject)(e)?
39
- te(e,(0,m.getObjectMembers)(e),r,a):(0,m.isModelDeclaration)(e)?J(e)?te(e,(0,m.getModelMembers)(
40
- e),r,a):(a.push(new E(e.name,e.file)),null):(a.push(new j(t.file)),null),te=(e,t,r,a)=>{
41
- let o={},s=new Set(["handler"]);for(let i of t)if(!(!(0,T.isModelProperty)(i)||i.
42
- inherited))switch(i.name){case"handler":o.handler=ee(i.value,r,a);break;case"tim\
43
- eout":case"memory":{let n=(0,m.getPropertyNumber)(i);n!=null&&(o[i.name]=n);break}case"\
44
- variables":o.variables=(0,m.getLinkedVariableList)(i,a);break}return Se(o)?o:(a.
45
- push(new P([...s],e.file)),null)};var F=(e,t,r)=>{if(!(0,y.isTypeReference)(e))return oe(e,t,r);let a=t[e.path];return a?
46
- oe(a,t,r):null},Ie=e=>!!e.name&&!!e.schema&&!!e.indexes,oe=(e,t,r)=>_(e)?ne(e,(0,u.getModelMembers)(
47
- e),t,r):(0,y.isTypeObject)(e)?ne(e,(0,u.getObjectMembers)(e),t,r):null,ne=(e,t,r,a)=>{
48
- let o={},s=new Set(["name","schema","indexes"]);for(let n of t)if(!(!(0,y.isModelProperty)(
49
- n)||n.inherited))switch(n.name){case"name":(o.name=(0,u.getPropertyString)(n))&&
50
- s.delete(n.name);break;case"indexes":{(o.indexes=Z(n.value,e,r,a))&&s.delete(n.name);
51
- break}case"schema":{(o.schema=R(n.value,e,r,a))&&s.delete(n.name);break}case"str\
52
- eam":{o.stream=ae(n.value,e,r,a);break}}if(!Ie(o))return a.push(new g([...s],e.file)),
53
- null;let i=Me(e,o.indexes,o.schema);return i.length?(a.push(...i),null):o},Me=(e,t,r)=>{
54
- let a=r.properties,o=[];for(let s in t)for(let i of s.split(":"))a[i]||o.push(new h(
55
- s,e.file));return o};var V=e=>{let t={},r=[];for(let a in e){let o=e[a];if(!z(o))continue;let s={type:A},
56
- i=new Set(["engine","tables"]);s.name=o.name;for(let n of(0,l.getModelMembers)(o))
57
- if(!(!(0,se.isModelProperty)(n)||n.inherited))switch(n.name){case"engine":{let $=(0,l.getPropertyString)(
58
- n);$&&(s[n.name]=$,i.delete(n.name));break}case"tables":(s.tables=ve(n,e,r))&&i.
59
- delete(n.name);break;case"variables":s.variables=(0,l.getLinkedVariableList)(n,r);
60
- break;case"services":s.services=(0,l.getLinkedServiceList)(n,e,r);break}if(!he(s)){
61
- r.push(new x([...i],o.file));continue}t[o.name]=s}return{services:t,errors:r}},he=e=>!!e.
62
- name&&!!e.tables,ve=(e,t,r)=>{let a=(0,l.getPropertyTuple)(e)??[],o=[];for(let s of a){
63
- let i=F(s,t,r);i&&o.push(i)}return o};var ie=e=>z(e)?e.name:null;var pe=!1,De=()=>{pe||((0,me.registerTriggers)(),(0,le.registerTriggers)(),(0,ce.createTrigger)(
64
- "@ez4/database",{"metadata:getServices":V,"metadata:getLinkedService":ie}),pe=!0)};0&&(module.exports={IncompleteHandlerError,IncompleteServiceError,IncompleteStreamError,
65
- IncompleteTableError,IncorrectIndexesTypeError,IncorrectSchemaTypeError,IncorrectStreamTypeError,
66
- InvalidIndexReferenceError,InvalidIndexTypeError,InvalidIndexesTypeError,InvalidSchemaTypeError,
67
- InvalidStreamTypeError,ServiceType,getDatabaseServices,getDatabaseTable,getTableSchema,
68
- isDatabaseService,registerTriggers});
1
+ "use strict";var X=Object.defineProperty;var ze=Object.getOwnPropertyDescriptor;var Ce=Object.getOwnPropertyNames;var Ne=Object.prototype.hasOwnProperty;var He=(e,t)=>{for(var r in t)X(e,r,{get:t[r],enumerable:!0})},$e=(e,t,r,o)=>{if(t&&
2
+ typeof t=="object"||typeof t=="function")for(let s of Ce(t))!Ne.call(e,s)&&s!==r&&
3
+ X(e,s,{get:()=>t[s],enumerable:!(o=ze(t,s))||o.enumerable});return e};var qe=e=>$e(X({},"__esModule",{value:!0}),e);var Xe={};He(Xe,{IncompleteHandlerError:()=>F,IncompleteServiceError:()=>w,IncompleteStreamError:()=>H,
4
+ IncompleteTableError:()=>O,IncorrectIndexesTypeError:()=>k,IncorrectRelationsTypeError:()=>v,
5
+ IncorrectSchemaTypeError:()=>N,IncorrectStreamTypeError:()=>q,InvalidIndexReferenceError:()=>z,
6
+ InvalidIndexTypeError:()=>R,InvalidIndexesTypeError:()=>A,InvalidRelationAliasError:()=>E,
7
+ InvalidRelationColumnError:()=>f,InvalidRelationTableError:()=>j,InvalidRelationTargetError:()=>P,
8
+ InvalidRelationsTypeError:()=>D,InvalidSchemaTypeError:()=>C,InvalidStreamTypeError:()=>$,
9
+ ServiceType:()=>U,getDatabaseServices:()=>L,getDatabaseTable:()=>Z,getTableSchema:()=>Y,
10
+ isDatabaseService:()=>Fe,registerTriggers:()=>We});module.exports=qe(Xe);var Oe=require("@ez4/common/library"),Ae=require("@ez4/schema/library"),ke=require("@ez4/project/library");var l=require("@ez4/common/library"),je=require("@ez4/reflection");var u=require("@ez4/common/library"),D=class extends u.InvalidTypeError{constructor(t){
11
+ super("Invalid table relations type",void 0,"Database.Relations",t)}},v=class extends u.IncorrectTypeError{constructor(r,o){
12
+ super("Incorrect table relations type",r,"Database.Relations",o);this.schemaType=
13
+ r}},P=class extends u.TypeError{constructor(r,o){super(`Target ${r} must follow \
14
+ the pattern 'column@alias'.`,o);this.relationSource=r}},j=class extends u.TypeError{constructor(r,o){
15
+ super(`Relation table ${r} don't exists.`,o);this.relationTable=r}},f=class extends u.TypeError{constructor(r,o){
16
+ super(`Relation column ${r} don't exists.`,o);this.relationColumn=r}},E=class extends u.TypeError{constructor(r,o){
17
+ super(`Relation alias ${r} can't override table columns.`,o);this.relationAlias=
18
+ r}};var U="@ez4/database",Fe=e=>e.type===U;var re=require("@ez4/common/library"),w=class extends re.IncompleteTypeError{constructor(t,r){
19
+ super("Incomplete database service",t,r)}};var m=require("@ez4/common/library"),V=require("@ez4/reflection"),_=e=>(0,m.isClassDeclaration)(
20
+ e)&&(0,m.hasHeritageType)(e,"Database.Service"),te=e=>(0,m.isModelDeclaration)(e)&&
21
+ (0,m.hasHeritageType)(e,"Database.Table"),oe=e=>(0,V.isTypeCallback)(e)||(0,V.isTypeFunction)(
22
+ e),se=e=>(0,m.hasHeritageType)(e,"Database.Relations"),ae=e=>(0,m.hasHeritageType)(
23
+ e,"Database.Indexes"),ne=e=>(0,m.hasHeritageType)(e,"Database.Schema"),ie=e=>(0,m.hasHeritageType)(
24
+ e,"Database.Stream");var I=require("@ez4/common/library"),M=require("@ez4/reflection");var pe=require("@ez4/common/library"),O=class extends pe.IncompleteTypeError{constructor(t,r){
25
+ super("Incomplete database table",t,r)}};var T=require("@ez4/common/library"),A=class extends T.InvalidTypeError{constructor(t){
26
+ super("Invalid table indexes type",void 0,"Database.Indexes",t)}},k=class extends T.IncorrectTypeError{constructor(r,o){
27
+ super("Incorrect table indexes type",r,"Database.Indexes",o);this.schemaType=r}},
28
+ R=class extends T.TypeError{constructor(r,o){super(`Invalid index type, ${r} mus\
29
+ t follow one of the Index options.`,o);this.indexName=r}},z=class extends T.TypeError{constructor(r,o){
30
+ super(`Invalid index reference, ${r} must be valid column.`,o);this.indexName=r}};var b=require("@ez4/common/library"),y=require("@ez4/reflection");var ce=(e,t,r,o)=>{if(!(0,y.isTypeReference)(e))return le(e,t,o);let s=r[e.path];
31
+ return s?le(s,t,o):null},le=(e,t,r)=>(0,y.isTypeObject)(e)?me(e,(0,b.getObjectMembers)(
32
+ e),r):(0,b.isModelDeclaration)(e)?se(e)?me(e,(0,b.getModelMembers)(e),r):(r.push(
33
+ new v(e.name,e.file)),null):(r.push(new D(t.file)),null),me=(e,t,r)=>{let o=[];for(let s of t){
34
+ if(!(0,y.isModelProperty)(s)||s.inherited)continue;let a=(0,b.getPropertyString)(
35
+ s);if(!a)return r.push(new P(s.name,e.file)),null;let[n,i]=s.name.split(":",2),[
36
+ p,h]=a.split("@",2);o.push({sourceTable:n,sourceColumn:i,targetColumn:p,targetAlias:h})}
37
+ return o};var d=require("@ez4/common/library"),x=require("@ez4/reflection");var de=(e,t,r,o)=>{if(!(0,x.isTypeReference)(e))return ue(e,t,o);let s=r[e.path];
38
+ return s?ue(s,t,o):null},ue=(e,t,r)=>(0,x.isTypeObject)(e)?be(e,(0,d.getObjectMembers)(
39
+ e),r):(0,d.isModelDeclaration)(e)?ae(e)?be(e,(0,d.getModelMembers)(e),r):(r.push(
40
+ new k(e.name,e.file)),null):(r.push(new A(t.file)),null),be=(e,t,r)=>{let o=[];for(let s of t){
41
+ if(!(0,x.isModelProperty)(s)||s.inherited)continue;let a=s.name,n=(0,d.getPropertyString)(
42
+ s);switch(n){case"primary":case"secondary":case"unique":case"ttl":o.push({name:a,
43
+ columns:a.split(":"),type:n});break;default:return r.push(new R(a,e.file)),null}}
44
+ return o};var G=require("@ez4/schema/library"),J=require("@ez4/reflection"),ye=require("@ez4/common/library");var B=require("@ez4/common/library"),C=class extends B.InvalidTypeError{constructor(t){
45
+ super("Invalid table schema type",void 0,"Database.Schema",t)}},N=class extends B.IncorrectTypeError{constructor(r,o){
46
+ super("Incorrect table schema type",r,"Database.Schema",o);this.schemaType=r}};var Y=(e,t,r,o)=>{if(!(0,J.isTypeReference)(e))return Te(e,t,r,o);let s=r[e.path];
47
+ return s?Te(s,t,r,o):null},Te=(e,t,r,o)=>(0,J.isTypeObject)(e)?fe(e,r):(0,ye.isModelDeclaration)(
48
+ e)?ne(e)?fe(e,r):(o.push(new N(e.name,e.file)),null):(o.push(new C(t.file)),null),
49
+ fe=(e,t)=>{let r=(0,G.getObjectSchema)(e,t);return r&&(0,G.isObjectSchema)(r)?r:
50
+ null};var c=require("@ez4/common/library"),S=require("@ez4/reflection"),Me=require("@ez4/utils");var g=require("@ez4/common/library"),H=class extends g.IncompleteTypeError{constructor(t,r){
51
+ super("Incomplete table stream",t,r)}},$=class extends g.InvalidTypeError{constructor(t){
52
+ super("Invalid table stream type",void 0,"Database.Stream",t)}},q=class extends g.IncorrectTypeError{constructor(r,o){
53
+ super("Incorrect table stream type",r,"Database.Stream",o);this.streamType=r}};var xe=require("@ez4/common/library"),F=class extends xe.IncompleteTypeError{constructor(t,r){
54
+ super("Incomplete stream handler",t,r)}};var ge=(e,t,r)=>{if(!oe(e))return null;let o={},s=new Set(["name","file","change"]);
55
+ return e.description&&(o.description=e.description),(o.name=e.name)&&s.delete("n\
56
+ ame"),(o.file=e.file)&&s.delete("file"),e.parameters&&s.delete("change"),s.size===
57
+ 0&&Ue(o)?o:(r.push(new F([...s],e.file)),null)},Ue=e=>!!e.name&&!!e.file;var he=(e,t,r,o)=>{if(!(0,S.isTypeReference)(e))return Se(e,t,r,o);let s=r[e.path];
58
+ return s?Se(s,t,r,o):null},Ve=e=>!!e.handler,Se=(e,t,r,o)=>(0,S.isTypeObject)(e)?
59
+ Ie(e,(0,c.getObjectMembers)(e),r,o):(0,c.isModelDeclaration)(e)?ie(e)?Ie(e,(0,c.getModelMembers)(
60
+ e),r,o):(o.push(new q(e.name,e.file)),null):(o.push(new $(t.file)),null),Ie=(e,t,r,o)=>{
61
+ let s={},a=new Set(["handler"]);for(let n of t)if(!(!(0,S.isModelProperty)(n)||n.
62
+ inherited))switch(n.name){case"handler":s.handler=ge(n.value,r,o);break;case"tim\
63
+ eout":case"memory":{let i=(0,c.getPropertyNumber)(n);(0,Me.isAnyNumber)(i)&&(s[n.
64
+ name]=i);break}case"variables":s.variables=(0,c.getLinkedVariableList)(n,o);break}
65
+ return Ve(s)?s:(o.push(new H([...a],e.file)),null)};var Z=(e,t,r)=>{if(!(0,M.isTypeReference)(e))return De(e,t,r);let o=t[e.path];return o?
66
+ De(o,t,r):null},_e=e=>!!e.name&&!!e.schema&&!!e.indexes,De=(e,t,r)=>te(e)?ve(e,(0,I.getModelMembers)(
67
+ e),t,r):(0,M.isTypeObject)(e)?ve(e,(0,I.getObjectMembers)(e),t,r):null,ve=(e,t,r,o)=>{
68
+ let s={},a=new Set(["name","schema","indexes"]);for(let i of t)if(!(!(0,M.isModelProperty)(
69
+ i)||i.inherited))switch(i.name){case"name":(s.name=(0,I.getPropertyString)(i))&&
70
+ a.delete(i.name);break;case"relations":{let p=ce(i.value,e,r,o);p&&(s.relations=
71
+ p);break}case"indexes":{(s.indexes=de(i.value,e,r,o))&&a.delete(i.name);break}case"\
72
+ schema":{(s.schema=Y(i.value,e,r,o))&&a.delete(i.name);break}case"stream":{s.stream=
73
+ he(i.value,e,r,o);break}}if(!_e(s))return o.push(new O([...a],e.file)),null;let n=Be(
74
+ e,s.indexes,s.schema);return n.length?(o.push(...n),null):s},Be=(e,t,r)=>{let o=r.
75
+ properties,s=[];for(let{name:a,columns:n}of t)n.some(p=>!o[p])&&s.push(new z(a,e.
76
+ file));return s};var L=e=>{let t={},r=[];for(let o in e){let s=e[o];if(!_(s)||(0,l.isExternalStatement)(
77
+ s))continue;let a={type:U},n=new Set(["engine","tables"]);a.name=s.name;for(let p of(0,l.getModelMembers)(
78
+ s))if(!(!(0,je.isModelProperty)(p)||p.inherited))switch(p.name){case"engine":{(a.
79
+ engine=(0,l.getPropertyString)(p))&&n.delete(p.name);break}case"tables":(a.tables=
80
+ Je(p,e,r))&&n.delete(p.name);break;case"variables":a.variables=(0,l.getLinkedVariableList)(
81
+ p,r);break;case"services":a.services=(0,l.getLinkedServiceList)(p,e,r);break}if(!Ge(
82
+ a)){r.push(new w([...n],s.file));continue}let i=Ke(s,a.tables);if(i.length){r.push(
83
+ ...i);continue}if(t[s.name]){r.push(new l.DuplicateServiceError(s.name,s.file));
84
+ continue}t[s.name]=a}return{services:t,errors:r}},Ge=e=>!!e.name&&!!e.tables,Je=(e,t,r)=>{
85
+ let o=(0,l.getPropertyTuple)(e)??[],s=[];for(let a of o){let n=Z(a,t,r);n&&s.push(
86
+ n)}return s},Ke=(e,t)=>{let r=Qe(t),o=[];for(let{relations:s,schema:a,indexes:n}of t){
87
+ if(!s)continue;let i=a.properties;for(let p of s){let{sourceTable:h,sourceColumn:K,
88
+ targetColumn:Q,targetAlias:ee}=p;i[Q]||o.push(new f(Q,e.file)),i[ee]&&o.push(new E(
89
+ ee,e.file));let W=r[h]?.schema.properties;W||o.push(new j(h,e.file)),W&&!W[K]&&o.
90
+ push(new f(K,e.file));let Re=r[h]?.indexes??[];p.sourceIndex=Pe(Re,K),p.targetIndex=
91
+ Pe(n,Q)}}return o},Pe=(e,t)=>e.find(({name:r})=>r===t)?.type,Qe=e=>e.reduce((t,r)=>({
92
+ ...t,[r.name]:r}),{});var Ee=e=>_(e)?e.name:null;var we=!1,We=()=>{we||((0,Oe.registerTriggers)(),(0,Ae.registerTriggers)(),(0,ke.createTrigger)(
93
+ "@ez4/database",{"metadata:getServices":L,"metadata:getLinkedService":Ee}),we=!0)};0&&(module.exports={IncompleteHandlerError,IncompleteServiceError,IncompleteStreamError,
94
+ IncompleteTableError,IncorrectIndexesTypeError,IncorrectRelationsTypeError,IncorrectSchemaTypeError,
95
+ IncorrectStreamTypeError,InvalidIndexReferenceError,InvalidIndexTypeError,InvalidIndexesTypeError,
96
+ InvalidRelationAliasError,InvalidRelationColumnError,InvalidRelationTableError,InvalidRelationTargetError,
97
+ InvalidRelationsTypeError,InvalidSchemaTypeError,InvalidStreamTypeError,ServiceType,
98
+ getDatabaseServices,getDatabaseTable,getTableSchema,isDatabaseService,registerTriggers});
package/dist/library.d.ts CHANGED
@@ -5,9 +5,12 @@ export * from './metadata/schema.js';
5
5
  export * from './errors/service.js';
6
6
  export * from './errors/table.js';
7
7
  export * from './errors/schema.js';
8
+ export * from './errors/relations.js';
8
9
  export * from './errors/indexes.js';
9
10
  export * from './errors/stream.js';
10
11
  export * from './errors/handler.js';
11
12
  export * from './types/service.js';
12
- export * from './types/table.js';
13
+ export * from './types/relations.js';
14
+ export * from './types/indexes.js';
13
15
  export * from './types/schema.js';
16
+ export * from './types/table.js';
package/dist/library.mjs CHANGED
@@ -1,63 +1,92 @@
1
- import{registerTriggers as _e}from"@ez4/common/library";import{registerTriggers as qe}from"@ez4/schema/library";
2
- import{createTrigger as Be}from"@ez4/project/library";import{getLinkedServiceList as Ne,getLinkedVariableList as Ce,getPropertyString as He,
3
- getPropertyTuple as Re,getModelMembers as Fe}from"@ez4/common/library";import{isModelProperty as Ve}from"@ez4/reflection";var M="@ez4/database",Ge=e=>e.type===M;import{IncompleteTypeError as J}from"@ez4/common/library";var m=class extends J{constructor(t,r){
4
- super("Incomplete database service",t,r)}};import{hasHeritageType as p,isClassDeclaration as K,isModelDeclaration as Q}from"@ez4/common/library";
5
- import{isTypeCallback as W,isTypeFunction as X}from"@ez4/reflection";var l=e=>K(
6
- e)&&p(e,"Database.Service"),v=e=>Q(e)&&p(e,"Database.Table"),D=e=>W(e)||X(e),P=e=>p(
7
- e,"Database.Indexes"),j=e=>p(e,"Database.Schema"),E=e=>p(e,"Database.Stream");import{getModelMembers as Pe,getObjectMembers as je,getPropertyString as Ee}from"@ez4/common/library";
8
- import{isModelProperty as ke,isTypeObject as Ae,isTypeReference as we}from"@ez4/reflection";import{IncompleteTypeError as Y}from"@ez4/common/library";var c=class extends Y{constructor(t,r){
9
- super("Incomplete database table",t,r)}};import{IncorrectTypeError as Z,InvalidTypeError as L,TypeError as k}from"@ez4/common/library";
10
- var d=class extends L{constructor(t){super("Invalid table indexes type",void 0,"\
11
- Database.Indexes",t)}},b=class extends Z{constructor(r,a){super("Incorrect table\
12
- indexes type",r,"Database.Indexes",a);this.schemaType=r}},f=class extends k{constructor(r,a){
13
- super(`Invalid index type, ${r} must follow one of the Index options.`,a);this.indexName=
14
- r}},T=class extends k{constructor(r,a){super(`Invalid index reference, ${r} must\
15
- be valid column.`,a);this.indexName=r}};import{isTypeObject as te,isTypeReference as ae}from"@ez4/reflection";import{isModelDeclaration as oe}from"@ez4/common/library";
16
- import{getObjectSchema as A}from"@ez4/schema/library";import{IncorrectTypeError as ee,InvalidTypeError as re}from"@ez4/common/library";
17
- var u=class extends re{constructor(t){super("Invalid table schema type",void 0,"\
18
- Database.Schema",t)}},y=class extends ee{constructor(r,a){super("Incorrect table\
19
- schema type",r,"Database.Schema",a);this.schemaType=r}};var z=(e,t,r,a)=>{if(!ae(e))return w(e,t,r,a);let o=r[e.path];return o?w(o,t,r,a):
20
- null},w=(e,t,r,a)=>te(e)?A(e,r):oe(e)?j(e)?A(e,r):(a.push(new y(e.name,e.file)),
21
- null):(a.push(new u(t.file)),null);import{isModelDeclaration as ne,getModelMembers as se,getObjectMembers as ie,getPropertyString as pe}from"@ez4/common/library";
22
- import{isModelProperty as me,isTypeObject as le,isTypeReference as ce}from"@ez4/reflection";var C=(e,t,r,a)=>{if(!ce(e))return O(e,t,a);let o=r[e.path];return o?O(o,t,a):null},
23
- O=(e,t,r)=>le(e)?N(e,ie(e),r):ne(e)?P(e)?N(e,se(e),r):(r.push(new b(e.name,e.file)),
24
- null):(r.push(new d(t.file)),null),N=(e,t,r)=>{let a={};for(let o of t){if(!me(o)||
25
- o.inherited)continue;let s=o.name,i=pe(o);switch(i){case"primary":case"secondary":case"\
26
- ttl":a[s]=i;break;default:return r.push(new f(s,e.file)),null}}return a};import{getLinkedVariableList as ye,getModelMembers as xe,getObjectMembers as ge,
27
- getPropertyNumber as Se,isModelDeclaration as Ie}from"@ez4/common/library";import{
28
- isModelProperty as Me,isTypeObject as he,isTypeReference as ve}from"@ez4/reflection";import{IncompleteTypeError as de,IncorrectTypeError as be,InvalidTypeError as fe}from"@ez4/common/library";
29
- var x=class extends de{constructor(t,r){super("Incomplete table stream",t,r)}},g=class extends fe{constructor(t){
30
- super("Invalid table stream type",void 0,"Database.Stream",t)}},S=class extends be{constructor(r,a){
31
- super("Incorrect table stream type",r,"Database.Stream",a);this.streamType=r}};import{IncompleteTypeError as Te}from"@ez4/common/library";var I=class extends Te{constructor(t,r){
32
- super("Incomplete stream handler",t,r)}};var H=(e,t,r)=>{if(!D(e))return null;let a={},o=new Set(["name","file","change"]);
33
- return e.description&&(a.description=e.description),(a.name=e.name)&&o.delete("n\
34
- ame"),(a.file=e.file)&&o.delete("file"),e.parameters&&o.delete("change"),o.size===
35
- 0&&ue(a)?a:(r.push(new I([...o],e.file)),null)},ue=e=>!!e.name&&!!e.file;var V=(e,t,r,a)=>{if(!ve(e))return R(e,t,r,a);let o=r[e.path];return o?R(o,t,r,a):
36
- null},De=e=>!!e.handler,R=(e,t,r,a)=>he(e)?F(e,ge(e),r,a):Ie(e)?E(e)?F(e,xe(e),r,
37
- a):(a.push(new S(e.name,e.file)),null):(a.push(new g(t.file)),null),F=(e,t,r,a)=>{
38
- let o={},s=new Set(["handler"]);for(let i of t)if(!(!Me(i)||i.inherited))switch(i.
39
- name){case"handler":o.handler=H(i.value,r,a);break;case"timeout":case"memory":{let n=Se(
40
- i);n!=null&&(o[i.name]=n);break}case"variables":o.variables=ye(i,a);break}return De(
41
- o)?o:(a.push(new x([...s],e.file)),null)};var _=(e,t,r)=>{if(!we(e))return $(e,t,r);let a=t[e.path];return a?$(a,t,r):null},
42
- ze=e=>!!e.name&&!!e.schema&&!!e.indexes,$=(e,t,r)=>v(e)?U(e,Pe(e),t,r):Ae(e)?U(e,
43
- je(e),t,r):null,U=(e,t,r,a)=>{let o={},s=new Set(["name","schema","indexes"]);for(let n of t)
44
- if(!(!ke(n)||n.inherited))switch(n.name){case"name":(o.name=Ee(n))&&s.delete(n.name);
45
- break;case"indexes":{(o.indexes=C(n.value,e,r,a))&&s.delete(n.name);break}case"s\
46
- chema":{(o.schema=z(n.value,e,r,a))&&s.delete(n.name);break}case"stream":{o.stream=
47
- V(n.value,e,r,a);break}}if(!ze(o))return a.push(new c([...s],e.file)),null;let i=Oe(
48
- e,o.indexes,o.schema);return i.length?(a.push(...i),null):o},Oe=(e,t,r)=>{let a=r.
49
- properties,o=[];for(let s in t)for(let i of s.split(":"))a[i]||o.push(new T(s,e.
50
- file));return o};var q=e=>{let t={},r=[];for(let a in e){let o=e[a];if(!l(o))continue;let s={type:M},
51
- i=new Set(["engine","tables"]);s.name=o.name;for(let n of Fe(o))if(!(!Ve(n)||n.inherited))
52
- switch(n.name){case"engine":{let h=He(n);h&&(s[n.name]=h,i.delete(n.name));break}case"\
53
- tables":(s.tables=Ue(n,e,r))&&i.delete(n.name);break;case"variables":s.variables=
54
- Ce(n,r);break;case"services":s.services=Ne(n,e,r);break}if(!$e(s)){r.push(new m(
55
- [...i],o.file));continue}t[o.name]=s}return{services:t,errors:r}},$e=e=>!!e.name&&
56
- !!e.tables,Ue=(e,t,r)=>{let a=Re(e)??[],o=[];for(let s of a){let i=_(s,t,r);i&&o.
57
- push(i)}return o};var B=e=>l(e)?e.name:null;var G=!1,et=()=>{G||(_e(),qe(),Be("@ez4/database",{"metadata:getServices":q,"met\
58
- adata:getLinkedService":B}),G=!0)};export{I as IncompleteHandlerError,m as IncompleteServiceError,x as IncompleteStreamError,
59
- c as IncompleteTableError,b as IncorrectIndexesTypeError,y as IncorrectSchemaTypeError,
60
- S as IncorrectStreamTypeError,T as InvalidIndexReferenceError,f as InvalidIndexTypeError,
61
- d as InvalidIndexesTypeError,u as InvalidSchemaTypeError,g as InvalidStreamTypeError,
62
- M as ServiceType,q as getDatabaseServices,_ as getDatabaseTable,z as getTableSchema,
63
- Ge as isDatabaseService,et as registerTriggers};
1
+ import{registerTriggers as Mr}from"@ez4/common/library";import{registerTriggers as hr}from"@ez4/schema/library";
2
+ import{createTrigger as Dr}from"@ez4/project/library";import{DuplicateServiceError as mr,isExternalStatement as cr,getLinkedServiceList as ur,
3
+ getLinkedVariableList as br,getPropertyString as dr,getPropertyTuple as Tr,getModelMembers as fr}from"@ez4/common/library";
4
+ import{isModelProperty as yr}from"@ez4/reflection";import{IncorrectTypeError as me,InvalidTypeError as ce,TypeError as y}from"@ez4/common/library";
5
+ var u=class extends ce{constructor(t){super("Invalid table relations type",void 0,
6
+ "Database.Relations",t)}},b=class extends me{constructor(r,o){super("Incorrect t\
7
+ able relations type",r,"Database.Relations",o);this.schemaType=r}},d=class extends y{constructor(r,o){
8
+ super(`Target ${r} must follow the pattern 'column@alias'.`,o);this.relationSource=
9
+ r}},T=class extends y{constructor(r,o){super(`Relation table ${r} don't exists.`,
10
+ o);this.relationTable=r}},c=class extends y{constructor(r,o){super(`Relation col\
11
+ umn ${r} don't exists.`,o);this.relationColumn=r}},f=class extends y{constructor(r,o){
12
+ super(`Relation alias ${r} can't override table columns.`,o);this.relationAlias=
13
+ r}};var z="@ez4/database",jr=e=>e.type===z;import{IncompleteTypeError as ue}from"@ez4/common/library";var x=class extends ue{constructor(t,r){
14
+ super("Incomplete database service",t,r)}};import{hasHeritageType as l,isClassDeclaration as be,isModelDeclaration as de}from"@ez4/common/library";
15
+ import{isTypeCallback as Te,isTypeFunction as fe}from"@ez4/reflection";var g=e=>be(
16
+ e)&&l(e,"Database.Service"),N=e=>de(e)&&l(e,"Database.Table"),H=e=>Te(e)||fe(e),
17
+ $=e=>l(e,"Database.Relations"),q=e=>l(e,"Database.Indexes"),F=e=>l(e,"Database.S\
18
+ chema"),U=e=>l(e,"Database.Stream");import{getModelMembers as tr,getObjectMembers as or,getPropertyString as sr}from"@ez4/common/library";
19
+ import{isModelProperty as ar,isTypeObject as nr,isTypeReference as ir}from"@ez4/reflection";import{IncompleteTypeError as ye}from"@ez4/common/library";var S=class extends ye{constructor(t,r){
20
+ super("Incomplete database table",t,r)}};import{IncorrectTypeError as xe,InvalidTypeError as ge,TypeError as V}from"@ez4/common/library";
21
+ var I=class extends ge{constructor(t){super("Invalid table indexes type",void 0,
22
+ "Database.Indexes",t)}},M=class extends xe{constructor(r,o){super("Incorrect tab\
23
+ le indexes type",r,"Database.Indexes",o);this.schemaType=r}},h=class extends V{constructor(r,o){
24
+ super(`Invalid index type, ${r} must follow one of the Index options.`,o);this.indexName=
25
+ r}},D=class extends V{constructor(r,o){super(`Invalid index reference, ${r} must\
26
+ be valid column.`,o);this.indexName=r}};import{isModelDeclaration as Se,getModelMembers as Ie,getObjectMembers as Me,getPropertyString as he}from"@ez4/common/library";
27
+ import{isModelProperty as De,isTypeObject as ve,isTypeReference as Pe}from"@ez4/reflection";var G=(e,t,r,o)=>{if(!Pe(e))return _(e,t,o);let s=r[e.path];return s?_(s,t,o):null},
28
+ _=(e,t,r)=>ve(e)?B(e,Me(e),r):Se(e)?$(e)?B(e,Ie(e),r):(r.push(new b(e.name,e.file)),
29
+ null):(r.push(new u(t.file)),null),B=(e,t,r)=>{let o=[];for(let s of t){if(!De(s)||
30
+ s.inherited)continue;let a=he(s);if(!a)return r.push(new d(s.name,e.file)),null;
31
+ let[n,i]=s.name.split(":",2),[p,m]=a.split("@",2);o.push({sourceTable:n,sourceColumn:i,
32
+ targetColumn:p,targetAlias:m})}return o};import{isModelDeclaration as je,getModelMembers as Ee,getObjectMembers as we,getPropertyString as Oe}from"@ez4/common/library";
33
+ import{isModelProperty as Ae,isTypeObject as ke,isTypeReference as Re}from"@ez4/reflection";var Q=(e,t,r,o)=>{if(!Re(e))return J(e,t,o);let s=r[e.path];return s?J(s,t,o):null},
34
+ J=(e,t,r)=>ke(e)?K(e,we(e),r):je(e)?q(e)?K(e,Ee(e),r):(r.push(new M(e.name,e.file)),
35
+ null):(r.push(new I(t.file)),null),K=(e,t,r)=>{let o=[];for(let s of t){if(!Ae(s)||
36
+ s.inherited)continue;let a=s.name,n=Oe(s);switch(n){case"primary":case"secondary":case"\
37
+ unique":case"ttl":o.push({name:a,columns:a.split(":"),type:n});break;default:return r.
38
+ push(new h(a,e.file)),null}}return o};import{getObjectSchema as Ne,isObjectSchema as He}from"@ez4/schema/library";import{
39
+ isTypeObject as $e,isTypeReference as qe}from"@ez4/reflection";import{isModelDeclaration as Fe}from"@ez4/common/library";import{IncorrectTypeError as ze,InvalidTypeError as Ce}from"@ez4/common/library";
40
+ var v=class extends Ce{constructor(t){super("Invalid table schema type",void 0,"\
41
+ Database.Schema",t)}},P=class extends ze{constructor(r,o){super("Incorrect table\
42
+ schema type",r,"Database.Schema",o);this.schemaType=r}};var Y=(e,t,r,o)=>{if(!qe(e))return W(e,t,r,o);let s=r[e.path];return s?W(s,t,r,o):
43
+ null},W=(e,t,r,o)=>$e(e)?X(e,r):Fe(e)?F(e)?X(e,r):(o.push(new P(e.name,e.file)),
44
+ null):(o.push(new v(t.file)),null),X=(e,t)=>{let r=Ne(e,t);return r&&He(r)?r:null};import{getLinkedVariableList as Je,getModelMembers as Ke,getObjectMembers as Qe,
45
+ getPropertyNumber as We,isModelDeclaration as Xe}from"@ez4/common/library";import{
46
+ isModelProperty as Ye,isTypeObject as Ze,isTypeReference as Le}from"@ez4/reflection";
47
+ import{isAnyNumber as er}from"@ez4/utils";import{IncompleteTypeError as Ue,IncorrectTypeError as Ve,InvalidTypeError as _e}from"@ez4/common/library";
48
+ var j=class extends Ue{constructor(t,r){super("Incomplete table stream",t,r)}},E=class extends _e{constructor(t){
49
+ super("Invalid table stream type",void 0,"Database.Stream",t)}},w=class extends Ve{constructor(r,o){
50
+ super("Incorrect table stream type",r,"Database.Stream",o);this.streamType=r}};import{IncompleteTypeError as Be}from"@ez4/common/library";var O=class extends Be{constructor(t,r){
51
+ super("Incomplete stream handler",t,r)}};var Z=(e,t,r)=>{if(!H(e))return null;let o={},s=new Set(["name","file","change"]);
52
+ return e.description&&(o.description=e.description),(o.name=e.name)&&s.delete("n\
53
+ ame"),(o.file=e.file)&&s.delete("file"),e.parameters&&s.delete("change"),s.size===
54
+ 0&&Ge(o)?o:(r.push(new O([...s],e.file)),null)},Ge=e=>!!e.name&&!!e.file;var re=(e,t,r,o)=>{if(!Le(e))return L(e,t,r,o);let s=r[e.path];return s?L(s,t,r,
55
+ o):null},rr=e=>!!e.handler,L=(e,t,r,o)=>Ze(e)?ee(e,Qe(e),r,o):Xe(e)?U(e)?ee(e,Ke(
56
+ e),r,o):(o.push(new w(e.name,e.file)),null):(o.push(new E(t.file)),null),ee=(e,t,r,o)=>{
57
+ let s={},a=new Set(["handler"]);for(let n of t)if(!(!Ye(n)||n.inherited))switch(n.
58
+ name){case"handler":s.handler=Z(n.value,r,o);break;case"timeout":case"memory":{let i=We(
59
+ n);er(i)&&(s[n.name]=i);break}case"variables":s.variables=Je(n,o);break}return rr(
60
+ s)?s:(o.push(new j([...a],e.file)),null)};var se=(e,t,r)=>{if(!ir(e))return te(e,t,r);let o=t[e.path];return o?te(o,t,r):null},
61
+ pr=e=>!!e.name&&!!e.schema&&!!e.indexes,te=(e,t,r)=>N(e)?oe(e,tr(e),t,r):nr(e)?oe(
62
+ e,or(e),t,r):null,oe=(e,t,r,o)=>{let s={},a=new Set(["name","schema","indexes"]);
63
+ for(let i of t)if(!(!ar(i)||i.inherited))switch(i.name){case"name":(s.name=sr(i))&&
64
+ a.delete(i.name);break;case"relations":{let p=G(i.value,e,r,o);p&&(s.relations=p);
65
+ break}case"indexes":{(s.indexes=Q(i.value,e,r,o))&&a.delete(i.name);break}case"s\
66
+ chema":{(s.schema=Y(i.value,e,r,o))&&a.delete(i.name);break}case"stream":{s.stream=
67
+ re(i.value,e,r,o);break}}if(!pr(s))return o.push(new S([...a],e.file)),null;let n=lr(
68
+ e,s.indexes,s.schema);return n.length?(o.push(...n),null):s},lr=(e,t,r)=>{let o=r.
69
+ properties,s=[];for(let{name:a,columns:n}of t)n.some(p=>!o[p])&&s.push(new D(a,e.
70
+ file));return s};var ne=e=>{let t={},r=[];for(let o in e){let s=e[o];if(!g(s)||cr(s))continue;let a={
71
+ type:z},n=new Set(["engine","tables"]);a.name=s.name;for(let p of fr(s))if(!(!yr(
72
+ p)||p.inherited))switch(p.name){case"engine":{(a.engine=dr(p))&&n.delete(p.name);
73
+ break}case"tables":(a.tables=gr(p,e,r))&&n.delete(p.name);break;case"variables":
74
+ a.variables=br(p,r);break;case"services":a.services=ur(p,e,r);break}if(!xr(a)){r.
75
+ push(new x([...n],s.file));continue}let i=Sr(s,a.tables);if(i.length){r.push(...i);
76
+ continue}if(t[s.name]){r.push(new mr(s.name,s.file));continue}t[s.name]=a}return{
77
+ services:t,errors:r}},xr=e=>!!e.name&&!!e.tables,gr=(e,t,r)=>{let o=Tr(e)??[],s=[];
78
+ for(let a of o){let n=se(a,t,r);n&&s.push(n)}return s},Sr=(e,t)=>{let r=Ir(t),o=[];
79
+ for(let{relations:s,schema:a,indexes:n}of t){if(!s)continue;let i=a.properties;for(let p of s){
80
+ let{sourceTable:m,sourceColumn:A,targetColumn:k,targetAlias:C}=p;i[k]||o.push(new c(
81
+ k,e.file)),i[C]&&o.push(new f(C,e.file));let R=r[m]?.schema.properties;R||o.push(
82
+ new T(m,e.file)),R&&!R[A]&&o.push(new c(A,e.file));let le=r[m]?.indexes??[];p.sourceIndex=
83
+ ae(le,A),p.targetIndex=ae(n,k)}}return o},ae=(e,t)=>e.find(({name:r})=>r===t)?.type,
84
+ Ir=e=>e.reduce((t,r)=>({...t,[r.name]:r}),{});var ie=e=>g(e)?e.name:null;var pe=!1,Bt=()=>{pe||(Mr(),hr(),Dr("@ez4/database",{"metadata:getServices":ne,"\
85
+ metadata:getLinkedService":ie}),pe=!0)};export{O as IncompleteHandlerError,x as IncompleteServiceError,j as IncompleteStreamError,
86
+ S as IncompleteTableError,M as IncorrectIndexesTypeError,b as IncorrectRelationsTypeError,
87
+ P as IncorrectSchemaTypeError,w as IncorrectStreamTypeError,D as InvalidIndexReferenceError,
88
+ h as InvalidIndexTypeError,I as InvalidIndexesTypeError,f as InvalidRelationAliasError,
89
+ c as InvalidRelationColumnError,T as InvalidRelationTableError,d as InvalidRelationTargetError,
90
+ u as InvalidRelationsTypeError,v as InvalidSchemaTypeError,E as InvalidStreamTypeError,
91
+ z as ServiceType,ne as getDatabaseServices,se as getDatabaseTable,Y as getTableSchema,
92
+ jr as isDatabaseService,Bt as registerTriggers};
package/dist/main.cjs CHANGED
@@ -1,4 +1,5 @@
1
- "use strict";var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var y=(r,t)=>{for(var a in t)s(r,a,{get:t[a],enumerable:!0})},c=(r,t,a,e)=>{if(t&&
2
- typeof t=="object"||typeof t=="function")for(let n of i(t))!T.call(r,n)&&n!==a&&
3
- s(r,n,{get:()=>t[n],enumerable:!(e=d(t,n))||e.enumerable});return r};var I=r=>c(s({},"__esModule",{value:!0}),r);var l={};y(l,{Database:()=>x,Index:()=>m,Order:()=>o,StreamType:()=>p});module.exports=
4
- I(l);var o=(a=>(a.Asc="asc",a.Desc="desc",a))(o||{});var m=(e=>(e.Primary="primary",e.Secondary="secondary",e.TTL="ttl",e))(m||{});var p=(e=>(e.Insert="insert",e.Update="update",e.Delete="delete",e))(p||{});var x;(r=>{})(x||={});0&&(module.exports={Database,Index,Order,StreamType});
1
+ "use strict";var s=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var c=(a,t)=>{for(var r in t)s(a,r,{get:t[r],enumerable:!0})},y=(a,t,r,n)=>{if(t&&
2
+ typeof t=="object"||typeof t=="function")for(let e of i(t))!T.call(a,e)&&e!==r&&
3
+ s(a,e,{get:()=>t[e],enumerable:!(n=d(t,e))||n.enumerable});return a};var I=a=>y(s({},"__esModule",{value:!0}),a);var l={};c(l,{Database:()=>o,Index:()=>x,Order:()=>m,StreamType:()=>p});module.exports=
4
+ I(l);var p=(n=>(n.Insert="insert",n.Update="update",n.Delete="delete",n))(p||{});var o;(a=>{})(o||={});var x=(e=>(e.Primary="primary",e.Secondary="secondary",e.Unique="unique",e.TTL="\
5
+ ttl",e))(x||{});var m=(r=>(r.Asc="asc",r.Desc="desc",r))(m||{});0&&(module.exports={Database,Index,Order,StreamType});
package/dist/main.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- export * from './services/client.js';
2
- export * from './services/transaction.js';
3
- export * from './services/query.js';
4
- export * from './services/order.js';
5
- export * from './services/indexes.js';
6
- export * from './services/schemas.js';
7
1
  export * from './services/streams.js';
8
- export * from './services/database.js';
2
+ export { Client } from './services/client.js';
3
+ export { Database } from './services/database.js';
4
+ export { Transaction } from './services/transaction.js';
5
+ export { Relations } from './services/relations.js';
6
+ export { Index } from './services/indexes.js';
7
+ export { Table } from './services/table.js';
8
+ export { Query } from './services/query.js';
9
+ export { Order } from './services/order.js';
package/dist/main.mjs CHANGED
@@ -1 +1,2 @@
1
- var r=(t=>(t.Asc="asc",t.Desc="desc",t))(r||{});var a=(e=>(e.Primary="primary",e.Secondary="secondary",e.TTL="ttl",e))(a||{});var n=(e=>(e.Insert="insert",e.Update="update",e.Delete="delete",e))(n||{});var s;(o=>{})(s||={});export{s as Database,a as Index,r as Order,n as StreamType};
1
+ var o=(t=>(t.Insert="insert",t.Update="update",t.Delete="delete",t))(o||{});var r;(x=>{})(r||={});var n=(e=>(e.Primary="primary",e.Secondary="secondary",e.Unique="unique",e.TTL="\
2
+ ttl",e))(n||{});var s=(a=>(a.Asc="asc",a.Desc="desc",a))(s||{});export{r as Database,n as Index,s as Order,o as StreamType};
@@ -1,5 +1,5 @@
1
1
  import type { AllType, SourceMap, TypeModel, TypeObject } from '@ez4/reflection';
2
- import type { TableIndexes } from '../types/indexes.js';
2
+ import type { TableIndex } from '../types/indexes.js';
3
3
  type TypeParent = TypeModel | TypeObject;
4
- export declare const getTableIndexes: (type: AllType, parent: TypeParent, reflection: SourceMap, errorList: Error[]) => TableIndexes | null;
4
+ export declare const getTableIndexes: (type: AllType, parent: TypeParent, reflection: SourceMap, errorList: Error[]) => TableIndex[] | null;
5
5
  export {};
@@ -0,0 +1,5 @@
1
+ import type { AllType, SourceMap, TypeModel, TypeObject } from '@ez4/reflection';
2
+ import type { TableRelation } from '../types/relations.js';
3
+ type TypeParent = TypeModel | TypeObject;
4
+ export declare const getTableRelations: (type: AllType, parent: TypeParent, reflection: SourceMap, errorList: Error[]) => TableRelation[] | null;
5
+ export {};
@@ -2,6 +2,7 @@ import type { AllType, TypeCallback, TypeClass, TypeFunction, TypeModel } from '
2
2
  export declare const isDatabaseService: (type: AllType) => type is TypeClass;
3
3
  export declare const isDatabaseTable: (type: AllType) => type is TypeModel;
4
4
  export declare const isStreamHandler: (type: AllType) => type is TypeCallback | TypeFunction;
5
+ export declare const isTableRelations: (type: TypeModel) => boolean;
5
6
  export declare const isTableIndexes: (type: TypeModel) => boolean;
6
7
  export declare const isTableSchema: (type: TypeModel) => boolean;
7
8
  export declare const isTableStream: (type: TypeModel) => boolean;
@@ -1,12 +1,10 @@
1
- import type { Indexes, TableIndexes } from './indexes.js';
2
- import type { TableSchemas } from './schemas.js';
3
- import type { Database } from './database.js';
1
+ import type { TableClients } from './table.js';
4
2
  import type { Transaction } from './transaction.js';
5
- import type { Query } from './query.js';
3
+ import type { Database } from './database.js';
6
4
  /**
7
5
  * Database client.
8
6
  */
9
- export type Client<T extends Database.Service<any>> = ClientTables<T> & {
7
+ export type Client<T extends Database.Service<any>> = TableClients<T> & {
10
8
  /**
11
9
  * Prepare and execute the given query.
12
10
  *
@@ -22,23 +20,3 @@ export type Client<T extends Database.Service<any>> = ClientTables<T> & {
22
20
  */
23
21
  transaction<O extends Transaction.WriteOperations<T>>(operations: O): Promise<void>;
24
22
  };
25
- /**
26
- * Client tables.
27
- */
28
- export type ClientTables<T extends Database.Service<any>> = {
29
- [P in keyof TableSchemas<T>]: TableSchemas<T>[P] extends Database.Schema ? Table<TableSchemas<T>[P], P extends keyof TableIndexes<T> ? TableIndexes<T>[P] extends Indexes ? TableIndexes<T>[P] : {} : {}> : never;
30
- };
31
- /**
32
- * Client table.
33
- */
34
- export interface Table<T extends Database.Schema, I extends Indexes> {
35
- insertOne(query: Query.InsertOneInput<T>): Promise<Query.InsertOneResult>;
36
- findOne<S extends Query.SelectInput<T>>(query: Query.FindOneInput<T, S, I>): Promise<Query.FindOneResult<T, S>>;
37
- updateOne<S extends Query.SelectInput<T>>(query: Query.UpdateOneInput<T, S, I>): Promise<Query.UpdateOneResult<T, S>>;
38
- upsertOne<S extends Query.SelectInput<T>>(query: Query.UpsertOneInput<T, S, I>): Promise<Query.UpsertOneResult<T, S>>;
39
- deleteOne<S extends Query.SelectInput<T>>(query: Query.DeleteOneInput<T, S, I>): Promise<Query.DeleteOneResult<T, S>>;
40
- insertMany(query: Query.InsertManyInput<T>): Promise<Query.InsertManyResult>;
41
- findMany<S extends Query.SelectInput<T>>(query: Query.FindManyInput<T, S, I>): Promise<Query.FindManyResult<T, S>>;
42
- updateMany<S extends Query.SelectInput<T>>(query: Query.UpdateManyInput<T, S>): Promise<Query.UpdateManyResult<T, S>>;
43
- deleteMany<S extends Query.SelectInput<T>>(query: Query.DeleteManyInput<T, S>): Promise<Query.DeleteManyResult<T, S>>;
44
- }
@@ -1,9 +1,15 @@
1
1
  import type { Service } from '@ez4/common';
2
2
  import type { LinkedVariables } from '@ez4/project/library';
3
3
  import type { StreamChange } from './streams.js';
4
- import type { TableTypes } from './helpers.js';
4
+ import type { TableTypes } from './table.js';
5
5
  import type { Client } from './client.js';
6
6
  import type { Index } from './indexes.js';
7
+ /**
8
+ * Given a database service `T`, it returns all its table.
9
+ */
10
+ export type DatabaseTables<T> = T extends {
11
+ tables: infer U;
12
+ } ? U : [];
7
13
  /**
8
14
  * Provide all contracts for a self-managed database service.
9
15
  */
@@ -13,11 +19,16 @@ export declare namespace Database {
13
19
  */
14
20
  interface Schema {
15
21
  }
22
+ /**
23
+ * Table relations.
24
+ */
25
+ interface Relations {
26
+ }
16
27
  /**
17
28
  * Table indexes.
18
29
  */
19
30
  type Indexes<T extends Schema = Schema> = {
20
- [P in `${string & keyof T}:${string & keyof T}` | keyof T]?: Index;
31
+ [P in keyof T]?: Index;
21
32
  };
22
33
  /**
23
34
  * Table stream.
@@ -55,6 +66,10 @@ export declare namespace Database {
55
66
  * Table schema.
56
67
  */
57
68
  schema: T;
69
+ /**
70
+ * Table relations.
71
+ */
72
+ relations?: Relations;
58
73
  /**
59
74
  * Table indexes.
60
75
  */
@@ -1,59 +1,64 @@
1
1
  import type { ArrayRest, IsArrayEmpty } from '@ez4/utils';
2
- import type { DatabaseTables } from './helpers.js';
3
- import type { Database } from './database.js';
2
+ import type { Database, DatabaseTables } from './database.js';
4
3
  /**
5
4
  * All supported index types.
6
5
  */
7
6
  export declare const enum Index {
8
7
  Primary = "primary",
9
8
  Secondary = "secondary",
9
+ Unique = "unique",
10
10
  TTL = "ttl"
11
11
  }
12
- /**
13
- * An object containing only indexes.
14
- */
15
- export type Indexes = {
16
- [name: string]: Index;
17
- };
18
12
  /**
19
13
  * Given an index name `T`, it produces the decomposed index names.
20
14
  */
21
15
  export type DecomposeIndexName<T> = T extends `${infer L}:${infer R}` ? L | DecomposeIndexName<R> : T;
22
16
  /**
23
- * Given an index object `T`, it produces another object containing only primary indexes.
17
+ * Given an index object `T`, it produces an object containing only primary indexes.
18
+ */
19
+ export type PrimaryIndexes<T extends Database.Indexes> = {
20
+ [P in keyof T as Index.Primary extends T[P] ? P : never]: T[P];
21
+ };
22
+ /**
23
+ * Given an index object `T`, it produces an object containing only unique indexes.
24
24
  */
25
- export type PrimaryIndexes<T> = {
26
- [P in keyof T as T[P] extends Index.Primary ? P : never]: T[P];
25
+ export type UniqueIndexes<T extends Database.Indexes> = {
26
+ [P in keyof T as Index.Unique extends T[P] ? P : never]: T[P];
27
27
  };
28
28
  /**
29
- * Given an index object `T`, it produces another object containing only secondary indexes.
29
+ * Given an index object `T`, it produces an object containing only secondary indexes.
30
30
  */
31
- export type SecondaryIndexes<T> = {
32
- [P in keyof T as T[P] extends Index.Secondary ? P : never]: T[P];
31
+ export type SecondaryIndexes<T extends Database.Indexes> = {
32
+ [P in keyof T as Index.Secondary | Index.TTL extends T[P] ? P : never]: T[P];
33
33
  };
34
34
  /**
35
- * Given a database service `T`, it produces an object containing all tables with indexes.
35
+ * Given an index object `T`, it produces the primary decomposed index names.
36
+ */
37
+ export type DecomposePrimaryIndexNames<T extends Database.Indexes> = DecomposeIndexName<keyof PrimaryIndexes<T>>;
38
+ /**
39
+ * Given an index object `T`, it produces the unique decomposed index names.
36
40
  */
37
- export type TableIndexes<T extends Database.Service<any>> = MergeIndexes<DatabaseTables<T>>;
41
+ export type DecomposeUniqueIndexNames<T extends Database.Indexes> = DecomposeIndexName<keyof UniqueIndexes<T>>;
42
+ /**
43
+ * Given an index object `T`, it produces the secondary decomposed index names.
44
+ */
45
+ export type DecomposeSecondaryIndexNames<T extends Database.Indexes> = DecomposeIndexName<keyof SecondaryIndexes<T>>;
46
+ /**
47
+ * Given a database service `T`, it produces an object with all tables containing indexes.
48
+ */
49
+ export type IndexedTables<T extends Database.Service<any>> = MergeIndexes<DatabaseTables<T>>;
38
50
  /**
39
51
  * Given a list of tables with indexes `T`, it produces another object containing all the
40
- * table indexes mapped by table name.
52
+ * table indexes.
41
53
  */
42
- type MergeIndexes<T extends Database.Table[]> = IsArrayEmpty<T> extends true ? {} : TableIndex<T[0]> & MergeIndexes<ArrayRest<T>>;
54
+ type MergeIndexes<T extends Database.Table[]> = IsArrayEmpty<T> extends false ? TableIndexes<T[0]> & MergeIndexes<ArrayRest<T>> : {};
43
55
  /**
44
- * Given a database table `T`, it produces another object containing all its index names.
56
+ * Given a database table `T`, it produces an object containing all the table indexes.
45
57
  */
46
- type TableIndex<T> = T extends {
58
+ type TableIndexes<T> = T extends {
47
59
  name: infer N;
48
60
  indexes: infer I;
49
- } ? N extends string ? {
50
- [P in N]: IndexProperties<Index.Secondary, DecomposeIndexName<keyof SecondaryIndexes<I>>> | IndexProperties<Index.Primary, DecomposeIndexName<keyof PrimaryIndexes<I>>>;
51
- } : {} : {};
52
- /**
53
- * Given a union of indexes `U`, it produces another object containing the index type `T`
54
- * for each index within the union.
55
- */
56
- type IndexProperties<T extends Index, U extends string> = U extends never ? {} : {
57
- [P in U]: T;
58
- };
61
+ } ? N extends string ? I extends Database.Indexes ? {
62
+ [P in N]: I;
63
+ } : {} : {} : {};
59
64
  export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Query order.
2
+ * Query order types.
3
3
  */
4
4
  export declare const enum Order {
5
5
  Asc = "asc",
@@ -1,90 +1,94 @@
1
- import type { AnyObject, PartialProperties, PartialObject, DeepPartial } from '@ez4/utils';
2
- import type { Indexes, PrimaryIndexes } from './indexes.js';
1
+ import type { Relations } from './relations.js';
3
2
  import type { Database } from './database.js';
4
3
  import type { Order } from './order.js';
4
+ import type { DecomposeIndexName, DecomposePrimaryIndexNames, DecomposeUniqueIndexNames } from './indexes.js';
5
+ import type { AnyObject, PartialProperties, PartialObject, DeepPartial, FlatObject, IsObject, StrictType } from '@ez4/utils';
5
6
  /**
6
7
  * Query builder types.
7
8
  */
8
9
  export declare namespace Query {
9
- type InsertOneInput<T extends Database.Schema> = {
10
- data: T;
10
+ export type InsertOneInput<T extends Database.Schema, R extends Relations> = {
11
+ data: Omit<T, R['indexes']> & R['changes'];
11
12
  };
12
- type UpdateOneInput<T extends Database.Schema, S extends Database.Schema, I extends Indexes> = {
13
- select?: S;
14
- data: DeepPartial<T>;
13
+ export type UpdateOneInput<T extends Database.Schema, S extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
14
+ select?: StrictType<SelectInput<T, R>, S>;
15
+ data: DeepPartial<Omit<T, R['indexes']> & FlatObject<R['changes']>>;
15
16
  where: WhereInput<T, I>;
16
17
  };
17
- type FindOneInput<T extends Database.Schema, S extends Database.Schema, I extends Indexes> = {
18
- select: S;
18
+ export type FindOneInput<T extends Database.Schema, S extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
19
+ select: StrictType<SelectInput<T, R>, S>;
19
20
  where: WhereInput<T, I>;
20
21
  };
21
- type UpsertOneInput<T extends Database.Schema, S extends Database.Schema, I extends Indexes> = {
22
- select?: S;
23
- insert: T;
24
- update: DeepPartial<T>;
22
+ export type UpsertOneInput<T extends Database.Schema, S extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
23
+ select?: StrictType<SelectInput<T, R>, S>;
24
+ insert: Omit<T, R['indexes']> & R['changes'];
25
+ update: DeepPartial<Omit<T, R['indexes']> & FlatObject<R['changes']>>;
25
26
  where: WhereInput<T, I>;
26
27
  };
27
- type DeleteOneInput<T extends Database.Schema, S extends Database.Schema, I extends Indexes> = {
28
- select?: S;
28
+ export type DeleteOneInput<T extends Database.Schema, S extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
29
+ select?: StrictType<SelectInput<T, R>, S>;
29
30
  where: WhereInput<T, I>;
30
31
  };
31
- type InsertManyInput<T extends Database.Schema> = {
32
+ export type InsertManyInput<T extends Database.Schema> = {
32
33
  data: T[];
33
34
  };
34
- type UpdateManyInput<T extends Database.Schema, S extends Database.Schema> = {
35
- select?: S;
36
- data: DeepPartial<T>;
35
+ export type UpdateManyInput<T extends Database.Schema, S extends Database.Schema, R extends Relations> = {
36
+ select?: StrictType<SelectInput<T, R>, S>;
37
+ data: DeepPartial<Omit<T, R['indexes']> & FlatObject<R['changes']>>;
37
38
  where?: WhereInput<T>;
38
39
  limit?: number;
39
40
  };
40
- type FindManyInput<T extends Database.Schema, S extends Database.Schema, I extends Indexes> = {
41
- select: S;
41
+ export type FindManyInput<T extends Database.Schema, S extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
42
+ select: StrictType<SelectInput<T, R>, S>;
42
43
  where?: WhereInput<T>;
43
44
  order?: OrderInput<I>;
44
45
  cursor?: number | string;
45
46
  limit?: number;
46
47
  };
47
- type DeleteManyInput<T extends Database.Schema, S extends Database.Schema> = {
48
- select?: S;
48
+ export type DeleteManyInput<T extends Database.Schema, S extends Database.Schema, R extends Relations> = {
49
+ select?: StrictType<SelectInput<T, R>, S>;
49
50
  where?: WhereInput<T>;
50
51
  limit?: number;
51
52
  };
52
- type InsertOneResult = void;
53
- type UpdateOneResult<T extends Database.Schema, S extends AnyObject> = FindOneResult<T, S> | undefined;
54
- type FindOneResult<T extends Database.Schema, S extends AnyObject> = Record<T, S> | undefined;
55
- type UpsertOneResult<T extends Database.Schema, S extends AnyObject> = FindOneResult<T, S> | undefined;
56
- type DeleteOneResult<T extends Database.Schema, S extends AnyObject> = FindOneResult<T, S> | undefined;
57
- type InsertManyResult = void;
58
- type UpdateManyResult<T extends Database.Schema, S extends AnyObject> = Record<T, S>[];
59
- type FindManyResult<T extends Database.Schema, S extends AnyObject> = {
60
- records: Record<T, S>[];
53
+ export type InsertOneResult = void;
54
+ export type UpdateOneResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = Record<T, S, R> | undefined;
55
+ export type FindOneResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = Record<T, S, R> | undefined;
56
+ export type UpsertOneResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = Record<T, S, R> | undefined;
57
+ export type DeleteOneResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = Record<T, S, R> | undefined;
58
+ export type InsertManyResult = void;
59
+ export type UpdateManyResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = Record<T, S, R>[];
60
+ export type FindManyResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = {
61
+ records: Record<T, S, R>[];
61
62
  cursor?: number | string;
62
63
  };
63
- type DeleteManyResult<T extends Database.Schema, S extends AnyObject> = Record<T, S>[];
64
- type Record<T extends Database.Schema, S extends AnyObject> = PartialObject<T, S, false>;
65
- type SelectInput<T extends Database.Schema> = PartialProperties<T>;
66
- type OrderInput<I extends Indexes> = {
67
- [P in keyof I]?: Order;
64
+ export type DeleteManyResult<T extends Database.Schema, S extends AnyObject, R extends Relations> = Record<T, S, R>[];
65
+ export type Record<T extends Database.Schema, S extends AnyObject, R extends Relations> = PartialObject<T & R['selects'], S, false>;
66
+ export type SelectInput<T extends Database.Schema, R extends Relations> = PartialProperties<T & R['selects']>;
67
+ export type OrderInput<I extends Database.Indexes> = {
68
+ [P in DecomposeIndexName<keyof I>]?: Order;
68
69
  };
69
- type WhereInput<T extends Database.Schema, I extends Indexes = never> = WhereFields<T, I> & WhereNot<T, I> & WhereAnd<T, I> & WhereOr<T, I>;
70
- type WhereRequiredFields<T extends Database.Schema, I extends Indexes> = {
71
- [P in keyof PrimaryIndexes<I>]: P extends keyof T ? T[P] extends AnyObject ? WhereFields<T[P], I> : T[P] | WhereOperations<T[P]> : never;
70
+ export type WhereInput<T extends Database.Schema, I extends Database.Indexes<T> = {}> = WhereFields<T, I> & WhereNot<T, I> & WhereAnd<T, I> & WhereOr<T, I>;
71
+ export type WhereOperators = keyof (WhereNegate<any> & WhereEqual<any> & WhereGreaterThan<any> & WhereGreaterThanOrEqual<any> & WhereLessThan<any> & WhereLessThanOrEqual<any> & WhereIn<any> & WhereBetween<any> & WhereIsMissing & WhereIsNull & WhereStartsWith & WhereContains);
72
+ type WhereOperations<T> = WhereNegate<T> | WhereEqual<T> | WhereGreaterThan<T> | WhereGreaterThanOrEqual<T> | WhereLessThan<T> | WhereLessThanOrEqual<T> | WhereIn<T> | WhereBetween<T> | WhereIsMissing | WhereIsNull | WhereStartsWith | WhereContains;
73
+ type WherePrimaryFields<T extends Database.Schema, I extends Database.Indexes<T>> = {
74
+ [P in DecomposePrimaryIndexNames<I>]: P extends keyof T ? IsObject<T[P]> extends true ? WhereFields<NonNullable<T[P]>, I> : T[P] | WhereOperations<T[P]> : never;
75
+ };
76
+ type WhereUniqueFields<T extends Database.Schema, I extends Database.Indexes<T>> = {
77
+ [P in DecomposeUniqueIndexNames<I>]: P extends keyof T ? IsObject<T[P]> extends true ? WhereFields<NonNullable<T[P]>, I> : T[P] | WhereOperations<T[P]> : never;
72
78
  };
73
- type WhereOptionalFields<T extends Database.Schema, I extends Indexes> = {
74
- [P in Exclude<keyof T, I>]?: T[P] extends AnyObject ? WhereFields<T[P], I> : T[P] | WhereOperations<T[P]>;
79
+ type WhereOptionalFields<T extends Database.Schema, I extends Database.Indexes<T>, N> = {
80
+ [P in Exclude<keyof T, N>]?: IsObject<T[P]> extends true ? WhereFields<NonNullable<T[P]>, I> : T[P] | WhereOperations<T[P]>;
75
81
  };
76
- type WhereFields<T extends Database.Schema, I extends Indexes> = WhereRequiredFields<T, I> & WhereOptionalFields<T, I>;
77
- type WhereNot<T extends Database.Schema, I extends Indexes> = {
82
+ type WhereFields<T extends Database.Schema, I extends Database.Indexes<T>> = (WherePrimaryFields<T, I> & WhereOptionalFields<T, I, DecomposePrimaryIndexNames<I>>) | (WhereUniqueFields<T, I> & WhereOptionalFields<T, I, DecomposeUniqueIndexNames<I>>);
83
+ type WhereNot<T extends Database.Schema, I extends Database.Indexes<T>> = {
78
84
  NOT?: WhereInput<T, I> | WhereAnd<T, I> | WhereOr<T, I>;
79
85
  };
80
- type WhereAnd<T extends Database.Schema, I extends Indexes> = {
86
+ type WhereAnd<T extends Database.Schema, I extends Database.Indexes<T>> = {
81
87
  AND?: (WhereInput<T, I> | WhereOr<T, I> | WhereNot<T, I>)[];
82
88
  };
83
- type WhereOr<T extends Database.Schema, I extends Indexes> = {
89
+ type WhereOr<T extends Database.Schema, I extends Database.Indexes<T>> = {
84
90
  OR?: (WhereInput<T, I> | WhereAnd<T, I> | WhereNot<T, I>)[];
85
91
  };
86
- type WhereOperations<T> = WhereNegate<T> | WhereEqual<T> | WhereGreaterThan<T> | WhereGreaterThanOrEqual<T> | WhereLessThan<T> | WhereLessThanOrEqual<T> | WhereIn<T> | WhereBetween<T> | WhereIsMissing | WhereIsNull | WhereStartsWith | WhereContains;
87
- type WhereOperators = keyof (WhereNegate<any> & WhereEqual<any> & WhereGreaterThan<any> & WhereGreaterThanOrEqual<any> & WhereLessThan<any> & WhereLessThanOrEqual<any> & WhereIn<any> & WhereBetween<any> & WhereIsMissing & WhereIsNull & WhereStartsWith & WhereContains);
88
92
  type WhereNegate<T> = {
89
93
  not: T | WhereOperations<T>;
90
94
  };
@@ -121,4 +125,5 @@ export declare namespace Query {
121
125
  type WhereContains = {
122
126
  contains: string;
123
127
  };
128
+ export {};
124
129
  }
@@ -0,0 +1,87 @@
1
+ import type { AnyObject, ArrayRest, IsArrayEmpty, PropertyType, ExclusiveType } from '@ez4/utils';
2
+ import type { IndexedTables, PrimaryIndexes, UniqueIndexes } from './indexes.js';
3
+ import type { Database, DatabaseTables } from './database.js';
4
+ import type { TableSchemas } from './schemas.js';
5
+ /**
6
+ * Internal relation type.
7
+ */
8
+ export type Relations = {
9
+ indexes: string;
10
+ selects: Record<string, any>;
11
+ changes: Record<string, any>;
12
+ };
13
+ /**
14
+ * Given a relation source name `T`, it produces the source table name.
15
+ */
16
+ export type RelationSourceTable<T> = T extends `${infer U}:${string}` ? U : never;
17
+ /**
18
+ * Given a relation source name `T`, it produces the source column name.
19
+ */
20
+ export type RelationSourceColumn<T> = T extends `${string}:${infer U}` ? U : never;
21
+ /**
22
+ * Given a relation target name `T`, it produces the target column name.
23
+ */
24
+ export type RelationTargetColumn<T> = T extends `${infer U}@${string}` ? U : never;
25
+ /**
26
+ * Given a relation target name `T`, it produces the target alias name.
27
+ */
28
+ export type RelationTargetAlias<T> = T extends `${string}@${infer U}` ? U : never;
29
+ /**
30
+ * Given a database service `T`, it produces an object with all relation tables.
31
+ */
32
+ export type RelationTables<T extends Database.Service<any>> = MergeRelations<DatabaseTables<T>, TableSchemas<T>, IndexedTables<T>>;
33
+ /**
34
+ * Given a list of tables with relations `T`, it produces an object containing all the
35
+ * relation tables.
36
+ */
37
+ type MergeRelations<T extends Database.Table[], S extends Record<string, Database.Schema>, I extends Record<string, Database.Indexes>> = IsArrayEmpty<T> extends false ? TableRelation<T[0], S, I> & MergeRelations<ArrayRest<T>, S, I> : {};
38
+ /**
39
+ * Given a database table `T`, it produces an object containing all its relations.
40
+ */
41
+ type TableRelation<T, S extends Record<string, Database.Schema>, I extends Record<string, Database.Indexes>> = T extends {
42
+ name: infer N;
43
+ relations: infer R;
44
+ } ? N extends string ? R extends AnyObject ? {
45
+ [P in N]: {
46
+ indexes: keyof RelationIndexes<PropertyType<N, S>, I, R>;
47
+ changes: RequiredRelationSchemas<PropertyType<N, S>, S, I, R, true> & OptionalRelationSchemas<PropertyType<N, S>, S, I, R, true>;
48
+ selects: RequiredRelationSchemas<PropertyType<N, S>, S, I, R, false> & OptionalRelationSchemas<PropertyType<N, S>, S, I, R, false>;
49
+ };
50
+ } : {} : {} : {};
51
+ /**
52
+ * Produce an object containing only required relation schemas.
53
+ */
54
+ type RequiredRelationSchemas<T extends Database.Schema, S extends Record<string, Database.Schema>, I extends Record<string, Database.Indexes>, R extends AnyObject, E extends boolean> = {
55
+ [C in keyof R as IsOptionalRelation<C, R[C], T, I> extends true ? never : RelationTargetAlias<R[C]>]: RelationSchema<C, R[C], T, S, I, E>;
56
+ };
57
+ /**
58
+ * Produce an object containing only optional relation schemas.
59
+ */
60
+ type OptionalRelationSchemas<T extends Database.Schema, S extends Record<string, Database.Schema>, I extends Record<string, Database.Indexes>, R extends AnyObject, E extends boolean> = {
61
+ [C in keyof R as IsOptionalRelation<C, R[C], T, I> extends true ? RelationTargetAlias<R[C]> : never]?: RelationSchema<C, R[C], T, S, I, E>;
62
+ };
63
+ /**
64
+ * Produce an object containing all relation indexes.
65
+ */
66
+ type RelationIndexes<T extends Database.Schema, I extends Record<string, Database.Indexes>, R extends AnyObject> = {
67
+ [C in keyof R as IsOptionalRelation<C, R[C], T, I> extends true ? never : RelationTargetColumn<R[C]>]: never;
68
+ };
69
+ /**
70
+ * Check whether a relation is optional or not.
71
+ */
72
+ type IsOptionalRelation<C, V, T extends Database.Schema, I extends Record<string, Database.Indexes>> = RelationSourceColumn<C> extends keyof PrimaryIndexes<PropertyType<RelationSourceTable<C>, I>> ? undefined extends PropertyType<RelationTargetColumn<V>, T> ? true : false : true;
73
+ /**
74
+ * Check whether a column is primary.
75
+ */
76
+ type IsPrimaryIndex<C, I extends Record<string, Database.Indexes>> = RelationSourceColumn<C> extends keyof PrimaryIndexes<PropertyType<RelationSourceTable<C>, I>> ? true : false;
77
+ /**
78
+ * Check whether a column is unique.
79
+ */
80
+ type IsUniqueIndex<C, I extends Record<string, Database.Indexes>> = RelationSourceColumn<C> extends keyof UniqueIndexes<PropertyType<RelationSourceTable<C>, I>> ? true : false;
81
+ /**
82
+ * Produce a relation schema according to its indexation.
83
+ */
84
+ type RelationSchema<C, V, T extends Database.Schema, S extends Record<string, Database.Schema>, I extends Record<string, Database.Indexes>, E extends boolean> = IsPrimaryIndex<C, I> extends true ? E extends false ? PropertyType<RelationSourceTable<C>, S> : ExclusiveType<PropertyType<RelationSourceTable<C>, S>, {
85
+ [P in RelationTargetColumn<V>]: PropertyType<RelationTargetColumn<V>, T>;
86
+ }> : IsUniqueIndex<C, I> extends true ? E extends false ? PropertyType<RelationSourceTable<C>, S> : Omit<PropertyType<RelationSourceTable<C>, S>, RelationSourceColumn<C>> : Omit<PropertyType<RelationSourceTable<C>, S>, RelationSourceColumn<C>>[];
87
+ export {};
@@ -1,22 +1,20 @@
1
1
  import type { ArrayRest, IsArrayEmpty } from '@ez4/utils';
2
- import type { DatabaseTables } from './helpers.js';
3
- import type { Database } from './database.js';
2
+ import type { Database, DatabaseTables } from './database.js';
4
3
  /**
5
4
  * Given a database service `T`, it produces an object containing all tables with schemas.
6
5
  */
7
6
  export type TableSchemas<T extends Database.Service<any>> = MergeTables<DatabaseTables<T>>;
8
7
  /**
9
- * Given a list of tables with schema `T`, it produces an object containing all schemas
10
- * mapped by table name.
8
+ * Given a list of tables with schema `T`, it produces an object containing all schemas.
11
9
  */
12
- type MergeTables<T extends Database.Table[]> = IsArrayEmpty<T> extends true ? {} : TableSchema<T[0]> & MergeTables<ArrayRest<T>>;
10
+ type MergeTables<T extends Database.Table[]> = IsArrayEmpty<T> extends false ? TableSchema<T[0]> & MergeTables<ArrayRest<T>> : {};
13
11
  /**
14
- * Given a database table `T`, it produces an object containing the `schema`.
12
+ * Given a database table `T`, it produces an object containing the table schema.
15
13
  */
16
14
  type TableSchema<T> = T extends {
17
15
  name: infer N;
18
16
  schema: infer S;
19
- } ? N extends string ? {
17
+ } ? N extends string ? S extends Database.Schema ? {
20
18
  [P in N]: S;
21
- } : {} : {};
19
+ } : {} : {} : {};
22
20
  export {};
@@ -0,0 +1,93 @@
1
+ import type { AnyObject, ArrayRest, IsArrayEmpty, IsAny, PropertyExists } from '@ez4/utils';
2
+ import type { Relations, RelationTables } from './relations.js';
3
+ import type { IndexedTables } from './indexes.js';
4
+ import type { TableSchemas } from './schemas.js';
5
+ import type { Database } from './database.js';
6
+ import type { Query } from './query.js';
7
+ /**
8
+ * Given an array of schemas `T`, it returns an union of `Database.Table` for each schema.
9
+ */
10
+ export type TableTypes<T extends Database.Schema[]> = IsAny<T> extends true ? any : IsArrayEmpty<T> extends true ? Database.Table<Database.Schema> : Database.Table<T[0]> | TableTypes<ArrayRest<T>>;
11
+ /**
12
+ * Given an indexed table `T` and a property `P`, it returns all the indexes corresponding
13
+ * to the given property.
14
+ */
15
+ export type TableIndex<P, T extends AnyObject> = PropertyExists<P, T> extends true ? (T[P] extends Database.Indexes ? T[P] : {}) : {};
16
+ /**
17
+ * Given a table `T` and a property `P`, it returns all the relations corresponding
18
+ * to the given property.
19
+ */
20
+ export type TableRelation<P, T extends AnyObject> = PropertyExists<P, T> extends true ? T[P] extends Relations ? T[P] : {
21
+ indexes: never;
22
+ selects: {};
23
+ changes: {};
24
+ } : {
25
+ indexes: never;
26
+ selects: {};
27
+ changes: {};
28
+ };
29
+ /**
30
+ * Given a database service `T`, it returns all table clients.
31
+ */
32
+ export type TableClients<T extends Database.Service<any>> = {
33
+ [P in keyof TableSchemas<T>]: TableSchemas<T>[P] extends Database.Schema ? Table<TableSchemas<T>[P], TableIndex<P, IndexedTables<T>>, TableRelation<P, RelationTables<T>>> : never;
34
+ };
35
+ /**
36
+ * Table client.
37
+ */
38
+ export interface Table<T extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> {
39
+ /**
40
+ * Insert one record into the database.
41
+ *
42
+ * @param query Input query.
43
+ */
44
+ insertOne(query: Query.InsertOneInput<T, R>): Promise<Query.InsertOneResult>;
45
+ /**
46
+ * Find one database record.
47
+ *
48
+ * @param query Input query.
49
+ */
50
+ findOne<S extends Query.SelectInput<T, R>>(query: Query.FindOneInput<T, S, I, R>): Promise<Query.FindOneResult<T, S, R>>;
51
+ /**
52
+ * Update one database record.
53
+ *
54
+ * @param query Input query.
55
+ */
56
+ updateOne<S extends Query.SelectInput<T, R>>(query: Query.UpdateOneInput<T, S, I, R>): Promise<Query.UpdateOneResult<T, S, R>>;
57
+ /**
58
+ * Try to insert a database record, and if it already exists, perform an update instead.
59
+ *
60
+ * @param query Input query.
61
+ */
62
+ upsertOne<S extends Query.SelectInput<T, R>>(query: Query.UpsertOneInput<T, S, I, R>): Promise<Query.UpsertOneResult<T, S, R>>;
63
+ /**
64
+ * Delete one database record.
65
+ *
66
+ * @param query Input query.
67
+ */
68
+ deleteOne<S extends Query.SelectInput<T, R>>(query: Query.DeleteOneInput<T, S, I, R>): Promise<Query.DeleteOneResult<T, S, R>>;
69
+ /**
70
+ * Insert multiple records into the database.
71
+ *
72
+ * @param query Input query.
73
+ */
74
+ insertMany(query: Query.InsertManyInput<T>): Promise<Query.InsertManyResult>;
75
+ /**
76
+ * Find multiple database records.
77
+ *
78
+ * @param query Input query.
79
+ */
80
+ findMany<S extends Query.SelectInput<T, R>>(query: Query.FindManyInput<T, S, I, R>): Promise<Query.FindManyResult<T, S, R>>;
81
+ /**
82
+ * Update multiple database records.
83
+ *
84
+ * @param query Input query.
85
+ */
86
+ updateMany<S extends Query.SelectInput<T, R>>(query: Query.UpdateManyInput<T, S, R>): Promise<Query.UpdateManyResult<T, S, R>>;
87
+ /**
88
+ * Delete multiple database records.
89
+ *
90
+ * @param query Input query.
91
+ */
92
+ deleteMany<S extends Query.SelectInput<T, R>>(query: Query.DeleteManyInput<T, S, R>): Promise<Query.DeleteManyResult<T, S, R>>;
93
+ }
@@ -1,4 +1,6 @@
1
- import type { Indexes, TableIndexes } from './indexes.js';
1
+ import type { Relations, RelationTables } from './relations.js';
2
+ import type { TableIndex, TableRelation } from './table.js';
3
+ import type { IndexedTables } from './indexes.js';
2
4
  import type { TableSchemas } from './schemas.js';
3
5
  import type { Database } from './database.js';
4
6
  import type { Query } from './query.js';
@@ -11,17 +13,17 @@ export declare namespace Transaction {
11
13
  */
12
14
  export type WriteOperations<T extends Database.Service<any>> = {
13
15
  [P in keyof TableSchemas<T>]?: TableSchemas<T>[P] extends Database.Schema ? {
14
- [alias: string]: InsertOperation<TableSchemas<T>[P]> | UpdateOperation<TableSchemas<T>[P], P extends keyof TableIndexes<T> ? TableIndexes<T>[P] extends Indexes ? TableIndexes<T>[P] : never : never> | DeleteOperation<TableSchemas<T>[P], P extends keyof TableIndexes<T> ? TableIndexes<T>[P] extends Indexes ? TableIndexes<T>[P] : never : never>;
16
+ [alias: string]: InsertOperation<TableSchemas<T>[P], TableRelation<P, RelationTables<T>>> | UpdateOperation<TableSchemas<T>[P], TableIndex<P, IndexedTables<T>>, TableRelation<P, RelationTables<T>>> | DeleteOperation<TableSchemas<T>[P], TableIndex<P, IndexedTables<T>>, TableRelation<P, RelationTables<T>>>;
15
17
  } : never;
16
18
  };
17
- type InsertOperation<T extends Database.Schema> = {
18
- insert: Query.InsertOneInput<T>;
19
+ type InsertOperation<T extends Database.Schema, R extends Relations> = {
20
+ insert: Query.InsertOneInput<T, R>;
19
21
  };
20
- type UpdateOperation<T extends Database.Schema, I extends Indexes> = {
21
- update: Omit<Query.UpdateOneInput<T, Query.SelectInput<T>, I>, 'select'>;
22
+ type UpdateOperation<T extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
23
+ update: Omit<Query.UpdateOneInput<T, Query.SelectInput<T, R>, I, R>, 'select'>;
22
24
  };
23
- type DeleteOperation<T extends Database.Schema, I extends Indexes> = {
24
- delete: Omit<Query.DeleteOneInput<T, Query.SelectInput<T>, I>, 'select'>;
25
+ type DeleteOperation<T extends Database.Schema, I extends Database.Indexes<T>, R extends Relations> = {
26
+ delete: Omit<Query.DeleteOneInput<T, Query.SelectInput<T, R>, I, R>, 'select'>;
25
27
  };
26
28
  export {};
27
29
  }
@@ -1,2 +1,6 @@
1
1
  import type { Index } from '../services/indexes.js';
2
- export type TableIndexes = Record<string, Index>;
2
+ export type TableIndex = {
3
+ name: string;
4
+ columns: string[];
5
+ type: Index;
6
+ };
@@ -0,0 +1,9 @@
1
+ import type { Index } from '../services/indexes.js';
2
+ export type TableRelation = {
3
+ sourceTable: string;
4
+ sourceColumn: string;
5
+ sourceIndex?: Index;
6
+ targetColumn: string;
7
+ targetAlias: string;
8
+ targetIndex?: Index;
9
+ };
@@ -1,9 +1,11 @@
1
+ import type { TableRelation } from './relations.js';
2
+ import type { TableIndex } from './indexes.js';
1
3
  import type { TableSchema } from './schema.js';
2
- import type { TableIndexes } from './indexes.js';
3
4
  import type { TableStream } from './stream.js';
4
5
  export type DatabaseTable = {
5
6
  name: string;
6
7
  schema: TableSchema;
7
- indexes: TableIndexes;
8
+ relations?: TableRelation[];
9
+ indexes: TableIndex[];
8
10
  stream?: TableStream;
9
11
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ez4/database",
3
3
  "description": "EZ4: Components to build database services",
4
- "version": "0.8.0",
4
+ "version": "0.10.0",
5
5
  "author": "Silas B.",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -42,12 +42,12 @@
42
42
  "live:publish": "npm run test && npm publish --access public"
43
43
  },
44
44
  "peerDependencies": {
45
- "@ez4/project": "^0.8.0"
45
+ "@ez4/project": "^0.10.0"
46
46
  },
47
47
  "dependencies": {
48
- "@ez4/common": "^0.8.0",
49
- "@ez4/reflection": "^0.8.0",
50
- "@ez4/schema": "^0.8.0",
51
- "@ez4/utils": "^0.8.0"
48
+ "@ez4/common": "^0.10.0",
49
+ "@ez4/reflection": "^0.10.0",
50
+ "@ez4/schema": "^0.10.0",
51
+ "@ez4/utils": "^0.10.0"
52
52
  }
53
53
  }