@ruiapp/rapid-core 0.5.11 → 0.6.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.
@@ -43,17 +43,6 @@ declare const _default: {
43
43
  targetSingularCode?: undefined;
44
44
  selfIdColumnName?: undefined;
45
45
  defaultValue?: undefined;
46
- } | {
47
- name: string;
48
- code: string;
49
- type: "relation[]";
50
- relation: "many";
51
- targetSingularCode: string;
52
- selfIdColumnName: string;
53
- columnName?: undefined;
54
- required?: undefined;
55
- autoIncrement?: undefined;
56
- defaultValue?: undefined;
57
46
  } | {
58
47
  name: string;
59
48
  code: string;
@@ -65,6 +54,17 @@ declare const _default: {
65
54
  targetSingularCode?: undefined;
66
55
  selfIdColumnName?: undefined;
67
56
  defaultValue?: undefined;
57
+ } | {
58
+ name: string;
59
+ code: string;
60
+ type: "relation[]";
61
+ relation: "many";
62
+ targetSingularCode: string;
63
+ selfIdColumnName: string;
64
+ columnName?: undefined;
65
+ required?: undefined;
66
+ autoIncrement?: undefined;
67
+ defaultValue?: undefined;
68
68
  } | {
69
69
  name: string;
70
70
  code: string;
@@ -110,6 +110,7 @@ declare const _default: {
110
110
  targetSingularCode?: undefined;
111
111
  targetIdColumnName?: undefined;
112
112
  defaultValue?: undefined;
113
+ description?: undefined;
113
114
  } | {
114
115
  name: string;
115
116
  code: string;
@@ -121,6 +122,7 @@ declare const _default: {
121
122
  columnName?: undefined;
122
123
  autoIncrement?: undefined;
123
124
  defaultValue?: undefined;
125
+ description?: undefined;
124
126
  } | {
125
127
  name: string;
126
128
  code: string;
@@ -132,6 +134,7 @@ declare const _default: {
132
134
  targetSingularCode?: undefined;
133
135
  targetIdColumnName?: undefined;
134
136
  defaultValue?: undefined;
137
+ description?: undefined;
135
138
  } | {
136
139
  name: string;
137
140
  code: string;
@@ -143,6 +146,19 @@ declare const _default: {
143
146
  targetSingularCode?: undefined;
144
147
  targetIdColumnName?: undefined;
145
148
  defaultValue?: undefined;
149
+ description?: undefined;
150
+ } | {
151
+ name: string;
152
+ code: string;
153
+ columnName: string;
154
+ type: "json";
155
+ required: false;
156
+ autoIncrement?: undefined;
157
+ relation?: undefined;
158
+ targetSingularCode?: undefined;
159
+ targetIdColumnName?: undefined;
160
+ defaultValue?: undefined;
161
+ description?: undefined;
146
162
  } | {
147
163
  name: string;
148
164
  code: string;
@@ -154,22 +170,25 @@ declare const _default: {
154
170
  relation?: undefined;
155
171
  targetSingularCode?: undefined;
156
172
  targetIdColumnName?: undefined;
173
+ description?: undefined;
157
174
  } | {
158
175
  name: string;
159
176
  code: string;
160
177
  columnName: string;
161
- type: "json";
178
+ type: "integer";
162
179
  required: false;
163
180
  autoIncrement?: undefined;
164
181
  relation?: undefined;
165
182
  targetSingularCode?: undefined;
166
183
  targetIdColumnName?: undefined;
167
184
  defaultValue?: undefined;
185
+ description?: undefined;
168
186
  } | {
169
187
  name: string;
170
188
  code: string;
171
189
  columnName: string;
172
- type: "integer";
190
+ description: string;
191
+ type: "text";
173
192
  required: false;
174
193
  autoIncrement?: undefined;
175
194
  relation?: undefined;
@@ -336,6 +355,17 @@ declare const _default: {
336
355
  targetSingularCode?: undefined;
337
356
  targetIdColumnName?: undefined;
338
357
  defaultValue?: undefined;
358
+ } | {
359
+ name: string;
360
+ code: string;
361
+ columnName: string;
362
+ type: "json";
363
+ required: false;
364
+ autoIncrement?: undefined;
365
+ relation?: undefined;
366
+ targetSingularCode?: undefined;
367
+ targetIdColumnName?: undefined;
368
+ defaultValue?: undefined;
339
369
  })[];
340
370
  indexes?: undefined;
341
371
  })[];
@@ -7,8 +7,10 @@ export interface CacheProvider {
7
7
  createCache: (server: IRpdServer) => Promise<Cache>;
8
8
  }
9
9
  export interface Cache {
10
- set: (key: string, value: any, options?: SetValueOptions) => Promise<void>;
11
- get: (key: string) => Promise<any>;
10
+ set: (key: string, value: string, options?: SetValueOptions) => Promise<void>;
11
+ setObject: (key: string, value: Record<string, any>, options?: SetValueOptions) => Promise<void>;
12
+ get: (key: string) => Promise<string | null>;
13
+ getObject: (key: string) => Promise<Record<string, any> | null>;
12
14
  del: (key: string) => Promise<void>;
13
15
  }
14
16
  export interface SetValueOptions {
@@ -4,7 +4,9 @@ export type MemoryCacheItem<TValue = any> = {
4
4
  expireAt: number;
5
5
  };
6
6
  export default class MemoryCache implements Cache {
7
- set(key: string, value: any, options?: SetValueOptions): Promise<void>;
7
+ set(key: string, value: string, options?: SetValueOptions): Promise<void>;
8
+ setObject(key: string, value: Record<string, any>, options?: SetValueOptions): Promise<void>;
8
9
  get(key: string): Promise<any>;
10
+ getObject(key: string): Promise<any>;
9
11
  del(key: string): Promise<void>;
10
12
  }
package/dist/index.d.ts CHANGED
@@ -6,7 +6,10 @@ export * from "./core/routeContext";
6
6
  export * from "./core/server";
7
7
  export * from "./core/http-types";
8
8
  export * from "./core/actionHandler";
9
+ export * from "./utilities/accessControlUtility";
10
+ export * from "./utilities/entityUtility";
9
11
  export * from "./utilities/jwtUtility";
12
+ export * from "./utilities/timeUtility";
10
13
  export * from "./deno-std/http/cookie";
11
14
  export { mapDbRowToEntity } from "./dataAccess/entityMapper";
12
15
  export * as bootstrapApplicationConfig from "./bootstrapApplicationConfig";
package/dist/index.js CHANGED
@@ -1641,6 +1641,13 @@ var bootstrapApplicationConfig = {
1641
1641
  type: "text",
1642
1642
  required: false,
1643
1643
  },
1644
+ {
1645
+ name: "locales",
1646
+ code: "locales",
1647
+ columnName: "locales",
1648
+ type: "json",
1649
+ required: false,
1650
+ },
1644
1651
  {
1645
1652
  name: "code",
1646
1653
  code: "code",
@@ -1813,6 +1820,13 @@ var bootstrapApplicationConfig = {
1813
1820
  type: "text",
1814
1821
  required: false,
1815
1822
  },
1823
+ {
1824
+ name: "locales",
1825
+ code: "locales",
1826
+ columnName: "locales",
1827
+ type: "json",
1828
+ required: false,
1829
+ },
1816
1830
  {
1817
1831
  name: "column name",
1818
1832
  code: "columnName",
@@ -1935,6 +1949,14 @@ var bootstrapApplicationConfig = {
1935
1949
  type: "text",
1936
1950
  required: false,
1937
1951
  },
1952
+ {
1953
+ name: "i18n string storage",
1954
+ code: "i18nStringStorage",
1955
+ columnName: "i18n_string_storage",
1956
+ description: "The storage type of i18n strings. `json` or `i18nStringsTable`.",
1957
+ type: "text",
1958
+ required: false,
1959
+ },
1938
1960
  ],
1939
1961
  indexes: [
1940
1962
  {
@@ -2041,6 +2063,13 @@ var bootstrapApplicationConfig = {
2041
2063
  targetSingularCode: "data_dictionary_entry",
2042
2064
  selfIdColumnName: "dictionary_id",
2043
2065
  },
2066
+ {
2067
+ name: "locales",
2068
+ code: "locales",
2069
+ columnName: "locales",
2070
+ type: "json",
2071
+ required: false,
2072
+ },
2044
2073
  ],
2045
2074
  },
2046
2075
  {
@@ -2119,6 +2148,13 @@ var bootstrapApplicationConfig = {
2119
2148
  type: "boolean",
2120
2149
  required: false,
2121
2150
  },
2151
+ {
2152
+ name: "locales",
2153
+ code: "locales",
2154
+ columnName: "locales",
2155
+ type: "json",
2156
+ required: false,
2157
+ },
2122
2158
  ],
2123
2159
  },
2124
2160
  {
@@ -2197,6 +2233,54 @@ var bootstrapApplicationConfig = {
2197
2233
  },
2198
2234
  ],
2199
2235
  },
2236
+ {
2237
+ maintainedBy: "dataManager",
2238
+ namespace: "meta",
2239
+ name: "i18n strings",
2240
+ code: "I18nString",
2241
+ singularCode: "i18n_string",
2242
+ pluralCode: "i18n_strings",
2243
+ schema: "public",
2244
+ tableName: "meta_i18n_strings",
2245
+ properties: [
2246
+ {
2247
+ name: "id",
2248
+ code: "id",
2249
+ columnName: "id",
2250
+ type: "integer",
2251
+ required: true,
2252
+ autoIncrement: true,
2253
+ },
2254
+ {
2255
+ name: "namespace",
2256
+ code: "namespace",
2257
+ columnName: "namespace",
2258
+ type: "text",
2259
+ required: true,
2260
+ },
2261
+ {
2262
+ name: "lingual",
2263
+ code: "lingual",
2264
+ columnName: "lingual",
2265
+ type: "text",
2266
+ required: true,
2267
+ },
2268
+ {
2269
+ name: "name",
2270
+ code: "name",
2271
+ columnName: "name",
2272
+ type: "text",
2273
+ required: true,
2274
+ },
2275
+ {
2276
+ name: "text",
2277
+ code: "text",
2278
+ columnName: "text",
2279
+ type: "text",
2280
+ required: false,
2281
+ },
2282
+ ],
2283
+ },
2200
2284
  ],
2201
2285
  dataDictionaries: [],
2202
2286
  routes: [
@@ -2509,6 +2593,9 @@ function getEntityPartChanges(server, model, before, after) {
2509
2593
  return null;
2510
2594
  }
2511
2595
 
2596
+ function getNowString() {
2597
+ return dayjs__default["default"]().format("YYYY-MM-DD HH:mm:ss.SSS");
2598
+ }
2512
2599
  function getNowStringWithTimezone() {
2513
2600
  return dayjs__default["default"]().format("YYYY-MM-DD HH:mm:ss.SSSZ");
2514
2601
  }
@@ -4511,6 +4598,46 @@ class RapidServer {
4511
4598
  }
4512
4599
  }
4513
4600
 
4601
+ function isAccessAllowed(policy, allowedActions) {
4602
+ let isAnyCheckPassed = true;
4603
+ let isAllCheckPassed = true;
4604
+ if (policy.any) {
4605
+ isAnyCheckPassed = false;
4606
+ for (const action of policy.any) {
4607
+ if (lodash.find(allowedActions, (item) => item === action) != null) {
4608
+ isAnyCheckPassed = true;
4609
+ break;
4610
+ }
4611
+ }
4612
+ }
4613
+ if (policy.all) {
4614
+ isAllCheckPassed = true;
4615
+ for (const action of policy.all) {
4616
+ if (lodash.find(allowedActions, (item) => item === action) == null) {
4617
+ isAnyCheckPassed = false;
4618
+ break;
4619
+ }
4620
+ }
4621
+ }
4622
+ return isAnyCheckPassed && isAllCheckPassed;
4623
+ }
4624
+
4625
+ function getEntityRelationTargetId(entity, propName, targetColumnName) {
4626
+ if (!entity) {
4627
+ throw new Error(`"entity" parameter is required.`);
4628
+ }
4629
+ let targetId = entity[propName];
4630
+ if (!targetId && targetColumnName) {
4631
+ targetId = entity[targetColumnName];
4632
+ }
4633
+ if (lodash.isObject(targetId)) {
4634
+ return targetId.id;
4635
+ }
4636
+ else {
4637
+ return targetId;
4638
+ }
4639
+ }
4640
+
4514
4641
  // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
4515
4642
  // This module is browser compatible.
4516
4643
  /**
@@ -4655,29 +4782,41 @@ async function generateJwtSecretKey() {
4655
4782
  }
4656
4783
 
4657
4784
  const values = new Map();
4785
+ async function set(key, value, options) {
4786
+ let expireAt = -1;
4787
+ if (options && options.ttl > 0) {
4788
+ expireAt = new Date().valueOf() + options.ttl;
4789
+ }
4790
+ const cacheItem = {
4791
+ value,
4792
+ expireAt,
4793
+ };
4794
+ values.set(key, cacheItem);
4795
+ }
4796
+ async function get(key) {
4797
+ const cacheItem = values.get(key);
4798
+ if (cacheItem) {
4799
+ if (cacheItem.expireAt === -1) {
4800
+ return cacheItem.value;
4801
+ }
4802
+ if (cacheItem.expireAt >= new Date().valueOf()) {
4803
+ return cacheItem.value;
4804
+ }
4805
+ }
4806
+ return undefined;
4807
+ }
4658
4808
  class MemoryCache {
4659
4809
  async set(key, value, options) {
4660
- let expireAt = -1;
4661
- if (options && options.ttl > 0) {
4662
- expireAt = new Date().valueOf() + options.ttl;
4663
- }
4664
- const cacheItem = {
4665
- value,
4666
- expireAt,
4667
- };
4668
- values.set(key, cacheItem);
4810
+ await set(key, value, options);
4811
+ }
4812
+ async setObject(key, value, options) {
4813
+ await set(key, value, options);
4669
4814
  }
4670
4815
  async get(key) {
4671
- const cacheItem = values.get(key);
4672
- if (cacheItem) {
4673
- if (cacheItem.expireAt === -1) {
4674
- return cacheItem.value;
4675
- }
4676
- if (cacheItem.expireAt >= new Date().valueOf()) {
4677
- return cacheItem.value;
4678
- }
4679
- }
4680
- return undefined;
4816
+ return get(key);
4817
+ }
4818
+ async getObject(key) {
4819
+ return get(key);
4681
4820
  }
4682
4821
  async del(key) {
4683
4822
  values.delete(key);
@@ -4699,9 +4838,9 @@ class CacheFactory {
4699
4838
  #providers;
4700
4839
  constructor(config) {
4701
4840
  this.name = "cache";
4702
- const memoryCacheCreator = new MemoryCacheProvider();
4841
+ const memoryCacheProvider = new MemoryCacheProvider();
4703
4842
  this.#providers = new Map();
4704
- this.#providers.set(memoryCacheCreator.providerName, memoryCacheCreator);
4843
+ this.#providers.set(memoryCacheProvider.providerName, memoryCacheProvider);
4705
4844
  for (const provider of config.providers) {
4706
4845
  this.#providers.set(provider.providerName, provider);
4707
4846
  }
@@ -8591,30 +8730,6 @@ function getStateMachineCode(model, property) {
8591
8730
  }
8592
8731
  }
8593
8732
 
8594
- function isAccessAllowed(policy, allowedActions) {
8595
- let isAnyCheckPassed = true;
8596
- let isAllCheckPassed = true;
8597
- if (policy.any) {
8598
- isAnyCheckPassed = false;
8599
- for (const action of policy.any) {
8600
- if (lodash.find(allowedActions, (item) => item === action) != null) {
8601
- isAnyCheckPassed = true;
8602
- break;
8603
- }
8604
- }
8605
- }
8606
- if (policy.all) {
8607
- isAllCheckPassed = true;
8608
- for (const action of policy.all) {
8609
- if (lodash.find(allowedActions, (item) => item === action) == null) {
8610
- isAnyCheckPassed = false;
8611
- break;
8612
- }
8613
- }
8614
- }
8615
- return isAnyCheckPassed && isAllCheckPassed;
8616
- }
8617
-
8618
8733
  class EntityAccessControlPlugin {
8619
8734
  constructor() { }
8620
8735
  get code() {
@@ -8762,7 +8877,11 @@ exports.decodeJwt = decodeJwt;
8762
8877
  exports.deleteCookie = deleteCookie;
8763
8878
  exports.generateJwtSecretKey = generateJwtSecretKey;
8764
8879
  exports.getCookies = getCookies;
8880
+ exports.getEntityRelationTargetId = getEntityRelationTargetId;
8881
+ exports.getNowString = getNowString;
8882
+ exports.getNowStringWithTimezone = getNowStringWithTimezone;
8765
8883
  exports.getSetCookies = getSetCookies;
8884
+ exports.isAccessAllowed = isAccessAllowed;
8766
8885
  exports.mapDbRowToEntity = mapDbRowToEntity;
8767
8886
  exports.setCookie = setCookie;
8768
8887
  exports.verifyJwt = verifyJwt;
package/dist/types.d.ts CHANGED
@@ -196,7 +196,19 @@ export interface RpdDataModel {
196
196
  * 是否使用软删除
197
197
  */
198
198
  softDelete?: boolean;
199
+ /**
200
+ * 多语言配置
201
+ */
202
+ locales?: Record<string, RpdDataModelLocale>;
199
203
  }
204
+ /**
205
+ * 实体多语言配置
206
+ */
207
+ export type RpdDataModelLocale = {
208
+ name: string;
209
+ description?: string;
210
+ properties?: Record<string, RpdDataModelPropertyLocale>;
211
+ };
200
212
  export interface RpdDataModelPermissionPolicies {
201
213
  find?: PermissionPolicy;
202
214
  create?: PermissionPolicy;
@@ -224,6 +236,10 @@ export interface RpdDataModelProperty {
224
236
  * 字段代码。会用于数据表列名和 API 的字段名。
225
237
  */
226
238
  code: string;
239
+ /**
240
+ * 字段描述。
241
+ */
242
+ description?: string;
227
243
  /**
228
244
  * 数据表列名。如果没有设置则使用 code。
229
245
  */
@@ -290,7 +306,15 @@ export interface RpdDataModelProperty {
290
306
  * 当设置为`true`时,仅允许在创建时设置此属性的值,不允许更新。
291
307
  */
292
308
  readonly?: boolean;
309
+ /**
310
+ * 多语言配置
311
+ */
312
+ locales?: Record<string, RpdDataModelPropertyLocale>;
293
313
  }
314
+ export type RpdDataModelPropertyLocale = {
315
+ name: string;
316
+ description?: string;
317
+ };
294
318
  export type RpdDataPropertyTypes = "integer" | "long" | "float" | "double" | "decimal" | "text" | "boolean" | "date" | "time" | "datetime" | "json" | "relation" | "relation[]" | "option" | "option[]" | "file" | "file[]" | "image" | "image[]";
295
319
  export type RpdEntityDeleteRelationPropertyReaction = "doNothing" | "unlink" | "cascadingDelete";
296
320
  /**
@@ -561,3 +585,9 @@ export type EntityWatchHandlerContext<TEventName extends keyof RpdServerEventTyp
561
585
  export interface EntityWatchPluginInitOptions {
562
586
  watchers: EntityWatcherType[];
563
587
  }
588
+ export interface I18nString {
589
+ namespace: string;
590
+ name: string;
591
+ lingual: string;
592
+ text?: string;
593
+ }
@@ -0,0 +1 @@
1
+ export declare function getEntityRelationTargetId(entity: Record<string, any>, propName: string, targetColumnName?: string): number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.5.11",
3
+ "version": "0.6.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -36,6 +36,13 @@ export default {
36
36
  type: "text",
37
37
  required: false,
38
38
  },
39
+ {
40
+ name: "locales",
41
+ code: "locales",
42
+ columnName: "locales",
43
+ type: "json",
44
+ required: false,
45
+ },
39
46
  {
40
47
  name: "code",
41
48
  code: "code",
@@ -208,6 +215,13 @@ export default {
208
215
  type: "text",
209
216
  required: false,
210
217
  },
218
+ {
219
+ name: "locales",
220
+ code: "locales",
221
+ columnName: "locales",
222
+ type: "json",
223
+ required: false,
224
+ },
211
225
  {
212
226
  name: "column name",
213
227
  code: "columnName",
@@ -330,6 +344,14 @@ export default {
330
344
  type: "text",
331
345
  required: false,
332
346
  },
347
+ {
348
+ name: "i18n string storage",
349
+ code: "i18nStringStorage",
350
+ columnName: "i18n_string_storage",
351
+ description: "The storage type of i18n strings. `json` or `i18nStringsTable`.",
352
+ type: "text",
353
+ required: false,
354
+ },
333
355
  ],
334
356
  indexes: [
335
357
  {
@@ -436,6 +458,13 @@ export default {
436
458
  targetSingularCode: "data_dictionary_entry",
437
459
  selfIdColumnName: "dictionary_id",
438
460
  },
461
+ {
462
+ name: "locales",
463
+ code: "locales",
464
+ columnName: "locales",
465
+ type: "json",
466
+ required: false,
467
+ },
439
468
  ],
440
469
  },
441
470
  {
@@ -514,6 +543,13 @@ export default {
514
543
  type: "boolean",
515
544
  required: false,
516
545
  },
546
+ {
547
+ name: "locales",
548
+ code: "locales",
549
+ columnName: "locales",
550
+ type: "json",
551
+ required: false,
552
+ },
517
553
  ],
518
554
  },
519
555
  {
@@ -592,6 +628,54 @@ export default {
592
628
  },
593
629
  ],
594
630
  },
631
+ {
632
+ maintainedBy: "dataManager",
633
+ namespace: "meta",
634
+ name: "i18n strings",
635
+ code: "I18nString",
636
+ singularCode: "i18n_string",
637
+ pluralCode: "i18n_strings",
638
+ schema: "public",
639
+ tableName: "meta_i18n_strings",
640
+ properties: [
641
+ {
642
+ name: "id",
643
+ code: "id",
644
+ columnName: "id",
645
+ type: "integer",
646
+ required: true,
647
+ autoIncrement: true,
648
+ },
649
+ {
650
+ name: "namespace",
651
+ code: "namespace",
652
+ columnName: "namespace",
653
+ type: "text",
654
+ required: true,
655
+ },
656
+ {
657
+ name: "lingual",
658
+ code: "lingual",
659
+ columnName: "lingual",
660
+ type: "text",
661
+ required: true,
662
+ },
663
+ {
664
+ name: "name",
665
+ code: "name",
666
+ columnName: "name",
667
+ type: "text",
668
+ required: true,
669
+ },
670
+ {
671
+ name: "text",
672
+ code: "text",
673
+ columnName: "text",
674
+ type: "text",
675
+ required: false,
676
+ },
677
+ ],
678
+ },
595
679
  ],
596
680
  dataDictionaries: [],
597
681
  routes: [
@@ -10,8 +10,10 @@ export interface CacheProvider {
10
10
  }
11
11
 
12
12
  export interface Cache {
13
- set: (key: string, value: any, options?: SetValueOptions) => Promise<void>;
14
- get: (key: string) => Promise<any>;
13
+ set: (key: string, value: string, options?: SetValueOptions) => Promise<void>;
14
+ setObject: (key: string, value: Record<string, any>, options?: SetValueOptions) => Promise<void>;
15
+ get: (key: string) => Promise<string | null>;
16
+ getObject: (key: string) => Promise<Record<string, any> | null>;
15
17
  del: (key: string) => Promise<void>;
16
18
  }
17
19
 
@@ -10,10 +10,10 @@ export default class CacheFactory implements FacilityFactory<Cache, CreateCacheF
10
10
  constructor(config: CacheFactoryConfig) {
11
11
  this.name = "cache";
12
12
 
13
- const memoryCacheCreator = new MemoryCacheProvider();
13
+ const memoryCacheProvider = new MemoryCacheProvider();
14
14
 
15
15
  this.#providers = new Map();
16
- this.#providers.set(memoryCacheCreator.providerName, memoryCacheCreator);
16
+ this.#providers.set(memoryCacheProvider.providerName, memoryCacheProvider);
17
17
 
18
18
  for (const provider of config.providers) {
19
19
  this.#providers.set(provider.providerName, provider);
@@ -7,33 +7,49 @@ export type MemoryCacheItem<TValue = any> = {
7
7
 
8
8
  const values: Map<string, MemoryCacheItem> = new Map();
9
9
 
10
- export default class MemoryCache implements Cache {
11
- async set(key: string, value: any, options?: SetValueOptions) {
12
- let expireAt = -1;
13
- if (options && options.ttl > 0) {
14
- expireAt = new Date().valueOf() + options.ttl;
10
+ async function set(key: string, value: any, options?: SetValueOptions) {
11
+ let expireAt = -1;
12
+ if (options && options.ttl > 0) {
13
+ expireAt = new Date().valueOf() + options.ttl;
14
+ }
15
+
16
+ const cacheItem = {
17
+ value,
18
+ expireAt,
19
+ };
20
+ values.set(key, cacheItem);
21
+ }
22
+
23
+ async function get(key: string) {
24
+ const cacheItem = values.get(key);
25
+ if (cacheItem) {
26
+ if (cacheItem.expireAt === -1) {
27
+ return cacheItem.value;
15
28
  }
16
29
 
17
- const cacheItem = {
18
- value,
19
- expireAt,
20
- };
21
- values.set(key, cacheItem);
30
+ if (cacheItem.expireAt >= new Date().valueOf()) {
31
+ return cacheItem.value;
32
+ }
33
+ }
34
+
35
+ return undefined;
36
+ }
37
+
38
+ export default class MemoryCache implements Cache {
39
+ async set(key: string, value: string, options?: SetValueOptions) {
40
+ await set(key, value, options);
41
+ }
42
+
43
+ async setObject(key: string, value: Record<string, any>, options?: SetValueOptions) {
44
+ await set(key, value, options);
22
45
  }
23
46
 
24
47
  async get(key: string) {
25
- const cacheItem = values.get(key);
26
- if (cacheItem) {
27
- if (cacheItem.expireAt === -1) {
28
- return cacheItem.value;
29
- }
30
-
31
- if (cacheItem.expireAt >= new Date().valueOf()) {
32
- return cacheItem.value;
33
- }
34
- }
48
+ return get(key);
49
+ }
35
50
 
36
- return undefined;
51
+ async getObject(key: string) {
52
+ return get(key);
37
53
  }
38
54
 
39
55
  async del(key: string) {
package/src/index.ts CHANGED
@@ -11,7 +11,10 @@ export * from "./core/server";
11
11
  export * from "./core/http-types";
12
12
  export * from "./core/actionHandler";
13
13
 
14
+ export * from "./utilities/accessControlUtility";
15
+ export * from "./utilities/entityUtility";
14
16
  export * from "./utilities/jwtUtility";
17
+ export * from "./utilities/timeUtility";
15
18
 
16
19
  export * from "./deno-std/http/cookie";
17
20
 
package/src/types.ts CHANGED
@@ -223,8 +223,22 @@ export interface RpdDataModel {
223
223
  * 是否使用软删除
224
224
  */
225
225
  softDelete?: boolean;
226
+
227
+ /**
228
+ * 多语言配置
229
+ */
230
+ locales?: Record<string, RpdDataModelLocale>;
226
231
  }
227
232
 
233
+ /**
234
+ * 实体多语言配置
235
+ */
236
+ export type RpdDataModelLocale = {
237
+ name: string;
238
+ description?: string;
239
+ properties?: Record<string, RpdDataModelPropertyLocale>;
240
+ };
241
+
228
242
  export interface RpdDataModelPermissionPolicies {
229
243
  find?: PermissionPolicy;
230
244
  create?: PermissionPolicy;
@@ -254,6 +268,10 @@ export interface RpdDataModelProperty {
254
268
  * 字段代码。会用于数据表列名和 API 的字段名。
255
269
  */
256
270
  code: string;
271
+ /**
272
+ * 字段描述。
273
+ */
274
+ description?: string;
257
275
  /**
258
276
  * 数据表列名。如果没有设置则使用 code。
259
277
  */
@@ -323,8 +341,18 @@ export interface RpdDataModelProperty {
323
341
  * 当设置为`true`时,仅允许在创建时设置此属性的值,不允许更新。
324
342
  */
325
343
  readonly?: boolean;
344
+
345
+ /**
346
+ * 多语言配置
347
+ */
348
+ locales?: Record<string, RpdDataModelPropertyLocale>;
326
349
  }
327
350
 
351
+ export type RpdDataModelPropertyLocale = {
352
+ name: string;
353
+ description?: string;
354
+ };
355
+
328
356
  export type RpdDataPropertyTypes =
329
357
  | "integer"
330
358
  | "long"
@@ -720,3 +748,10 @@ export type EntityWatchHandlerContext<TEventName extends keyof RpdServerEventTyp
720
748
  export interface EntityWatchPluginInitOptions {
721
749
  watchers: EntityWatcherType[];
722
750
  }
751
+
752
+ export interface I18nString {
753
+ namespace: string;
754
+ name: string;
755
+ lingual: string;
756
+ text?: string;
757
+ }
@@ -0,0 +1,18 @@
1
+ import { isObject } from "lodash";
2
+
3
+ export function getEntityRelationTargetId(entity: Record<string, any>, propName: string, targetColumnName?: string) {
4
+ if (!entity) {
5
+ throw new Error(`"entity" parameter is required.`);
6
+ }
7
+
8
+ let targetId: number | { id?: number } = entity[propName];
9
+ if (!targetId && targetColumnName) {
10
+ targetId = entity[targetColumnName];
11
+ }
12
+
13
+ if (isObject(targetId)) {
14
+ return targetId.id;
15
+ } else {
16
+ return targetId;
17
+ }
18
+ }