@getodk/xforms-engine 0.3.0 → 0.5.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/dist/client/BaseNode.d.ts +15 -5
- package/dist/client/BaseValueNode.d.ts +32 -0
- package/dist/client/EngineConfig.d.ts +49 -49
- package/dist/client/GroupNode.d.ts +2 -3
- package/dist/client/InputNode.d.ts +53 -0
- package/dist/client/ModelValueNode.d.ts +13 -9
- package/dist/client/NodeAppearances.d.ts +1 -2
- package/dist/client/NoteNode.d.ts +3 -4
- package/dist/client/RootNode.d.ts +36 -10
- package/dist/client/SelectNode.d.ts +4 -5
- package/dist/client/SubtreeNode.d.ts +1 -2
- package/dist/client/TextRange.d.ts +3 -4
- package/dist/client/TriggerNode.d.ts +25 -0
- package/dist/client/ValueType.d.ts +3 -0
- package/dist/client/constants.d.ts +50 -1
- package/dist/client/hierarchy.d.ts +9 -5
- package/dist/client/identity.d.ts +14 -0
- package/dist/client/index.d.ts +0 -1
- package/dist/client/node-types.d.ts +3 -1
- package/dist/client/repeat/BaseRepeatRangeNode.d.ts +1 -2
- package/dist/client/repeat/RepeatInstanceNode.d.ts +2 -3
- package/dist/client/repeat/RepeatRangeControlledNode.d.ts +1 -2
- package/dist/client/repeat/RepeatRangeUncontrolledNode.d.ts +1 -2
- package/dist/client/resources.d.ts +93 -0
- package/dist/client/submission/SubmissionData.d.ts +7 -0
- package/dist/client/submission/SubmissionDefinition.d.ts +14 -0
- package/dist/client/submission/SubmissionInstanceFile.d.ts +6 -0
- package/dist/client/submission/SubmissionOptions.d.ts +23 -0
- package/dist/client/submission/SubmissionResult.d.ts +91 -0
- package/dist/client/submission/SubmissionState.d.ts +12 -0
- package/dist/client/unsupported/RangeNode.d.ts +9 -0
- package/dist/client/unsupported/RankNode.d.ts +9 -0
- package/dist/client/unsupported/UnsupportedControlNode.d.ts +32 -0
- package/dist/client/unsupported/UploadNode.d.ts +9 -0
- package/dist/client/validation.d.ts +2 -3
- package/dist/error/ErrorProductionDesignPendingError.d.ts +7 -0
- package/dist/error/ValueTypeInvariantError.d.ts +17 -0
- package/dist/error/XPathFunctionalityError.d.ts +14 -0
- package/dist/error/XPathFunctionalityNotSupportedError.d.ts +7 -0
- package/dist/error/XPathFunctionalityPendingError.d.ts +7 -0
- package/dist/index.d.ts +16 -4
- package/dist/index.js +8559 -4700
- package/dist/index.js.map +1 -1
- package/dist/instance/Group.d.ts +9 -5
- package/dist/instance/InputControl.d.ts +36 -0
- package/dist/instance/ModelValue.d.ts +16 -27
- package/dist/instance/Note.d.ts +11 -5
- package/dist/instance/PrimaryInstance.d.ts +84 -0
- package/dist/instance/Root.d.ts +31 -28
- package/dist/instance/SelectField.d.ts +13 -6
- package/dist/instance/Subtree.d.ts +10 -6
- package/dist/instance/TriggerControl.d.ts +47 -0
- package/dist/instance/abstract/DescendantNode.d.ts +33 -26
- package/dist/instance/abstract/InstanceNode.d.ts +50 -31
- package/dist/instance/abstract/UnsupportedControl.d.ts +53 -0
- package/dist/instance/abstract/ValueNode.d.ts +48 -0
- package/dist/instance/children.d.ts +0 -1
- package/dist/instance/hierarchy.d.ts +13 -8
- package/dist/instance/identity.d.ts +2 -7
- package/dist/instance/index.d.ts +0 -1
- package/dist/instance/internal-api/EvaluationContext.d.ts +53 -13
- package/dist/instance/internal-api/InstanceConfig.d.ts +8 -3
- package/dist/instance/internal-api/InstanceValueContext.d.ts +20 -0
- package/dist/instance/internal-api/PrimaryInstanceDocument.d.ts +36 -0
- package/dist/instance/internal-api/TranslationContext.d.ts +3 -3
- package/dist/instance/internal-api/ValidationContext.d.ts +12 -6
- package/dist/instance/internal-api/ValueContext.d.ts +5 -5
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableInstance.d.ts +14 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.d.ts +31 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableParentNode.d.ts +18 -0
- package/dist/instance/internal-api/submission/ClientReactiveSubmittableValueNode.d.ts +17 -0
- package/dist/instance/repeat/BaseRepeatRange.d.ts +40 -85
- package/dist/instance/repeat/RepeatInstance.d.ts +11 -30
- package/dist/instance/repeat/RepeatRangeControlled.d.ts +3 -4
- package/dist/instance/repeat/RepeatRangeUncontrolled.d.ts +3 -4
- package/dist/instance/resource.d.ts +1 -2
- package/dist/instance/text/TextChunk.d.ts +0 -1
- package/dist/instance/text/TextRange.d.ts +1 -2
- package/dist/instance/unsupported/RangeControl.d.ts +6 -0
- package/dist/instance/unsupported/RankControl.d.ts +6 -0
- package/dist/instance/unsupported/UploadControl.d.ts +6 -0
- package/dist/integration/xpath/EngineXPathEvaluator.d.ts +14 -0
- package/dist/integration/xpath/adapter/XFormsXPathNode.d.ts +71 -0
- package/dist/integration/xpath/adapter/engineDOMAdapter.d.ts +5 -0
- package/dist/integration/xpath/adapter/kind.d.ts +32 -0
- package/dist/integration/xpath/adapter/names.d.ts +16 -0
- package/dist/integration/xpath/adapter/traversal.d.ts +25 -0
- package/dist/integration/xpath/adapter/values.d.ts +2 -0
- package/dist/integration/xpath/static-dom/StaticAttribute.d.ts +19 -0
- package/dist/integration/xpath/static-dom/StaticDocument.d.ts +16 -0
- package/dist/integration/xpath/static-dom/StaticElement.d.ts +40 -0
- package/dist/integration/xpath/static-dom/StaticNamedNode.d.ts +17 -0
- package/dist/integration/xpath/static-dom/StaticNode.d.ts +33 -0
- package/dist/integration/xpath/static-dom/StaticText.d.ts +16 -0
- package/dist/lib/TokenListParser.d.ts +3 -3
- package/dist/lib/client-reactivity/submission/createInstanceSubmissionState.d.ts +3 -0
- package/dist/lib/client-reactivity/submission/createLeafNodeSubmissionState.d.ts +3 -0
- package/dist/lib/client-reactivity/submission/createNodeRangeSubmissionState.d.ts +4 -0
- package/dist/lib/client-reactivity/submission/createParentNodeSubmissionState.d.ts +4 -0
- package/dist/lib/client-reactivity/submission/createValueNodeSubmissionState.d.ts +3 -0
- package/dist/lib/client-reactivity/submission/prepareSubmission.d.ts +8 -0
- package/dist/lib/codecs/DecimalValueCodec.d.ts +6 -0
- package/dist/lib/codecs/IntValueCodec.d.ts +6 -0
- package/dist/lib/codecs/StringValueCodec.d.ts +4 -0
- package/dist/lib/codecs/ValueCodec.d.ts +30 -0
- package/dist/lib/codecs/ValueTypePlaceholderCodec.d.ts +12 -0
- package/dist/lib/codecs/getSharedValueCodec.d.ts +47 -0
- package/dist/lib/dom/query.d.ts +4 -2
- package/dist/lib/reactivity/createChildrenState.d.ts +7 -6
- package/dist/lib/reactivity/createComputedExpression.d.ts +19 -7
- package/dist/lib/reactivity/createInstanceValueState.d.ts +40 -0
- package/dist/lib/reactivity/createNoteReadonlyThunk.d.ts +2 -3
- package/dist/lib/reactivity/createSelectItems.d.ts +0 -1
- package/dist/lib/reactivity/createTranslationState.d.ts +19 -0
- package/dist/lib/reactivity/createValueState.d.ts +6 -11
- package/dist/lib/reactivity/materializeCurrentStateChildren.d.ts +4 -5
- package/dist/lib/reactivity/node-state/createClientState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createCurrentState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createEngineState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSharedNodeState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSpecifiedPropertyDescriptor.d.ts +0 -1
- package/dist/lib/reactivity/node-state/createSpecifiedState.d.ts +0 -1
- package/dist/lib/reactivity/node-state/representations.d.ts +0 -1
- package/dist/lib/reactivity/scope.d.ts +0 -1
- package/dist/lib/reactivity/text/createFieldHint.d.ts +1 -2
- package/dist/lib/reactivity/text/createNodeLabel.d.ts +1 -2
- package/dist/lib/reactivity/text/createNoteText.d.ts +1 -2
- package/dist/lib/reactivity/text/createTextRange.d.ts +0 -1
- package/dist/lib/reactivity/types.d.ts +0 -1
- package/dist/lib/reactivity/validation/createAggregatedViolations.d.ts +0 -1
- package/dist/lib/reactivity/validation/createValidation.d.ts +0 -1
- package/dist/lib/xml-serialization.d.ts +41 -0
- package/dist/parse/XFormDOM.d.ts +42 -0
- package/dist/{XFormDefinition.d.ts → parse/XFormDefinition.d.ts} +3 -5
- package/dist/parse/attachments/FormAttachmentResource.d.ts +27 -0
- package/dist/{body → parse/body}/BodyDefinition.d.ts +16 -11
- package/dist/{body → parse/body}/BodyElementDefinition.d.ts +7 -7
- package/dist/{body → parse/body}/RepeatElementDefinition.d.ts +3 -4
- package/dist/{body → parse/body}/UnsupportedBodyElementDefinition.d.ts +0 -1
- package/dist/parse/body/appearance/inputAppearanceParser.d.ts +3 -0
- package/dist/{body → parse/body}/appearance/selectAppearanceParser.d.ts +1 -2
- package/dist/{body → parse/body}/appearance/structureElementAppearanceParser.d.ts +1 -2
- package/dist/parse/body/appearance/unknownAppearanceParser.d.ts +3 -0
- package/dist/{body → parse/body}/control/ControlDefinition.d.ts +3 -4
- package/dist/{body/control/InputDefinition.d.ts → parse/body/control/InputControlDefinition.d.ts} +2 -3
- package/dist/parse/body/control/RangeControlDefinition.d.ts +11 -0
- package/dist/parse/body/control/RankControlDefinition.d.ts +11 -0
- package/dist/parse/body/control/TriggerControlDefinition.d.ts +11 -0
- package/dist/parse/body/control/UploadControlDefinition.d.ts +11 -0
- package/dist/{body → parse/body}/control/select/ItemDefinition.d.ts +2 -3
- package/dist/{body → parse/body}/control/select/ItemsetDefinition.d.ts +4 -5
- package/dist/{body → parse/body}/control/select/ItemsetNodesetContext.d.ts +1 -4
- package/dist/{body → parse/body}/control/select/SelectDefinition.d.ts +3 -12
- package/dist/{body → parse/body}/group/BaseGroupDefinition.d.ts +3 -5
- package/dist/{body → parse/body}/group/LogicalGroupDefinition.d.ts +0 -1
- package/dist/{body → parse/body}/group/PresentationGroupDefinition.d.ts +1 -2
- package/dist/{body → parse/body}/group/StructuralGroupDefinition.d.ts +0 -1
- package/dist/{model/BindComputation.d.ts → parse/expression/BindComputationExpression.d.ts} +5 -6
- package/dist/{body/control/select → parse/expression}/ItemsetNodesetExpression.d.ts +2 -3
- package/dist/{body/control/select → parse/expression}/ItemsetValueExpression.d.ts +2 -3
- package/dist/parse/expression/RepeatCountControlExpression.d.ts +2 -3
- package/dist/parse/expression/TextLiteralExpression.d.ts +9 -0
- package/dist/parse/expression/TextOutputExpression.d.ts +7 -0
- package/dist/parse/expression/TextReferenceExpression.d.ts +7 -0
- package/dist/parse/expression/TextTranslationExpression.d.ts +8 -0
- package/dist/parse/expression/abstract/DependencyContext.d.ts +7 -0
- package/dist/{expression → parse/expression/abstract}/DependentExpression.d.ts +4 -6
- package/dist/parse/expression/abstract/TextChunkExpression.d.ts +17 -0
- package/dist/parse/model/BindDefinition.d.ts +38 -0
- package/dist/parse/model/BindTypeDefinition.d.ts +20 -0
- package/dist/{model → parse/model}/DescendentNodeDefinition.d.ts +0 -2
- package/dist/parse/model/FormSubmissionDefinition.d.ts +8 -0
- package/dist/parse/model/ItextTranslation/ItextTranslationDefinition.d.ts +4 -0
- package/dist/parse/model/ItextTranslation/ItextTranslationRootDefinition.d.ts +8 -0
- package/dist/parse/model/ItextTranslation/ItextTranslationsDefinition.d.ts +8 -0
- package/dist/{model → parse/model}/LeafNodeDefinition.d.ts +4 -3
- package/dist/{model → parse/model}/ModelBindMap.d.ts +1 -2
- package/dist/{model → parse/model}/ModelDefinition.d.ts +3 -2
- package/dist/{model → parse/model}/NodeDefinition.d.ts +0 -2
- package/dist/parse/{NoteNodeDefinition.d.ts → model/NoteNodeDefinition.d.ts} +12 -13
- package/dist/{model → parse/model}/RepeatInstanceDefinition.d.ts +1 -2
- package/dist/{model → parse/model}/RepeatRangeDefinition.d.ts +2 -3
- package/dist/{model → parse/model}/RepeatTemplateDefinition.d.ts +2 -3
- package/dist/{model → parse/model}/RootDefinition.d.ts +5 -5
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceDefinition.d.ts +4 -0
- package/dist/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.d.ts +7 -0
- package/dist/parse/model/SecondaryInstance/SecondaryInstancesDefinition.d.ts +13 -0
- package/dist/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.d.ts +14 -0
- package/dist/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.d.ts +22 -0
- package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.d.ts +23 -0
- package/dist/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.d.ts +9 -0
- package/dist/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.d.ts +5 -0
- package/dist/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.d.ts +7 -0
- package/dist/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.d.ts +13 -0
- package/dist/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.d.ts +12 -0
- package/dist/{model → parse/model}/SubtreeDefinition.d.ts +1 -2
- package/dist/parse/shared/parseStaticDocumentFromDOMSubtree.d.ts +24 -0
- package/dist/parse/text/HintDefinition.d.ts +2 -3
- package/dist/parse/text/ItemLabelDefinition.d.ts +2 -3
- package/dist/parse/text/ItemsetLabelDefinition.d.ts +3 -4
- package/dist/parse/text/LabelDefinition.d.ts +5 -6
- package/dist/parse/text/MessageDefinition.d.ts +4 -5
- package/dist/parse/text/abstract/TextElementDefinition.d.ts +8 -9
- package/dist/parse/text/abstract/TextRangeDefinition.d.ts +4 -7
- package/dist/parse/xpath/path-resolution.d.ts +0 -1
- package/dist/parse/xpath/predicate-analysis.d.ts +0 -1
- package/dist/parse/xpath/reference-parsing.d.ts +0 -1
- package/dist/parse/xpath/semantic-analysis.d.ts +5 -1
- package/dist/parse/xpath/syntax-traversal.d.ts +0 -1
- package/dist/solid.js +8398 -4543
- package/dist/solid.js.map +1 -1
- package/package.json +14 -12
- package/src/client/BaseNode.ts +17 -7
- package/src/client/BaseValueNode.ts +35 -0
- package/src/client/EngineConfig.ts +52 -51
- package/src/client/GroupNode.ts +2 -2
- package/src/client/InputNode.ts +77 -0
- package/src/client/ModelValueNode.ts +31 -8
- package/src/client/NodeAppearances.ts +1 -1
- package/src/client/NoteNode.ts +3 -3
- package/src/client/RootNode.ts +39 -9
- package/src/client/SelectNode.ts +5 -5
- package/src/client/SubtreeNode.ts +1 -1
- package/src/client/TextRange.ts +4 -5
- package/src/client/TriggerNode.ts +29 -0
- package/src/client/ValueType.ts +4 -0
- package/src/client/constants.ts +67 -0
- package/src/client/hierarchy.ts +16 -4
- package/src/client/identity.ts +16 -0
- package/src/client/node-types.ts +19 -5
- package/src/client/repeat/BaseRepeatRangeNode.ts +1 -1
- package/src/client/repeat/RepeatInstanceNode.ts +2 -2
- package/src/client/repeat/RepeatRangeControlledNode.ts +1 -1
- package/src/client/repeat/RepeatRangeUncontrolledNode.ts +1 -1
- package/src/client/resources.ts +118 -0
- package/src/client/submission/SubmissionData.ts +12 -0
- package/src/client/submission/SubmissionDefinition.ts +16 -0
- package/src/client/submission/SubmissionInstanceFile.ts +9 -0
- package/src/client/submission/SubmissionOptions.ts +28 -0
- package/src/client/submission/SubmissionResult.ts +124 -0
- package/src/client/submission/SubmissionState.ts +14 -0
- package/src/client/unsupported/RangeNode.ts +14 -0
- package/src/client/unsupported/RankNode.ts +14 -0
- package/src/client/unsupported/UnsupportedControlNode.ts +40 -0
- package/src/client/unsupported/UploadNode.ts +14 -0
- package/src/client/validation.ts +2 -2
- package/src/error/ErrorProductionDesignPendingError.ts +6 -0
- package/src/error/ValueTypeInvariantError.ts +22 -0
- package/src/error/XPathFunctionalityError.ts +26 -0
- package/src/error/XPathFunctionalityNotSupportedError.ts +18 -0
- package/src/error/XPathFunctionalityPendingError.ts +18 -0
- package/src/index.ts +16 -2
- package/src/instance/Group.ts +17 -5
- package/src/instance/InputControl.ts +119 -0
- package/src/instance/ModelValue.ts +47 -54
- package/src/instance/Note.ts +26 -10
- package/src/instance/PrimaryInstance.ts +244 -0
- package/src/instance/Root.ts +64 -132
- package/src/instance/SelectField.ts +62 -25
- package/src/instance/Subtree.ts +19 -7
- package/src/instance/{StringField.ts → TriggerControl.ts} +61 -30
- package/src/instance/abstract/DescendantNode.ts +92 -47
- package/src/instance/abstract/InstanceNode.ts +104 -98
- package/src/instance/abstract/UnsupportedControl.ts +174 -0
- package/src/instance/abstract/ValueNode.ts +127 -0
- package/src/instance/children.ts +83 -14
- package/src/instance/hierarchy.ts +36 -14
- package/src/instance/identity.ts +3 -9
- package/src/instance/index.ts +26 -8
- package/src/instance/internal-api/EvaluationContext.ts +61 -14
- package/src/instance/internal-api/InstanceConfig.ts +9 -2
- package/src/instance/internal-api/InstanceValueContext.ts +24 -0
- package/src/instance/internal-api/PrimaryInstanceDocument.ts +53 -0
- package/src/instance/internal-api/TranslationContext.ts +3 -2
- package/src/instance/internal-api/ValidationContext.ts +13 -5
- package/src/instance/internal-api/ValueContext.ts +5 -4
- package/src/instance/internal-api/submission/ClientReactiveSubmittableInstance.ts +20 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableLeafNode.ts +42 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableParentNode.ts +25 -0
- package/src/instance/internal-api/submission/ClientReactiveSubmittableValueNode.ts +23 -0
- package/src/instance/repeat/BaseRepeatRange.ts +51 -132
- package/src/instance/repeat/RepeatInstance.ts +20 -46
- package/src/instance/repeat/RepeatRangeControlled.ts +6 -6
- package/src/instance/repeat/RepeatRangeUncontrolled.ts +3 -5
- package/src/instance/resource.ts +1 -1
- package/src/instance/text/TextChunk.ts +1 -1
- package/src/instance/unsupported/RangeControl.ts +9 -0
- package/src/instance/unsupported/RankControl.ts +9 -0
- package/src/instance/unsupported/UploadControl.ts +9 -0
- package/src/integration/xpath/EngineXPathEvaluator.ts +22 -0
- package/src/integration/xpath/adapter/XFormsXPathNode.ts +126 -0
- package/src/integration/xpath/adapter/engineDOMAdapter.ts +57 -0
- package/src/integration/xpath/adapter/kind.ts +114 -0
- package/src/integration/xpath/adapter/names.ts +99 -0
- package/src/integration/xpath/adapter/traversal.ts +228 -0
- package/src/integration/xpath/adapter/values.ts +5 -0
- package/src/integration/xpath/static-dom/StaticAttribute.ts +33 -0
- package/src/integration/xpath/static-dom/StaticDocument.ts +38 -0
- package/src/integration/xpath/static-dom/StaticElement.ts +106 -0
- package/src/integration/xpath/static-dom/StaticNamedNode.ts +45 -0
- package/src/integration/xpath/static-dom/StaticNode.ts +68 -0
- package/src/integration/xpath/static-dom/StaticText.ts +28 -0
- package/src/lib/TokenListParser.ts +11 -7
- package/src/lib/client-reactivity/README.md +0 -0
- package/src/lib/client-reactivity/submission/createInstanceSubmissionState.ts +12 -0
- package/src/lib/client-reactivity/submission/createLeafNodeSubmissionState.ts +20 -0
- package/src/lib/client-reactivity/submission/createNodeRangeSubmissionState.ts +17 -0
- package/src/lib/client-reactivity/submission/createParentNodeSubmissionState.ts +22 -0
- package/src/lib/client-reactivity/submission/createValueNodeSubmissionState.ts +21 -0
- package/src/lib/client-reactivity/submission/prepareSubmission.ts +172 -0
- package/src/lib/codecs/DecimalValueCodec.ts +46 -0
- package/src/lib/codecs/IntValueCodec.ts +100 -0
- package/src/lib/codecs/StringValueCodec.ts +11 -0
- package/src/lib/codecs/ValueCodec.ts +106 -0
- package/src/lib/codecs/ValueTypePlaceholderCodec.ts +19 -0
- package/src/lib/codecs/getSharedValueCodec.ts +77 -0
- package/src/lib/dom/query.ts +8 -1
- package/src/lib/reactivity/createChildrenState.ts +8 -6
- package/src/lib/reactivity/createComputedExpression.ts +59 -36
- package/src/lib/reactivity/createInstanceValueState.ts +166 -0
- package/src/lib/reactivity/createNoteReadonlyThunk.ts +12 -7
- package/src/lib/reactivity/createSelectItems.ts +23 -23
- package/src/lib/reactivity/createTranslationState.ts +61 -0
- package/src/lib/reactivity/createValueState.ts +64 -122
- package/src/lib/reactivity/materializeCurrentStateChildren.ts +7 -7
- package/src/lib/reactivity/node-state/createSpecifiedState.ts +1 -1
- package/src/lib/reactivity/text/createFieldHint.ts +1 -1
- package/src/lib/reactivity/text/createNodeLabel.ts +1 -1
- package/src/lib/reactivity/text/createNoteText.ts +1 -1
- package/src/lib/reactivity/text/createTextRange.ts +8 -7
- package/src/lib/reactivity/validation/createAggregatedViolations.ts +9 -4
- package/src/lib/reactivity/validation/createValidation.ts +2 -3
- package/src/lib/xml-serialization.ts +96 -0
- package/src/{XFormDOM.ts → parse/XFormDOM.ts} +110 -75
- package/src/{XFormDefinition.ts → parse/XFormDefinition.ts} +3 -8
- package/src/parse/attachments/FormAttachmentResource.ts +40 -0
- package/src/{body → parse/body}/BodyDefinition.ts +46 -29
- package/src/{body → parse/body}/BodyElementDefinition.ts +12 -6
- package/src/{body → parse/body}/RepeatElementDefinition.ts +7 -5
- package/src/{body → parse/body}/appearance/inputAppearanceParser.ts +2 -2
- package/src/{body → parse/body}/appearance/selectAppearanceParser.ts +1 -1
- package/src/{body → parse/body}/appearance/structureElementAppearanceParser.ts +1 -1
- package/src/parse/body/appearance/unknownAppearanceParser.ts +5 -0
- package/src/{body → parse/body}/control/ControlDefinition.ts +4 -4
- package/src/{body/control/InputDefinition.ts → parse/body/control/InputControlDefinition.ts} +3 -5
- package/src/parse/body/control/RangeControlDefinition.ts +26 -0
- package/src/parse/body/control/RankControlDefinition.ts +27 -0
- package/src/parse/body/control/TriggerControlDefinition.ts +26 -0
- package/src/parse/body/control/UploadControlDefinition.ts +26 -0
- package/src/{body → parse/body}/control/select/ItemDefinition.ts +2 -2
- package/src/{body → parse/body}/control/select/ItemsetDefinition.ts +5 -5
- package/src/{body → parse/body}/control/select/ItemsetNodesetContext.ts +1 -6
- package/src/{body → parse/body}/control/select/SelectDefinition.ts +3 -11
- package/src/{body → parse/body}/group/BaseGroupDefinition.ts +11 -22
- package/src/{body → parse/body}/group/PresentationGroupDefinition.ts +1 -1
- package/src/{model/BindComputation.ts → parse/expression/BindComputationExpression.ts} +8 -8
- package/src/{body/control/select → parse/expression}/ItemsetNodesetExpression.ts +2 -2
- package/src/{body/control/select → parse/expression}/ItemsetValueExpression.ts +2 -2
- package/src/parse/expression/RepeatCountControlExpression.ts +2 -2
- package/src/parse/expression/TextLiteralExpression.ts +19 -0
- package/src/parse/{text/OutputChunkDefinition.ts → expression/TextOutputExpression.ts} +4 -4
- package/src/parse/{text/ReferenceChunkDefinition.ts → expression/TextReferenceExpression.ts} +4 -4
- package/src/parse/{text/TranslationChunkDefinition.ts → expression/TextTranslationExpression.ts} +4 -4
- package/src/{expression → parse/expression/abstract}/DependencyContext.ts +0 -26
- package/src/{expression → parse/expression/abstract}/DependentExpression.ts +5 -16
- package/src/parse/expression/abstract/TextChunkExpression.ts +38 -0
- package/src/parse/model/BindDefinition.ts +104 -0
- package/src/parse/model/BindTypeDefinition.ts +175 -0
- package/src/{model → parse/model}/DescendentNodeDefinition.ts +0 -6
- package/src/parse/model/FormSubmissionDefinition.ts +44 -0
- package/src/parse/model/ItextTranslation/ItextTranslationDefinition.ts +4 -0
- package/src/parse/model/ItextTranslation/ItextTranslationRootDefinition.ts +41 -0
- package/src/parse/model/ItextTranslation/ItextTranslationsDefinition.ts +31 -0
- package/src/{model → parse/model}/LeafNodeDefinition.ts +4 -1
- package/src/{model → parse/model}/ModelBindMap.ts +6 -8
- package/src/parse/model/ModelDefinition.ts +24 -0
- package/src/{model → parse/model}/NodeDefinition.ts +0 -3
- package/src/parse/{NoteNodeDefinition.ts → model/NoteNodeDefinition.ts} +12 -12
- package/src/{model → parse/model}/RepeatRangeDefinition.ts +1 -1
- package/src/{model → parse/model}/RootDefinition.ts +4 -3
- package/src/parse/model/SecondaryInstance/SecondaryInstanceDefinition.ts +4 -0
- package/src/parse/model/SecondaryInstance/SecondaryInstanceRootDefinition.ts +12 -0
- package/src/parse/model/SecondaryInstance/SecondaryInstancesDefinition.ts +102 -0
- package/src/parse/model/SecondaryInstance/sources/BlankSecondaryInstanceSource.ts +40 -0
- package/src/parse/model/SecondaryInstance/sources/CSVExternalSecondaryInstance.ts +288 -0
- package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceResource.ts +222 -0
- package/src/parse/model/SecondaryInstance/sources/ExternalSecondaryInstanceSource.ts +22 -0
- package/src/parse/model/SecondaryInstance/sources/GeoJSONExternalSecondaryInstance.ts +414 -0
- package/src/parse/model/SecondaryInstance/sources/InternalSecondaryInstanceSource.ts +19 -0
- package/src/parse/model/SecondaryInstance/sources/SecondaryInstanceSource.ts +29 -0
- package/src/parse/model/SecondaryInstance/sources/XMLExternalSecondaryInstanceSource.ts +32 -0
- package/src/parse/shared/parseStaticDocumentFromDOMSubtree.ts +149 -0
- package/src/parse/text/HintDefinition.ts +2 -2
- package/src/parse/text/ItemLabelDefinition.ts +2 -2
- package/src/parse/text/ItemsetLabelDefinition.ts +7 -7
- package/src/parse/text/LabelDefinition.ts +5 -5
- package/src/parse/text/MessageDefinition.ts +7 -7
- package/src/parse/text/abstract/TextElementDefinition.ts +14 -14
- package/src/parse/text/abstract/TextRangeDefinition.ts +4 -10
- package/src/parse/xpath/semantic-analysis.ts +29 -0
- package/dist/XFormDOM.d.ts +0 -32
- package/dist/XFormDataType.d.ts +0 -27
- package/dist/body/appearance/inputAppearanceParser.d.ts +0 -4
- package/dist/client/StringNode.d.ts +0 -47
- package/dist/expression/DependencyContext.d.ts +0 -13
- package/dist/instance/StringField.d.ts +0 -45
- package/dist/instance/internal-api/SubscribableDependency.d.ts +0 -60
- package/dist/model/BindDefinition.d.ts +0 -34
- package/dist/parse/text/OutputChunkDefinition.d.ts +0 -8
- package/dist/parse/text/ReferenceChunkDefinition.d.ts +0 -8
- package/dist/parse/text/StaticTextChunkDefinition.d.ts +0 -10
- package/dist/parse/text/TranslationChunkDefinition.d.ts +0 -9
- package/dist/parse/text/abstract/TextChunkDefinition.d.ts +0 -18
- package/src/XFormDataType.ts +0 -64
- package/src/client/StringNode.ts +0 -52
- package/src/instance/internal-api/SubscribableDependency.ts +0 -61
- package/src/model/BindDefinition.ts +0 -106
- package/src/model/ModelDefinition.ts +0 -19
- package/src/parse/TODO.md +0 -3
- package/src/parse/text/StaticTextChunkDefinition.ts +0 -19
- package/src/parse/text/abstract/TextChunkDefinition.ts +0 -38
- /package/dist/{model → parse/model}/BindElement.d.ts +0 -0
- /package/src/{body → parse/body}/UnsupportedBodyElementDefinition.ts +0 -0
- /package/src/{body → parse/body}/group/LogicalGroupDefinition.ts +0 -0
- /package/src/{body → parse/body}/group/StructuralGroupDefinition.ts +0 -0
- /package/src/{model → parse/model}/BindElement.ts +0 -0
- /package/src/{model → parse/model}/RepeatInstanceDefinition.ts +0 -0
- /package/src/{model → parse/model}/RepeatTemplateDefinition.ts +0 -0
- /package/src/{model → parse/model}/SubtreeDefinition.ts +0 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import type { JRResourceURL } from '@getodk/common/jr-resources/JRResourceURL.ts';
|
|
2
|
+
import type { MissingResourceBehavior } from '../../../../client/constants.ts';
|
|
3
|
+
import type { FetchResource, FetchResourceResponse } from '../../../../client/resources.ts';
|
|
4
|
+
import { ErrorProductionDesignPendingError } from '../../../../error/ErrorProductionDesignPendingError.ts';
|
|
5
|
+
import { FormAttachmentResource } from '../../../attachments/FormAttachmentResource.ts';
|
|
6
|
+
import type { ExternalSecondaryInstanceSourceFormat } from './SecondaryInstanceSource.ts';
|
|
7
|
+
|
|
8
|
+
const assertResponseSuccess = (resourceURL: JRResourceURL, response: FetchResourceResponse) => {
|
|
9
|
+
const { ok = true, status = 200 } = response;
|
|
10
|
+
|
|
11
|
+
if (!ok || status !== 200) {
|
|
12
|
+
throw new ErrorProductionDesignPendingError(`Failed to load ${resourceURL.href}`);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const stripContentTypeCharset = (contentType: string): string => {
|
|
17
|
+
return contentType.replace(/;charset=.*$/, '');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const getResponseContentType = (response: FetchResourceResponse): string | null => {
|
|
21
|
+
const { headers } = response;
|
|
22
|
+
|
|
23
|
+
if (headers == null) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const contentType = headers.get('content-type');
|
|
28
|
+
|
|
29
|
+
if (contentType != null) {
|
|
30
|
+
return stripContentTypeCharset(contentType);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (headers instanceof Headers) {
|
|
34
|
+
return contentType;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const [header, value] of headers) {
|
|
38
|
+
if (header.toLowerCase() === 'content-type') {
|
|
39
|
+
return stripContentTypeCharset(value);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return null;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
interface ExternalSecondaryInstanceResourceMetadata<
|
|
47
|
+
Format extends ExternalSecondaryInstanceSourceFormat = ExternalSecondaryInstanceSourceFormat,
|
|
48
|
+
> {
|
|
49
|
+
readonly contentType: string;
|
|
50
|
+
readonly format: Format;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const inferSecondaryInstanceResourceMetadata = (
|
|
54
|
+
resourceURL: JRResourceURL,
|
|
55
|
+
contentType: string | null,
|
|
56
|
+
data: string
|
|
57
|
+
): ExternalSecondaryInstanceResourceMetadata => {
|
|
58
|
+
const url = resourceURL.href;
|
|
59
|
+
|
|
60
|
+
let format: ExternalSecondaryInstanceSourceFormat | null = null;
|
|
61
|
+
|
|
62
|
+
if (url.endsWith('.xml') && data.startsWith('<')) {
|
|
63
|
+
format = 'xml';
|
|
64
|
+
} else if (url.endsWith('.csv')) {
|
|
65
|
+
format = 'csv';
|
|
66
|
+
} else if (url.endsWith('.geojson') && data.startsWith('{')) {
|
|
67
|
+
format = 'geojson';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (format == null) {
|
|
71
|
+
throw new ErrorProductionDesignPendingError(
|
|
72
|
+
`Failed to infer external secondary instance format/content type for resource ${url} (response content type: ${contentType}, data: ${data})`
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
contentType: contentType ?? 'text/plain',
|
|
78
|
+
format,
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const detectSecondaryInstanceResourceMetadata = (
|
|
83
|
+
resourceURL: JRResourceURL,
|
|
84
|
+
response: FetchResourceResponse,
|
|
85
|
+
data: string
|
|
86
|
+
): ExternalSecondaryInstanceResourceMetadata => {
|
|
87
|
+
const contentType = getResponseContentType(response);
|
|
88
|
+
|
|
89
|
+
if (contentType == null || contentType === 'text/plain') {
|
|
90
|
+
return inferSecondaryInstanceResourceMetadata(resourceURL, contentType, data);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let format: ExternalSecondaryInstanceSourceFormat | null = null;
|
|
94
|
+
|
|
95
|
+
switch (contentType) {
|
|
96
|
+
case 'text/csv':
|
|
97
|
+
format = 'csv';
|
|
98
|
+
break;
|
|
99
|
+
|
|
100
|
+
case 'application/geo+json':
|
|
101
|
+
format = 'geojson';
|
|
102
|
+
break;
|
|
103
|
+
|
|
104
|
+
case 'text/xml':
|
|
105
|
+
format = 'xml';
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (format == null) {
|
|
110
|
+
throw new ErrorProductionDesignPendingError(
|
|
111
|
+
`Failed to detect external secondary instance format for resource ${resourceURL.href} (response content type: ${contentType}, data: ${data})`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
contentType,
|
|
117
|
+
format,
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
interface MissingResourceResponse extends FetchResourceResponse {
|
|
122
|
+
readonly status: 404;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ExternalSecondaryInstanceResourceLoadOptions {
|
|
126
|
+
readonly fetchResource: FetchResource<JRResourceURL>;
|
|
127
|
+
readonly missingResourceBehavior: MissingResourceBehavior;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type LoadedExternalSecondaryInstanceResource = {
|
|
131
|
+
[Format in ExternalSecondaryInstanceSourceFormat]: ExternalSecondaryInstanceResource<Format>;
|
|
132
|
+
}[ExternalSecondaryInstanceSourceFormat];
|
|
133
|
+
|
|
134
|
+
interface ExternalSecondaryInstanceResourceOptions {
|
|
135
|
+
readonly isExplicitlyBlank?: boolean;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export class ExternalSecondaryInstanceResource<
|
|
139
|
+
Format extends ExternalSecondaryInstanceSourceFormat = ExternalSecondaryInstanceSourceFormat,
|
|
140
|
+
> extends FormAttachmentResource<'secondary-instance'> {
|
|
141
|
+
private static isMissingResource(
|
|
142
|
+
response: FetchResourceResponse
|
|
143
|
+
): response is MissingResourceResponse {
|
|
144
|
+
return response.status === 404;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private static createBlankResource(
|
|
148
|
+
instanceId: string,
|
|
149
|
+
resourceURL: JRResourceURL,
|
|
150
|
+
response: MissingResourceResponse,
|
|
151
|
+
options: ExternalSecondaryInstanceResourceLoadOptions
|
|
152
|
+
) {
|
|
153
|
+
if (options.missingResourceBehavior === 'BLANK') {
|
|
154
|
+
return new this(
|
|
155
|
+
response.status,
|
|
156
|
+
instanceId,
|
|
157
|
+
resourceURL,
|
|
158
|
+
{
|
|
159
|
+
format: 'xml',
|
|
160
|
+
contentType: 'text/xml',
|
|
161
|
+
},
|
|
162
|
+
'',
|
|
163
|
+
{ isExplicitlyBlank: true }
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
throw new ErrorProductionDesignPendingError(
|
|
168
|
+
`Failed to load resource: ${resourceURL.href}: resource is missing (status: ${response.status})`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
static async load(
|
|
173
|
+
instanceId: string,
|
|
174
|
+
resourceURL: JRResourceURL,
|
|
175
|
+
options: ExternalSecondaryInstanceResourceLoadOptions
|
|
176
|
+
): Promise<LoadedExternalSecondaryInstanceResource> {
|
|
177
|
+
const response = await options.fetchResource(resourceURL);
|
|
178
|
+
|
|
179
|
+
if (this.isMissingResource(response)) {
|
|
180
|
+
return this.createBlankResource(instanceId, resourceURL, response, options);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
assertResponseSuccess(resourceURL, response);
|
|
184
|
+
|
|
185
|
+
const data = await response.text();
|
|
186
|
+
const metadata = detectSecondaryInstanceResourceMetadata(resourceURL, response, data);
|
|
187
|
+
|
|
188
|
+
return new this(response.status ?? null, instanceId, resourceURL, metadata, data, {
|
|
189
|
+
isExplicitlyBlank: false,
|
|
190
|
+
}) satisfies ExternalSecondaryInstanceResource as LoadedExternalSecondaryInstanceResource;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
readonly format: Format;
|
|
194
|
+
readonly isBlank: boolean;
|
|
195
|
+
|
|
196
|
+
private constructor(
|
|
197
|
+
readonly responseStatus: number | null,
|
|
198
|
+
readonly instanceId: string,
|
|
199
|
+
resourceURL: JRResourceURL,
|
|
200
|
+
metadata: ExternalSecondaryInstanceResourceMetadata<Format>,
|
|
201
|
+
data: string,
|
|
202
|
+
options: ExternalSecondaryInstanceResourceOptions
|
|
203
|
+
) {
|
|
204
|
+
const { contentType, format } = metadata;
|
|
205
|
+
|
|
206
|
+
super('secondary-instance', resourceURL, contentType, data);
|
|
207
|
+
|
|
208
|
+
this.format = format;
|
|
209
|
+
|
|
210
|
+
if (data === '') {
|
|
211
|
+
if (options.isExplicitlyBlank) {
|
|
212
|
+
this.isBlank = true;
|
|
213
|
+
} else {
|
|
214
|
+
throw new ErrorProductionDesignPendingError(
|
|
215
|
+
`Failed to load blank external secndary instance ${resourceURL.href}`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
this.isBlank = false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { JRResourceURL } from '@getodk/common/jr-resources/JRResourceURL.ts';
|
|
2
|
+
import type { DOMSecondaryInstanceElement } from '../../../XFormDOM.ts';
|
|
3
|
+
import type { ExternalSecondaryInstanceResource } from './ExternalSecondaryInstanceResource.ts';
|
|
4
|
+
import type { ExternalSecondaryInstanceSourceFormat } from './SecondaryInstanceSource.ts';
|
|
5
|
+
import { SecondaryInstanceSource } from './SecondaryInstanceSource.ts';
|
|
6
|
+
|
|
7
|
+
export abstract class ExternalSecondaryInstanceSource<
|
|
8
|
+
Format extends ExternalSecondaryInstanceSourceFormat = ExternalSecondaryInstanceSourceFormat,
|
|
9
|
+
> extends SecondaryInstanceSource<Format> {
|
|
10
|
+
override readonly resourceURL: JRResourceURL;
|
|
11
|
+
|
|
12
|
+
constructor(
|
|
13
|
+
domElement: DOMSecondaryInstanceElement,
|
|
14
|
+
protected readonly resource: ExternalSecondaryInstanceResource<Format>
|
|
15
|
+
) {
|
|
16
|
+
const { format, instanceId, resourceURL } = resource;
|
|
17
|
+
|
|
18
|
+
super(format, instanceId, resourceURL, domElement);
|
|
19
|
+
|
|
20
|
+
this.resourceURL = resourceURL;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { XFORMS_NAMESPACE_URI } from '@getodk/common/constants/xmlns.ts';
|
|
2
|
+
import { UnreachableError } from '@getodk/common/lib/error/UnreachableError.ts';
|
|
3
|
+
import { assertUnknownArray } from '@getodk/common/lib/type-assertions/assertUnknownArray.ts';
|
|
4
|
+
import type { UnknownObject } from '@getodk/common/lib/type-assertions/assertUnknownObject.ts';
|
|
5
|
+
import { assertUnknownObject } from '@getodk/common/lib/type-assertions/assertUnknownObject.ts';
|
|
6
|
+
import type {
|
|
7
|
+
GeoJsonProperties as BaseGeoJSONProperties,
|
|
8
|
+
LineString as BaseLineString,
|
|
9
|
+
Point as BasePoint,
|
|
10
|
+
Polygon as BasePolygon,
|
|
11
|
+
Feature as GeoJSONFeature,
|
|
12
|
+
FeatureCollection as GeoJSONFeatureCollection,
|
|
13
|
+
} from 'geojson';
|
|
14
|
+
import { ErrorProductionDesignPendingError } from '../../../../error/ErrorProductionDesignPendingError.ts';
|
|
15
|
+
import { StaticAttribute } from '../../../../integration/xpath/static-dom/StaticAttribute.ts';
|
|
16
|
+
import { StaticElement } from '../../../../integration/xpath/static-dom/StaticElement.ts';
|
|
17
|
+
import { StaticText } from '../../../../integration/xpath/static-dom/StaticText.ts';
|
|
18
|
+
import { SecondaryInstanceDefinition } from '../SecondaryInstanceDefinition.ts';
|
|
19
|
+
import { SecondaryInstanceRootDefinition } from '../SecondaryInstanceRootDefinition.ts';
|
|
20
|
+
import { ExternalSecondaryInstanceSource } from './ExternalSecondaryInstanceSource.ts';
|
|
21
|
+
|
|
22
|
+
const FEATURE_COLLECTION = 'FeatureCollection';
|
|
23
|
+
type FEATURE_COLLECTION = typeof FEATURE_COLLECTION;
|
|
24
|
+
|
|
25
|
+
const FEATURE = 'Feature';
|
|
26
|
+
type FEATURE = typeof FEATURE;
|
|
27
|
+
|
|
28
|
+
const POINT = 'Point';
|
|
29
|
+
type POINT = typeof POINT;
|
|
30
|
+
|
|
31
|
+
const LINE_STRING = 'LineString';
|
|
32
|
+
type LINE_STRING = typeof LINE_STRING;
|
|
33
|
+
|
|
34
|
+
const POLYGON = 'Polygon';
|
|
35
|
+
type POLYGON = typeof POLYGON;
|
|
36
|
+
|
|
37
|
+
type SupportedGeometryType = LINE_STRING | POINT | POLYGON;
|
|
38
|
+
|
|
39
|
+
const SUPPORTED_TYPES = new Set<SupportedGeometryType>([POINT, LINE_STRING, POLYGON]);
|
|
40
|
+
|
|
41
|
+
const SUPPORTED_TYPES_MESSAGE = 'Only Points, LineStrings and Polygons are currently supported';
|
|
42
|
+
|
|
43
|
+
type LongLatCoordinates = readonly [longitude: number, latitude: number];
|
|
44
|
+
|
|
45
|
+
interface UnknownCoordinatesObject {
|
|
46
|
+
readonly coordinates: unknown;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// prettier-ignore
|
|
50
|
+
type ExtensibleBaseGeoJSONType<T> =
|
|
51
|
+
T extends UnknownCoordinatesObject
|
|
52
|
+
? Readonly<Omit<T, 'coordinates'>>
|
|
53
|
+
: Readonly<T>;
|
|
54
|
+
|
|
55
|
+
interface Point extends ExtensibleBaseGeoJSONType<BasePoint> {
|
|
56
|
+
readonly coordinates: LongLatCoordinates;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type LineStringCoordinates = readonly LongLatCoordinates[];
|
|
60
|
+
|
|
61
|
+
interface LineString extends ExtensibleBaseGeoJSONType<BaseLineString> {
|
|
62
|
+
readonly coordinates: LineStringCoordinates;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// prettier-ignore
|
|
66
|
+
type PolygonCoordinates =
|
|
67
|
+
| readonly []
|
|
68
|
+
| readonly [LineStringCoordinates];
|
|
69
|
+
|
|
70
|
+
interface Polygon extends ExtensibleBaseGeoJSONType<BasePolygon> {
|
|
71
|
+
readonly coordinates: PolygonCoordinates;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// prettier-ignore
|
|
75
|
+
type SupportedGeometry =
|
|
76
|
+
| LineString
|
|
77
|
+
| Point
|
|
78
|
+
| Polygon;
|
|
79
|
+
|
|
80
|
+
interface UnparsedGeometry<Type extends SupportedGeometryType> {
|
|
81
|
+
readonly type: Type;
|
|
82
|
+
readonly coordinates: readonly unknown[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type UnknownGeometry = {
|
|
86
|
+
[Type in SupportedGeometryType]: UnparsedGeometry<Type>;
|
|
87
|
+
}[SupportedGeometryType];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* This is a stricter variant of {@link BaseGeoJSONProperties}.
|
|
91
|
+
*/
|
|
92
|
+
type GeoJSONProperties = UnknownObject;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* This is our supported variant/subset of {@link GeoJSONFeature} where:
|
|
96
|
+
*
|
|
97
|
+
* - {@link geometry} is parsed/validated to be one of our
|
|
98
|
+
* {@link SupportedGeometry | supported geometries}
|
|
99
|
+
*
|
|
100
|
+
* - all properties and non-primitive property values are deeply `readonly`
|
|
101
|
+
*/
|
|
102
|
+
interface Feature {
|
|
103
|
+
readonly type: FEATURE;
|
|
104
|
+
readonly geometry: SupportedGeometry;
|
|
105
|
+
readonly id?: number | string | undefined;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Perhaps surprising: this property is required by the
|
|
109
|
+
* {@link https://datatracker.ietf.org/doc/html/rfc7946#section-3.2 | GeoJSON spec}!
|
|
110
|
+
*/
|
|
111
|
+
readonly properties: GeoJSONProperties | null;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* This is our supported variant/subset of {@link GeoJSONFeatureCollection}, as
|
|
116
|
+
* described for {@link Feature}.
|
|
117
|
+
*/
|
|
118
|
+
interface FeatureCollection {
|
|
119
|
+
readonly type: FEATURE_COLLECTION;
|
|
120
|
+
readonly features: readonly Feature[];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
type AssertLongLatCoordinates = (data: unknown) => asserts data is LongLatCoordinates;
|
|
124
|
+
|
|
125
|
+
const assertLongLatCoordinates: AssertLongLatCoordinates = (data) => {
|
|
126
|
+
assertUnknownArray(data);
|
|
127
|
+
|
|
128
|
+
const [longitude, latitude, ...rest] = data;
|
|
129
|
+
|
|
130
|
+
if (typeof longitude === 'number' && typeof latitude === 'number' && rest.length === 0) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
throw new ErrorProductionDesignPendingError(
|
|
135
|
+
`Only ${POINT}s with latitude and longitude are currently supported`
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
type AssertUnknownGeometry = (value: unknown) => asserts value is UnknownGeometry;
|
|
140
|
+
|
|
141
|
+
const assertUnknownGeometry: AssertUnknownGeometry = (value) => {
|
|
142
|
+
assertUnknownObject(value);
|
|
143
|
+
|
|
144
|
+
if (!SUPPORTED_TYPES.has(value.type as SupportedGeometryType)) {
|
|
145
|
+
throw new ErrorProductionDesignPendingError(SUPPORTED_TYPES_MESSAGE);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
assertUnknownArray(value.coordinates);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
type AssertSupportedGeometry = (value: unknown) => asserts value is SupportedGeometry;
|
|
152
|
+
|
|
153
|
+
const assertSupportedGeometry: AssertSupportedGeometry = (value) => {
|
|
154
|
+
assertUnknownGeometry(value);
|
|
155
|
+
|
|
156
|
+
switch (value.type) {
|
|
157
|
+
case LINE_STRING:
|
|
158
|
+
value.coordinates.forEach(assertLongLatCoordinates);
|
|
159
|
+
break;
|
|
160
|
+
|
|
161
|
+
case POINT:
|
|
162
|
+
assertLongLatCoordinates(value.coordinates);
|
|
163
|
+
break;
|
|
164
|
+
|
|
165
|
+
case POLYGON: {
|
|
166
|
+
const [coordinates, ...rest] = value.coordinates;
|
|
167
|
+
|
|
168
|
+
if (coordinates == null) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (rest.length > 0) {
|
|
173
|
+
throw new ErrorProductionDesignPendingError(
|
|
174
|
+
`Unsupported ${POLYGON}: multiple sets of coordinates`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
assertUnknownArray(coordinates);
|
|
179
|
+
coordinates.forEach(assertLongLatCoordinates);
|
|
180
|
+
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
default:
|
|
185
|
+
throw new UnreachableError(value);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
type AssertFeature = (value: unknown) => asserts value is Feature;
|
|
190
|
+
|
|
191
|
+
const assertFeature: AssertFeature = (value) => {
|
|
192
|
+
assertUnknownObject(value);
|
|
193
|
+
|
|
194
|
+
const { geometry, type, id, properties } = value;
|
|
195
|
+
|
|
196
|
+
if (type !== FEATURE) {
|
|
197
|
+
throw new ErrorProductionDesignPendingError(
|
|
198
|
+
`Expected Feature.type ${FEATURE}, got ${String(type)}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
assertSupportedGeometry(geometry);
|
|
203
|
+
|
|
204
|
+
if ('id' in value) {
|
|
205
|
+
const typeofId = typeof id;
|
|
206
|
+
|
|
207
|
+
switch (typeofId) {
|
|
208
|
+
case 'number':
|
|
209
|
+
case 'string':
|
|
210
|
+
case 'undefined':
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
default:
|
|
214
|
+
throw new ErrorProductionDesignPendingError(
|
|
215
|
+
`Unexpected type of feature id property: ${typeofId}`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Note: atypical strict check for `null` value! The `properties` key is
|
|
221
|
+
// required per
|
|
222
|
+
if (properties === null) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
assertUnknownObject(properties);
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
type AssertFeatureCollection = (value: unknown) => asserts value is FeatureCollection;
|
|
230
|
+
|
|
231
|
+
const assertFeatureCollection: AssertFeatureCollection = (value) => {
|
|
232
|
+
assertUnknownObject(value);
|
|
233
|
+
|
|
234
|
+
const { type, features } = value;
|
|
235
|
+
|
|
236
|
+
if (type !== FEATURE_COLLECTION) {
|
|
237
|
+
throw new ErrorProductionDesignPendingError(
|
|
238
|
+
`Expected FeatureCollection.type ${FEATURE_COLLECTION}, got ${String(type)}`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
assertUnknownArray(features);
|
|
243
|
+
|
|
244
|
+
features.forEach(assertFeature);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
type SerializedCoordinates = `${LongLatCoordinates[1]} ${LongLatCoordinates[0]} 0 0`;
|
|
248
|
+
|
|
249
|
+
const serializeCoordinates = (coordinates: LongLatCoordinates): SerializedCoordinates => {
|
|
250
|
+
const [longitude, latitude] = coordinates;
|
|
251
|
+
|
|
252
|
+
return `${latitude} ${longitude} 0 0`;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
class GeoJSONSecondaryInstanceFeatureGeometryElement extends StaticElement {
|
|
256
|
+
static from(
|
|
257
|
+
parent: StaticElement,
|
|
258
|
+
feature: Feature
|
|
259
|
+
): GeoJSONSecondaryInstanceFeatureGeometryElement {
|
|
260
|
+
const { geometry } = feature;
|
|
261
|
+
|
|
262
|
+
switch (geometry.type) {
|
|
263
|
+
case 'LineString':
|
|
264
|
+
return new this(parent, geometry.coordinates);
|
|
265
|
+
|
|
266
|
+
case 'Point':
|
|
267
|
+
return new this(parent, [geometry.coordinates]);
|
|
268
|
+
|
|
269
|
+
case 'Polygon':
|
|
270
|
+
return new this(parent, geometry.coordinates[0] ?? []);
|
|
271
|
+
|
|
272
|
+
default:
|
|
273
|
+
throw new UnreachableError(geometry);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
constructor(parent: StaticElement, points: readonly LongLatCoordinates[]) {
|
|
278
|
+
const values = points.map(serializeCoordinates);
|
|
279
|
+
const value = values.join('; ');
|
|
280
|
+
|
|
281
|
+
super(
|
|
282
|
+
parent,
|
|
283
|
+
() => [],
|
|
284
|
+
(self) => [new StaticText(self, value)],
|
|
285
|
+
{
|
|
286
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
287
|
+
localName: 'geometry',
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
class GeoJSONSecondaryInstanceFeaturePropertyElement extends StaticElement {
|
|
294
|
+
static *buildPropertyElements(
|
|
295
|
+
parent: StaticElement,
|
|
296
|
+
feature: Feature
|
|
297
|
+
): Iterable<GeoJSONSecondaryInstanceFeaturePropertyElement> {
|
|
298
|
+
const { properties } = feature;
|
|
299
|
+
|
|
300
|
+
if (properties == null) {
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const { id: propertiesId, ...nonIdProperties } = properties;
|
|
305
|
+
const { id = propertiesId } = feature;
|
|
306
|
+
|
|
307
|
+
if (id !== undefined) {
|
|
308
|
+
yield new this(parent, 'id', String(id));
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
for (const [propertyName, propertyValue] of Object.entries(nonIdProperties)) {
|
|
312
|
+
yield new this(parent, propertyName, String(propertyValue));
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
constructor(parent: StaticElement, propertyName: string, propertyValue: string) {
|
|
317
|
+
super(
|
|
318
|
+
parent,
|
|
319
|
+
() => [],
|
|
320
|
+
(self) => [new StaticText(self, propertyValue)],
|
|
321
|
+
{
|
|
322
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
323
|
+
localName: propertyName,
|
|
324
|
+
}
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
class GeoJSONSecondaryInstanceFeatureItemElement extends StaticElement {
|
|
330
|
+
constructor(parent: StaticElement, feature: Feature) {
|
|
331
|
+
super(
|
|
332
|
+
parent,
|
|
333
|
+
() => [],
|
|
334
|
+
(self) => {
|
|
335
|
+
const geometry = GeoJSONSecondaryInstanceFeatureGeometryElement.from(self, feature);
|
|
336
|
+
const properties = GeoJSONSecondaryInstanceFeaturePropertyElement.buildPropertyElements(
|
|
337
|
+
self,
|
|
338
|
+
feature
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
return [geometry, ...properties];
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
345
|
+
localName: 'item',
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
class GeoJSONSecondaryInstanceRootElement extends StaticElement {
|
|
352
|
+
constructor(parent: StaticElement, featureCollection: FeatureCollection) {
|
|
353
|
+
super(
|
|
354
|
+
parent,
|
|
355
|
+
() => [],
|
|
356
|
+
(self) => {
|
|
357
|
+
return featureCollection.features.map((feature) => {
|
|
358
|
+
return new GeoJSONSecondaryInstanceFeatureItemElement(self, feature);
|
|
359
|
+
});
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
363
|
+
localName: 'root',
|
|
364
|
+
}
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
class GeoJSONExternalSecondaryInstanceDocumentElement extends SecondaryInstanceRootDefinition {
|
|
370
|
+
constructor(
|
|
371
|
+
instanceId: string,
|
|
372
|
+
parent: GeoJSONExternalSecondaryInstanceDefinition,
|
|
373
|
+
featureCollection: FeatureCollection
|
|
374
|
+
) {
|
|
375
|
+
super(
|
|
376
|
+
parent,
|
|
377
|
+
(self) => [
|
|
378
|
+
new StaticAttribute(self, {
|
|
379
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
380
|
+
localName: 'id',
|
|
381
|
+
value: instanceId,
|
|
382
|
+
}),
|
|
383
|
+
],
|
|
384
|
+
(self) => [new GeoJSONSecondaryInstanceRootElement(self, featureCollection)],
|
|
385
|
+
{
|
|
386
|
+
namespaceURI: XFORMS_NAMESPACE_URI,
|
|
387
|
+
localName: 'instance',
|
|
388
|
+
}
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
class GeoJSONExternalSecondaryInstanceDefinition extends SecondaryInstanceDefinition {
|
|
394
|
+
constructor(instanceId: string, featureCollection: FeatureCollection) {
|
|
395
|
+
super((self) => {
|
|
396
|
+
return new GeoJSONExternalSecondaryInstanceDocumentElement(
|
|
397
|
+
instanceId,
|
|
398
|
+
self,
|
|
399
|
+
featureCollection
|
|
400
|
+
);
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
export class GeoJSONExternalSecondaryInstanceSource extends ExternalSecondaryInstanceSource<'geojson'> {
|
|
406
|
+
parseDefinition(): SecondaryInstanceDefinition {
|
|
407
|
+
const { data } = this.resource;
|
|
408
|
+
const value = JSON.parse(data) as unknown;
|
|
409
|
+
|
|
410
|
+
assertFeatureCollection(value);
|
|
411
|
+
|
|
412
|
+
return new GeoJSONExternalSecondaryInstanceDefinition(this.instanceId, value);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { parseStaticDocumentFromDOMSubtree } from '../../../shared/parseStaticDocumentFromDOMSubtree.ts';
|
|
2
|
+
import type { DOMSecondaryInstanceElement } from '../../../XFormDOM.ts';
|
|
3
|
+
import { SecondaryInstanceDefinition } from '../SecondaryInstanceDefinition.ts';
|
|
4
|
+
import { SecondaryInstanceRootDefinition } from '../SecondaryInstanceRootDefinition.ts';
|
|
5
|
+
import { SecondaryInstanceSource } from './SecondaryInstanceSource.ts';
|
|
6
|
+
|
|
7
|
+
export class InternalSecondaryInstanceSource extends SecondaryInstanceSource<'internal'> {
|
|
8
|
+
constructor(instanceId: string, resourceURL: null, domElement: DOMSecondaryInstanceElement) {
|
|
9
|
+
super('internal', instanceId, resourceURL, domElement);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
parseDefinition(): SecondaryInstanceDefinition {
|
|
13
|
+
return parseStaticDocumentFromDOMSubtree(
|
|
14
|
+
SecondaryInstanceDefinition,
|
|
15
|
+
SecondaryInstanceRootDefinition,
|
|
16
|
+
this.domElement
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { JRResourceURL } from '@getodk/common/jr-resources/JRResourceURL.ts';
|
|
2
|
+
import type { DOMSecondaryInstanceElement } from '../../../XFormDOM.ts';
|
|
3
|
+
import type { SecondaryInstanceDefinition } from '../SecondaryInstanceDefinition.ts';
|
|
4
|
+
|
|
5
|
+
// prettier-ignore
|
|
6
|
+
export type ExternalSecondaryInstanceSourceFormat =
|
|
7
|
+
| 'csv'
|
|
8
|
+
| 'geojson'
|
|
9
|
+
| 'xml';
|
|
10
|
+
|
|
11
|
+
// prettier-ignore
|
|
12
|
+
export type SecondaryInstanceSourceFormat =
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/sort-type-constituents
|
|
14
|
+
| ExternalSecondaryInstanceSourceFormat
|
|
15
|
+
| 'internal'
|
|
16
|
+
| 'blank';
|
|
17
|
+
|
|
18
|
+
export abstract class SecondaryInstanceSource<
|
|
19
|
+
Format extends SecondaryInstanceSourceFormat = SecondaryInstanceSourceFormat,
|
|
20
|
+
> {
|
|
21
|
+
constructor(
|
|
22
|
+
readonly format: Format,
|
|
23
|
+
readonly instanceId: string,
|
|
24
|
+
readonly resourceURL: JRResourceURL | null,
|
|
25
|
+
readonly domElement: DOMSecondaryInstanceElement
|
|
26
|
+
) {}
|
|
27
|
+
|
|
28
|
+
abstract parseDefinition(): SecondaryInstanceDefinition;
|
|
29
|
+
}
|