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.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `index.ts`
3
+ * - main index
4
+ *
5
+ * @author Steve Jung <steve@lemoncloud.io>
6
+ * @date 2023-01-19 initial version
7
+ *
8
+ * @copyright (C) lemoncloud.io 2023 - All Rights Reserved.
9
+ */
10
+ export * from './transformer';
@@ -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
@@ -9,3 +9,4 @@
9
9
  * @copyright (C) lemoncloud.io 2019 - All Rights Reserved.
10
10
  */
11
11
  export * from './types';
12
+ export * from './cores';
package/dist/index.js CHANGED
@@ -25,4 +25,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
25
25
  * @copyright (C) lemoncloud.io 2019 - All Rights Reserved.
26
26
  */
27
27
  __exportStar(require("./types"), exports);
28
+ __exportStar(require("./cores"), exports);
28
29
  //# sourceMappingURL=index.js.map
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.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\" \"src/**/*.js\"",
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
- "!prepublishOnly": "npm test && npm run lint && npm run format",
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": ">=12.22.12"
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": "^8.1.6",
59
+ "lint-staged": "^13.1.0",
62
60
  "prettier": "^2.6.0",
63
61
  "superagent": "^5.3.1",
64
62
  "supertest": "^4.0.2",