@techspokes/typescript-wsdl-client 1.1.4 → 1.1.8
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/README.md +81 -35
- package/dist/app/generateApp.d.ts +0 -1
- package/dist/app/generateApp.js +8 -6
- package/dist/app/generateCheckedApp.d.ts +38 -0
- package/dist/app/generateCheckedApp.js +108 -0
- package/dist/checkedPipeline.d.ts +155 -0
- package/dist/checkedPipeline.js +448 -0
- package/dist/checkedPlanning.d.ts +123 -0
- package/dist/checkedPlanning.js +245 -0
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +123 -5
- package/dist/client/checkedDirectRuntime.d.ts +96 -0
- package/dist/client/checkedDirectRuntime.js +43 -0
- package/dist/client/directClientRuntime.d.ts +74 -0
- package/dist/client/directClientRuntime.js +165 -0
- package/dist/client/directClientVersion.d.ts +6 -0
- package/dist/client/directClientVersion.js +6 -0
- package/dist/client/generateClient.d.ts +0 -1
- package/dist/client/generateClient.js +26 -12
- package/dist/client/generateDirectClient.d.ts +32 -0
- package/dist/client/generateDirectClient.js +268 -0
- package/dist/client/generateOperations.d.ts +0 -1
- package/dist/client/generateTypes.d.ts +0 -1
- package/dist/client/generateUtils.d.ts +0 -1
- package/dist/client/generateUtils.js +3 -1
- package/dist/compiler/applicationGroups.d.ts +53 -0
- package/dist/compiler/applicationGroups.js +403 -0
- package/dist/compiler/buildCanonicalGraph.d.ts +6 -0
- package/dist/compiler/buildCanonicalGraph.js +381 -0
- package/dist/compiler/canonicalGraph.d.ts +197 -0
- package/dist/compiler/canonicalGraph.js +37 -0
- package/dist/compiler/catalogErrors.d.ts +17 -0
- package/dist/compiler/catalogErrors.js +86 -0
- package/dist/compiler/catalogProvenance.d.ts +14 -0
- package/dist/compiler/catalogProvenance.js +229 -0
- package/dist/compiler/checkedAssessment.d.ts +90 -0
- package/dist/compiler/checkedAssessment.js +300 -0
- package/dist/compiler/checkedComponentSource.d.ts +16 -0
- package/dist/compiler/checkedComponentSource.js +31 -0
- package/dist/compiler/checkedSourcePreparation.d.ts +72 -0
- package/dist/compiler/checkedSourcePreparation.js +202 -0
- package/dist/compiler/complexTypeContent.d.ts +58 -0
- package/dist/compiler/complexTypeContent.js +558 -0
- package/dist/compiler/componentCorrespondence.d.ts +32 -0
- package/dist/compiler/componentCorrespondence.js +140 -0
- package/dist/compiler/componentRecordProjection.d.ts +109 -0
- package/dist/compiler/componentRecordProjection.js +319 -0
- package/dist/compiler/componentSoapPreparation.d.ts +20 -0
- package/dist/compiler/componentSoapPreparation.js +36 -0
- package/dist/compiler/composeCanonicalGraph.d.ts +68 -0
- package/dist/compiler/composeCanonicalGraph.js +252 -0
- package/dist/compiler/dataOwnership.d.ts +21 -0
- package/dist/compiler/dataOwnership.js +167 -0
- package/dist/compiler/datatypeValues.d.ts +46 -0
- package/dist/compiler/datatypeValues.js +275 -0
- package/dist/compiler/directCodec.d.ts +116 -0
- package/dist/compiler/directCodec.js +377 -0
- package/dist/compiler/directExecutionPolicy.d.ts +9 -0
- package/dist/compiler/directExecutionPolicy.js +17 -0
- package/dist/compiler/directOperation.d.ts +114 -0
- package/dist/compiler/directOperation.js +373 -0
- package/dist/compiler/directSoap.d.ts +66 -0
- package/dist/compiler/directSoap.js +391 -0
- package/dist/compiler/directSoapSource.d.ts +38 -0
- package/dist/compiler/directSoapSource.js +233 -0
- package/dist/compiler/directSourceCapsule.d.ts +169 -0
- package/dist/compiler/directSourceCapsule.js +727 -0
- package/dist/compiler/directStructure.d.ts +128 -0
- package/dist/compiler/directStructure.js +543 -0
- package/dist/compiler/directStructurePlan.d.ts +149 -0
- package/dist/compiler/directStructurePlan.js +623 -0
- package/dist/compiler/directValues.d.ts +128 -0
- package/dist/compiler/directValues.js +1116 -0
- package/dist/compiler/finiteRe01Construction.d.ts +69 -0
- package/dist/compiler/finiteRe01Construction.js +422 -0
- package/dist/compiler/finiteRe01Verification.d.ts +218 -0
- package/dist/compiler/finiteRe01Verification.js +1217 -0
- package/dist/compiler/generateCatalog.d.ts +0 -1
- package/dist/compiler/graphTraversal.d.ts +10 -0
- package/dist/compiler/graphTraversal.js +37 -0
- package/dist/compiler/hypotheticalScopedIdentity.d.ts +22 -0
- package/dist/compiler/hypotheticalScopedIdentity.js +81 -0
- package/dist/compiler/occurrenceAnalysis.d.ts +66 -0
- package/dist/compiler/occurrenceAnalysis.js +316 -0
- package/dist/compiler/originalSourceMembership.d.ts +5 -0
- package/dist/compiler/originalSourceMembership.js +31 -0
- package/dist/compiler/particleAttribution.d.ts +16 -0
- package/dist/compiler/particleAttribution.js +494 -0
- package/dist/compiler/particleDeclarationConsistency.d.ts +23 -0
- package/dist/compiler/particleDeclarationConsistency.js +206 -0
- package/dist/compiler/particleExtension.d.ts +21 -0
- package/dist/compiler/particleExtension.js +123 -0
- package/dist/compiler/particleLocalAssessment.d.ts +19 -0
- package/dist/compiler/particleLocalAssessment.js +92 -0
- package/dist/compiler/particleRestriction.d.ts +23 -0
- package/dist/compiler/particleRestriction.js +494 -0
- package/dist/compiler/particleSemanticView.d.ts +51 -0
- package/dist/compiler/particleSemanticView.js +310 -0
- package/dist/compiler/particleWildcardRelation.d.ts +87 -0
- package/dist/compiler/particleWildcardRelation.js +143 -0
- package/dist/compiler/projectionScalar.d.ts +32 -0
- package/dist/compiler/projectionScalar.js +184 -0
- package/dist/compiler/re01CandidateAssignments.d.ts +95 -0
- package/dist/compiler/re01CandidateAssignments.js +341 -0
- package/dist/compiler/re01CandidateCorrespondence.d.ts +85 -0
- package/dist/compiler/re01CandidateCorrespondence.js +701 -0
- package/dist/compiler/re01TypeProperties.d.ts +70 -0
- package/dist/compiler/re01TypeProperties.js +120 -0
- package/dist/compiler/re01TypePropertyValidation.d.ts +22 -0
- package/dist/compiler/re01TypePropertyValidation.js +161 -0
- package/dist/compiler/resolveCanonicalGraph.d.ts +41 -0
- package/dist/compiler/resolveCanonicalGraph.js +240 -0
- package/dist/compiler/scalarSchemaAssessment.d.ts +424 -0
- package/dist/compiler/scalarSchemaAssessment.js +5198 -0
- package/dist/compiler/schemaAttributeGroupProperties.d.ts +16 -0
- package/dist/compiler/schemaAttributeGroupProperties.js +53 -0
- package/dist/compiler/schemaAttributeProperties.d.ts +9 -0
- package/dist/compiler/schemaAttributeProperties.js +11 -0
- package/dist/compiler/schemaAttributeUses.d.ts +110 -0
- package/dist/compiler/schemaAttributeUses.js +798 -0
- package/dist/compiler/schemaBinaryWordReconstruction.d.ts +9 -0
- package/dist/compiler/schemaBinaryWordReconstruction.js +33 -0
- package/dist/compiler/schemaBuiltinFacets.d.ts +13 -0
- package/dist/compiler/schemaBuiltinFacets.js +51 -0
- package/dist/compiler/schemaCalendarImages.d.ts +7 -0
- package/dist/compiler/schemaCalendarImages.js +204 -0
- package/dist/compiler/schemaCalendarLanguage.d.ts +10 -0
- package/dist/compiler/schemaCalendarLanguage.js +227 -0
- package/dist/compiler/schemaCompiler.d.ts +0 -1
- package/dist/compiler/schemaComponentEquality.d.ts +27 -0
- package/dist/compiler/schemaComponentEquality.js +446 -0
- package/dist/compiler/schemaConstructionAssessment.d.ts +79 -0
- package/dist/compiler/schemaConstructionAssessment.js +745 -0
- package/dist/compiler/schemaDatatypeValues.d.ts +3 -0
- package/dist/compiler/schemaDatatypeValues.js +2 -0
- package/dist/compiler/schemaDecimalLanguage.d.ts +6 -0
- package/dist/compiler/schemaDecimalLanguage.js +102 -0
- package/dist/compiler/schemaDeclarationPrimitives.d.ts +39 -0
- package/dist/compiler/schemaDeclarationPrimitives.js +211 -0
- package/dist/compiler/schemaDocumentSyntax.d.ts +54 -0
- package/dist/compiler/schemaDocumentSyntax.js +294 -0
- package/dist/compiler/schemaDurationLanguage.d.ts +10 -0
- package/dist/compiler/schemaDurationLanguage.js +170 -0
- package/dist/compiler/schemaElementInstance.d.ts +30 -0
- package/dist/compiler/schemaElementInstance.js +45 -0
- package/dist/compiler/schemaElementProperties.d.ts +15 -0
- package/dist/compiler/schemaElementProperties.js +23 -0
- package/dist/compiler/schemaEndpointWordCapacity.d.ts +35 -0
- package/dist/compiler/schemaEndpointWordCapacity.js +39 -0
- package/dist/compiler/schemaExactCalendar.d.ts +72 -0
- package/dist/compiler/schemaExactCalendar.js +264 -0
- package/dist/compiler/schemaFacetAnnotation.d.ts +31 -0
- package/dist/compiler/schemaFacetAnnotation.js +199 -0
- package/dist/compiler/schemaGeneratedScalarShape.d.ts +34 -0
- package/dist/compiler/schemaGeneratedScalarShape.js +178 -0
- package/dist/compiler/schemaIdentityConstraints.d.ts +72 -0
- package/dist/compiler/schemaIdentityConstraints.js +362 -0
- package/dist/compiler/schemaIeeeLanguage.d.ts +42 -0
- package/dist/compiler/schemaIeeeLanguage.js +759 -0
- package/dist/compiler/schemaIntegerImages.d.ts +10 -0
- package/dist/compiler/schemaIntegerImages.js +113 -0
- package/dist/compiler/schemaLexicalPredicates.d.ts +28 -0
- package/dist/compiler/schemaLexicalPredicates.js +63 -0
- package/dist/compiler/schemaNotationProperties.d.ts +31 -0
- package/dist/compiler/schemaNotationProperties.js +84 -0
- package/dist/compiler/schemaNumericImageConditions.d.ts +23 -0
- package/dist/compiler/schemaNumericImageConditions.js +66 -0
- package/dist/compiler/schemaParticleWildcardProperties.d.ts +19 -0
- package/dist/compiler/schemaParticleWildcardProperties.js +43 -0
- package/dist/compiler/schemaPattern.d.ts +1061 -0
- package/dist/compiler/schemaPattern.js +581 -0
- package/dist/compiler/schemaRegularLanguage.d.ts +66 -0
- package/dist/compiler/schemaRegularLanguage.js +1166 -0
- package/dist/compiler/schemaScalarContext.d.ts +85 -0
- package/dist/compiler/schemaScalarContext.js +78 -0
- package/dist/compiler/schemaScalarKernel.d.ts +181 -0
- package/dist/compiler/schemaScalarKernel.js +391 -0
- package/dist/compiler/schemaScalarWitnesses.d.ts +5 -0
- package/dist/compiler/schemaScalarWitnesses.js +118 -0
- package/dist/compiler/schemaSimpleTypeProperties.d.ts +94 -0
- package/dist/compiler/schemaSimpleTypeProperties.js +103 -0
- package/dist/compiler/schemaSourceGrammar.d.ts +26 -0
- package/dist/compiler/schemaSourceGrammar.js +290 -0
- package/dist/compiler/schemaSourceLexical.d.ts +3 -0
- package/dist/compiler/schemaSourceLexical.js +12 -0
- package/dist/compiler/schemaSourceValues.d.ts +50 -0
- package/dist/compiler/schemaSourceValues.js +225 -0
- package/dist/compiler/schemaSourceWildcards.d.ts +27 -0
- package/dist/compiler/schemaSourceWildcards.js +249 -0
- package/dist/compiler/schemaSymbolicSequences.d.ts +15 -0
- package/dist/compiler/schemaSymbolicSequences.js +99 -0
- package/dist/compiler/schemaSymbolicValueSets.d.ts +31 -0
- package/dist/compiler/schemaSymbolicValueSets.js +149 -0
- package/dist/compiler/schemaSyntaxAssessment.d.ts +24 -0
- package/dist/compiler/schemaSyntaxAssessment.js +361 -0
- package/dist/compiler/schemaTemporalAliases.d.ts +5 -0
- package/dist/compiler/schemaTemporalAliases.js +195 -0
- package/dist/compiler/schemaTokenImages.d.ts +8 -0
- package/dist/compiler/schemaTokenImages.js +142 -0
- package/dist/compiler/schemaTypeIdentity.d.ts +38 -0
- package/dist/compiler/schemaTypeIdentity.js +80 -0
- package/dist/compiler/schemaTypeRelations.d.ts +37 -0
- package/dist/compiler/schemaTypeRelations.js +576 -0
- package/dist/compiler/schemaUri.d.ts +12 -0
- package/dist/compiler/schemaUri.js +103 -0
- package/dist/compiler/schemaValueContext.d.ts +25 -0
- package/dist/compiler/schemaValueContext.js +1 -0
- package/dist/compiler/schemaValueImages.d.ts +9 -0
- package/dist/compiler/schemaValueImages.js +142 -0
- package/dist/compiler/schemaValueSequences.d.ts +14 -0
- package/dist/compiler/schemaValueSequences.js +19 -0
- package/dist/compiler/semanticBudget.d.ts +67 -0
- package/dist/compiler/semanticBudget.js +193 -0
- package/dist/compiler/semanticCatalog.d.ts +121 -0
- package/dist/compiler/semanticCatalog.js +160 -0
- package/dist/compiler/semanticContext.d.ts +183 -0
- package/dist/compiler/semanticContext.js +1207 -0
- package/dist/compiler/semanticTypeDependencies.d.ts +7 -0
- package/dist/compiler/semanticTypeDependencies.js +64 -0
- package/dist/compiler/semanticTypeReference.d.ts +23 -0
- package/dist/compiler/semanticTypeReference.js +36 -0
- package/dist/compiler/shapeResolver.d.ts +1 -1
- package/dist/compiler/shapeResolver.js +7 -9
- package/dist/compiler/soapHeaders.d.ts +16 -0
- package/dist/compiler/soapHeaders.js +42 -0
- package/dist/compiler/sourceSchemaBinding.d.ts +25 -0
- package/dist/compiler/sourceSchemaBinding.js +39 -0
- package/dist/compiler/standardSchemaComponents.d.ts +71 -0
- package/dist/compiler/standardSchemaComponents.js +74 -0
- package/dist/compiler/standardSchemaConstruction.d.ts +20 -0
- package/dist/compiler/standardSchemaConstruction.js +34 -0
- package/dist/compiler/structuralCompanions.d.ts +15 -0
- package/dist/compiler/structuralCompanions.js +232 -0
- package/dist/compiler/validateSemanticGraph.d.ts +4 -0
- package/dist/compiler/validateSemanticGraph.js +376 -0
- package/dist/compiler/wildcardAlgebra.d.ts +25 -0
- package/dist/compiler/wildcardAlgebra.js +155 -0
- package/dist/compiler/wsdlPolicyRequirements.d.ts +43 -0
- package/dist/compiler/wsdlPolicyRequirements.js +239 -0
- package/dist/config.d.ts +0 -1
- package/dist/gateway/generateCheckedGateway.d.ts +32 -0
- package/dist/gateway/generateCheckedGateway.js +293 -0
- package/dist/gateway/generateGateway.d.ts +0 -1
- package/dist/gateway/generateGateway.js +2 -2
- package/dist/gateway/generators.d.ts +0 -1
- package/dist/gateway/helpers.d.ts +0 -1
- package/dist/generation/componentShape.d.ts +14 -0
- package/dist/generation/componentShape.js +269 -0
- package/dist/generation/preamble.d.ts +0 -1
- package/dist/generation/sourceLayout.d.ts +13 -0
- package/dist/generation/sourceLayout.js +40 -0
- package/dist/generation/writeGeneratedSource.d.ts +0 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +3 -0
- package/dist/loader/fetch.d.ts +0 -1
- package/dist/loader/orderedSyntax.d.ts +84 -0
- package/dist/loader/orderedSyntax.js +222 -0
- package/dist/loader/resolutionDepth.d.ts +6 -0
- package/dist/loader/resolutionDepth.js +65 -0
- package/dist/loader/schemaInput.d.ts +80 -0
- package/dist/loader/schemaInput.js +249 -0
- package/dist/loader/schemaResources.d.ts +60 -0
- package/dist/loader/schemaResources.js +333 -0
- package/dist/loader/wsdlLoader.d.ts +0 -1
- package/dist/openapi/casing.d.ts +0 -1
- package/dist/openapi/generateOpenAPI.d.ts +0 -1
- package/dist/openapi/generateOpenAPI.js +2 -2
- package/dist/openapi/generatePaths.d.ts +0 -1
- package/dist/openapi/generateSchemas.d.ts +0 -1
- package/dist/openapi/security.d.ts +0 -1
- package/dist/pipeline.d.ts +6 -2
- package/dist/pipeline.js +13 -0
- package/dist/test/generateCheckedTests.d.ts +17 -0
- package/dist/test/generateCheckedTests.js +60 -0
- package/dist/test/generateTests.d.ts +0 -1
- package/dist/test/generateTests.js +2 -2
- package/dist/test/generators.d.ts +0 -1
- package/dist/test/mockData.d.ts +0 -1
- package/dist/test/mockData.js +20 -14
- package/dist/util/attributeWildcards.d.ts +0 -1
- package/dist/util/builder.d.ts +0 -1
- package/dist/util/catalogMeta.d.ts +0 -1
- package/dist/util/checkedCliDiagnostics.d.ts +11 -0
- package/dist/util/checkedCliDiagnostics.js +22 -0
- package/dist/util/cli.d.ts +0 -1
- package/dist/util/errors.d.ts +0 -1
- package/dist/util/imports.d.ts +0 -1
- package/dist/util/runtimeSource.d.ts +0 -1
- package/dist/util/runtimeSource.js +3 -5
- package/dist/util/securityConfig.d.ts +0 -1
- package/dist/util/streamConfig.d.ts +0 -1
- package/dist/util/tools.d.ts +0 -1
- package/dist/util/xmlWhitespace.d.ts +2 -0
- package/dist/util/xmlWhitespace.js +4 -0
- package/dist/xsd/primitives.d.ts +0 -1
- package/docs/agent-skill.md +2 -0
- package/docs/api-reference.md +1 -1
- package/docs/checked-gateway.md +210 -0
- package/docs/checked-generation.md +161 -0
- package/docs/cli-reference.md +43 -1
- package/docs/concepts.md +136 -1
- package/docs/configuration.md +5 -1
- package/docs/corpus.md +33 -0
- package/docs/direct-values.md +311 -0
- package/docs/examples/checked-forecast.wsdl +19 -0
- package/docs/gateway-guide.md +1 -1
- package/docs/generated-code.md +10 -5
- package/docs/mapping-contract.md +114 -0
- package/docs/migration-playbook.md +1 -1
- package/docs/output-anatomy.md +1 -1
- package/docs/start-here.md +8 -2
- package/docs/supported-patterns.md +17 -5
- package/docs/testing.md +117 -31
- package/llms.txt +7 -7
- package/package.json +79 -25
- package/src/generation/preambles/direct-client/typescript.preamble +3 -0
- package/src/runtime/checkedGatewayHost.tpl.txt +157 -0
- package/src/runtime/streamXml.ts +1 -1
- package/dist/app/generateApp.d.ts.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/client/generateClient.d.ts.map +0 -1
- package/dist/client/generateOperations.d.ts.map +0 -1
- package/dist/client/generateTypes.d.ts.map +0 -1
- package/dist/client/generateUtils.d.ts.map +0 -1
- package/dist/compiler/generateCatalog.d.ts.map +0 -1
- package/dist/compiler/schemaCompiler.d.ts.map +0 -1
- package/dist/compiler/shapeResolver.d.ts.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/gateway/generateGateway.d.ts.map +0 -1
- package/dist/gateway/generators.d.ts.map +0 -1
- package/dist/gateway/helpers.d.ts.map +0 -1
- package/dist/generation/preamble.d.ts.map +0 -1
- package/dist/generation/writeGeneratedSource.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/loader/fetch.d.ts.map +0 -1
- package/dist/loader/wsdlLoader.d.ts.map +0 -1
- package/dist/openapi/casing.d.ts.map +0 -1
- package/dist/openapi/generateOpenAPI.d.ts.map +0 -1
- package/dist/openapi/generatePaths.d.ts.map +0 -1
- package/dist/openapi/generateSchemas.d.ts.map +0 -1
- package/dist/openapi/security.d.ts.map +0 -1
- package/dist/pipeline.d.ts.map +0 -1
- package/dist/runtime/jsonArray.d.ts +0 -24
- package/dist/runtime/jsonArray.d.ts.map +0 -1
- package/dist/runtime/jsonArray.js +0 -52
- package/dist/runtime/ndjson.d.ts +0 -24
- package/dist/runtime/ndjson.d.ts.map +0 -1
- package/dist/runtime/ndjson.js +0 -30
- package/dist/runtime/streamXml.d.ts +0 -45
- package/dist/runtime/streamXml.d.ts.map +0 -1
- package/dist/runtime/streamXml.js +0 -212
- package/dist/test/generateTests.d.ts.map +0 -1
- package/dist/test/generators.d.ts.map +0 -1
- package/dist/test/mockData.d.ts.map +0 -1
- package/dist/util/attributeWildcards.d.ts.map +0 -1
- package/dist/util/builder.d.ts.map +0 -1
- package/dist/util/catalogMeta.d.ts.map +0 -1
- package/dist/util/cli.d.ts.map +0 -1
- package/dist/util/errors.d.ts.map +0 -1
- package/dist/util/imports.d.ts.map +0 -1
- package/dist/util/runtimeSource.d.ts.map +0 -1
- package/dist/util/securityConfig.d.ts.map +0 -1
- package/dist/util/streamConfig.d.ts.map +0 -1
- package/dist/util/tools.d.ts.map +0 -1
- package/dist/xsd/primitives.d.ts.map +0 -1
- package/docs/AGENTS.md +0 -47
- package/docs/README.md +0 -56
- package/docs/architecture.md +0 -149
- package/docs/decisions/001-test-generation.md +0 -36
- package/docs/decisions/002-streamable-responses.md +0 -330
- package/docs/file-naming-and-path-organization.md +0 -213
- package/docs/releases/README.md +0 -94
- package/docs/releases/v0.20.0.md +0 -22
- package/docs/releases/v0.21.0.md +0 -30
- package/docs/releases/v0.22.0.md +0 -30
- package/docs/releases/v0.23.0.md +0 -31
- package/docs/releases/v0.24.0.md +0 -38
- package/docs/releases/v0.25.0.md +0 -31
- package/docs/releases/v0.25.2.md +0 -32
- package/docs/releases/v0.26.0.md +0 -32
- package/docs/releases/v0.27.0.md +0 -31
- package/docs/releases/v0.28.0.md +0 -32
- package/docs/releases/v0.29.0.md +0 -32
- package/docs/releases/v0.30.0.md +0 -30
- package/docs/releases/v0.30.1.md +0 -31
- package/docs/releases/v0.30.2.md +0 -30
- package/docs/releases/v0.30.3.md +0 -33
- package/docs/releases/v0.31.0.md +0 -33
- package/docs/releases/v0.32.0.md +0 -33
- package/docs/releases/v0.33.0.md +0 -34
- package/docs/releases/v0.34.0.md +0 -30
- package/docs/releases/v0.35.0.md +0 -33
- package/docs/releases/v0.36.0.md +0 -32
- package/docs/releases/v0.37.0.md +0 -33
- package/docs/releases/v0.38.0.md +0 -35
- package/docs/releases/v0.39.0.md +0 -35
- package/docs/releases/v0.40.0.md +0 -45
- package/docs/releases/v0.40.1.md +0 -34
- package/docs/releases/v1.0.0.md +0 -42
- package/docs/releases/v1.0.1.md +0 -38
- package/docs/releases/v1.0.2.md +0 -51
- package/docs/releases/v1.0.3.md +0 -37
- package/docs/releases/v1.0.4.md +0 -45
- package/docs/releases/v1.0.5.md +0 -41
- package/docs/releases/v1.0.6.md +0 -35
- package/docs/releases/v1.0.7.md +0 -36
- package/docs/releases/v1.1.0.md +0 -42
- package/docs/releases/v1.1.1.md +0 -44
- package/docs/releases/v1.1.2.md +0 -42
- package/docs/releases/v1.1.3.md +0 -36
- package/docs/releases/v1.1.4.md +0 -36
- package/docs/roadmap/README.md +0 -107
- package/docs/roadmap/v1.0-capability-conformance-framework.md +0 -582
- package/docs/roadmap/v1.0-choice-union-mode.md +0 -90
- package/docs/roadmap/v1.0-contract-audit.md +0 -75
- package/docs/roadmap/v1.0-json-array-streaming.md +0 -101
- package/docs/roadmap/v1.0-openapi-fastify-compatibility.md +0 -99
- package/docs/roadmap/v1.0-release-candidate-gates.md +0 -92
- package/docs/roadmap/v1.0-wsdl-coverage-matrix.md +0 -200
- package/docs/roadmap/v1.0-xs-anyattribute-wildcard-bag.md +0 -932
- package/src/runtime/jsonArray.ts +0 -55
- package/src/runtime/ndjson.ts +0 -32
|
@@ -0,0 +1,727 @@
|
|
|
1
|
+
import { directDataOwnership, directLimit, directLoadingLimits } from './directExecutionPolicy.js';
|
|
2
|
+
/** Internal P3.6 data boundary. Reading data never grants source or dispatch authority. */
|
|
3
|
+
import { checkSemanticBudget } from './semanticBudget.js';
|
|
4
|
+
import { DataOwnershipLimitError } from './dataOwnership.js';
|
|
5
|
+
import { createHash } from 'node:crypto';
|
|
6
|
+
import { types } from 'node:util';
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { fileURLToPath } from 'node:url';
|
|
9
|
+
import { canonicalJson, parseCatalogJson, CatalogError } from './catalogErrors.js';
|
|
10
|
+
import { createApplicationBudget } from './semanticBudget.js';
|
|
11
|
+
import { inspectDirectOperation, selectDirectOperationInRequest, selectComponentOperationInRequest } from './directOperation.js';
|
|
12
|
+
import { createDirectValueMapping, createComponentValueMapping, inspectComponentValueMapping, DIRECT_VALUE_VERSION, DIRECT_SCALAR_POLICY } from './directValues.js';
|
|
13
|
+
import { prepareDirectSoapSource, prepareComponentSoapWsdl, DirectSoapSourceError, DIRECT_SOAP_SOURCE_MAX_BYTES } from './directSoapSource.js';
|
|
14
|
+
import { ComponentSoapPreparation } from './componentSoapPreparation.js';
|
|
15
|
+
import { copyOriginalSchemaResource } from '../loader/schemaInput.js';
|
|
16
|
+
import { SchemaResourceLoader, resolveResourceUri } from '../loader/schemaResources.js';
|
|
17
|
+
import { parseOrderedSyntax, syntaxElements, isXmlNCName, SchemaLoadingError } from '../loader/orderedSyntax.js';
|
|
18
|
+
import { createComponentRecordProjection, inspectComponentRecordProjection } from './componentRecordProjection.js';
|
|
19
|
+
import { acquireStandardSchemaLibrary, SCHEMA_ELEMENT_LIBRARY } from './standardSchemaComponents.js';
|
|
20
|
+
import { parseApplicationGroups } from './applicationGroups.js';
|
|
21
|
+
export const DIRECT_CAPSULE_LIMITS = Object.freeze({ maxBytes: 256 * 1024, sourceBytes: DIRECT_SOAP_SOURCE_MAX_BYTES });
|
|
22
|
+
const versions = Object.freeze({ capsuleFormat: 1, model: 'xsd10-faithful-v1', scope: 'direct-soap11-single-utf8-v1',
|
|
23
|
+
mapping: DIRECT_VALUE_VERSION, scalarPolicy: DIRECT_SCALAR_POLICY, runtimePolicy: 'owned-loopback-http-no-extensions-v1' });
|
|
24
|
+
const reconstructed = new WeakMap();
|
|
25
|
+
class Stop extends Error {
|
|
26
|
+
kind;
|
|
27
|
+
rule;
|
|
28
|
+
constructor(kind, rule) {
|
|
29
|
+
super(rule);
|
|
30
|
+
this.kind = kind;
|
|
31
|
+
this.rule = rule;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const reject = (rule) => { throw new Stop('incompatible-artifact', rule); };
|
|
35
|
+
function failure(error, budget) {
|
|
36
|
+
let kind, rule;
|
|
37
|
+
if (budget.exhausted()) {
|
|
38
|
+
kind = 'resource-limit';
|
|
39
|
+
rule = 'request-budget';
|
|
40
|
+
}
|
|
41
|
+
else if (error instanceof DataOwnershipLimitError) {
|
|
42
|
+
kind = 'resource-limit';
|
|
43
|
+
rule = error.message;
|
|
44
|
+
}
|
|
45
|
+
else if (error instanceof Stop) {
|
|
46
|
+
({ kind, rule } = error);
|
|
47
|
+
}
|
|
48
|
+
else if (error instanceof CatalogError) {
|
|
49
|
+
kind = error.category === 'resource-limit' ? 'resource-limit' : 'incompatible-artifact';
|
|
50
|
+
rule = 'capsule-json';
|
|
51
|
+
}
|
|
52
|
+
else if (error instanceof DirectSoapSourceError) {
|
|
53
|
+
kind = error.kind;
|
|
54
|
+
rule = error.message;
|
|
55
|
+
}
|
|
56
|
+
else if (error instanceof SchemaLoadingError) {
|
|
57
|
+
kind = error.category === 'resource-limit' ? 'resource-limit' : 'missing-authority';
|
|
58
|
+
rule = 'authorized-local-source-required';
|
|
59
|
+
}
|
|
60
|
+
else
|
|
61
|
+
throw error;
|
|
62
|
+
return Object.freeze({ kind, rule, repair: 'Regenerate matched checked direct artifacts from explicitly authorized original WSDL using the checked-direct-v1 pipeline.', usage: Object.freeze({ ...budget.usage() }) });
|
|
63
|
+
}
|
|
64
|
+
function check(budget, signal) {
|
|
65
|
+
checkSemanticBudget(budget);
|
|
66
|
+
if (signal?.aborted)
|
|
67
|
+
throw new Stop('cancelled', 'cooperative-cancellation');
|
|
68
|
+
}
|
|
69
|
+
function hash(text) { return createHash('sha256').update(text).digest('hex'); }
|
|
70
|
+
function json(value, budget) {
|
|
71
|
+
directDataOwnership(budget).freeze(value);
|
|
72
|
+
return canonicalJson(value);
|
|
73
|
+
}
|
|
74
|
+
function record(value, fields) {
|
|
75
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
76
|
+
return reject('data-record-required');
|
|
77
|
+
const result = value;
|
|
78
|
+
const keys = Object.keys(result);
|
|
79
|
+
if (keys.length !== fields.length || keys.some(key => !fields.includes(key)))
|
|
80
|
+
return reject('missing-or-unknown-field');
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
function text(value) { if (typeof value !== 'string')
|
|
84
|
+
reject('string-required'); }
|
|
85
|
+
function name(value) {
|
|
86
|
+
const v = record(value, ['namespace', 'local']);
|
|
87
|
+
text(v.namespace);
|
|
88
|
+
text(v.local);
|
|
89
|
+
if (!isXmlNCName(v.local))
|
|
90
|
+
reject('expanded-name-required');
|
|
91
|
+
}
|
|
92
|
+
function ncname(value) { text(value); if (!isXmlNCName(value))
|
|
93
|
+
reject('name-required'); }
|
|
94
|
+
function root(value) {
|
|
95
|
+
const v = record(value, ['element', 'message', 'part', 'type', 'builtin', 'slots']);
|
|
96
|
+
name(v.element);
|
|
97
|
+
name(v.message);
|
|
98
|
+
ncname(v.part);
|
|
99
|
+
name(v.type);
|
|
100
|
+
if (v.builtin !== null)
|
|
101
|
+
name(v.builtin);
|
|
102
|
+
if (!Array.isArray(v.slots))
|
|
103
|
+
reject('slots-required');
|
|
104
|
+
for (const item of v.slots) {
|
|
105
|
+
const slot = record(item, ['element', 'builtin', 'min', 'max']);
|
|
106
|
+
name(slot.element);
|
|
107
|
+
name(slot.builtin);
|
|
108
|
+
if (!['0', '1'].includes(slot.min) || !['1', 'unbounded'].includes(slot.max))
|
|
109
|
+
reject('direct-occurrence-required');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** Bounded bytes only, duplicate checking delegated to the existing catalog reader. No I/O. */
|
|
113
|
+
export function readDirectSourceCapsule(bytes, budget, signal) {
|
|
114
|
+
try {
|
|
115
|
+
return read(bytes, budget, signal);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
return failure(error, budget);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function capsuleJson(bytes, budget, signal) {
|
|
122
|
+
check(budget, signal);
|
|
123
|
+
if (!types.isUint8Array(bytes) || types.isProxy(bytes))
|
|
124
|
+
return reject('byte-input-required');
|
|
125
|
+
const typed = Object.getPrototypeOf(Uint8Array.prototype);
|
|
126
|
+
const length = Object.getOwnPropertyDescriptor(typed, 'byteLength').get.call(bytes);
|
|
127
|
+
const backing = Object.getOwnPropertyDescriptor(typed, 'buffer').get.call(bytes);
|
|
128
|
+
if (types.isSharedArrayBuffer(backing))
|
|
129
|
+
return reject('shared-bytes-unsupported');
|
|
130
|
+
if (length > directLimit(budget, DIRECT_CAPSULE_LIMITS.maxBytes))
|
|
131
|
+
throw new Stop('resource-limit', 'capsule-byte-limit');
|
|
132
|
+
// The actual capsule byte/depth caps bound decoding, hashing and canonicalization.
|
|
133
|
+
const input = new Uint8Array(length);
|
|
134
|
+
Uint8Array.prototype.set.call(input, bytes);
|
|
135
|
+
let decoded;
|
|
136
|
+
try {
|
|
137
|
+
decoded = new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(input);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
return reject('capsule-utf8');
|
|
141
|
+
}
|
|
142
|
+
return parseCatalogJson(decoded, { maxBytes: directLimit(budget, DIRECT_CAPSULE_LIMITS.maxBytes), maxDepth: 16 });
|
|
143
|
+
}
|
|
144
|
+
function read(bytes, budget, signal) {
|
|
145
|
+
const parsed = record(capsuleJson(bytes, budget, signal), ['versions', 'source', 'compatibility', 'fingerprint']);
|
|
146
|
+
const actual = record(parsed.versions, Object.keys(versions));
|
|
147
|
+
for (const key of Object.keys(versions))
|
|
148
|
+
if (actual[key] !== versions[key])
|
|
149
|
+
reject('unsupported-version-mode-or-policy');
|
|
150
|
+
const source = record(parsed.source, ['base64', 'digest']);
|
|
151
|
+
text(source.base64);
|
|
152
|
+
text(source.digest);
|
|
153
|
+
if (source.base64.length > Math.ceil(directLimit(budget, DIRECT_CAPSULE_LIMITS.sourceBytes) / 3) * 4)
|
|
154
|
+
throw new Stop('resource-limit', 'source-byte-limit');
|
|
155
|
+
const sourceBytes = Buffer.from(source.base64, 'base64');
|
|
156
|
+
if (sourceBytes.byteLength > directLimit(budget, DIRECT_CAPSULE_LIMITS.sourceBytes))
|
|
157
|
+
throw new Stop('resource-limit', 'source-byte-limit');
|
|
158
|
+
if (sourceBytes.toString('base64') !== source.base64 || hash(sourceBytes) !== source.digest)
|
|
159
|
+
reject('corrupt-source');
|
|
160
|
+
try {
|
|
161
|
+
new TextDecoder('utf-8', { fatal: true }).decode(sourceBytes);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return reject('source-utf8');
|
|
165
|
+
}
|
|
166
|
+
const c = record(parsed.compatibility, ['selector', 'service', 'port', 'action', 'input', 'output', 'faults']);
|
|
167
|
+
const s = record(c.selector, ['portType', 'binding', 'operation']);
|
|
168
|
+
name(s.portType);
|
|
169
|
+
name(s.binding);
|
|
170
|
+
ncname(s.operation);
|
|
171
|
+
name(c.service);
|
|
172
|
+
ncname(c.port);
|
|
173
|
+
text(c.action);
|
|
174
|
+
root(c.input);
|
|
175
|
+
root(c.output);
|
|
176
|
+
if (!Array.isArray(c.faults))
|
|
177
|
+
reject('faults-required');
|
|
178
|
+
const faults = new Set();
|
|
179
|
+
for (const item of c.faults) {
|
|
180
|
+
const f = record(item, ['name', 'root']);
|
|
181
|
+
ncname(f.name);
|
|
182
|
+
root(f.root);
|
|
183
|
+
if (faults.has(f.name))
|
|
184
|
+
reject('duplicate-fault');
|
|
185
|
+
faults.add(f.name);
|
|
186
|
+
}
|
|
187
|
+
text(parsed.fingerprint);
|
|
188
|
+
if (hash(json({ versions: parsed.versions, compatibility: c }, budget)) !== parsed.fingerprint)
|
|
189
|
+
reject('compatibility-fingerprint');
|
|
190
|
+
check(budget, signal);
|
|
191
|
+
return directDataOwnership(budget).freeze(parsed);
|
|
192
|
+
}
|
|
193
|
+
function descriptor(contract, selection, signal) {
|
|
194
|
+
const { context: { budget }, source } = inspectDirectOperation(contract);
|
|
195
|
+
check(budget, signal);
|
|
196
|
+
if (source.resources.some(r => r.byteLength > directLimit(budget, DIRECT_CAPSULE_LIMITS.sourceBytes)))
|
|
197
|
+
throw new Stop('resource-limit', 'source-byte-limit');
|
|
198
|
+
const owned = directDataOwnership(budget).snapshot(selection, () => check(budget, signal));
|
|
199
|
+
name(owned.service);
|
|
200
|
+
ncname(owned.port);
|
|
201
|
+
record(owned, ['service', 'port']);
|
|
202
|
+
const { original } = prepareDirectSoapSource(contract, owned, () => check(budget, signal));
|
|
203
|
+
if (original.byteLength > directLimit(budget, DIRECT_CAPSULE_LIMITS.sourceBytes))
|
|
204
|
+
throw new Stop('resource-limit', 'source-byte-limit');
|
|
205
|
+
const mappings = [];
|
|
206
|
+
const make = (direction) => {
|
|
207
|
+
const m = createDirectValueMapping(contract, direction, { signal });
|
|
208
|
+
if (m.kind !== 'direct-mapping')
|
|
209
|
+
throw new Stop(m.kind === 'resource-limit' || m.kind === 'cancelled' ? m.kind : 'unsupported', m.rule);
|
|
210
|
+
mappings.push(m);
|
|
211
|
+
// Resolved schema type names and expanded slot identities are independent
|
|
212
|
+
// of retrieval URI, source offsets, lexical prefixes and context IDs.
|
|
213
|
+
const type = m.root.type;
|
|
214
|
+
if (type.kind !== 'builtin' && type.kind !== 'symbol')
|
|
215
|
+
throw new Stop('unsupported', 'named-direct-type-required');
|
|
216
|
+
return { element: m.root.element.name, message: m.root.message, part: m.root.part, type: type.name,
|
|
217
|
+
builtin: m.rootBuiltin ?? null, slots: m.slots.map(s => ({ element: s.element.name, builtin: s.builtin, min: s.particle.occurs.min, max: s.particle.occurs.max })) };
|
|
218
|
+
};
|
|
219
|
+
const input = make({ kind: 'input' }), output = make({ kind: 'output' });
|
|
220
|
+
const faults = contract.faults.map(f => ({ name: f.name, root: make({ kind: 'fault', name: f.name }) }));
|
|
221
|
+
const compatibility = directDataOwnership(budget).freeze({ selector: contract.selector, service: owned.service, port: owned.port, action: contract.binding.action, input, output, faults });
|
|
222
|
+
return { compatibility, original, mappings };
|
|
223
|
+
}
|
|
224
|
+
/** Writer consumes native authority; produced bytes contain no handles or source paths. */
|
|
225
|
+
export function createDirectSourceCapsule(contract, selection, signal) {
|
|
226
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
227
|
+
try {
|
|
228
|
+
const { compatibility, original } = descriptor(contract, selection, signal);
|
|
229
|
+
const capsule = { versions, source: { base64: Buffer.from(original).toString('base64'), digest: hash(original) }, compatibility,
|
|
230
|
+
fingerprint: hash(json({ versions, compatibility }, budget)) };
|
|
231
|
+
const serialized = json(capsule, budget) + '\n';
|
|
232
|
+
if (Buffer.byteLength(serialized) > directLimit(budget, DIRECT_CAPSULE_LIMITS.maxBytes))
|
|
233
|
+
throw new Stop('resource-limit', 'capsule-byte-limit');
|
|
234
|
+
const bytes = Buffer.from(serialized);
|
|
235
|
+
read(bytes, budget, signal);
|
|
236
|
+
check(budget, signal);
|
|
237
|
+
return Object.freeze({ kind: 'direct-capsule', bytes, admitted: false, usage: Object.freeze({ ...budget.usage() }) });
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
return failure(error, budget);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/** No capsule path is used. Caller chooses and authorizes a NEW physical source. */
|
|
244
|
+
export async function reconstructDirectSourceCapsule(bytes, localSource, options) {
|
|
245
|
+
const budget = createApplicationBudget(options.limits);
|
|
246
|
+
return reconstructDirectSourceCapsuleInRequest(bytes, localSource, options, budget);
|
|
247
|
+
}
|
|
248
|
+
/** Internal consumer entry: decoding/emission and reconstruction share one sticky request. */
|
|
249
|
+
export async function reconstructDirectSourceCapsuleInRequest(bytes, localSource, options, budget) {
|
|
250
|
+
try {
|
|
251
|
+
const capsule = read(bytes, budget, options.signal);
|
|
252
|
+
if (new URL(resolveResourceUri(localSource)).protocol !== 'file:')
|
|
253
|
+
throw new Stop('missing-authority', 'new-local-file-required');
|
|
254
|
+
// Pin the caller-authorized actual file, rather than substituting artifact
|
|
255
|
+
// bytes for a modified file. No network origins are inherited or accepted.
|
|
256
|
+
const loader = await SchemaResourceLoader.create({ fileRoots: options.policy.fileRoots }, { ...directLoadingLimits(budget), resources: 1, resourceBytes: directLimit(budget, DIRECT_CAPSULE_LIMITS.sourceBytes), totalBytes: directLimit(budget, DIRECT_CAPSULE_LIMITS.sourceBytes) }, undefined, () => check(budget, options.signal), options.signal);
|
|
257
|
+
const resource = await loader.fetchResource(localSource);
|
|
258
|
+
if (resource.digest !== capsule.source.digest || Buffer.from(resource.bytes).toString('base64') !== capsule.source.base64)
|
|
259
|
+
reject('local-source-changed');
|
|
260
|
+
// Existing syntax owner refuses DTD/entities; graph triggers are rejected
|
|
261
|
+
// before semantic preparation, even if the caller authorized a wider root.
|
|
262
|
+
let syntax;
|
|
263
|
+
try {
|
|
264
|
+
syntax = parseOrderedSyntax(resource.bytes, resource.uri, { maxDepth: directLimit(budget, 256), maxNodes: options.limits?.maxNodes,
|
|
265
|
+
reserveNode: () => budget.reserveNodes(1), chargeWork: () => check(budget, options.signal) });
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
if (error instanceof SchemaLoadingError)
|
|
269
|
+
throw new Stop(error.category === 'resource-limit' ? 'resource-limit' : error.category === 'unsupported-capability' ? 'unsupported' : 'invalid-schema', 'source-syntax');
|
|
270
|
+
throw error;
|
|
271
|
+
}
|
|
272
|
+
const stack = [syntax.root];
|
|
273
|
+
while (stack.length) {
|
|
274
|
+
check(budget, options.signal);
|
|
275
|
+
const node = stack.pop();
|
|
276
|
+
if (['import', 'include', 'redefine'].includes(node.name.local))
|
|
277
|
+
throw new Stop('unsupported', 'single-source-required');
|
|
278
|
+
stack.push(...syntaxElements(node));
|
|
279
|
+
}
|
|
280
|
+
const selected = await selectDirectOperationInRequest(resource.uri, capsule.compatibility.selector, {
|
|
281
|
+
loading: { policy: { fileRoots: options.policy.fileRoots }, offlineResources: new Map([[resource.uri, resource]]) }, limits: options.limits, signal: options.signal,
|
|
282
|
+
}, budget);
|
|
283
|
+
if (selected.kind !== 'selected')
|
|
284
|
+
throw new Stop(selected.kind === 'loading-refused' ? 'missing-authority' : selected.kind === 'selection-refused' ? 'incompatible-artifact' : selected.kind, selected.rule);
|
|
285
|
+
const derived = descriptor(selected.contract, { service: capsule.compatibility.service, port: capsule.compatibility.port }, options.signal);
|
|
286
|
+
if (json(derived.compatibility, budget) !== json(capsule.compatibility, budget))
|
|
287
|
+
reject('source-contract-changed');
|
|
288
|
+
check(budget, options.signal);
|
|
289
|
+
const result = Object.freeze({ kind: 'reconstructed-direct', contract: selected.contract, mappings: Object.freeze(derived.mappings), selection: Object.freeze({ service: capsule.compatibility.service, port: capsule.compatibility.port }), admitted: false, usage: Object.freeze({ ...budget.usage() }) });
|
|
290
|
+
reconstructed.set(result, capsule);
|
|
291
|
+
return result;
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
if (!budget.exhausted() && options.signal?.aborted)
|
|
295
|
+
return failure(new Stop('cancelled', 'cooperative-cancellation'), budget);
|
|
296
|
+
return failure(error, budget);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** #195/#201 handoff: compare expected data against a freshly issued native plan. */
|
|
300
|
+
export function checkDirectSourceCompatibility(expected, contract, selection, signal) {
|
|
301
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
302
|
+
if (!expected || typeof expected !== 'object' || !reconstructed.has(expected))
|
|
303
|
+
throw new TypeError('Freshly reconstructed expected source required');
|
|
304
|
+
try {
|
|
305
|
+
const capsule = reconstructed.get(expected);
|
|
306
|
+
const fresh = descriptor(contract, selection, signal);
|
|
307
|
+
if (json(capsule.compatibility, budget) !== json(fresh.compatibility, budget))
|
|
308
|
+
reject('operation-binding-root-fault-slot-or-datatype-changed');
|
|
309
|
+
check(budget, signal);
|
|
310
|
+
return Object.freeze({ kind: 'compatible-direct', sourceIdentity: capsule.source.digest === hash(fresh.original) ? 'exact-bytes' : 'revised-bytes', admitted: false, usage: Object.freeze({ ...budget.usage() }) });
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
return failure(error, budget);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
const componentVersions = Object.freeze({ ...versions, scope: 'component-soap11-utf8-graph-v1', mapping: 'component-values-v1',
|
|
317
|
+
runtimePolicy: 'explicit-http-verified-https-transport-v1' });
|
|
318
|
+
const scopedComponentVersions = Object.freeze({ ...componentVersions, scope: 'component-soap11-utf8-graph-v2', mapping: 'component-values-and-record-scope-v1' });
|
|
319
|
+
const componentReconstructions = new WeakMap();
|
|
320
|
+
function componentFailure(error, budget) {
|
|
321
|
+
return Object.freeze({ ...failure(error, budget), repair: 'Regenerate matched component artifacts from explicitly authorized original WSDL and dependencies.' });
|
|
322
|
+
}
|
|
323
|
+
// @constraints Retrieval keys are compared only; artifact paths never initiate I/O. Local relative imports can relocate together.
|
|
324
|
+
function componentResourceKey(source, uri) {
|
|
325
|
+
if (uri === source.root.uri)
|
|
326
|
+
return 'root';
|
|
327
|
+
if (new URL(uri).protocol !== 'file:')
|
|
328
|
+
return 'uri:' + uri;
|
|
329
|
+
return 'file:' + path.relative(path.dirname(fileURLToPath(source.root.uri)), fileURLToPath(uri)).replaceAll('\\', '/');
|
|
330
|
+
}
|
|
331
|
+
function componentResources(contract, signal) {
|
|
332
|
+
const { source, context: { budget } } = inspectDirectOperation(contract);
|
|
333
|
+
const resources = source.resources.map(resource => {
|
|
334
|
+
check(budget, signal);
|
|
335
|
+
const bytes = copyOriginalSchemaResource(source, resource.uri, amount => { check(budget, signal); budget.chargeWork(amount); });
|
|
336
|
+
return { key: componentResourceKey(source, resource.uri), base64: Buffer.from(bytes).toString('base64'), digest: resource.digest };
|
|
337
|
+
}).sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
|
|
338
|
+
if (new Set(resources.map(resource => resource.key)).size !== resources.length)
|
|
339
|
+
throw new Stop('unsupported', 'ambiguous-resource-key');
|
|
340
|
+
return resources;
|
|
341
|
+
}
|
|
342
|
+
async function componentDescriptor(contract, selection, signal, responseProjection, preparation, applicationGroups) {
|
|
343
|
+
const { context: { budget }, source } = inspectDirectOperation(contract);
|
|
344
|
+
const tick = () => check(budget, signal);
|
|
345
|
+
tick();
|
|
346
|
+
if (contract.basis !== 'native-component-premises-v1' || contract.correspondence !== 'dated-XSD-2004-components-v1')
|
|
347
|
+
throw new Stop('unsupported', 'component-capsule-version');
|
|
348
|
+
const owned = directDataOwnership(budget).snapshot(selection, tick);
|
|
349
|
+
record(owned, ['service', 'port']);
|
|
350
|
+
name(owned.service);
|
|
351
|
+
ncname(owned.port);
|
|
352
|
+
if (preparation)
|
|
353
|
+
await ComponentSoapPreparation.prototype.prepare.call(preparation, contract, owned, tick);
|
|
354
|
+
else
|
|
355
|
+
await prepareComponentSoapWsdl(contract, owned, tick);
|
|
356
|
+
if (responseProjection)
|
|
357
|
+
inspectComponentRecordProjection(responseProjection, contract);
|
|
358
|
+
const mappings = [];
|
|
359
|
+
const make = (direction) => {
|
|
360
|
+
tick();
|
|
361
|
+
const mapping = direction.kind === 'output' && responseProjection ? responseProjection : createComponentValueMapping(contract, direction, { signal }, applicationGroups);
|
|
362
|
+
if (mapping.kind !== 'component-mapping' && mapping.kind !== 'component-record-projection')
|
|
363
|
+
throw new Stop(mapping.kind === 'resource-limit' || mapping.kind === 'cancelled' ? mapping.kind : 'unsupported', mapping.rule);
|
|
364
|
+
mappings.push(mapping);
|
|
365
|
+
return { element: mapping.root.element.name, message: mapping.root.message, part: mapping.root.part };
|
|
366
|
+
};
|
|
367
|
+
const input = make({ kind: 'input' }), output = make({ kind: 'output' });
|
|
368
|
+
const faults = contract.faults.map(fault => ({ name: fault.name, root: make({ kind: 'fault', name: fault.name }) }));
|
|
369
|
+
const compatibility = { selector: contract.selector, service: owned.service, port: owned.port,
|
|
370
|
+
action: contract.binding.action, input, output, faults };
|
|
371
|
+
let projection = null;
|
|
372
|
+
if (responseProjection) {
|
|
373
|
+
const { companion } = inspectComponentRecordProjection(responseProjection, contract);
|
|
374
|
+
const { context } = inspectDirectOperation(companion);
|
|
375
|
+
projection = { spec: responseProjection.spec, source: { selector: companion.selector, action: companion.binding.action,
|
|
376
|
+
output: { element: companion.output.element.name, message: companion.output.message, part: companion.output.part },
|
|
377
|
+
libraries: context.standardLibraryIds(), resources: componentResources(companion, signal) } };
|
|
378
|
+
}
|
|
379
|
+
const targets = new Set(mappings.flatMap(mapping => mapping.kind === 'component-mapping'
|
|
380
|
+
? (inspectComponentValueMapping(mapping, contract).applicationGroups?.targets ?? []).map(target => target.target) : []));
|
|
381
|
+
const groups = applicationGroups ? parseApplicationGroups(applicationGroups) : undefined;
|
|
382
|
+
const groupPlans = mappings.flatMap(mapping => mapping.kind === 'component-mapping'
|
|
383
|
+
? [inspectComponentValueMapping(mapping, contract).applicationGroups] : []);
|
|
384
|
+
const applicationGroupIdentity = groups ? hash(json({ version: 'application-groups-v1',
|
|
385
|
+
targets: [...new Map(groupPlans.flatMap(plan => plan.targets.map(target => [target.target, target]))).values()].sort((a, b) => a.target.localeCompare(b.target, 'en')),
|
|
386
|
+
records: [...new Map(groupPlans.flatMap(plan => plan.dispositions.map(record => [record.source, record]))).values()].sort((a, b) => a.source.localeCompare(b.source, 'en')) }, budget)) : undefined;
|
|
387
|
+
tick();
|
|
388
|
+
return { compatibility, resources: componentResources(contract, signal), mappings, libraries: inspectDirectOperation(contract).context.standardLibraryIds(), projection,
|
|
389
|
+
...(groups ? { applicationGroups: groups.names === undefined ? {} : { names: groups.names.filter(item => targets.has(item.target)) }, applicationGroupIdentity } : {}) };
|
|
390
|
+
}
|
|
391
|
+
/** Serialize native component provenance as data; no source, mapping or execution authority is serialized.
|
|
392
|
+
* @returns Deterministic original resource bytes and compatibility description, or explicit refusal.
|
|
393
|
+
* @throws TypeError For foreign operation handles. Caller cancellation is returned as a refusal.
|
|
394
|
+
*/
|
|
395
|
+
export async function createComponentSourceCapsule(contract, selection, signal, responseProjection) {
|
|
396
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
397
|
+
try {
|
|
398
|
+
const { compatibility, resources, libraries, projection } = await componentDescriptor(contract, selection, signal, responseProjection);
|
|
399
|
+
const capsule = componentCapsule({ compatibility, resources, libraries, projection }, budget);
|
|
400
|
+
const serialized = json(capsule, budget) + '\n';
|
|
401
|
+
if (Buffer.byteLength(serialized) > directLimit(budget, DIRECT_CAPSULE_LIMITS.maxBytes))
|
|
402
|
+
throw new Stop('resource-limit', 'capsule-byte-limit');
|
|
403
|
+
check(budget, signal);
|
|
404
|
+
return Object.freeze({ kind: 'component-capsule', bytes: Buffer.from(serialized), admitted: false, usage: Object.freeze({ ...budget.usage() }) });
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
if (!budget.exhausted() && signal?.aborted)
|
|
408
|
+
return componentFailure(new Stop('cancelled', 'cooperative-cancellation'), budget);
|
|
409
|
+
return componentFailure(error, budget);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function componentCapsule(derived, budget) {
|
|
413
|
+
const { compatibility, resources, libraries, projection } = derived;
|
|
414
|
+
const extended = libraries.length > 0 || projection !== null;
|
|
415
|
+
const value = { versions: extended ? scopedComponentVersions : componentVersions, resources, compatibility,
|
|
416
|
+
...(extended ? { libraries, projection } : {}), ...(derived.applicationGroups ? { applicationGroups: derived.applicationGroups, applicationGroupIdentity: derived.applicationGroupIdentity } : {}) };
|
|
417
|
+
return { ...value, fingerprint: hash(json(value, budget)) };
|
|
418
|
+
}
|
|
419
|
+
/** Prepare a generator-owned operation once through the same native descriptor used by runtime reconstruction.
|
|
420
|
+
* @param contract Fresh source-owned operation, never a report or copied handle.
|
|
421
|
+
* @param selection Explicit resolved service and port.
|
|
422
|
+
* @param preparation Invocation-owned SOAP metadata reuse.
|
|
423
|
+
* @param signal Caller cancellation.
|
|
424
|
+
* @param responseProjection Optional native companion projection.
|
|
425
|
+
* @returns An authentic reconstruction retaining its exact issued capsule and mappings, or native refusal.
|
|
426
|
+
* @throws TypeError For foreign native operation identities.
|
|
427
|
+
* @constraints Runtime physical-source reconstruction is independent and unchanged.
|
|
428
|
+
*/
|
|
429
|
+
export async function prepareComponentSourceForOperation(contract, selection, preparation, signal, responseProjection, applicationGroups) {
|
|
430
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
431
|
+
try {
|
|
432
|
+
const derived = await componentDescriptor(contract, selection, signal, responseProjection, preparation, applicationGroups);
|
|
433
|
+
const capsule = componentCapsule(derived, budget);
|
|
434
|
+
if (Buffer.byteLength(json(capsule, budget) + '\n') > directLimit(budget, DIRECT_CAPSULE_LIMITS.maxBytes))
|
|
435
|
+
throw new Stop('resource-limit', 'capsule-byte-limit');
|
|
436
|
+
return issueComponentReconstruction(capsule, contract, derived, signal, responseProjection);
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
if (!budget.exhausted() && signal?.aborted)
|
|
440
|
+
return componentFailure(new Stop('cancelled', 'cooperative-cancellation'), budget);
|
|
441
|
+
return componentFailure(error, budget);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/** Copy capsule data retained by an authentic reconstruction without repeating preparation.
|
|
445
|
+
* @param expected Fresh owned reconstruction.
|
|
446
|
+
* @param signal Caller cancellation.
|
|
447
|
+
* @returns Deterministic capsule bytes; the data grants no runtime authority.
|
|
448
|
+
* @throws TypeError For copied or foreign reconstruction identities; cancellation/resource failures propagate.
|
|
449
|
+
*/
|
|
450
|
+
export function componentSourceCapsuleBytes(expected, signal) {
|
|
451
|
+
inspectReconstructedComponentSource(expected);
|
|
452
|
+
const { budget } = inspectDirectOperation(expected.contract).context;
|
|
453
|
+
check(budget, signal);
|
|
454
|
+
return Buffer.from(json(componentReconstructions.get(expected), budget) + '\n');
|
|
455
|
+
}
|
|
456
|
+
function readComponent(bytes, budget, signal) {
|
|
457
|
+
const value = capsuleJson(bytes, budget, signal);
|
|
458
|
+
const extended = !!value && typeof value === 'object' && (Object.hasOwn(value, 'libraries') || Object.hasOwn(value, 'projection'));
|
|
459
|
+
const grouped = !!value && typeof value === 'object' && Object.hasOwn(value, 'applicationGroups');
|
|
460
|
+
const parsed = record(value, [...(extended ? ['versions', 'resources', 'compatibility', 'libraries', 'projection', 'fingerprint']
|
|
461
|
+
: ['versions', 'resources', 'compatibility', 'fingerprint']), ...(grouped ? ['applicationGroups', 'applicationGroupIdentity'] : [])]);
|
|
462
|
+
if (grouped) {
|
|
463
|
+
try {
|
|
464
|
+
parseApplicationGroups(parsed.applicationGroups);
|
|
465
|
+
}
|
|
466
|
+
catch {
|
|
467
|
+
reject('application-group-configuration');
|
|
468
|
+
}
|
|
469
|
+
text(parsed.applicationGroupIdentity);
|
|
470
|
+
if (!/^[a-f0-9]{64}$/.test(parsed.applicationGroupIdentity))
|
|
471
|
+
reject('application-group-identity');
|
|
472
|
+
}
|
|
473
|
+
const expectedVersions = extended ? scopedComponentVersions : componentVersions;
|
|
474
|
+
const actual = record(parsed.versions, Object.keys(expectedVersions));
|
|
475
|
+
for (const key of Object.keys(expectedVersions))
|
|
476
|
+
if (actual[key] !== expectedVersions[key])
|
|
477
|
+
reject('unsupported-version-mode-or-policy');
|
|
478
|
+
validateComponentResources(parsed.resources, budget, signal);
|
|
479
|
+
const root = (value) => { const r = record(value, ['element', 'message', 'part']); name(r.element); name(r.message); ncname(r.part); };
|
|
480
|
+
const selector = (value) => { const s = record(value, ['portType', 'binding', 'operation']); name(s.portType); name(s.binding); ncname(s.operation); };
|
|
481
|
+
if (extended) {
|
|
482
|
+
validateComponentLibraries(parsed.libraries);
|
|
483
|
+
if (parsed.projection !== null) {
|
|
484
|
+
const projection = record(parsed.projection, ['spec', 'source']);
|
|
485
|
+
const spec = record(projection.spec, ['version', 'scope', 'payloadPath', 'recordPath', 'opaqueExclusions']);
|
|
486
|
+
if (spec.version !== 'component-record-scope-v1' || spec.scope !== 'records-with-declared-wrapper-scope')
|
|
487
|
+
reject('unsupported-record-projection');
|
|
488
|
+
const path = (value) => { if (!Array.isArray(value) || !value.length)
|
|
489
|
+
reject('record-projection-path');
|
|
490
|
+
else
|
|
491
|
+
for (const entry of value) {
|
|
492
|
+
check(budget, signal);
|
|
493
|
+
name(entry);
|
|
494
|
+
} };
|
|
495
|
+
path(spec.payloadPath);
|
|
496
|
+
path(spec.recordPath);
|
|
497
|
+
if (!Array.isArray(spec.opaqueExclusions))
|
|
498
|
+
return reject('record-projection-exclusions');
|
|
499
|
+
for (const item of spec.opaqueExclusions) {
|
|
500
|
+
check(budget, signal);
|
|
501
|
+
const exclusion = record(item, ['path', 'reason']);
|
|
502
|
+
path(exclusion.path);
|
|
503
|
+
if (!['standard-schema-metadata', 'wrapper-declaration-universe'].includes(exclusion.reason))
|
|
504
|
+
reject('record-projection-exclusion');
|
|
505
|
+
}
|
|
506
|
+
const source = record(projection.source, ['selector', 'action', 'output', 'libraries', 'resources']);
|
|
507
|
+
selector(source.selector);
|
|
508
|
+
text(source.action);
|
|
509
|
+
root(source.output);
|
|
510
|
+
validateComponentLibraries(source.libraries);
|
|
511
|
+
validateComponentResources(source.resources, budget, signal);
|
|
512
|
+
}
|
|
513
|
+
if (!parsed.libraries.length && parsed.projection === null)
|
|
514
|
+
reject('empty-component-extension');
|
|
515
|
+
}
|
|
516
|
+
const c = record(parsed.compatibility, ['selector', 'service', 'port', 'action', 'input', 'output', 'faults']);
|
|
517
|
+
selector(c.selector);
|
|
518
|
+
name(c.service);
|
|
519
|
+
ncname(c.port);
|
|
520
|
+
text(c.action);
|
|
521
|
+
root(c.input);
|
|
522
|
+
root(c.output);
|
|
523
|
+
if (!Array.isArray(c.faults))
|
|
524
|
+
return reject('faults-required');
|
|
525
|
+
const names = new Set();
|
|
526
|
+
for (const entry of c.faults) {
|
|
527
|
+
check(budget, signal);
|
|
528
|
+
const fault = record(entry, ['name', 'root']);
|
|
529
|
+
ncname(fault.name);
|
|
530
|
+
root(fault.root);
|
|
531
|
+
if (names.has(fault.name))
|
|
532
|
+
reject('duplicate-fault');
|
|
533
|
+
names.add(fault.name);
|
|
534
|
+
}
|
|
535
|
+
text(parsed.fingerprint);
|
|
536
|
+
if (hash(json({ versions: actual, resources: parsed.resources, compatibility: c,
|
|
537
|
+
...(extended ? { libraries: parsed.libraries, projection: parsed.projection } : {}),
|
|
538
|
+
...(grouped ? { applicationGroups: parsed.applicationGroups, applicationGroupIdentity: parsed.applicationGroupIdentity } : {}) }, budget)) !== parsed.fingerprint)
|
|
539
|
+
reject('compatibility-fingerprint');
|
|
540
|
+
check(budget, signal);
|
|
541
|
+
return directDataOwnership(budget).freeze(parsed);
|
|
542
|
+
}
|
|
543
|
+
function validateComponentLibraries(value) {
|
|
544
|
+
if (!Array.isArray(value))
|
|
545
|
+
return reject('component-libraries-required');
|
|
546
|
+
let previous = '';
|
|
547
|
+
for (const id of value) {
|
|
548
|
+
if (typeof id !== 'string' || id !== SCHEMA_ELEMENT_LIBRARY || id <= previous)
|
|
549
|
+
reject('supported-sorted-unique-libraries-required');
|
|
550
|
+
previous = id;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
function validateComponentResources(value, budget, signal) {
|
|
554
|
+
if (!Array.isArray(value) || !value.length)
|
|
555
|
+
return reject('resources-required');
|
|
556
|
+
let previous = '';
|
|
557
|
+
for (const entry of value) {
|
|
558
|
+
check(budget, signal);
|
|
559
|
+
const resource = record(entry, ['key', 'base64', 'digest']);
|
|
560
|
+
text(resource.key);
|
|
561
|
+
text(resource.base64);
|
|
562
|
+
text(resource.digest);
|
|
563
|
+
if (resource.key <= previous)
|
|
564
|
+
reject('sorted-unique-resources-required');
|
|
565
|
+
previous = resource.key;
|
|
566
|
+
const original = Buffer.from(resource.base64, 'base64');
|
|
567
|
+
if (original.toString('base64') !== resource.base64 || hash(original) !== resource.digest)
|
|
568
|
+
reject('corrupt-source');
|
|
569
|
+
}
|
|
570
|
+
if (!value.some(resource => resource.key === 'root'))
|
|
571
|
+
reject('root-resource-required');
|
|
572
|
+
}
|
|
573
|
+
export async function reconstructComponentSourceCapsule(bytes, localSource, options) {
|
|
574
|
+
return reconstructComponentSourceCapsuleInRequest(bytes, localSource, options, createApplicationBudget(options.limits));
|
|
575
|
+
}
|
|
576
|
+
/** Private runtime seam retaining one sticky request for artifact reading, source qualification and exchange. */
|
|
577
|
+
export async function reconstructComponentSourceCapsuleInRequest(bytes, localSource, options, budget) {
|
|
578
|
+
try {
|
|
579
|
+
const capsule = readComponent(bytes, budget, options.signal);
|
|
580
|
+
const allowed = directDataOwnership(budget).snapshot(options.standardLibraries ?? [], () => check(budget, options.signal));
|
|
581
|
+
if (!Array.isArray(allowed) || allowed.some(id => id !== SCHEMA_ELEMENT_LIBRARY) || new Set(allowed).size !== allowed.length)
|
|
582
|
+
throw new Stop('unsupported', 'explicit-standard-library-permissions');
|
|
583
|
+
const sources = directDataOwnership(budget).snapshot(options.recordSources ?? [], () => check(budget, options.signal));
|
|
584
|
+
if (!Array.isArray(sources))
|
|
585
|
+
throw new Stop('unsupported', 'explicit-record-source-permissions');
|
|
586
|
+
let recordSource;
|
|
587
|
+
const sourceKeys = new Set();
|
|
588
|
+
for (const entry of sources) {
|
|
589
|
+
check(budget, options.signal);
|
|
590
|
+
const supplied = record(entry, ['selector', 'source']);
|
|
591
|
+
text(supplied.source);
|
|
592
|
+
const selector = record(supplied.selector, ['portType', 'binding', 'operation']);
|
|
593
|
+
name(selector.portType);
|
|
594
|
+
name(selector.binding);
|
|
595
|
+
ncname(selector.operation);
|
|
596
|
+
const key = json(selector, budget);
|
|
597
|
+
if (sourceKeys.has(key))
|
|
598
|
+
throw new Stop('unsupported', 'duplicate-record-source-permission');
|
|
599
|
+
sourceKeys.add(key);
|
|
600
|
+
if (key === json(capsule.compatibility.selector, budget))
|
|
601
|
+
recordSource = supplied.source;
|
|
602
|
+
}
|
|
603
|
+
if (capsule.projection && !recordSource)
|
|
604
|
+
throw new Stop('missing-authority', 'explicit-companion-source-required');
|
|
605
|
+
const contract = await selectPinnedComponentSource(capsule.resources, capsule.compatibility.selector, capsule.libraries ?? [], localSource, options, budget, allowed);
|
|
606
|
+
let responseProjection;
|
|
607
|
+
if (capsule.projection) {
|
|
608
|
+
const source = capsule.projection.source;
|
|
609
|
+
const companion = await selectPinnedComponentSource(source.resources, source.selector, source.libraries, recordSource, { ...options, loading: { ...options.loading, sourceUri: undefined } }, budget, allowed);
|
|
610
|
+
const projection = createComponentRecordProjection(contract, companion, capsule.projection.spec, { signal: options.signal });
|
|
611
|
+
if (projection.kind !== 'component-record-projection')
|
|
612
|
+
throw new Stop(projection.kind === 'resource-limit' || projection.kind === 'cancelled'
|
|
613
|
+
? projection.kind : 'incompatible-artifact', projection.rule);
|
|
614
|
+
responseProjection = projection;
|
|
615
|
+
}
|
|
616
|
+
return await reconstructComponentAgainst(capsule, contract, { service: capsule.compatibility.service, port: capsule.compatibility.port }, options.signal, responseProjection);
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
if (!budget.exhausted() && options.signal?.aborted)
|
|
620
|
+
return componentFailure(new Stop('cancelled', 'cooperative-cancellation'), budget);
|
|
621
|
+
return componentFailure(error, budget);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
async function selectPinnedComponentSource(resources, selector, libraries, localSource, options, budget, allowed) {
|
|
625
|
+
if (typeof localSource !== 'string' || new URL(resolveResourceUri(localSource)).protocol !== 'file:')
|
|
626
|
+
throw new Stop('missing-authority', 'new-local-file-required');
|
|
627
|
+
if (libraries.some(id => !allowed.includes(id)))
|
|
628
|
+
throw new Stop('missing-authority', 'explicit-standard-component-permission');
|
|
629
|
+
const loader = await SchemaResourceLoader.create({ fileRoots: options.loading.policy.fileRoots }, directLoadingLimits(budget, options.loading.limits), undefined, amount => { check(budget, options.signal); budget.chargeWork(amount); }, options.signal);
|
|
630
|
+
const physical = await loader.fetchResource(localSource), expectedRoot = resources.find(resource => resource.key === 'root');
|
|
631
|
+
if (physical.digest !== expectedRoot.digest || Buffer.from(physical.bytes).toString('base64') !== expectedRoot.base64)
|
|
632
|
+
reject('local-source-changed');
|
|
633
|
+
const offline = options.loading.offlineResources ? new Map(options.loading.offlineResources) : undefined;
|
|
634
|
+
offline?.set(physical.uri, physical);
|
|
635
|
+
const loading = { ...options.loading, ...(offline ? { offlineResources: offline } : {}) };
|
|
636
|
+
const selected = await selectComponentOperationInRequest(loading.sourceUri ?? physical.uri, selector, { loading, signal: options.signal,
|
|
637
|
+
standardLibraries: libraries.map(acquireStandardSchemaLibrary) }, budget);
|
|
638
|
+
if (selected.kind !== 'selected')
|
|
639
|
+
throw new Stop(selected.kind === 'loading-refused' ? 'missing-authority'
|
|
640
|
+
: selected.kind === 'selection-refused' ? 'incompatible-artifact' : selected.kind, selected.rule);
|
|
641
|
+
return selected.contract;
|
|
642
|
+
}
|
|
643
|
+
/** Generator seam: expected bytes are checked against an already fresh, source-owned native operation.
|
|
644
|
+
* @remarks This accepts transient native authority only. Runtime consumers still reconstruct from independently
|
|
645
|
+
* authorized physical files. It permits service-wide generation to reuse one native whole-source qualification.
|
|
646
|
+
*/
|
|
647
|
+
export async function reconstructComponentSourceCapsuleForOperation(bytes, contract, selection, signal, responseProjection) {
|
|
648
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
649
|
+
try {
|
|
650
|
+
return await reconstructComponentAgainst(readComponent(bytes, budget, signal), contract, selection, signal, responseProjection);
|
|
651
|
+
}
|
|
652
|
+
catch (error) {
|
|
653
|
+
if (!budget.exhausted() && signal?.aborted)
|
|
654
|
+
return componentFailure(new Stop('cancelled', 'cooperative-cancellation'), budget);
|
|
655
|
+
return componentFailure(error, budget);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
async function reconstructComponentAgainst(capsule, contract, selection, signal, responseProjection) {
|
|
659
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
660
|
+
let derived;
|
|
661
|
+
try {
|
|
662
|
+
derived = await componentDescriptor(contract, selection, signal, responseProjection, undefined, capsule.applicationGroups);
|
|
663
|
+
}
|
|
664
|
+
catch (error) {
|
|
665
|
+
if (error instanceof TypeError && error.message.startsWith('applicationGroups'))
|
|
666
|
+
return reject('source-application-groups-changed');
|
|
667
|
+
throw error;
|
|
668
|
+
}
|
|
669
|
+
if (json(derived.applicationGroups ?? null, budget) !== json(capsule.applicationGroups ?? null, budget))
|
|
670
|
+
reject('source-application-groups-changed');
|
|
671
|
+
if (derived.applicationGroupIdentity !== capsule.applicationGroupIdentity)
|
|
672
|
+
reject('source-application-groups-changed');
|
|
673
|
+
if (json(derived.resources, budget) !== json(capsule.resources, budget))
|
|
674
|
+
reject('local-source-changed');
|
|
675
|
+
if (json(derived.compatibility, budget) !== json(capsule.compatibility, budget))
|
|
676
|
+
reject('source-contract-changed');
|
|
677
|
+
if (json(derived.libraries, budget) !== json(capsule.libraries ?? [], budget) || json(derived.projection, budget) !== json(capsule.projection ?? null, budget))
|
|
678
|
+
reject('source-projection-changed');
|
|
679
|
+
return issueComponentReconstruction(capsule, contract, derived, signal, responseProjection);
|
|
680
|
+
}
|
|
681
|
+
function issueComponentReconstruction(capsule, contract, derived, signal, responseProjection) {
|
|
682
|
+
const { budget } = inspectDirectOperation(contract).context;
|
|
683
|
+
check(budget, signal);
|
|
684
|
+
const result = Object.freeze({ kind: 'reconstructed-component', contract,
|
|
685
|
+
mappings: Object.freeze(derived.mappings), selection: Object.freeze({ service: derived.compatibility.service, port: derived.compatibility.port }),
|
|
686
|
+
...(responseProjection ? { responseProjection } : {}),
|
|
687
|
+
admitted: false, usage: Object.freeze({ ...budget.usage() }) });
|
|
688
|
+
componentReconstructions.set(result, capsule);
|
|
689
|
+
return result;
|
|
690
|
+
}
|
|
691
|
+
/** Authenticate transient reconstruction identity; saved/copy-shaped reports cannot be consumed by generators. */
|
|
692
|
+
export function inspectReconstructedComponentSource(value) {
|
|
693
|
+
if (!componentReconstructions.has(value))
|
|
694
|
+
throw new TypeError('Freshly reconstructed component source required');
|
|
695
|
+
inspectDirectOperation(value.contract);
|
|
696
|
+
return value;
|
|
697
|
+
}
|
|
698
|
+
/** Group fresh operations for one service without merging source contexts or binding identities.
|
|
699
|
+
* @returns A deterministic operation order over the original native handles.
|
|
700
|
+
* @throws TypeError For foreign handles, duplicate operations, accessors or mixed sources/services/bindings.
|
|
701
|
+
*/
|
|
702
|
+
export function inspectComponentSourceService(values) {
|
|
703
|
+
if (!Array.isArray(values) || types.isProxy(values) || !values.length)
|
|
704
|
+
throw new TypeError('Nonempty native component operations required');
|
|
705
|
+
const keys = Reflect.ownKeys(values);
|
|
706
|
+
if (keys.length !== values.length + 1)
|
|
707
|
+
throw new TypeError('Dense native operation array required');
|
|
708
|
+
const operations = [];
|
|
709
|
+
for (let index = 0; index < values.length; index++) {
|
|
710
|
+
const descriptor = Object.getOwnPropertyDescriptor(values, String(index));
|
|
711
|
+
if (!descriptor || !('value' in descriptor))
|
|
712
|
+
throw new TypeError('Data-only native operation array required');
|
|
713
|
+
operations.push(inspectReconstructedComponentSource(descriptor.value));
|
|
714
|
+
}
|
|
715
|
+
const first = operations[0], { source, context: { budget } } = inspectDirectOperation(first.contract), names = new Set();
|
|
716
|
+
for (const operation of operations) {
|
|
717
|
+
check(budget);
|
|
718
|
+
const inspection = inspectDirectOperation(operation.contract);
|
|
719
|
+
if (inspection.source !== source || inspection.context.budget !== budget
|
|
720
|
+
|| json(operation.selection, budget) !== json(first.selection, budget)
|
|
721
|
+
|| json(operation.contract.selector.binding, budget) !== json(first.contract.selector.binding, budget)
|
|
722
|
+
|| names.has(operation.contract.selector.operation))
|
|
723
|
+
throw new TypeError('One source/service/binding and unique operations required');
|
|
724
|
+
names.add(operation.contract.selector.operation);
|
|
725
|
+
}
|
|
726
|
+
return Object.freeze(operations.sort((a, b) => budget.compareText(a.contract.selector.operation, b.contract.selector.operation)));
|
|
727
|
+
}
|