jopi-toolkit 3.0.15 → 3.1.22
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/jk_app/common.d.ts +8 -5
- package/dist/jk_app/common.js +35 -19
- package/dist/jk_app/common.js.map +1 -1
- package/dist/jk_data/index.d.ts +32 -17
- package/dist/jk_data/index.js +55 -25
- package/dist/jk_data/index.js.map +1 -1
- package/dist/jk_events/index.d.ts +2 -0
- package/dist/jk_events/index.js +29 -7
- package/dist/jk_events/index.js.map +1 -1
- package/dist/jk_fs/jBundler_ifBrowser.d.ts +2 -0
- package/dist/jk_fs/jBundler_ifBrowser.js +6 -0
- package/dist/jk_fs/jBundler_ifBrowser.js.map +1 -1
- package/dist/jk_fs/jBundler_ifServer.d.ts +13 -11
- package/dist/jk_fs/jBundler_ifServer.js +53 -7
- package/dist/jk_fs/jBundler_ifServer.js.map +1 -1
- package/dist/jk_logs/jBundler_ifServer.js +5 -0
- package/dist/jk_logs/jBundler_ifServer.js.map +1 -1
- package/dist/jk_process/jBundler_ifServer.d.ts +4 -0
- package/dist/jk_process/jBundler_ifServer.js +31 -0
- package/dist/jk_process/jBundler_ifServer.js.map +1 -1
- package/dist/jk_schemas/index.d.ts +82 -6
- package/dist/jk_schemas/index.js +48 -5
- package/dist/jk_schemas/index.js.map +1 -1
- package/dist/jk_term/index.d.ts +2 -0
- package/dist/jk_term/index.js +2 -0
- package/dist/jk_term/index.js.map +1 -1
- package/dist/jk_tools/jBundler_ifServer.js +19 -7
- package/dist/jk_tools/jBundler_ifServer.js.map +1 -1
- package/package.json +26 -18
- package/src/jk_app/common.js +40 -24
- package/src/jk_app/common.ts +41 -26
- package/src/jk_data/index.js +68 -30
- package/src/jk_data/index.ts +86 -49
- package/src/jk_events/index.js +15 -7
- package/src/jk_events/index.ts +50 -19
- package/src/jk_fs/jBundler_ifBrowser.ts +8 -0
- package/src/jk_fs/jBundler_ifServer.ts +54 -7
- package/src/jk_logs/jBundler_ifServer.ts +6 -0
- package/src/{jk_fs → jk_process}/index.js +0 -1
- package/src/jk_process/jBundler_ifServer.ts +35 -1
- package/src/jk_schemas/index.js +50 -5
- package/src/jk_schemas/index.ts +140 -11
- package/src/jk_term/index.js +2 -0
- package/src/jk_term/index.ts +3 -0
- package/src/jk_tools/jBundler_ifServer.ts +19 -6
- package/src/jk_what/jBundler_ifServer.js +8 -5
- package/dist/jk_schemas/jkSchemas.d.ts +0 -188
- package/dist/jk_schemas/jkSchemas.js +0 -257
- package/dist/jk_schemas/jkSchemas.js.map +0 -1
- package/dist/jk_translate/index.d.ts +0 -21
- package/dist/jk_translate/index.js +0 -56
- package/dist/jk_translate/index.js.map +0 -1
- package/src/jk_fs/common.js +0 -1
- package/src/jk_fs/jBundler_ifServer.js +0 -729
- package/src/jk_translate/index.js +0 -56
- package/src/jk_translate/index.ts +0 -85
package/src/jk_events/index.js
CHANGED
|
@@ -57,15 +57,21 @@ var EventGroup = /** @class */ (function () {
|
|
|
57
57
|
if (this.evenSpy)
|
|
58
58
|
this.evenSpy(eventName, e);
|
|
59
59
|
var events = this.listenersFor[eventName];
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
60
|
+
//
|
|
61
|
+
if (events) {
|
|
62
|
+
if (events.value) {
|
|
63
|
+
var values = events.value;
|
|
64
|
+
for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
|
|
65
|
+
var listener = values_1[_i];
|
|
66
|
+
listener(e, eventName);
|
|
67
|
+
}
|
|
67
68
|
}
|
|
68
69
|
}
|
|
70
|
+
var staticEvent = gStaticEvents[eventName];
|
|
71
|
+
//
|
|
72
|
+
if (staticEvent) {
|
|
73
|
+
staticEvent.send(e);
|
|
74
|
+
}
|
|
69
75
|
};
|
|
70
76
|
EventGroup.prototype.sendAsyncEvent = function (eventName, e) {
|
|
71
77
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -178,6 +184,7 @@ var StaticEventImpl = /** @class */ (function () {
|
|
|
178
184
|
function StaticEventImpl(eventName, eventItems) {
|
|
179
185
|
this.eventName = eventName;
|
|
180
186
|
this.eventItems = eventItems;
|
|
187
|
+
gStaticEvents[eventName] = this;
|
|
181
188
|
}
|
|
182
189
|
StaticEventImpl.prototype.send = function (data) {
|
|
183
190
|
for (var _i = 0, _a = this.eventItems; _i < _a.length; _i++) {
|
|
@@ -211,3 +218,4 @@ export var sendAsyncEvent = defaultEventGroup.sendAsyncEvent.bind(defaultEventGr
|
|
|
211
218
|
export function addListener(eventName, priorityOrListener, listener) {
|
|
212
219
|
defaultEventGroup.addListener(eventName, priorityOrListener, listener);
|
|
213
220
|
}
|
|
221
|
+
var gStaticEvents = {};
|
package/src/jk_events/index.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import {PriorityLevel as EventPriority} from "jopi-toolkit/jk_tools";
|
|
1
|
+
import { PriorityLevel as EventPriority } from "jopi-toolkit/jk_tools";
|
|
2
|
+
import { isBrowser } from "jopi-toolkit/jk_what";
|
|
3
|
+
|
|
2
4
|
// Warning: it's export.
|
|
3
|
-
export {PriorityLevel as EventPriority} from "jopi-toolkit/jk_tools";
|
|
5
|
+
export { PriorityLevel as EventPriority } from "jopi-toolkit/jk_tools";
|
|
4
6
|
|
|
5
7
|
// noinspection JSUnusedGlobalSymbols
|
|
6
8
|
|
|
7
|
-
export type EventListener<T = any> = (e: T, eventName: string) => void|Promise<void>;
|
|
9
|
+
export type EventListener<T = any> = (e: T, eventName: string) => void | Promise<void>;
|
|
8
10
|
export type SyncEventListener<T = any> = (e: T, eventName: string) => void;
|
|
9
11
|
|
|
10
12
|
export type EventListenerProvider = () => Promise<EventListener[]>;
|
|
11
13
|
|
|
14
|
+
let gStaticEvents: Record<string, any> = {};
|
|
15
|
+
let gStaticEventsThisValue: any;
|
|
16
|
+
|
|
12
17
|
export class EventGroup {
|
|
13
18
|
private readonly listenersFor: Record<string, PriorityArray<EventListener>> = {};
|
|
14
19
|
private evenSpy: undefined | ((eventName: string, data?: any) => void);
|
|
@@ -27,23 +32,30 @@ export class EventGroup {
|
|
|
27
32
|
if (events) events.remove(listener);
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
sendEvent(eventName: string, e?: any|undefined): void {
|
|
35
|
+
sendEvent(eventName: string, e?: any | undefined): void {
|
|
31
36
|
if (this.evenSpy) this.evenSpy(eventName, e);
|
|
32
37
|
|
|
33
38
|
const events = this.listenersFor[eventName];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
//
|
|
40
|
+
if (events) {
|
|
41
|
+
if (events.value) {
|
|
42
|
+
const values = events.value;
|
|
43
|
+
|
|
44
|
+
for (const listener of values) {
|
|
45
|
+
listener(e, eventName);
|
|
46
|
+
}
|
|
41
47
|
}
|
|
42
48
|
}
|
|
49
|
+
|
|
50
|
+
let staticEvent = gStaticEvents[eventName];
|
|
51
|
+
//
|
|
52
|
+
if (staticEvent) {
|
|
53
|
+
staticEvent.send(e);
|
|
54
|
+
}
|
|
43
55
|
}
|
|
44
56
|
|
|
45
|
-
async sendAsyncEvent(eventName: string, e?: any|undefined): Promise<void> {
|
|
46
|
-
if (eventName[0]!=='@') {
|
|
57
|
+
async sendAsyncEvent(eventName: string, e?: any | undefined): Promise<void> {
|
|
58
|
+
if (eventName[0] !== '@') {
|
|
47
59
|
throw new Error(`Async events ${eventName} must start with @`);
|
|
48
60
|
}
|
|
49
61
|
|
|
@@ -74,7 +86,7 @@ export class EventGroup {
|
|
|
74
86
|
}
|
|
75
87
|
}
|
|
76
88
|
|
|
77
|
-
addListener<T = any|undefined>(eventName: string, priorityOrListener: EventPriority | EventListener<T>, listener?: EventListener<T>): void {
|
|
89
|
+
addListener<T = any | undefined>(eventName: string, priorityOrListener: EventPriority | EventListener<T>, listener?: EventListener<T>): void {
|
|
78
90
|
let priority: EventPriority;
|
|
79
91
|
let actualListener: EventListener;
|
|
80
92
|
|
|
@@ -109,11 +121,11 @@ export class EventGroup {
|
|
|
109
121
|
*/
|
|
110
122
|
class PriorityArray<T> {
|
|
111
123
|
private entries: PriorityArrayEntry<T>[] = [];
|
|
112
|
-
private build: T[]|undefined;
|
|
124
|
+
private build: T[] | undefined;
|
|
113
125
|
|
|
114
126
|
add(priority: EventPriority, value: T) {
|
|
115
127
|
this.build = undefined;
|
|
116
|
-
this.entries.push({priority, value});
|
|
128
|
+
this.entries.push({ priority, value });
|
|
117
129
|
}
|
|
118
130
|
|
|
119
131
|
remove(value: T) {
|
|
@@ -127,7 +139,7 @@ class PriorityArray<T> {
|
|
|
127
139
|
}
|
|
128
140
|
|
|
129
141
|
return this.build = this.entries
|
|
130
|
-
.sort((a,b) => Number(a.priority) - Number(b.priority))
|
|
142
|
+
.sort((a, b) => Number(a.priority) - Number(b.priority))
|
|
131
143
|
.map(e => e.value);
|
|
132
144
|
}
|
|
133
145
|
}
|
|
@@ -141,6 +153,7 @@ interface PriorityArrayEntry<T> {
|
|
|
141
153
|
|
|
142
154
|
export interface StaticEvent {
|
|
143
155
|
send<T>(data: T): T;
|
|
156
|
+
setThisValue(value: any): void;
|
|
144
157
|
}
|
|
145
158
|
|
|
146
159
|
export interface SEventController {
|
|
@@ -148,12 +161,17 @@ export interface SEventController {
|
|
|
148
161
|
}
|
|
149
162
|
|
|
150
163
|
class StaticEventImpl implements StaticEvent, SEventController {
|
|
164
|
+
private thisValue: any;
|
|
165
|
+
|
|
151
166
|
constructor(public readonly eventName: string, private readonly eventItems: SyncEventListener[]) {
|
|
167
|
+
gStaticEvents[eventName] = this;
|
|
152
168
|
}
|
|
153
169
|
|
|
154
170
|
send<T>(data: T): T {
|
|
171
|
+
let thisValue = this.thisValue ?? gStaticEventsThisValue;
|
|
172
|
+
|
|
155
173
|
for (const listener of this.eventItems) {
|
|
156
|
-
listener(data, this.eventName);
|
|
174
|
+
listener.call(thisValue, data, this.eventName);
|
|
157
175
|
}
|
|
158
176
|
|
|
159
177
|
return data;
|
|
@@ -167,12 +185,25 @@ class StaticEventImpl implements StaticEvent, SEventController {
|
|
|
167
185
|
if (idx >= 0) this.eventItems.splice(idx, 1);
|
|
168
186
|
};
|
|
169
187
|
}
|
|
188
|
+
|
|
189
|
+
setThisValue(thisValue: any): void {
|
|
190
|
+
if (isBrowser) {
|
|
191
|
+
this.thisValue = thisValue;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
170
194
|
}
|
|
171
195
|
|
|
172
196
|
export function createStaticEvent(eventName: string, eventItems: SyncEventListener[]): StaticEvent {
|
|
173
197
|
return new StaticEventImpl(eventName, eventItems);
|
|
174
198
|
}
|
|
175
199
|
|
|
200
|
+
export function setStaticEventsThisValue(thisValue: any) {
|
|
201
|
+
if (isBrowser) {
|
|
202
|
+
gStaticEventsThisValue = thisValue;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
176
207
|
export const defaultEventGroup = new EventGroup();
|
|
177
208
|
|
|
178
209
|
export function newEventGroup(): EventGroup {
|
|
@@ -184,6 +215,6 @@ export const removeListener = defaultEventGroup.removeListener.bind(defaultEvent
|
|
|
184
215
|
export const sendEvent = defaultEventGroup.sendEvent.bind(defaultEventGroup);
|
|
185
216
|
export const sendAsyncEvent = defaultEventGroup.sendAsyncEvent.bind(defaultEventGroup);
|
|
186
217
|
|
|
187
|
-
export function addListener<T = any|undefined>(eventName: string, priorityOrListener: EventPriority | EventListener<T>, listener?: EventListener<T>): void {
|
|
218
|
+
export function addListener<T = any | undefined>(eventName: string, priorityOrListener: EventPriority | EventListener<T>, listener?: EventListener<T>): void {
|
|
188
219
|
defaultEventGroup.addListener(eventName, priorityOrListener as EventPriority, listener as EventListener<T>);
|
|
189
220
|
}
|
|
@@ -68,6 +68,14 @@ export function readTextFromFileSync(filePath: string): string {
|
|
|
68
68
|
throw new Error("Not implemented");
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
export async function readJsonFromFile<T = any>(filePath: string, throwError: boolean = false): Promise<T> {
|
|
72
|
+
throw new Error("Not implemented");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function readJsonFromFileSync<T = any>(filePath: string, throwError: boolean = false): T {
|
|
76
|
+
throw new Error("Not implemented");
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
export async function isFile(filePath: string): Promise<boolean> {
|
|
72
80
|
throw new Error("Not implemented");
|
|
73
81
|
}
|
|
@@ -181,17 +181,64 @@ export function writeTextToFileSync(filePath: string, text: string, createDir: b
|
|
|
181
181
|
fss.writeFileSync(filePath, text, {encoding: 'utf8', flag: 'w'});
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
export function readTextFromFile(filePath: string): Promise<string> {
|
|
185
|
-
|
|
184
|
+
export async function readTextFromFile(filePath: string, throwError: boolean = false): Promise<string> {
|
|
185
|
+
if (throwError) {
|
|
186
|
+
return fs.readFile(filePath, 'utf8');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
return await fs.readFile(filePath, 'utf8');
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// @ts-ignore
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function readTextFromFileSync(filePath: string, throwError: boolean = false): string {
|
|
199
|
+
if (throwError) {
|
|
200
|
+
return fss.readFileSync(filePath, 'utf8');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
return fss.readFileSync(filePath, 'utf8');
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
186
210
|
}
|
|
187
211
|
|
|
188
|
-
export async function readJsonFromFile<T = any>(filePath: string): Promise<T> {
|
|
189
|
-
|
|
190
|
-
|
|
212
|
+
export async function readJsonFromFile<T = any>(filePath: string, throwError: boolean = false): Promise<T> {
|
|
213
|
+
if (throwError) {
|
|
214
|
+
let txt = await readTextFromFile(filePath, true);
|
|
215
|
+
return JSON.parse(txt) as T;
|
|
216
|
+
} else {
|
|
217
|
+
try {
|
|
218
|
+
let txt = await readTextFromFile(filePath);
|
|
219
|
+
return JSON.parse(txt) as T;
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
// @ts-ignore
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
191
226
|
}
|
|
192
227
|
|
|
193
|
-
export function
|
|
194
|
-
|
|
228
|
+
export function readJsonFromFileSync<T = any>(filePath: string, throwError: boolean = false): T {
|
|
229
|
+
if (throwError) {
|
|
230
|
+
let txt = readTextFromFileSync(filePath);
|
|
231
|
+
return JSON.parse(txt) as T;
|
|
232
|
+
} else {
|
|
233
|
+
try {
|
|
234
|
+
let txt = readTextFromFileSync(filePath);
|
|
235
|
+
return JSON.parse(txt) as T;
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// @ts-ignore
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
195
242
|
}
|
|
196
243
|
|
|
197
244
|
export async function isFile(filePath: string): Promise<boolean> {
|
|
@@ -4,6 +4,12 @@ import type {LogInitializer} from "./index.ts";
|
|
|
4
4
|
|
|
5
5
|
export function init(init: LogInitializer) {
|
|
6
6
|
const mainDir = jk_app.findPackageJsonDir();
|
|
7
|
+
|
|
8
|
+
// Possible that no package.json is found.
|
|
9
|
+
// For exemple, when using a command line tool (ex: jopi init).
|
|
10
|
+
//
|
|
11
|
+
if (!mainDir) return;
|
|
12
|
+
|
|
7
13
|
const filePath = jk_fs.join(mainDir, "logConfig.json");
|
|
8
14
|
|
|
9
15
|
if (!jk_fs.isFileSync(filePath)) return;
|
|
@@ -1,4 +1,38 @@
|
|
|
1
|
+
import * as inspector from "node:inspector";
|
|
2
|
+
|
|
1
3
|
export const argv = process.argv;
|
|
2
4
|
export const env = process.env as Record<string, string>;
|
|
3
5
|
export const isProduction = process.env.NODE_ENV === 'production';
|
|
4
|
-
export const isDevelopment: boolean = !isProduction;
|
|
6
|
+
export const isDevelopment: boolean = !isProduction;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Detect if Node.js or Bun.js is running with the debugger launcher.
|
|
10
|
+
*/
|
|
11
|
+
export function isLaunchedWithDebugger(): boolean {
|
|
12
|
+
const args = process.execArgv;
|
|
13
|
+
if (args.some((arg) => arg.includes("--inspect") || arg.includes("--debug") || arg.includes("bootloader.js"))) return true;
|
|
14
|
+
|
|
15
|
+
// Check environment variables
|
|
16
|
+
if (process.env.VSCODE_INSPECTOR_OPTIONS) return true;
|
|
17
|
+
|
|
18
|
+
if (process.env.NODE_OPTIONS) {
|
|
19
|
+
const nodeOptions = process.env.NODE_OPTIONS;
|
|
20
|
+
if (nodeOptions.includes("--inspect") ||
|
|
21
|
+
nodeOptions.includes("--debug") ||
|
|
22
|
+
nodeOptions.includes("bootloader.js") ||
|
|
23
|
+
nodeOptions.includes("js-debug")) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check Bun environment variables
|
|
29
|
+
if (process.env.BUN_INSPECT || process.env.BUN_INSPECT_BRK || process.env.BUN_INSPECT_WAIT) return true;
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
// Check inspector url. This is the most reliable way to detect if a debugger is attached.
|
|
33
|
+
try {
|
|
34
|
+
if (inspector.url()) return true;
|
|
35
|
+
} catch { /* ignore */ }
|
|
36
|
+
|
|
37
|
+
return false;
|
|
38
|
+
}
|
package/src/jk_schemas/index.js
CHANGED
|
@@ -54,7 +54,7 @@ export function validateSchema(data, schema) {
|
|
|
54
54
|
//
|
|
55
55
|
if (schema.schemaMeta.normalize) {
|
|
56
56
|
try {
|
|
57
|
-
schema.schemaMeta.normalize(data);
|
|
57
|
+
schema.schemaMeta.normalize(data, gValueCheckingHelper);
|
|
58
58
|
}
|
|
59
59
|
catch (e) {
|
|
60
60
|
if (e instanceof SchemaError) {
|
|
@@ -81,7 +81,7 @@ export function validateSchema(data, schema) {
|
|
|
81
81
|
var value = data[fieldName];
|
|
82
82
|
if (field.normalize) {
|
|
83
83
|
defaultErrorMessage = field.errorMessage_theValueIsInvalid;
|
|
84
|
-
field.normalize(value, data);
|
|
84
|
+
field.normalize(value, data, gValueCheckingHelper);
|
|
85
85
|
}
|
|
86
86
|
if (!field.optional) {
|
|
87
87
|
if (value === undefined) {
|
|
@@ -102,7 +102,7 @@ export function validateSchema(data, schema) {
|
|
|
102
102
|
}
|
|
103
103
|
if (field.validator) {
|
|
104
104
|
defaultErrorMessage = field.errorMessage_theValueIsInvalid;
|
|
105
|
-
field.validator(value, data);
|
|
105
|
+
field.validator(value, data, gValueCheckingHelper);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
catch (e) {
|
|
@@ -124,7 +124,7 @@ export function validateSchema(data, schema) {
|
|
|
124
124
|
// Allow validating if values are ok with each others.
|
|
125
125
|
if (schema.schemaMeta.validate) {
|
|
126
126
|
try {
|
|
127
|
-
schema.schemaMeta.validate(data);
|
|
127
|
+
schema.schemaMeta.validate(data, gValueCheckingHelper);
|
|
128
128
|
}
|
|
129
129
|
catch (e) {
|
|
130
130
|
if (e instanceof SchemaError) {
|
|
@@ -147,6 +147,19 @@ export function validateSchema(data, schema) {
|
|
|
147
147
|
return { fields: fieldErrors };
|
|
148
148
|
}
|
|
149
149
|
var byTypeValidator = {};
|
|
150
|
+
/**
|
|
151
|
+
* A helper allowing to make field validation easier.
|
|
152
|
+
* Is sent to normalize and validate functions.
|
|
153
|
+
*/
|
|
154
|
+
var ValueCheckingHelper = /** @class */ (function () {
|
|
155
|
+
function ValueCheckingHelper() {
|
|
156
|
+
}
|
|
157
|
+
ValueCheckingHelper.prototype.declareError = function (message, errorCode) {
|
|
158
|
+
throw new SchemaError(message, errorCode);
|
|
159
|
+
};
|
|
160
|
+
return ValueCheckingHelper;
|
|
161
|
+
}());
|
|
162
|
+
var gValueCheckingHelper = new ValueCheckingHelper();
|
|
150
163
|
export function registerSchema(schemaId, schema, meta) {
|
|
151
164
|
if (!schemaId) {
|
|
152
165
|
throw new Error("jk_schemas - Schema id required. If you need an uid you can use: " + generateUUIDv4());
|
|
@@ -176,8 +189,40 @@ var gRegistry = {};
|
|
|
176
189
|
//endregion
|
|
177
190
|
//region Schema
|
|
178
191
|
export function schema(descriptor, meta) {
|
|
179
|
-
return
|
|
192
|
+
return new SchemaImpl(descriptor, meta || {});
|
|
180
193
|
}
|
|
194
|
+
var SchemaImpl = /** @class */ (function () {
|
|
195
|
+
function SchemaImpl(desc, schemaMeta) {
|
|
196
|
+
this.desc = desc;
|
|
197
|
+
this.schemaMeta = schemaMeta;
|
|
198
|
+
}
|
|
199
|
+
SchemaImpl.prototype.toJson = function () {
|
|
200
|
+
return toJson(this);
|
|
201
|
+
};
|
|
202
|
+
SchemaImpl.prototype.addDataNormalizer = function (f) {
|
|
203
|
+
if (!this.schemaMeta.normalize) {
|
|
204
|
+
this.schemaMeta.normalize = f;
|
|
205
|
+
}
|
|
206
|
+
var f1 = this.schemaMeta.normalize;
|
|
207
|
+
this.schemaMeta.normalize = function (values, helper) {
|
|
208
|
+
f1(values, helper);
|
|
209
|
+
f(values, helper);
|
|
210
|
+
};
|
|
211
|
+
return this;
|
|
212
|
+
};
|
|
213
|
+
SchemaImpl.prototype.addDataValidator = function (f) {
|
|
214
|
+
if (!this.schemaMeta.validate) {
|
|
215
|
+
this.schemaMeta.validate = f;
|
|
216
|
+
}
|
|
217
|
+
var f1 = this.schemaMeta.validate;
|
|
218
|
+
this.schemaMeta.validate = function (values, helper) {
|
|
219
|
+
f1(values, helper);
|
|
220
|
+
f(values, helper);
|
|
221
|
+
};
|
|
222
|
+
return this;
|
|
223
|
+
};
|
|
224
|
+
return SchemaImpl;
|
|
225
|
+
}());
|
|
181
226
|
export function toJson(schema) {
|
|
182
227
|
return schema;
|
|
183
228
|
}
|
package/src/jk_schemas/index.ts
CHANGED
|
@@ -47,7 +47,7 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
|
|
|
47
47
|
//
|
|
48
48
|
if (schema.schemaMeta.normalize) {
|
|
49
49
|
try {
|
|
50
|
-
schema.schemaMeta.normalize(data);
|
|
50
|
+
schema.schemaMeta.normalize(data, gValueCheckingHelper);
|
|
51
51
|
}
|
|
52
52
|
catch (e: any) {
|
|
53
53
|
if (e instanceof SchemaError) {
|
|
@@ -80,7 +80,7 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
|
|
|
80
80
|
|
|
81
81
|
if (field.normalize) {
|
|
82
82
|
defaultErrorMessage = field.errorMessage_theValueIsInvalid;
|
|
83
|
-
field.normalize(value, data);
|
|
83
|
+
field.normalize(value, data, gValueCheckingHelper);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
if (!field.optional) {
|
|
@@ -103,7 +103,7 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
|
|
|
103
103
|
|
|
104
104
|
if (field.validator) {
|
|
105
105
|
defaultErrorMessage = field.errorMessage_theValueIsInvalid;
|
|
106
|
-
field.validator(value, data);
|
|
106
|
+
field.validator(value, data, gValueCheckingHelper);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
catch (e: any) {
|
|
@@ -126,7 +126,7 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
|
|
|
126
126
|
|
|
127
127
|
if (schema.schemaMeta.validate) {
|
|
128
128
|
try {
|
|
129
|
-
schema.schemaMeta.validate(data);
|
|
129
|
+
schema.schemaMeta.validate(data, gValueCheckingHelper);
|
|
130
130
|
}
|
|
131
131
|
catch (e: any) {
|
|
132
132
|
if (e instanceof SchemaError) {
|
|
@@ -151,6 +151,18 @@ export function validateSchema(data: any, schema: Schema): ValidationErrors|unde
|
|
|
151
151
|
|
|
152
152
|
const byTypeValidator: Record<string, (v: any, fieldInfos: SchemaFieldInfos) => void> = {};
|
|
153
153
|
|
|
154
|
+
/**
|
|
155
|
+
* A helper allowing to make field validation easier.
|
|
156
|
+
* Is sent to normalize and validate functions.
|
|
157
|
+
*/
|
|
158
|
+
class ValueCheckingHelper {
|
|
159
|
+
declareError(message?: string, errorCode?: string) {
|
|
160
|
+
throw new SchemaError(message, errorCode);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const gValueCheckingHelper = new ValueCheckingHelper();
|
|
165
|
+
|
|
154
166
|
//endregion
|
|
155
167
|
|
|
156
168
|
//region Registry
|
|
@@ -197,11 +209,50 @@ const gRegistry: Record<string, RegistryEntry> = {};
|
|
|
197
209
|
//region Schema
|
|
198
210
|
|
|
199
211
|
export function schema<T extends SchemaDescriptor>(descriptor: T, meta?: SchemaMeta): Schema & { desc: T } {
|
|
200
|
-
return
|
|
212
|
+
return new SchemaImpl(descriptor, meta || {});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
class SchemaImpl<T extends SchemaDescriptor> implements Schema {
|
|
216
|
+
constructor(public readonly desc: T, public readonly schemaMeta: SchemaMeta) {
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
toJson(): SchemaInfo {
|
|
220
|
+
return toJson(this);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
addDataNormalizer(f: (allValues: any, checkHelper: ValueCheckingHelper) => void): this {
|
|
224
|
+
if (!this.schemaMeta.normalize) {
|
|
225
|
+
this.schemaMeta.normalize = f;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const f1 = this.schemaMeta.normalize;
|
|
229
|
+
|
|
230
|
+
this.schemaMeta.normalize = function (values, helper) {
|
|
231
|
+
f1(values, helper);
|
|
232
|
+
f(values, helper);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
addDataValidator(f: (allValues: any, checkHelper: ValueCheckingHelper) => void): this {
|
|
239
|
+
if (!this.schemaMeta.validate) {
|
|
240
|
+
this.schemaMeta.validate = f;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const f1 = this.schemaMeta.validate;
|
|
244
|
+
|
|
245
|
+
this.schemaMeta.validate = function (values, helper) {
|
|
246
|
+
f1(values, helper);
|
|
247
|
+
f(values, helper);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return this;
|
|
251
|
+
}
|
|
201
252
|
}
|
|
202
253
|
|
|
203
254
|
export interface SchemaDescriptor {
|
|
204
|
-
[field: string]:
|
|
255
|
+
[field: string]: Field;
|
|
205
256
|
}
|
|
206
257
|
|
|
207
258
|
export interface SchemaMeta {
|
|
@@ -209,8 +260,8 @@ export interface SchemaMeta {
|
|
|
209
260
|
description?: string;
|
|
210
261
|
[key: string]: any;
|
|
211
262
|
|
|
212
|
-
normalize?: (allValues: any) => void;
|
|
213
|
-
validate?: (allValues: any) => void;
|
|
263
|
+
normalize?: (allValues: any, checkHelper: ValueCheckingHelper) => void;
|
|
264
|
+
validate?: (allValues: any, checkHelper: ValueCheckingHelper) => void;
|
|
214
265
|
}
|
|
215
266
|
|
|
216
267
|
export interface SchemaInfo {
|
|
@@ -219,6 +270,26 @@ export interface SchemaInfo {
|
|
|
219
270
|
}
|
|
220
271
|
|
|
221
272
|
export interface Schema extends SchemaInfo {
|
|
273
|
+
/**
|
|
274
|
+
* Get serializable data describing this schema.
|
|
275
|
+
*/
|
|
276
|
+
toJson(): SchemaInfo;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Add a function whose role is to normalize the data.
|
|
280
|
+
*
|
|
281
|
+
* Cumulating: if a normalize function has already been added,
|
|
282
|
+
* then the previous function will be called before this one.
|
|
283
|
+
*/
|
|
284
|
+
addDataNormalizer(f: (allValues: any, checkHelper: ValueCheckingHelper) => void): this;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Add a function whose role is to validate the data.
|
|
288
|
+
*
|
|
289
|
+
* Cumulating: if a validate function has already been added,
|
|
290
|
+
* then the previous function will be called before this one.
|
|
291
|
+
*/
|
|
292
|
+
addDataValidator(f: (allValues: any, checkHelper: ValueCheckingHelper) => void): this;
|
|
222
293
|
}
|
|
223
294
|
|
|
224
295
|
export function toJson(schema: Schema): SchemaInfo {
|
|
@@ -304,7 +375,46 @@ export interface ScOnTableRenderingInfo {
|
|
|
304
375
|
textAlign?: "left" | "center" | "right";
|
|
305
376
|
}
|
|
306
377
|
|
|
307
|
-
|
|
378
|
+
/**
|
|
379
|
+
* Get information about how storing this field.
|
|
380
|
+
*/
|
|
381
|
+
export interface ScFieldStore {
|
|
382
|
+
/**
|
|
383
|
+
* Allow knowing if a BDD index must be created for this field.
|
|
384
|
+
* The default is true.
|
|
385
|
+
*/
|
|
386
|
+
mustIndex?: boolean;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Allow knowing if this field is the primary key.
|
|
390
|
+
* If more than one primary is set, then a composed key will be created.
|
|
391
|
+
* The default is false.
|
|
392
|
+
*/
|
|
393
|
+
isPrimaryKey?: boolean;
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* The column name to use when storing this field in a database.
|
|
397
|
+
* The default is the field name.
|
|
398
|
+
*/
|
|
399
|
+
colName?: string;
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* An indication on the size of the data to store.
|
|
403
|
+
* The default is "default".
|
|
404
|
+
*
|
|
405
|
+
* - big: for storing large strings / binary.
|
|
406
|
+
* - medium: for storing item with a common size.
|
|
407
|
+
* - tiny: for storing small strings / binary.
|
|
408
|
+
*/
|
|
409
|
+
dataSize?: "tiny" | "medium" | "big";
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Allow forcing the type name for the BDD.
|
|
413
|
+
*/
|
|
414
|
+
databaseType?: string;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
export interface ScField<T, Opt extends boolean> {
|
|
308
418
|
title: string;
|
|
309
419
|
type: string;
|
|
310
420
|
|
|
@@ -316,12 +426,31 @@ interface ScField<T, Opt extends boolean> {
|
|
|
316
426
|
errorMessage_theDataTypeIsInvalid?: string;
|
|
317
427
|
errorMessage_theValueIsInvalid?: string;
|
|
318
428
|
|
|
319
|
-
|
|
320
|
-
|
|
429
|
+
/**
|
|
430
|
+
* A function used to normalize the field value.
|
|
431
|
+
*/
|
|
432
|
+
normalize?: (value: T, allValues: any, valueCheckingHelp: ValueCheckingHelper) => void;
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* A function used to validate the field.
|
|
436
|
+
*/
|
|
437
|
+
validator?: (value: T, allValues: any, valueCheckingHelp: ValueCheckingHelper) => void;
|
|
321
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Meta-data associated with this field.
|
|
441
|
+
* The usage is free, you can use it for whatever you want.
|
|
442
|
+
*/
|
|
322
443
|
metas?: Record<string, string>;
|
|
323
444
|
|
|
445
|
+
/**
|
|
446
|
+
* Get information about how to render this field in a data table.
|
|
447
|
+
*/
|
|
324
448
|
onTableRendering?: ScOnTableRenderingInfo;
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Get information about how storing this field.
|
|
452
|
+
*/
|
|
453
|
+
store?: ScFieldStore;
|
|
325
454
|
}
|
|
326
455
|
|
|
327
456
|
export type Field = ScField<any, any>;
|
package/src/jk_term/index.js
CHANGED
|
@@ -114,6 +114,8 @@ export var logBgRed = buildLogger(B_RED);
|
|
|
114
114
|
export var textBgRed = buildWriter(B_RED);
|
|
115
115
|
export var logBlue = buildLogger(C_BLUE);
|
|
116
116
|
export var textBlue = buildWriter(C_BLUE);
|
|
117
|
+
export var logGrey = buildLogger(C_GREY);
|
|
118
|
+
export var textGrey = buildWriter(C_GREY);
|
|
117
119
|
export var logBgBlue = buildLogger(B_BLUE, C_WHITE);
|
|
118
120
|
export var textBgBlue = buildWriter(B_BLUE, C_WHITE);
|
|
119
121
|
export var logGreen = buildLogger(C_GREEN);
|
package/src/jk_term/index.ts
CHANGED
|
@@ -105,6 +105,9 @@ export const textBgRed = buildWriter(B_RED);
|
|
|
105
105
|
export const logBlue = buildLogger(C_BLUE);
|
|
106
106
|
export const textBlue = buildWriter(C_BLUE);
|
|
107
107
|
|
|
108
|
+
export const logGrey = buildLogger(C_GREY);
|
|
109
|
+
export const textGrey = buildWriter(C_GREY);
|
|
110
|
+
|
|
108
111
|
export const logBgBlue = buildLogger(B_BLUE, C_WHITE);
|
|
109
112
|
export const textBgBlue = buildWriter(B_BLUE, C_WHITE);
|
|
110
113
|
|