arrmatura 4.2.2 → 5.0.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.
- package/README.md +30 -25
- package/commons/auth/UserService.ts +107 -0
- package/commons/auth/index.ts +4 -0
- package/commons/auth/user.xml +66 -0
- package/commons/components/buttons.xml +23 -0
- package/commons/components/index.ts +13 -0
- package/commons/components/inputs.xml +33 -0
- package/commons/components/layouts.xml +77 -0
- package/commons/components/media.xml +21 -0
- package/commons/components/modal.xml +37 -0
- package/commons/components/navigation.xml +59 -0
- package/commons/components/popups.xml +12 -0
- package/commons/components/searchbar.xml +40 -0
- package/commons/components/table.xml +120 -0
- package/commons/components/toasts.xml +13 -0
- package/commons/components/viewport.xml +48 -0
- package/commons/forms/FieldItem.xml +20 -0
- package/commons/forms/FormController.ts +73 -0
- package/commons/forms/Item.ts +68 -0
- package/commons/forms/ItemCollection.ts +152 -0
- package/commons/forms/ItemController.ts +62 -0
- package/commons/forms/MetadataService.ts +45 -0
- package/commons/forms/MultiEnumField.xml +44 -0
- package/commons/forms/MultivalueController.ts +49 -0
- package/commons/forms/SmartareaField.xml +51 -0
- package/commons/forms/SuggestionController.ts +80 -0
- package/commons/forms/SuggestionField.xml +28 -0
- package/commons/forms/fields.xml +138 -0
- package/commons/forms/form.xml +37 -0
- package/commons/forms/index.ts +29 -0
- package/commons/index.ts +6 -0
- package/commons/pipes/index.ts +21 -0
- package/commons/pipes/showCounts.ts +16 -0
- package/commons/services/ErrorHandlingService.ts +11 -0
- package/commons/services/FirebaseService.ts +185 -0
- package/commons/services/GSheetsService.ts +92 -0
- package/commons/services/HeartbeatService.ts +35 -0
- package/commons/services/Invoke.ts +13 -0
- package/commons/services/JsonpService.ts +18 -0
- package/commons/services/Loader.ts +17 -0
- package/commons/services/LocalStorage.ts +46 -0
- package/commons/services/NavigationService.ts +55 -0
- package/commons/services/Service.ts +68 -0
- package/commons/services/ServiceWorker.ts +111 -0
- package/commons/services/ToastService.ts +49 -0
- package/commons/services/index.ts +14 -0
- package/core/Arrmatura.ts +79 -0
- package/core/CNode.ts +112 -0
- package/core/Component.ts +431 -0
- package/core/Platform.ts +3 -0
- package/core/cnodes/composition.ts +100 -0
- package/core/cnodes/conditionals.ts +51 -0
- package/core/cnodes/elementary.ts +45 -0
- package/core/cnodes/iterations.ts +94 -0
- package/core/cnodes/routing.ts +25 -0
- package/core/compileNode.ts +39 -0
- package/core/expression.ts +73 -0
- package/core/index.ts +2 -0
- package/core/register.ts +43 -0
- package/core/utils.ts +25 -0
- package/core-web/WebPlatform.ts +25 -0
- package/core-web/attributes.ts +197 -0
- package/core-web/elements.ts +64 -0
- package/core-web/index.ts +19 -0
- package/core-web/reflow.ts +30 -0
- package/core-web/type.ts +19 -0
- package/docs/index.js +191 -4077
- package/lib/arrayGroupBy.ts +19 -0
- package/lib/arraySortBy.ts +49 -0
- package/lib/arrayToObject.ts +18 -0
- package/lib/codus.ts +25 -0
- package/lib/consts.ts +3 -0
- package/lib/createListeners.ts +12 -0
- package/lib/curry.ts +8 -0
- package/lib/dateFormat.ts +69 -0
- package/lib/dateOf.ts +31 -0
- package/lib/dateParseISO8601.ts +27 -0
- package/lib/fx.ts +62 -0
- package/lib/guid.ts +7 -0
- package/lib/index.ts +19 -0
- package/lib/l10n.ts +40 -0
- package/lib/nextId.ts +9 -0
- package/lib/noop.ts +8 -0
- package/lib/obj.ts +62 -0
- package/lib/predicat.ts +26 -0
- package/lib/resources.ru.ts +20 -0
- package/lib/resources.ts +20 -0
- package/lib/scalar.ts +25 -0
- package/lib/str.ts +76 -0
- package/lib/urls.ts +91 -0
- package/lib/xml.ts +117 -0
- package/package.json +17 -8
- package/docs/index.js.map +0 -1
package/lib/urls.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses string into Url object.
|
|
3
|
+
*/
|
|
4
|
+
export const urlParse = (_s: string): Url => {
|
|
5
|
+
const r: Url = { path: [], params: {}, host: '' };
|
|
6
|
+
if (!_s) {
|
|
7
|
+
return r;
|
|
8
|
+
}
|
|
9
|
+
let p: number;
|
|
10
|
+
let s = _s;
|
|
11
|
+
// extract type:
|
|
12
|
+
p = s.indexOf(':');
|
|
13
|
+
if (p > -1) {
|
|
14
|
+
r.protocol = s.slice(0, p);
|
|
15
|
+
s = s.slice(p + 1);
|
|
16
|
+
}
|
|
17
|
+
// extract hash:
|
|
18
|
+
p = s.indexOf('#');
|
|
19
|
+
if (p > -1) {
|
|
20
|
+
r.hash = decodeURIComponent(s.slice(p + 1));
|
|
21
|
+
s = s.slice(0, p);
|
|
22
|
+
}
|
|
23
|
+
// extract query params:
|
|
24
|
+
p = s.indexOf('?');
|
|
25
|
+
if (p > -1) {
|
|
26
|
+
s.slice(p + 1)
|
|
27
|
+
.replace(/\+/g, ' ')
|
|
28
|
+
.split('&')
|
|
29
|
+
.forEach((param) => {
|
|
30
|
+
const [key, value] = param.split('=');
|
|
31
|
+
if (value) {
|
|
32
|
+
r.params[decodeURIComponent(key)] = decodeURIComponent(value);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
s = s.slice(0, p);
|
|
36
|
+
}
|
|
37
|
+
// host and path:
|
|
38
|
+
r.path = s.split('/').map(decodeURIComponent);
|
|
39
|
+
const path = r.path;
|
|
40
|
+
if (path.length > 2 && !path[0] && !path[1]) {
|
|
41
|
+
path.shift();
|
|
42
|
+
path.shift();
|
|
43
|
+
r.host = path.shift() || '';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return r;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Represents an Url object as a string
|
|
51
|
+
*
|
|
52
|
+
* @param {object} r Url object like `{type, host, path, params, hash }`
|
|
53
|
+
* @returns string in format `type:host/path?params#hash`
|
|
54
|
+
*/
|
|
55
|
+
export const urlStringify = (r: Url): string => {
|
|
56
|
+
let result = '';
|
|
57
|
+
if (!r) {
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
if (r.host) {
|
|
61
|
+
if (r.protocol) {
|
|
62
|
+
result += `${r.protocol}:`;
|
|
63
|
+
}
|
|
64
|
+
result += `//${r.host}`;
|
|
65
|
+
}
|
|
66
|
+
if (r?.path.length) {
|
|
67
|
+
result += `/${r.path.map(encodeURIComponent).join('/')}`;
|
|
68
|
+
}
|
|
69
|
+
const { params } = r;
|
|
70
|
+
|
|
71
|
+
const keys = Object.keys(params).filter((key) => params[key] != null);
|
|
72
|
+
if (keys.length) {
|
|
73
|
+
result += `?${keys
|
|
74
|
+
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
|
|
75
|
+
.join('&')}`.replace(/ /g, '+');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (r.hash) {
|
|
79
|
+
result += `${r.hash[0] === '#' ? '' : '#'}${encodeURIComponent(r.hash)}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return result;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const urlAppendParams = (url: string = '', params: UrlParams = {}): string => {
|
|
86
|
+
const queryString = Object.entries(params)
|
|
87
|
+
?.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
|
88
|
+
.join('&');
|
|
89
|
+
|
|
90
|
+
return [url, queryString].filter(Boolean).join(url.includes('?') ? '&' : '?');
|
|
91
|
+
};
|
package/lib/xml.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { scalarParse } from './scalar';
|
|
2
|
+
|
|
3
|
+
const RE_ATTRS = /([a-z][a-zA-Z0-9-:]+)(="[^"]*"|={[^}]*})?/g;
|
|
4
|
+
const RE_EMPTY = /^\s*$/;
|
|
5
|
+
const RE_XML_COMMENT = /<!--((?!-->)[\s\S])*-->/g;
|
|
6
|
+
const RE_XML_TAG = /(<)(\/?)([a-zа-я][a-zа-я0-9-:]*)((?:\s+[a-z][a-z0-9-:]+(?:="[^"]*"|={[^}]*})?)*)\s*(\/?)>/gi;
|
|
7
|
+
const SINGLE_TAGS = { img: 1, input: 1, br: 1, col: 1 };
|
|
8
|
+
|
|
9
|
+
const RE_XML_ENTITY = /&#?[0-9a-z]{3,5};/g;
|
|
10
|
+
|
|
11
|
+
const SUBST_XML_ENTITY: Record<string, string> = {
|
|
12
|
+
amp: '&',
|
|
13
|
+
gt: '>',
|
|
14
|
+
lt: '<',
|
|
15
|
+
quot: '"',
|
|
16
|
+
nbsp: ' ',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const ESCAPE_XML_ENTITY: Record<string, string> = {
|
|
20
|
+
34: '"',
|
|
21
|
+
38: '&',
|
|
22
|
+
39: ''',
|
|
23
|
+
60: '<',
|
|
24
|
+
62: '>',
|
|
25
|
+
};
|
|
26
|
+
const RE_ESCAPE_XML_ENTITY = /["'&<>]/g;
|
|
27
|
+
|
|
28
|
+
const FN_ESCAPE_XML_ENTITY = (m: string) => ESCAPE_XML_ENTITY[m.charCodeAt(0)];
|
|
29
|
+
|
|
30
|
+
const FN_XML_ENTITY = function (s0: string) {
|
|
31
|
+
const s = s0.substring(1, s0.length - 1);
|
|
32
|
+
return s[0] === '#' ? String.fromCharCode(+s.slice(1)) : SUBST_XML_ENTITY[s] || ' ';
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const skipQoutes = (s: string) => (s[0] === '"' && s[s.length - 1] === '"' ? s.slice(1, -1) : s);
|
|
36
|
+
|
|
37
|
+
export const decodeXmlEntities = (s = '') => s.replace(RE_XML_ENTITY, FN_XML_ENTITY);
|
|
38
|
+
|
|
39
|
+
const addNode = (c: XmlNode, tag: string) => {
|
|
40
|
+
const node: XmlNode = { tag };
|
|
41
|
+
(c.nodes || (c.nodes = [])).push(node);
|
|
42
|
+
|
|
43
|
+
return node;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const parseAttrs = (node: XmlNode, s: string) => {
|
|
47
|
+
if (!s) return;
|
|
48
|
+
node.attrs = {};
|
|
49
|
+
for (let e = RE_ATTRS.exec(s); e; e = RE_ATTRS.exec(s)) {
|
|
50
|
+
const value = !e[2] ? true : scalarParse(decodeXmlEntities(skipQoutes(e[2].slice(1))));
|
|
51
|
+
node.attrs[e[1]] = value;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const escapeXml = (s: string) => (!s ? '' : ('' + s).replace(RE_ESCAPE_XML_ENTITY, FN_ESCAPE_XML_ENTITY));
|
|
56
|
+
|
|
57
|
+
export const attributesToString = (v?: Hash): string | undefined => {
|
|
58
|
+
if (typeof v === 'object') {
|
|
59
|
+
if (Array.isArray(v)) {
|
|
60
|
+
return !v.length ? '[]' : '[' + attributesToString(v[0]) + ' x' + v.length + ']';
|
|
61
|
+
}
|
|
62
|
+
return '{' + Object.keys(v).toString() + '}';
|
|
63
|
+
}
|
|
64
|
+
return v;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export function xmlStringify({ tag, attrs, nodes = [] }: XmlNode, tab = ''): string {
|
|
68
|
+
if (tag === '#text') {
|
|
69
|
+
return `${tab}${escapeXml(String(attrs?.text || ''))}`;
|
|
70
|
+
}
|
|
71
|
+
const sattrs = attributesToString(attrs);
|
|
72
|
+
const ssubs = nodes.map((c) => xmlStringify(c, ` ${tab}`)).join('\n');
|
|
73
|
+
|
|
74
|
+
return `${tab}<${tag}${sattrs}` + (!ssubs ? '/>' : `>\n${ssubs}\n${tab}</${tag}>`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const xmlParse = (_s?: string): XmlNode[] => {
|
|
78
|
+
const ctx: XmlNode[] = [{ tag: '#root' }];
|
|
79
|
+
const s = String(_s).trim().replace(RE_XML_COMMENT, '');
|
|
80
|
+
let lastIndex = 0;
|
|
81
|
+
// head text omitted
|
|
82
|
+
for (let e = RE_XML_TAG.exec(s); e; e = RE_XML_TAG.exec(s)) {
|
|
83
|
+
// preceding text
|
|
84
|
+
const text = e.index && s.slice(lastIndex, e.index);
|
|
85
|
+
if (text && !text.match(RE_EMPTY)) {
|
|
86
|
+
const node = addNode(ctx[0], '#text');
|
|
87
|
+
node.attrs = { text: decodeXmlEntities(text) };
|
|
88
|
+
}
|
|
89
|
+
// closing tag
|
|
90
|
+
if (e[2]) {
|
|
91
|
+
if (ctx[0].tag !== e[3]) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
' XML Parse closing tag does not match at: ' +
|
|
94
|
+
e.index +
|
|
95
|
+
' near ' +
|
|
96
|
+
e.input.slice(Math.max(e.index - 150, 0), e.index) +
|
|
97
|
+
'^^^^' +
|
|
98
|
+
e.input.slice(e.index, Math.min(e.index + 150, e.input.length))
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
ctx.shift();
|
|
102
|
+
} else {
|
|
103
|
+
const elt = addNode(ctx[0], e[3]);
|
|
104
|
+
parseAttrs(elt, e[4].trim());
|
|
105
|
+
// not single tag
|
|
106
|
+
if (!(e[5] || e[3] in SINGLE_TAGS)) {
|
|
107
|
+
ctx.unshift(elt);
|
|
108
|
+
if (ctx.length === 1) {
|
|
109
|
+
throw new Error('Parse error at: ' + e[0]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
lastIndex = RE_XML_TAG.lastIndex;
|
|
114
|
+
}
|
|
115
|
+
// tail text omitted
|
|
116
|
+
return ctx[0].nodes || [];
|
|
117
|
+
};
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arrmatura",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"description": "framework",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "npx webpack-dev-server --hot --contentBase docs",
|
|
7
|
-
"build": "npx webpack-cli",
|
|
7
|
+
"build": "npx webpack-cli --mode production && cp -fv docs/quiz.js public",
|
|
8
|
+
"deploy:host": "firebase use ${NODE_ENV:-default} && firebase deploy --only hosting",
|
|
8
9
|
"release": "npx webpack-cli && npm publish"
|
|
9
10
|
},
|
|
10
11
|
"repository": {
|
|
@@ -15,22 +16,30 @@
|
|
|
15
16
|
"license": "MIT",
|
|
16
17
|
"main": "docs/index.js",
|
|
17
18
|
"files": [
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
19
|
+
"lib",
|
|
20
|
+
"core",
|
|
21
|
+
"core-web",
|
|
22
|
+
"commons"
|
|
21
23
|
],
|
|
22
24
|
"devDependencies": {
|
|
23
25
|
"@babel/cli": "^7.12.1",
|
|
24
26
|
"@babel/core": "^7.12.3",
|
|
25
27
|
"@babel/preset-env": "^7.12.1",
|
|
26
28
|
"babel-loader": "^8.2.1",
|
|
27
|
-
"
|
|
28
|
-
"eslint
|
|
29
|
+
"babel-plugin-module-resolver": "^4.1.0",
|
|
30
|
+
"eslint": "^7.30.0",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^2.27.0",
|
|
32
|
+
"@typescript-eslint/parser": "^2.27.0",
|
|
33
|
+
"eslint-config-airbnb": "^18.2.1",
|
|
34
|
+
"eslint-plugin-jest": "^23.18.0",
|
|
35
|
+
"eslint-plugin-react": "^7.20.3",
|
|
36
|
+
"eslint-plugin-react-hooks": "^4.0.5",
|
|
29
37
|
"eslint-plugin-import": "^2.22.1",
|
|
30
38
|
"eslint-plugin-node": "^11.1.0",
|
|
31
39
|
"eslint-plugin-promise": "^4.2.1",
|
|
32
|
-
"
|
|
40
|
+
"metro-react-native-babel-preset": "^0.66.2",
|
|
33
41
|
"raw-loader": "^4.0.2",
|
|
42
|
+
"typescript": "^4.4.4",
|
|
34
43
|
"webpack": "^4.44.2",
|
|
35
44
|
"webpack-cli": "^3.3.12",
|
|
36
45
|
"webpack-dev-server": "^3.11.0"
|