@es-joy/jsoe 0.0.1

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 (43) hide show
  1. package/.editorconfig +15 -0
  2. package/.eslintignore +7 -0
  3. package/.eslintrc.cjs +120 -0
  4. package/CHANGES.md +5 -0
  5. package/LICENSE-MIT.txt +22 -0
  6. package/README.md +82 -0
  7. package/package.json +101 -0
  8. package/rollup.config.js +29 -0
  9. package/server.js +25 -0
  10. package/src/deepEqual.js +72 -0
  11. package/src/formats/indexedDBKey.js +66 -0
  12. package/src/formats/json.js +64 -0
  13. package/src/formats/schemaAndArbitrary.js +20 -0
  14. package/src/formats/schemaOnly.js +529 -0
  15. package/src/formats/structuredCloning.js +372 -0
  16. package/src/formats.js +229 -0
  17. package/src/fundamentalTypes/BooleanObjectType.js +55 -0
  18. package/src/fundamentalTypes/NumberObjectType.js +41 -0
  19. package/src/fundamentalTypes/StringObjectType.js +37 -0
  20. package/src/fundamentalTypes/arrayReferenceType.js +203 -0
  21. package/src/fundamentalTypes/arrayType.js +898 -0
  22. package/src/fundamentalTypes/bigintType.js +53 -0
  23. package/src/fundamentalTypes/dateType.js +129 -0
  24. package/src/fundamentalTypes/nullType.js +33 -0
  25. package/src/fundamentalTypes/numberType.js +56 -0
  26. package/src/fundamentalTypes/objectReferenceType.js +51 -0
  27. package/src/fundamentalTypes/objectType.js +30 -0
  28. package/src/fundamentalTypes/regexpType.js +95 -0
  29. package/src/fundamentalTypes/sparseUndefinedType.js +43 -0
  30. package/src/fundamentalTypes/stringType.js +31 -0
  31. package/src/fundamentalTypes/undefinedType.js +37 -0
  32. package/src/index.js +7 -0
  33. package/src/subTypes/blobHTMLType.js +160 -0
  34. package/src/subTypes/falseType.js +42 -0
  35. package/src/subTypes/trueType.js +42 -0
  36. package/src/superTypes/InfinitiesSuperType.js +49 -0
  37. package/src/superTypes/SpecialNumberSuperType.js +62 -0
  38. package/src/typeChoices.js +125 -0
  39. package/src/types.js +665 -0
  40. package/src/utils/dialogs.js +115 -0
  41. package/src/utils/jsonPointer.js +89 -0
  42. package/src/utils/templateUtils.js +106 -0
  43. package/src/utils/types.js +6 -0
@@ -0,0 +1,115 @@
1
+ /* eslint-disable promise/avoid-new */
2
+ import {jml, nbsp} from '../../node_modules/jamilih/dist/jml-es.js';
3
+ import {$e} from './templateUtils.js';
4
+
5
+ const localeStrings = {
6
+ submit: 'Submit',
7
+ cancel: 'Cancel',
8
+ ok: 'Ok'
9
+ };
10
+
11
+ // Todo: i18nize
12
+ const dialogs = {
13
+ setLocale (locale = {}) {
14
+ this.localeStrings = {...localeStrings, ...locale};
15
+ },
16
+ makeDialog ({atts = {}, children = [], close, remove = true} = {}) {
17
+ if (close) {
18
+ if (!atts.$on) {
19
+ atts.$on = {};
20
+ }
21
+ if (!atts.$on.close) {
22
+ atts.$on.close = close;
23
+ }
24
+ }
25
+ const dialog = jml('dialog', atts, children, document.body);
26
+ dialog.showModal();
27
+ if (remove) {
28
+ dialog.addEventListener('close', () => {
29
+ dialog.remove();
30
+ });
31
+ }
32
+ return dialog;
33
+ },
34
+ makeSubmitDialog ({submit, submitClass = 'submit', ...args}) {
35
+ const dialog = this.makeCancelDialog(args);
36
+ $e(dialog, `button.${args.cancelClass || 'cancel'}`).before(
37
+ jml('button', {
38
+ class: submitClass,
39
+ $on: {
40
+ click (e) {
41
+ submit.call(this, {e, dialog});
42
+ }
43
+ }
44
+ }, [this.localeStrings.submit]),
45
+ nbsp.repeat(2)
46
+ );
47
+ return dialog;
48
+ },
49
+ makeCancelDialog ({
50
+ submit, // Don't pass this on to `args` if present
51
+ cancel,
52
+ cancelClass = 'cancel', submitClass = 'submit',
53
+ ...args
54
+ }) {
55
+ const dialog = this.makeDialog(args);
56
+ jml('div', {class: submitClass}, [
57
+ ['br'], ['br'],
58
+ ['button', {class: cancelClass, $on: {
59
+ click (e) {
60
+ e.preventDefault();
61
+ if (cancel) {
62
+ if (cancel.call(this, {e, dialog}) === false) {
63
+ return;
64
+ }
65
+ }
66
+ dialog.close();
67
+ }
68
+ }}, [this.localeStrings.cancel]]
69
+ ], dialog);
70
+ return dialog;
71
+ },
72
+ alert (message) {
73
+ message = typeof message === 'string' ? {message} : message;
74
+ const {submitClass = 'submit'} = message;
75
+ ({message} = message);
76
+ return new Promise((resolve, _reject) => {
77
+ const dialog = jml('dialog', [
78
+ message,
79
+ ['br'], ['br'],
80
+ ['div', {class: submitClass}, [
81
+ ['button', {$on: {click () {
82
+ dialog.close();
83
+ resolve();
84
+ }}}, [this.localeStrings.ok]]
85
+ ]]
86
+ ], document.body);
87
+ dialog.showModal();
88
+ });
89
+ },
90
+ confirm ({atts = {}, message, submitClass = 'submit'}) {
91
+ ({message} = typeof message === 'string' ? {message} : message);
92
+ return new Promise((resolve, reject) => {
93
+ const dialog = jml('dialog', atts, [
94
+ message,
95
+ ['br'], ['br'],
96
+ ['div', {class: submitClass}, [
97
+ ['button', {$on: {click () {
98
+ dialog.close();
99
+ resolve();
100
+ }}}, [this.localeStrings.ok]],
101
+ nbsp.repeat(2),
102
+ ['button', {$on: {click () {
103
+ dialog.close();
104
+ reject(new Error('cancelled'));
105
+ }}}, [this.localeStrings.cancel]]
106
+ ]]
107
+ ], document.body);
108
+ dialog.showModal();
109
+ });
110
+ }
111
+ };
112
+
113
+ dialogs.setLocale();
114
+
115
+ export default dialogs;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @param {...string} args
3
+ * @returns {string}
4
+ */
5
+ const makeJSONPointer = (...args) => {
6
+ return '#/' + args.map((path) => {
7
+ return escapeJSONPointer(path);
8
+ }).join('/');
9
+ };
10
+
11
+ /**
12
+ * @param {string} path
13
+ * @returns {string}
14
+ */
15
+ const escapeJSONPointer = (path) => {
16
+ return path.replace(/~/gu, '~0').replace(/\//gu, '~1');
17
+ };
18
+
19
+ /**
20
+ * @param {string} pathPart
21
+ * @returns {string}
22
+ */
23
+ const unescapeJSONPointerPart = (pathPart) => {
24
+ return pathPart.replace(/~([01])/gu, (_n0, n1) => {
25
+ if (n1 === '0') {
26
+ return '~';
27
+ }
28
+ return '/';
29
+ });
30
+ };
31
+
32
+ /**
33
+ * @param {string} path
34
+ * @returns {string[]}
35
+ */
36
+ const getJSONPointerParts = (path) => {
37
+ return path.split('/').slice(1).map(
38
+ (pathPart) => unescapeJSONPointerPart(pathPart)
39
+ );
40
+ };
41
+
42
+ /**
43
+ * @param {ArbitraryObject} obj
44
+ * @param {string} pathPart
45
+ * @returns {ArbitraryObject|string}
46
+ */
47
+ const reduceJSONPointerParts = (obj, pathPart) => {
48
+ if (!(pathPart in obj)) {
49
+ throw new TypeError('Path part not found in object');
50
+ }
51
+ obj = obj[pathPart];
52
+ return obj;
53
+ };
54
+
55
+ /**
56
+ * @param {object} cfg
57
+ * @param {string} cfg.path
58
+ * @param {ArbitraryObject} cfg.obj
59
+ * @returns {string|ArbitraryObject}
60
+ */
61
+ const resolveJSONPointer = ({path, obj}) => {
62
+ return getJSONPointerParts(path).reduce(
63
+ (obj, pathPart) => reduceJSONPointerParts(obj, pathPart),
64
+ obj
65
+ );
66
+ };
67
+
68
+ /**
69
+ * @param {string} path
70
+ * @returns {string}
71
+ */
72
+ const typesonPathToJSONPointer = (path) => {
73
+ if (!path) {
74
+ return path;
75
+ }
76
+ return '/' + path.split('.').map((keyPathComponent) => {
77
+ // Keep `~0` (representing tilde) escaped as same sequence in
78
+ // JSONPointer (that's why we don't just use
79
+ // Typeson's `unescapeKeyPathComponent` + `escapeJSONPointer` here)
80
+ return keyPathComponent.replace(/~1/gu, '.').replace(/\//gu, '~1');
81
+ }).join('/');
82
+ };
83
+
84
+ export {
85
+ makeJSONPointer, escapeJSONPointer,
86
+ unescapeJSONPointerPart, getJSONPointerParts, reduceJSONPointerParts,
87
+ resolveJSONPointer,
88
+ typesonPathToJSONPointer
89
+ };
@@ -0,0 +1,106 @@
1
+
2
+ const nbsp = '\u00A0';
3
+ const upArrow = '\u2191';
4
+ const downArrow = '\u2193';
5
+ const U = {nbsp, upArrow, downArrow};
6
+
7
+ /**
8
+ * @param {string} sel
9
+ * @returns {Element}
10
+ */
11
+ const $ = (sel) => document.querySelector(sel);
12
+
13
+ /**
14
+ * @param {string} sel
15
+ * @returns {Element[]}
16
+ */
17
+ const $$ = (sel) => [...document.querySelectorAll(sel)];
18
+
19
+ /**
20
+ * @param {Element|string} el
21
+ * @param {string} descendentsSel
22
+ * @returns {Element}
23
+ */
24
+ const $e = (el, descendentsSel) => {
25
+ el = typeof el === 'string' ? $(el) : el;
26
+ return el.querySelector(descendentsSel);
27
+ };
28
+
29
+ /**
30
+ * @param {Element|string} el
31
+ * @param {string} descendentsSel
32
+ * @returns {Element[]}
33
+ */
34
+ const $$e = (el, descendentsSel) => {
35
+ el = typeof el === 'string' ? $(el) : el;
36
+ return [...el.querySelectorAll(descendentsSel)];
37
+ };
38
+
39
+ /**
40
+ * @param {Node} node
41
+ * @returns {void}
42
+ */
43
+ const removeChildren = (node) => {
44
+ node = typeof node === 'string' ? $(node) : node;
45
+ while (node.hasChildNodes()) {
46
+ node.lastChild.remove();
47
+ }
48
+ };
49
+
50
+ /**
51
+ * @param {Element|string} sel
52
+ * @returns {void}
53
+ */
54
+ const removeIfExists = (sel) => {
55
+ const el = typeof sel === 'string' ? $(sel) : sel;
56
+ if (el) {
57
+ el.remove();
58
+ }
59
+ };
60
+
61
+ /**
62
+ * @param {Element} el
63
+ * @param {string|string[]} selectors
64
+ * @returns {Element[]}
65
+ */
66
+ const filterChildElements = (el, selectors) => {
67
+ /**
68
+ * @param {Element} el
69
+ * @param {string} sel
70
+ * @returns {Element[]}
71
+ */
72
+ const getMatchingChildrenForElement = (el, sel) => {
73
+ const childElements = el.children;
74
+ const matchingChildElements = [...childElements].filter((el) => {
75
+ return el.matches(sel);
76
+ });
77
+ return matchingChildElements;
78
+ };
79
+ el = typeof el === 'string' ? $(el) : el;
80
+ let filtered = [el];
81
+ selectors = Array.isArray(selectors) ? selectors : [selectors];
82
+ selectors.forEach((sel) => {
83
+ filtered = filtered.reduce((els, childElement) => {
84
+ els.push(...getMatchingChildrenForElement(childElement, sel));
85
+ return els;
86
+ }, []);
87
+ });
88
+ return filtered;
89
+ };
90
+
91
+ /**
92
+ * @param {string} s
93
+ * @returns {string}
94
+ */
95
+ const initialCaps = (s) => {
96
+ return s.charAt(0).toUpperCase() + s.slice(1);
97
+ };
98
+
99
+ const DOM = {removeChildren, removeIfExists, filterChildElements, initialCaps};
100
+
101
+ export {
102
+ U,
103
+ $, $$,
104
+ $e, $$e,
105
+ DOM
106
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @param {unknown} obj
3
+ */
4
+ export const isNullish = (obj) => {
5
+ return obj === null || typeof obj === 'undefined';
6
+ };