@lokascript/semantic 1.0.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/LICENSE +21 -0
- package/README.md +686 -0
- package/dist/browser-ar.ar.global.js +2 -0
- package/dist/browser-core.core.global.js +2 -0
- package/dist/browser-de.de.global.js +2 -0
- package/dist/browser-east-asian.east-asian.global.js +2 -0
- package/dist/browser-en-tr.en-tr.global.js +2 -0
- package/dist/browser-en.en.global.js +2 -0
- package/dist/browser-es-en.es-en.global.js +2 -0
- package/dist/browser-es.es.global.js +2 -0
- package/dist/browser-fr.fr.global.js +2 -0
- package/dist/browser-id.id.global.js +2 -0
- package/dist/browser-ja.ja.global.js +2 -0
- package/dist/browser-ko.ko.global.js +2 -0
- package/dist/browser-lazy.lazy.global.js +2 -0
- package/dist/browser-priority.priority.global.js +2 -0
- package/dist/browser-pt.pt.global.js +2 -0
- package/dist/browser-qu.qu.global.js +2 -0
- package/dist/browser-sw.sw.global.js +2 -0
- package/dist/browser-tr.tr.global.js +2 -0
- package/dist/browser-western.western.global.js +2 -0
- package/dist/browser-zh.zh.global.js +2 -0
- package/dist/browser.global.js +3 -0
- package/dist/browser.global.js.map +1 -0
- package/dist/index.cjs +35051 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3426 -0
- package/dist/index.d.ts +3426 -0
- package/dist/index.js +34890 -0
- package/dist/index.js.map +1 -0
- package/dist/languages/ar.d.ts +78 -0
- package/dist/languages/ar.js +1622 -0
- package/dist/languages/ar.js.map +1 -0
- package/dist/languages/de.d.ts +38 -0
- package/dist/languages/de.js +1168 -0
- package/dist/languages/de.js.map +1 -0
- package/dist/languages/en.d.ts +44 -0
- package/dist/languages/en.js +3491 -0
- package/dist/languages/en.js.map +1 -0
- package/dist/languages/es.d.ts +52 -0
- package/dist/languages/es.js +1493 -0
- package/dist/languages/es.js.map +1 -0
- package/dist/languages/fr.d.ts +37 -0
- package/dist/languages/fr.js +1159 -0
- package/dist/languages/fr.js.map +1 -0
- package/dist/languages/id.d.ts +35 -0
- package/dist/languages/id.js +1152 -0
- package/dist/languages/id.js.map +1 -0
- package/dist/languages/ja.d.ts +53 -0
- package/dist/languages/ja.js +1430 -0
- package/dist/languages/ja.js.map +1 -0
- package/dist/languages/ko.d.ts +51 -0
- package/dist/languages/ko.js +1729 -0
- package/dist/languages/ko.js.map +1 -0
- package/dist/languages/pt.d.ts +37 -0
- package/dist/languages/pt.js +1127 -0
- package/dist/languages/pt.js.map +1 -0
- package/dist/languages/qu.d.ts +36 -0
- package/dist/languages/qu.js +1143 -0
- package/dist/languages/qu.js.map +1 -0
- package/dist/languages/sw.d.ts +35 -0
- package/dist/languages/sw.js +1147 -0
- package/dist/languages/sw.js.map +1 -0
- package/dist/languages/tr.d.ts +45 -0
- package/dist/languages/tr.js +1529 -0
- package/dist/languages/tr.js.map +1 -0
- package/dist/languages/zh.d.ts +58 -0
- package/dist/languages/zh.js +1257 -0
- package/dist/languages/zh.js.map +1 -0
- package/dist/types-C4dcj53L.d.ts +600 -0
- package/package.json +202 -0
- package/src/__test-utils__/index.ts +7 -0
- package/src/__test-utils__/test-helpers.ts +8 -0
- package/src/__types__/test-helpers.ts +122 -0
- package/src/analysis/index.ts +479 -0
- package/src/ast-builder/command-mappers.ts +1133 -0
- package/src/ast-builder/expression-parser/index.ts +41 -0
- package/src/ast-builder/expression-parser/parser.ts +563 -0
- package/src/ast-builder/expression-parser/tokenizer.ts +394 -0
- package/src/ast-builder/expression-parser/types.ts +208 -0
- package/src/ast-builder/index.ts +536 -0
- package/src/ast-builder/value-converters.ts +172 -0
- package/src/bridge.ts +275 -0
- package/src/browser-ar.ts +162 -0
- package/src/browser-core.ts +231 -0
- package/src/browser-de.ts +162 -0
- package/src/browser-east-asian.ts +173 -0
- package/src/browser-en-tr.ts +165 -0
- package/src/browser-en.ts +157 -0
- package/src/browser-es-en.ts +200 -0
- package/src/browser-es.ts +170 -0
- package/src/browser-fr.ts +162 -0
- package/src/browser-id.ts +162 -0
- package/src/browser-ja.ts +162 -0
- package/src/browser-ko.ts +162 -0
- package/src/browser-lazy.ts +189 -0
- package/src/browser-priority.ts +214 -0
- package/src/browser-pt.ts +162 -0
- package/src/browser-qu.ts +162 -0
- package/src/browser-sw.ts +162 -0
- package/src/browser-tr.ts +162 -0
- package/src/browser-western.ts +181 -0
- package/src/browser-zh.ts +162 -0
- package/src/browser.ts +268 -0
- package/src/cache/index.ts +14 -0
- package/src/cache/semantic-cache.ts +344 -0
- package/src/core-bridge.ts +372 -0
- package/src/explicit/converter.ts +258 -0
- package/src/explicit/index.ts +18 -0
- package/src/explicit/parser.ts +236 -0
- package/src/explicit/renderer.ts +424 -0
- package/src/generators/command-schemas.ts +1636 -0
- package/src/generators/event-handler-generator.ts +109 -0
- package/src/generators/index.ts +117 -0
- package/src/generators/language-profiles.ts +139 -0
- package/src/generators/pattern-generator.ts +537 -0
- package/src/generators/profiles/arabic.ts +131 -0
- package/src/generators/profiles/bengali.ts +132 -0
- package/src/generators/profiles/chinese.ts +124 -0
- package/src/generators/profiles/english.ts +113 -0
- package/src/generators/profiles/french.ts +125 -0
- package/src/generators/profiles/german.ts +126 -0
- package/src/generators/profiles/hindi.ts +146 -0
- package/src/generators/profiles/index.ts +46 -0
- package/src/generators/profiles/indonesian.ts +125 -0
- package/src/generators/profiles/italian.ts +139 -0
- package/src/generators/profiles/japanese.ts +149 -0
- package/src/generators/profiles/korean.ts +127 -0
- package/src/generators/profiles/marker-templates.ts +288 -0
- package/src/generators/profiles/ms.ts +130 -0
- package/src/generators/profiles/polish.ts +249 -0
- package/src/generators/profiles/portuguese.ts +115 -0
- package/src/generators/profiles/quechua.ts +113 -0
- package/src/generators/profiles/russian.ts +260 -0
- package/src/generators/profiles/spanish.ts +130 -0
- package/src/generators/profiles/swahili.ts +129 -0
- package/src/generators/profiles/thai.ts +132 -0
- package/src/generators/profiles/tl.ts +128 -0
- package/src/generators/profiles/turkish.ts +124 -0
- package/src/generators/profiles/types.ts +165 -0
- package/src/generators/profiles/ukrainian.ts +270 -0
- package/src/generators/profiles/vietnamese.ts +133 -0
- package/src/generators/schema-error-codes.ts +160 -0
- package/src/generators/schema-validator.ts +391 -0
- package/src/index.ts +429 -0
- package/src/language-building-schema.ts +3170 -0
- package/src/language-loader.ts +394 -0
- package/src/languages/_all.ts +65 -0
- package/src/languages/ar.ts +15 -0
- package/src/languages/bn.ts +16 -0
- package/src/languages/de.ts +15 -0
- package/src/languages/en.ts +29 -0
- package/src/languages/es.ts +15 -0
- package/src/languages/fr.ts +15 -0
- package/src/languages/hi.ts +26 -0
- package/src/languages/id.ts +15 -0
- package/src/languages/index.ts +18 -0
- package/src/languages/it.ts +15 -0
- package/src/languages/ja.ts +15 -0
- package/src/languages/ko.ts +15 -0
- package/src/languages/ms.ts +16 -0
- package/src/languages/pl.ts +18 -0
- package/src/languages/pt.ts +15 -0
- package/src/languages/qu.ts +15 -0
- package/src/languages/ru.ts +26 -0
- package/src/languages/sw.ts +15 -0
- package/src/languages/th.ts +16 -0
- package/src/languages/tl.ts +16 -0
- package/src/languages/tr.ts +15 -0
- package/src/languages/uk.ts +26 -0
- package/src/languages/vi.ts +16 -0
- package/src/languages/zh.ts +15 -0
- package/src/parser/index.ts +15 -0
- package/src/parser/pattern-matcher.ts +1181 -0
- package/src/parser/semantic-parser.ts +573 -0
- package/src/parser/utils/index.ts +35 -0
- package/src/parser/utils/marker-resolution.ts +111 -0
- package/src/parser/utils/possessive-keywords.ts +43 -0
- package/src/parser/utils/role-positioning.ts +70 -0
- package/src/parser/utils/type-validation.ts +134 -0
- package/src/patterns/add/ar.ts +71 -0
- package/src/patterns/add/bn.ts +70 -0
- package/src/patterns/add/hi.ts +69 -0
- package/src/patterns/add/index.ts +87 -0
- package/src/patterns/add/it.ts +61 -0
- package/src/patterns/add/ja.ts +93 -0
- package/src/patterns/add/ko.ts +74 -0
- package/src/patterns/add/ms.ts +30 -0
- package/src/patterns/add/pl.ts +62 -0
- package/src/patterns/add/ru.ts +62 -0
- package/src/patterns/add/th.ts +49 -0
- package/src/patterns/add/tl.ts +30 -0
- package/src/patterns/add/tr.ts +71 -0
- package/src/patterns/add/uk.ts +62 -0
- package/src/patterns/add/vi.ts +61 -0
- package/src/patterns/add/zh.ts +71 -0
- package/src/patterns/builders.ts +207 -0
- package/src/patterns/decrement/bn.ts +70 -0
- package/src/patterns/decrement/de.ts +42 -0
- package/src/patterns/decrement/hi.ts +68 -0
- package/src/patterns/decrement/index.ts +79 -0
- package/src/patterns/decrement/it.ts +69 -0
- package/src/patterns/decrement/ms.ts +30 -0
- package/src/patterns/decrement/pl.ts +58 -0
- package/src/patterns/decrement/ru.ts +58 -0
- package/src/patterns/decrement/th.ts +49 -0
- package/src/patterns/decrement/tl.ts +30 -0
- package/src/patterns/decrement/tr.ts +48 -0
- package/src/patterns/decrement/uk.ts +58 -0
- package/src/patterns/decrement/vi.ts +61 -0
- package/src/patterns/decrement/zh.ts +32 -0
- package/src/patterns/en.ts +302 -0
- package/src/patterns/event-handler/ar.ts +151 -0
- package/src/patterns/event-handler/bn.ts +72 -0
- package/src/patterns/event-handler/de.ts +117 -0
- package/src/patterns/event-handler/en.ts +117 -0
- package/src/patterns/event-handler/es.ts +136 -0
- package/src/patterns/event-handler/fr.ts +117 -0
- package/src/patterns/event-handler/hi.ts +64 -0
- package/src/patterns/event-handler/id.ts +117 -0
- package/src/patterns/event-handler/index.ts +119 -0
- package/src/patterns/event-handler/it.ts +54 -0
- package/src/patterns/event-handler/ja.ts +118 -0
- package/src/patterns/event-handler/ko.ts +133 -0
- package/src/patterns/event-handler/ms.ts +30 -0
- package/src/patterns/event-handler/pl.ts +62 -0
- package/src/patterns/event-handler/pt.ts +117 -0
- package/src/patterns/event-handler/qu.ts +66 -0
- package/src/patterns/event-handler/ru.ts +62 -0
- package/src/patterns/event-handler/shared.ts +270 -0
- package/src/patterns/event-handler/sw.ts +117 -0
- package/src/patterns/event-handler/th.ts +53 -0
- package/src/patterns/event-handler/tl.ts +30 -0
- package/src/patterns/event-handler/tr.ts +170 -0
- package/src/patterns/event-handler/uk.ts +62 -0
- package/src/patterns/event-handler/vi.ts +61 -0
- package/src/patterns/event-handler/zh.ts +150 -0
- package/src/patterns/get/ar.ts +49 -0
- package/src/patterns/get/bn.ts +47 -0
- package/src/patterns/get/de.ts +32 -0
- package/src/patterns/get/hi.ts +52 -0
- package/src/patterns/get/index.ts +83 -0
- package/src/patterns/get/it.ts +56 -0
- package/src/patterns/get/ja.ts +53 -0
- package/src/patterns/get/ko.ts +53 -0
- package/src/patterns/get/ms.ts +30 -0
- package/src/patterns/get/pl.ts +57 -0
- package/src/patterns/get/ru.ts +57 -0
- package/src/patterns/get/th.ts +29 -0
- package/src/patterns/get/tl.ts +30 -0
- package/src/patterns/get/uk.ts +57 -0
- package/src/patterns/get/vi.ts +48 -0
- package/src/patterns/grammar-transformed/index.ts +39 -0
- package/src/patterns/grammar-transformed/ja.ts +1713 -0
- package/src/patterns/grammar-transformed/ko.ts +1311 -0
- package/src/patterns/grammar-transformed/tr.ts +1067 -0
- package/src/patterns/hide/ar.ts +67 -0
- package/src/patterns/hide/bn.ts +47 -0
- package/src/patterns/hide/de.ts +36 -0
- package/src/patterns/hide/hi.ts +61 -0
- package/src/patterns/hide/index.ts +91 -0
- package/src/patterns/hide/it.ts +56 -0
- package/src/patterns/hide/ja.ts +69 -0
- package/src/patterns/hide/ko.ts +69 -0
- package/src/patterns/hide/ms.ts +30 -0
- package/src/patterns/hide/pl.ts +57 -0
- package/src/patterns/hide/ru.ts +57 -0
- package/src/patterns/hide/th.ts +29 -0
- package/src/patterns/hide/tl.ts +30 -0
- package/src/patterns/hide/tr.ts +65 -0
- package/src/patterns/hide/uk.ts +57 -0
- package/src/patterns/hide/vi.ts +56 -0
- package/src/patterns/hide/zh.ts +68 -0
- package/src/patterns/increment/bn.ts +70 -0
- package/src/patterns/increment/de.ts +36 -0
- package/src/patterns/increment/hi.ts +68 -0
- package/src/patterns/increment/index.ts +79 -0
- package/src/patterns/increment/it.ts +69 -0
- package/src/patterns/increment/ms.ts +30 -0
- package/src/patterns/increment/pl.ts +58 -0
- package/src/patterns/increment/ru.ts +58 -0
- package/src/patterns/increment/th.ts +49 -0
- package/src/patterns/increment/tl.ts +30 -0
- package/src/patterns/increment/tr.ts +52 -0
- package/src/patterns/increment/uk.ts +58 -0
- package/src/patterns/increment/vi.ts +61 -0
- package/src/patterns/increment/zh.ts +32 -0
- package/src/patterns/index.ts +84 -0
- package/src/patterns/languages/en/control-flow.ts +93 -0
- package/src/patterns/languages/en/fetch.ts +62 -0
- package/src/patterns/languages/en/index.ts +42 -0
- package/src/patterns/languages/en/repeat.ts +67 -0
- package/src/patterns/languages/en/set.ts +48 -0
- package/src/patterns/languages/en/swap.ts +38 -0
- package/src/patterns/languages/en/temporal.ts +57 -0
- package/src/patterns/put/ar.ts +74 -0
- package/src/patterns/put/bn.ts +53 -0
- package/src/patterns/put/en.ts +74 -0
- package/src/patterns/put/es.ts +74 -0
- package/src/patterns/put/hi.ts +69 -0
- package/src/patterns/put/id.ts +96 -0
- package/src/patterns/put/index.ts +99 -0
- package/src/patterns/put/it.ts +56 -0
- package/src/patterns/put/ja.ts +75 -0
- package/src/patterns/put/ko.ts +67 -0
- package/src/patterns/put/ms.ts +30 -0
- package/src/patterns/put/pl.ts +81 -0
- package/src/patterns/put/ru.ts +85 -0
- package/src/patterns/put/th.ts +32 -0
- package/src/patterns/put/tl.ts +30 -0
- package/src/patterns/put/tr.ts +67 -0
- package/src/patterns/put/uk.ts +85 -0
- package/src/patterns/put/vi.ts +72 -0
- package/src/patterns/put/zh.ts +62 -0
- package/src/patterns/registry.ts +163 -0
- package/src/patterns/remove/ar.ts +71 -0
- package/src/patterns/remove/bn.ts +68 -0
- package/src/patterns/remove/hi.ts +69 -0
- package/src/patterns/remove/index.ts +87 -0
- package/src/patterns/remove/it.ts +69 -0
- package/src/patterns/remove/ja.ts +74 -0
- package/src/patterns/remove/ko.ts +78 -0
- package/src/patterns/remove/ms.ts +30 -0
- package/src/patterns/remove/pl.ts +62 -0
- package/src/patterns/remove/ru.ts +62 -0
- package/src/patterns/remove/th.ts +49 -0
- package/src/patterns/remove/tl.ts +30 -0
- package/src/patterns/remove/tr.ts +78 -0
- package/src/patterns/remove/uk.ts +62 -0
- package/src/patterns/remove/vi.ts +61 -0
- package/src/patterns/remove/zh.ts +72 -0
- package/src/patterns/set/ar.ts +84 -0
- package/src/patterns/set/bn.ts +53 -0
- package/src/patterns/set/de.ts +84 -0
- package/src/patterns/set/es.ts +92 -0
- package/src/patterns/set/fr.ts +88 -0
- package/src/patterns/set/hi.ts +56 -0
- package/src/patterns/set/id.ts +84 -0
- package/src/patterns/set/index.ts +107 -0
- package/src/patterns/set/it.ts +56 -0
- package/src/patterns/set/ja.ts +86 -0
- package/src/patterns/set/ko.ts +85 -0
- package/src/patterns/set/ms.ts +30 -0
- package/src/patterns/set/pl.ts +57 -0
- package/src/patterns/set/pt.ts +84 -0
- package/src/patterns/set/ru.ts +57 -0
- package/src/patterns/set/th.ts +31 -0
- package/src/patterns/set/tl.ts +30 -0
- package/src/patterns/set/tr.ts +107 -0
- package/src/patterns/set/uk.ts +57 -0
- package/src/patterns/set/vi.ts +53 -0
- package/src/patterns/set/zh.ts +84 -0
- package/src/patterns/show/ar.ts +67 -0
- package/src/patterns/show/bn.ts +47 -0
- package/src/patterns/show/de.ts +32 -0
- package/src/patterns/show/fr.ts +32 -0
- package/src/patterns/show/hi.ts +61 -0
- package/src/patterns/show/index.ts +95 -0
- package/src/patterns/show/it.ts +56 -0
- package/src/patterns/show/ja.ts +69 -0
- package/src/patterns/show/ko.ts +73 -0
- package/src/patterns/show/ms.ts +30 -0
- package/src/patterns/show/pl.ts +57 -0
- package/src/patterns/show/ru.ts +57 -0
- package/src/patterns/show/th.ts +29 -0
- package/src/patterns/show/tl.ts +30 -0
- package/src/patterns/show/tr.ts +65 -0
- package/src/patterns/show/uk.ts +57 -0
- package/src/patterns/show/vi.ts +56 -0
- package/src/patterns/show/zh.ts +68 -0
- package/src/patterns/take/ar.ts +51 -0
- package/src/patterns/take/index.ts +31 -0
- package/src/patterns/toggle/ar.ts +61 -0
- package/src/patterns/toggle/bn.ts +70 -0
- package/src/patterns/toggle/en.ts +61 -0
- package/src/patterns/toggle/es.ts +61 -0
- package/src/patterns/toggle/hi.ts +80 -0
- package/src/patterns/toggle/index.ts +95 -0
- package/src/patterns/toggle/it.ts +69 -0
- package/src/patterns/toggle/ja.ts +156 -0
- package/src/patterns/toggle/ko.ts +113 -0
- package/src/patterns/toggle/ms.ts +30 -0
- package/src/patterns/toggle/pl.ts +62 -0
- package/src/patterns/toggle/ru.ts +62 -0
- package/src/patterns/toggle/th.ts +50 -0
- package/src/patterns/toggle/tl.ts +30 -0
- package/src/patterns/toggle/tr.ts +88 -0
- package/src/patterns/toggle/uk.ts +62 -0
- package/src/patterns/toggle/vi.ts +61 -0
- package/src/patterns/toggle/zh.ts +99 -0
- package/src/public-api.ts +286 -0
- package/src/registry.ts +441 -0
- package/src/tokenizers/arabic.ts +723 -0
- package/src/tokenizers/base.ts +1300 -0
- package/src/tokenizers/bengali.ts +289 -0
- package/src/tokenizers/chinese.ts +481 -0
- package/src/tokenizers/english.ts +416 -0
- package/src/tokenizers/french.ts +326 -0
- package/src/tokenizers/german.ts +324 -0
- package/src/tokenizers/hindi.ts +319 -0
- package/src/tokenizers/index.ts +127 -0
- package/src/tokenizers/indonesian.ts +306 -0
- package/src/tokenizers/italian.ts +458 -0
- package/src/tokenizers/japanese.ts +447 -0
- package/src/tokenizers/korean.ts +642 -0
- package/src/tokenizers/morphology/arabic-normalizer.ts +242 -0
- package/src/tokenizers/morphology/french-normalizer.ts +268 -0
- package/src/tokenizers/morphology/german-normalizer.ts +256 -0
- package/src/tokenizers/morphology/index.ts +46 -0
- package/src/tokenizers/morphology/italian-normalizer.ts +329 -0
- package/src/tokenizers/morphology/japanese-normalizer.ts +288 -0
- package/src/tokenizers/morphology/korean-normalizer.ts +428 -0
- package/src/tokenizers/morphology/polish-normalizer.ts +264 -0
- package/src/tokenizers/morphology/portuguese-normalizer.ts +310 -0
- package/src/tokenizers/morphology/spanish-normalizer.ts +327 -0
- package/src/tokenizers/morphology/turkish-normalizer.ts +412 -0
- package/src/tokenizers/morphology/types.ts +211 -0
- package/src/tokenizers/ms.ts +198 -0
- package/src/tokenizers/polish.ts +354 -0
- package/src/tokenizers/portuguese.ts +304 -0
- package/src/tokenizers/quechua.ts +339 -0
- package/src/tokenizers/russian.ts +375 -0
- package/src/tokenizers/spanish.ts +403 -0
- package/src/tokenizers/swahili.ts +303 -0
- package/src/tokenizers/thai.ts +236 -0
- package/src/tokenizers/tl.ts +198 -0
- package/src/tokenizers/turkish.ts +411 -0
- package/src/tokenizers/ukrainian.ts +369 -0
- package/src/tokenizers/vietnamese.ts +410 -0
- package/src/types/grammar-types.ts +617 -0
- package/src/types/unified-profile.ts +267 -0
- package/src/types.ts +709 -0
- package/src/utils/confidence-calculator.ts +147 -0
- package/src/validators/command-validator.ts +380 -0
- package/src/validators/index.ts +15 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema Validation
|
|
3
|
+
*
|
|
4
|
+
* Validates command schemas to catch design issues early:
|
|
5
|
+
* - Ambiguous type combinations (e.g., both 'literal' and 'selector')
|
|
6
|
+
* - Missing required roles for specific commands
|
|
7
|
+
* - Schema inconsistencies
|
|
8
|
+
*
|
|
9
|
+
* This runs at build time in development to catch schema errors before they cause
|
|
10
|
+
* runtime issues.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { CommandSchema } from './command-schemas';
|
|
14
|
+
import type { ActionType } from '../types';
|
|
15
|
+
import {
|
|
16
|
+
type SchemaValidationItem,
|
|
17
|
+
type SchemaValidationSeverity,
|
|
18
|
+
SchemaErrorCodes,
|
|
19
|
+
createSchemaValidationItem,
|
|
20
|
+
} from './schema-error-codes';
|
|
21
|
+
|
|
22
|
+
// Re-export for convenience
|
|
23
|
+
export type { SchemaValidationItem, SchemaValidationSeverity };
|
|
24
|
+
export { SchemaErrorCodes };
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Result from validating a single command schema.
|
|
28
|
+
*
|
|
29
|
+
* The `items` array contains all validation results with machine-readable codes.
|
|
30
|
+
* For backward compatibility, `notes`, `warnings`, and `errors` getters are provided.
|
|
31
|
+
*/
|
|
32
|
+
export interface SchemaValidation {
|
|
33
|
+
action: ActionType;
|
|
34
|
+
/** All validation items with structured codes and severity */
|
|
35
|
+
items: SchemaValidationItem[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Extended validation result with backward-compatible getters.
|
|
40
|
+
*/
|
|
41
|
+
export interface SchemaValidationResult extends SchemaValidation {
|
|
42
|
+
/** @deprecated Use items.filter(i => i.severity === 'note') */
|
|
43
|
+
readonly notes: string[];
|
|
44
|
+
/** @deprecated Use items.filter(i => i.severity === 'warning') */
|
|
45
|
+
readonly warnings: string[];
|
|
46
|
+
/** @deprecated Use items.filter(i => i.severity === 'error') */
|
|
47
|
+
readonly errors: string[];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create a SchemaValidationResult with backward-compatible getters.
|
|
52
|
+
*/
|
|
53
|
+
function createValidationResult(
|
|
54
|
+
action: ActionType,
|
|
55
|
+
items: SchemaValidationItem[]
|
|
56
|
+
): SchemaValidationResult {
|
|
57
|
+
return {
|
|
58
|
+
action,
|
|
59
|
+
items,
|
|
60
|
+
get notes() {
|
|
61
|
+
return items.filter(i => i.severity === 'note').map(i => i.message);
|
|
62
|
+
},
|
|
63
|
+
get warnings() {
|
|
64
|
+
return items.filter(i => i.severity === 'warning').map(i => i.message);
|
|
65
|
+
},
|
|
66
|
+
get errors() {
|
|
67
|
+
return items.filter(i => i.severity === 'error').map(i => i.message);
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Commands where multi-type patient roles are intentional (not ambiguous)
|
|
73
|
+
const MULTI_TYPE_PATIENT_COMMANDS = new Set([
|
|
74
|
+
'put',
|
|
75
|
+
'append',
|
|
76
|
+
'prepend',
|
|
77
|
+
'log',
|
|
78
|
+
'throw',
|
|
79
|
+
'make',
|
|
80
|
+
'measure',
|
|
81
|
+
'return',
|
|
82
|
+
'swap',
|
|
83
|
+
'morph', // DOM manipulation commands that accept various content types
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
// Commands that intentionally have no required roles
|
|
87
|
+
const NO_REQUIRED_ROLES_COMMANDS = new Set([
|
|
88
|
+
'compound',
|
|
89
|
+
'else',
|
|
90
|
+
'halt',
|
|
91
|
+
'continue',
|
|
92
|
+
'async',
|
|
93
|
+
'init',
|
|
94
|
+
'settle',
|
|
95
|
+
'focus',
|
|
96
|
+
'blur',
|
|
97
|
+
'return',
|
|
98
|
+
'js',
|
|
99
|
+
'measure', // Commands with optional-only roles
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Validate a single command schema for potential issues.
|
|
104
|
+
*
|
|
105
|
+
* @param schema - The command schema to validate
|
|
106
|
+
* @returns Validation result with structured items and backward-compatible getters
|
|
107
|
+
*/
|
|
108
|
+
export function validateCommandSchema(schema: CommandSchema): SchemaValidationResult {
|
|
109
|
+
const items: SchemaValidationItem[] = [];
|
|
110
|
+
|
|
111
|
+
// Check for ambiguous type combinations in roles
|
|
112
|
+
for (const role of schema.roles) {
|
|
113
|
+
// Check if a role accepts both 'literal' and 'selector'
|
|
114
|
+
if (role.expectedTypes.includes('literal') && role.expectedTypes.includes('selector')) {
|
|
115
|
+
if (role.role === 'patient' && MULTI_TYPE_PATIENT_COMMANDS.has(schema.action)) {
|
|
116
|
+
// Known pattern - add as note, not warning
|
|
117
|
+
items.push(
|
|
118
|
+
createSchemaValidationItem(
|
|
119
|
+
SchemaErrorCodes.MULTI_TYPE_PATIENT_EXPECTED,
|
|
120
|
+
'note',
|
|
121
|
+
{ role: role.role, command: schema.action },
|
|
122
|
+
role.role
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
} else {
|
|
126
|
+
items.push(
|
|
127
|
+
createSchemaValidationItem(
|
|
128
|
+
SchemaErrorCodes.AMBIGUOUS_TYPE_LITERAL_SELECTOR,
|
|
129
|
+
'warning',
|
|
130
|
+
{ role: role.role },
|
|
131
|
+
role.role
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Warn if a role has too many expected types (> 3)
|
|
138
|
+
if (role.expectedTypes.length > 3 && !MULTI_TYPE_PATIENT_COMMANDS.has(schema.action)) {
|
|
139
|
+
items.push(
|
|
140
|
+
createSchemaValidationItem(
|
|
141
|
+
SchemaErrorCodes.TOO_MANY_EXPECTED_TYPES,
|
|
142
|
+
'warning',
|
|
143
|
+
{ role: role.role, count: role.expectedTypes.length },
|
|
144
|
+
role.role
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Command-specific validation rules
|
|
151
|
+
switch (schema.action) {
|
|
152
|
+
case 'transition':
|
|
153
|
+
validateTransitionSchema(schema, items);
|
|
154
|
+
break;
|
|
155
|
+
|
|
156
|
+
case 'on':
|
|
157
|
+
validateEventHandlerSchema(schema, items);
|
|
158
|
+
break;
|
|
159
|
+
|
|
160
|
+
case 'if':
|
|
161
|
+
case 'unless':
|
|
162
|
+
validateConditionalSchema(schema, items);
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case 'repeat':
|
|
166
|
+
case 'for':
|
|
167
|
+
case 'while':
|
|
168
|
+
validateLoopSchema(schema, items);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Check for schemas with no required roles
|
|
173
|
+
const requiredRoles = schema.roles.filter(r => r.required);
|
|
174
|
+
if (requiredRoles.length === 0) {
|
|
175
|
+
if (NO_REQUIRED_ROLES_COMMANDS.has(schema.action)) {
|
|
176
|
+
// Known pattern - add as note
|
|
177
|
+
items.push(
|
|
178
|
+
createSchemaValidationItem(SchemaErrorCodes.NO_REQUIRED_ROLES_EXPECTED, 'note', {
|
|
179
|
+
command: schema.action,
|
|
180
|
+
})
|
|
181
|
+
);
|
|
182
|
+
} else {
|
|
183
|
+
items.push(createSchemaValidationItem(SchemaErrorCodes.NO_REQUIRED_ROLES, 'warning', {}));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return createValidationResult(schema.action, items);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Validate the transition command schema.
|
|
192
|
+
*/
|
|
193
|
+
function validateTransitionSchema(schema: CommandSchema, items: SchemaValidationItem[]): void {
|
|
194
|
+
const patientRole = schema.roles.find(r => r.role === 'patient');
|
|
195
|
+
const goalRole = schema.roles.find(r => r.role === 'goal');
|
|
196
|
+
|
|
197
|
+
// Check that patient (property name) only accepts literals
|
|
198
|
+
if (patientRole && patientRole.expectedTypes.includes('selector')) {
|
|
199
|
+
items.push(
|
|
200
|
+
createSchemaValidationItem(
|
|
201
|
+
SchemaErrorCodes.TRANSITION_PATIENT_ACCEPTS_SELECTOR,
|
|
202
|
+
'warning',
|
|
203
|
+
{},
|
|
204
|
+
'patient'
|
|
205
|
+
)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Check that transition has a goal role for the target value
|
|
210
|
+
if (patientRole && !goalRole) {
|
|
211
|
+
items.push(createSchemaValidationItem(SchemaErrorCodes.TRANSITION_MISSING_GOAL, 'error', {}));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Validate event handler schemas (on command).
|
|
217
|
+
*/
|
|
218
|
+
function validateEventHandlerSchema(schema: CommandSchema, items: SchemaValidationItem[]): void {
|
|
219
|
+
const eventRole = schema.roles.find(r => r.role === 'event');
|
|
220
|
+
|
|
221
|
+
if (!eventRole) {
|
|
222
|
+
items.push(
|
|
223
|
+
createSchemaValidationItem(SchemaErrorCodes.EVENT_HANDLER_MISSING_EVENT, 'warning', {})
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (eventRole && !eventRole.required) {
|
|
228
|
+
items.push(
|
|
229
|
+
createSchemaValidationItem(SchemaErrorCodes.EVENT_HANDLER_EVENT_NOT_REQUIRED, 'warning', {})
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Validate conditional schemas (if/unless).
|
|
236
|
+
*/
|
|
237
|
+
function validateConditionalSchema(schema: CommandSchema, items: SchemaValidationItem[]): void {
|
|
238
|
+
const conditionRole = schema.roles.find(r => r.role === 'condition');
|
|
239
|
+
|
|
240
|
+
if (!conditionRole) {
|
|
241
|
+
items.push(
|
|
242
|
+
createSchemaValidationItem(SchemaErrorCodes.CONDITIONAL_MISSING_CONDITION, 'warning', {})
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (conditionRole && !conditionRole.required) {
|
|
247
|
+
items.push(
|
|
248
|
+
createSchemaValidationItem(SchemaErrorCodes.CONDITIONAL_CONDITION_NOT_REQUIRED, 'warning', {})
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Validate loop schemas (repeat, for, while).
|
|
255
|
+
*/
|
|
256
|
+
function validateLoopSchema(schema: CommandSchema, items: SchemaValidationItem[]): void {
|
|
257
|
+
// Different loop types have different requirements
|
|
258
|
+
if (schema.action === 'for') {
|
|
259
|
+
const sourceRole = schema.roles.find(r => r.role === 'source');
|
|
260
|
+
if (!sourceRole) {
|
|
261
|
+
items.push(
|
|
262
|
+
createSchemaValidationItem(SchemaErrorCodes.FOR_LOOP_MISSING_SOURCE, 'warning', {})
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
} else if (schema.action === 'while') {
|
|
266
|
+
const conditionRole = schema.roles.find(r => r.role === 'condition');
|
|
267
|
+
if (!conditionRole) {
|
|
268
|
+
items.push(
|
|
269
|
+
createSchemaValidationItem(SchemaErrorCodes.WHILE_LOOP_MISSING_CONDITION, 'warning', {})
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Validate all command schemas in the registry.
|
|
277
|
+
*
|
|
278
|
+
* @param schemas - Map of action names to command schemas
|
|
279
|
+
* @param options - Validation options
|
|
280
|
+
* @returns Map of action names to validation results (only includes schemas with issues)
|
|
281
|
+
*/
|
|
282
|
+
export function validateAllSchemas(
|
|
283
|
+
schemas: Record<string, CommandSchema>,
|
|
284
|
+
options: { includeNotes?: boolean } = {}
|
|
285
|
+
): Map<string, SchemaValidationResult> {
|
|
286
|
+
const results = new Map<string, SchemaValidationResult>();
|
|
287
|
+
const { includeNotes = false } = options;
|
|
288
|
+
|
|
289
|
+
for (const [action, schema] of Object.entries(schemas)) {
|
|
290
|
+
const validation = validateCommandSchema(schema);
|
|
291
|
+
|
|
292
|
+
// Include in results if there are warnings/errors (or notes if requested)
|
|
293
|
+
const hasWarningsOrErrors = validation.items.some(
|
|
294
|
+
i => i.severity === 'warning' || i.severity === 'error'
|
|
295
|
+
);
|
|
296
|
+
const hasNotes = includeNotes && validation.items.some(i => i.severity === 'note');
|
|
297
|
+
|
|
298
|
+
if (hasWarningsOrErrors || hasNotes) {
|
|
299
|
+
results.set(action, validation);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return results;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Format validation results for console output.
|
|
308
|
+
*
|
|
309
|
+
* @param validations - Map of validation results
|
|
310
|
+
* @param options - Formatting options
|
|
311
|
+
* @returns Formatted string for console output
|
|
312
|
+
*/
|
|
313
|
+
export function formatValidationResults(
|
|
314
|
+
validations: Map<string, SchemaValidationResult>,
|
|
315
|
+
options: { showNotes?: boolean; showCodes?: boolean } = {}
|
|
316
|
+
): string {
|
|
317
|
+
const lines: string[] = [];
|
|
318
|
+
const { showNotes = false, showCodes = true } = options;
|
|
319
|
+
|
|
320
|
+
for (const [action, result] of validations) {
|
|
321
|
+
const errors = result.items.filter(i => i.severity === 'error');
|
|
322
|
+
const warnings = result.items.filter(i => i.severity === 'warning');
|
|
323
|
+
const notes = result.items.filter(i => i.severity === 'note');
|
|
324
|
+
|
|
325
|
+
if (errors.length > 0) {
|
|
326
|
+
lines.push(` ❌ ${action}:`);
|
|
327
|
+
for (const item of errors) {
|
|
328
|
+
const codeStr = showCodes ? ` [${item.code}]` : '';
|
|
329
|
+
lines.push(` ERROR${codeStr}: ${item.message}`);
|
|
330
|
+
if (item.suggestion) {
|
|
331
|
+
lines.push(` 💡 Suggestion: ${item.suggestion}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (warnings.length > 0) {
|
|
337
|
+
lines.push(` ⚠️ ${action}:`);
|
|
338
|
+
for (const item of warnings) {
|
|
339
|
+
const codeStr = showCodes ? ` [${item.code}]` : '';
|
|
340
|
+
lines.push(` ${codeStr ? `${item.code}: ` : ''}${item.message}`);
|
|
341
|
+
if (item.suggestion) {
|
|
342
|
+
lines.push(` 💡 ${item.suggestion}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (showNotes && notes.length > 0) {
|
|
348
|
+
lines.push(` ℹ️ ${action}:`);
|
|
349
|
+
for (const item of notes) {
|
|
350
|
+
const codeStr = showCodes ? ` [${item.code}]` : '';
|
|
351
|
+
lines.push(` ${codeStr ? `${item.code}: ` : ''}${item.message}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return lines.join('\n');
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Get validation statistics.
|
|
361
|
+
*/
|
|
362
|
+
export function getValidationStats(validations: Map<string, SchemaValidationResult>): {
|
|
363
|
+
totalCommands: number;
|
|
364
|
+
errors: number;
|
|
365
|
+
warnings: number;
|
|
366
|
+
notes: number;
|
|
367
|
+
byCode: Record<string, number>;
|
|
368
|
+
} {
|
|
369
|
+
let errors = 0;
|
|
370
|
+
let warnings = 0;
|
|
371
|
+
let notes = 0;
|
|
372
|
+
const byCode: Record<string, number> = {};
|
|
373
|
+
|
|
374
|
+
for (const result of validations.values()) {
|
|
375
|
+
for (const item of result.items) {
|
|
376
|
+
if (item.severity === 'error') errors++;
|
|
377
|
+
else if (item.severity === 'warning') warnings++;
|
|
378
|
+
else if (item.severity === 'note') notes++;
|
|
379
|
+
|
|
380
|
+
byCode[item.code] = (byCode[item.code] || 0) + 1;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return {
|
|
385
|
+
totalCommands: validations.size,
|
|
386
|
+
errors,
|
|
387
|
+
warnings,
|
|
388
|
+
notes,
|
|
389
|
+
byCode,
|
|
390
|
+
};
|
|
391
|
+
}
|