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