@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,37 @@
1
+ import {$e} from '../utils/templateUtils.js';
2
+
3
+ /**
4
+ * @type {TypeObject}
5
+ */
6
+ const StringObjectType = {
7
+ stringRegex: /^String\(([^)]*)\)$/u,
8
+ toValue (s) {
9
+ /* eslint-disable no-new-wrappers, unicorn/new-for-builtins */
10
+ return {value: new String(s)};
11
+ /* eslint-enable no-new-wrappers, unicorn/new-for-builtins */
12
+ },
13
+ option: ['StringObject'],
14
+ getInput ({root}) {
15
+ return $e(root, 'textarea');
16
+ },
17
+ getValue ({root}) {
18
+ return this.toValue(this.getInput({root}).value).value;
19
+ },
20
+ setValue ({root, value}) {
21
+ this.getInput({root}).value = value;
22
+ },
23
+ viewUI ({value}) {
24
+ return ['span', {dataset: {type: 'StringObject'}}, [
25
+ ['i', ['String(']],
26
+ ['span', [value.valueOf()]],
27
+ ['i', [')']]
28
+ ]];
29
+ },
30
+ editUI ({typeNamespace, value = ''}) {
31
+ return ['div', {dataset: {type: 'StringObject'}}, [
32
+ ['textarea', {name: `${typeNamespace}-StringObject`}, [value]]
33
+ ]];
34
+ }
35
+ };
36
+
37
+ export default StringObjectType;
@@ -0,0 +1,203 @@
1
+ import Types, {getPropertyValueFromLegend} from '../types.js';
2
+ import {$e, $$e, DOM} from '../utils/templateUtils.js';
3
+ import {
4
+ getJSONPointerParts
5
+ } from '../utils/jsonPointer.js';
6
+
7
+ /**
8
+ * @type {TypeObject}
9
+ */
10
+ const arrayReferenceType = {
11
+ option: ['Array reference'],
12
+ type: 'array',
13
+ stringRegex: /^arrayRef\((?:|\/[^)]*)\)$/u,
14
+ toValue (s, {rootHolder, parent, parentPath}) {
15
+ const path = s.slice(`${this.type}Ref(`.length, -1);
16
+ rootHolder.push([this.type, parent, parentPath, path]);
17
+ return {assign: false};
18
+ },
19
+ resolveReference (path, value) {
20
+ let parent = value;
21
+ if (path !== '') {
22
+ getJSONPointerParts(path).forEach((pathPart) => {
23
+ parent = parent[pathPart];
24
+ if (!parent) {
25
+ throw new Error('Bad path');
26
+ }
27
+ });
28
+ }
29
+ return parent;
30
+ },
31
+ stateDependent: {
32
+ structuredCloning: {
33
+ // after: 'sparseArrays',
34
+ after: 'arrayNonindexKeys',
35
+ contexts: ['arrayNonindexKeys', 'object']
36
+ // contexts: ['sparseArrays', 'object']
37
+ }
38
+ },
39
+ getInput ({root}) {
40
+ return $e(root, 'input');
41
+ },
42
+ setValue ({root, value}) {
43
+ this.getInput({root}).value = value;
44
+ },
45
+ getValue ({root, stateObj, currentPath}) {
46
+ const referentPath = this.getInput({root}).value;
47
+ // eslint-disable-next-line max-len -- Long
48
+ /* istanbul ignore else -- ArrayRef will not be a root, so should have stateObj */
49
+ if (stateObj) {
50
+ if (!stateObj.paths) {
51
+ stateObj.paths = {};
52
+ }
53
+ stateObj.paths[currentPath] = {
54
+ referentPath,
55
+ // Todo (low): Should be utilized along with
56
+ // other validation checking
57
+ expectArrayReferent: this.type === 'array'
58
+ };
59
+ stateObj.handlingReference = true;
60
+ }
61
+ console.log(referentPath);
62
+ },
63
+ validate ({root, topRoot}) {
64
+ const {type} = this;
65
+ const input = this.getInput({root});
66
+ const path = input.value;
67
+ const invalidMessage = (message) => {
68
+ return {valid: false, message};
69
+ };
70
+
71
+ if (input.validity.patternMismatch) {
72
+ return invalidMessage(
73
+ 'You must use a path beginning with "/" (or the empty string)'
74
+ );
75
+ }
76
+ if ((/~([^01]|$)/u).test(path)) {
77
+ return invalidMessage(
78
+ 'You must use a valid JSON Pointer (with ' +
79
+ 'tildes followed by 0 or 1)'
80
+ );
81
+ }
82
+
83
+ let referent = topRoot ||
84
+ /* istanbul ignore next -- Should always exist? */
85
+ root;
86
+ const isObjectOrArray = () => {
87
+ return [
88
+ 'array', 'object',
89
+ 'arrayNonindexKeys'
90
+ // 'sparseArrays'
91
+ ].includes(
92
+ Types.getTypeForRoot(referent)
93
+ );
94
+ };
95
+ let message;
96
+ if (path !== '') { // If empty string, referent will be topRoot
97
+ if (getJSONPointerParts(path).some((pathPart, i) => {
98
+ // Todo (low): We should also support `arrayReference` and
99
+ // `objectReference`, but will need to resolve and bear
100
+ // in mind that references may need to be added out of
101
+ // order)
102
+ const legends = DOM.filterChildElements(
103
+ // Ensure we are only getting one array level at a time
104
+ $e(referent, '.arrayItems'), ['fieldset', 'legend']
105
+ );
106
+ const childPropertyValues = legends.map(
107
+ (legend) => getPropertyValueFromLegend(legend)
108
+ );
109
+ const partMatchIndex = childPropertyValues.indexOf(pathPart);
110
+ if (partMatchIndex === -1) {
111
+ message = "Specified path doesn't exist";
112
+ return true;
113
+ }
114
+ referent = $e(
115
+ legends[partMatchIndex].parentElement, 'div[data-type]'
116
+ );
117
+ if (referent === root) {
118
+ message = "Can't reference self";
119
+ return true;
120
+ }
121
+ // Condition that path isn't an object/array
122
+ if (!isObjectOrArray()) {
123
+ message = `Referent portion (at segment ${i}) is ` +
124
+ `not an object or array`;
125
+ return true;
126
+ }
127
+ return false;
128
+ })) {
129
+ return invalidMessage(message);
130
+ }
131
+ }
132
+ // Root can only be an object or array unless it is itself
133
+ // else if (!isObjectOrArray()) {
134
+ // return invalidMessage('Referent is not an object or array');
135
+ // }
136
+
137
+ // UI prevents array/object references at root
138
+ // Condition to forbid path to self
139
+ // if (referent === root) {
140
+ // return invalidMessage("Can't reference self");
141
+ // }
142
+
143
+ // Condition to confirm that referenced element is an array or
144
+ // object (or reference) with the designated `type`
145
+ const referentType = Types.getTypeForRoot(referent);
146
+ const referentBaseType = [
147
+ 'array',
148
+ 'arrayNonindexKeys'
149
+ // 'sparseArrays'
150
+ ].includes(referentType)
151
+ ? 'array'
152
+ : (referentType === 'object'
153
+ ? 'object'
154
+ /* istanbul ignore next -- Bad ref should have been caught earlier */
155
+ : null);
156
+
157
+ if (referentBaseType !== type) {
158
+ return invalidMessage(
159
+ 'Reference must match expected reference type ' +
160
+ '(array or object)'
161
+ );
162
+ }
163
+ return {
164
+ valid: true
165
+ };
166
+ },
167
+ validateAll ({topRoot}) {
168
+ const type = `${this.type}Reference`;
169
+ $$e(topRoot, `div[data-type="${type}"]`).forEach((root) => {
170
+ Types.validate({
171
+ type,
172
+ root,
173
+ topRoot
174
+ });
175
+ });
176
+ },
177
+ viewUI ({value}) {
178
+ return ['i', {
179
+ dataset: {type: `${this.type}Reference`}
180
+ }, [`${this.type}Ref(${value})`]];
181
+ },
182
+ // Note: The `value` here must not be the object itself (the
183
+ // circular object/array) as the `value` usually should be,
184
+ // but instead the array/object path
185
+ editUI ({typeNamespace, value = '' /* , topRoot */}) {
186
+ const {type} = this;
187
+ return ['div', {dataset: {type: `${type}Reference`}}, [
188
+ ['label', [
189
+ `JSON Pointer path to ${type} (leave blank for path to root) `,
190
+ ['input', {
191
+ name: `${typeNamespace}-${type}Reference`,
192
+ type: 'text',
193
+ pattern: '^(|/.*)$',
194
+ value
195
+ }]
196
+ ]]
197
+ // Todo (low): Add button to enable mode (supporting
198
+ // scrolling) for clicking on desired referent element
199
+ ]];
200
+ }
201
+ };
202
+
203
+ export default arrayReferenceType;