jopi-toolkit 3.1.32 → 3.1.34
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 +1 -0
- package/dist/jk_app/common.js +9 -2
- package/dist/jk_app/common.js.map +1 -1
- package/dist/jk_data/browserActions.d.ts +8 -0
- package/dist/jk_data/browserActions.js +9 -0
- package/dist/jk_data/browserActions.js.map +1 -0
- package/dist/jk_data/bundler_ifServer.d.ts +2 -0
- package/dist/jk_data/bundler_ifServer.js +2 -0
- package/dist/jk_data/bundler_ifServer.js.map +1 -0
- package/dist/jk_data/common.d.ts +8 -0
- package/dist/jk_data/common.js +2 -0
- package/dist/jk_data/common.js.map +1 -0
- package/dist/jk_data/core.d.ts +13 -0
- package/dist/jk_data/core.js +85 -0
- package/dist/jk_data/core.js.map +1 -0
- package/dist/jk_data/dataTableProxy.d.ts +21 -0
- package/dist/jk_data/dataTableProxy.js +49 -0
- package/dist/jk_data/dataTableProxy.js.map +1 -0
- package/dist/jk_data/ifServerSide.d.ts +0 -0
- package/dist/jk_data/ifServerSide.js +2 -0
- package/dist/jk_data/ifServerSide.js.map +1 -0
- package/dist/jk_data/index.d.ts +3 -55
- package/dist/jk_data/index.js +3 -105
- package/dist/jk_data/index.js.map +1 -1
- package/dist/jk_data/interfaces.d.ts +107 -0
- package/dist/jk_data/interfaces.js +2 -0
- package/dist/jk_data/interfaces.js.map +1 -0
- package/dist/jk_data/jBundler_common.d.ts +12 -0
- package/dist/jk_data/jBundler_common.js +2 -0
- package/dist/jk_data/jBundler_common.js.map +1 -0
- package/dist/jk_data/jBundler_ifBrowser.d.ts +2 -0
- package/dist/jk_data/jBundler_ifBrowser.js +2 -0
- package/dist/jk_data/jBundler_ifBrowser.js.map +1 -0
- package/dist/jk_data/jBundler_ifServer.1.d.ts +2 -0
- package/dist/jk_data/jBundler_ifServer.1.js +2 -0
- package/dist/jk_data/jBundler_ifServer.1.js.map +1 -0
- package/dist/jk_data/jBundler_ifServer.d.ts +2 -0
- package/dist/jk_data/jBundler_ifServer.js +2 -0
- package/dist/jk_data/jBundler_ifServer.js.map +1 -0
- package/dist/jk_data/proxy.d.ts +24 -0
- package/dist/jk_data/proxy.js +82 -0
- package/dist/jk_data/proxy.js.map +1 -0
- package/dist/jk_fs/jBundler_ifServer.d.ts +1 -0
- package/dist/jk_fs/jBundler_ifServer.js +1 -0
- package/dist/jk_fs/jBundler_ifServer.js.map +1 -1
- package/dist/jk_memcache/index.d.ts +1 -0
- package/dist/jk_memcache/index.js +1 -5
- package/dist/jk_memcache/index.js.map +1 -1
- package/dist/jk_schemas/index.d.ts +20 -16
- package/dist/jk_schemas/index.js +13 -15
- package/dist/jk_schemas/index.js.map +1 -1
- package/dist/jk_tools/index.d.ts +1 -0
- package/package.json +3 -3
- package/src/jk_app/common.ts +12 -2
- package/src/jk_data/core.ts +92 -0
- package/src/jk_data/index.ts +3 -166
- package/src/jk_data/interfaces.ts +140 -0
- package/src/jk_data/proxy.ts +102 -0
- package/src/jk_fs/jBundler_ifServer.ts +1 -0
- package/src/jk_memcache/index.ts +4 -8
- package/src/jk_schemas/index.ts +29 -27
- package/src/jk_tools/index.ts +3 -1
- package/src/jk_compress/index.js +0 -1
- package/src/jk_compress/jBundler_ifServer.js +0 -10
- package/src/jk_data/index.js +0 -155
- package/src/jk_schemas/index.js +0 -330
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {type Schema} from "jopi-toolkit/jk_schema";
|
|
2
|
+
import type { JopiDataTable, JDataReadParams, JDataReadResult, JRowArrayFilter } from "./interfaces.ts";
|
|
3
|
+
export * from "./interfaces.ts";
|
|
4
|
+
|
|
5
|
+
//region Rows Arrays
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Filter the row content according to rules.
|
|
9
|
+
*/
|
|
10
|
+
export function simpleRowArrayFilter(rows: any[], params: JRowArrayFilter): JDataReadResult {
|
|
11
|
+
// > Apply filter.
|
|
12
|
+
|
|
13
|
+
if (params.filter) {
|
|
14
|
+
const f = params.filter;
|
|
15
|
+
|
|
16
|
+
rows = rows.filter(r => {
|
|
17
|
+
if (f.field) {
|
|
18
|
+
let v = r[f.field];
|
|
19
|
+
if (v===undefined) return false;
|
|
20
|
+
return String(v).includes(f.value);
|
|
21
|
+
} else {
|
|
22
|
+
for (let v of Object.values(r)) {
|
|
23
|
+
if (v===undefined) continue;
|
|
24
|
+
if (String(v).includes(f.value)) return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// > Apply sorting.
|
|
33
|
+
|
|
34
|
+
if (params.sorting && params.sorting.length) {
|
|
35
|
+
const sorting = params.sorting[0];
|
|
36
|
+
const sortField = sorting.id;
|
|
37
|
+
const sortDesc = sorting.desc;
|
|
38
|
+
|
|
39
|
+
rows = rows.sort((a, b) => {
|
|
40
|
+
let av = a[sortField];
|
|
41
|
+
let bv = b[sortField];
|
|
42
|
+
|
|
43
|
+
if (av === undefined) av = "";
|
|
44
|
+
if (bv === undefined) bv = "";
|
|
45
|
+
|
|
46
|
+
const avIsNumber = typeof av === "number";
|
|
47
|
+
const bvIsNumber = typeof bv === "number";
|
|
48
|
+
|
|
49
|
+
if (avIsNumber && bvIsNumber) {
|
|
50
|
+
if (sortDesc) {
|
|
51
|
+
return bv - av;
|
|
52
|
+
} else {
|
|
53
|
+
return av - bv;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
const avStr = String(av);
|
|
57
|
+
const bvStr = String(bv);
|
|
58
|
+
|
|
59
|
+
if (sortDesc) {
|
|
60
|
+
return bvStr.localeCompare(avStr);
|
|
61
|
+
} else {
|
|
62
|
+
return avStr.localeCompare(bvStr);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const totalWithoutPagination = rows.length;
|
|
69
|
+
let offset = 0;
|
|
70
|
+
|
|
71
|
+
if (params.page) {
|
|
72
|
+
offset = params.page.pageIndex * params.page.pageSize;
|
|
73
|
+
rows = rows.slice(offset, offset + params.page.pageSize);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {rows, total: totalWithoutPagination, offset};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//endregion
|
|
80
|
+
|
|
81
|
+
//region JDataBinding
|
|
82
|
+
|
|
83
|
+
export class JDataBinding_UseArray implements JopiDataTable {
|
|
84
|
+
public constructor(public readonly schema: Schema, private readonly rows: any[]) {
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async read(params: JDataReadParams): Promise<JDataReadResult> {
|
|
88
|
+
return simpleRowArrayFilter(this.rows, params);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//endregion
|
package/src/jk_data/index.ts
CHANGED
|
@@ -1,166 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export interface JFieldSorting {
|
|
6
|
-
id: string;
|
|
7
|
-
desc: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface JFieldFilter {
|
|
11
|
-
value?: string | number | boolean;
|
|
12
|
-
constraint: JFieldConstraintType;
|
|
13
|
-
caseSensitive?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type JFieldConstraintType =
|
|
17
|
-
| "$eq" // Equals
|
|
18
|
-
| "$ne" // Not equals
|
|
19
|
-
| "$gt" // Greater than
|
|
20
|
-
| "$gte" // Greater than or equals
|
|
21
|
-
| "$lt" // Less than
|
|
22
|
-
| "$lte" // Less than or equals
|
|
23
|
-
| "$in" // In an array of values
|
|
24
|
-
| "$nin" // Not in an array of values
|
|
25
|
-
| "$like" // Like search %endsWith or startsWith%
|
|
26
|
-
|
|
27
|
-
export interface JRowsFilter {
|
|
28
|
-
field?: string;
|
|
29
|
-
value: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface JPageExtraction {
|
|
33
|
-
pageIndex: number;
|
|
34
|
-
pageSize: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface JRowArrayFilter {
|
|
38
|
-
page?: JPageExtraction;
|
|
39
|
-
filter?: JRowsFilter;
|
|
40
|
-
sorting?: JFieldSorting[];
|
|
41
|
-
fieldFilters?: Record<string, JFieldFilter[]>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Filter the row content according to rules.
|
|
46
|
-
*/
|
|
47
|
-
export function simpleRowArrayFilter(rows: any[], params: JRowArrayFilter): JTableDs_ReadResult {
|
|
48
|
-
// > Apply filter.
|
|
49
|
-
|
|
50
|
-
if (params.filter) {
|
|
51
|
-
const f = params.filter;
|
|
52
|
-
|
|
53
|
-
rows = rows.filter(r => {
|
|
54
|
-
if (f.field) {
|
|
55
|
-
let v = r[f.field];
|
|
56
|
-
if (v===undefined) return false;
|
|
57
|
-
return String(v).includes(f.value);
|
|
58
|
-
} else {
|
|
59
|
-
for (let v of Object.values(r)) {
|
|
60
|
-
if (v===undefined) continue;
|
|
61
|
-
if (String(v).includes(f.value)) return true;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// > Apply sorting.
|
|
70
|
-
|
|
71
|
-
if (params.sorting && params.sorting.length) {
|
|
72
|
-
const sorting = params.sorting[0];
|
|
73
|
-
const sortField = sorting.id;
|
|
74
|
-
const sortDesc = sorting.desc;
|
|
75
|
-
|
|
76
|
-
rows = rows.sort((a, b) => {
|
|
77
|
-
let av = a[sortField];
|
|
78
|
-
let bv = b[sortField];
|
|
79
|
-
|
|
80
|
-
if (av === undefined) av = "";
|
|
81
|
-
if (bv === undefined) bv = "";
|
|
82
|
-
|
|
83
|
-
const avIsNumber = typeof av === "number";
|
|
84
|
-
const bvIsNumber = typeof bv === "number";
|
|
85
|
-
|
|
86
|
-
if (avIsNumber && bvIsNumber) {
|
|
87
|
-
if (sortDesc) {
|
|
88
|
-
return bv - av;
|
|
89
|
-
} else {
|
|
90
|
-
return av - bv;
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
const avStr = String(av);
|
|
94
|
-
const bvStr = String(bv);
|
|
95
|
-
|
|
96
|
-
if (sortDesc) {
|
|
97
|
-
return bvStr.localeCompare(avStr);
|
|
98
|
-
} else {
|
|
99
|
-
return avStr.localeCompare(bvStr);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const totalWithoutPagination = rows.length;
|
|
106
|
-
let offset = 0;
|
|
107
|
-
|
|
108
|
-
if (params.page) {
|
|
109
|
-
offset = params.page.pageIndex * params.page.pageSize;
|
|
110
|
-
rows = rows.slice(offset, offset + params.page.pageSize);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {rows, total: totalWithoutPagination, offset};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
//endregion
|
|
117
|
-
|
|
118
|
-
//region JTableDs
|
|
119
|
-
|
|
120
|
-
export interface JTableDs_ReadParams extends JRowArrayFilter {
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface JTableDs_ReadResult {
|
|
124
|
-
rows: any[];
|
|
125
|
-
total?: number;
|
|
126
|
-
offset?: number;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export interface JTableDs {
|
|
130
|
-
get name(): string;
|
|
131
|
-
get schema(): Schema;
|
|
132
|
-
read(params: JTableDs_ReadParams): Promise<JTableDs_ReadResult>;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export class JTableDs_UseArray implements JTableDs {
|
|
136
|
-
public constructor(public readonly name: string, public readonly schema: Schema, private readonly rows: any[]) {
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async read(params: JTableDs_ReadParams): Promise<JTableDs_ReadResult> {
|
|
140
|
-
return simpleRowArrayFilter(this.rows, params);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export class JTableDs_HttpProxy implements JTableDs {
|
|
145
|
-
public constructor(public readonly name: string, private readonly url: string, public readonly schema: Schema) {
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async read(params: JTableDs_ReadParams): Promise<JTableDs_ReadResult> {
|
|
149
|
-
let toSend = {dsName: this.name, read: params};
|
|
150
|
-
|
|
151
|
-
let res = await fetch(this.url, {
|
|
152
|
-
method: "POST",
|
|
153
|
-
headers: {"Content-Type": "application/json"},
|
|
154
|
-
body: JSON.stringify(toSend)
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
if (res.status !== 200) {
|
|
158
|
-
throw new Error(`Error while reading data source "${this.name}"`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
let asJson = await res.json();
|
|
162
|
-
return asJson as JTableDs_ReadResult;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
//endregion
|
|
1
|
+
export * from "./core.ts";
|
|
2
|
+
export * from "./proxy.ts";
|
|
3
|
+
export * from "./interfaces.ts";
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type Schema } from "jopi-toolkit/jk_schema";
|
|
2
|
+
import type {Translatable} from "../jk_tools";
|
|
3
|
+
|
|
4
|
+
export interface JFieldSorting {
|
|
5
|
+
id: string;
|
|
6
|
+
desc: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IActionContext {
|
|
10
|
+
refresh: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface JFieldFilter {
|
|
14
|
+
value?: string | number | boolean;
|
|
15
|
+
constraint: JFieldConstraintType;
|
|
16
|
+
caseSensitive?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type JFieldConstraintType =
|
|
20
|
+
| "$eq" // Equals
|
|
21
|
+
| "$ne" // Not equals
|
|
22
|
+
| "$gt" // Greater than
|
|
23
|
+
| "$gte" // Greater than or equals
|
|
24
|
+
| "$lt" // Less than
|
|
25
|
+
| "$lte" // Less than or equals
|
|
26
|
+
| "$in" // In an array of values
|
|
27
|
+
| "$nin" // Not in an array of values
|
|
28
|
+
| "$like" // Like search %endsWith or startsWith%
|
|
29
|
+
;
|
|
30
|
+
|
|
31
|
+
export interface JGlobalFilter {
|
|
32
|
+
field?: string;
|
|
33
|
+
value: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface JPageExtraction {
|
|
37
|
+
pageIndex: number;
|
|
38
|
+
pageSize: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface JRowArrayFilter {
|
|
42
|
+
page?: JPageExtraction;
|
|
43
|
+
filter?: JGlobalFilter;
|
|
44
|
+
sorting?: JFieldSorting[];
|
|
45
|
+
fieldFilters?: Record<string, JFieldFilter[]>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface JDataReadParams extends JRowArrayFilter {
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface JDataReadResult {
|
|
52
|
+
rows: any[];
|
|
53
|
+
total?: number;
|
|
54
|
+
offset?: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface JActionDef {
|
|
58
|
+
id: string;
|
|
59
|
+
title?: Translatable;
|
|
60
|
+
separator?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface JopiDataTable {
|
|
64
|
+
readonly schema: Schema;
|
|
65
|
+
readonly actions?: JActionDef[];
|
|
66
|
+
read(params: JDataReadParams): Promise<JDataReadResult>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface JDataTable extends JopiDataTable {
|
|
70
|
+
readonly name: string;
|
|
71
|
+
executeAction?: (rows: any[], actionName: string, context?: IActionContext) => Promise<JActionResult | void>
|
|
72
|
+
isActionEnabled?: (actionName: string, rows: any[], context?: IActionContext) => boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface JActionPreProcessParams {
|
|
76
|
+
rows: any[];
|
|
77
|
+
context?: IActionContext;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface JActionResult {
|
|
81
|
+
isOk?: boolean;
|
|
82
|
+
errorCode?: string;
|
|
83
|
+
errorMessage?: string;
|
|
84
|
+
userMessage?: string;
|
|
85
|
+
data?: any;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface JActionPreProcessResult extends JActionResult {
|
|
89
|
+
rows?: any[];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface JActionPostProcessParams {
|
|
93
|
+
rows: any[];
|
|
94
|
+
context?: IActionContext;
|
|
95
|
+
|
|
96
|
+
data?: any[];
|
|
97
|
+
userMessage?: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Defines the behavior of a custom action in the browser for a Jopi table.
|
|
102
|
+
* allowing to hook into the action lifecycle (pre-process, server call, post-process).
|
|
103
|
+
*/
|
|
104
|
+
export interface JopiTableBrowserActionItem {
|
|
105
|
+
/**
|
|
106
|
+
* Callback invoked when an error occurs during the action execution.
|
|
107
|
+
* This can be triggered by a failure in the `action` handler or a server-side error.
|
|
108
|
+
*/
|
|
109
|
+
onError?: (params: JActionResult) => Promise<void>,
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The main client-side action handler.
|
|
113
|
+
* - Can be used to perform checks or data transformation before sending to the server.
|
|
114
|
+
* - Can be used as a standalone action if `disableServerCall` is true.
|
|
115
|
+
* - Return `void` to proceed with the default flow.
|
|
116
|
+
* - Return a `JActionPreProcessResult` to control flow (e.g., stop execution if `isOk` is false) or modify data sent to server.
|
|
117
|
+
*/
|
|
118
|
+
action?: (params: JActionPreProcessParams) => Promise<JActionPreProcessResult|void>,
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Callback invoked after the server-side action has successfully completed.
|
|
122
|
+
* Useful for showing notifications, refreshing data, or triggering other UI updates.
|
|
123
|
+
*/
|
|
124
|
+
afterServerCall?: (params: JActionPostProcessParams) => Promise<void>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Function to determine if the action should be enabled/clickable.
|
|
128
|
+
* Based on the currently selected rows and the current action context.
|
|
129
|
+
* If not provided, the action is assumed to be always enabled.
|
|
130
|
+
*/
|
|
131
|
+
canEnable?: (rows: any[], context?: IActionContext) => boolean;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* If set to true, the framework will NOT assume there is a corresponding server-side action to call.
|
|
135
|
+
* Use this for actions that are purely client-side (e.g., "Copy to clipboard").
|
|
136
|
+
*/
|
|
137
|
+
disableServerCall?: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export type JopiTableBrowserActions = Record<string, JopiTableBrowserActionItem>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { IActionContext, JopiTableBrowserActions, JDataReadParams, JDataReadResult, JDataTable, JActionDef, JActionResult } from "./interfaces.ts";
|
|
2
|
+
import { schema, type Schema } from "jopi-toolkit/jk_schema";
|
|
3
|
+
|
|
4
|
+
export interface ProxyParams {
|
|
5
|
+
name: string;
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
actions?: JActionDef[];
|
|
8
|
+
schema: { meta: any; desc: any; };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class Proxy implements JDataTable {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly schema: Schema;
|
|
14
|
+
readonly actions?: JActionDef[];
|
|
15
|
+
private readonly url: string;
|
|
16
|
+
|
|
17
|
+
readonly browserActions: JopiTableBrowserActions;
|
|
18
|
+
|
|
19
|
+
constructor(params: ProxyParams, browserActions: JopiTableBrowserActions) {
|
|
20
|
+
this.name = params.name;
|
|
21
|
+
this.url = params.apiUrl;
|
|
22
|
+
this.actions = params.actions;
|
|
23
|
+
this.schema = schema(params.schema.desc, params.schema.meta);
|
|
24
|
+
this.browserActions = browserActions;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async read(params: JDataReadParams): Promise<JDataReadResult> {
|
|
28
|
+
const asJson = await this.callServer({ dsName: this.name, read: params });
|
|
29
|
+
return asJson as JDataReadResult;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
isActionEnabled(actionName: string, rows: any[], context?: IActionContext): boolean {
|
|
33
|
+
let actionEntry = this.browserActions[actionName];
|
|
34
|
+
if (!actionEntry) return false;
|
|
35
|
+
if (!actionEntry.canEnable) return true;
|
|
36
|
+
return actionEntry.canEnable(rows, context);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async executeAction(rows: any[], actionName: string, context?: IActionContext): Promise<JActionResult|void> {
|
|
40
|
+
async function processError(res: JActionResult | undefined) {
|
|
41
|
+
if (!res) return true;
|
|
42
|
+
|
|
43
|
+
if (res.isOk===false||res.errorCode||res.errorMessage) {
|
|
44
|
+
if (actionEntry.onError) {
|
|
45
|
+
await actionEntry.onError(res);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let actionEntry = this.browserActions[actionName];
|
|
54
|
+
if (!actionEntry) return;
|
|
55
|
+
|
|
56
|
+
if (actionEntry.action) {
|
|
57
|
+
let res = await actionEntry.action({ rows, context });
|
|
58
|
+
|
|
59
|
+
if (res) {
|
|
60
|
+
if (!processError(res)) return;
|
|
61
|
+
|
|
62
|
+
if (res.rows !== undefined) {
|
|
63
|
+
rows = res.rows;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (actionEntry.disableServerCall === true) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let serverRes = await this.callServer({ action: actionName, rows });
|
|
73
|
+
if (!processError(serverRes)) return;
|
|
74
|
+
|
|
75
|
+
if (actionEntry.afterServerCall) {
|
|
76
|
+
await actionEntry.afterServerCall({
|
|
77
|
+
rows,
|
|
78
|
+
context,
|
|
79
|
+
data: serverRes?.data,
|
|
80
|
+
userMessage: serverRes?.userMessage
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async callServer(data: any): Promise<any> {
|
|
86
|
+
let res = await fetch(this.url, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {"Content-Type": "application/json"},
|
|
89
|
+
body: JSON.stringify(data)
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (res.status !== 200) {
|
|
93
|
+
throw new Error(`Error while calling data source "${this.name}"`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return await res.json();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function toDataTableProxy(params: ProxyParams, browserActions?: JopiTableBrowserActions): JDataTable {
|
|
101
|
+
return new Proxy(params, browserActions || {});
|
|
102
|
+
}
|
|
@@ -516,6 +516,7 @@ export const join = path.join;
|
|
|
516
516
|
export const resolve = path.resolve;
|
|
517
517
|
export const dirname = path.dirname;
|
|
518
518
|
export const extname = path.extname;
|
|
519
|
+
export const relative = path.relative;
|
|
519
520
|
|
|
520
521
|
export const sep = path.sep;
|
|
521
522
|
export const isAbsolute = path.isAbsolute;
|
package/src/jk_memcache/index.ts
CHANGED
|
@@ -202,18 +202,14 @@ export class JkMemCache {
|
|
|
202
202
|
/**
|
|
203
203
|
* Retrieve an item from the cache with its metadata.
|
|
204
204
|
*/
|
|
205
|
-
public getWithMeta<T = any>(key: string, peek = false): { value: T; meta: any } | null {
|
|
205
|
+
public getWithMeta<T = any>(key: string, peek = false): { value: T; meta: any; size: number } | null {
|
|
206
206
|
const entry = this._storage.get(key);
|
|
207
|
+
|
|
207
208
|
if (!entry) return null;
|
|
208
|
-
|
|
209
|
-
if (entry.expiresAt && entry.expiresAt < Date.now()) {
|
|
210
|
-
this.delete(key);
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
209
|
if (!peek) entry.accessCount++;
|
|
215
210
|
|
|
216
211
|
let value: T;
|
|
212
|
+
|
|
217
213
|
if (entry.type === 'buffer') {
|
|
218
214
|
value = entry.value as T;
|
|
219
215
|
} else if (entry.type === 'json') {
|
|
@@ -222,7 +218,7 @@ export class JkMemCache {
|
|
|
222
218
|
value = entry.value as T;
|
|
223
219
|
}
|
|
224
220
|
|
|
225
|
-
return { value, meta: entry.meta };
|
|
221
|
+
return { value, meta: entry.meta, size: entry.size };
|
|
226
222
|
}
|
|
227
223
|
|
|
228
224
|
/**
|
package/src/jk_schemas/index.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
// noinspection JSUnusedGlobalSymbols
|
|
2
|
-
|
|
3
|
-
import {generateUUIDv4} from "jopi-toolkit/jk_tools";
|
|
4
|
-
|
|
5
1
|
//region Validation
|
|
6
2
|
|
|
3
|
+
import type { Translatable } from "jopi-toolkit/jk_tools";
|
|
4
|
+
|
|
7
5
|
/**
|
|
8
6
|
* Throwing this error allows it to be caught
|
|
9
7
|
* when validating an object.
|
|
@@ -174,7 +172,7 @@ interface RegistryEntry {
|
|
|
174
172
|
|
|
175
173
|
export function registerSchema(schemaId: string|undefined, schema: Schema, meta?: any) {
|
|
176
174
|
if (!schemaId) {
|
|
177
|
-
throw new Error("jk_schemas - Schema id required
|
|
175
|
+
throw new Error("jk_schemas - Schema id required");
|
|
178
176
|
}
|
|
179
177
|
|
|
180
178
|
gRegistry[schemaId!] = {schema, meta};
|
|
@@ -251,17 +249,20 @@ class SchemaImpl<T extends SchemaDescriptor> implements Schema {
|
|
|
251
249
|
}
|
|
252
250
|
}
|
|
253
251
|
|
|
254
|
-
export
|
|
255
|
-
[field: string]: Field;
|
|
256
|
-
}
|
|
252
|
+
export type SchemaDescriptor = Record<string, Field>;
|
|
257
253
|
|
|
258
254
|
export interface SchemaMeta {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
255
|
+
/**
|
|
256
|
+
* The title of this schema.
|
|
257
|
+
* Can be translated to languages.
|
|
258
|
+
*/
|
|
259
|
+
title?: Translatable;
|
|
260
|
+
description?: Translatable;
|
|
262
261
|
|
|
263
262
|
normalize?: (allValues: any, checkHelper: ValueCheckingHelper) => void;
|
|
264
263
|
validate?: (allValues: any, checkHelper: ValueCheckingHelper) => void;
|
|
264
|
+
|
|
265
|
+
[key: string]: any;
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
export interface SchemaInfo {
|
|
@@ -415,10 +416,11 @@ export interface ScFieldStore {
|
|
|
415
416
|
}
|
|
416
417
|
|
|
417
418
|
export interface ScField<T, Opt extends boolean> {
|
|
418
|
-
|
|
419
|
+
id: string;
|
|
419
420
|
type: string;
|
|
421
|
+
title?: Translatable;
|
|
420
422
|
|
|
421
|
-
description?:
|
|
423
|
+
description?: Translatable;
|
|
422
424
|
default?: T;
|
|
423
425
|
optional?: Opt;
|
|
424
426
|
|
|
@@ -456,7 +458,7 @@ export interface ScField<T, Opt extends boolean> {
|
|
|
456
458
|
export type Field = ScField<any, any>;
|
|
457
459
|
export type SchemaFieldInfos = Field;
|
|
458
460
|
|
|
459
|
-
type OnlyInfos<T> = Omit<T, "
|
|
461
|
+
type OnlyInfos<T> = Omit<T, "id" | "optional" | "type">;
|
|
460
462
|
|
|
461
463
|
//endregion
|
|
462
464
|
|
|
@@ -471,16 +473,16 @@ export interface ScString<Opt extends boolean = boolean> extends ScField<string,
|
|
|
471
473
|
maxLength?: number;
|
|
472
474
|
errorMessage_maxLength?: string;
|
|
473
475
|
|
|
474
|
-
placeholder?:
|
|
476
|
+
placeholder?: Translatable;
|
|
475
477
|
}
|
|
476
478
|
|
|
477
|
-
export function string<Opt extends boolean>(
|
|
479
|
+
export function string<Opt extends boolean>(id: string, optional: Opt, infos?: OnlyInfos<ScString<Opt>>): ScString<Opt> {
|
|
478
480
|
if (!optional) {
|
|
479
481
|
if (!infos) infos = {};
|
|
480
482
|
if (infos.minLength===undefined) infos.minLength = 1;
|
|
481
483
|
}
|
|
482
484
|
|
|
483
|
-
return {...infos,
|
|
485
|
+
return {...infos, id, optional, type: "string"};
|
|
484
486
|
}
|
|
485
487
|
|
|
486
488
|
byTypeValidator["string"] = (v,f) => {
|
|
@@ -514,8 +516,8 @@ export interface ScBoolean<Opt extends boolean = boolean> extends ScField<boolea
|
|
|
514
516
|
errorMessage_requireFalse?: string;
|
|
515
517
|
}
|
|
516
518
|
|
|
517
|
-
export function boolean<Opt extends boolean>(
|
|
518
|
-
return {...infos,
|
|
519
|
+
export function boolean<Opt extends boolean>(id: string, optional: Opt, infos?: OnlyInfos<ScBoolean<Opt>>): ScBoolean<Opt> {
|
|
520
|
+
return {...infos, id, optional, type: "boolean"};
|
|
519
521
|
}
|
|
520
522
|
|
|
521
523
|
byTypeValidator["boolean"] = (v, f) => {
|
|
@@ -574,8 +576,8 @@ export interface ScNumber<Opt extends boolean = boolean> extends ScField<number,
|
|
|
574
576
|
currency?: string;
|
|
575
577
|
}
|
|
576
578
|
|
|
577
|
-
export function number<Opt extends boolean>(
|
|
578
|
-
return {...infos,
|
|
579
|
+
export function number<Opt extends boolean>(id: string, optional: Opt, infos?: OnlyInfos<ScNumber<Opt>>): ScNumber<Opt> {
|
|
580
|
+
return {...infos, id, optional, type: "number"};
|
|
579
581
|
}
|
|
580
582
|
|
|
581
583
|
export function formatNumber(value: string, fieldNumber: ScNumber, defaultLocalFormat: string = "en-US", defaultCurrency: string = "USD") {
|
|
@@ -616,16 +618,16 @@ byTypeValidator["number"] = (v,f) => {
|
|
|
616
618
|
|
|
617
619
|
//region Currency
|
|
618
620
|
|
|
619
|
-
export function currency<Opt extends boolean>(
|
|
620
|
-
return number(
|
|
621
|
+
export function currency<Opt extends boolean>(id: string, optional: Opt, infos?: OnlyInfos<ScNumber<Opt>>): ScNumber<Opt> {
|
|
622
|
+
return number(id, optional, {...infos, displayType: "currency"})
|
|
621
623
|
}
|
|
622
624
|
|
|
623
625
|
//endregion
|
|
624
626
|
|
|
625
627
|
//region Percent
|
|
626
628
|
|
|
627
|
-
export function percent<Opt extends boolean>(
|
|
628
|
-
return number(
|
|
629
|
+
export function percent<Opt extends boolean>(id: string, optional: Opt, infos?: OnlyInfos<ScNumber<Opt>>): ScNumber<Opt> {
|
|
630
|
+
return number(id, optional, {...infos, displayType: "percent"})
|
|
629
631
|
}
|
|
630
632
|
|
|
631
633
|
|
|
@@ -650,8 +652,8 @@ export interface ScFile<Opt extends boolean> extends ScField<File[], Opt> {
|
|
|
650
652
|
errorMessage_maxFileSize?: string;
|
|
651
653
|
}
|
|
652
654
|
|
|
653
|
-
export function file<Opt extends boolean>(
|
|
654
|
-
return {...infos,
|
|
655
|
+
export function file<Opt extends boolean>(id: string, optional: Opt, infos?: OnlyInfos<ScFile<Opt>>): ScFile<Opt> {
|
|
656
|
+
return {...infos, id, optional, type: "file"};
|
|
655
657
|
}
|
|
656
658
|
|
|
657
659
|
//endregion
|
package/src/jk_tools/index.ts
CHANGED
package/src/jk_compress/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./jBundler_ifServer.ts";
|