@trustme24/flext 1.10.1 → 1.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,198 @@
1
+ import {audit, sum, defineModule, isNumber} from '@/lib';
2
+ import {BaseError, TemplateSyntaxError} from '@/errors';
3
+
4
+
5
+ // Types
6
+
7
+ export type Arg = string|number|null|undefined;
8
+
9
+ export type FlattenFuncArg = number | number[];
10
+
11
+
12
+ // Functions
13
+
14
+ export function op(state: any): number {
15
+ const args: Arg[] = state?.args ?? [];
16
+ const [ a, op, b, ...rest ] = args;
17
+
18
+
19
+ // Defining the functions
20
+
21
+ const handle = (..._args: Arg[]): number => {
22
+ const [ mathOp, ...mathArgs ] = _args;
23
+ const handle = Math[mathOp] ?? null;
24
+
25
+ if (handle)
26
+ return handle(...mathArgs);
27
+ else
28
+ throw new TemplateSyntaxError('Math: Unknown operation: ' + audit(mathOp));
29
+ }
30
+
31
+ const flatten = (..._args: FlattenFuncArg[] | any[]): number[] => {
32
+ const result: number[] = [];
33
+
34
+ for (const arg of _args) {
35
+ if (isNumber(arg))
36
+ result.push(arg);
37
+ else if (Array.isArray(arg) && arg.every(isNumber))
38
+ result.push(...arg);
39
+ else
40
+ throw new BaseError('Math: Unable to sum: The given arguments are not numbers: ' + audit(_args));
41
+ }
42
+
43
+ return result;
44
+ };
45
+
46
+
47
+ // Applying the operation
48
+
49
+ switch (op) {
50
+ case 'plus':
51
+ case 'sum':
52
+ return sum(...flatten(a, b || 0, ...rest));
53
+ case 'minus':
54
+ return Number(a) - Number(b || 0);
55
+ case 'multiply':
56
+ return Number(a) * Number(b || 1);
57
+ case 'divide':
58
+ return Number(a) / Number(b || 1);
59
+ case 'intDivide':
60
+ return Number(a) % Number(b || 1);
61
+ case 'power':
62
+ return Number(a) ** Number(b || 1);
63
+ default:
64
+ return handle(...args);
65
+ }
66
+ }
67
+
68
+ export function plus(state: any): number {
69
+ const args: Arg[] = state?.args ?? [];
70
+ const [ a, b, ...rest ] = args;
71
+
72
+ return op({ ...state, args: [ a, 'plus', b, ...rest ] });
73
+ }
74
+
75
+ export function _sum(state: any): number {
76
+ const args: Arg[] = state?.args ?? [];
77
+ const [ a, b, ...rest ] = args;
78
+
79
+ return op({ ...state, args: [ a, 'sum', b, ...rest ] });
80
+ }
81
+
82
+ export function minus(state: any): number {
83
+ const args: Arg[] = state?.args ?? [];
84
+ const [ a, b ] = args;
85
+
86
+ return op({ ...state, args: [ a, 'minus', b ] });
87
+ }
88
+
89
+ export function multiply(state: any): number {
90
+ const args: Arg[] = state?.args ?? [];
91
+ const [ a, b ] = args;
92
+
93
+ return op({ ...state, args: [ a, 'multiply', b ] });
94
+ }
95
+
96
+ export function divide(state: any): number {
97
+ const args: Arg[] = state?.args ?? [];
98
+ const [ a, b ] = args;
99
+
100
+ return op({ ...state, args: [ a, 'divide', b ] });
101
+ }
102
+
103
+ export function intDivide(state: any): number {
104
+ const args: Arg[] = state?.args ?? [];
105
+ const [ a, b ] = args;
106
+
107
+ return op({ ...state, args: [ a, 'intDivide', b ] });
108
+ }
109
+
110
+ export function power(state: any): number {
111
+ const args: Arg[] = state?.args ?? [];
112
+ const [ a, b ] = args;
113
+
114
+ return op({ ...state, args: [ a, 'power', b ] });
115
+ }
116
+
117
+ export function round(state: any): number {
118
+ const args: Arg[] = state?.args ?? [];
119
+ const [ a, _op ] = args;
120
+
121
+
122
+ // Defining the function
123
+
124
+ const handle = (__op: string, val: Arg): number => op({ ...state, args: [ __op, val ] });
125
+
126
+
127
+ // If the operation is not defined
128
+
129
+ if (!_op) return handle('round', a);
130
+
131
+
132
+ // Applying the operation
133
+
134
+ switch (_op) {
135
+ case 'floor':
136
+ return handle('floor', a);
137
+ case 'ceil':
138
+ return handle('ceil', a);
139
+ case 'trunc':
140
+ return handle('trunc', a);
141
+ default:
142
+ throw new TemplateSyntaxError('Math: Unknown operation: ' + audit(_op));
143
+ }
144
+ }
145
+
146
+ export function percent(state: any): number {
147
+ const args: Arg[] = state?.args ?? [];
148
+ const [ a, b ] = args;
149
+
150
+ if (b === undefined || b === null) {
151
+ return op({ ...state, args: [ 'percent', a ] });
152
+ } else {
153
+ return op({ ...state, args: [ a, 'divide', b, 'multiply', 100 ] });
154
+ }
155
+ }
156
+
157
+ export function sqrt(state: any): number {
158
+ const args: Arg[] = state?.args ?? [];
159
+ const [ a ] = args;
160
+
161
+ return op({ ...state, args: [ 'sqrt', a ] });
162
+ }
163
+
164
+ export function cbrt(state: any): number {
165
+ const args: Arg[] = state?.args ?? [];
166
+ const [ a ] = args;
167
+
168
+ return op({ ...state, args: [ 'cbrt', a ] });
169
+ }
170
+
171
+ export function abs(state: any): number {
172
+ const args: Arg[] = state?.args ?? [];
173
+ const [ a ] = args;
174
+
175
+ return op({ ...state, args: [ 'abs', a ] });
176
+ }
177
+
178
+
179
+ export default defineModule({
180
+ helpers: {
181
+ op: op,
182
+ plus: plus,
183
+ sum: _sum,
184
+ minus: minus,
185
+ mul: multiply,
186
+ multiply: multiply,
187
+ div: divide,
188
+ divide: divide,
189
+ intDivide: intDivide,
190
+ pow: power,
191
+ power: power,
192
+ round: round,
193
+ sqrt: sqrt,
194
+ cbrt: cbrt,
195
+ abs: abs,
196
+ __default: op,
197
+ },
198
+ });
@@ -0,0 +1,27 @@
1
+ import { Obj } from '@/types';
2
+ import { defineModule } from '@/lib';
3
+ import { TemplateError } from '@/errors';
4
+
5
+
6
+ // Functions
7
+
8
+ export function url(state: any): string {
9
+ const flext: Obj = state?.flext ?? {};
10
+ const args: any[] = state?.args ?? [];
11
+ const [ name ] = args;
12
+ const assets = flext?.assets ?? {};
13
+ const asset = assets[name] ?? null;
14
+
15
+ if (asset)
16
+ return URL.createObjectURL(asset);
17
+ else
18
+ throw new TemplateError(`Media: Unable to get the asset: Asset '${name}' does not exist`);
19
+ }
20
+
21
+
22
+ export default defineModule({
23
+ helpers: {
24
+ url: url,
25
+ __default: url,
26
+ },
27
+ });
@@ -0,0 +1,73 @@
1
+ import { Obj } from '@/types';
2
+ import { isNumber, defineModule } from '@/lib';
3
+ import writtenNumber from 'written-number';
4
+ import kkKz from './locales/kkKz.json';
5
+ import localeNames from './localeNames.json';
6
+
7
+
8
+ // Constants
9
+
10
+ export const DEFAULT_LANG = 'en';
11
+
12
+ export const LOCALES: Obj = {
13
+ 'kk-KZ': kkKz,
14
+ };
15
+
16
+
17
+ // Functions
18
+
19
+ export function op(state: any): number|string|boolean {
20
+ const flext: Obj = state?.flext ?? {};
21
+ const args: any[] = state?.args ?? [];
22
+ const namedArgs: Obj = state?.namedArgs ?? {};
23
+ const [ op, number ] = args;
24
+ const { lang, strict } = namedArgs;
25
+
26
+
27
+ // Defining the functions
28
+
29
+ const locale = (lang: string): string | Obj | null => {
30
+ return localeNames[lang] ?? LOCALES[lang] ?? null;
31
+ };
32
+
33
+
34
+ // Getting the locale
35
+
36
+ const newLang = locale(lang) ?? locale(flext?.lang) ?? DEFAULT_LANG;
37
+
38
+
39
+ // Applying the operation
40
+
41
+ switch (op) {
42
+ case 'text':
43
+ return writtenNumber(Number(number), { lang: newLang });
44
+ case 'check':
45
+ return strict ? typeof number === 'number' : isNumber(number);
46
+ default:
47
+ return Number(op);
48
+ }
49
+ }
50
+
51
+ export function text(state: any): string {
52
+ const args: any[] = state?.args ?? [];
53
+ const [ number ] = args;
54
+
55
+ return String(op({ ...state, args: [ 'text', number ] }));
56
+ }
57
+
58
+ export function check(state: any): boolean {
59
+ const args: any[] = state?.args ?? [];
60
+ const [ number ] = args;
61
+
62
+ return op({ ...state, args: [ 'check', number ] }) as boolean;
63
+ }
64
+
65
+
66
+ export default defineModule({
67
+ helpers: {
68
+ op: op,
69
+ text: text,
70
+ check: check,
71
+ __default: op,
72
+ },
73
+ });
@@ -0,0 +1,16 @@
1
+ {
2
+ "ar-EG": "ar",
3
+ "az-AZ": "az",
4
+ "en-IN": "enIndian",
5
+ "en-GB": "uk",
6
+ "en-US": "en",
7
+ "eo": "eo",
8
+ "es-ES": "es",
9
+ "fr-FR": "fr",
10
+ "id-ID": "id",
11
+ "pt-BR": "pt",
12
+ "pt-PT": "ptPT",
13
+ "ru-RU": "ru",
14
+ "tr-TR": "tr",
15
+ "vi-VN": "vi"
16
+ }
@@ -0,0 +1,98 @@
1
+ {
2
+ "useLongScale": false,
3
+ "baseSeparator": " ",
4
+ "unitSeparator": " ",
5
+ "base": {
6
+ "0": "нөл",
7
+ "1": "бір",
8
+ "2": "екі",
9
+ "3": "үш",
10
+ "4": "төрт",
11
+ "5": "бес",
12
+ "6": "алты",
13
+ "7": "жеті",
14
+ "8": "сегіз",
15
+ "9": "тоғыз",
16
+ "10": "он",
17
+ "11": "он бір",
18
+ "12": "он екі",
19
+ "13": "он үш",
20
+ "14": "он төрт",
21
+ "15": "он бес",
22
+ "16": "он алты",
23
+ "17": "он жеті",
24
+ "18": "он сегіз",
25
+ "19": "он тоғыз",
26
+ "20": "жиырма",
27
+ "30": "отыз",
28
+ "40": "қырық",
29
+ "50": "елу",
30
+ "60": "алпыс",
31
+ "70": "жетпіс",
32
+ "80": "сексен",
33
+ "90": "тоқсан",
34
+ "100": "жүз",
35
+ "200": "екі жүз",
36
+ "300": "үш жүз",
37
+ "400": "төрт жүз",
38
+ "500": "бес жүз",
39
+ "600": "алты жүз",
40
+ "700": "жеті жүз",
41
+ "800": "сегіз жүз",
42
+ "900": "тоғыз жүз"
43
+ },
44
+ "alternativeBase": {},
45
+ "units": [
46
+ {
47
+ "useBaseInstead": true,
48
+ "useBaseException": []
49
+ },
50
+ {
51
+ "singular": "мың",
52
+ "plural": "мың"
53
+ },
54
+ {
55
+ "singular": "миллион",
56
+ "plural": "миллион"
57
+ },
58
+ {
59
+ "singular": "миллиард",
60
+ "plural": "миллиард"
61
+ },
62
+ {
63
+ "singular": "триллион",
64
+ "plural": "триллион"
65
+ },
66
+ {
67
+ "singular": "квадриллион",
68
+ "plural": "квадриллион"
69
+ },
70
+ {
71
+ "singular": "квинтиллион",
72
+ "plural": "квинтиллион"
73
+ },
74
+ {
75
+ "singular": "секстиллион",
76
+ "plural": "секстиллион"
77
+ },
78
+ {
79
+ "singular": "септиллион",
80
+ "plural": "септиллион"
81
+ },
82
+ {
83
+ "singular": "октиллион",
84
+ "plural": "октиллион"
85
+ },
86
+ {
87
+ "singular": "нониллион",
88
+ "plural": "нониллион"
89
+ },
90
+ {
91
+ "singular": "дециллион",
92
+ "plural": "дециллион"
93
+ }
94
+ ],
95
+ "unitExceptions": {
96
+ "1000": "мың"
97
+ }
98
+ }
@@ -0,0 +1,41 @@
1
+ import { SafeString } from 'handlebars';
2
+ import { Obj } from '@/types';
3
+ import { defineModule, isNumber, inarr, ensureDate } from '@/lib';
4
+ import { format } from '../date';
5
+
6
+
7
+ // Contents
8
+
9
+ export const DEFAULT_COLOR = 'text-blue-500';
10
+
11
+
12
+ // Functions
13
+
14
+ export function put(state: any): string {
15
+ const args = state?.args ?? [];
16
+ const [ val, fallback ] = args;
17
+ const date = ensureDate(val, false);
18
+
19
+ if (date && !isNumber(val) && !inarr(val, true, false))
20
+ return format(date);
21
+ else
22
+ return val ?? fallback ?? '';
23
+ }
24
+
25
+ export function putWithColor(state: any): SafeString {
26
+ const namedArgs: Obj = state?.namedArgs ?? {};
27
+ const color = namedArgs?.color ?? DEFAULT_COLOR;
28
+
29
+ if (color)
30
+ return new SafeString(`<span class="${color}">${put(state)}</span>`);
31
+ else
32
+ return new SafeString(state);
33
+ }
34
+
35
+
36
+ export default defineModule({
37
+ helpers: {
38
+ noColor: put,
39
+ __default: putWithColor,
40
+ },
41
+ });
@@ -0,0 +1,45 @@
1
+ import { defineModule } from '@/lib';
2
+
3
+
4
+ // Functions
5
+
6
+ export function op(state: any): any[] | boolean {
7
+ const args: any[] = state?.args ?? [];
8
+ const [ op, str ] = args;
9
+
10
+
11
+ // Applying the operation
12
+
13
+ switch (op) {
14
+ case 'json':
15
+ return JSON.parse(str);
16
+ case 'check':
17
+ return typeof str === 'string';
18
+ default:
19
+ return op;
20
+ }
21
+ }
22
+
23
+ export function json(state: any): any[] {
24
+ const args: any[] = state?.args ?? [];
25
+ const [ str ] = args;
26
+
27
+ return op({ ...state, args: [ 'json', str ] }) as any[];
28
+ }
29
+
30
+ export function check(state: any): boolean {
31
+ const args: any[] = state?.args ?? [];
32
+ const [ str ] = args;
33
+
34
+ return op({ ...state, args: [ 'check', str ] }) as boolean;
35
+ }
36
+
37
+
38
+ export default defineModule({
39
+ helpers: {
40
+ op: op,
41
+ json: json,
42
+ check: check,
43
+ __default: op,
44
+ },
45
+ });
@@ -0,0 +1,35 @@
1
+ {
2
+ "compilerOptions": {
3
+ "baseUrl": "..",
4
+ "paths": {
5
+ "@/*": [ "src/*" ]
6
+ },
7
+ "target": "ES2020",
8
+ "useDefineForClassFields": true,
9
+ "module": "ESNext",
10
+ "lib": [ "ES2020", "DOM" ],
11
+ "types": [ "node" ],
12
+ "skipLibCheck": true,
13
+ "resolveJsonModule": true,
14
+ "esModuleInterop": true,
15
+ "allowSyntheticDefaultImports": true,
16
+ "noImplicitAny": false,
17
+
18
+ /* Bundler mode */
19
+ "outDir": "../dist",
20
+ "moduleResolution": "node",
21
+ "isolatedModules": false,
22
+ "moduleDetection": "force",
23
+ "declaration": true,
24
+ "sourceMap": false,
25
+ "emitDeclarationOnly": true,
26
+
27
+ /* Linting */
28
+ "strict": true,
29
+ "strictNullChecks": false,
30
+ "noUnusedLocals": true,
31
+ "noUnusedParameters": true,
32
+ "noFallthroughCasesInSwitch": true
33
+ },
34
+ "include": [ "**/*.ts", "**/*.d.ts" ]
35
+ }
package/src/types.ts ADDED
@@ -0,0 +1,103 @@
1
+ import { AST } from '@handlebars/parser';
2
+
3
+
4
+ // Base Data Types
5
+
6
+ export type Obj<T extends any = any> = Record<string, T>;
7
+
8
+ export type Isset<T extends any> = T extends null|undefined ? false : true;
9
+
10
+ export type IsNumber<T extends any> = T extends number ? true : false;
11
+
12
+ export type IsObject<T extends any, O extends Obj = Obj> = T extends O ? true : false;
13
+
14
+ export type Has<T extends Obj, K extends keyof T> = T[K];
15
+
16
+ export type Inarr<T extends any, A extends any[]> = T extends A[any] ? true : false;
17
+
18
+ export type FieldType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'date' | 'mixed';
19
+
20
+ export type FieldValue = string | number | boolean | Obj | FieldValue[] | null;
21
+
22
+
23
+ // Base Struct Types
24
+
25
+ export type MacroParam = {
26
+ name: string,
27
+ value: string|null,
28
+ };
29
+
30
+ export type Macro = {
31
+ name: string,
32
+ params: MacroParam[],
33
+ };
34
+
35
+ export type FieldValueOption = {
36
+ type: string,
37
+ name: string,
38
+ fieldName: string,
39
+ label?: string|null,
40
+ descr?: string|null,
41
+ value?: FieldValue | null,
42
+ isDisabled: boolean,
43
+ };
44
+
45
+ export type Field = {
46
+ type: FieldType,
47
+ name: string,
48
+ label?: string|null,
49
+ descr?: string|null,
50
+ hint?: string|null,
51
+ min?: Date | number | null,
52
+ max?: Date | number | null,
53
+ minLength?: number|null,
54
+ maxLength?: number|null,
55
+ order?: number|null,
56
+ options?: FieldValueOption[] | null,
57
+ value?: FieldValue,
58
+ isRequired: boolean,
59
+ extra?: {
60
+ macroName?: string|null,
61
+ absoluteOrder?: number|null,
62
+ }
63
+ };
64
+
65
+ export type DataModelNode = {
66
+ name: string,
67
+ $?: DataModelNode[],
68
+ };
69
+
70
+ export type DataModel = DataModelNode & {
71
+ addPath: (path: string, depth?: number) => void,
72
+ };
73
+
74
+ export type MetadataModelNode = DataModelNode & {
75
+ type: FieldType,
76
+ label?: string|null,
77
+ descr?: string|null,
78
+ hint?: string|null,
79
+ min?: Date | number | null,
80
+ max?: Date | number | null,
81
+ minLength?: number|null,
82
+ maxLength?: number|null,
83
+ order?: number|null,
84
+ options?: FieldValueOption[] | null,
85
+ value?: string|null,
86
+ isRequired: boolean,
87
+ extra?: {
88
+ fieldName?: string|null,
89
+ },
90
+ };
91
+
92
+
93
+ // Base Callable Types
94
+
95
+ export type CollectorFilterHandler<T = any> = (val?: T) => boolean;
96
+
97
+ export type GetProcessedTemplateHandler = (val: string) => string;
98
+
99
+ export type GetTemplateAstHandler = (val: string) => AST.Program;
100
+
101
+ export type GetTemplateTitleHandler = (ast: AST.Program) => string[];
102
+
103
+ export type GetTemplateMacroHandler = (ast: AST.Program) => Macro[];