@declaro/data 2.0.0-beta.9 → 2.0.0-beta.90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{LICENSE → LICENSE.md} +1 -1
- package/README.md +0 -0
- package/dist/browser/index.js +32 -0
- package/dist/browser/index.js.map +86 -0
- package/dist/node/index.cjs +11547 -0
- package/dist/node/index.cjs.map +86 -0
- package/dist/node/index.js +11526 -0
- package/dist/node/index.js.map +86 -0
- package/dist/ts/application/model-controller.d.ts +29 -0
- package/dist/ts/application/model-controller.d.ts.map +1 -0
- package/dist/ts/application/model-controller.test.d.ts +2 -0
- package/dist/ts/application/model-controller.test.d.ts.map +1 -0
- package/dist/ts/application/read-only-model-controller.d.ts +20 -0
- package/dist/ts/application/read-only-model-controller.d.ts.map +1 -0
- package/dist/ts/application/read-only-model-controller.test.d.ts +2 -0
- package/dist/ts/application/read-only-model-controller.test.d.ts.map +1 -0
- package/dist/ts/domain/events/domain-event.d.ts +41 -0
- package/dist/ts/domain/events/domain-event.d.ts.map +1 -0
- package/dist/ts/domain/events/domain-event.test.d.ts +2 -0
- package/dist/ts/domain/events/domain-event.test.d.ts.map +1 -0
- package/dist/ts/domain/events/event-types.d.ts +21 -0
- package/dist/ts/domain/events/event-types.d.ts.map +1 -0
- package/dist/ts/domain/events/mutation-event.d.ts +6 -0
- package/dist/ts/domain/events/mutation-event.d.ts.map +1 -0
- package/dist/ts/domain/events/mutation-event.test.d.ts +2 -0
- package/dist/ts/domain/events/mutation-event.test.d.ts.map +1 -0
- package/dist/ts/domain/events/query-event.d.ts +6 -0
- package/dist/ts/domain/events/query-event.d.ts.map +1 -0
- package/dist/ts/domain/events/query-event.test.d.ts +2 -0
- package/dist/ts/domain/events/query-event.test.d.ts.map +1 -0
- package/dist/ts/domain/events/request-event.d.ts +11 -0
- package/dist/ts/domain/events/request-event.d.ts.map +1 -0
- package/dist/ts/domain/events/request-event.test.d.ts +2 -0
- package/dist/ts/domain/events/request-event.test.d.ts.map +1 -0
- package/dist/ts/domain/interfaces/repository.d.ts +84 -0
- package/dist/ts/domain/interfaces/repository.d.ts.map +1 -0
- package/dist/ts/domain/models/pagination.d.ts +28 -0
- package/dist/ts/domain/models/pagination.d.ts.map +1 -0
- package/dist/ts/domain/services/base-model-service.d.ts +22 -0
- package/dist/ts/domain/services/base-model-service.d.ts.map +1 -0
- package/dist/ts/domain/services/model-service-args.d.ts +9 -0
- package/dist/ts/domain/services/model-service-args.d.ts.map +1 -0
- package/dist/ts/domain/services/model-service.d.ts +42 -0
- package/dist/ts/domain/services/model-service.d.ts.map +1 -0
- package/dist/ts/domain/services/model-service.test.d.ts +2 -0
- package/dist/ts/domain/services/model-service.test.d.ts.map +1 -0
- package/dist/ts/domain/services/read-only-model-service.d.ts +40 -0
- package/dist/ts/domain/services/read-only-model-service.d.ts.map +1 -0
- package/dist/ts/domain/services/read-only-model-service.test.d.ts +2 -0
- package/dist/ts/domain/services/read-only-model-service.test.d.ts.map +1 -0
- package/dist/ts/index.d.ts +18 -0
- package/dist/ts/index.d.ts.map +1 -0
- package/dist/ts/shared/utils/schema-inference.d.ts +23 -0
- package/dist/ts/shared/utils/schema-inference.d.ts.map +1 -0
- package/dist/ts/shared/utils/schema-inheritance.d.ts +24 -0
- package/dist/ts/shared/utils/schema-inheritance.d.ts.map +1 -0
- package/dist/ts/test/domain/services/model-service.test.d.ts +1 -0
- package/dist/ts/test/domain/services/model-service.test.d.ts.map +1 -0
- package/dist/ts/test/mock/models/mock-book-models.d.ts +42 -0
- package/dist/ts/test/mock/models/mock-book-models.d.ts.map +1 -0
- package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts +36 -0
- package/dist/ts/test/mock/repositories/mock-memory-repository.d.ts.map +1 -0
- package/dist/ts/test/mock/repositories/mock-memory-repository.test.d.ts +2 -0
- package/dist/ts/test/mock/repositories/mock-memory-repository.test.d.ts.map +1 -0
- package/package.json +45 -42
- package/src/application/model-controller.test.ts +488 -0
- package/src/application/model-controller.ts +92 -0
- package/src/application/read-only-model-controller.test.ts +327 -0
- package/src/application/read-only-model-controller.ts +61 -0
- package/src/domain/events/domain-event.test.ts +82 -0
- package/src/domain/events/domain-event.ts +69 -0
- package/src/domain/events/event-types.ts +21 -0
- package/src/domain/events/mutation-event.test.ts +38 -0
- package/src/domain/events/mutation-event.ts +8 -0
- package/src/domain/events/query-event.test.ts +28 -0
- package/src/domain/events/query-event.ts +8 -0
- package/src/domain/events/request-event.test.ts +38 -0
- package/src/domain/events/request-event.ts +32 -0
- package/src/domain/interfaces/repository.ts +107 -0
- package/src/domain/models/pagination.ts +28 -0
- package/src/domain/services/base-model-service.ts +50 -0
- package/src/domain/services/model-service-args.ts +9 -0
- package/src/domain/services/model-service.test.ts +631 -0
- package/src/domain/services/model-service.ts +322 -0
- package/src/domain/services/read-only-model-service.test.ts +296 -0
- package/src/domain/services/read-only-model-service.ts +133 -0
- package/src/index.ts +17 -4
- package/src/shared/utils/schema-inference.ts +26 -0
- package/src/shared/utils/schema-inheritance.ts +28 -0
- package/src/test/domain/services/model-service.test.ts +0 -0
- package/src/test/mock/models/mock-book-models.ts +78 -0
- package/src/test/mock/repositories/mock-memory-repository.test.ts +715 -0
- package/src/test/mock/repositories/mock-memory-repository.ts +235 -0
- package/dist/databaseConnection.d.ts +0 -24
- package/dist/datastoreAbstract.d.ts +0 -37
- package/dist/declaro-data.cjs +0 -1
- package/dist/declaro-data.mjs +0 -250
- package/dist/hydrateEntity.d.ts +0 -8
- package/dist/index.d.ts +0 -4
- package/dist/serverConnection.d.ts +0 -15
- package/dist/trackedStatus.d.ts +0 -15
- package/src/databaseConnection.ts +0 -137
- package/src/datastoreAbstract.ts +0 -190
- package/src/hydrateEntity.ts +0 -36
- package/src/placeholder.test.ts +0 -7
- package/src/serverConnection.ts +0 -74
- package/src/trackedStatus.ts +0 -35
- package/tsconfig.json +0 -10
- package/vite.config.ts +0 -23
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import type { IDatastoreProvider, BaseModel, BaseModelClass } from '@declaro/core'
|
|
2
|
-
import type { EntityManager, FilterQuery, Reference } from "@mikro-orm/core";
|
|
3
|
-
import type { EntityRepository } from '@mikro-orm/postgresql'
|
|
4
|
-
import { Hydrator } from "./hydrateEntity";
|
|
5
|
-
import type { RemoveReturnType, UpsertReturnType } from "./datastoreAbstract";
|
|
6
|
-
|
|
7
|
-
export type DatabaseConnectionOptions = {
|
|
8
|
-
populate?: string[];
|
|
9
|
-
immutableFields?: string[];
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export class DatabaseConnection<T extends BaseModel<any>> implements IDatastoreProvider<T> {
|
|
14
|
-
|
|
15
|
-
private repository : EntityRepository<any>
|
|
16
|
-
|
|
17
|
-
public static inject = ['EntityManager', 'Reference'] as const;
|
|
18
|
-
|
|
19
|
-
public readonly em: EntityManager;
|
|
20
|
-
private hydrator: Hydrator;
|
|
21
|
-
private populate;
|
|
22
|
-
private immutableFields = [];
|
|
23
|
-
|
|
24
|
-
constructor(em : EntityManager, reference: typeof Reference) {
|
|
25
|
-
this.em = em;
|
|
26
|
-
this.hydrator = new Hydrator(this.em, reference);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
setup(model: BaseModelClass<T>, options: DatabaseConnectionOptions) {
|
|
30
|
-
this.repository = this.em.getRepository(model);
|
|
31
|
-
this.populate = options?.populate;
|
|
32
|
-
if (options?.immutableFields) {
|
|
33
|
-
this.immutableFields = options.immutableFields;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
getAll() {
|
|
38
|
-
return this.repository.findAll({populate: this.populate}).catch(e => {
|
|
39
|
-
console.log(e);
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
getWhere(filter?: FilterQuery<any>) {
|
|
44
|
-
return this.repository.find(filter, {populate: this.populate}).catch(e => {
|
|
45
|
-
console.log(e);
|
|
46
|
-
})
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
get(id: string | number) {
|
|
50
|
-
return this.repository.findOne(id, {populate: this.populate}).catch(e => {
|
|
51
|
-
console.log(e);
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async upsert<T extends BaseModel<any> | BaseModel<any>[]>(data: T): Promise<UpsertReturnType<T>> {
|
|
56
|
-
if (Array.isArray(data)) {
|
|
57
|
-
const entities: BaseModel<any>[] = [];
|
|
58
|
-
|
|
59
|
-
for (const singleData of data) {
|
|
60
|
-
const entity = await this.singleUpsert(singleData);
|
|
61
|
-
entities.push(entity);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return entities as UpsertReturnType<T>;
|
|
65
|
-
} else {
|
|
66
|
-
return await this.singleUpsert(data) as UpsertReturnType<T>;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private async singleUpsert<T extends BaseModel<any>>(data: T) {
|
|
71
|
-
let entity: T;
|
|
72
|
-
|
|
73
|
-
// Get entity metadata
|
|
74
|
-
const meta = this.em.getMetadata().get(data.constructor.name);
|
|
75
|
-
|
|
76
|
-
// Create a shallow copy of data, excluding m:n fields, these are ignored for the
|
|
77
|
-
// shallow clone because those aren't stored in the row itself but rather a linking table
|
|
78
|
-
const shallowData: Partial<T> = {};
|
|
79
|
-
Object.keys(data).forEach((key) => {
|
|
80
|
-
const property = meta.properties[key];
|
|
81
|
-
if (property && property.reference !== 'm:n') {
|
|
82
|
-
shallowData[key] = data[key];
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
if (!data.id) {
|
|
87
|
-
// Create new entity with shallow data
|
|
88
|
-
entity = this.em.create(data.constructor.name, shallowData as any);
|
|
89
|
-
await this.em.persist(entity).flush();
|
|
90
|
-
} else {
|
|
91
|
-
// Fetch and merge for existing entity
|
|
92
|
-
entity = await this.em.findOneOrFail(data.constructor.name, data.id);
|
|
93
|
-
}
|
|
94
|
-
// NOTE: this is a current hacky workaround to prevent the em.assign call trying to reset the entity's id
|
|
95
|
-
// to undefined on an insert. This should probably actually reference the schema metadata to determine the PK
|
|
96
|
-
delete data.id;
|
|
97
|
-
|
|
98
|
-
this.immutableFields.forEach(f => {
|
|
99
|
-
if (f in data) {
|
|
100
|
-
data[f] = entity[f];
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
// Use em.assign to properly handle m:n relationships for both new and existing entities
|
|
104
|
-
this.em.assign(entity, data);
|
|
105
|
-
await this.em.persist(entity).flush();
|
|
106
|
-
|
|
107
|
-
return entity;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async remove(data: T[] | T): Promise<RemoveReturnType> {
|
|
111
|
-
if (Array.isArray(data)) {
|
|
112
|
-
const removedIds: (number|string)[] = [];
|
|
113
|
-
for (const singleData of data) {
|
|
114
|
-
if(await this.singleRemove(singleData)) {
|
|
115
|
-
removedIds.push(singleData.id);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return removedIds;
|
|
119
|
-
} else {
|
|
120
|
-
return await this.singleRemove(data) ? data.id : null;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private async singleRemove<T extends BaseModel<any>>(data: T): Promise<boolean> {
|
|
125
|
-
try {
|
|
126
|
-
const entity = await this.em.findOneOrFail(data.constructor.name, data.id);
|
|
127
|
-
await this.em.remove(entity).flush();
|
|
128
|
-
return true;
|
|
129
|
-
} catch (e) {
|
|
130
|
-
if (e.constructor.name === 'NotFoundError') {
|
|
131
|
-
return false;
|
|
132
|
-
} else {
|
|
133
|
-
throw e;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
package/src/datastoreAbstract.ts
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import type { IDatastoreProvider, IDatastoreProviderWithFetch, BaseModel, BaseModelClass, IStore } from "@declaro/core";
|
|
2
|
-
import type { FetchFunc } from '@declaro/core';
|
|
3
|
-
import { TrackedStatusStore } from "./trackedStatus";
|
|
4
|
-
import type { FilterQuery } from "@mikro-orm/core";
|
|
5
|
-
|
|
6
|
-
export type TrackedPayload<T> = {
|
|
7
|
-
model: T,
|
|
8
|
-
requestId: string,
|
|
9
|
-
optimistic?: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type UpsertReturnType<T> = T extends (infer U)[] ? U[] : T;
|
|
13
|
-
export type RemoveReturnType = (number|string)[] | number | string | null;
|
|
14
|
-
|
|
15
|
-
export abstract class AbstractStore<T extends BaseModel<any>> implements IStore{
|
|
16
|
-
protected value: T[] = [];
|
|
17
|
-
private subscribers: Array<(value: T[]) => void> = [];
|
|
18
|
-
|
|
19
|
-
private hydrated = false;
|
|
20
|
-
|
|
21
|
-
public trackedStatus = new TrackedStatusStore();
|
|
22
|
-
|
|
23
|
-
protected constructor(
|
|
24
|
-
protected connection: IDatastoreProvider<T>,
|
|
25
|
-
protected model: BaseModelClass<T>,
|
|
26
|
-
protected options?: any)
|
|
27
|
-
{
|
|
28
|
-
this.connection.setup(this.model, options);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
subscribe(subscription: (value: T[]) => void): (() => void) {
|
|
32
|
-
// Add the new subscriber to the subscribers array
|
|
33
|
-
this.subscribers.push(subscription);
|
|
34
|
-
|
|
35
|
-
// Immediately call the subscription with the current value
|
|
36
|
-
subscription(this.value);
|
|
37
|
-
|
|
38
|
-
// Return an unsubscribe function
|
|
39
|
-
return () => {
|
|
40
|
-
// Remove the subscriber from the subscribers array
|
|
41
|
-
this.subscribers = this.subscribers.filter(sub => sub !== subscription);
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
setFetch(fetch: FetchFunc) {
|
|
46
|
-
const connectionWithFetch = this.connection as IDatastoreProviderWithFetch<T>;
|
|
47
|
-
|
|
48
|
-
if (connectionWithFetch.setFetch) {
|
|
49
|
-
connectionWithFetch.setFetch(fetch);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
set(value: T[]) {
|
|
54
|
-
// Update the current value
|
|
55
|
-
this.value = value;
|
|
56
|
-
|
|
57
|
-
// Notify all subscribers of the new value
|
|
58
|
-
this.subscribers.forEach(sub => sub(value));
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async get(value: string | number) {
|
|
62
|
-
await this.hydrate(value)
|
|
63
|
-
|
|
64
|
-
if (typeof this.value == 'undefined') {
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const matches = this.value.filter((i: T) => {
|
|
69
|
-
return i.id == value;
|
|
70
|
-
});
|
|
71
|
-
return matches[0];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async getWhere(filter?: FilterQuery<any>) {
|
|
75
|
-
await this.hydrate(null, filter);
|
|
76
|
-
return this.value;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async getAll() {
|
|
80
|
-
await this.hydrate();
|
|
81
|
-
return this.value;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async hydrate(id?: string | number, filter?: FilterQuery<any>): Promise<void> {
|
|
85
|
-
if (this.hydrated && !filter) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
if (filter) {
|
|
89
|
-
const v = await this.connection.getWhere(filter);
|
|
90
|
-
if (v) {
|
|
91
|
-
this.set(v);
|
|
92
|
-
}
|
|
93
|
-
} else if (!id) {
|
|
94
|
-
const v = await this.connection.getAll();
|
|
95
|
-
if (v) {
|
|
96
|
-
this.set(v);
|
|
97
|
-
}
|
|
98
|
-
} else if (!filter) {
|
|
99
|
-
const v = await this.connection.get(id);
|
|
100
|
-
if (v) {
|
|
101
|
-
this.set([v]);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
this.hydrated = true;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async upsert(model: T | T[], optimistic: boolean = false): Promise<UpsertReturnType<T>> {
|
|
108
|
-
if (Array.isArray(model)) {
|
|
109
|
-
const objArray = model.map(m => Object.assign(new this.model(), m));
|
|
110
|
-
if (optimistic) {
|
|
111
|
-
objArray.forEach(obj => this.insertIntoStore(obj));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const updatedArray: T[] = await this.connection.upsert(objArray);
|
|
115
|
-
updatedArray.forEach(obj => this.insertIntoStore(obj));
|
|
116
|
-
|
|
117
|
-
return updatedArray as UpsertReturnType<T>;
|
|
118
|
-
} else {
|
|
119
|
-
const obj = Object.assign(new this.model(), model);
|
|
120
|
-
if (optimistic) {
|
|
121
|
-
this.insertIntoStore(obj);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const updated: T = await this.connection.upsert(obj);
|
|
125
|
-
this.insertIntoStore(updated);
|
|
126
|
-
|
|
127
|
-
return updated as UpsertReturnType<T>;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
async remove(model: T | T[], optimistic: boolean = false): Promise<RemoveReturnType> {
|
|
132
|
-
if (Array.isArray(model)) {
|
|
133
|
-
const objArray = model.map(m => Object.assign(new this.model(), m));
|
|
134
|
-
if (optimistic) {
|
|
135
|
-
objArray.forEach(obj => this.removeFromStore(obj));
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const result: RemoveReturnType = await this.connection.remove(objArray);
|
|
139
|
-
objArray.forEach(obj => this.removeFromStore(obj));
|
|
140
|
-
return result;
|
|
141
|
-
} else {
|
|
142
|
-
const obj = Object.assign(new this.model(), model);
|
|
143
|
-
if (optimistic) {
|
|
144
|
-
this.removeFromStore(obj);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
const result: RemoveReturnType = await this.connection.remove(obj);
|
|
148
|
-
this.removeFromStore(obj);
|
|
149
|
-
return result;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
async trackedUpsert(payload: TrackedPayload<T | T[]>): Promise<UpsertReturnType<T>> {
|
|
154
|
-
try {
|
|
155
|
-
const ret = await this.upsert(payload.model);
|
|
156
|
-
this.trackedStatus.push({ requestId: payload.requestId, error: false, message: 'Upserted successfully' });
|
|
157
|
-
return ret;
|
|
158
|
-
} catch (e) {
|
|
159
|
-
this.trackedStatus.push({ requestId: payload.requestId, error: true, message: e.message });
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async trackedRemove(payload: TrackedPayload<T | T[]>): Promise<RemoveReturnType> {
|
|
164
|
-
try {
|
|
165
|
-
const ret = await this.remove(payload.model);
|
|
166
|
-
this.trackedStatus.push({ requestId: payload.requestId, error: false, message: 'Removed successfully' });
|
|
167
|
-
return ret;
|
|
168
|
-
} catch (e) {
|
|
169
|
-
this.trackedStatus.push({ requestId: payload.requestId, error: true, message: e.message });
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
insertIntoStore(obj: T) {
|
|
174
|
-
const exists = this.value.some((i: T) => i.id === obj.id);
|
|
175
|
-
if (exists) {
|
|
176
|
-
this.set(this.value.map((i: T) => i.id === obj.id ? obj : i));
|
|
177
|
-
} else {
|
|
178
|
-
this.set([...this.value, obj]);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
removeFromStore(obj: T) {
|
|
183
|
-
this.set(this.value.filter((i: T) => i.id !== obj.id));
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// this is useful for dynamic references to methods on concrete extensions of this class
|
|
188
|
-
export type ActionableStore = AbstractStore<BaseModel<any>> & {
|
|
189
|
-
[key: string]: (...args: any[]) => any;
|
|
190
|
-
};
|
package/src/hydrateEntity.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { EntityManager, Reference, EntityProperty } from "@mikro-orm/core";
|
|
2
|
-
import type { BaseModel } from "@declaro/core";
|
|
3
|
-
import type { EntitySchema } from "@mikro-orm/core";
|
|
4
|
-
|
|
5
|
-
export class Hydrator {
|
|
6
|
-
constructor(
|
|
7
|
-
private readonly em: EntityManager,
|
|
8
|
-
private readonly reference: typeof Reference,
|
|
9
|
-
) {}
|
|
10
|
-
|
|
11
|
-
hydrateEntity<T extends BaseModel<any>>(
|
|
12
|
-
entity: T
|
|
13
|
-
): BaseModel<T> {
|
|
14
|
-
const metadata = this.em.getMetadata().get(entity.constructor.name);
|
|
15
|
-
|
|
16
|
-
for (const prop in entity) {
|
|
17
|
-
const property: EntityProperty = metadata.properties[prop];
|
|
18
|
-
|
|
19
|
-
// Check if this property is a relation (ManyToOne, OneToOne, etc.)
|
|
20
|
-
if (
|
|
21
|
-
entity[prop] !== undefined
|
|
22
|
-
&& entity[prop] !== null
|
|
23
|
-
&& property && ['m:1', '1:1'].includes(property.reference)
|
|
24
|
-
) {
|
|
25
|
-
// in EntitySchema mode Mikro allows the entity to be another schema instead of an EntityName
|
|
26
|
-
const entitySchema = property.entity() as EntitySchema;
|
|
27
|
-
|
|
28
|
-
// this is force to an 'any' here because Mikro can understand a 'Reference' on an instance of our entity
|
|
29
|
-
// even when it's our native entity instead of a Mikro entity (User vs Entity<User>)
|
|
30
|
-
entity[prop] = this.reference.createFromPK(entitySchema.meta.class, entity[prop]) as any;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return entity;
|
|
35
|
-
}
|
|
36
|
-
}
|
package/src/placeholder.test.ts
DELETED
package/src/serverConnection.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import type { IDatastoreProviderWithFetch, BaseModel, BaseModelClass } from '@declaro/core'
|
|
2
|
-
import type { FetchFunc } from '@declaro/core'
|
|
3
|
-
import type { FilterQuery } from "@mikro-orm/core";
|
|
4
|
-
|
|
5
|
-
export class ServerConnection<T extends BaseModel<any>> implements IDatastoreProviderWithFetch<T> {
|
|
6
|
-
|
|
7
|
-
private fetch: FetchFunc;
|
|
8
|
-
private model: BaseModelClass<T>;
|
|
9
|
-
|
|
10
|
-
setup(model: BaseModelClass<T>) {
|
|
11
|
-
this.model = model;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
setFetch(fetch: FetchFunc) {
|
|
15
|
-
this.fetch = fetch;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
getAll(): Promise<any> {
|
|
19
|
-
return this.fetch(`/store/${this.model.name}/getAll`).then(r => {
|
|
20
|
-
return r.json().then((objs: any[]) => {
|
|
21
|
-
// turn results back into objects of the correct type
|
|
22
|
-
return objs.map(o => Object.assign(new this.model(), o));
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
getWhere(filter?: FilterQuery<any>) {
|
|
28
|
-
return this.fetch(`/store/${this.model.name}/getWhere/${JSON.stringify(filter)}`).then(r => {
|
|
29
|
-
return r.json().then((objs: any[]) => {
|
|
30
|
-
// turn results back into objects of the correct type
|
|
31
|
-
return objs.map(o => Object.assign(new this.model(), o));
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get(id: string | number): Promise<any> {
|
|
37
|
-
return this.fetch(`/store/${this.model.name}/get/${id}`).then(r => {
|
|
38
|
-
return r.json();
|
|
39
|
-
})
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
upsert(model: T | T[]): Promise<any> {
|
|
43
|
-
return this._callStoreMethod('upsert', 'POST', model);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
remove(model: T | T[]): Promise<any> {
|
|
47
|
-
return this._callStoreMethod('remove', 'POST', model);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
_callStoreMethod(method: string, httpMethod: string, payload: any = null): Promise<any> {
|
|
51
|
-
let headers = {};
|
|
52
|
-
|
|
53
|
-
if (payload) {
|
|
54
|
-
headers['Content-Type'] = 'application/json;'
|
|
55
|
-
headers['Accept'] = 'application/json;'
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return this.fetch(
|
|
59
|
-
`/store/${this.model.name}/${method}`,
|
|
60
|
-
{
|
|
61
|
-
method: httpMethod,
|
|
62
|
-
body: payload ? JSON.stringify(payload) : null,
|
|
63
|
-
headers
|
|
64
|
-
}
|
|
65
|
-
).then(async r => {
|
|
66
|
-
const data = await r.json();
|
|
67
|
-
if (!r.ok) {
|
|
68
|
-
throw Error(data.message);
|
|
69
|
-
} else {
|
|
70
|
-
return data;
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}
|
package/src/trackedStatus.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { IStore } from "@declaro/core";
|
|
2
|
-
|
|
3
|
-
export type RequestStatus = { requestId: string, error: boolean, message: string }
|
|
4
|
-
|
|
5
|
-
export class TrackedStatusStore implements IStore {
|
|
6
|
-
private value: { [key: string]: RequestStatus } = {};
|
|
7
|
-
private subscribers: Array<(value: { [key: string]: RequestStatus }) => void> = [];
|
|
8
|
-
|
|
9
|
-
subscribe(subscription: (value: { [key: string]: RequestStatus }) => void): (() => void) {
|
|
10
|
-
// Add the new subscriber to the subscribers array
|
|
11
|
-
this.subscribers.push(subscription);
|
|
12
|
-
|
|
13
|
-
// Immediately call the subscription with the current value
|
|
14
|
-
subscription(this.value);
|
|
15
|
-
|
|
16
|
-
// Return an unsubscribe function
|
|
17
|
-
return () => {
|
|
18
|
-
// Remove the subscriber from the subscribers array
|
|
19
|
-
this.subscribers = this.subscribers.filter(sub => sub !== subscription);
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
public push(status: RequestStatus) {
|
|
24
|
-
this.value = { ...this.value, [status.requestId]: status };
|
|
25
|
-
|
|
26
|
-
this.subscribers.forEach(sub => sub(this.value));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public remove(requestId: string) {
|
|
30
|
-
const { [requestId]: removedError, ...rest } = this.value;
|
|
31
|
-
this.value = rest;
|
|
32
|
-
|
|
33
|
-
this.subscribers.forEach(sub => sub(this.value));
|
|
34
|
-
}
|
|
35
|
-
}
|
package/tsconfig.json
DELETED
package/vite.config.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { resolve } from 'path'
|
|
2
|
-
import { defineConfig } from 'vitest/config'
|
|
3
|
-
import dts from 'vite-plugin-dts'
|
|
4
|
-
|
|
5
|
-
const extensions = {
|
|
6
|
-
es: 'mjs',
|
|
7
|
-
cjs: 'cjs',
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default defineConfig({
|
|
11
|
-
build: {
|
|
12
|
-
lib: {
|
|
13
|
-
entry: resolve(__dirname, 'src/index.ts'),
|
|
14
|
-
name: 'DeclaroData',
|
|
15
|
-
formats: ['es', 'cjs'],
|
|
16
|
-
fileName: (format) => `declaro-data.${extensions[format]}`,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
plugins: [dts()],
|
|
20
|
-
optimizeDeps: {
|
|
21
|
-
include: ['src/**/*'],
|
|
22
|
-
},
|
|
23
|
-
})
|