lemon-model 1.0.0 → 1.0.2
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/dist/cores/index.d.ts +10 -0
- package/dist/cores/index.js +27 -0
- package/dist/cores/index.js.map +1 -0
- package/dist/cores/transformer.d.ts +143 -0
- package/dist/cores/transformer.js +78 -0
- package/dist/cores/transformer.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/core-types.d.ts +11 -0
- package/package.json +5 -7
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* `index.ts`
|
|
19
|
+
* - main index
|
|
20
|
+
*
|
|
21
|
+
* @author Steve Jung <steve@lemoncloud.io>
|
|
22
|
+
* @date 2023-01-19 initial version
|
|
23
|
+
*
|
|
24
|
+
* @copyright (C) lemoncloud.io 2023 - All Rights Reserved.
|
|
25
|
+
*/
|
|
26
|
+
__exportStar(require("./transformer"), exports);
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cores/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;GAQG;AACH,gDAA8B"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `transformer.ts`
|
|
3
|
+
* - general transformer between `Model`, `View` and `Body`
|
|
4
|
+
*
|
|
5
|
+
*
|
|
6
|
+
* @author Steve <steve@lemoncloud.io>
|
|
7
|
+
* @date 2023-01-19 initial version
|
|
8
|
+
*
|
|
9
|
+
* @copyright (C) 2023 LemonCloud Co Ltd. - All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
import { CoreModel } from '../types/core-storage';
|
|
12
|
+
/**
|
|
13
|
+
* internal type `Model`
|
|
14
|
+
*/
|
|
15
|
+
declare type Model = CoreModel<string>;
|
|
16
|
+
/**
|
|
17
|
+
* partial set of `CoreModel`
|
|
18
|
+
*/
|
|
19
|
+
export interface Cores {
|
|
20
|
+
/**
|
|
21
|
+
* site-id of model
|
|
22
|
+
* - inited by `identity-token` if use session
|
|
23
|
+
*/
|
|
24
|
+
sid?: string;
|
|
25
|
+
/**
|
|
26
|
+
* user-id of model
|
|
27
|
+
* - inited by `identity-token` if use session
|
|
28
|
+
*/
|
|
29
|
+
uid?: string;
|
|
30
|
+
/**
|
|
31
|
+
* group-id of model
|
|
32
|
+
* - inited by `identity-token` if use session
|
|
33
|
+
*/
|
|
34
|
+
gid?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* common `View` types.
|
|
38
|
+
* - layout of response.
|
|
39
|
+
*/
|
|
40
|
+
export interface View {
|
|
41
|
+
/**
|
|
42
|
+
* (optional) model's id
|
|
43
|
+
*/
|
|
44
|
+
id?: string;
|
|
45
|
+
/**
|
|
46
|
+
* created timestamp
|
|
47
|
+
*/
|
|
48
|
+
createdAt?: number;
|
|
49
|
+
/**
|
|
50
|
+
* updated timestamp
|
|
51
|
+
*/
|
|
52
|
+
updatedAt?: number;
|
|
53
|
+
/**
|
|
54
|
+
* deleted timestamp
|
|
55
|
+
*/
|
|
56
|
+
deletedAt?: number;
|
|
57
|
+
/**
|
|
58
|
+
* (optional) internal error.
|
|
59
|
+
*/
|
|
60
|
+
error?: string;
|
|
61
|
+
/**
|
|
62
|
+
* (optional) internal cores data
|
|
63
|
+
*/
|
|
64
|
+
readonly $?: Cores;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* common `Body` types.
|
|
68
|
+
* - layout of request's body.
|
|
69
|
+
*/
|
|
70
|
+
export interface Body {
|
|
71
|
+
/**
|
|
72
|
+
* (optional) target model's id
|
|
73
|
+
*/
|
|
74
|
+
id?: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* transform model to view, or body to model.
|
|
78
|
+
* - required the sub-class model of `CoreModel`
|
|
79
|
+
*
|
|
80
|
+
* @see CoreModel
|
|
81
|
+
*/
|
|
82
|
+
export interface Transformable<MyModel extends Model, MyView extends View, MyBody extends Body> {
|
|
83
|
+
/**
|
|
84
|
+
* transform model to view
|
|
85
|
+
* - result will be response json.
|
|
86
|
+
*
|
|
87
|
+
* @param model the data model.
|
|
88
|
+
* @param hasCores (optional) include the properties in `CoreModel` as `$`
|
|
89
|
+
*/
|
|
90
|
+
modelAsView: (model: MyModel, hasCores?: boolean) => MyView;
|
|
91
|
+
/**
|
|
92
|
+
* transform request-body to model.
|
|
93
|
+
* - must check data types
|
|
94
|
+
*
|
|
95
|
+
* @param body the body posted
|
|
96
|
+
* @param isCreate (optional) if body is for creation.
|
|
97
|
+
*/
|
|
98
|
+
bodyToModel: (body: MyBody, isCreate?: boolean) => MyModel;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* reverse into model from remote view & body.
|
|
102
|
+
*/
|
|
103
|
+
export interface Reversable<Model, View = Model, Body = Model> {
|
|
104
|
+
/**
|
|
105
|
+
* convert response-view to model
|
|
106
|
+
*/
|
|
107
|
+
asModel: (view: View) => Model;
|
|
108
|
+
/**
|
|
109
|
+
* convert model to request-body.
|
|
110
|
+
*/
|
|
111
|
+
asBody: (model: Model) => Body;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* type: `AbstractTransformer`
|
|
115
|
+
* - common base class of `Transformable`
|
|
116
|
+
*/
|
|
117
|
+
export declare abstract class AbstractTransformer<MyModel extends Model, MyView extends View, MyBody extends Body> implements Transformable<MyModel, MyView, MyBody> {
|
|
118
|
+
/**
|
|
119
|
+
* check in date: YYYY-MM-DD
|
|
120
|
+
*
|
|
121
|
+
* @param val string
|
|
122
|
+
* @param field (optional) target field name to use
|
|
123
|
+
*/
|
|
124
|
+
asDate: (val: string, field?: string) => string;
|
|
125
|
+
/**
|
|
126
|
+
* extract only the defined attribute.
|
|
127
|
+
* ex) `{ a:1, b: undefined }` -> `{ a:1 }`
|
|
128
|
+
*/
|
|
129
|
+
onlyDefined: <T extends object>(N: T) => T;
|
|
130
|
+
/**
|
|
131
|
+
* transform from model to view
|
|
132
|
+
*
|
|
133
|
+
* @see Transformable.modelAsView
|
|
134
|
+
*/
|
|
135
|
+
modelAsView(model: MyModel, hasCores?: boolean): MyView;
|
|
136
|
+
/**
|
|
137
|
+
* transform from body(req-body) to model
|
|
138
|
+
*
|
|
139
|
+
* @see Transformable.bodyToModel
|
|
140
|
+
*/
|
|
141
|
+
bodyToModel(body: MyBody | any, isCreate?: boolean): MyModel;
|
|
142
|
+
}
|
|
143
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AbstractTransformer = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* type: `AbstractTransformer`
|
|
6
|
+
* - common base class of `Transformable`
|
|
7
|
+
*/
|
|
8
|
+
class AbstractTransformer {
|
|
9
|
+
constructor() {
|
|
10
|
+
/**
|
|
11
|
+
* check in date: YYYY-MM-DD
|
|
12
|
+
*
|
|
13
|
+
* @param val string
|
|
14
|
+
* @param field (optional) target field name to use
|
|
15
|
+
*/
|
|
16
|
+
this.asDate = (val, field = 'date') => {
|
|
17
|
+
if (!val || typeof val !== 'string')
|
|
18
|
+
return '';
|
|
19
|
+
const re = /^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
|
|
20
|
+
if (!re.test(val))
|
|
21
|
+
throw new Error(`.${field}[${val}] is invalid format - asDate()`);
|
|
22
|
+
return val;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* extract only the defined attribute.
|
|
26
|
+
* ex) `{ a:1, b: undefined }` -> `{ a:1 }`
|
|
27
|
+
*/
|
|
28
|
+
this.onlyDefined = (N) => N && typeof N === 'object'
|
|
29
|
+
? Object.entries(N).reduce((N, [k, v]) => {
|
|
30
|
+
if (v !== undefined)
|
|
31
|
+
N[k] = v;
|
|
32
|
+
return N;
|
|
33
|
+
}, {})
|
|
34
|
+
: null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* transform from model to view
|
|
38
|
+
*
|
|
39
|
+
* @see Transformable.modelAsView
|
|
40
|
+
*/
|
|
41
|
+
modelAsView(model, hasCores) {
|
|
42
|
+
if (!model || typeof model !== 'object')
|
|
43
|
+
return null;
|
|
44
|
+
const view = {
|
|
45
|
+
id: model.id,
|
|
46
|
+
createdAt: model.createdAt,
|
|
47
|
+
updatedAt: model.updatedAt,
|
|
48
|
+
deletedAt: model.deletedAt,
|
|
49
|
+
};
|
|
50
|
+
if (model.error)
|
|
51
|
+
view.error = model.error;
|
|
52
|
+
if (hasCores) {
|
|
53
|
+
const $ = this.onlyDefined({
|
|
54
|
+
sid: model.sid,
|
|
55
|
+
gid: model.gid,
|
|
56
|
+
uid: model.uid,
|
|
57
|
+
});
|
|
58
|
+
Object.assign(view, { $ });
|
|
59
|
+
}
|
|
60
|
+
return this.onlyDefined(view);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* transform from body(req-body) to model
|
|
64
|
+
*
|
|
65
|
+
* @see Transformable.bodyToModel
|
|
66
|
+
*/
|
|
67
|
+
bodyToModel(body, isCreate) {
|
|
68
|
+
var _a;
|
|
69
|
+
if (!body || typeof body !== 'object')
|
|
70
|
+
return null;
|
|
71
|
+
const model = {};
|
|
72
|
+
if ((body === null || body === void 0 ? void 0 : body.id) !== undefined)
|
|
73
|
+
model.id = `${(_a = body.id) !== null && _a !== void 0 ? _a : ''}`;
|
|
74
|
+
return model;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.AbstractTransformer = AbstractTransformer;
|
|
78
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../src/cores/transformer.ts"],"names":[],"mappings":";;;AA0HA;;;GAGG;AACH,MAAsB,mBAAmB;IAAzC;QAGI;;;;;WAKG;QACI,WAAM,GAAG,CAAC,GAAW,EAAE,KAAK,GAAG,MAAM,EAAE,EAAE;YAC5C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,OAAO,EAAE,CAAC;YAC/C,MAAM,EAAE,GAAG,mDAAmD,CAAC;YAC/D,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,gCAAgC,CAAC,CAAC;YACrF,OAAO,GAAG,CAAC;QACf,CAAC,CAAC;QAEF;;;WAGG;QACI,gBAAW,GAAG,CAAmB,CAAI,EAAE,EAAE,CAC5C,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;YACtB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBACtC,IAAI,CAAC,KAAK,SAAS;oBAAE,CAAC,CAAC,CAAY,CAAC,GAAG,CAAC,CAAC;gBACzC,OAAO,CAAC,CAAC;YACb,CAAC,EAAE,EAAO,CAAC;YACb,CAAC,CAAC,IAAI,CAAC;IAwCnB,CAAC;IAtCG;;;;OAIG;IACI,WAAW,CAAC,KAAc,EAAE,QAAkB;QACjD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACrD,MAAM,IAAI,GAAS;YACf,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;SAC7B,CAAC;QACF,IAAI,KAAK,CAAC,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QAC1C,IAAI,QAAQ,EAAE;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAQ;gBAC9B,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;aACjB,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;SAC9B;QACD,OAAO,IAAI,CAAC,WAAW,CAAS,IAAc,CAAC,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,IAAkB,EAAE,QAAkB;;QACrD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACnD,MAAM,KAAK,GAAG,EAAa,CAAC;QAE5B,IAAI,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,EAAE,MAAK,SAAS;YAAE,KAAK,CAAC,EAAE,GAAG,GAAG,MAAA,IAAI,CAAC,EAAE,mCAAI,EAAE,EAAE,CAAC;QAE1D,OAAO,KAAgB,CAAC;IAC5B,CAAC;CACJ;AAlED,kDAkEC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,0CAAwB"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,0CAAwB;AACxB,0CAAwB"}
|
|
@@ -32,6 +32,17 @@ export interface GeneralItem {
|
|
|
32
32
|
*/
|
|
33
33
|
[key: string]: string | string[] | number | number[];
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* type: simple data-types
|
|
37
|
+
* - it should be compartible with elastic-search.
|
|
38
|
+
* - it should be consistancy within same key name.
|
|
39
|
+
*/
|
|
40
|
+
export interface SimpleSet {
|
|
41
|
+
/**
|
|
42
|
+
* only has simple string or number w/o array.
|
|
43
|
+
*/
|
|
44
|
+
[key: string]: string | number;
|
|
45
|
+
}
|
|
35
46
|
/** ********************************************************************************************************************
|
|
36
47
|
* COMMON Interfaces
|
|
37
48
|
** ********************************************************************************************************************/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lemon-model",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Common shared model definitions for Lemon Micro-Service Platform",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,14 +12,13 @@
|
|
|
12
12
|
"doc:html": "typedoc src/ --exclude **/*.spec.ts --target ES6 --mode file --out dist/docs",
|
|
13
13
|
"doc:publish": "npm run doc:html && gh-pages -m \"docs(gh-pages): publish gh-pages via typedoc\" -d dist/docs",
|
|
14
14
|
"lint": "tsc --noEmit && eslint '*/**/*.{js,ts,jsx,tsx}' --fix",
|
|
15
|
-
"format": "prettier --write \"src/**/*.ts\"
|
|
15
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
16
16
|
"!test": "------- run self-test with jest -----",
|
|
17
17
|
"test": "jest --config=jest.config.json",
|
|
18
18
|
"test:watch": "jest --config=jest.config.json --watchAll",
|
|
19
19
|
"!publish": "------- publish into repository -----",
|
|
20
20
|
"prepare": "npm run build",
|
|
21
|
-
"
|
|
22
|
-
"prepublishOnly": "npm test && npm run lint"
|
|
21
|
+
"prepublishOnly": "npm test && npm run lint && npm run format"
|
|
23
22
|
},
|
|
24
23
|
"husky": {
|
|
25
24
|
"hooks": {
|
|
@@ -36,11 +35,10 @@
|
|
|
36
35
|
"dist/**/*"
|
|
37
36
|
],
|
|
38
37
|
"engines": {
|
|
39
|
-
"node": ">=
|
|
38
|
+
"node": ">=16.17.0"
|
|
40
39
|
},
|
|
41
40
|
"author": "Steve Jung <steve@lemoncloud.io>",
|
|
42
41
|
"license": "MIT",
|
|
43
|
-
"dependencies": {},
|
|
44
42
|
"devDependencies": {
|
|
45
43
|
"@types/async": "^3.2.3",
|
|
46
44
|
"@types/cookie-parser": "^1.4.2",
|
|
@@ -58,7 +56,7 @@
|
|
|
58
56
|
"gh-pages": "^2.2.0",
|
|
59
57
|
"husky": "^2.2.0",
|
|
60
58
|
"jest": "^27.5.1",
|
|
61
|
-
"lint-staged": "^
|
|
59
|
+
"lint-staged": "^13.1.0",
|
|
62
60
|
"prettier": "^2.6.0",
|
|
63
61
|
"superagent": "^5.3.1",
|
|
64
62
|
"supertest": "^4.0.2",
|