jopi-toolkit 3.0.11 → 3.0.15

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.
Files changed (38) hide show
  1. package/dist/jk_data/index.d.ts +40 -0
  2. package/dist/jk_data/index.js +76 -0
  3. package/dist/jk_data/index.js.map +1 -0
  4. package/dist/jk_fs/jBundler_ifServer.d.ts +1 -1
  5. package/dist/jk_schemas/index.d.ts +76 -6
  6. package/dist/jk_schemas/index.js +82 -47
  7. package/dist/jk_schemas/index.js.map +1 -1
  8. package/dist/jk_schemas/jkSchemas.d.ts +188 -0
  9. package/dist/jk_schemas/jkSchemas.js +257 -0
  10. package/dist/jk_schemas/jkSchemas.js.map +1 -0
  11. package/dist/jk_timer/index.d.ts +2 -0
  12. package/dist/jk_timer/index.js +2 -0
  13. package/dist/jk_timer/index.js.map +1 -1
  14. package/dist/jk_tools/jBundler_ifServer.d.ts +1 -0
  15. package/dist/jk_tools/jBundler_ifServer.js +40 -10
  16. package/dist/jk_tools/jBundler_ifServer.js.map +1 -1
  17. package/package.json +10 -5
  18. package/src/jk_app/common.js +442 -0
  19. package/src/jk_crypto/jBundler_ifServer.js +16 -0
  20. package/src/jk_data/index.js +117 -0
  21. package/src/jk_data/index.ts +129 -0
  22. package/src/jk_events/index.js +213 -0
  23. package/src/jk_fs/index.js +2 -0
  24. package/src/jk_fs/jBundler_ifServer.js +729 -0
  25. package/src/jk_logs/index.js +371 -0
  26. package/src/jk_logs/jBundler_ifServer.js +24 -0
  27. package/src/jk_schemas/index.js +84 -47
  28. package/src/jk_schemas/index.ts +196 -69
  29. package/src/jk_thread/common.js +7 -0
  30. package/src/jk_timer/index.js +2 -0
  31. package/src/jk_timer/index.ts +3 -0
  32. package/src/jk_tools/common.js +101 -0
  33. package/src/jk_tools/index.js +1 -0
  34. package/src/jk_tools/jBundler_ifServer.js +215 -0
  35. package/src/jk_tools/jBundler_ifServer.ts +49 -11
  36. package/src/jk_translate/index.js +56 -0
  37. package/src/jk_what/jBundler_ifServer.js +5 -0
  38. package/src/jk_os/jBundler_ifServer.js +0 -132
@@ -41,64 +41,10 @@ export interface ValidationErrors {
41
41
  fields?: Record<string, FieldError>;
42
42
  }
43
43
 
44
- const byTypeValidator: Record<string, (v: any, fieldInfos: SchemaFieldInfos) => void> = {
45
- "string": (v, f) => {
46
- if (typeof v !== "string") {
47
- declareError(f.errorMessage_theValueIsInvalid || `Value must be a string`, "INVALID_TYPE");
48
- return;
49
- }
50
-
51
- let sf = f as ScString<any>;
52
-
53
- if ((sf.minLength!==undefined) && (v.length < sf.minLength)) {
54
- declareError(sf.errorMessage_minLength || `Value must be at least ${sf.minLength} characters long`, "INVALID_LENGTH");
55
- return;
56
- }
57
-
58
- if ((sf.maxLength!==undefined) && (v.length > sf.maxLength)) {
59
- declareError(sf.errorMessage_maxLength || `Value must be less than ${sf.maxLength} characters long`, "INVALID_LENGTH");
60
- return;
61
- }
62
- },
63
-
64
- "number": (v, f) => {
65
- if (typeof v !== "number") {
66
- declareError(f.errorMessage_theValueIsInvalid || `Value must be a number`, "INVALID_TYPE");
67
- }
68
-
69
- let sf = f as ScNumber<any>;
70
-
71
- if ((sf.minValue!==undefined) && (v < sf.minValue)) {
72
- declareError(sf.errorMessage_minValue || `Value must be at least ${sf.minValue}`, "INVALID_LENGTH");
73
- return;
74
- }
75
-
76
- if ((sf.maxValue!==undefined) && (v > sf.maxValue)) {
77
- declareError(sf.errorMessage_maxValue || `Value must be less than ${sf.maxValue}`, "INVALID_LENGTH");
78
- return;
79
- }
80
- },
81
-
82
- "boolean": (v, f) => {
83
- if (typeof v !== "boolean") {
84
- declareError(f.errorMessage_theValueIsInvalid || `Value must be a boolean`, "INVALID_TYPE");
85
- }
86
-
87
- let sf = f as ScBoolean<any>;
88
-
89
- if (sf.requireTrue) {
90
- if (v!==true) {
91
- declareError(sf.errorMessage_requireTrue || `Value must be true`, "INVALID_VALUE");
92
- }
93
- } else if (sf.requireFalse) {
94
- if (v!==false) {
95
- declareError(sf.errorMessage_requireFalse || `Value must be false`, "INVALID_VALUE");
96
- }
97
- }
98
- }
99
- }
100
-
101
44
  export function validateSchema(data: any, schema: Schema): ValidationErrors|undefined {
45
+ // Normalize the data.
46
+ // It's a step where we apply automatic corrections.
47
+ //
102
48
  if (schema.schemaMeta.normalize) {
103
49
  try {
104
50
  schema.schemaMeta.normalize(data);
@@ -116,6 +62,13 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
116
62
  }
117
63
  }
118
64
 
65
+ // >>> Check each field individually.
66
+
67
+ // Each time it will:
68
+ // - Normalize the value.
69
+ // - Check if optional + undefined.
70
+ // - Apply validator for the field type.
71
+
119
72
  let fieldErrors: Record<string, FieldError>|undefined;
120
73
 
121
74
  for (let fieldName in schema.desc) {
@@ -168,6 +121,9 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
168
121
  }
169
122
  }
170
123
 
124
+ // >>> Validate the whole fields.
125
+ // Allow validating if values are ok with each others.
126
+
171
127
  if (schema.schemaMeta.validate) {
172
128
  try {
173
129
  schema.schemaMeta.validate(data);
@@ -186,10 +142,15 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
186
142
  }
187
143
  }
188
144
 
145
+ // No error ? --> undefined.
146
+ // Otherwise returns the errors.
147
+ //
189
148
  if (!fieldErrors) return undefined;
190
149
  return {fields: fieldErrors};
191
150
  }
192
151
 
152
+ const byTypeValidator: Record<string, (v: any, fieldInfos: SchemaFieldInfos) => void> = {};
153
+
193
154
  //endregion
194
155
 
195
156
  //region Registry
@@ -275,18 +236,75 @@ export function toJson(schema: Schema): SchemaInfo {
275
236
  * ```
276
237
  */
277
238
  export type SchemaToType<S extends Schema> =
278
- // 1. On accède au descripteur de schéma S['desc']
279
- // 2. On itère sur ses clés K
280
- // 3. On filtre les champs obligatoires (Opt = false)
281
239
  { [K in keyof S['desc'] as S['desc'][K] extends ScField<any, false> ? K : never]:
282
- // 4. On infère le type T du champ
283
240
  S['desc'][K] extends ScField<infer T, any> ? T : never }
284
241
 
285
- // 5. On fusionne avec les champs optionnels (Opt = true)
286
242
  & { [K in keyof S['desc'] as S['desc'][K] extends ScField<any, true> ? K : never] ?:
287
243
  S['desc'][K] extends ScField<infer T, any> ? T : never };
288
244
 
289
- export interface ScField<T, Opt extends boolean> {
245
+ export interface ScOnTableRenderingInfo {
246
+ /**
247
+ * The title to use if rendering with a Table.
248
+ */
249
+ title?: string;
250
+
251
+ /**
252
+ * If true, then allows hiding the column
253
+ * when rendering into a UI table component.
254
+ */
255
+ enableHiding?: boolean;
256
+
257
+ /**
258
+ * If true, then the table column is hidden by default.
259
+ */
260
+ defaultHidden?: boolean;
261
+
262
+ /**
263
+ * If true, then the table column is hidden and remain hidden.
264
+ */
265
+ alwaysHidden?: boolean;
266
+
267
+ /**
268
+ * If true, then allows sorting the column
269
+ * when rendering into a UI table component.
270
+ */
271
+ enableSorting?: boolean;
272
+
273
+ /**
274
+ * If true, then allows editing the column
275
+ * when rendering into a UI table component.
276
+ */
277
+ enableEditing?: boolean;
278
+
279
+ /**
280
+ * Contains the name of the renderer to user for the header.
281
+ */
282
+ rendererForHeader?: string;
283
+
284
+ /**
285
+ * Contains the name of the renderer to user for the cell.
286
+ */
287
+ rendererForCell?: string;
288
+
289
+ /**
290
+ * Allows setting the column grow rule.
291
+ */
292
+ columnGrow?: "takeAllPlace" | "takeMinPlace";
293
+
294
+ /**
295
+ * Allows defining extra-css class for rendering the cells.
296
+ */
297
+ cellCssClass?: string;
298
+
299
+ /**
300
+ * Allows defining extra-css class for rendering the header.
301
+ */
302
+ headerCssClass?: string;
303
+
304
+ textAlign?: "left" | "center" | "right";
305
+ }
306
+
307
+ interface ScField<T, Opt extends boolean> {
290
308
  title: string;
291
309
  type: string;
292
310
 
@@ -302,11 +320,14 @@ export interface ScField<T, Opt extends boolean> {
302
320
  validator?: (value: T, allValues: any) => void;
303
321
 
304
322
  metas?: Record<string, string>;
323
+
324
+ onTableRendering?: ScOnTableRenderingInfo;
305
325
  }
306
326
 
307
- export type SchemaFieldInfos = ScField<any, any>;
327
+ export type Field = ScField<any, any>;
328
+ export type SchemaFieldInfos = Field;
308
329
 
309
- type OnlyInfos<T> = Omit<Omit<Omit<T, "title">, "optional">, "type">;
330
+ type OnlyInfos<T> = Omit<T, "title" | "optional" | "type">;
310
331
 
311
332
  //endregion
312
333
 
@@ -314,7 +335,7 @@ type OnlyInfos<T> = Omit<Omit<Omit<T, "title">, "optional">, "type">;
314
335
 
315
336
  //region String
316
337
 
317
- export interface ScString<Opt extends boolean> extends ScField<string, Opt> {
338
+ export interface ScString<Opt extends boolean = boolean> extends ScField<string, Opt> {
318
339
  minLength?: number;
319
340
  errorMessage_minLength?: string;
320
341
 
@@ -333,11 +354,30 @@ export function string<Opt extends boolean>(title: string, optional: Opt, infos?
333
354
  return {...infos, title, optional, type: "string"};
334
355
  }
335
356
 
357
+ byTypeValidator["string"] = (v,f) => {
358
+ if (typeof v !== "string") {
359
+ declareError(f.errorMessage_theValueIsInvalid || `Value must be a string`, "INVALID_TYPE");
360
+ return;
361
+ }
362
+
363
+ let sf = f as ScString<any>;
364
+
365
+ if ((sf.minLength !== undefined) && (v.length < sf.minLength)) {
366
+ declareError(sf.errorMessage_minLength || `Value must be at least ${sf.minLength} characters long`, "INVALID_LENGTH");
367
+ return;
368
+ }
369
+
370
+ if ((sf.maxLength !== undefined) && (v.length > sf.maxLength)) {
371
+ declareError(sf.errorMessage_maxLength || `Value must be less than ${sf.maxLength} characters long`, "INVALID_LENGTH");
372
+ return;
373
+ }
374
+ };
375
+
336
376
  //endregion
337
377
 
338
378
  //region Boolean
339
379
 
340
- export interface ScBoolean<Opt extends boolean> extends ScField<boolean, Opt> {
380
+ export interface ScBoolean<Opt extends boolean = boolean> extends ScField<boolean, Opt> {
341
381
  requireTrue?: boolean;
342
382
  errorMessage_requireTrue?: string;
343
383
 
@@ -349,30 +389,117 @@ export function boolean<Opt extends boolean>(title: string, optional: Opt, infos
349
389
  return {...infos, title, optional, type: "boolean"};
350
390
  }
351
391
 
392
+ byTypeValidator["boolean"] = (v, f) => {
393
+ if (typeof v !== "boolean") {
394
+ declareError(f.errorMessage_theValueIsInvalid || `Value must be a boolean`, "INVALID_TYPE");
395
+ }
396
+
397
+ let sf = f as ScBoolean<any>;
398
+
399
+ if (sf.requireTrue) {
400
+ if (v !== true) {
401
+ declareError(sf.errorMessage_requireTrue || `Value must be true`, "INVALID_VALUE");
402
+ }
403
+ } else if (sf.requireFalse) {
404
+ if (v !== false) {
405
+ declareError(sf.errorMessage_requireFalse || `Value must be false`, "INVALID_VALUE");
406
+ }
407
+ }
408
+ };
409
+
352
410
  //endregion
353
411
 
354
412
  //region Number
355
413
 
356
- export interface ScNumber<Opt extends boolean> extends ScField<number, Opt> {
414
+ export interface ScNumber<Opt extends boolean = boolean> extends ScField<number, Opt> {
357
415
  minValue?: number;
358
416
  errorMessage_minValue?: string;
359
417
 
360
418
  maxValue?: number;
361
419
  errorMessage_maxValue?: string;
362
420
 
363
- // TODO: allowDecimal
364
421
  allowDecimal?: boolean;
422
+
365
423
  roundMethod?: "round" | "floor" | "ceil";
366
424
  errorMessage_dontAllowDecimal?: string;
367
425
 
368
426
  incrStep?: number;
369
427
  placeholder?: string;
428
+
429
+ /**
430
+ * Allows displaying this value as a simple
431
+ * number, or a current, or a percent.
432
+ */
433
+ displayType?: "decimal" | "currency" | "percent";
434
+
435
+ /**
436
+ * The regional currency format to use for formating.
437
+ * Ex: "en-US", "fr-FR".
438
+ */
439
+ localFormat?: string;
440
+
441
+ /**
442
+ * The type of currency.
443
+ * Ex: "USD".
444
+ */
445
+ currency?: string;
370
446
  }
371
447
 
372
448
  export function number<Opt extends boolean>(title: string, optional: Opt, infos?: OnlyInfos<ScNumber<Opt>>): ScNumber<Opt> {
373
449
  return {...infos, title, optional, type: "number"};
374
450
  }
375
451
 
452
+ export function formatNumber(value: string, fieldNumber: ScNumber, defaultLocalFormat: string = "en-US", defaultCurrency: string = "USD") {
453
+ const amount = parseFloat(value);
454
+
455
+ let localFormat = fieldNumber.localFormat || defaultLocalFormat;
456
+
457
+ switch (fieldNumber.displayType) {
458
+ case "currency":
459
+ return new Intl.NumberFormat(localFormat, {
460
+ style: "currency",
461
+ currency: fieldNumber.currency || defaultCurrency,
462
+ }).format(amount);
463
+ default:
464
+ return new Intl.NumberFormat(localFormat, {style: fieldNumber.displayType || "decimal"}).format(amount);
465
+ }
466
+ }
467
+
468
+ byTypeValidator["number"] = (v,f) => {
469
+ if (typeof v !== "number") {
470
+ declareError(f.errorMessage_theValueIsInvalid || `Value must be a number`, "INVALID_TYPE");
471
+ }
472
+
473
+ let sf = f as ScNumber<any>;
474
+
475
+ if ((sf.minValue!==undefined) && (v < sf.minValue)) {
476
+ declareError(sf.errorMessage_minValue || `Value must be at least ${sf.minValue}`, "INVALID_LENGTH");
477
+ return;
478
+ }
479
+
480
+ if ((sf.maxValue!==undefined) && (v > sf.maxValue)) {
481
+ declareError(sf.errorMessage_maxValue || `Value must be less than ${sf.maxValue}`, "INVALID_LENGTH");
482
+ return;
483
+ }
484
+ }
485
+
486
+ //endregion
487
+
488
+ //region Currency
489
+
490
+ export function currency<Opt extends boolean>(title: string, optional: Opt, infos?: OnlyInfos<ScNumber<Opt>>): ScNumber<Opt> {
491
+ return number(title, optional, {...infos, displayType: "currency"})
492
+ }
493
+
494
+ //endregion
495
+
496
+ //region Percent
497
+
498
+ export function percent<Opt extends boolean>(title: string, optional: Opt, infos?: OnlyInfos<ScNumber<Opt>>): ScNumber<Opt> {
499
+ return number(title, optional, {...infos, displayType: "percent"})
500
+ }
501
+
502
+
376
503
  //endregion
377
504
 
378
505
  //region File
@@ -0,0 +1,7 @@
1
+ export var gIsUsingWorkers = false;
2
+ export function declareUsingWorker() {
3
+ gIsUsingWorkers = true;
4
+ }
5
+ export function isUsingWorker() {
6
+ return gIsUsingWorkers;
7
+ }
@@ -95,6 +95,8 @@ export function deferred(callback) {
95
95
  export function tick(timeInMs) {
96
96
  return new Promise(function (resolve) { return setTimeout(resolve, timeInMs); });
97
97
  }
98
+ export var sleep = tick;
99
+ export var pause = tick;
98
100
  export function chrono(mustSaveMeasures) {
99
101
  return new ChronoImpl(mustSaveMeasures);
100
102
  }
@@ -78,6 +78,9 @@ export function tick(timeInMs: number): Promise<void> {
78
78
  return new Promise(resolve => setTimeout(resolve, timeInMs));
79
79
  }
80
80
 
81
+ export const sleep = tick;
82
+ export const pause = tick;
83
+
81
84
  export function chrono(mustSaveMeasures: boolean): Chrono {
82
85
  return new ChronoImpl(mustSaveMeasures)
83
86
  }
@@ -0,0 +1,101 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ export function generateUUIDv4() {
13
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
14
+ return crypto.randomUUID();
15
+ }
16
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
17
+ var r = Math.random() * 16 | 0;
18
+ var v = c === 'x' ? r : (r & 0x3 | 0x8);
19
+ return v.toString(16);
20
+ });
21
+ }
22
+ export function isUUIDv4(text) {
23
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(text);
24
+ }
25
+ export function getErrorMessage(e) {
26
+ if (e instanceof Error)
27
+ return e.message;
28
+ return "" + e;
29
+ }
30
+ export function applyDefaults(source, defaults) {
31
+ if (!source)
32
+ source = {};
33
+ return __assign(__assign({}, defaults), source);
34
+ }
35
+ /**
36
+ * Allow knowing the file path of the function calling us.
37
+ */
38
+ export function getCallerFilePath() {
39
+ try {
40
+ throw new Error("");
41
+ }
42
+ catch (e) {
43
+ var error = e;
44
+ if (!error.stack)
45
+ return undefined;
46
+ var stackLines = error.stack.split('\n');
47
+ if (stackLines.length < 4)
48
+ return undefined;
49
+ // Here we have something like:
50
+ // at file:///Users/johan/Projets/jopijs-workspace/__tests/jopi-ui-sample/dist/mod_sample/routes/tests/test3.page.js:4:1
51
+ //
52
+ var fileUrl = stackLines[3].trim();
53
+ var idx = fileUrl.indexOf("file://");
54
+ fileUrl = fileUrl.substring(idx);
55
+ idx = fileUrl.lastIndexOf(":");
56
+ fileUrl = fileUrl.substring(0, idx);
57
+ idx = fileUrl.lastIndexOf(":");
58
+ if (idx !== -1)
59
+ fileUrl = fileUrl.substring(0, idx);
60
+ return fileUrl;
61
+ }
62
+ }
63
+ export var PriorityLevel;
64
+ (function (PriorityLevel) {
65
+ PriorityLevel[PriorityLevel["veryLow"] = -200] = "veryLow";
66
+ PriorityLevel[PriorityLevel["low"] = -100] = "low";
67
+ PriorityLevel[PriorityLevel["default"] = 0] = "default";
68
+ PriorityLevel[PriorityLevel["high"] = 100] = "high";
69
+ PriorityLevel[PriorityLevel["veryHigh"] = 200] = "veryHigh";
70
+ })(PriorityLevel || (PriorityLevel = {}));
71
+ export function sortByPriority(values) {
72
+ if (values === undefined)
73
+ return undefined;
74
+ values.sort(function (a, b) {
75
+ if (a.priority < b.priority)
76
+ return -1;
77
+ if (a.priority > b.priority)
78
+ return 1;
79
+ return 0;
80
+ });
81
+ return values.map(function (v) { return v.value; });
82
+ }
83
+ /**
84
+ * Allows avoiding calling a function before n-milliseconds is elapsed.
85
+ */
86
+ var DontCallBeforeElapsed = /** @class */ (function () {
87
+ function DontCallBeforeElapsed(requireMs) {
88
+ if (requireMs === void 0) { requireMs = 1000; }
89
+ this.requireMs = requireMs;
90
+ this.lastTime = 0;
91
+ }
92
+ DontCallBeforeElapsed.prototype.check = function () {
93
+ var now = Date.now();
94
+ if (now - this.lastTime < this.requireMs)
95
+ return false;
96
+ this.lastTime = now;
97
+ return true;
98
+ };
99
+ return DontCallBeforeElapsed;
100
+ }());
101
+ export { DontCallBeforeElapsed };
@@ -0,0 +1 @@
1
+ export * from "./jBundler_ifServer.ts";