@quatrain/core 0.5.0 → 0.5.3

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/README.md CHANGED
@@ -11,13 +11,114 @@ and storage.
11
11
 
12
12
  ## How to install
13
13
 
14
- ```javascript
14
+ ```bash
15
15
  yarn install @quatrain/core
16
16
  ```
17
17
 
18
18
  Quatrain Core comes with a built-in Mock backend adapter. Other adapters are available in
19
19
  different packages. For example, a Google Firestore adapter is available:
20
20
 
21
- ```javascript
21
+ ```bash
22
22
  yarn install @quatrain/backend-firestore
23
23
  ```
24
+
25
+ ## How to use
26
+
27
+ ### Setup
28
+
29
+ ```ts
30
+ import { Core } from '@quatrain/core'
31
+
32
+ Core.addBackend(myAdapter, 'myDB', true)
33
+ ```
34
+
35
+ ### Create a model
36
+
37
+ ```ts
38
+ import { BaseObjectCore } from '@quatrain/core'
39
+
40
+ export type Cat = {
41
+ name: string
42
+ color: `#${string}`
43
+ }
44
+
45
+ export class CatCore extends BaseObjectCore {
46
+ static COLLECTION = 'cats'
47
+
48
+ static PROPERTIES = [
49
+ {
50
+ name: 'name',
51
+ type: Property.STRING,
52
+ minLength: 1,
53
+ maxLength: 32,
54
+ },
55
+ {
56
+ name: 'color',
57
+ type: Property.STRING,
58
+ minLength: 4,
59
+ maxLength: 7,
60
+ },
61
+ ]
62
+ }
63
+ ```
64
+
65
+ ### Instantiate a model
66
+
67
+ ```ts
68
+ const catData: Cat = {
69
+ name: 'Garfield',
70
+ color: '#ffa502',
71
+ }
72
+
73
+ const garfield = CatCore.fromObject(catData)
74
+
75
+ console.log(garfield.name)
76
+ // > "Garfield"
77
+ console.log(garfield.color)
78
+ // > "#ffa502"
79
+ console.log(garfield.core)
80
+ // > CatCore { ... }
81
+ ```
82
+
83
+ ### Interact with backend
84
+
85
+ ```ts
86
+ // Let's save Garfield in our database
87
+ garfield.core.save()
88
+
89
+ // Now, let's retrieve Garfield in the database
90
+ const persistedGarfield = await CatCore.fromBackend('garfield')
91
+ ```
92
+
93
+ ### Using repositories
94
+
95
+ You can use repositories as an alternative way to persist and retrieve models in your backend.
96
+
97
+ This module provides a BaseRepository class that you can extend and override to apply your business logic when doing backend operations.
98
+
99
+ Let's create a repository for our Cat model, that prevents us from deleting a cat.
100
+
101
+ ```ts
102
+ import { Core, BackendInterface, BaseRepository } from '@quatrain/core'
103
+
104
+ export default class CatRepository extends BaseRepository<Cat> {
105
+ constructor(backendAdapter: BackendInterface = Core.getBackend()) {
106
+ super(CatCore, backendAdapter)
107
+ }
108
+
109
+ async delete(uid: string) {
110
+ throw Error("Don't delete the cats!")
111
+ }
112
+ }
113
+ ```
114
+
115
+ Now, let's use our new CatRepository.
116
+
117
+ ```ts
118
+ const repository = new CatRepository()
119
+
120
+ repository.create(garfield)
121
+ repository.read('garfield')
122
+ repository.update(persistedGarfield)
123
+ repository.delete('garfield') // Will throw "Don't delete the cats!"
124
+ ```
@@ -2,11 +2,12 @@ import { DataObjectClass } from '../../components';
2
2
  import { BackendAction } from '../../Backend';
3
3
  import { User } from '../../components/User';
4
4
  import Middleware from './Middleware';
5
+ import { Proxy } from '../../components/types/ProxyConstructor';
5
6
  export interface InjectMetaMiddlewareParams {
6
- user: User;
7
+ user: Proxy<User>;
7
8
  }
8
9
  export declare class InjectMetaMiddleware implements Middleware {
9
- protected _user: User;
10
+ protected _user: Proxy<User>;
10
11
  constructor(params: InjectMetaMiddlewareParams);
11
12
  execute(dataObject: DataObjectClass<any>, action: BackendAction): void;
12
13
  }
@@ -10,15 +10,15 @@ class InjectMetaMiddleware {
10
10
  switch (action) {
11
11
  // add properties existence validation
12
12
  case Backend_1.BackendAction.CREATE:
13
- dataObject.set('createdBy', this._user);
13
+ dataObject.set('createdBy', this._user.core.dataObject.uri);
14
14
  dataObject.set('createdAt', Date.now());
15
15
  break;
16
16
  case Backend_1.BackendAction.UPDATE:
17
- dataObject.set('updatedBy', this._user);
17
+ dataObject.set('updatedBy', this._user.core.dataObject.uri);
18
18
  dataObject.set('updatedAt', Date.now());
19
19
  break;
20
20
  case Backend_1.BackendAction.DELETE:
21
- dataObject.set('deletedBy', this._user);
21
+ dataObject.set('deletedBy', this._user.core.dataObject.uri);
22
22
  dataObject.set('deletedAt', Date.now());
23
23
  break;
24
24
  default:
@@ -65,7 +65,7 @@ export declare class DataObject implements DataObjectClass<any> {
65
65
  set uid(uid: string | undefined);
66
66
  get uid(): string | undefined;
67
67
  get data(): any;
68
- set uri(uri: string | ObjectUri | undefined);
68
+ set uri(uri: ObjectUri);
69
69
  get uri(): ObjectUri;
70
70
  get class(): any;
71
71
  has(key: string): boolean;
@@ -85,7 +85,19 @@ class DataObject {
85
85
  if (this._populated === false) {
86
86
  for (const key in data) {
87
87
  if (Reflect.get(this._properties, key)) {
88
- Reflect.get(this._properties, key).set(data[key]);
88
+ const val = data[key];
89
+ if (val &&
90
+ typeof val === 'object' &&
91
+ 'ref' in val &&
92
+ typeof val.ref == 'string' &&
93
+ 'label' in val &&
94
+ typeof val.label == 'string') {
95
+ const { ref, label } = val;
96
+ Reflect.get(this._properties, key).set(new ObjectUri_1.ObjectUri(ref, label));
97
+ }
98
+ else {
99
+ Reflect.get(this._properties, key).set(data[key]);
100
+ }
89
101
  }
90
102
  }
91
103
  this._populated = true;
@@ -141,7 +153,7 @@ class DataObject {
141
153
  return this._properties;
142
154
  }
143
155
  set uri(uri) {
144
- this._objectUri = uri instanceof ObjectUri_1.ObjectUri ? uri : new ObjectUri_1.ObjectUri(uri);
156
+ this._objectUri = uri;
145
157
  if (this._objectUri.collection !== ObjectUri_1.ObjectUri.MISSING_COLLECTION) {
146
158
  this._persisted = true;
147
159
  }
@@ -19,7 +19,7 @@ class ObjectUri {
19
19
  this._label = '';
20
20
  this._str = str;
21
21
  this._label = label;
22
- if (str.indexOf(':') !== -1) {
22
+ if (str.includes(':')) {
23
23
  const [backend, path] = str.split(':');
24
24
  this._backend = backend || Core_1.Core.defaultBackend;
25
25
  this._path = path;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quatrain/core",
3
- "version": "0.5.0",
3
+ "version": "0.5.3",
4
4
  "description": "Core objects for business apps",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",