@kform/core
Version:
JavaScript bindings for KForm.
1 lines • 219 kB
Source Map (JSON)
{"version":3,"sources":["../../../../../../src/jsMain/kotlin/AbsolutePathJs.kt","../../../../../../src/jsMain/kotlin/PathJs.kt","js/src/kotlin/kotlin.kt","common/src/generated/_Arrays.kt","../../../../../../src/jsMain/kotlin/internal/FunctionArguments.kt","js/src/kotlin/collectionJs.kt","src/kotlin/util/Standard.kt","../../../../../../src/jsMain/kotlin/EventsJs.kt","../../../../../../src/jsMain/kotlin/FormManagerJs.kt","../../../../../../src/jsMain/kotlin/FormUtilsJs.kt","../../../../../../src/jsMain/kotlin/InfoJs.kt","../../../../../../src/jsMain/kotlin/PathFragmentsJs.kt","../../../../../../src/jsMain/kotlin/SchemasJs.kt","../../../../../../src/jsMain/kotlin/TypeInfoJs.kt","../../../../../../src/jsMain/kotlin/ValidationIssuesJs.kt","../../../../../../src/jsMain/kotlin/ValidationsJs.kt","../../../../../../src/jsMain/kotlin/internal/MapUtils.kt","src/kotlin/text/Strings.kt","../../../../../../src/jsMain/kotlin/collections/PathMultimapJs.kt","common/src/generated/_Collections.kt","../../../../../../src/jsMain/kotlin/schemas/ArraySchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/DateSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/ObjectSchemaJs.kt","src/kotlin/collections/Maps.kt","../../../../../../src/jsMain/kotlin/util/CancellablePromise.kt","../../../../../../src/jsMain/kotlin/util/JsIterableUtils.kt","../../../../../../src/jsMain/kotlin/util/TablePathUtilsJs.kt","../../../../../../src/jsMain/kotlin/LogLevelJs.kt","js/src/kotlin/text/stringJs.kt","../../../../../../src/jsMain/kotlin/StatusJs.kt","js/src/kotlin/text/charJs.kt","../../../../../../src/jsMain/kotlin/internal/Caching.kt","../../../../../../src/jsMain/kotlin/internal/IterableUtils.kt","../../../../../../src/jsMain/kotlin/schemas/BigDecimalSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/BigIntegerSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/BooleanSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/FileSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/NullableSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/NumberSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/StringSchemaJs.kt","../../../../../../src/jsMain/kotlin/schemas/TableSchemaJs.kt","../../../../../../src/jsMain/kotlin/util/CharUtils.kt","src/kotlin/CharCode.kt","../../../../../../src/jsMain/kotlin/util/FileUtils.kt","libraries/stdlib/js/src/org.w3c/org.w3c.files.kt","JsIterableUtils.kt","../../../../../../src/jsMain/kotlin/util/ListableUtils.kt","../../../../../../src/jsMain/kotlin/util/MapUtils.kt","../../../../../../src/jsMain/kotlin/util/NumericUtils.kt","../../../../../../src/jsMain/kotlin/util/SchemaPathUtilsJs.kt","../../../../../../src/jsMain/kotlin/util/SchemaUtils.kt","../../../../../../src/jsMain/kotlin/util/TemporalUtils.kt","../../../../../../src/jsMain/kotlin/util/ValidationIssueUtils.kt","../../../../../../src/jsMain/kotlin/validations/AcceptedFileTypesJs.kt","../../../../../../src/jsMain/kotlin/validations/AllowedValuesJs.kt","../../../../../../src/jsMain/kotlin/validations/ComparableBoundsJs.kt","../../../../../../src/jsMain/kotlin/validations/LengthBoundsJs.kt","../../../../../../src/jsMain/kotlin/validations/PatternsJs.kt","../../../../../../src/jsMain/kotlin/validations/RequiredValuesJs.kt","../../../../../../src/jsMain/kotlin/validations/ScaleJs.kt","../../../../../../src/jsMain/kotlin/validations/SizeBoundsJs.kt","../../../../../../src/jsMain/kotlin/validations/UniqueItemsJs.kt"],"sourcesContent":["import io.kform.AbsolutePath\nimport io.kform.AbsolutePathFragment\nimport io.kform.Path\nimport io.kform.toAbsolutePath\n\n/** [Absolute path][AbsolutePath] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"AbsolutePath\")\npublic open class AbsolutePathJs(path: Any = emptyArray<AbsolutePathFragmentJs>()) : PathJs(path) {\n final override val pathKt: AbsolutePath =\n when (path) {\n is Path -> path.toAbsolutePath()\n is PathJs -> path.pathKt.toAbsolutePath()\n is Array<*> -> AbsolutePath(path.map { (it as AbsolutePathFragmentJs).fragmentKt })\n else -> AbsolutePath(path.toString())\n }\n\n public override val fragments: Array<Any>\n get() = pathKt.fragments.cachedToJs { it.toJs() }\n\n public val size: Int = pathKt.size\n\n public val isRoot: Boolean = pathKt.isRoot\n\n public val lastFragment: Any? = pathKt.lastFragment?.toJs()\n\n override fun fragment(index: Int): Any = pathKt[index].toJs()\n\n public fun hasWildcard(): Boolean = pathKt.hasWildcard()\n\n public fun hasRecursiveWildcard(): Boolean = pathKt.hasRecursiveWildcard()\n\n public fun hasAnyWildcard(): Boolean = pathKt.hasAnyWildcard()\n\n override fun parent(): AbsolutePathJs = AbsolutePathJs(pathKt.parent())\n\n public override fun append(): PathJs {\n var allAbsolute = true\n val fragmentsKt =\n functionArguments<Any>().map {\n (it as PathFragmentJs).fragmentKt.also { fragmentKt ->\n if (fragmentKt !is AbsolutePathFragment) {\n allAbsolute = false\n }\n }\n }\n\n @Suppress(\"UNCHECKED_CAST\")\n return if (allAbsolute)\n AbsolutePathJs(\n pathKt.append(*(fragmentsKt as List<AbsolutePathFragment>).toTypedArray())\n )\n else PathJs(pathKt.append(*fragmentsKt.toTypedArray()))\n }\n\n override fun resolve(): AbsolutePathJs =\n AbsolutePathJs(\n pathKt.resolve(\n *functionArguments<Any>()\n .map { if (it is PathJs) it.pathKt else Path(it.toString()) }\n .toTypedArray()\n )\n )\n\n public fun matches(path: Any): Boolean = pathKt.matches(path.toPathKt())\n\n public operator fun contains(path: Any): Boolean = pathKt.contains(path.toPathKt())\n\n public fun relativeTo(path: Any): PathJs = PathJs(pathKt.relativeTo(path.toPathKt()))\n\n public override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is PathJs -> false\n else -> pathKt == other.pathKt\n }\n\n public override fun hashCode(): Int = pathKt.hashCode()\n\n public companion object {\n /** [Root absolute path][AbsolutePath.ROOT] wrapper for use from JavaScript. */\n @JsStatic public val ROOT: AbsolutePathJs = AbsolutePathJs(AbsolutePath.ROOT)\n\n /** [Match all absolute path][AbsolutePath.MATCH_ALL] wrapper for use from JavaScript. */\n @JsStatic public val MATCH_ALL: AbsolutePathJs = AbsolutePathJs(AbsolutePath.MATCH_ALL)\n }\n}\n\n/**\n * Function which converts an [AbsolutePath] into a wrapped [AbsolutePathJs] object to be used from\n * JavaScript, while caching the conversion in the process.\n */\ninternal fun AbsolutePath.cachedToJs(): AbsolutePathJs =\n getOrSetFromCache(this) { AbsolutePathJs(this) }\n","import io.kform.Path\n\n/** [Path] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"Path\")\npublic open class PathJs(path: Any = emptyArray<PathFragmentJs>()) {\n internal open val pathKt: Path =\n when (path) {\n is Path -> path\n is PathJs -> path.pathKt\n is Array<*> -> Path(path.map { (it as PathFragmentJs).fragmentKt })\n else -> Path(path.toString())\n }\n\n public open val fragments: Array<Any>\n get() = pathKt.fragments.cachedToJs { it.toJs() }\n\n public open fun fragment(index: Int): Any = pathKt[index].toJs()\n\n public open fun parent(): PathJs = PathJs(pathKt.parent())\n\n public open fun append(): PathJs =\n PathJs(\n pathKt.append(\n *functionArguments<Any>().map { (it as PathFragmentJs).fragmentKt }.toTypedArray()\n )\n )\n\n public fun join(): PathJs =\n PathJs(\n pathKt.join(\n *functionArguments<Any>()\n .map { if (it is PathJs) it.pathKt else Path(it.toString()) }\n .toTypedArray()\n )\n )\n\n public open fun resolve(): PathJs =\n PathJs(\n pathKt.resolve(\n *functionArguments<Any>()\n .map { if (it is PathJs) it.pathKt else Path(it.toString()) }\n .toTypedArray()\n )\n )\n\n public override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is PathJs -> false\n else -> pathKt == other.pathKt\n }\n\n public override fun hashCode(): Int = pathKt.hashCode()\n\n public override fun toString(): String = pathKt.toString()\n\n public companion object {\n /** [Current path][Path.CURRENT] wrapper for use from JavaScript. */\n @JsStatic public val CURRENT: PathJs = PathJs(Path.CURRENT)\n\n /** [Current deep path][Path.CURRENT_DEEP] wrapper for use from JavaScript. */\n @JsStatic public val CURRENT_DEEP: PathJs = PathJs(Path.CURRENT_DEEP)\n\n /** [Parent path][Path.PARENT] wrapper for use from JavaScript. */\n @JsStatic public val PARENT: PathJs = PathJs(Path.PARENT)\n\n /** [Children path][Path.CHILDREN] wrapper for use from JavaScript. */\n @JsStatic public val CHILDREN: PathJs = PathJs(Path.CHILDREN)\n\n /** [Descendants path][Path.DESCENDANTS] wrapper for use from JavaScript. */\n @JsStatic public val DESCENDANTS: PathJs = PathJs(Path.DESCENDANTS)\n }\n}\n\n/**\n * Function which converts a [Path] into a wrapped [PathJs] object to be used from JavaScript, while\n * caching the conversion in the process.\n */\ninternal fun Path.cachedToJs(): PathJs = getOrSetFromCache(this) { PathJs(this) }\n\n/** Function that converts a wrapped [PathJs] or a string into a [Path]. */\ninternal fun Any.toPathKt(): Path =\n when (this) {\n is PathJs -> pathKt\n is String -> Path(this)\n else -> error(\"Invalid path.\")\n }\n",null,null,"/**\n * Provies a way of accessing the `arguments` passed to a function in JavaScript.\n *\n * This is useful in order to define functions to be exposed to JavaScript that take a variable\n * number of arguments (Kotlin's `vararg` expects an array to be passed as argument).\n */\n@Suppress(\"NOTHING_TO_INLINE\", \"UnsafeCastFromDynamic\")\ninternal inline fun <T> functionArguments(): Array<T> = js(\"Array.from(arguments)\")\n",null,null,"import io.kform.FormManagerEvent\nimport io.kform.StateEvent\nimport io.kform.ValueEvent\n\n/** [Form manager event][FormManagerEvent] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"FormManagerEvent\")\npublic sealed interface FormManagerEventJs<T> {\n public val path: AbsolutePathJs\n public val schema: SchemaJs<T>\n}\n\n/** [Value event][ValueEvent] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ValueEvent\")\npublic sealed class ValueEventJs<T> : FormManagerEventJs<T> {\n internal abstract val eventKt: ValueEvent<T>\n\n public open val value: T?\n get() = eventKt.value\n\n public open val oldValue: T?\n get() = eventKt.oldValue\n\n override val path: AbsolutePathJs\n get() = eventKt.path.cachedToJs()\n\n override val schema: SchemaJs<T>\n get() = eventKt.schema.cachedToJs()\n\n public override fun toString(): String = eventKt.toString()\n\n public class Init<T> internal constructor(override val eventKt: ValueEvent.Init<T>) :\n ValueEventJs<T>() {\n public override val oldValue: Nothing? = undefined\n }\n\n public class Change<T> internal constructor(override val eventKt: ValueEvent.Change<T>) :\n ValueEventJs<T>()\n\n public class Destroy<T> internal constructor(override val eventKt: ValueEvent.Destroy<T>) :\n ValueEventJs<T>() {\n public override val value: Nothing? = undefined\n }\n\n public class Add<T, TChildren>\n internal constructor(override val eventKt: ValueEvent.Add<T, TChildren>) : ValueEventJs<T>() {\n public override val oldValue: Nothing? = undefined\n\n public val addedValue: TChildren\n get() = eventKt.addedValue\n\n public val id: AbsolutePathFragmentJs.Id\n get() = eventKt.id.toJs() as AbsolutePathFragmentJs.Id\n }\n\n public class Remove<T, TChildren>\n internal constructor(override val eventKt: ValueEvent.Remove<T, TChildren>) :\n ValueEventJs<T>() {\n public override val oldValue: Nothing? = undefined\n\n public val removedValue: TChildren\n get() = eventKt.removedValue\n\n public val id: AbsolutePathFragmentJs.Id\n get() = eventKt.id.toJs() as AbsolutePathFragmentJs.Id\n }\n}\n\n/** [State event][StateEvent] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"StateEvent\")\npublic sealed class StateEventJs<T> : FormManagerEventJs<T> {\n internal abstract val eventKt: StateEvent<T>\n\n override val path: AbsolutePathJs\n get() = eventKt.path.cachedToJs()\n\n override val schema: SchemaJs<T>\n get() = eventKt.schema.cachedToJs()\n\n public class ValidationChange<T>\n internal constructor(override val eventKt: StateEvent.ValidationChange<T>) : StateEventJs<T>() {\n public val status: ValidationStatusJs\n get() = eventKt.status.toJs()\n\n public val issues: Array<ValidationIssueJs>\n get() = eventKt.issues.cachedToJs { it.cachedToJs() }\n }\n\n public class DisplayChange<T>\n internal constructor(override val eventKt: StateEvent.DisplayChange<T>) : StateEventJs<T>() {\n public val status: DisplayStatusJs\n get() = eventKt.status.toJs()\n }\n\n public class DirtyChange<T>\n internal constructor(override val eventKt: StateEvent.DirtyChange<T>) : StateEventJs<T>() {\n public val status: Boolean\n get() = eventKt.status\n }\n\n public class TouchedChange<T>\n internal constructor(override val eventKt: StateEvent.TouchedChange<T>) : StateEventJs<T>() {\n public val status: Boolean\n get() = eventKt.status\n }\n\n public override fun toString(): String = eventKt.toString()\n}\n\n/**\n * Function which converts a [FormManagerEvent] into the JavaScript [FormManagerEventJs]\n * representation for use from JavaScript while caching the transformation.\n */\ninternal fun <T> FormManagerEvent<T>.cachedToJs(): FormManagerEventJs<T> =\n getOrSetFromCache(this) {\n when (this) {\n is ValueEvent.Init<T> -> ValueEventJs.Init(this)\n is ValueEvent.Change<T> -> ValueEventJs.Change(this)\n is ValueEvent.Destroy<T> -> ValueEventJs.Destroy(this)\n is ValueEvent.Add<T, *> -> ValueEventJs.Add(this)\n is ValueEvent.Remove<T, *> -> ValueEventJs.Remove(this)\n is StateEvent.ValidationChange -> StateEventJs.ValidationChange(this)\n is StateEvent.DisplayChange -> StateEventJs.DisplayChange(this)\n is StateEvent.DirtyChange -> StateEventJs.DirtyChange(this)\n is StateEvent.TouchedChange -> StateEventJs.TouchedChange(this)\n }\n }\n","@file:OptIn(DelicateCoroutinesApi::class)\n\nimport io.kform.FormManager\nimport io.kform.LocatedValidationIssue\nimport io.kform.ValidationMode\nimport kotlinx.coroutines.*\nimport kotlinx.coroutines.flow.onSubscription\n\n/**\n * [Validation mode][ValidationMode] representation for use from JavaScript (`\"auto\" | \"manual\"`).\n */\npublic typealias ValidationModeJs = String\n\ninternal fun ValidationModeJs.toValidationModeKt(): ValidationMode =\n when (this) {\n \"auto\" -> ValidationMode.Auto\n \"manual\" -> ValidationMode.Manual\n else -> error(\"Invalid validation mode: '$this'.\")\n }\n\n/** [Form manager][FormManager] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"FormManager\")\npublic class FormManagerJs(\n formSchema: Any,\n initialValue: Any? = undefined,\n externalContexts: RecordTs<String, Any>? = null,\n validationMode: ValidationModeJs = \"auto\",\n autoInit: Boolean = true,\n) {\n private val formManager =\n if (initialValue == undefined)\n FormManager(\n formSchema.toSchemaKt(),\n jsObjectToMap(externalContexts),\n validationMode.toValidationModeKt(),\n autoInit = autoInit,\n )\n else\n FormManager(\n formSchema.toSchemaKt(),\n initialValue,\n jsObjectToMap(externalContexts),\n validationMode.toValidationModeKt(),\n autoInit = autoInit,\n )\n\n public fun init(\n externalContexts: RecordTs<String, Any>? = null,\n validationMode: ValidationModeJs = \"auto\",\n ): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.init(jsObjectToMap(externalContexts), validationMode.toValidationModeKt())\n undefined\n }\n\n public fun destroy(): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.destroy()\n undefined\n }\n\n public val autoValidationStatus: AutoValidationStatusJs\n get() = formManager.autoValidationStatus.value.toJs()\n\n public fun onAutoValidationStatusChange(\n statusChangeHandler: (status: AutoValidationStatusJs) -> Any?,\n onSubscription: (() -> Any?)? = null,\n ): CancellablePromise<() -> CancellablePromise<Nothing?>> =\n GlobalScope.cancellablePromise {\n val subscribed = CompletableDeferred<Unit>()\n val job =\n GlobalScope.launch {\n formManager.autoValidationStatus\n .onSubscription {\n onSubscription?.invoke().maybeAwait()\n subscribed.complete(Unit)\n }\n .collect { statusChangeHandler(it.toJs()).maybeAwait() }\n }\n subscribed.join()\n return@cancellablePromise {\n GlobalScope.cancellablePromise {\n job.cancelAndJoin()\n undefined\n }\n }\n }\n\n public fun setValidationMode(validationMode: ValidationModeJs): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.setValidationMode(validationMode.toValidationModeKt())\n undefined\n }\n\n public fun isValidPath(path: Any): Boolean = formManager.isValidPath(path.toPathKt())\n\n public fun schemaInfo(path: Any = AbsolutePathJs.MATCH_ALL): IterableJs<SchemaInfoJs<Any?>> =\n formManager.schemaInfo(path.toPathKt()).toIterableJs {\n it.cachedToJs() as SchemaInfoJs<Any?>\n }\n\n public fun valueInfo(\n path: Any = AbsolutePathJs.MATCH_ALL,\n infoHandler: (infoIterable: AsyncIterableJs<ValueInfoJs<Any?>>) -> Any?,\n ): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n formManager.valueInfo(path.toPathKt()) { infoFlow ->\n infoHandler(infoFlow.toAsyncIterableJs { it.cachedToJs() }).maybeAwait()\n }\n }\n\n public fun info(\n path: Any = AbsolutePathJs.MATCH_ALL,\n infoHandler: (infoIterable: AsyncIterableJs<InfoJs<Any?>>) -> Any?,\n ): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n formManager.info(path.toPathKt()) { infoFlow ->\n infoHandler(infoFlow.toAsyncIterableJs { it.cachedToJs() }).maybeAwait()\n }\n }\n\n public fun schema(path: Any = AbsolutePathJs.ROOT): SchemaJs<Any?> =\n formManager.schema(path.toPathKt()).cachedToJs() as SchemaJs<Any?>\n\n public fun has(path: Any): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise { formManager.has(path.toPathKt()) }\n\n public fun <T> get(\n path: Any = AbsolutePathJs.ROOT,\n valueHandler: (value: T) -> Any?,\n ): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n formManager.get(path.toPathKt()) { value: T -> valueHandler(value).maybeAwait() }\n }\n\n public fun <T> getClone(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise { formManager.getClone<T>(path.toPathKt()) }\n\n public fun set(path: Any = AbsolutePathJs.ROOT, toSet: Any?): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.set(path.toPathKt(), toSet)\n undefined\n }\n\n public fun reset(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.reset(path.toPathKt())\n undefined\n }\n\n public fun remove(path: Any): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.remove(path.toPathKt())\n undefined\n }\n\n public fun getExternalContext(\n externalContextName: String,\n externalContextHandler: (externalContext: Any?) -> Any?,\n ): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n formManager.getExternalContext<Any?, Any?>(externalContextName) {\n externalContextHandler(it).maybeAwait()\n }\n }\n\n public fun <T> setExternalContext(\n externalContextName: String,\n externalContext: T,\n ): CancellablePromise<T?> =\n GlobalScope.cancellablePromise {\n formManager.setExternalContext(externalContextName, externalContext)\n }\n\n public fun <T> removeExternalContext(externalContextName: String): CancellablePromise<T?> =\n GlobalScope.cancellablePromise { formManager.removeExternalContext(externalContextName) }\n\n public fun validate(\n path: Any = AbsolutePathJs.MATCH_ALL,\n issuesHandler: ((issuesIterable: AsyncIterableJs<LocatedValidationIssueJs>) -> Any?)? = null,\n ): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n if (issuesHandler != null)\n formManager.validate(path.toPathKt()) { issuesFlow ->\n issuesHandler(issuesFlow.toAsyncIterableJs { it.cachedToJs() }).maybeAwait()\n }\n else formManager.validate(path.toPathKt()).map { it.cachedToJs() }.toTypedArray()\n }\n\n public fun isValid(path: Any = AbsolutePathJs.MATCH_ALL): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise { formManager.isValid(path.toPathKt()) }\n\n public fun addExternalIssues(issues: Any): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.addExternalIssues(\n issues.toIterableKt<Any, LocatedValidationIssue> { it.toLocatedValidationIssueKt() }\n )\n undefined\n }\n\n public fun removeExternalIssues(\n path: Any = AbsolutePathJs.MATCH_ALL,\n code: String? = null,\n ): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.removeExternalIssues(path.toPathKt(), code)\n undefined\n }\n\n public fun isDirty(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise { formManager.isDirty(path.toPathKt()) }\n\n public fun isPristine(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise { formManager.isPristine(path.toPathKt()) }\n\n public fun setDirty(path: Any = AbsolutePathJs.MATCH_ALL): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.setDirty(path.toPathKt())\n undefined\n }\n\n public fun setPristine(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.setPristine(path.toPathKt())\n undefined\n }\n\n public fun isTouched(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise { formManager.isTouched(path.toPathKt()) }\n\n public fun isUntouched(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise { formManager.isUntouched(path.toPathKt()) }\n\n public fun setTouched(path: Any = AbsolutePathJs.MATCH_ALL): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.setTouched(path.toPathKt())\n undefined\n }\n\n public fun setUntouched(path: Any = AbsolutePathJs.ROOT): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n formManager.setUntouched(path.toPathKt())\n undefined\n }\n\n public fun subscribe(\n path: Any = AbsolutePathJs.MATCH_ALL,\n eventHandler: (event: FormManagerEventJs<Any?>) -> Any?,\n onSubscription: (() -> Any?)? = null,\n ): CancellablePromise<() -> CancellablePromise<Nothing?>> =\n GlobalScope.cancellablePromise {\n val unsubscribe =\n formManager.subscribe(\n path.toPathKt(),\n onSubscription?.let { { onSubscription().maybeAwait() } },\n ) {\n eventHandler(it.cachedToJs() as FormManagerEventJs<Any?>).maybeAwait()\n }\n return@cancellablePromise {\n GlobalScope.cancellablePromise {\n unsubscribe()\n undefined\n }\n }\n }\n}\n","@file:OptIn(DelicateCoroutinesApi::class)\n\nimport io.kform.*\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.GlobalScope\n\n@JsExport\n@JsName(\"validatePath\")\npublic fun validatePathJs(formSchema: Any, path: Any): Nothing? {\n validatePath(formSchema.toSchemaKt(), path.toPathKt())\n return undefined\n}\n\n@JsExport\n@JsName(\"validateSchemaValidations\")\npublic fun validateSchemaValidationsJs(formSchema: Any): Nothing? {\n validateSchemaValidations(formSchema.toSchemaKt())\n return undefined\n}\n\n@JsExport\n@JsName(\"validateExternalValidations\")\npublic fun validateExternalValidationsJs(\n formSchema: Any,\n externalValidations: RecordTs<String, Array<Any>>,\n): Nothing? {\n @Suppress(\"UNCHECKED_CAST\")\n validateExternalValidations(\n formSchema.toSchemaKt(),\n jsObjectToMap(externalValidations) { array -> array.map { it.toValidationKt() } }\n as Map<PathOrString, List<Validation<*>>>,\n )\n return undefined\n}\n\n@JsExport\n@JsName(\"isValidPath\")\npublic fun isValidPathJs(formSchema: Any, path: Any): Boolean =\n isValidPath(formSchema.toSchemaKt(), path.toPathKt())\n\n@JsExport\n@JsName(\"schemaInfo\")\npublic fun schemaInfoJs(\n formSchema: Any,\n path: Any = AbsolutePathJs.MATCH_ALL,\n): IterableJs<SchemaInfoJs<Any?>> =\n schemaInfo(formSchema.toSchemaKt(), path.toPathKt()).toIterableJs {\n it.cachedToJs() as SchemaInfoJs<Any?>\n }\n\n@JsExport\n@JsName(\"schema\")\npublic fun schemaJs(formSchema: Any, path: Any): SchemaJs<Any?> =\n schema(formSchema.toSchemaKt(), path.toPathKt()).cachedToJs() as SchemaJs<Any?>\n\n@JsExport\n@JsName(\"valueInfo\")\npublic fun valueInfoJs(\n formSchema: Any,\n formValue: Any?,\n path: Any = AbsolutePathJs.MATCH_ALL,\n): AsyncIterableJs<ValueInfoJs<Any?>> =\n @Suppress(\"UNCHECKED_CAST\")\n valueInfo(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt())\n .toAsyncIterableJs { it.cachedToJs() }\n\n@JsExport\n@JsName(\"has\")\npublic fun hasJs(formSchema: Any, formValue: Any?, path: Any): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise {\n @Suppress(\"UNCHECKED_CAST\")\n has(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt())\n }\n\n@JsExport\n@JsName(\"get\")\npublic fun getJs(formSchema: Any, formValue: Any?, path: Any): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n @Suppress(\"UNCHECKED_CAST\")\n get(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt())\n }\n\n@JsExport\n@JsName(\"getClone\")\npublic fun getCloneJs(formSchema: Any, formValue: Any?, path: Any): CancellablePromise<Any?> =\n GlobalScope.cancellablePromise {\n @Suppress(\"UNCHECKED_CAST\")\n getClone(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt())\n }\n\n@JsExport\n@JsName(\"set\")\npublic fun setJs(\n formSchema: Any,\n formValue: Any?,\n path: Any,\n toSet: Any?,\n): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n @Suppress(\"UNCHECKED_CAST\")\n set(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt(), toSet)\n undefined\n }\n\n@JsExport\n@JsName(\"reset\")\npublic fun resetJs(formSchema: Any, formValue: Any?, path: Any): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n @Suppress(\"UNCHECKED_CAST\")\n reset(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt())\n undefined\n }\n\n@JsExport\n@JsName(\"remove\")\npublic fun removeJs(formSchema: Any, formValue: Any?, path: Any): CancellablePromise<Nothing?> =\n GlobalScope.cancellablePromise {\n @Suppress(\"UNCHECKED_CAST\")\n remove(formSchema.toSchemaKt() as Schema<Any?>, formValue, path.toPathKt())\n undefined\n }\n\n@JsExport\n@JsName(\"validate\")\npublic fun validateJs(\n formSchema: Any,\n formValue: Any?,\n pathOrExternalContexts: Any? = null,\n maybeExternalContexts: RecordTs<String, Any?>? = null,\n): AsyncIterableJs<ValueInfoJs<Any?>> {\n val path: Path\n val externalContexts: RecordTs<String, Any?>?\n if (pathOrExternalContexts is PathJs || pathOrExternalContexts is String) {\n path = pathOrExternalContexts.toPathKt()\n externalContexts = maybeExternalContexts\n } else {\n path = AbsolutePath.MATCH_ALL\n @Suppress(\"UNCHECKED_CAST\", \"UNCHECKED_CAST_TO_EXTERNAL_INTERFACE\")\n externalContexts =\n if (pathOrExternalContexts == null) maybeExternalContexts\n else pathOrExternalContexts as RecordTs<String, Any?>?\n }\n @Suppress(\"UNCHECKED_CAST\")\n return validate(\n formSchema.toSchemaKt() as Schema<Any?>,\n formValue,\n path,\n jsObjectToMap(externalContexts),\n )\n .toAsyncIterableJs { it.cachedToJs() }\n}\n\n@JsExport\n@JsName(\"validateExternally\")\npublic fun validateExternallyJs(\n formSchema: Any,\n formValue: Any?,\n pathOrExternalValidations: Any? = null,\n externalValidationsOrExternalContexts: RecordTs<String, Any?>? = null,\n maybeExternalContexts: RecordTs<String, Any?>? = null,\n): AsyncIterableJs<ValueInfoJs<Any?>> {\n val path: Path\n val externalValidations: RecordTs<String, Array<Any>>?\n val externalContexts: RecordTs<String, Any?>?\n if (pathOrExternalValidations is PathJs || pathOrExternalValidations is String) {\n path = pathOrExternalValidations.toPathKt()\n @Suppress(\"UNCHECKED_CAST\", \"UNCHECKED_CAST_TO_EXTERNAL_INTERFACE\")\n externalValidations = externalValidationsOrExternalContexts as RecordTs<String, Array<Any>>?\n externalContexts = null\n } else {\n path = AbsolutePath.MATCH_ALL\n @Suppress(\"UNCHECKED_CAST\", \"UNCHECKED_CAST_TO_EXTERNAL_INTERFACE\")\n externalValidations = pathOrExternalValidations as RecordTs<String, Array<Any>>?\n externalContexts = maybeExternalContexts\n }\n @Suppress(\"UNCHECKED_CAST\")\n return validateExternally(\n formSchema.toSchemaKt() as Schema<Any?>,\n formValue,\n path,\n jsObjectToMap(externalValidations) {\n it.map { validation -> validation.toValidationKt() }\n }\n as ExternalValidations,\n jsObjectToMap(externalContexts),\n )\n .toAsyncIterableJs { it.cachedToJs() }\n}\n\n@JsExport\n@JsName(\"isValid\")\npublic fun isValidJs(\n formSchema: Any,\n formValue: Any?,\n pathOrExternalContexts: Any? = null,\n maybeExternalContexts: RecordTs<String, Any?>? = null,\n): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise {\n val path: Path\n val externalContexts: RecordTs<String, Any?>?\n if (pathOrExternalContexts is PathJs || pathOrExternalContexts is String) {\n path = pathOrExternalContexts.toPathKt()\n externalContexts = maybeExternalContexts\n } else {\n path = AbsolutePath.MATCH_ALL\n @Suppress(\"UNCHECKED_CAST\", \"UNCHECKED_CAST_TO_EXTERNAL_INTERFACE\")\n externalContexts =\n if (pathOrExternalContexts == null) maybeExternalContexts\n else pathOrExternalContexts as RecordTs<String, Any?>?\n }\n @Suppress(\"UNCHECKED_CAST\")\n isValid(\n formSchema.toSchemaKt() as Schema<Any?>,\n formValue,\n path,\n jsObjectToMap(externalContexts),\n )\n }\n\n@JsExport\n@JsName(\"isValidExternally\")\npublic fun isValidExternallyJs(\n formSchema: Any,\n formValue: Any?,\n pathOrExternalValidations: Any? = null,\n externalValidationsOrExternalContexts: RecordTs<String, Any?>? = null,\n maybeExternalContexts: RecordTs<String, Any?>? = null,\n): CancellablePromise<Boolean> =\n GlobalScope.cancellablePromise {\n val path: Path\n val externalValidations: RecordTs<String, Array<Any>>?\n val externalContexts: RecordTs<String, Any?>?\n if (pathOrExternalValidations is PathJs || pathOrExternalValidations is String) {\n path = pathOrExternalValidations.toPathKt()\n @Suppress(\"UNCHECKED_CAST\", \"UNCHECKED_CAST_TO_EXTERNAL_INTERFACE\")\n externalValidations =\n externalValidationsOrExternalContexts as RecordTs<String, Array<Any>>?\n externalContexts = null\n } else {\n path = AbsolutePath.MATCH_ALL\n @Suppress(\"UNCHECKED_CAST\", \"UNCHECKED_CAST_TO_EXTERNAL_INTERFACE\")\n externalValidations = pathOrExternalValidations as RecordTs<String, Array<Any>>?\n externalContexts = maybeExternalContexts\n }\n @Suppress(\"UNCHECKED_CAST\")\n isValidExternally(\n formSchema.toSchemaKt() as Schema<Any?>,\n formValue,\n path,\n jsObjectToMap(externalValidations) {\n it.map { validation -> validation.toValidationKt() }\n }\n as ExternalValidations,\n jsObjectToMap(externalContexts),\n )\n }\n","import io.kform.Info\nimport io.kform.SchemaInfo\nimport io.kform.ValueInfo\n\n/** [Schema info][SchemaInfo] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"SchemaInfo\")\npublic class SchemaInfoJs<T> internal constructor(private val infoKt: SchemaInfo<T>) {\n public val schema: SchemaJs<T>\n get() = infoKt.schema.cachedToJs()\n\n public val path: AbsolutePathJs\n get() = infoKt.path.cachedToJs()\n\n public val queriedPath: AbsolutePathJs\n get() = infoKt.queriedPath.cachedToJs()\n\n public override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is SchemaInfoJs<*> -> false\n else -> infoKt == other.infoKt\n }\n\n public override fun hashCode(): Int = infoKt.hashCode()\n\n public override fun toString(): String = infoKt.toString()\n}\n\n/** [Value info][ValueInfo] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ValueInfo\")\npublic class ValueInfoJs<T> internal constructor(private val infoKt: ValueInfo<T>) {\n public val value: T\n get() = infoKt.value\n\n public val schema: SchemaJs<T>\n get() = infoKt.schema.cachedToJs()\n\n public val path: AbsolutePathJs\n get() = infoKt.path.cachedToJs()\n\n public val schemaPath: AbsolutePathJs\n get() = infoKt.schemaPath.cachedToJs()\n\n public override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is ValueInfoJs<*> -> false\n else -> infoKt == other.infoKt\n }\n\n public override fun hashCode(): Int = infoKt.hashCode()\n\n public override fun toString(): String = infoKt.toString()\n}\n\n/** [Info] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"Info\")\npublic class InfoJs<T> internal constructor(private val infoKt: Info<T>) {\n public val value: T\n get() = infoKt.value\n\n public val schema: SchemaJs<T>\n get() = infoKt.schema.cachedToJs()\n\n public val path: AbsolutePathJs\n get() = infoKt.path.cachedToJs()\n\n public val schemaPath: AbsolutePathJs\n get() = infoKt.schemaPath.cachedToJs()\n\n public val dirty: Boolean\n get() = infoKt.dirty\n\n public val touched: Boolean\n get() = infoKt.touched\n\n public val issues: Array<ValidationIssueJs>\n get() = infoKt.issues.cachedToJs { it.cachedToJs() }\n\n public val validationStatus: ValidationStatusJs\n get() = infoKt.validationStatus.toJs()\n\n public val displayStatus: DisplayStatusJs\n get() = infoKt.displayStatus.toJs()\n\n public override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is InfoJs<*> -> false\n else -> infoKt == other.infoKt\n }\n\n public override fun hashCode(): Int = infoKt.hashCode()\n\n public override fun toString(): String = infoKt.toString()\n}\n\ninternal fun <T> SchemaInfo<T>.cachedToJs(): SchemaInfoJs<T> =\n getOrSetFromCache(this) { SchemaInfoJs(this) }\n\ninternal fun <T> ValueInfo<T>.cachedToJs(): ValueInfoJs<T> =\n getOrSetFromCache(this) { ValueInfoJs(this) }\n\ninternal fun <T> Info<T>.cachedToJs(): InfoJs<T> = getOrSetFromCache(this) { InfoJs(this) }\n","import io.kform.AbsolutePathFragment\nimport io.kform.PathFragment\n\n/** [Path fragment][PathFragment] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"PathFragment\")\npublic sealed class PathFragmentJs {\n internal abstract val fragmentKt: PathFragment\n\n public override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is PathFragmentJs -> false\n else -> fragmentKt == other.fragmentKt\n }\n\n public override fun hashCode(): Int = fragmentKt.hashCode()\n\n public override fun toString(): String = fragmentKt.toString()\n\n public object Root : PathFragmentJs() {\n override val fragmentKt = PathFragment.Root\n }\n\n public object CurrentPath : PathFragmentJs() {\n override val fragmentKt = PathFragment.CurrentPath\n }\n\n public object ParentPath : PathFragmentJs() {\n override val fragmentKt = PathFragment.ParentPath\n }\n}\n\n/** [Absolute path fragment][AbsolutePathFragment] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"AbsolutePathFragment\")\npublic sealed class AbsolutePathFragmentJs : PathFragmentJs() {\n abstract override val fragmentKt: AbsolutePathFragment\n\n public class Id(fragmentKtOrId: Any) : AbsolutePathFragmentJs() {\n override val fragmentKt =\n when (fragmentKtOrId) {\n is AbsolutePathFragment.Id -> fragmentKtOrId\n else -> AbsolutePathFragment.Id(fragmentKtOrId)\n }\n\n public val id: String\n get() = fragmentKt.id\n }\n\n public object CollectionEnd : AbsolutePathFragmentJs() {\n override val fragmentKt = AbsolutePathFragment.CollectionEnd\n }\n\n public object Wildcard : AbsolutePathFragmentJs() {\n override val fragmentKt = AbsolutePathFragment.Wildcard\n }\n\n public object RecursiveWildcard : AbsolutePathFragmentJs() {\n override val fragmentKt = AbsolutePathFragment.RecursiveWildcard\n }\n}\n\n/**\n * Function which converts a [PathFragment] into its JavaScript representation to be used from\n * JavaScript.\n */\ninternal fun PathFragment.toJs(): PathFragmentJs =\n when (this) {\n is PathFragment.Root -> PathFragmentJs.Root\n is PathFragment.CurrentPath -> PathFragmentJs.CurrentPath\n is PathFragment.ParentPath -> PathFragmentJs.ParentPath\n else -> (this as AbsolutePathFragment).toJs()\n }\n\n/**\n * Function which converts an [AbsolutePathFragment] into its JavaScript representation to be used\n * from JavaScript.\n */\ninternal fun AbsolutePathFragment.toJs(): AbsolutePathFragmentJs =\n when (this) {\n is AbsolutePathFragment.Id -> AbsolutePathFragmentJs.Id(this)\n is AbsolutePathFragment.CollectionEnd -> AbsolutePathFragmentJs.CollectionEnd\n is AbsolutePathFragment.Wildcard -> AbsolutePathFragmentJs.Wildcard\n is AbsolutePathFragment.RecursiveWildcard -> AbsolutePathFragmentJs.RecursiveWildcard\n }\n","import io.kform.*\nimport kotlinx.coroutines.DelicateCoroutinesApi\nimport kotlinx.coroutines.GlobalScope\n\n/** Options used when creating a schema from JavaScript. */\npublic external interface SchemaOptionsJs<T> {\n public val initialValue: T?\n public val validations: Array<ValidationJs<T>>?\n}\n\n/** [Schema] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"Schema\")\npublic open class SchemaJs<T> internal constructor(internal val schemaKt: Schema<T>) {\n public val typeInfo: TypeInfoJs\n get() = schemaKt.typeInfo.cachedToJs()\n\n public val validations: Array<ValidationJs<T>>\n get() = schemaKt.validations.cachedToJs { it.cachedToJs() }\n\n public val initialValue: T\n get() = schemaKt.initialValue\n\n @OptIn(DelicateCoroutinesApi::class)\n public fun clone(value: T): CancellablePromise<T> =\n GlobalScope.cancellablePromise { schemaKt.clone(value) }\n}\n\n/** [Parent schema][ParentSchema] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ParentSchema\")\npublic open class ParentSchemaJs<T> internal constructor(schemaKt: ParentSchema<T>) :\n SchemaJs<T>(schemaKt)\n\n/** [Collection schema][CollectionSchema] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"CollectionSchema\")\npublic class CollectionSchemaJs<T> internal constructor(schemaKt: CollectionSchema<T, *>) :\n ParentSchemaJs<T>(schemaKt)\n\n/**\n * Function which converts a [Schema] into a wrapped [SchemaJs] object to be used from JavaScript,\n * while caching the conversion in the process.\n */\npublic fun <T> Schema<T>.cachedToJs(): SchemaJs<T> =\n getOrSetFromCache(this) {\n when (this) {\n is CollectionSchema<*, *> -> CollectionSchemaJs(this as CollectionSchema<T, *>)\n is ParentSchema<*> -> ParentSchemaJs(this as ParentSchema<T>)\n else -> SchemaJs(this)\n }\n }\n\n/** Function that returns a [Schema] from a wrapped [SchemaJs] or a [Schema]. */\ninternal fun Any.toSchemaKt(): Schema<*> =\n when (this) {\n is Schema<*> -> this\n is SchemaJs<*> -> schemaKt\n else -> error(\"Invalid schema.\")\n }\n","import io.kform.TypeInfo\n\n/** [TypeInfo] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"TypeInfo\")\npublic class TypeInfoJs internal constructor(private val typeInfoKt: TypeInfo) {\n public val name: String\n get() = typeInfoKt.name\n\n public val nullable: Boolean\n get() = typeInfoKt.nullable\n\n public val arguments: Array<TypeInfoJs>\n get() = typeInfoKt.arguments.cachedToJs { it.cachedToJs() }\n\n public val restrictions: RecordTs<String, Any?>\n get() = typeInfoKt.restrictions.cachedToJs()\n\n override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is TypeInfoJs -> false\n else -> typeInfoKt == other.typeInfoKt\n }\n\n override fun hashCode(): Int = typeInfoKt.hashCode()\n\n public override fun toString(): String = typeInfoKt.toString()\n}\n\n/**\n * Function which converts a [TypeInfo] into a wrapped [TypeInfoJs] object to be used from\n * JavaScript, while caching the conversion in the process.\n */\ninternal fun TypeInfo.cachedToJs(): TypeInfoJs = getOrSetFromCache(this) { TypeInfoJs(this) }\n","import io.kform.*\n\n/**\n * [Validation issue severity][ValidationIssueSeverity] representation for use from JavaScript\n * (`\"error\" | \"warning\"`).\n */\npublic typealias ValidationIssueSeverityJs = String\n\ninternal fun ValidationIssueSeverityJs.toValidationIssueSeverityKt(): ValidationIssueSeverity =\n when (this) {\n \"error\" -> ValidationIssueSeverity.Error\n \"warning\" -> ValidationIssueSeverity.Warning\n else -> error(\"Invalid validation issue severity: '$this'.\")\n }\n\ninternal fun ValidationIssueSeverity.toJs(): ValidationIssueSeverityJs =\n toString().replaceFirstChar { it.lowercase() }\n\n/** [Validation issue][ValidationIssue] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ValidationIssue\")\npublic sealed class ValidationIssueJs {\n internal abstract val issueKt: ValidationIssue\n\n public val code: String\n get() = issueKt.code\n\n public val data: RecordTs<String, String?>\n get() = issueKt.data.cachedToJs()\n\n public val severity: ValidationIssueSeverityJs\n get() = issueKt.severity.toJs()\n\n override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is ValidationIssueJs -> false\n else -> issueKt == other.issueKt\n }\n\n override fun hashCode(): Int = issueKt.hashCode()\n\n public fun contains(issue: ValidationIssueJs): Boolean = issueKt.contains(issue.issueKt)\n\n public override fun toString(): String = issueKt.toString()\n}\n\n/** [Validation error][ValidationError] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ValidationError\")\npublic class ValidationErrorJs(issueKtOrCode: Any, data: RecordTs<String, String?>? = null) :\n ValidationIssueJs() {\n override val issueKt: ValidationError =\n when (issueKtOrCode) {\n is ValidationError -> issueKtOrCode\n else -> ValidationError(issueKtOrCode.toString(), jsObjectToMap(data) ?: emptyMap())\n }\n}\n\n/** [Validation warning][ValidationWarning] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ValidationWarning\")\npublic class ValidationWarningJs(issueKtOrCode: Any, data: RecordTs<String, String?>? = null) :\n ValidationIssueJs() {\n override val issueKt: ValidationWarning =\n when (issueKtOrCode) {\n is ValidationWarning -> issueKtOrCode\n else -> ValidationWarning(issueKtOrCode.toString(), jsObjectToMap(data) ?: emptyMap())\n }\n}\n\n/** [Validation failure][ValidationFailure] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"ValidationFailure\")\npublic class ValidationFailureJs internal constructor(issueKt: Any) : ValidationIssueJs() {\n override val issueKt: ValidationFailure =\n when (issueKt) {\n is ValidationFailure -> issueKt\n else -> error(\"Invalid argument.\")\n }\n\n public val validation: String\n get() = issueKt.validation\n\n public val exception: String?\n get() = issueKt.exception\n\n public val stackTrace: String\n get() = issueKt.stackTrace\n}\n\n/** [Located validation issue][LocatedValidationIssue] wrapper for use from JavaScript. */\n@JsExport\n@JsName(\"LocatedValidationIssue\")\npublic sealed class LocatedValidationIssueJs {\n internal abstract val issueKt: LocatedValidationIssue\n\n public val path: AbsolutePathJs\n get() = issueKt.path.cachedToJs()\n\n public val code: String\n get() = issueKt.code\n\n public val dependencies: Array<AbsolutePathJs>\n get() = issueKt.dependencies.cachedToJs { it.cachedToJs() }\n\n public val dependsOnDescendants: Boolean\n get() = issueKt.dependsOnDescendants\n\n public val externalContextDependencies: Array<String>\n get() = issueKt.externalContextDependencies.cachedToJs()\n\n public val data: RecordTs<String, String?>\n get() = issueKt.data.cachedToJs()\n\n public val severity: ValidationIssueSeverityJs\n get() = issueKt.severity.toJs()\n\n override fun equals(other: Any?): Boolean =\n when {\n this === other -> true\n other !is LocatedValidationIssueJs -> false\n else -> issueKt == other.issueKt\n }\n\n override fun hashCode(): Int = issueKt.hashCode()\n\n public fun contains(issue: LocatedValidationIssueJs): Boolean = issueKt.contains(issue.issueKt)\n\n public override fun toString(): String = issueKt.toString()\n}\n\ninternal fun LocatedValidationIssue.cachedToJs(): LocatedValidationIssueJs =\n getOrSetFromCache(this) {\n when (this) {\n is LocatedValidationError -> LocatedValidationErrorJs(this)\n is LocatedValidationWarning -> LocatedValidationWarningJs(this)\n is LocatedValidationFailure -> LocatedValidationFailureJs(this)\n }\n }\n\n/** Options available when building a [LocatedValidationErrorJs] or [LocatedValidationWarningJs]. */\npublic external interface LocatedValidationIssueOptionsJs {\n public val dependencies: Array<Any>?\n public val dependsOnDescendants: Boolean?\n public val externalContextDependencies: Array<String>?\n public val data: RecordTs<String, String?>?\n}\n\n/** [Located validati