@es-joy/jsoe 0.26.1 → 0.28.0
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/.gitignore +10 -0
- package/.npmignore +9 -0
- package/CHANGES.md +76 -0
- package/README.md +6 -4
- package/badges/coverage-badge.svg +1 -1
- package/badges/tests-badge.svg +1 -0
- package/dist/formats/schema.d.ts +11 -0
- package/dist/formats/schema.d.ts.map +1 -1
- package/dist/formats/structuredCloning.d.ts.map +1 -1
- package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
- package/dist/fundamentalTypes/stringType.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/typeChoices.d.ts +32 -2
- package/dist/typeChoices.d.ts.map +1 -1
- package/dist/types.d.ts +8 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/rawTypesonEditor.d.ts +110 -0
- package/dist/utils/rawTypesonEditor.d.ts.map +1 -0
- package/dist/vendor-imports.d.ts +4 -0
- package/docs/proposals/raw-typeson-edit-view.md +575 -0
- package/eslint.config.js +36 -27
- package/mmr.json +6 -0
- package/package.json +22 -12
- package/pnpm-workspace.yaml +4 -2
- package/src/formats/schema.js +38 -7
- package/src/formats/structuredCloning.js +24 -17
- package/src/fundamentalTypes/arrayType.js +135 -7
- package/src/fundamentalTypes/stringType.js +5 -0
- package/src/jsoe.css +12 -0
- package/src/typeChoices.js +39 -8
- package/src/types.js +20 -2
- package/src/utils/rawTypesonEditor.js +669 -0
- package/src/vendor-imports.js +12 -0
- package/tsconfig.json +1 -1
- package/typings/json-6.d.ts +12 -0
- package/vendor/@codemirror/autocomplete/dist/index.js +2125 -0
- package/vendor/@codemirror/commands/dist/index.js +1826 -0
- package/vendor/@codemirror/lang-javascript/dist/index.js +513 -0
- package/vendor/@codemirror/language/dist/index.js +2693 -0
- package/vendor/@codemirror/lint/dist/index.js +956 -0
- package/vendor/@codemirror/search/dist/index.js +1238 -0
- package/vendor/@codemirror/state/dist/index.js +3947 -0
- package/vendor/@codemirror/view/dist/index.js +11867 -0
- package/vendor/@lezer/common/dist/index.js +2202 -0
- package/vendor/@lezer/highlight/dist/index.js +927 -0
- package/vendor/@lezer/javascript/dist/index.js +192 -0
- package/vendor/@lezer/lr/dist/index.js +1889 -0
- package/vendor/@marijn/find-cluster-break/src/index.js +87 -0
- package/vendor/codemirror/dist/index.js +96 -0
- package/vendor/crelt/index.js +28 -0
- package/vendor/json-6/dist/index.mjs +1783 -0
- package/vendor/style-mod/src/style-mod.js +172 -0
- package/vendor/typeson-registry/dist/index.js +83 -10
- package/vendor/w3c-keyname/index.js +119 -0
- package/vendor/zod/classic/checks.d.ts +1 -1
- package/vendor/zod/classic/checks.js +1 -1
- package/vendor/zod/classic/external.d.ts +1 -1
- package/vendor/zod/classic/external.js +1 -1
- package/vendor/zod/classic/from-json-schema.js +245 -24
- package/vendor/zod/classic/schemas.d.ts +17 -1
- package/vendor/zod/classic/schemas.js +77 -29
- package/vendor/zod/core/api.d.ts +6 -4
- package/vendor/zod/core/api.js +17 -2
- package/vendor/zod/core/checks.d.ts +1 -1
- package/vendor/zod/core/checks.js +0 -96
- package/vendor/zod/core/compile.d.ts +18 -4
- package/vendor/zod/core/compile.js +146 -67
- package/vendor/zod/core/doc.js +7 -2
- package/vendor/zod/core/errors.js +2 -5
- package/vendor/zod/core/json-schema-generator.js +2 -2
- package/vendor/zod/core/json-schema-processors.d.ts +17 -0
- package/vendor/zod/core/json-schema-processors.js +195 -64
- package/vendor/zod/core/memoizer.js +72 -23
- package/vendor/zod/core/parse.js +37 -16
- package/vendor/zod/core/regexes.d.ts +2 -0
- package/vendor/zod/core/regexes.js +8 -4
- package/vendor/zod/core/schemas.d.ts +42 -7
- package/vendor/zod/core/schemas.js +301 -94
- package/vendor/zod/core/to-json-schema.d.ts +7 -3
- package/vendor/zod/core/to-json-schema.js +8 -7
- package/vendor/zod/core/util.d.ts +25 -4
- package/vendor/zod/core/util.js +160 -143
- package/vendor/zod/core/versions.d.ts +1 -1
- package/vendor/zod/core/versions.js +2 -2
- package/vendor/zod/core/visit.js +12 -0
- package/vendor/zod/locales/ar.js +1 -0
- package/vendor/zod/locales/az.js +1 -0
- package/vendor/zod/locales/be.js +1 -0
- package/vendor/zod/locales/bg.js +1 -0
- package/vendor/zod/locales/bn.js +1 -0
- package/vendor/zod/locales/ca.js +1 -0
- package/vendor/zod/locales/ckb.js +1 -0
- package/vendor/zod/locales/cs.js +1 -0
- package/vendor/zod/locales/da.js +1 -0
- package/vendor/zod/locales/de.js +1 -0
- package/vendor/zod/locales/el.js +1 -0
- package/vendor/zod/locales/en.js +1 -0
- package/vendor/zod/locales/eo.js +1 -0
- package/vendor/zod/locales/es.js +1 -0
- package/vendor/zod/locales/fa.js +1 -0
- package/vendor/zod/locales/fi.js +1 -0
- package/vendor/zod/locales/fr-CA.js +1 -0
- package/vendor/zod/locales/fr.js +1 -0
- package/vendor/zod/locales/gu.js +1 -0
- package/vendor/zod/locales/he.js +1 -0
- package/vendor/zod/locales/hi.js +1 -0
- package/vendor/zod/locales/hr.js +1 -0
- package/vendor/zod/locales/hu.js +1 -0
- package/vendor/zod/locales/hy.js +1 -0
- package/vendor/zod/locales/id.js +1 -0
- package/vendor/zod/locales/index.d.ts +1 -0
- package/vendor/zod/locales/index.js +1 -0
- package/vendor/zod/locales/is.js +1 -0
- package/vendor/zod/locales/it.js +1 -0
- package/vendor/zod/locales/ja.js +1 -0
- package/vendor/zod/locales/ka.js +1 -0
- package/vendor/zod/locales/km.js +1 -0
- package/vendor/zod/locales/kn.js +1 -0
- package/vendor/zod/locales/ko.js +1 -0
- package/vendor/zod/locales/lt.js +1 -0
- package/vendor/zod/locales/mk.js +1 -0
- package/vendor/zod/locales/ms.js +1 -0
- package/vendor/zod/locales/ne.js +1 -0
- package/vendor/zod/locales/nl.js +1 -0
- package/vendor/zod/locales/nn.js +1 -0
- package/vendor/zod/locales/no.js +1 -0
- package/vendor/zod/locales/ota.js +1 -0
- package/vendor/zod/locales/pl.js +1 -0
- package/vendor/zod/locales/ps.js +1 -0
- package/vendor/zod/locales/pt-BR.js +1 -0
- package/vendor/zod/locales/pt.js +1 -0
- package/vendor/zod/locales/ro.js +1 -0
- package/vendor/zod/locales/ru.js +1 -0
- package/vendor/zod/locales/sk.js +1 -0
- package/vendor/zod/locales/sl.js +1 -0
- package/vendor/zod/locales/sv.js +1 -0
- package/vendor/zod/locales/ta.js +1 -0
- package/vendor/zod/locales/tg.d.ts +4 -0
- package/vendor/zod/locales/tg.js +116 -0
- package/vendor/zod/locales/th.js +1 -0
- package/vendor/zod/locales/tk.js +1 -0
- package/vendor/zod/locales/tr.js +1 -0
- package/vendor/zod/locales/uk.js +1 -0
- package/vendor/zod/locales/ur.js +1 -0
- package/vendor/zod/locales/uz.js +1 -0
- package/vendor/zod/locales/vi.js +1 -0
- package/vendor/zod/locales/yo.js +1 -0
- package/vendor/zod/locales/zh-CN.js +1 -0
- package/vendor/zod/locales/zh-TW.js +1 -0
- package/vendor/zod/mini/checks.d.ts +1 -1
- package/vendor/zod/mini/checks.js +1 -1
- package/vendor/zod/mini/external.d.ts +1 -1
- package/vendor/zod/mini/external.js +1 -1
- package/vendor/zod/mini/schemas.d.ts +8 -0
- package/vendor/zod/mini/schemas.js +19 -2
- package/vendor/zodexy/dist/esm/index.js +34 -1
- package/vendor/zodexy/dist/schema.zodexy.json +18 -0
package/eslint.config.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import ashNazg from 'eslint-config-ash-nazg';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import {
|
|
3
|
+
parser as typescriptEslintParser
|
|
4
|
+
} from 'typescript-eslint';
|
|
5
|
+
|
|
6
|
+
const typescriptEslintEnabled = false;
|
|
5
7
|
|
|
6
8
|
export default [
|
|
7
9
|
{
|
|
8
10
|
name: 'JSOE/Ignores',
|
|
9
11
|
ignores: [
|
|
12
|
+
'.agents',
|
|
10
13
|
'coverage',
|
|
11
14
|
'instrumented',
|
|
12
15
|
'ignore',
|
|
@@ -17,21 +20,23 @@ export default [
|
|
|
17
20
|
'docs'
|
|
18
21
|
]
|
|
19
22
|
},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
...(typescriptEslintEnabled
|
|
24
|
+
? [{
|
|
25
|
+
languageOptions: {
|
|
26
|
+
parser: typescriptEslintParser,
|
|
27
|
+
parserOptions: {
|
|
28
|
+
projectService: {
|
|
29
|
+
// eslint-disable-next-line camelcase -- API
|
|
30
|
+
maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING: 500,
|
|
31
|
+
allowDefaultProject: [
|
|
32
|
+
'*.js', '.ncurc.cjs', 'demo/*.js'
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
tsconfigRootDir: import.meta.dirname
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}]
|
|
39
|
+
: []),
|
|
35
40
|
...ashNazg(['sauron', 'browser']),
|
|
36
41
|
{
|
|
37
42
|
name: 'JSOE/Coverage',
|
|
@@ -106,17 +111,21 @@ export default [
|
|
|
106
111
|
|
|
107
112
|
// Disable in ash-nazg?
|
|
108
113
|
'unicorn/no-top-level-assignment-in-function': 0,
|
|
109
|
-
'unicorn/no-top-level-side-effects': 0
|
|
114
|
+
'unicorn/no-top-level-side-effects': 0,
|
|
110
115
|
|
|
111
116
|
// Good but slow
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
117
|
+
...(typescriptEslintEnabled
|
|
118
|
+
? {
|
|
119
|
+
'jsdoc/no-unnecessary-type-assertion': ['error', {
|
|
120
|
+
checkLiteralConstAssertions: true,
|
|
121
|
+
preferConstToLiteralTuples: true,
|
|
122
|
+
treatAnyAsRedundant: false,
|
|
123
|
+
typesToIgnore: [
|
|
124
|
+
`import('../types.js').SuperTypeObject`
|
|
125
|
+
]
|
|
126
|
+
}]
|
|
127
|
+
}
|
|
128
|
+
: {})
|
|
120
129
|
}
|
|
121
130
|
}
|
|
122
131
|
];
|
package/mmr.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@es-joy/jsoe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -28,14 +28,19 @@
|
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@
|
|
31
|
+
"@codemirror/lang-javascript": "^6.2.5",
|
|
32
|
+
"@codemirror/state": "^6.7.4",
|
|
33
|
+
"@marijn/find-cluster-break": "^1.0.4",
|
|
34
|
+
"@node-static/node-static": "^0.9.2",
|
|
32
35
|
"acorn": "^8.18.0",
|
|
33
|
-
"
|
|
36
|
+
"codemirror": "^6.0.2",
|
|
37
|
+
"jamilih": "0.69.1",
|
|
38
|
+
"json-6": "^1.1.4",
|
|
34
39
|
"mime": "^4.1.0",
|
|
35
40
|
"sceditor": "3.2.1",
|
|
36
|
-
"typeson-registry": "14.
|
|
37
|
-
"zod": "^4.
|
|
38
|
-
"zodexy": "^0.
|
|
41
|
+
"typeson-registry": "14.6.1",
|
|
42
|
+
"zod": "^4.6.1",
|
|
43
|
+
"zodexy": "^0.31.0"
|
|
39
44
|
},
|
|
40
45
|
"devDependencies": {
|
|
41
46
|
"@babel/core": "^8.0.1",
|
|
@@ -55,11 +60,13 @@
|
|
|
55
60
|
"cypress": "^16.0.0",
|
|
56
61
|
"cypress-axe": "^1.7.0",
|
|
57
62
|
"cypress-terminal-report": "^7.3.3",
|
|
58
|
-
"eslint": "^10.
|
|
59
|
-
"eslint-config-ash-nazg": "^43.1.
|
|
63
|
+
"eslint": "^10.10.0",
|
|
64
|
+
"eslint-config-ash-nazg": "^43.1.8",
|
|
60
65
|
"fast-deep-equal": "^3.1.3",
|
|
61
66
|
"jsdom": "^30.0.1",
|
|
62
67
|
"license-badger": "^0.23.0",
|
|
68
|
+
"mocha-badge-generator": "^0.13.0",
|
|
69
|
+
"mocha-multi-reporters": "^1.5.2",
|
|
63
70
|
"npm-run-all": "^4.1.5",
|
|
64
71
|
"nyc": "^18.0.0",
|
|
65
72
|
"open-cli": "^9.0.0",
|
|
@@ -68,7 +75,7 @@
|
|
|
68
75
|
"rollup-plugin-istanbul": "^5.0.0",
|
|
69
76
|
"rollup-plugin-node-builtins": "^2.1.2",
|
|
70
77
|
"typescript": "^6.0.3",
|
|
71
|
-
"typescript-eslint": "^8.
|
|
78
|
+
"typescript-eslint": "^8.70.0",
|
|
72
79
|
"typeson": "^10.3.0",
|
|
73
80
|
"webappfind-demos-samples": "^0.7.0"
|
|
74
81
|
},
|
|
@@ -115,12 +122,15 @@
|
|
|
115
122
|
"copy-zodexy": "cp -R node_modules/zodexy/dist/esm vendor/zodexy/dist && cp node_modules/zodexy/dist/schema.zodexy.json vendor/zodexy/dist/schema.zodexy.json",
|
|
116
123
|
"copy-acorn": "cp -R node_modules/acorn/dist vendor/acorn",
|
|
117
124
|
"copy-mime": "mkdir -p vendor/mime/dist/types && cp node_modules/mime/dist/types/standard.js vendor/mime/dist/types/standard.js && cp node_modules/mime/dist/types/other.js vendor/mime/dist/types/other.js",
|
|
118
|
-
"copy": "
|
|
125
|
+
"copy-json6": "mkdir -p vendor/json-6/dist && cp node_modules/json-6/dist/index.mjs vendor/json-6/dist/index.mjs",
|
|
126
|
+
"copy-codemirror": "mkdir -p vendor/codemirror/dist vendor/@codemirror/lang-javascript/dist vendor/@codemirror/state/dist vendor/@codemirror/view/dist vendor/@codemirror/language/dist vendor/@codemirror/commands/dist vendor/@codemirror/search/dist vendor/@codemirror/autocomplete/dist vendor/@codemirror/lint/dist vendor/@lezer/common/dist vendor/@lezer/highlight/dist vendor/@lezer/lr/dist vendor/@lezer/javascript/dist vendor/@marijn/find-cluster-break/src vendor/crelt vendor/style-mod/src vendor/w3c-keyname && cp node_modules/codemirror/dist/index.js vendor/codemirror/dist/index.js && cp node_modules/@codemirror/lang-javascript/dist/index.js vendor/@codemirror/lang-javascript/dist/index.js && cp node_modules/@codemirror/state/dist/index.js vendor/@codemirror/state/dist/index.js && cp node_modules/@codemirror/view/dist/index.js vendor/@codemirror/view/dist/index.js && cp node_modules/@codemirror/language/dist/index.js vendor/@codemirror/language/dist/index.js && cp node_modules/@codemirror/commands/dist/index.js vendor/@codemirror/commands/dist/index.js && cp node_modules/@codemirror/search/dist/index.js vendor/@codemirror/search/dist/index.js && cp node_modules/@codemirror/autocomplete/dist/index.js vendor/@codemirror/autocomplete/dist/index.js && cp node_modules/@codemirror/lint/dist/index.js vendor/@codemirror/lint/dist/index.js && cp node_modules/@lezer/common/dist/index.js vendor/@lezer/common/dist/index.js && cp node_modules/@lezer/highlight/dist/index.js vendor/@lezer/highlight/dist/index.js && cp node_modules/@lezer/lr/dist/index.js vendor/@lezer/lr/dist/index.js && cp node_modules/@lezer/javascript/dist/index.js vendor/@lezer/javascript/dist/index.js && cp node_modules/@marijn/find-cluster-break/src/index.js vendor/@marijn/find-cluster-break/src/index.js && cp node_modules/crelt/index.js vendor/crelt/index.js && cp node_modules/style-mod/src/style-mod.js vendor/style-mod/src/style-mod.js && cp node_modules/w3c-keyname/index.js vendor/w3c-keyname/index.js",
|
|
127
|
+
"copy": "run-p copy-jamilih copy-typeson-registry copy-zod copy-zodexy copy-acorn copy-mime copy-json6 copy-codemirror",
|
|
119
128
|
"instrument": "NODE_OPTIONS=--max-old-space-size=8192 run-s -c instrument-remove instrument-add copy-index rollup",
|
|
120
129
|
"coveradge": "coveradge badges/coverage-badge.svg",
|
|
121
130
|
"cypress:log": "ELECTRON_ENABLE_LOGGING=1 cypress run; npm run report",
|
|
122
|
-
"cypress": "cypress run --spec cypress/e2e/all.cy.js; npm run report && npm run coveradge",
|
|
123
|
-
"cypress:record": "cypress run --record --parallel",
|
|
131
|
+
"cypress": "rm -Rf .nyc_output && cypress run --browser chrome --reporter=mocha-multi-reporters --reporter-options configFile=mmr.json --spec cypress/e2e/all.cy.js; npm run report && npm run coveradge",
|
|
132
|
+
"cypress:record": "cypress run --browser chrome --record --parallel",
|
|
133
|
+
"cypress:sample-spec": "rm -Rf .nyc_output && cypress run --browser chrome --reporter=mocha-multi-reporters --reporter-options configFile=mmr.json --spec cypress/e2e/subTypes/true.cy.js; npm run report && npm run coveradge",
|
|
124
134
|
"report": "nyc report",
|
|
125
135
|
"test": "npm run eslint && npm run rollup && npm run cypress"
|
|
126
136
|
}
|
package/pnpm-workspace.yaml
CHANGED
|
@@ -13,7 +13,7 @@ minimumReleaseAgeExclude:
|
|
|
13
13
|
- eslint-config-ash-nazg@42.3.0 || 42.5.0 || 43.0.1 || 43.1.0 || 43.1.2 || 43.1.5 || 43.1.6
|
|
14
14
|
- eslint-plugin-jsdoc@64.1.0 || 64.2.1 || 64.3.0 || 64.3.2 || 64.3.3
|
|
15
15
|
- jsdoc-type-pratt-parser@9.1.1 || 9.1.2
|
|
16
|
-
- zodexy@0.21.1 || 0.21.2 || 0.22.0 || 0.23.0 || 0.24.0 || 0.24.1 || 0.25.0 || 0.26.0 || 0.26.1 || 0.27.0 || 0.30.0 || 0.30.1
|
|
16
|
+
- zodexy@0.21.1 || 0.21.2 || 0.22.0 || 0.23.0 || 0.24.0 || 0.24.1 || 0.25.0 || 0.26.0 || 0.26.1 || 0.27.0 || 0.30.0 || 0.30.1 || 0.31.0
|
|
17
17
|
- typeson-registry@13.0.1 || 13.1.0 || 14.4.0 || 14.5.0
|
|
18
18
|
- typeson@10.1.1 || 10.2.0 || 10.3.0
|
|
19
19
|
- '@rollup/rollup-android-arm-eabi@4.63.1'
|
|
@@ -43,7 +43,7 @@ minimumReleaseAgeExclude:
|
|
|
43
43
|
- '@rollup/rollup-win32-x64-msvc@4.63.1'
|
|
44
44
|
- eslint-plugin-escompat@3.11.6 || 3.12.0
|
|
45
45
|
- rollup@4.63.1
|
|
46
|
-
- zod@4.5.2 || 4.5.4
|
|
46
|
+
- zod@4.5.2 || 4.5.4 || 4.6.1
|
|
47
47
|
- '@typescript-eslint/eslint-plugin@8.69.0'
|
|
48
48
|
- '@typescript-eslint/parser@8.69.0'
|
|
49
49
|
- '@typescript-eslint/project-service@8.69.0'
|
|
@@ -55,3 +55,5 @@ minimumReleaseAgeExclude:
|
|
|
55
55
|
- '@typescript-eslint/visitor-keys@8.69.0'
|
|
56
56
|
- typescript-eslint@8.69.0
|
|
57
57
|
- '@types/node@26.4.1'
|
|
58
|
+
- '@node-static/node-static@0.9.2'
|
|
59
|
+
- mocha-multi-reporters@1.5.2
|
package/src/formats/schema.js
CHANGED
|
@@ -43,6 +43,10 @@ const zodexToStructuredCloningTypeMap = new Map([
|
|
|
43
43
|
['array', 'arrayNonindexKeys'],
|
|
44
44
|
|
|
45
45
|
['object', 'object'],
|
|
46
|
+
// `z.properties()` (Zod 4.5+) is a bare named-property shape: like `object`
|
|
47
|
+
// but with no `catchall`/`symbols` and, in Zod, no unknown-key stripping.
|
|
48
|
+
// jsoe edits it through the same `object` UI, keyed off the schema `type`.
|
|
49
|
+
['properties', 'object'],
|
|
46
50
|
|
|
47
51
|
['tuple', 'array'],
|
|
48
52
|
['record', 'object'],
|
|
@@ -190,13 +194,15 @@ const dezerializerCodecs = {
|
|
|
190
194
|
};
|
|
191
195
|
|
|
192
196
|
/**
|
|
197
|
+
* Exported for reuse by `src/utils/rawTypesonEditor.js`, which must enforce
|
|
198
|
+
* the same schema conformance check before accepting a raw-edited value.
|
|
193
199
|
* @param {InstanceType<typeof import('../types.js').default>} types
|
|
194
200
|
* @param {ZodexSchema} schemaObject
|
|
195
201
|
* @param {ZodexSchema} originalShape
|
|
196
202
|
* @param {unknown} value
|
|
197
203
|
* @returns {ReturnType<ReturnType<typeof dezerialize>['safeParse']>}
|
|
198
204
|
*/
|
|
199
|
-
function parseValue (types, schemaObject, originalShape, value) {
|
|
205
|
+
export function parseValue (types, schemaObject, originalShape, value) {
|
|
200
206
|
return dezerialize(schemaObject, {
|
|
201
207
|
checks: getChecks(types),
|
|
202
208
|
codecs: dezerializerCodecs,
|
|
@@ -380,6 +386,17 @@ function mergeMeta (target, source) {
|
|
|
380
386
|
return merged;
|
|
381
387
|
}
|
|
382
388
|
|
|
389
|
+
/**
|
|
390
|
+
* Whether a schema node carries a fixed bag of named property schemas under
|
|
391
|
+
* `properties` - `object` and `z.properties()`. Both are merged the same way
|
|
392
|
+
* across an intersection and both drive the `object` editor UI.
|
|
393
|
+
* @param {ZodexSchema['type']|undefined} type
|
|
394
|
+
* @returns {boolean}
|
|
395
|
+
*/
|
|
396
|
+
function isPropertyBagType (type) {
|
|
397
|
+
return type === 'object' || type === 'properties';
|
|
398
|
+
}
|
|
399
|
+
|
|
383
400
|
/**
|
|
384
401
|
* @param {ZodexSchema} leftItem
|
|
385
402
|
* @param {ZodexSchema} rightItem
|
|
@@ -412,7 +429,7 @@ function mergeSchema (leftItem, rightItem) {
|
|
|
412
429
|
);
|
|
413
430
|
} else if (Object.hasOwn(newLeftObj, prop)) {
|
|
414
431
|
if (newLeftObj[prop] !== val && !deepEqual(newLeftObj[prop], val)) {
|
|
415
|
-
if (leftItem.type
|
|
432
|
+
if (isPropertyBagType(leftItem.type)) {
|
|
416
433
|
throw new Error(
|
|
417
434
|
'Duplicate property ' + prop + ' of value ' +
|
|
418
435
|
JSON.stringify(val) + ' and ' +
|
|
@@ -450,12 +467,14 @@ function mergeSchema (leftItem, rightItem) {
|
|
|
450
467
|
}
|
|
451
468
|
}
|
|
452
469
|
|
|
453
|
-
if (leftItem.type
|
|
470
|
+
if (!isPropertyBagType(leftItem.type) || !isPropertyBagType(rightItem.type)) {
|
|
454
471
|
delete newLeftObj.error;
|
|
455
472
|
return newLeftObj;
|
|
456
473
|
}
|
|
457
474
|
|
|
458
|
-
for (const [prop, val] of Object.entries(
|
|
475
|
+
for (const [prop, val] of Object.entries(
|
|
476
|
+
/** @type {import('zodexy').SzObject} */ (rightItem).properties
|
|
477
|
+
)) {
|
|
459
478
|
if (typeof newLeftObj.properties !== 'string' &&
|
|
460
479
|
Object.hasOwn(newLeftObj.properties, prop)) {
|
|
461
480
|
if (deepEqual(newLeftObj.properties[prop], val)) {
|
|
@@ -594,6 +613,7 @@ export function getTypesForSchema (schemaObject, originalJSON) {
|
|
|
594
613
|
originalJSON
|
|
595
614
|
);
|
|
596
615
|
}
|
|
616
|
+
case 'properties':
|
|
597
617
|
case 'object': {
|
|
598
618
|
const set = new Set();
|
|
599
619
|
// const {properties} = schemaObject;
|
|
@@ -859,7 +879,9 @@ const schema = {
|
|
|
859
879
|
if (['record', 'looseRecord', 'tuple'].includes(schemaObject.type)) {
|
|
860
880
|
return true;
|
|
861
881
|
}
|
|
862
|
-
|
|
882
|
+
// `properties` is a named-property shape like `object`: the per-property
|
|
883
|
+
// controls carry their own schemas, so no value-level reparse is needed.
|
|
884
|
+
return !isPropertyBagType(schemaObject.type) &&
|
|
863
885
|
intersectionSchemas.has(schemaObject);
|
|
864
886
|
},
|
|
865
887
|
validateValue (types, schemaObject, value) {
|
|
@@ -914,16 +936,25 @@ const schema = {
|
|
|
914
936
|
|
|
915
937
|
switch (parentSchema?.type) {
|
|
916
938
|
case 'object':
|
|
939
|
+
case 'properties':
|
|
940
|
+
// A key outside the declared shape: an `object` pins it to its
|
|
941
|
+
// `catchall` if it has one; otherwise (and always for `properties`,
|
|
942
|
+
// which has no `catchall`) its control is offered the unconstrained
|
|
943
|
+
// type choice - as a `looseRecord`'s non-conforming entry is - rather
|
|
944
|
+
// than the bare "unschema'd" fallback. A strict `object` will still
|
|
945
|
+
// strip the key on parse; this only governs how it is edited.
|
|
917
946
|
currentSchema = /** @type {import('zodexy').SzObject} */ (
|
|
918
947
|
parentSchema
|
|
919
948
|
).properties[
|
|
920
949
|
/** @type {string} */ (arrayOrObjectPropertyName)
|
|
921
950
|
];
|
|
922
951
|
if (!currentSchema) {
|
|
952
|
+
mustBeOptional = true;
|
|
923
953
|
currentSchema = /** @type {import('zodexy').SzObject} */ (
|
|
924
954
|
parentSchema
|
|
925
|
-
).catchall
|
|
926
|
-
|
|
955
|
+
).catchall ?? /** @type {import('zodexy').SzType} */ (
|
|
956
|
+
{type: 'unknown'}
|
|
957
|
+
);
|
|
927
958
|
}
|
|
928
959
|
break;
|
|
929
960
|
case 'array':
|
|
@@ -274,23 +274,30 @@ const encapsulateObserver = (stateObj) => {
|
|
|
274
274
|
// console.log('but could set to', schema);
|
|
275
275
|
// console.log('arrayOrObjectPropertyName', arrayOrObjectPropertyName);
|
|
276
276
|
|
|
277
|
-
if (!
|
|
278
|
-
//
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
277
|
+
if (!parents['']) {
|
|
278
|
+
// A caller repopulating an *existing* container in place (e.g. the raw
|
|
279
|
+
// Typeson/JSON6 editor replacing one control's children after a
|
|
280
|
+
// bulk edit, `src/utils/rawTypesonEditor.js`) pre-seeds
|
|
281
|
+
// `stateObj.rootUI` with that container so it is reused here instead
|
|
282
|
+
// of a fresh one being built.
|
|
283
|
+
if (!stateObj.rootUI) {
|
|
284
|
+
// console.log('vvvv0', newType, newValue);
|
|
285
|
+
stateObj.rootUI = types?.getUIForModeAndType({
|
|
286
|
+
readonly,
|
|
287
|
+
typeNamespace,
|
|
288
|
+
type: newType,
|
|
289
|
+
bringIntoFocus: false,
|
|
290
|
+
buildTypeChoices,
|
|
291
|
+
format,
|
|
292
|
+
specificSchemaObject: schema,
|
|
293
|
+
schemaContent,
|
|
294
|
+
value: newValue,
|
|
295
|
+
hasValue: true,
|
|
296
|
+
// Not currently in use but may be convenient for a
|
|
297
|
+
// type wanting the serialized data
|
|
298
|
+
replaced
|
|
299
|
+
});
|
|
300
|
+
}
|
|
294
301
|
parents[''] = /**
|
|
295
302
|
* @type {HTMLElement &
|
|
296
303
|
* {$addAndSetArrayElement: AddAndSetArrayElement}}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
schemaLabel, lastTypeChild, deprecatedClassSuffix
|
|
8
8
|
} from '../utils/schemaMeta.js';
|
|
9
9
|
import dialogs from '../utils/dialogs.js';
|
|
10
|
+
import {openRawEditorDialog} from '../utils/rawTypesonEditor.js';
|
|
10
11
|
import {
|
|
11
12
|
resolveJSONPointer, getJSONPointerParts, reduceJSONPointerParts
|
|
12
13
|
} from '../utils/jsonPointer.js';
|
|
@@ -428,6 +429,13 @@ const arrayType = {
|
|
|
428
429
|
specificSchemaObject?.type === 'looseRecord';
|
|
429
430
|
const tupleMode = specificSchemaObject?.type === 'tuple';
|
|
430
431
|
|
|
432
|
+
// See `docs/proposals/raw-typeson-edit-view.md` §1 for the scope
|
|
433
|
+
// rationale (why `filelist` is included, why record/tuple count).
|
|
434
|
+
const isRawEditable = types.showRawTypesonControls &&
|
|
435
|
+
((type === 'object' || type === 'array' ||
|
|
436
|
+
type === 'set' || type === 'map' || type === 'filelist') ||
|
|
437
|
+
recordMode || tupleMode);
|
|
438
|
+
|
|
431
439
|
/**
|
|
432
440
|
* @param {{
|
|
433
441
|
* itemIndex: number,
|
|
@@ -660,6 +668,31 @@ const arrayType = {
|
|
|
660
668
|
target
|
|
661
669
|
).textContent = arrayContents.hidden ? '+' : '-';
|
|
662
670
|
}}}, ['-']],
|
|
671
|
+
...(isRawEditable
|
|
672
|
+
? /** @type {import('jamilih').JamilihArray[]} */ ([
|
|
673
|
+
nbsp.repeat(2),
|
|
674
|
+
['button', {
|
|
675
|
+
class: 'viewRawTypeson',
|
|
676
|
+
$on: {click (/** @type {Event} */ e) {
|
|
677
|
+
e.preventDefault();
|
|
678
|
+
openRawEditorDialog({
|
|
679
|
+
types,
|
|
680
|
+
format: /** @type {import('../formats.js').AvailableFormat} */ (
|
|
681
|
+
format
|
|
682
|
+
),
|
|
683
|
+
type: /** @type {import('../types.js').AvailableArbitraryType} */ (
|
|
684
|
+
type
|
|
685
|
+
),
|
|
686
|
+
root: /** @type {HTMLDivElement} */ (div),
|
|
687
|
+
topRoot: /** @type {HTMLDivElement} */ (topRoot),
|
|
688
|
+
typeNamespace,
|
|
689
|
+
specificSchemaObject,
|
|
690
|
+
readonly: true
|
|
691
|
+
});
|
|
692
|
+
}}
|
|
693
|
+
}, ['View raw']]
|
|
694
|
+
])
|
|
695
|
+
: []),
|
|
663
696
|
['div', {class: 'arrayContents'}, [
|
|
664
697
|
!recordMode && this.array
|
|
665
698
|
? ['div', {
|
|
@@ -724,6 +757,13 @@ const arrayType = {
|
|
|
724
757
|
specificSchemaObject?.type === 'looseRecord';
|
|
725
758
|
const tupleMode = specificSchemaObject?.type === 'tuple';
|
|
726
759
|
|
|
760
|
+
// See `docs/proposals/raw-typeson-edit-view.md` §1 for the scope
|
|
761
|
+
// rationale (why `filelist` is included, why record/tuple count).
|
|
762
|
+
const isRawEditable = types.showRawTypesonControls &&
|
|
763
|
+
((type === 'object' || type === 'array' ||
|
|
764
|
+
type === 'set' || type === 'map' || type === 'filelist') ||
|
|
765
|
+
recordMode || tupleMode);
|
|
766
|
+
|
|
727
767
|
// A `record` refines `object` but, for legend numbering/reordering, behaves
|
|
728
768
|
// like the array-based types did when it was its own (`array: true`) type.
|
|
729
769
|
const parentIsArrayLike = parentTypeObject.array || recordMode;
|
|
@@ -1628,9 +1668,27 @@ const arrayType = {
|
|
|
1628
1668
|
specificSchemaObject
|
|
1629
1669
|
)?.element;
|
|
1630
1670
|
}
|
|
1631
|
-
|
|
1671
|
+
const objectSchema = /** @type {import('zodexy').SzObject} */ (
|
|
1632
1672
|
specificSchemaObject
|
|
1633
|
-
)
|
|
1673
|
+
);
|
|
1674
|
+
const schemaType = specificSchemaObject?.type;
|
|
1675
|
+
const propSchema = objectSchema?.properties?.[/** @type {string} */ (
|
|
1676
|
+
propName
|
|
1677
|
+
)];
|
|
1678
|
+
if (
|
|
1679
|
+
!propSchema &&
|
|
1680
|
+
(schemaType === 'properties' ||
|
|
1681
|
+
(schemaType === 'object' && !objectSchema.catchall))
|
|
1682
|
+
) {
|
|
1683
|
+
// A key outside the declared shape of a `z.properties()` (which keeps
|
|
1684
|
+
// it) or a `catchall`-less `z.object()` (which strips it on parse but
|
|
1685
|
+
// still shows it while editing): offer the unconstrained type choice
|
|
1686
|
+
// rather than an unschema'd control, as a `looseRecord`'s
|
|
1687
|
+
// non-conforming entry gets. An `object` `catchall` takes precedence
|
|
1688
|
+
// (handled where the per-property schema is chosen elsewhere).
|
|
1689
|
+
return /** @type {import('zodexy').SzType} */ ({type: 'unknown'});
|
|
1690
|
+
}
|
|
1691
|
+
return propSchema;
|
|
1634
1692
|
};
|
|
1635
1693
|
|
|
1636
1694
|
/**
|
|
@@ -2340,6 +2398,34 @@ const arrayType = {
|
|
|
2340
2398
|
).textContent = arrayContents.hidden ? '+' : '-';
|
|
2341
2399
|
}}}, ['-']];
|
|
2342
2400
|
|
|
2401
|
+
const rawEditButton = isRawEditable
|
|
2402
|
+
? [
|
|
2403
|
+
nbsp.repeat(2),
|
|
2404
|
+
['button', {
|
|
2405
|
+
class: 'editRawTypeson',
|
|
2406
|
+
$on: {click (/** @type {Event} */ e) {
|
|
2407
|
+
e.preventDefault();
|
|
2408
|
+
openRawEditorDialog({
|
|
2409
|
+
types,
|
|
2410
|
+
format: /** @type {import('../formats.js').AvailableFormat} */ (
|
|
2411
|
+
format
|
|
2412
|
+
),
|
|
2413
|
+
type: /** @type {import('../types.js').AvailableArbitraryType} */ (
|
|
2414
|
+
type
|
|
2415
|
+
),
|
|
2416
|
+
root: /** @type {HTMLDivElement} */ (div),
|
|
2417
|
+
// By click time `topRoot ||= div` below has already run if
|
|
2418
|
+
// this control is itself the root.
|
|
2419
|
+
topRoot: /** @type {HTMLDivElement} */ (topRoot),
|
|
2420
|
+
typeNamespace,
|
|
2421
|
+
specificSchemaObject,
|
|
2422
|
+
readonly: false
|
|
2423
|
+
});
|
|
2424
|
+
}}
|
|
2425
|
+
}, ['Edit raw']]
|
|
2426
|
+
]
|
|
2427
|
+
: [];
|
|
2428
|
+
|
|
2343
2429
|
const arrayContents = /** @type {import('jamilih').JamilihArray} */ (
|
|
2344
2430
|
['div', {class: 'arrayContents'}, [
|
|
2345
2431
|
arrayContentsFirstChild,
|
|
@@ -2415,7 +2501,8 @@ const arrayType = {
|
|
|
2415
2501
|
* $getTypeChoices: () => HTMLSelectElement & {
|
|
2416
2502
|
* $setType: import('../typeChoices.js').SetType,
|
|
2417
2503
|
* $getTypeRoot: import('../formatAndTypeChoices.js').TypeRootGetter
|
|
2418
|
-
* }
|
|
2504
|
+
* },
|
|
2505
|
+
* $resetItemIndex: () => void
|
|
2419
2506
|
* }} DivArrayOrObjectHolder
|
|
2420
2507
|
*/
|
|
2421
2508
|
|
|
@@ -2567,6 +2654,40 @@ const arrayType = {
|
|
|
2567
2654
|
this.$getAddArrayElement().previousElementSibling
|
|
2568
2655
|
);
|
|
2569
2656
|
},
|
|
2657
|
+
/**
|
|
2658
|
+
* Resets the `itemIndex`/legend-numbering counter back to its
|
|
2659
|
+
* empty-container baseline (`itemAdjust - 1`, the same value
|
|
2660
|
+
* it's initialized to before any item is ever added — *not*
|
|
2661
|
+
* the `-1` the "x All" button below hardcodes, which is only
|
|
2662
|
+
* correct for arrays; an object's baseline is `0`). Exposed so
|
|
2663
|
+
* a caller that repopulates this container's children from
|
|
2664
|
+
* outside this closure (bypassing the normal per-item
|
|
2665
|
+
* add/remove handlers that keep `itemIndex` in sync as they
|
|
2666
|
+
* go) — currently only
|
|
2667
|
+
* `src/utils/rawTypesonEditor.js`'s `commitValueToContainer`,
|
|
2668
|
+
* after a raw-value edit replaces every child — ends up with
|
|
2669
|
+
* exactly the same numbering a fresh container holding the
|
|
2670
|
+
* same new items would have, rather than continuing from
|
|
2671
|
+
* wherever the replaced content had left off (or, using the
|
|
2672
|
+
* wrong baseline, starting one lower than a fresh container
|
|
2673
|
+
* would: a single-property object's only property would be
|
|
2674
|
+
* renumbered from "1" to "0" by a bulk edit that didn't even
|
|
2675
|
+
* change its key, for example).
|
|
2676
|
+
* @this {DivArrayOrObjectHolder}
|
|
2677
|
+
* @returns {void}
|
|
2678
|
+
*/
|
|
2679
|
+
$resetItemIndex () {
|
|
2680
|
+
if (sparse) {
|
|
2681
|
+
decrementItemIndex(
|
|
2682
|
+
/**
|
|
2683
|
+
* @type {HTMLDivElement & {
|
|
2684
|
+
* $getPropertyInputs: GetPropertyInputs
|
|
2685
|
+
}} */ (this.$getArrayItems())
|
|
2686
|
+
);
|
|
2687
|
+
} else {
|
|
2688
|
+
itemIndex = itemAdjust - 1;
|
|
2689
|
+
}
|
|
2690
|
+
},
|
|
2570
2691
|
/**
|
|
2571
2692
|
* @this {DivArrayOrObjectHolder}
|
|
2572
2693
|
* @returns {HTMLSelectElement & {
|
|
@@ -2612,10 +2733,16 @@ const arrayType = {
|
|
|
2612
2733
|
}
|
|
2613
2734
|
}, /** @type {import('jamilih').JamilihChildren} */ ([
|
|
2614
2735
|
[specificSchemaObject ? 'span' : 'b', {
|
|
2615
|
-
title: schemaLabel(specificSchemaObject) ?? (
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2736
|
+
title: schemaLabel(specificSchemaObject) ?? (
|
|
2737
|
+
// `z.properties()` renders through the `object` UI; without a
|
|
2738
|
+
// `meta` label of its own, name it "Properties" rather than an
|
|
2739
|
+
// indistinguishable "Object".
|
|
2740
|
+
specificSchemaObject?.type === 'properties'
|
|
2741
|
+
? 'Properties'
|
|
2742
|
+
: DOM.initialCaps(
|
|
2743
|
+
/** @type {import('../types.js').AvailableType} */
|
|
2744
|
+
(itemType)
|
|
2745
|
+
).replace(/s$/u, ''))
|
|
2619
2746
|
}, [
|
|
2620
2747
|
specificSchemaObject
|
|
2621
2748
|
? '—'
|
|
@@ -2660,6 +2787,7 @@ const arrayType = {
|
|
|
2660
2787
|
}]
|
|
2661
2788
|
: '',
|
|
2662
2789
|
minusButton,
|
|
2790
|
+
...rawEditButton,
|
|
2663
2791
|
arrayContents
|
|
2664
2792
|
]))
|
|
2665
2793
|
);
|
|
@@ -133,6 +133,11 @@ const stringType = {
|
|
|
133
133
|
return `Value doesn't match credit card pattern.`;
|
|
134
134
|
}
|
|
135
135
|
break;
|
|
136
|
+
case 'iban':
|
|
137
|
+
if (!regexes.iban.test(value)) {
|
|
138
|
+
return `Value doesn't match iban pattern.`;
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
136
141
|
case 'ip':
|
|
137
142
|
switch ('version' in stringSchemaObject &&
|
|
138
143
|
stringSchemaObject.version) {
|
package/src/jsoe.css
CHANGED
|
@@ -139,6 +139,18 @@ video.recordedMedia {
|
|
|
139
139
|
height: 300px;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
+
.jsoe-raw-editor {
|
|
143
|
+
width: 500px;
|
|
144
|
+
max-width: 100%;
|
|
145
|
+
height: 300px;
|
|
146
|
+
overflow: auto;
|
|
147
|
+
border: 1px solid;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.jsoe-raw-editor-error:not(:empty) {
|
|
151
|
+
color: #b00;
|
|
152
|
+
}
|
|
153
|
+
|
|
142
154
|
.visualizer {
|
|
143
155
|
height: 60px;
|
|
144
156
|
}
|