@researchdatabox/redbox-core 5.0.4 → 5.1.0-beta.12573
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/AttachmentStagingIdentity.d.ts +3 -0
- package/dist/AttachmentStagingIdentity.d.ts.map +1 -0
- package/dist/AttachmentStagingIdentity.js +10 -0
- package/dist/CoreController.d.ts +7 -3
- package/dist/CoreController.d.ts.map +1 -1
- package/dist/CoreController.js +85 -3
- package/dist/DatastreamService.d.ts +5 -1
- package/dist/DatastreamService.d.ts.map +1 -1
- package/dist/HarvestRunService.d.ts +4 -3
- package/dist/HarvestRunService.d.ts.map +1 -1
- package/dist/HarvestRunService.js +1 -1
- package/dist/RecordConcurrencyObservability.d.ts +51 -0
- package/dist/RecordConcurrencyObservability.d.ts.map +1 -0
- package/dist/RecordConcurrencyObservability.js +136 -0
- package/dist/RecordEntityTag.d.ts +31 -0
- package/dist/RecordEntityTag.d.ts.map +1 -0
- package/dist/RecordEntityTag.js +101 -0
- package/dist/RecordFormFingerprint.d.ts +7 -0
- package/dist/RecordFormFingerprint.d.ts.map +1 -0
- package/dist/RecordFormFingerprint.js +106 -0
- package/dist/RecordHttpConcurrency.d.ts +60 -0
- package/dist/RecordHttpConcurrency.d.ts.map +1 -0
- package/dist/RecordHttpConcurrency.js +181 -0
- package/dist/RecordSaveResponse.d.ts +219 -0
- package/dist/RecordSaveResponse.d.ts.map +1 -0
- package/dist/RecordSaveResponse.js +639 -0
- package/dist/RecordStorageConcurrency.d.ts +49 -0
- package/dist/RecordStorageConcurrency.d.ts.map +1 -0
- package/dist/RecordStorageConcurrency.js +103 -0
- package/dist/RecordWriteClassification.d.ts +12 -0
- package/dist/RecordWriteClassification.d.ts.map +1 -0
- package/dist/RecordWriteClassification.js +70 -0
- package/dist/RecordsService.d.ts +109 -13
- package/dist/RecordsService.d.ts.map +1 -1
- package/dist/RecordsService.js +44 -1
- package/dist/SearchService.d.ts +2 -1
- package/dist/SearchService.d.ts.map +1 -1
- package/dist/StorageService.d.ts +49 -9
- package/dist/StorageService.d.ts.map +1 -1
- package/dist/StorageService.js +19 -1
- package/dist/StorageServiceResponse.d.ts +22 -1
- package/dist/StorageServiceResponse.d.ts.map +1 -1
- package/dist/StorageServiceResponse.js +22 -4
- package/dist/action-execution/audit.d.ts +41 -0
- package/dist/action-execution/audit.d.ts.map +1 -0
- package/dist/action-execution/audit.js +122 -0
- package/dist/action-execution/executor.d.ts +24 -0
- package/dist/action-execution/executor.d.ts.map +1 -0
- package/dist/action-execution/executor.js +435 -0
- package/dist/action-execution/failure.d.ts +49 -0
- package/dist/action-execution/failure.d.ts.map +1 -0
- package/dist/action-execution/failure.js +129 -0
- package/dist/action-execution/index.d.ts +7 -0
- package/dist/action-execution/index.d.ts.map +1 -0
- package/dist/action-execution/index.js +23 -0
- package/dist/action-execution/legacy-result.d.ts +21 -0
- package/dist/action-execution/legacy-result.d.ts.map +1 -0
- package/dist/action-execution/legacy-result.js +70 -0
- package/dist/action-execution/policy.d.ts +12 -0
- package/dist/action-execution/policy.d.ts.map +1 -0
- package/dist/action-execution/policy.js +138 -0
- package/dist/action-execution/types.d.ts +121 -0
- package/dist/action-execution/types.d.ts.map +1 -0
- package/dist/action-execution/types.js +22 -0
- package/dist/api-routes/groups/branding.d.ts +8 -0
- package/dist/api-routes/groups/branding.d.ts.map +1 -1
- package/dist/api-routes/groups/branding.js +86 -11
- package/dist/api-routes/groups/dashboard-config.d.ts +12 -9
- package/dist/api-routes/groups/dashboard-config.d.ts.map +1 -1
- package/dist/api-routes/groups/dashboard-config.js +136 -73
- package/dist/api-routes/groups/forms.d.ts.map +1 -1
- package/dist/api-routes/groups/forms.js +10 -2
- package/dist/api-routes/groups/record-schemas.d.ts +5 -0
- package/dist/api-routes/groups/record-schemas.d.ts.map +1 -0
- package/dist/api-routes/groups/record-schemas.js +181 -0
- package/dist/api-routes/groups/records.d.ts +1 -0
- package/dist/api-routes/groups/records.d.ts.map +1 -1
- package/dist/api-routes/groups/records.js +141 -26
- package/dist/api-routes/index.d.ts +3 -0
- package/dist/api-routes/index.d.ts.map +1 -1
- package/dist/api-routes/index.js +4 -1
- package/dist/api-routes/openapi.d.ts.map +1 -1
- package/dist/api-routes/openapi.js +7 -5
- package/dist/api-routes/record-schema-openapi.d.ts +26 -0
- package/dist/api-routes/record-schema-openapi.d.ts.map +1 -0
- package/dist/api-routes/record-schema-openapi.js +38 -0
- package/dist/api-routes/record-schema-response.d.ts +40 -0
- package/dist/api-routes/record-schema-response.d.ts.map +1 -0
- package/dist/api-routes/record-schema-response.js +89 -0
- package/dist/api-routes/request-extraction.d.ts.map +1 -1
- package/dist/api-routes/request-extraction.js +10 -8
- package/dist/api-routes/route-factory.d.ts.map +1 -1
- package/dist/api-routes/route-factory.js +2 -1
- package/dist/api-routes/route-registry.d.ts.map +1 -1
- package/dist/api-routes/route-registry.js +3 -1
- package/dist/api-routes/schemas/common.d.ts +36 -0
- package/dist/api-routes/schemas/common.d.ts.map +1 -1
- package/dist/api-routes/schemas/common.js +95 -5
- package/dist/api-routes/schemas/responses.d.ts +1424 -1
- package/dist/api-routes/schemas/responses.d.ts.map +1 -1
- package/dist/api-routes/schemas/responses.js +382 -60
- package/dist/api-routes/types.d.ts +1 -0
- package/dist/api-routes/types.d.ts.map +1 -1
- package/dist/api-routes/validation.d.ts +5 -1
- package/dist/api-routes/validation.d.ts.map +1 -1
- package/dist/api-routes/validation.js +14 -15
- package/dist/bootstrap.d.ts +3 -1
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +58 -41
- package/dist/config/agendaQueue.config.d.ts +3 -0
- package/dist/config/agendaQueue.config.d.ts.map +1 -1
- package/dist/config/agendaQueue.config.js +29 -2
- package/dist/config/branding.config.d.ts +13 -0
- package/dist/config/branding.config.d.ts.map +1 -1
- package/dist/config/branding.config.js +34 -2
- package/dist/config/brandingConfigurationDefaults.config.d.ts +4 -0
- package/dist/config/brandingConfigurationDefaults.config.d.ts.map +1 -1
- package/dist/config/brandingConfigurationDefaults.config.js +42 -3
- package/dist/config/index.d.ts +12 -4
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +7 -4
- package/dist/config/policies.config.d.ts.map +1 -1
- package/dist/config/policies.config.js +37 -23
- package/dist/config/raid.config.d.ts +7 -4
- package/dist/config/raid.config.d.ts.map +1 -1
- package/dist/config/raid.config.js +21 -35
- package/dist/config/record.config.d.ts +3 -0
- package/dist/config/record.config.d.ts.map +1 -1
- package/dist/config/record.config.js +37 -35
- package/dist/config/recordSchema.config.d.ts +68 -0
- package/dist/config/recordSchema.config.d.ts.map +1 -0
- package/dist/config/recordSchema.config.js +173 -0
- package/dist/config/recordValidation.config.d.ts +19 -0
- package/dist/config/recordValidation.config.d.ts.map +1 -0
- package/dist/config/recordValidation.config.js +10 -0
- package/dist/config/recordtype.config.d.ts +32 -9
- package/dist/config/recordtype.config.d.ts.map +1 -1
- package/dist/config/recordtype.config.js +4 -7
- package/dist/config/routes.config.d.ts.map +1 -1
- package/dist/config/routes.config.js +135 -53
- package/dist/config/workflow.config.d.ts +6 -0
- package/dist/config/workflow.config.d.ts.map +1 -1
- package/dist/config/workflow.config.js +1 -1
- package/dist/configmodels/AdminSidebarConfig.d.ts.map +1 -1
- package/dist/configmodels/AdminSidebarConfig.js +4 -2
- package/dist/configmodels/ConfigModels.d.ts +1 -1
- package/dist/configmodels/ConfigModels.d.ts.map +1 -1
- package/dist/configmodels/ConfigModels.js +26 -9
- package/dist/configmodels/DashboardFieldCatalogue.d.ts +67 -0
- package/dist/configmodels/DashboardFieldCatalogue.d.ts.map +1 -0
- package/dist/configmodels/DashboardFieldCatalogue.js +174 -0
- package/dist/configmodels/DashboardSettings.d.ts +191 -0
- package/dist/configmodels/DashboardSettings.d.ts.map +1 -0
- package/dist/configmodels/DashboardSettings.js +705 -0
- package/dist/configmodels/FigsharePublishing.d.ts +1 -1
- package/dist/configmodels/OniPublishing.d.ts +205 -0
- package/dist/configmodels/OniPublishing.d.ts.map +1 -0
- package/dist/configmodels/OniPublishing.js +335 -0
- package/dist/configmodels/RaidPublishing.d.ts +97 -0
- package/dist/configmodels/RaidPublishing.d.ts.map +1 -0
- package/dist/configmodels/RaidPublishing.js +35 -0
- package/dist/configmodels/WebAnalytics.d.ts +55 -0
- package/dist/configmodels/WebAnalytics.d.ts.map +1 -0
- package/dist/configmodels/WebAnalytics.js +61 -0
- package/dist/controllers/AppConfigController.d.ts.map +1 -1
- package/dist/controllers/AppConfigController.js +4 -1
- package/dist/controllers/BrandingAppController.d.ts +29 -7
- package/dist/controllers/BrandingAppController.d.ts.map +1 -1
- package/dist/controllers/BrandingAppController.js +265 -69
- package/dist/controllers/BrandingController.d.ts +24 -1
- package/dist/controllers/BrandingController.d.ts.map +1 -1
- package/dist/controllers/BrandingController.js +173 -43
- package/dist/controllers/BrandingControllerSupport.d.ts +20 -0
- package/dist/controllers/BrandingControllerSupport.d.ts.map +1 -0
- package/dist/controllers/BrandingControllerSupport.js +80 -0
- package/dist/controllers/DashboardConfigController.d.ts +6 -2
- package/dist/controllers/DashboardConfigController.d.ts.map +1 -1
- package/dist/controllers/DashboardConfigController.js +18 -4
- package/dist/controllers/DynamicAssetController.d.ts +7 -5
- package/dist/controllers/DynamicAssetController.d.ts.map +1 -1
- package/dist/controllers/DynamicAssetController.js +21 -12
- package/dist/controllers/RecordController.d.ts +45 -4
- package/dist/controllers/RecordController.d.ts.map +1 -1
- package/dist/controllers/RecordController.js +778 -345
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js +4 -1
- package/dist/controllers/webservice/AdminController.d.ts.map +1 -1
- package/dist/controllers/webservice/AdminController.js +4 -3
- package/dist/controllers/webservice/BrandingController.d.ts +26 -1
- package/dist/controllers/webservice/BrandingController.d.ts.map +1 -1
- package/dist/controllers/webservice/BrandingController.js +292 -116
- package/dist/controllers/webservice/DashboardConfigController.d.ts +25 -17
- package/dist/controllers/webservice/DashboardConfigController.d.ts.map +1 -1
- package/dist/controllers/webservice/DashboardConfigController.js +90 -205
- package/dist/controllers/webservice/FormManagementController.d.ts.map +1 -1
- package/dist/controllers/webservice/FormManagementController.js +37 -3
- package/dist/controllers/webservice/RecordController.d.ts +15 -1
- package/dist/controllers/webservice/RecordController.d.ts.map +1 -1
- package/dist/controllers/webservice/RecordController.js +647 -267
- package/dist/controllers/webservice/RecordSchemaController.d.ts +32 -0
- package/dist/controllers/webservice/RecordSchemaController.d.ts.map +1 -0
- package/dist/controllers/webservice/RecordSchemaController.js +356 -0
- package/dist/controllers/webservice/RecordTypeController.d.ts +6 -1
- package/dist/controllers/webservice/RecordTypeController.d.ts.map +1 -1
- package/dist/controllers/webservice/RecordTypeController.js +21 -3
- package/dist/controllers/webservice/SearchController.d.ts.map +1 -1
- package/dist/controllers/webservice/SearchController.js +7 -3
- package/dist/hooks/defineRedboxHook.d.ts +3 -0
- package/dist/hooks/defineRedboxHook.d.ts.map +1 -1
- package/dist/hooks/defineRedboxHook.js +4 -1
- package/dist/index.d.ts +50 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +90 -2
- package/dist/loader/bootstrapShimRuntime.d.ts +1 -1
- package/dist/loader/bootstrapShimRuntime.d.ts.map +1 -1
- package/dist/loader/bootstrapShimRuntime.js +20 -12
- package/dist/loader/index.d.ts +9 -0
- package/dist/loader/index.d.ts.map +1 -1
- package/dist/loader/index.js +93 -4
- package/dist/model/BrandingTypeface.d.ts +70 -0
- package/dist/model/BrandingTypeface.d.ts.map +1 -0
- package/dist/model/BrandingTypeface.js +116 -0
- package/dist/model/BuildResponse.d.ts +25 -11
- package/dist/model/BuildResponse.d.ts.map +1 -1
- package/dist/model/BuildResponse.js +4 -3
- package/dist/model/DashboardTypeResponseModel.d.ts +6 -0
- package/dist/model/DashboardTypeResponseModel.d.ts.map +1 -1
- package/dist/model/DashboardTypeResponseModel.js +7 -1
- package/dist/model/DashboardViewResponseModel.d.ts +5 -1
- package/dist/model/DashboardViewResponseModel.d.ts.map +1 -1
- package/dist/model/DashboardViewResponseModel.js +6 -3
- package/dist/model/RBValidationError.d.ts +17 -0
- package/dist/model/RBValidationError.d.ts.map +1 -1
- package/dist/model/RBValidationError.js +37 -1
- package/dist/model/RecordTypeResponseModel.d.ts +12 -4
- package/dist/model/RecordTypeResponseModel.d.ts.map +1 -1
- package/dist/model/RecordTypeResponseModel.js +11 -2
- package/dist/model/index.d.ts +5 -1
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/index.js +5 -2
- package/dist/model/record-contract.d.ts +42 -0
- package/dist/model/record-contract.d.ts.map +1 -0
- package/dist/model/record-contract.js +3 -0
- package/dist/model/storage/BrandingModel.d.ts +7 -0
- package/dist/model/storage/BrandingModel.d.ts.map +1 -1
- package/dist/model/storage/BrandingModel.js +7 -1
- package/dist/model/storage/DeletedRecordModel.d.ts +35 -0
- package/dist/model/storage/DeletedRecordModel.d.ts.map +1 -1
- package/dist/model/storage/DeletedRecordModel.js +62 -1
- package/dist/model/storage/IntegrationAuditModel.d.ts +16 -2
- package/dist/model/storage/IntegrationAuditModel.d.ts.map +1 -1
- package/dist/model/storage/IntegrationAuditModel.js +15 -1
- package/dist/model/storage/RecordAuditModel.d.ts +11 -1
- package/dist/model/storage/RecordAuditModel.d.ts.map +1 -1
- package/dist/model/storage/RecordAuditModel.js +8 -2
- package/dist/model/storage/RecordModel.d.ts +8 -2
- package/dist/model/storage/RecordModel.d.ts.map +1 -1
- package/dist/model/storage/RecordTypeModel.d.ts +6 -0
- package/dist/model/storage/RecordTypeModel.d.ts.map +1 -1
- package/dist/model/storage/RecordTypeModel.js +4 -1
- package/dist/model/storage/index.d.ts +12 -10
- package/dist/model/storage/index.d.ts.map +1 -1
- package/dist/model/storage/index.js +24 -2
- package/dist/model/storage/record-schema.d.ts +115 -0
- package/dist/model/storage/record-schema.d.ts.map +1 -0
- package/dist/model/storage/record-schema.js +3 -0
- package/dist/policies/checkAuth.d.ts +2 -6
- package/dist/policies/checkAuth.d.ts.map +1 -1
- package/dist/policies/checkAuth.js +32 -9
- package/dist/policies/contentSecurityPolicy.d.ts.map +1 -1
- package/dist/policies/contentSecurityPolicy.js +85 -2
- package/dist/policies/index.d.ts +3 -2
- package/dist/policies/index.d.ts.map +1 -1
- package/dist/policies/index.js +4 -2
- package/dist/policies/validateApiContractRequest.d.ts.map +1 -1
- package/dist/policies/validateApiContractRequest.js +49 -11
- package/dist/record-contract/ajv-error-mapper.d.ts +34 -0
- package/dist/record-contract/ajv-error-mapper.d.ts.map +1 -0
- package/dist/record-contract/ajv-error-mapper.js +153 -0
- package/dist/record-contract/canonical-json.d.ts +20 -0
- package/dist/record-contract/canonical-json.d.ts.map +1 -0
- package/dist/record-contract/canonical-json.js +126 -0
- package/dist/record-contract/codes.d.ts +36 -0
- package/dist/record-contract/codes.d.ts.map +1 -0
- package/dist/record-contract/codes.js +38 -0
- package/dist/record-contract/contributor-registry.d.ts +76 -0
- package/dist/record-contract/contributor-registry.d.ts.map +1 -0
- package/dist/record-contract/contributor-registry.js +126 -0
- package/dist/record-contract/core-contributors.d.ts +44 -0
- package/dist/record-contract/core-contributors.d.ts.map +1 -0
- package/dist/record-contract/core-contributors.js +395 -0
- package/dist/record-contract/deep-freeze.d.ts +3 -0
- package/dist/record-contract/deep-freeze.d.ts.map +1 -0
- package/dist/record-contract/deep-freeze.js +23 -0
- package/dist/record-contract/index.d.ts +13 -0
- package/dist/record-contract/index.d.ts.map +1 -0
- package/dist/record-contract/index.js +29 -0
- package/dist/record-contract/json-pointer.d.ts +20 -0
- package/dist/record-contract/json-pointer.d.ts.map +1 -0
- package/dist/record-contract/json-pointer.js +70 -0
- package/dist/record-contract/json-schema-renderer.d.ts +51 -0
- package/dist/record-contract/json-schema-renderer.d.ts.map +1 -0
- package/dist/record-contract/json-schema-renderer.js +450 -0
- package/dist/record-contract/record-contract-compiler.d.ts +42 -0
- package/dist/record-contract/record-contract-compiler.d.ts.map +1 -0
- package/dist/record-contract/record-contract-compiler.js +775 -0
- package/dist/record-contract/record-contract-context.d.ts +91 -0
- package/dist/record-contract/record-contract-context.d.ts.map +1 -0
- package/dist/record-contract/record-contract-context.js +39 -0
- package/dist/record-contract/record-json-schema-artifact.d.ts +74 -0
- package/dist/record-contract/record-json-schema-artifact.d.ts.map +1 -0
- package/dist/record-contract/record-json-schema-artifact.js +309 -0
- package/dist/record-contract/record-json-schema-etag.d.ts +15 -0
- package/dist/record-contract/record-json-schema-etag.d.ts.map +1 -0
- package/dist/record-contract/record-json-schema-etag.js +41 -0
- package/dist/record-contract/types.d.ts +151 -0
- package/dist/record-contract/types.d.ts.map +1 -0
- package/dist/record-contract/types.js +6 -0
- package/dist/services/AppConfigService.d.ts +6 -0
- package/dist/services/AppConfigService.d.ts.map +1 -1
- package/dist/services/AppConfigService.js +23 -1
- package/dist/services/AttachmentMetadataService.d.ts +58 -0
- package/dist/services/AttachmentMetadataService.d.ts.map +1 -1
- package/dist/services/AttachmentMetadataService.js +643 -8
- package/dist/services/BrandingLogoService.d.ts +6 -1
- package/dist/services/BrandingLogoService.d.ts.map +1 -1
- package/dist/services/BrandingLogoService.js +77 -9
- package/dist/services/BrandingService.d.ts +171 -9
- package/dist/services/BrandingService.d.ts.map +1 -1
- package/dist/services/BrandingService.js +572 -68
- package/dist/services/BrandingThemeCssService.d.ts +17 -1
- package/dist/services/BrandingThemeCssService.d.ts.map +1 -1
- package/dist/services/BrandingThemeCssService.js +71 -9
- package/dist/services/BrandingTypefaceService.d.ts +74 -0
- package/dist/services/BrandingTypefaceService.d.ts.map +1 -0
- package/dist/services/BrandingTypefaceService.js +359 -0
- package/dist/services/BrandingWoff2Inspector.d.ts +17 -0
- package/dist/services/BrandingWoff2Inspector.d.ts.map +1 -0
- package/dist/services/BrandingWoff2Inspector.js +402 -0
- package/dist/services/DashboardConfigService.d.ts +214 -54
- package/dist/services/DashboardConfigService.d.ts.map +1 -1
- package/dist/services/DashboardConfigService.js +829 -261
- package/dist/services/DashboardLegacyConversion.d.ts +82 -0
- package/dist/services/DashboardLegacyConversion.d.ts.map +1 -0
- package/dist/services/DashboardLegacyConversion.js +427 -0
- package/dist/services/DashboardTypesService.d.ts +15 -4
- package/dist/services/DashboardTypesService.d.ts.map +1 -1
- package/dist/services/DashboardTypesService.js +72 -139
- package/dist/services/DoiService.d.ts +1 -1
- package/dist/services/DoiService.d.ts.map +1 -1
- package/dist/services/DoiService.js +71 -45
- package/dist/services/FigshareService.d.ts.map +1 -1
- package/dist/services/FigshareService.js +8 -7
- package/dist/services/FormRecordConsistencyService.d.ts +8 -23
- package/dist/services/FormRecordConsistencyService.d.ts.map +1 -1
- package/dist/services/FormRecordConsistencyService.js +54 -70
- package/dist/services/FormsService.d.ts +91 -2
- package/dist/services/FormsService.d.ts.map +1 -1
- package/dist/services/FormsService.js +324 -64
- package/dist/services/HarvestRunService.d.ts +6 -3
- package/dist/services/HarvestRunService.d.ts.map +1 -1
- package/dist/services/HarvestRunService.js +161 -97
- package/dist/services/I18nEntriesService.d.ts +11 -11
- package/dist/services/I18nEntriesService.d.ts.map +1 -1
- package/dist/services/I18nEntriesService.js +71 -48
- package/dist/services/OniService.d.ts +19 -62
- package/dist/services/OniService.d.ts.map +1 -1
- package/dist/services/OniService.js +223 -691
- package/dist/services/RDMPService.d.ts +1 -1
- package/dist/services/RDMPService.d.ts.map +1 -1
- package/dist/services/RDMPService.js +5 -5
- package/dist/services/RaidService.d.ts +19 -61
- package/dist/services/RaidService.d.ts.map +1 -1
- package/dist/services/RaidService.js +191 -530
- package/dist/services/RecordSchemaService.d.ts +440 -0
- package/dist/services/RecordSchemaService.d.ts.map +1 -0
- package/dist/services/RecordSchemaService.js +3061 -0
- package/dist/services/RecordTypesService.d.ts +29 -0
- package/dist/services/RecordTypesService.d.ts.map +1 -1
- package/dist/services/RecordTypesService.js +106 -11
- package/dist/services/RecordValidationService.d.ts +340 -0
- package/dist/services/RecordValidationService.d.ts.map +1 -0
- package/dist/services/RecordValidationService.js +1898 -0
- package/dist/services/RecordsService.d.ts +317 -26
- package/dist/services/RecordsService.d.ts.map +1 -1
- package/dist/services/RecordsService.js +5145 -765
- package/dist/services/SolrSearchService.d.ts +1 -1
- package/dist/services/SolrSearchService.d.ts.map +1 -1
- package/dist/services/SolrSearchService.js +42 -12
- package/dist/services/StandardDatastreamService.d.ts +4 -0
- package/dist/services/StandardDatastreamService.d.ts.map +1 -1
- package/dist/services/StandardDatastreamService.js +106 -44
- package/dist/services/TriggerService.d.ts.map +1 -1
- package/dist/services/TriggerService.js +54 -30
- package/dist/services/UsersService.d.ts +2 -1
- package/dist/services/UsersService.d.ts.map +1 -1
- package/dist/services/UsersService.js +364 -283
- package/dist/services/VocabularyService.d.ts +2 -0
- package/dist/services/VocabularyService.d.ts.map +1 -1
- package/dist/services/VocabularyService.js +61 -2
- package/dist/services/WorkflowStepsService.d.ts +11 -0
- package/dist/services/WorkflowStepsService.d.ts.map +1 -1
- package/dist/services/WorkflowStepsService.js +32 -3
- package/dist/services/WorkspaceService.d.ts +2 -2
- package/dist/services/WorkspaceService.d.ts.map +1 -1
- package/dist/services/WorkspaceService.js +5 -5
- package/dist/services/doi-v2/bindings.d.ts.map +1 -1
- package/dist/services/doi-v2/bindings.js +3 -20
- package/dist/services/doi-v2/config.d.ts +1 -0
- package/dist/services/doi-v2/config.d.ts.map +1 -1
- package/dist/services/doi-v2/config.js +13 -5
- package/dist/services/doi-v2/runtime.d.ts.map +1 -1
- package/dist/services/doi-v2/runtime.js +14 -54
- package/dist/services/figshare-v2/bindings.d.ts.map +1 -1
- package/dist/services/figshare-v2/bindings.js +3 -20
- package/dist/services/figshare-v2/runtime.d.ts.map +1 -1
- package/dist/services/figshare-v2/runtime.js +11 -58
- package/dist/services/figshare-v2/worker.d.ts.map +1 -1
- package/dist/services/figshare-v2/worker.js +254 -74
- package/dist/services/form-record-access-user.d.ts +3 -0
- package/dist/services/form-record-access-user.d.ts.map +1 -0
- package/dist/services/form-record-access-user.js +23 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +45 -3
- package/dist/services/integration-v2/bindings.d.ts +3 -0
- package/dist/services/integration-v2/bindings.d.ts.map +1 -0
- package/dist/services/integration-v2/bindings.js +91 -0
- package/dist/services/integration-v2/runtime.d.ts +3 -0
- package/dist/services/integration-v2/runtime.d.ts.map +1 -0
- package/dist/services/integration-v2/runtime.js +50 -0
- package/dist/services/internal-record-schema-authorization.d.ts +8 -0
- package/dist/services/internal-record-schema-authorization.d.ts.map +1 -0
- package/dist/services/internal-record-schema-authorization.js +16 -0
- package/dist/services/oni-v2/audit.d.ts +19 -0
- package/dist/services/oni-v2/audit.d.ts.map +1 -0
- package/dist/services/oni-v2/audit.js +50 -0
- package/dist/services/oni-v2/bindings.d.ts +7 -0
- package/dist/services/oni-v2/bindings.d.ts.map +1 -0
- package/dist/services/oni-v2/bindings.js +31 -0
- package/dist/services/oni-v2/config.d.ts +12 -0
- package/dist/services/oni-v2/config.d.ts.map +1 -0
- package/dist/services/oni-v2/config.js +134 -0
- package/dist/services/oni-v2/context.d.ts +3 -0
- package/dist/services/oni-v2/context.d.ts.map +1 -0
- package/dist/services/oni-v2/context.js +17 -0
- package/dist/services/oni-v2/crate.d.ts +17 -0
- package/dist/services/oni-v2/crate.d.ts.map +1 -0
- package/dist/services/oni-v2/crate.js +504 -0
- package/dist/services/oni-v2/flydriveOcflStore.d.ts +69 -0
- package/dist/services/oni-v2/flydriveOcflStore.d.ts.map +1 -0
- package/dist/services/oni-v2/flydriveOcflStore.js +325 -0
- package/dist/services/oni-v2/ingestion.d.ts +37 -0
- package/dist/services/oni-v2/ingestion.d.ts.map +1 -0
- package/dist/services/oni-v2/ingestion.js +91 -0
- package/dist/services/oni-v2/mapping.d.ts +17 -0
- package/dist/services/oni-v2/mapping.d.ts.map +1 -0
- package/dist/services/oni-v2/mapping.js +137 -0
- package/dist/services/oni-v2/repository.d.ts +9 -0
- package/dist/services/oni-v2/repository.d.ts.map +1 -0
- package/dist/services/oni-v2/repository.js +180 -0
- package/dist/services/oni-v2/runtime.d.ts +23 -0
- package/dist/services/oni-v2/runtime.d.ts.map +1 -0
- package/dist/services/oni-v2/runtime.js +121 -0
- package/dist/services/oni-v2/templating.d.ts +11 -0
- package/dist/services/oni-v2/templating.d.ts.map +1 -0
- package/dist/services/oni-v2/templating.js +27 -0
- package/dist/services/oni-v2/types.d.ts +100 -0
- package/dist/services/oni-v2/types.d.ts.map +1 -0
- package/dist/services/oni-v2/types.js +3 -0
- package/dist/services/raid-v2/audit.d.ts +10 -0
- package/dist/services/raid-v2/audit.d.ts.map +1 -0
- package/dist/services/raid-v2/audit.js +29 -0
- package/dist/services/raid-v2/errors.d.ts +85 -0
- package/dist/services/raid-v2/errors.d.ts.map +1 -0
- package/dist/services/raid-v2/errors.js +36 -0
- package/dist/services/raid-v2/http.d.ts +4 -0
- package/dist/services/raid-v2/http.d.ts.map +1 -0
- package/dist/services/raid-v2/http.js +84 -0
- package/dist/services/raid-v2/logger.d.ts +8 -0
- package/dist/services/raid-v2/logger.d.ts.map +1 -0
- package/dist/services/raid-v2/logger.js +30 -0
- package/dist/services/raid-v2/mapping.d.ts +9 -0
- package/dist/services/raid-v2/mapping.d.ts.map +1 -0
- package/dist/services/raid-v2/mapping.js +168 -0
- package/dist/services/raid-v2/runtime.d.ts +5 -0
- package/dist/services/raid-v2/runtime.d.ts.map +1 -0
- package/dist/services/raid-v2/runtime.js +135 -0
- package/dist/services/raid-v2/tags.d.ts +11 -0
- package/dist/services/raid-v2/tags.d.ts.map +1 -0
- package/dist/services/raid-v2/tags.js +12 -0
- package/dist/services/raid-v2/types.d.ts +66 -0
- package/dist/services/raid-v2/types.d.ts.map +1 -0
- package/dist/services/raid-v2/types.js +3 -0
- package/dist/services/record-hooks/coordinator.d.ts +64 -0
- package/dist/services/record-hooks/coordinator.d.ts.map +1 -0
- package/dist/services/record-hooks/coordinator.js +276 -0
- package/dist/visitor/client.visitor.d.ts +6 -0
- package/dist/visitor/client.visitor.d.ts.map +1 -1
- package/dist/visitor/client.visitor.js +59 -14
- package/dist/visitor/construct.visitor.d.ts +27 -1
- package/dist/visitor/construct.visitor.d.ts.map +1 -1
- package/dist/visitor/construct.visitor.js +265 -177
- package/dist/visitor/context-variables.visitor.d.ts +3 -1
- package/dist/visitor/context-variables.visitor.d.ts.map +1 -1
- package/dist/visitor/context-variables.visitor.js +15 -1
- package/dist/visitor/data-value.visitor.d.ts +6 -0
- package/dist/visitor/data-value.visitor.d.ts.map +1 -1
- package/dist/visitor/data-value.visitor.js +10 -1
- package/dist/visitor/json-type-def.visitor.d.ts +6 -0
- package/dist/visitor/json-type-def.visitor.d.ts.map +1 -1
- package/dist/visitor/json-type-def.visitor.js +10 -1
- package/dist/visitor/migrate-config-v4-v5.visitor.d.ts +11 -0
- package/dist/visitor/migrate-config-v4-v5.visitor.d.ts.map +1 -1
- package/dist/visitor/migrate-config-v4-v5.visitor.js +228 -133
- package/dist/visitor/related-object-data-inline.visitor.d.ts +31 -0
- package/dist/visitor/related-object-data-inline.visitor.d.ts.map +1 -0
- package/dist/visitor/related-object-data-inline.visitor.js +96 -0
- package/dist/visitor/template.visitor.d.ts +17 -2
- package/dist/visitor/template.visitor.d.ts.map +1 -1
- package/dist/visitor/template.visitor.js +60 -22
- package/dist/visitor/validator.visitor.d.ts +49 -7
- package/dist/visitor/validator.visitor.d.ts.map +1 -1
- package/dist/visitor/validator.visitor.js +275 -178
- package/dist/waterline-models/AttachmentMetadata.d.ts +22 -0
- package/dist/waterline-models/AttachmentMetadata.d.ts.map +1 -1
- package/dist/waterline-models/AttachmentMetadata.js +147 -3
- package/dist/waterline-models/BrandingConfig.d.ts +7 -0
- package/dist/waterline-models/BrandingConfig.d.ts.map +1 -1
- package/dist/waterline-models/BrandingConfig.js +16 -1
- package/dist/waterline-models/BrandingConfigHistory.d.ts +11 -2
- package/dist/waterline-models/BrandingConfigHistory.d.ts.map +1 -1
- package/dist/waterline-models/BrandingConfigHistory.js +21 -1
- package/dist/waterline-models/DashboardConfiguration.d.ts +29 -0
- package/dist/waterline-models/DashboardConfiguration.d.ts.map +1 -0
- package/dist/waterline-models/DashboardConfiguration.js +52 -0
- package/dist/waterline-models/RecordType.d.ts +9 -0
- package/dist/waterline-models/RecordType.d.ts.map +1 -1
- package/dist/waterline-models/RecordType.js +16 -1
- package/dist/waterline-models/User.d.ts.map +1 -1
- package/dist/waterline-models/User.js +10 -15
- package/dist/waterline-models/index.d.ts +2 -0
- package/dist/waterline-models/index.d.ts.map +1 -1
- package/dist/waterline-models/index.js +4 -1
- package/package.json +59 -45
- package/dist/config/datapubs.config.d.ts +0 -72
- package/dist/config/datapubs.config.d.ts.map +0 -1
- package/dist/config/datapubs.config.js +0 -74
|
@@ -0,0 +1,3061 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Services = exports.RecordSchemaLifecycleError = exports.RECORD_SCHEMA_STARTUP_LOG_FINDING_COUNT_MAX = exports.RECORD_SCHEMA_RETENTION_REPORT_MAX_PAGE_SIZE = exports.RECORD_SCHEMA_RETENTION_REPORT_DEFAULT_PAGE_SIZE = exports.RECORD_SCHEMA_CONFIGURED_FORM_MAX_CANDIDATES = exports.RECORD_SCHEMA_LIFECYCLE_ERROR_CODE = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const api_1 = require("@opentelemetry/api");
|
|
6
|
+
const sails_ng_common_1 = require("@researchdatabox/sails-ng-common");
|
|
7
|
+
const CoreService_1 = require("../CoreService");
|
|
8
|
+
const recordSchema_config_1 = require("../config/recordSchema.config");
|
|
9
|
+
const record_contract_1 = require("../record-contract");
|
|
10
|
+
const StorageService_1 = require("../StorageService");
|
|
11
|
+
const codes_1 = require("../record-contract/codes");
|
|
12
|
+
const internal_record_schema_authorization_1 = require("./internal-record-schema-authorization");
|
|
13
|
+
exports.RECORD_SCHEMA_LIFECYCLE_ERROR_CODE = 'record-schema.lifecycle-failed';
|
|
14
|
+
const CATEGORY_ORDER = {
|
|
15
|
+
configuration: 0,
|
|
16
|
+
storage: 1,
|
|
17
|
+
contributor: 2,
|
|
18
|
+
coverage: 3,
|
|
19
|
+
form: 4,
|
|
20
|
+
pin: 5,
|
|
21
|
+
};
|
|
22
|
+
const DUPLICATE_REGISTRATION_CODES = new Set([
|
|
23
|
+
record_contract_1.RECORD_CONTRACT_REGISTRATION_CODES.DUPLICATE_KEY,
|
|
24
|
+
record_contract_1.RECORD_CONTRACT_REGISTRATION_CODES.DUPLICATE_COMPONENT,
|
|
25
|
+
]);
|
|
26
|
+
const DIGEST_PATTERN = /^[0-9a-f]{64}$/;
|
|
27
|
+
const SAFE_DIAGNOSTIC_IDENTIFIER = /^[A-Za-z0-9@._:/-]{1,200}$/;
|
|
28
|
+
const RECORD_SCHEMA_REFERENCE_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,511}$/;
|
|
29
|
+
exports.RECORD_SCHEMA_CONFIGURED_FORM_MAX_CANDIDATES = 1_000;
|
|
30
|
+
const RECORD_SCHEMA_RETENTION_REFERENCE_LIMIT = 1_000;
|
|
31
|
+
const RECORD_SCHEMA_RETENTION_REPORT_MAX_DIGESTS = 100;
|
|
32
|
+
exports.RECORD_SCHEMA_RETENTION_REPORT_DEFAULT_PAGE_SIZE = 100;
|
|
33
|
+
exports.RECORD_SCHEMA_RETENTION_REPORT_MAX_PAGE_SIZE = 100;
|
|
34
|
+
const RECORD_SCHEMA_STRICT_ALL_OPERATION = 'strict-all';
|
|
35
|
+
const MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1_000;
|
|
36
|
+
/** Maximum exact startup finding count exposed in one structured log event. */
|
|
37
|
+
exports.RECORD_SCHEMA_STARTUP_LOG_FINDING_COUNT_MAX = 100;
|
|
38
|
+
const recordSchemaMeter = api_1.metrics.getMeter('redbox.record-schema');
|
|
39
|
+
const recordSchemaCompileDuration = recordSchemaMeter.createHistogram('redbox.record_schema.compile.duration', {
|
|
40
|
+
description: 'Record-schema compilation duration.',
|
|
41
|
+
unit: 'ms',
|
|
42
|
+
});
|
|
43
|
+
const recordSchemaCompileOutcomes = recordSchemaMeter.createCounter('redbox.record_schema.compile.outcomes', {
|
|
44
|
+
description: 'Record-schema compilation outcomes.',
|
|
45
|
+
unit: '{compile}',
|
|
46
|
+
});
|
|
47
|
+
const recordSchemaCacheResults = recordSchemaMeter.createCounter('redbox.record_schema.cache.results', {
|
|
48
|
+
description: 'Record-schema validator cache results.',
|
|
49
|
+
unit: '{lookup}',
|
|
50
|
+
});
|
|
51
|
+
const recordSchemaCompleteness = recordSchemaMeter.createCounter('redbox.record_schema.completeness', {
|
|
52
|
+
description: 'Resolved record-schema completeness.',
|
|
53
|
+
unit: '{schema}',
|
|
54
|
+
});
|
|
55
|
+
const recordSchemaResolverOutcomes = recordSchemaMeter.createCounter('redbox.record_schema.resolver.outcomes', {
|
|
56
|
+
description: 'Record-schema resolver outcomes.',
|
|
57
|
+
unit: '{resolution}',
|
|
58
|
+
});
|
|
59
|
+
const recordSchemaValidationResults = recordSchemaMeter.createCounter('redbox.record_schema.validation.results', {
|
|
60
|
+
description: 'Record-schema structural validation results.',
|
|
61
|
+
unit: '{validation}',
|
|
62
|
+
});
|
|
63
|
+
const recordSchemaValidationProblems = recordSchemaMeter.createCounter('redbox.record_schema.validation.problems', {
|
|
64
|
+
description: 'Record-schema structural validation problems by stable code.',
|
|
65
|
+
unit: '{problem}',
|
|
66
|
+
});
|
|
67
|
+
const recordSchemaPreconditionMismatches = recordSchemaMeter.createCounter('redbox.record_schema.precondition.mismatches', { description: 'Record-schema update precondition mismatches.', unit: '{mismatch}' });
|
|
68
|
+
const recordSchemaPersistence = recordSchemaMeter.createCounter('redbox.record_schema.persistence', {
|
|
69
|
+
description: 'Record-schema artifact and grant persistence outcomes.',
|
|
70
|
+
unit: '{write}',
|
|
71
|
+
});
|
|
72
|
+
const recordSchemaUsageReferences = recordSchemaMeter.createCounter('redbox.record_schema.usage_references', {
|
|
73
|
+
description: 'Record-schema save and pin usage-reference outcomes.',
|
|
74
|
+
unit: '{reference}',
|
|
75
|
+
});
|
|
76
|
+
const recordSchemaTelemetryCodes = new Set(Object.values(codes_1.RECORD_SCHEMA_PROBLEM_CODES));
|
|
77
|
+
const RECORD_SCHEMA_RESOLVER_OUTCOMES = new Set([
|
|
78
|
+
'resolved',
|
|
79
|
+
'partial',
|
|
80
|
+
'unavailable',
|
|
81
|
+
'context-failed',
|
|
82
|
+
'limit-exceeded',
|
|
83
|
+
'compiler-failed',
|
|
84
|
+
'meta-validation-failed',
|
|
85
|
+
'storage-failed',
|
|
86
|
+
'denied',
|
|
87
|
+
'missing-oid',
|
|
88
|
+
'invalid-precondition',
|
|
89
|
+
'precondition-failed',
|
|
90
|
+
'invalid-request',
|
|
91
|
+
'not-found',
|
|
92
|
+
'invalid-contract',
|
|
93
|
+
'not-modified',
|
|
94
|
+
]);
|
|
95
|
+
const RECORD_SCHEMA_COMPILE_OUTCOMES = new Set([
|
|
96
|
+
'resolved',
|
|
97
|
+
'context-failed',
|
|
98
|
+
'unavailable',
|
|
99
|
+
'limit-exceeded',
|
|
100
|
+
'compiler-failed',
|
|
101
|
+
'meta-validation-failed',
|
|
102
|
+
'unexpected-failure',
|
|
103
|
+
]);
|
|
104
|
+
const RECORD_SCHEMA_USAGE_REFERENCE_OUTCOMES = new Set([
|
|
105
|
+
'recorded',
|
|
106
|
+
'write-failed',
|
|
107
|
+
'invalid-input',
|
|
108
|
+
'disabled',
|
|
109
|
+
'unavailable',
|
|
110
|
+
'materialized',
|
|
111
|
+
'failed',
|
|
112
|
+
'limit-exceeded',
|
|
113
|
+
]);
|
|
114
|
+
function metricKind(value) {
|
|
115
|
+
return value === 'create' || value === 'update' ? value : 'unknown';
|
|
116
|
+
}
|
|
117
|
+
function recordCounter(counter, attributes) {
|
|
118
|
+
try {
|
|
119
|
+
counter.add(1, attributes);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Telemetry must never alter service results.
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function recordDuration(durationMs, attributes) {
|
|
126
|
+
try {
|
|
127
|
+
recordSchemaCompileDuration.record(Number.isFinite(durationMs) && durationMs >= 0 ? durationMs : 0, attributes);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
// Telemetry must never alter service results.
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function telemetryCode(value) {
|
|
134
|
+
return typeof value === 'string' && recordSchemaTelemetryCodes.has(value) ? value : 'none';
|
|
135
|
+
}
|
|
136
|
+
function telemetryDimension(value, allowlist, fallback) {
|
|
137
|
+
return typeof value === 'string' && allowlist.has(value) ? value : fallback;
|
|
138
|
+
}
|
|
139
|
+
function safeErrorType(error) {
|
|
140
|
+
return error instanceof Error ? 'error' : 'non-error';
|
|
141
|
+
}
|
|
142
|
+
function unreadableConfigurationFinding() {
|
|
143
|
+
return {
|
|
144
|
+
category: 'configuration',
|
|
145
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
146
|
+
path: 'recordSchema',
|
|
147
|
+
reason: 'unreadable',
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function compareText(left, right) {
|
|
151
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
152
|
+
}
|
|
153
|
+
function isObjectRecord(value) {
|
|
154
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
155
|
+
}
|
|
156
|
+
function isReflectable(value) {
|
|
157
|
+
return value !== null && (typeof value === 'object' || typeof value === 'function');
|
|
158
|
+
}
|
|
159
|
+
function configuredRecordSchema() {
|
|
160
|
+
const configured = sails.config.recordSchema;
|
|
161
|
+
if (configured === undefined)
|
|
162
|
+
return recordSchema_config_1.recordSchema;
|
|
163
|
+
if (!isObjectRecord(configured))
|
|
164
|
+
return configured;
|
|
165
|
+
// Sails environment overrides can replace the nested config object rather
|
|
166
|
+
// than deep-merging it with config/recordSchema.js. Preserve partial
|
|
167
|
+
// overrides while keeping the required defaults available to runtime
|
|
168
|
+
// validation. An explicitly supplied non-object nested value remains
|
|
169
|
+
// untouched so malformed configuration is still reported as invalid.
|
|
170
|
+
const hasOwn = (property) => Object.prototype.hasOwnProperty.call(configured, property);
|
|
171
|
+
const configuredLimits = hasOwn('limits') ? configured.limits : undefined;
|
|
172
|
+
const configuredRetention = hasOwn('retention') ? configured.retention : undefined;
|
|
173
|
+
return {
|
|
174
|
+
...recordSchema_config_1.recordSchema,
|
|
175
|
+
...configured,
|
|
176
|
+
limits: configuredLimits === undefined
|
|
177
|
+
? recordSchema_config_1.recordSchema.limits
|
|
178
|
+
: isObjectRecord(configuredLimits)
|
|
179
|
+
? { ...recordSchema_config_1.recordSchema.limits, ...configuredLimits }
|
|
180
|
+
: configuredLimits,
|
|
181
|
+
retention: configuredRetention === undefined
|
|
182
|
+
? recordSchema_config_1.recordSchema.retention
|
|
183
|
+
: isObjectRecord(configuredRetention)
|
|
184
|
+
? { ...recordSchema_config_1.recordSchema.retention, ...configuredRetention }
|
|
185
|
+
: configuredRetention,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function configuredStorageProvider() {
|
|
189
|
+
const storageConfig = sails.config.storage;
|
|
190
|
+
if (isObjectRecord(storageConfig)) {
|
|
191
|
+
const serviceName = storageConfig.serviceName;
|
|
192
|
+
if (typeof serviceName === 'string' && serviceName.trim() !== '') {
|
|
193
|
+
return sails.services?.[serviceName];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return typeof RedboxJavaStorageService === 'undefined' ? undefined : RedboxJavaStorageService;
|
|
197
|
+
}
|
|
198
|
+
function hasRecordEditAuthorizationCapability(value) {
|
|
199
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function'))
|
|
200
|
+
return false;
|
|
201
|
+
try {
|
|
202
|
+
return typeof Reflect.get(value, 'hasEditAccess') === 'function';
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
function hasRecordCreateAuthorizationCapability(value) {
|
|
209
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function'))
|
|
210
|
+
return false;
|
|
211
|
+
try {
|
|
212
|
+
return typeof Reflect.get(value, 'hasCreateAccess') === 'function';
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function recordsAuthorizationService() {
|
|
219
|
+
const configured = sails.services?.recordsservice;
|
|
220
|
+
return configured === undefined && typeof RecordsService !== 'undefined' ? RecordsService : configured;
|
|
221
|
+
}
|
|
222
|
+
function recordEditAuthorizationService() {
|
|
223
|
+
const candidate = recordsAuthorizationService();
|
|
224
|
+
return hasRecordEditAuthorizationCapability(candidate) ? candidate : undefined;
|
|
225
|
+
}
|
|
226
|
+
async function authorizeCreateWithRecordsService(context, caller) {
|
|
227
|
+
const recordsService = recordsAuthorizationService();
|
|
228
|
+
if (!hasRecordCreateAuthorizationCapability(recordsService)) {
|
|
229
|
+
throw new Error('Record create authorization is unavailable.');
|
|
230
|
+
}
|
|
231
|
+
const username = typeof caller.user?.username === 'string' ? caller.user.username.trim() : '';
|
|
232
|
+
const brandId = typeof caller.brand?.id === 'string' ? caller.brand.id.trim() : '';
|
|
233
|
+
if (!username || brandId !== context.publicContext.brand || !context.resolution.actor.authenticated) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
const roles = Array.isArray(caller.user.roles) ? caller.user.roles : [];
|
|
237
|
+
return await recordsService.hasCreateAccess(caller.brand, caller.user, roles, context.publicContext.recordType, context.publicContext.workflowStep);
|
|
238
|
+
}
|
|
239
|
+
async function authorizeUpdateWithRecordsService(context, caller) {
|
|
240
|
+
const recordsService = recordEditAuthorizationService();
|
|
241
|
+
if (!recordsService) {
|
|
242
|
+
throw new Error('Record edit authorization is unavailable.');
|
|
243
|
+
}
|
|
244
|
+
const username = typeof caller.user?.username === 'string' ? caller.user.username.trim() : '';
|
|
245
|
+
const brandId = typeof caller.brand?.id === 'string' ? caller.brand.id.trim() : '';
|
|
246
|
+
if (!username || brandId !== context.publicContext.brand || !context.resolution.actor.authenticated) {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
const roles = Array.isArray(caller.user.roles) ? caller.user.roles : [];
|
|
250
|
+
return recordsService.hasEditAccess(caller.brand, caller.user, roles, context.resolution.existingRecord);
|
|
251
|
+
}
|
|
252
|
+
const DEFAULT_DEPENDENCIES = {
|
|
253
|
+
getConfig: configuredRecordSchema,
|
|
254
|
+
getStorageProvider: configuredStorageProvider,
|
|
255
|
+
getContributorRegistry: () => undefined,
|
|
256
|
+
getContributorRegistrationIssues: () => [],
|
|
257
|
+
getContributorComponentTypes: () => [],
|
|
258
|
+
getConfiguredFormCandidates: () => FormsService.listConfiguredRecordContractForms(),
|
|
259
|
+
resolveContractContext: request => RecordValidationService.resolveContractContext(request),
|
|
260
|
+
buildContractFormConfig: (context, recordAccessContext) => FormsService.buildContractFormConfig(context, recordAccessContext),
|
|
261
|
+
authorizeCreate: authorizeCreateWithRecordsService,
|
|
262
|
+
authorizeUpdate: authorizeUpdateWithRecordsService,
|
|
263
|
+
clock: () => Date.now(),
|
|
264
|
+
};
|
|
265
|
+
function findingSortKey(finding) {
|
|
266
|
+
switch (finding.category) {
|
|
267
|
+
case 'configuration':
|
|
268
|
+
return `${finding.path}\u0000${finding.reason}`;
|
|
269
|
+
case 'storage': {
|
|
270
|
+
const methodIndex = StorageService_1.RECORD_SCHEMA_STORAGE_CAPABILITY_METHODS.indexOf(finding.method);
|
|
271
|
+
return `${String(methodIndex).padStart(2, '0')}\u0000${finding.method}`;
|
|
272
|
+
}
|
|
273
|
+
case 'contributor':
|
|
274
|
+
return `${finding.registrationCode}\u0000${finding.key}`;
|
|
275
|
+
case 'coverage':
|
|
276
|
+
return finding.componentType;
|
|
277
|
+
case 'form':
|
|
278
|
+
return `${finding.form}\u0000${finding.stage}\u0000${finding.code}`;
|
|
279
|
+
case 'pin':
|
|
280
|
+
return `${finding.path}\u0000${finding.reason}`;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function sortFindings(findings) {
|
|
284
|
+
return [...findings].sort((left, right) => CATEGORY_ORDER[left.category] - CATEGORY_ORDER[right.category] ||
|
|
285
|
+
compareText(findingSortKey(left), findingSortKey(right)));
|
|
286
|
+
}
|
|
287
|
+
function diagnosticIdentifier(value) {
|
|
288
|
+
return SAFE_DIAGNOSTIC_IDENTIFIER.test(value) ? value : '<invalid-identifier>';
|
|
289
|
+
}
|
|
290
|
+
function findingMessage(finding) {
|
|
291
|
+
switch (finding.category) {
|
|
292
|
+
case 'configuration':
|
|
293
|
+
return `${finding.code} [${finding.path}]: configuration is invalid (${finding.reason}).`;
|
|
294
|
+
case 'storage':
|
|
295
|
+
return `${finding.code} [${finding.method}]: required record-schema storage method is unavailable.`;
|
|
296
|
+
case 'contributor':
|
|
297
|
+
return `${finding.code} [${diagnosticIdentifier(finding.key)}]: contributor registration is invalid (${finding.registrationCode}).`;
|
|
298
|
+
case 'coverage':
|
|
299
|
+
return `${finding.code} [${finding.componentType}]: core component has no registered record-contract contributor.`;
|
|
300
|
+
case 'form':
|
|
301
|
+
return `${finding.code} [${finding.form}]: configured form compilation failed (${finding.stage}).`;
|
|
302
|
+
case 'pin':
|
|
303
|
+
return `${finding.code} [${finding.path}]: configured integration pin is invalid (${finding.reason}).`;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
class RecordSchemaLifecycleError extends Error {
|
|
307
|
+
code = exports.RECORD_SCHEMA_LIFECYCLE_ERROR_CODE;
|
|
308
|
+
findings;
|
|
309
|
+
constructor(findings) {
|
|
310
|
+
const sorted = sortFindings(findings);
|
|
311
|
+
super(`RecordSchemaService initialization failed with ${sorted.length} fatal finding(s):\n${sorted
|
|
312
|
+
.map(finding => `- ${findingMessage(finding)}`)
|
|
313
|
+
.join('\n')}`);
|
|
314
|
+
this.name = 'RecordSchemaLifecycleError';
|
|
315
|
+
this.findings = Object.freeze(sorted.map(finding => Object.freeze({ ...finding })));
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
exports.RecordSchemaLifecycleError = RecordSchemaLifecycleError;
|
|
319
|
+
function configurationFindings(value) {
|
|
320
|
+
const validation = (0, recordSchema_config_1.validateRecordSchemaConfig)(value);
|
|
321
|
+
if (validation.valid) {
|
|
322
|
+
return [];
|
|
323
|
+
}
|
|
324
|
+
const rawPins = isObjectRecord(value) && Array.isArray(value.integrationPins) ? value.integrationPins : undefined;
|
|
325
|
+
const findings = [];
|
|
326
|
+
for (const problem of validation.problems) {
|
|
327
|
+
if (!problem.path.startsWith('recordSchema.integrationPins')) {
|
|
328
|
+
findings.push({
|
|
329
|
+
category: 'configuration',
|
|
330
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
331
|
+
path: problem.path,
|
|
332
|
+
reason: problem.reason,
|
|
333
|
+
});
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
const itemMatch = /^recordSchema\.integrationPins\.(\d+)$/.exec(problem.path);
|
|
337
|
+
if (itemMatch && rawPins && isObjectRecord(rawPins[Number(itemMatch[1])])) {
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
findings.push({
|
|
341
|
+
category: 'pin',
|
|
342
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
343
|
+
path: problem.path,
|
|
344
|
+
reason: problem.reason,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return findings;
|
|
348
|
+
}
|
|
349
|
+
function pinFinding(path, reason) {
|
|
350
|
+
return {
|
|
351
|
+
category: 'pin',
|
|
352
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
353
|
+
path,
|
|
354
|
+
reason,
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
function validatePinText(pin, index, property, maximumLength) {
|
|
358
|
+
const path = `recordSchema.integrationPins.${index}.${property}`;
|
|
359
|
+
const value = pin[property];
|
|
360
|
+
if (value === undefined) {
|
|
361
|
+
return [pinFinding(path, 'required')];
|
|
362
|
+
}
|
|
363
|
+
if (typeof value !== 'string') {
|
|
364
|
+
return [pinFinding(path, 'type')];
|
|
365
|
+
}
|
|
366
|
+
if (value.length === 0 || value !== value.trim()) {
|
|
367
|
+
return [pinFinding(path, 'normalized-non-empty')];
|
|
368
|
+
}
|
|
369
|
+
if (value.length > maximumLength) {
|
|
370
|
+
return [pinFinding(path, 'maximum-length')];
|
|
371
|
+
}
|
|
372
|
+
return [];
|
|
373
|
+
}
|
|
374
|
+
function integrationPinFindings(value) {
|
|
375
|
+
if (!isObjectRecord(value) || !Array.isArray(value.integrationPins)) {
|
|
376
|
+
return [];
|
|
377
|
+
}
|
|
378
|
+
if (value.integrationPins.length > recordSchema_config_1.MAX_RECORD_SCHEMA_INTEGRATION_PINS) {
|
|
379
|
+
return [];
|
|
380
|
+
}
|
|
381
|
+
const findings = [];
|
|
382
|
+
value.integrationPins.forEach((candidate, index) => {
|
|
383
|
+
if (!isObjectRecord(candidate)) {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
for (const property of ['digest', 'brand', 'portal', 'recordType', 'owner']) {
|
|
387
|
+
findings.push(...validatePinText(candidate, index, property, 512));
|
|
388
|
+
}
|
|
389
|
+
findings.push(...validatePinText(candidate, index, 'purpose', 2_048));
|
|
390
|
+
const digest = candidate.digest;
|
|
391
|
+
if (typeof digest === 'string' && digest === digest.trim() && digest.length > 0 && !DIGEST_PATTERN.test(digest)) {
|
|
392
|
+
findings.push(pinFinding(`recordSchema.integrationPins.${index}.digest`, 'digest'));
|
|
393
|
+
}
|
|
394
|
+
if (candidate.schemaKind !== 'create' && candidate.schemaKind !== 'update') {
|
|
395
|
+
findings.push(pinFinding(`recordSchema.integrationPins.${index}.schemaKind`, candidate.schemaKind === undefined ? 'required' : 'schema-kind'));
|
|
396
|
+
}
|
|
397
|
+
const operation = candidate.operation;
|
|
398
|
+
if (operation === undefined) {
|
|
399
|
+
findings.push(pinFinding(`recordSchema.integrationPins.${index}.operation`, 'required'));
|
|
400
|
+
}
|
|
401
|
+
else if (typeof operation !== 'string' || !sails_ng_common_1.VALIDATION_OPERATION_NAME_PATTERN.test(operation.trim())) {
|
|
402
|
+
findings.push(pinFinding(`recordSchema.integrationPins.${index}.operation`, 'operation'));
|
|
403
|
+
}
|
|
404
|
+
if (candidate.expiresAt !== undefined) {
|
|
405
|
+
const expiresAt = candidate.expiresAt;
|
|
406
|
+
if (typeof expiresAt !== 'string' ||
|
|
407
|
+
expiresAt.length === 0 ||
|
|
408
|
+
expiresAt !== expiresAt.trim() ||
|
|
409
|
+
!canonicalInstant(expiresAt)) {
|
|
410
|
+
findings.push(pinFinding(`recordSchema.integrationPins.${index}.expiresAt`, 'datetime'));
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
return findings;
|
|
415
|
+
}
|
|
416
|
+
const RFC_3339_INSTANT_PATTERN = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{3})?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
|
417
|
+
function canonicalInstant(value) {
|
|
418
|
+
if (!RFC_3339_INSTANT_PATTERN.test(value))
|
|
419
|
+
return undefined;
|
|
420
|
+
const [year, month, day] = value
|
|
421
|
+
.slice(0, 10)
|
|
422
|
+
.split('-')
|
|
423
|
+
.map(component => Number(component));
|
|
424
|
+
if (day > new Date(Date.UTC(year, month, 0)).getUTCDate())
|
|
425
|
+
return undefined;
|
|
426
|
+
const milliseconds = Date.parse(value);
|
|
427
|
+
if (!Number.isFinite(milliseconds))
|
|
428
|
+
return undefined;
|
|
429
|
+
const date = new Date(milliseconds);
|
|
430
|
+
return Number.isNaN(date.getTime()) ? undefined : date;
|
|
431
|
+
}
|
|
432
|
+
function configuredFindings(value) {
|
|
433
|
+
try {
|
|
434
|
+
return [...configurationFindings(value), ...integrationPinFindings(value)];
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
return [unreadableConfigurationFinding()];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function storageFindings(provider) {
|
|
441
|
+
let missing;
|
|
442
|
+
try {
|
|
443
|
+
missing = (0, StorageService_1.getMissingRecordSchemaStorageCapabilities)(provider);
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
missing = StorageService_1.RECORD_SCHEMA_STORAGE_CAPABILITY_METHODS;
|
|
447
|
+
}
|
|
448
|
+
return missing.map(method => ({
|
|
449
|
+
category: 'storage',
|
|
450
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
451
|
+
method,
|
|
452
|
+
}));
|
|
453
|
+
}
|
|
454
|
+
function contributorFindings(issues) {
|
|
455
|
+
return issues.map(issue => ({
|
|
456
|
+
category: 'contributor',
|
|
457
|
+
code: DUPLICATE_REGISTRATION_CODES.has(issue.code)
|
|
458
|
+
? codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONTRIBUTOR_DUPLICATE
|
|
459
|
+
: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONTRIBUTOR_INVALID,
|
|
460
|
+
registrationCode: issue.code,
|
|
461
|
+
key: diagnosticIdentifier(issue.key),
|
|
462
|
+
}));
|
|
463
|
+
}
|
|
464
|
+
function unavailableContributorStateIssue() {
|
|
465
|
+
return {
|
|
466
|
+
code: record_contract_1.RECORD_CONTRACT_REGISTRATION_CODES.INVALID_EXPORT,
|
|
467
|
+
key: 'registry',
|
|
468
|
+
detail: 'Contributor discovery state is unavailable.',
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
function coverageFindings(componentTypes) {
|
|
472
|
+
const covered = new Set(componentTypes);
|
|
473
|
+
return Object.keys(record_contract_1.CORE_RECORD_CONTRACT_COMPONENT_INVENTORY)
|
|
474
|
+
.filter(componentType => !covered.has(componentType))
|
|
475
|
+
.map(componentType => ({
|
|
476
|
+
category: 'coverage',
|
|
477
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNSUPPORTED_COMPONENT,
|
|
478
|
+
componentType,
|
|
479
|
+
}));
|
|
480
|
+
}
|
|
481
|
+
function isDisabled(value) {
|
|
482
|
+
const normalized = (0, recordSchema_config_1.normalizeRecordSchemaConfig)(value);
|
|
483
|
+
return isObjectRecord(normalized) && normalized.enabled === false;
|
|
484
|
+
}
|
|
485
|
+
function resolvedPipelineResult(pipeline, schemaKind, context) {
|
|
486
|
+
return Object.freeze({
|
|
487
|
+
kind: pipeline.kind,
|
|
488
|
+
document: pipeline.document,
|
|
489
|
+
digest: pipeline.digest,
|
|
490
|
+
grant: pipeline.grant,
|
|
491
|
+
metadata: Object.freeze({
|
|
492
|
+
schemaKind,
|
|
493
|
+
contractFormat: pipeline.contractFormat,
|
|
494
|
+
completeness: pipeline.completeness,
|
|
495
|
+
byteLength: pipeline.byteLength,
|
|
496
|
+
etag: pipeline.etag,
|
|
497
|
+
context: context.publicContext,
|
|
498
|
+
}),
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
function createStorageProvider(value) {
|
|
502
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
503
|
+
return undefined;
|
|
504
|
+
}
|
|
505
|
+
try {
|
|
506
|
+
return typeof Reflect.get(value, 'putRecordSchemaArtifact') === 'function' &&
|
|
507
|
+
typeof Reflect.get(value, 'putRecordSchemaReference') === 'function'
|
|
508
|
+
? value
|
|
509
|
+
: undefined;
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
return undefined;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
function isImmutableStorageProvider(value) {
|
|
516
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
return (typeof Reflect.get(value, 'getRecordSchemaArtifact') === 'function' &&
|
|
521
|
+
typeof Reflect.get(value, 'findRecordSchemaGrantForAuthorization') === 'function' &&
|
|
522
|
+
typeof Reflect.get(value, 'touchRecordSchemaArtifact') === 'function');
|
|
523
|
+
}
|
|
524
|
+
catch {
|
|
525
|
+
return false;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
function isReferenceStorageProvider(value) {
|
|
529
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
try {
|
|
533
|
+
return typeof Reflect.get(value, 'putRecordSchemaReference') === 'function';
|
|
534
|
+
}
|
|
535
|
+
catch {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
function isTargetedRetentionStorageProvider(value) {
|
|
540
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
try {
|
|
544
|
+
return (typeof Reflect.get(value, 'getRecordSchemaArtifact') === 'function' &&
|
|
545
|
+
typeof Reflect.get(value, 'listRecordSchemaReferences') === 'function');
|
|
546
|
+
}
|
|
547
|
+
catch {
|
|
548
|
+
return false;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
function isPagedRetentionStorageProvider(value) {
|
|
552
|
+
if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
try {
|
|
556
|
+
return (typeof Reflect.get(value, 'listRecordSchemaArtifacts') === 'function' &&
|
|
557
|
+
typeof Reflect.get(value, 'listRecordSchemaReferences') === 'function');
|
|
558
|
+
}
|
|
559
|
+
catch {
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
function storageResponseSucceeded(response) {
|
|
564
|
+
try {
|
|
565
|
+
return response?.success === true;
|
|
566
|
+
}
|
|
567
|
+
catch {
|
|
568
|
+
return false;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
function storageResponseCode(response) {
|
|
572
|
+
try {
|
|
573
|
+
const details = response?.details;
|
|
574
|
+
if (!isObjectRecord(details)) {
|
|
575
|
+
return undefined;
|
|
576
|
+
}
|
|
577
|
+
return typeof details.code === 'string' ? details.code : undefined;
|
|
578
|
+
}
|
|
579
|
+
catch {
|
|
580
|
+
return undefined;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
function referenceWriteFailure(response, unavailableCode = codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE) {
|
|
584
|
+
switch (storageResponseCode(response)) {
|
|
585
|
+
case codes_1.RECORD_SCHEMA_PROBLEM_CODES.ARTIFACT_NOT_FOUND:
|
|
586
|
+
return {
|
|
587
|
+
failureKind: 'artifact-not-found',
|
|
588
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.ARTIFACT_NOT_FOUND,
|
|
589
|
+
retryable: false,
|
|
590
|
+
};
|
|
591
|
+
case codes_1.RECORD_SCHEMA_PROBLEM_CODES.REFERENCE_INVALID:
|
|
592
|
+
return {
|
|
593
|
+
failureKind: 'invalid-reference',
|
|
594
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.REFERENCE_INVALID,
|
|
595
|
+
retryable: false,
|
|
596
|
+
};
|
|
597
|
+
case codes_1.RECORD_SCHEMA_PROBLEM_CODES.REFERENCE_KEY_COLLISION:
|
|
598
|
+
return {
|
|
599
|
+
failureKind: 'reference-key-collision',
|
|
600
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.REFERENCE_KEY_COLLISION,
|
|
601
|
+
retryable: false,
|
|
602
|
+
};
|
|
603
|
+
case codes_1.RECORD_SCHEMA_PROBLEM_CODES.DIGEST_COLLISION:
|
|
604
|
+
return { failureKind: 'digest-collision', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.DIGEST_COLLISION, retryable: false };
|
|
605
|
+
case codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT:
|
|
606
|
+
return { failureKind: 'invalid-state', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT, retryable: false };
|
|
607
|
+
default:
|
|
608
|
+
return {
|
|
609
|
+
failureKind: 'storage-unavailable',
|
|
610
|
+
code: unavailableCode,
|
|
611
|
+
retryable: true,
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
const INVALID_DATA_PROPERTY = Symbol('invalid-data-property');
|
|
616
|
+
function ownDataProperty(value, property) {
|
|
617
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, property);
|
|
618
|
+
return descriptor && 'value' in descriptor ? descriptor.value : INVALID_DATA_PROPERTY;
|
|
619
|
+
}
|
|
620
|
+
/** Consume at most maximum + 1 actual iterator values; array length is not trusted. */
|
|
621
|
+
function boundedArraySnapshot(value, maximum) {
|
|
622
|
+
if (!Array.isArray(value))
|
|
623
|
+
return { kind: 'invalid' };
|
|
624
|
+
try {
|
|
625
|
+
const iteratorFactory = Reflect.get(value, Symbol.iterator);
|
|
626
|
+
if (typeof iteratorFactory !== 'function')
|
|
627
|
+
return { kind: 'invalid' };
|
|
628
|
+
const iterator = Reflect.apply(iteratorFactory, value, []);
|
|
629
|
+
if (!isReflectable(iterator))
|
|
630
|
+
return { kind: 'invalid' };
|
|
631
|
+
const next = Reflect.get(iterator, 'next');
|
|
632
|
+
if (typeof next !== 'function')
|
|
633
|
+
return { kind: 'invalid' };
|
|
634
|
+
const values = [];
|
|
635
|
+
for (let index = 0; index <= maximum; index += 1) {
|
|
636
|
+
const step = Reflect.apply(next, iterator, []);
|
|
637
|
+
if (!isReflectable(step))
|
|
638
|
+
return { kind: 'invalid' };
|
|
639
|
+
const done = Reflect.get(step, 'done');
|
|
640
|
+
if (done === true)
|
|
641
|
+
return { kind: 'values', values: Object.freeze(values) };
|
|
642
|
+
if (done !== false && done !== undefined)
|
|
643
|
+
return { kind: 'invalid' };
|
|
644
|
+
if (index === maximum) {
|
|
645
|
+
const close = Reflect.get(iterator, 'return');
|
|
646
|
+
if (typeof close === 'function') {
|
|
647
|
+
try {
|
|
648
|
+
Reflect.apply(close, iterator, []);
|
|
649
|
+
}
|
|
650
|
+
catch {
|
|
651
|
+
// Overflow is already deterministic; iterator cleanup failure cannot change it.
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return { kind: 'overflow' };
|
|
655
|
+
}
|
|
656
|
+
values.push(Reflect.get(step, 'value'));
|
|
657
|
+
}
|
|
658
|
+
return { kind: 'overflow' };
|
|
659
|
+
}
|
|
660
|
+
catch {
|
|
661
|
+
return { kind: 'invalid' };
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
function boundedNormalizedText(value, property, maximumLength = 512) {
|
|
665
|
+
const candidate = ownDataProperty(value, property);
|
|
666
|
+
return typeof candidate === 'string' &&
|
|
667
|
+
candidate.length > 0 &&
|
|
668
|
+
candidate.length <= maximumLength &&
|
|
669
|
+
candidate === candidate.trim()
|
|
670
|
+
? candidate
|
|
671
|
+
: undefined;
|
|
672
|
+
}
|
|
673
|
+
function isConfiguredForm(value) {
|
|
674
|
+
if (!isObjectRecord(value))
|
|
675
|
+
return false;
|
|
676
|
+
return Array.isArray(ownDataProperty(value, 'componentDefinitions'));
|
|
677
|
+
}
|
|
678
|
+
function isReusableFormDefinitions(value) {
|
|
679
|
+
if (!isObjectRecord(value))
|
|
680
|
+
return false;
|
|
681
|
+
try {
|
|
682
|
+
return Object.keys(value).every(name => Array.isArray(ownDataProperty(value, name)));
|
|
683
|
+
}
|
|
684
|
+
catch {
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
function parseConfiguredFormCandidate(value) {
|
|
689
|
+
try {
|
|
690
|
+
if (!isObjectRecord(value))
|
|
691
|
+
return undefined;
|
|
692
|
+
const name = boundedNormalizedText(value, 'name', 200);
|
|
693
|
+
const form = ownDataProperty(value, 'form');
|
|
694
|
+
const reusableFormDefinitions = ownDataProperty(value, 'reusableFormDefinitions');
|
|
695
|
+
if (!name ||
|
|
696
|
+
!SAFE_DIAGNOSTIC_IDENTIFIER.test(name) ||
|
|
697
|
+
!isConfiguredForm(form) ||
|
|
698
|
+
!isReusableFormDefinitions(reusableFormDefinitions)) {
|
|
699
|
+
return undefined;
|
|
700
|
+
}
|
|
701
|
+
return Object.freeze({ name, form, reusableFormDefinitions });
|
|
702
|
+
}
|
|
703
|
+
catch {
|
|
704
|
+
return undefined;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
function configuredFormFinding(form, stage, code) {
|
|
708
|
+
return Object.freeze({
|
|
709
|
+
category: 'form',
|
|
710
|
+
code,
|
|
711
|
+
form: diagnosticIdentifier(form),
|
|
712
|
+
stage,
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
function parseSaveUsageRequest(value) {
|
|
716
|
+
try {
|
|
717
|
+
if (!isObjectRecord(value)) {
|
|
718
|
+
return undefined;
|
|
719
|
+
}
|
|
720
|
+
const digest = boundedNormalizedText(value, 'digest', 64);
|
|
721
|
+
const brand = boundedNormalizedText(value, 'brand');
|
|
722
|
+
const portal = boundedNormalizedText(value, 'portal');
|
|
723
|
+
const recordType = boundedNormalizedText(value, 'recordType');
|
|
724
|
+
const oid = boundedNormalizedText(value, 'oid');
|
|
725
|
+
const operation = boundedNormalizedText(value, 'operation');
|
|
726
|
+
const saveIdentity = boundedNormalizedText(value, 'saveIdentity');
|
|
727
|
+
const schemaKind = ownDataProperty(value, 'schemaKind');
|
|
728
|
+
if (!digest ||
|
|
729
|
+
!DIGEST_PATTERN.test(digest) ||
|
|
730
|
+
!brand ||
|
|
731
|
+
!portal ||
|
|
732
|
+
!recordType ||
|
|
733
|
+
!oid ||
|
|
734
|
+
!operation ||
|
|
735
|
+
!sails_ng_common_1.VALIDATION_OPERATION_NAME_PATTERN.test(operation) ||
|
|
736
|
+
!saveIdentity ||
|
|
737
|
+
!RECORD_SCHEMA_REFERENCE_KEY_PATTERN.test(saveIdentity) ||
|
|
738
|
+
(schemaKind !== 'create' && schemaKind !== 'update')) {
|
|
739
|
+
return undefined;
|
|
740
|
+
}
|
|
741
|
+
return Object.freeze({
|
|
742
|
+
digest,
|
|
743
|
+
brand,
|
|
744
|
+
portal,
|
|
745
|
+
schemaKind,
|
|
746
|
+
recordType,
|
|
747
|
+
oid,
|
|
748
|
+
operation,
|
|
749
|
+
saveIdentity,
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
catch {
|
|
753
|
+
return undefined;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
function parseResolvedSchemaValidationRequest(value) {
|
|
757
|
+
try {
|
|
758
|
+
if (!isObjectRecord(value))
|
|
759
|
+
return undefined;
|
|
760
|
+
const digest = ownDataProperty(value, 'digest');
|
|
761
|
+
const schemaKind = ownDataProperty(value, 'schemaKind');
|
|
762
|
+
const document = ownDataProperty(value, 'document');
|
|
763
|
+
const input = ownDataProperty(value, 'input');
|
|
764
|
+
if (typeof digest !== 'string' ||
|
|
765
|
+
!DIGEST_PATTERN.test(digest) ||
|
|
766
|
+
(schemaKind !== 'create' && schemaKind !== 'update') ||
|
|
767
|
+
!isObjectRecord(document) ||
|
|
768
|
+
input === INVALID_DATA_PROPERTY) {
|
|
769
|
+
return undefined;
|
|
770
|
+
}
|
|
771
|
+
return Object.freeze({
|
|
772
|
+
digest,
|
|
773
|
+
schemaKind,
|
|
774
|
+
document: document,
|
|
775
|
+
input,
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
catch {
|
|
779
|
+
return undefined;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
function hashedReferenceKey(prefix, identity) {
|
|
783
|
+
return `${prefix}:${(0, node_crypto_1.createHash)('sha256').update((0, record_contract_1.serializeRedboxCanonicalJsonV1)(identity), 'utf8').digest('hex')}`;
|
|
784
|
+
}
|
|
785
|
+
function createSaveReference(request) {
|
|
786
|
+
const persisted = {
|
|
787
|
+
digest: request.digest,
|
|
788
|
+
brand: request.brand,
|
|
789
|
+
portal: request.portal,
|
|
790
|
+
schemaKind: request.schemaKind,
|
|
791
|
+
recordType: request.recordType,
|
|
792
|
+
operation: request.operation,
|
|
793
|
+
oid: request.oid,
|
|
794
|
+
};
|
|
795
|
+
return Object.freeze({
|
|
796
|
+
referenceKey: hashedReferenceKey('save', {
|
|
797
|
+
...persisted,
|
|
798
|
+
kind: 'save',
|
|
799
|
+
saveIdentity: request.saveIdentity,
|
|
800
|
+
}),
|
|
801
|
+
...persisted,
|
|
802
|
+
kind: 'save',
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
function integrationPinReference(pin) {
|
|
806
|
+
const expiresAt = pin.expiresAt === undefined ? undefined : canonicalInstant(pin.expiresAt);
|
|
807
|
+
if (pin.expiresAt !== undefined && !expiresAt) {
|
|
808
|
+
throw new Error('Integration pin expiry is invalid.');
|
|
809
|
+
}
|
|
810
|
+
const persisted = {
|
|
811
|
+
digest: pin.digest,
|
|
812
|
+
brand: pin.brand,
|
|
813
|
+
portal: pin.portal,
|
|
814
|
+
schemaKind: pin.schemaKind,
|
|
815
|
+
recordType: pin.recordType,
|
|
816
|
+
operation: pin.operation.trim(),
|
|
817
|
+
owner: pin.owner,
|
|
818
|
+
purpose: pin.purpose,
|
|
819
|
+
...(expiresAt ? { expiresAt } : {}),
|
|
820
|
+
};
|
|
821
|
+
return Object.freeze({
|
|
822
|
+
referenceKey: hashedReferenceKey('pin', {
|
|
823
|
+
digest: persisted.digest,
|
|
824
|
+
brand: persisted.brand,
|
|
825
|
+
portal: persisted.portal,
|
|
826
|
+
schemaKind: persisted.schemaKind,
|
|
827
|
+
recordType: persisted.recordType,
|
|
828
|
+
operation: persisted.operation,
|
|
829
|
+
owner: persisted.owner,
|
|
830
|
+
purpose: persisted.purpose,
|
|
831
|
+
...(expiresAt ? { expiresAt: expiresAt.toISOString() } : {}),
|
|
832
|
+
kind: 'pin',
|
|
833
|
+
}),
|
|
834
|
+
...persisted,
|
|
835
|
+
kind: 'pin',
|
|
836
|
+
});
|
|
837
|
+
}
|
|
838
|
+
function configuredPinReferences(config) {
|
|
839
|
+
const referencesByKey = new Map();
|
|
840
|
+
for (const pin of config.integrationPins ?? []) {
|
|
841
|
+
const reference = integrationPinReference(pin);
|
|
842
|
+
referencesByKey.set(reference.referenceKey, reference);
|
|
843
|
+
}
|
|
844
|
+
return Object.freeze([...referencesByKey.values()].sort((left, right) => compareText(left.referenceKey, right.referenceKey)));
|
|
845
|
+
}
|
|
846
|
+
function parseRetentionReportRequest(value) {
|
|
847
|
+
try {
|
|
848
|
+
if (!isObjectRecord(value)) {
|
|
849
|
+
return { ok: false, reason: 'shape' };
|
|
850
|
+
}
|
|
851
|
+
const rawNow = ownDataProperty(value, 'now');
|
|
852
|
+
if (!(rawNow instanceof Date) || Number.isNaN(rawNow.getTime())) {
|
|
853
|
+
return { ok: false, reason: 'datetime' };
|
|
854
|
+
}
|
|
855
|
+
const modeDescriptor = Object.getOwnPropertyDescriptor(value, 'mode');
|
|
856
|
+
const digestsDescriptor = Object.getOwnPropertyDescriptor(value, 'digests');
|
|
857
|
+
const limitDescriptor = Object.getOwnPropertyDescriptor(value, 'limit');
|
|
858
|
+
const cursorDescriptor = Object.getOwnPropertyDescriptor(value, 'cursor');
|
|
859
|
+
if (modeDescriptor === undefined ||
|
|
860
|
+
!('value' in modeDescriptor) ||
|
|
861
|
+
(digestsDescriptor !== undefined && !('value' in digestsDescriptor)) ||
|
|
862
|
+
(limitDescriptor !== undefined && !('value' in limitDescriptor)) ||
|
|
863
|
+
(cursorDescriptor !== undefined && !('value' in cursorDescriptor))) {
|
|
864
|
+
return { ok: false, reason: 'shape' };
|
|
865
|
+
}
|
|
866
|
+
if (modeDescriptor.value === 'targeted') {
|
|
867
|
+
if (digestsDescriptor === undefined || limitDescriptor !== undefined || cursorDescriptor !== undefined) {
|
|
868
|
+
return { ok: false, reason: 'shape' };
|
|
869
|
+
}
|
|
870
|
+
const boundedDigests = boundedArraySnapshot(digestsDescriptor.value, RECORD_SCHEMA_RETENTION_REPORT_MAX_DIGESTS);
|
|
871
|
+
if (boundedDigests.kind === 'invalid') {
|
|
872
|
+
return { ok: false, reason: 'shape' };
|
|
873
|
+
}
|
|
874
|
+
if (boundedDigests.kind === 'overflow') {
|
|
875
|
+
return { ok: false, reason: 'limit' };
|
|
876
|
+
}
|
|
877
|
+
const uniqueDigests = [...new Set(boundedDigests.values)];
|
|
878
|
+
if (uniqueDigests.some(digest => typeof digest !== 'string' || !DIGEST_PATTERN.test(digest))) {
|
|
879
|
+
return { ok: false, reason: 'digest' };
|
|
880
|
+
}
|
|
881
|
+
const digests = uniqueDigests.filter((digest) => typeof digest === 'string');
|
|
882
|
+
return {
|
|
883
|
+
ok: true,
|
|
884
|
+
request: Object.freeze({
|
|
885
|
+
kind: 'targeted',
|
|
886
|
+
digests: Object.freeze(digests.sort(compareText)),
|
|
887
|
+
now: new Date(rawNow.getTime()),
|
|
888
|
+
}),
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
if (modeDescriptor.value !== 'paginated' || digestsDescriptor !== undefined) {
|
|
892
|
+
return { ok: false, reason: 'shape' };
|
|
893
|
+
}
|
|
894
|
+
const limit = limitDescriptor?.value ?? exports.RECORD_SCHEMA_RETENTION_REPORT_DEFAULT_PAGE_SIZE;
|
|
895
|
+
if (typeof limit !== 'number' ||
|
|
896
|
+
!Number.isSafeInteger(limit) ||
|
|
897
|
+
limit < 1 ||
|
|
898
|
+
limit > exports.RECORD_SCHEMA_RETENTION_REPORT_MAX_PAGE_SIZE) {
|
|
899
|
+
return { ok: false, reason: 'limit' };
|
|
900
|
+
}
|
|
901
|
+
const cursor = cursorDescriptor?.value;
|
|
902
|
+
if (cursor !== undefined && (typeof cursor !== 'string' || !DIGEST_PATTERN.test(cursor))) {
|
|
903
|
+
return { ok: false, reason: 'digest' };
|
|
904
|
+
}
|
|
905
|
+
return {
|
|
906
|
+
ok: true,
|
|
907
|
+
request: Object.freeze({
|
|
908
|
+
kind: 'page',
|
|
909
|
+
...(typeof cursor === 'string' ? { cursor } : {}),
|
|
910
|
+
limit,
|
|
911
|
+
now: new Date(rawNow.getTime()),
|
|
912
|
+
}),
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
catch {
|
|
916
|
+
return { ok: false, reason: 'shape' };
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
function isValidDate(value) {
|
|
920
|
+
return value instanceof Date && !Number.isNaN(value.getTime());
|
|
921
|
+
}
|
|
922
|
+
function hasOwnReferenceField(reference, field) {
|
|
923
|
+
return Object.getOwnPropertyDescriptor(reference, field) !== undefined;
|
|
924
|
+
}
|
|
925
|
+
function retentionReferenceEvidence(reference, expectedDigest, now) {
|
|
926
|
+
if (!isObjectRecord(reference))
|
|
927
|
+
return undefined;
|
|
928
|
+
const referenceKey = boundedNormalizedText(reference, 'referenceKey');
|
|
929
|
+
const digest = boundedNormalizedText(reference, 'digest', 64);
|
|
930
|
+
const brand = boundedNormalizedText(reference, 'brand');
|
|
931
|
+
const portal = boundedNormalizedText(reference, 'portal');
|
|
932
|
+
const recordType = boundedNormalizedText(reference, 'recordType');
|
|
933
|
+
const operation = boundedNormalizedText(reference, 'operation', 64);
|
|
934
|
+
const schemaKind = ownDataProperty(reference, 'schemaKind');
|
|
935
|
+
const kind = ownDataProperty(reference, 'kind');
|
|
936
|
+
const createdAt = ownDataProperty(reference, 'createdAt');
|
|
937
|
+
const updatedAt = ownDataProperty(reference, 'updatedAt');
|
|
938
|
+
if (!referenceKey ||
|
|
939
|
+
!RECORD_SCHEMA_REFERENCE_KEY_PATTERN.test(referenceKey) ||
|
|
940
|
+
digest !== expectedDigest ||
|
|
941
|
+
!brand ||
|
|
942
|
+
!portal ||
|
|
943
|
+
!recordType ||
|
|
944
|
+
!operation ||
|
|
945
|
+
!sails_ng_common_1.VALIDATION_OPERATION_NAME_PATTERN.test(operation) ||
|
|
946
|
+
(schemaKind !== 'create' && schemaKind !== 'update') ||
|
|
947
|
+
!isValidDate(createdAt) ||
|
|
948
|
+
!isValidDate(updatedAt)) {
|
|
949
|
+
return undefined;
|
|
950
|
+
}
|
|
951
|
+
if (kind === 'grant') {
|
|
952
|
+
if (hasOwnReferenceField(reference, 'owner') ||
|
|
953
|
+
hasOwnReferenceField(reference, 'purpose') ||
|
|
954
|
+
hasOwnReferenceField(reference, 'expiresAt') ||
|
|
955
|
+
(schemaKind === 'create' && hasOwnReferenceField(reference, 'oid')) ||
|
|
956
|
+
(schemaKind === 'update' && !boundedNormalizedText(reference, 'oid'))) {
|
|
957
|
+
return undefined;
|
|
958
|
+
}
|
|
959
|
+
return 'grant';
|
|
960
|
+
}
|
|
961
|
+
if (kind === 'save') {
|
|
962
|
+
if (hasOwnReferenceField(reference, 'owner') ||
|
|
963
|
+
hasOwnReferenceField(reference, 'purpose') ||
|
|
964
|
+
hasOwnReferenceField(reference, 'expiresAt')) {
|
|
965
|
+
return undefined;
|
|
966
|
+
}
|
|
967
|
+
return boundedNormalizedText(reference, 'oid') ? 'save' : undefined;
|
|
968
|
+
}
|
|
969
|
+
if (kind !== 'pin' ||
|
|
970
|
+
hasOwnReferenceField(reference, 'oid') ||
|
|
971
|
+
!boundedNormalizedText(reference, 'owner') ||
|
|
972
|
+
!boundedNormalizedText(reference, 'purpose', 2_048)) {
|
|
973
|
+
return undefined;
|
|
974
|
+
}
|
|
975
|
+
const expiresAt = ownDataProperty(reference, 'expiresAt');
|
|
976
|
+
if (expiresAt === INVALID_DATA_PROPERTY || expiresAt === undefined)
|
|
977
|
+
return 'active-pin';
|
|
978
|
+
if (!isValidDate(expiresAt))
|
|
979
|
+
return undefined;
|
|
980
|
+
return expiresAt.getTime() > now.getTime() ? 'active-pin' : 'expired-pin';
|
|
981
|
+
}
|
|
982
|
+
function retentionArtifactSummary(artifact, expectedDigest) {
|
|
983
|
+
try {
|
|
984
|
+
if (!isObjectRecord(artifact))
|
|
985
|
+
return undefined;
|
|
986
|
+
const digest = ownDataProperty(artifact, 'digest');
|
|
987
|
+
const createdAt = ownDataProperty(artifact, 'createdAt');
|
|
988
|
+
if (typeof digest !== 'string' ||
|
|
989
|
+
!DIGEST_PATTERN.test(digest) ||
|
|
990
|
+
(expectedDigest !== undefined && digest !== expectedDigest) ||
|
|
991
|
+
!isValidDate(createdAt)) {
|
|
992
|
+
return undefined;
|
|
993
|
+
}
|
|
994
|
+
return Object.freeze({ digest, createdAt: new Date(createdAt.getTime()) });
|
|
995
|
+
}
|
|
996
|
+
catch {
|
|
997
|
+
return undefined;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
function retentionEntry(artifact, references, expectedDigest, now, minimumAgeDays) {
|
|
1001
|
+
try {
|
|
1002
|
+
if (!Array.isArray(references))
|
|
1003
|
+
return undefined;
|
|
1004
|
+
const summary = retentionArtifactSummary(artifact, expectedDigest);
|
|
1005
|
+
if (!summary)
|
|
1006
|
+
return undefined;
|
|
1007
|
+
const { digest, createdAt } = summary;
|
|
1008
|
+
let grantCount = 0;
|
|
1009
|
+
let saveCount = 0;
|
|
1010
|
+
let activePinCount = 0;
|
|
1011
|
+
for (const reference of references) {
|
|
1012
|
+
const evidence = retentionReferenceEvidence(reference, digest, now);
|
|
1013
|
+
if (evidence === 'grant') {
|
|
1014
|
+
grantCount += 1;
|
|
1015
|
+
}
|
|
1016
|
+
else if (evidence === 'save') {
|
|
1017
|
+
saveCount += 1;
|
|
1018
|
+
}
|
|
1019
|
+
else if (evidence === 'active-pin') {
|
|
1020
|
+
activePinCount += 1;
|
|
1021
|
+
}
|
|
1022
|
+
else if (evidence !== 'expired-pin') {
|
|
1023
|
+
return undefined;
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const ageDays = Math.max(0, Math.floor((now.getTime() - createdAt.getTime()) / MILLISECONDS_PER_DAY));
|
|
1027
|
+
const reasons = [];
|
|
1028
|
+
if (ageDays < minimumAgeDays)
|
|
1029
|
+
reasons.push('minimum-age');
|
|
1030
|
+
if (grantCount > 0)
|
|
1031
|
+
reasons.push('grant-reference');
|
|
1032
|
+
if (saveCount > 0)
|
|
1033
|
+
reasons.push('save-reference');
|
|
1034
|
+
if (activePinCount > 0)
|
|
1035
|
+
reasons.push('active-pin');
|
|
1036
|
+
return Object.freeze({
|
|
1037
|
+
digest,
|
|
1038
|
+
createdAt: new Date(createdAt.getTime()),
|
|
1039
|
+
ageDays,
|
|
1040
|
+
grantCount,
|
|
1041
|
+
saveCount,
|
|
1042
|
+
activePinCount,
|
|
1043
|
+
reasons: Object.freeze(reasons),
|
|
1044
|
+
eligibleForDeletion: reasons.length === 0,
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
catch {
|
|
1048
|
+
return undefined;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
function isContractJsonObject(value) {
|
|
1052
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
1053
|
+
}
|
|
1054
|
+
function isCreateContractContext(context) {
|
|
1055
|
+
return context.publicContext.kind === 'create';
|
|
1056
|
+
}
|
|
1057
|
+
function isUpdateContractContext(context) {
|
|
1058
|
+
return context.publicContext.kind === 'update';
|
|
1059
|
+
}
|
|
1060
|
+
function publicBranding(request) {
|
|
1061
|
+
const branding = typeof request.branding === 'string' ? request.branding.trim() : '';
|
|
1062
|
+
return branding || request.brand;
|
|
1063
|
+
}
|
|
1064
|
+
function createContextWithPublicBrand(context, branding) {
|
|
1065
|
+
if (context.publicContext.brand === branding)
|
|
1066
|
+
return context;
|
|
1067
|
+
return Object.freeze({
|
|
1068
|
+
publicContext: Object.freeze({ ...context.publicContext, brand: branding }),
|
|
1069
|
+
resolution: context.resolution,
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
function updateContextWithPublicBrand(context, branding) {
|
|
1073
|
+
if (context.publicContext.brand === branding)
|
|
1074
|
+
return context;
|
|
1075
|
+
return Object.freeze({
|
|
1076
|
+
publicContext: Object.freeze({ ...context.publicContext, brand: branding }),
|
|
1077
|
+
resolution: context.resolution,
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
function callerActor(caller) {
|
|
1081
|
+
const username = typeof caller.user?.username === 'string' ? caller.user.username.trim() : '';
|
|
1082
|
+
const rawRoles = Array.isArray(caller.user?.roles) ? caller.user.roles : [];
|
|
1083
|
+
const roles = [
|
|
1084
|
+
...new Set(rawRoles.map(role => (typeof role?.name === 'string' ? role.name.trim() : '')).filter(role => role.length > 0)),
|
|
1085
|
+
].sort(compareText);
|
|
1086
|
+
return Object.freeze({
|
|
1087
|
+
authenticated: username.length > 0,
|
|
1088
|
+
roles: Object.freeze(roles),
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
function parseImmutableGrant(value, request) {
|
|
1092
|
+
try {
|
|
1093
|
+
if (!isObjectRecord(value))
|
|
1094
|
+
return { kind: 'invalid' };
|
|
1095
|
+
const referenceKey = boundedNormalizedText(value, 'referenceKey');
|
|
1096
|
+
const digest = boundedNormalizedText(value, 'digest', 64);
|
|
1097
|
+
const brand = boundedNormalizedText(value, 'brand');
|
|
1098
|
+
const portal = boundedNormalizedText(value, 'portal');
|
|
1099
|
+
const recordType = boundedNormalizedText(value, 'recordType');
|
|
1100
|
+
const operation = boundedNormalizedText(value, 'operation', 64);
|
|
1101
|
+
const kind = ownDataProperty(value, 'kind');
|
|
1102
|
+
const schemaKind = ownDataProperty(value, 'schemaKind');
|
|
1103
|
+
if (!referenceKey ||
|
|
1104
|
+
!RECORD_SCHEMA_REFERENCE_KEY_PATTERN.test(referenceKey) ||
|
|
1105
|
+
!digest ||
|
|
1106
|
+
!DIGEST_PATTERN.test(digest) ||
|
|
1107
|
+
!brand ||
|
|
1108
|
+
!portal ||
|
|
1109
|
+
!recordType ||
|
|
1110
|
+
!operation ||
|
|
1111
|
+
!sails_ng_common_1.VALIDATION_OPERATION_NAME_PATTERN.test(operation) ||
|
|
1112
|
+
kind !== 'grant' ||
|
|
1113
|
+
(schemaKind !== 'create' && schemaKind !== 'update') ||
|
|
1114
|
+
hasOwnReferenceField(value, 'owner') ||
|
|
1115
|
+
hasOwnReferenceField(value, 'purpose') ||
|
|
1116
|
+
hasOwnReferenceField(value, 'expiresAt')) {
|
|
1117
|
+
return { kind: 'invalid' };
|
|
1118
|
+
}
|
|
1119
|
+
if (digest !== request.digest || brand !== publicBranding(request) || portal !== request.portal) {
|
|
1120
|
+
return { kind: 'irrelevant' };
|
|
1121
|
+
}
|
|
1122
|
+
const oid = ownDataProperty(value, 'oid');
|
|
1123
|
+
if (schemaKind === 'create') {
|
|
1124
|
+
if (oid !== INVALID_DATA_PROPERTY)
|
|
1125
|
+
return { kind: 'invalid' };
|
|
1126
|
+
return {
|
|
1127
|
+
kind: 'grant',
|
|
1128
|
+
grant: Object.freeze({
|
|
1129
|
+
referenceKey,
|
|
1130
|
+
digest,
|
|
1131
|
+
brand,
|
|
1132
|
+
portal,
|
|
1133
|
+
kind: 'grant',
|
|
1134
|
+
schemaKind: 'create',
|
|
1135
|
+
recordType,
|
|
1136
|
+
operation,
|
|
1137
|
+
}),
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
if (typeof oid !== 'string' || !oid || oid !== oid.trim() || oid.length > 512) {
|
|
1141
|
+
return { kind: 'invalid' };
|
|
1142
|
+
}
|
|
1143
|
+
return {
|
|
1144
|
+
kind: 'grant',
|
|
1145
|
+
grant: Object.freeze({
|
|
1146
|
+
referenceKey,
|
|
1147
|
+
digest,
|
|
1148
|
+
brand,
|
|
1149
|
+
portal,
|
|
1150
|
+
kind: 'grant',
|
|
1151
|
+
schemaKind: 'update',
|
|
1152
|
+
recordType,
|
|
1153
|
+
operation,
|
|
1154
|
+
oid,
|
|
1155
|
+
}),
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
catch {
|
|
1159
|
+
return { kind: 'invalid' };
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
function immutableProblemInstance(request) {
|
|
1163
|
+
return `/${encodeURIComponent(publicBranding(request))}/${encodeURIComponent(request.portal)}/api/records/schemas/${encodeURIComponent(request.digest)}`;
|
|
1164
|
+
}
|
|
1165
|
+
function immutableProblem(request, values) {
|
|
1166
|
+
return Object.freeze({
|
|
1167
|
+
...values,
|
|
1168
|
+
instance: immutableProblemInstance(request),
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
function invalidDigestResult(request) {
|
|
1172
|
+
return Object.freeze({
|
|
1173
|
+
kind: 'invalid-request',
|
|
1174
|
+
problem: immutableProblem(request, {
|
|
1175
|
+
type: 'https://redboxresearchdata.com/problems/record-schema-invalid-request',
|
|
1176
|
+
title: 'Record schema request is invalid',
|
|
1177
|
+
status: 400,
|
|
1178
|
+
detail: 'The record schema digest must be a lowercase 64-character SHA-256 hexadecimal value.',
|
|
1179
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_REQUEST,
|
|
1180
|
+
}),
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
function invalidImmutableConditionalResult(request) {
|
|
1184
|
+
return Object.freeze({
|
|
1185
|
+
kind: 'invalid-request',
|
|
1186
|
+
problem: immutableProblem(request, {
|
|
1187
|
+
type: 'https://redboxresearchdata.com/problems/record-schema-invalid-request',
|
|
1188
|
+
title: 'Record schema request is invalid',
|
|
1189
|
+
status: 400,
|
|
1190
|
+
detail: 'If-None-Match must contain one supported strong record schema ETag.',
|
|
1191
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_REQUEST,
|
|
1192
|
+
}),
|
|
1193
|
+
});
|
|
1194
|
+
}
|
|
1195
|
+
function immutableNotFoundResult(request) {
|
|
1196
|
+
return Object.freeze({
|
|
1197
|
+
kind: 'not-found',
|
|
1198
|
+
problem: immutableProblem(request, {
|
|
1199
|
+
type: 'https://redboxresearchdata.com/problems/record-schema-not-found',
|
|
1200
|
+
title: 'Record schema was not found',
|
|
1201
|
+
status: 404,
|
|
1202
|
+
detail: 'No accessible schema was found.',
|
|
1203
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.NOT_FOUND,
|
|
1204
|
+
}),
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
function immutableUnavailableResult(request, code) {
|
|
1208
|
+
return Object.freeze({
|
|
1209
|
+
kind: 'unavailable',
|
|
1210
|
+
problem: immutableProblem(request, {
|
|
1211
|
+
type: 'https://redboxresearchdata.com/problems/record-schema-unavailable',
|
|
1212
|
+
title: 'Record schema is unavailable',
|
|
1213
|
+
status: 503,
|
|
1214
|
+
detail: 'Record schema retrieval is currently unavailable.',
|
|
1215
|
+
code,
|
|
1216
|
+
}),
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
function immutableInvalidContractResult(request, authorization) {
|
|
1220
|
+
return Object.freeze({
|
|
1221
|
+
kind: 'invalid-contract',
|
|
1222
|
+
authorization,
|
|
1223
|
+
problem: immutableProblem(request, {
|
|
1224
|
+
type: 'https://redboxresearchdata.com/problems/record-schema-invalid-contract',
|
|
1225
|
+
title: 'Record schema contract is invalid',
|
|
1226
|
+
status: 422,
|
|
1227
|
+
detail: 'The stored schema artifact failed its immutable identity check.',
|
|
1228
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
1229
|
+
}),
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
function immutableGrantInvalidContractResult(request) {
|
|
1233
|
+
return Object.freeze({
|
|
1234
|
+
kind: 'invalid-contract',
|
|
1235
|
+
authorization: 'unverified',
|
|
1236
|
+
problem: immutableProblem(request, {
|
|
1237
|
+
type: 'https://redboxresearchdata.com/problems/record-schema-invalid-contract',
|
|
1238
|
+
title: 'Record schema contract is invalid',
|
|
1239
|
+
status: 422,
|
|
1240
|
+
detail: 'Stored schema authorization data is invalid.',
|
|
1241
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
1242
|
+
}),
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
function immutableGrantOperation(operation) {
|
|
1246
|
+
return operation === RECORD_SCHEMA_STRICT_ALL_OPERATION ? undefined : operation;
|
|
1247
|
+
}
|
|
1248
|
+
function immutableCreateTargetStep(artifact) {
|
|
1249
|
+
const context = artifact.document['x-redbox-context'];
|
|
1250
|
+
if (!isObjectRecord(context) || context.kind !== 'create') {
|
|
1251
|
+
return undefined;
|
|
1252
|
+
}
|
|
1253
|
+
return typeof context.workflowStep === 'string' ? context.workflowStep : undefined;
|
|
1254
|
+
}
|
|
1255
|
+
function immutableAuthorizationQuery(artifact, request) {
|
|
1256
|
+
const context = artifact.document['x-redbox-context'];
|
|
1257
|
+
if (!isObjectRecord(context))
|
|
1258
|
+
return undefined;
|
|
1259
|
+
const schemaKind = ownDataProperty(context, 'kind');
|
|
1260
|
+
const brand = boundedNormalizedText(context, 'brand');
|
|
1261
|
+
const portal = boundedNormalizedText(context, 'portal');
|
|
1262
|
+
const recordType = boundedNormalizedText(context, 'recordType');
|
|
1263
|
+
const operation = boundedNormalizedText(context, 'operation', 64);
|
|
1264
|
+
const recordBrandId = String(request.caller.brand?.id ?? '').trim();
|
|
1265
|
+
const username = String(request.caller.user?.username ?? '').trim();
|
|
1266
|
+
if ((schemaKind !== 'create' && schemaKind !== 'update') ||
|
|
1267
|
+
brand !== publicBranding(request) ||
|
|
1268
|
+
portal !== request.portal ||
|
|
1269
|
+
!recordType ||
|
|
1270
|
+
!operation ||
|
|
1271
|
+
!sails_ng_common_1.VALIDATION_OPERATION_NAME_PATTERN.test(operation) ||
|
|
1272
|
+
!recordBrandId ||
|
|
1273
|
+
!username) {
|
|
1274
|
+
return undefined;
|
|
1275
|
+
}
|
|
1276
|
+
const roleNames = new Set();
|
|
1277
|
+
if (schemaKind === 'update') {
|
|
1278
|
+
const roles = Array.isArray(request.caller.user.roles) ? request.caller.user.roles : [];
|
|
1279
|
+
const brandRoles = Array.isArray(request.caller.brand.roles) ? request.caller.brand.roles : [];
|
|
1280
|
+
const configuredRoleNamesById = new Map();
|
|
1281
|
+
for (const configuredRole of brandRoles) {
|
|
1282
|
+
if (!isObjectRecord(configuredRole))
|
|
1283
|
+
continue;
|
|
1284
|
+
const configuredName = boundedNormalizedText(configuredRole, 'name');
|
|
1285
|
+
const configuredId = boundedNormalizedText(configuredRole, 'id');
|
|
1286
|
+
if (configuredName && configuredId)
|
|
1287
|
+
configuredRoleNamesById.set(configuredId, configuredName);
|
|
1288
|
+
}
|
|
1289
|
+
for (const actorRole of roles) {
|
|
1290
|
+
if (!isObjectRecord(actorRole))
|
|
1291
|
+
continue;
|
|
1292
|
+
const name = boundedNormalizedText(actorRole, 'name');
|
|
1293
|
+
const id = boundedNormalizedText(actorRole, 'id');
|
|
1294
|
+
if (!name || !id)
|
|
1295
|
+
continue;
|
|
1296
|
+
if (configuredRoleNamesById.get(id) === name) {
|
|
1297
|
+
roleNames.add(name);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
return Object.freeze({
|
|
1302
|
+
digest: request.digest,
|
|
1303
|
+
brand,
|
|
1304
|
+
portal,
|
|
1305
|
+
schemaKind,
|
|
1306
|
+
recordType,
|
|
1307
|
+
operation,
|
|
1308
|
+
recordBrandId,
|
|
1309
|
+
username,
|
|
1310
|
+
roleNames: Object.freeze([...roleNames].sort(compareText)),
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
function verifiedImmutableArtifact(artifact, expected) {
|
|
1314
|
+
try {
|
|
1315
|
+
const normalized = (0, record_contract_1.normalizeRecordJsonSchemaDocument)(artifact.document);
|
|
1316
|
+
const identity = (0, record_contract_1.identifyRecordJsonSchema)(normalized, Number.MAX_SAFE_INTEGER);
|
|
1317
|
+
if (artifact.digest !== expected.digest ||
|
|
1318
|
+
identity.digest !== expected.digest ||
|
|
1319
|
+
(0, record_contract_1.serializeRedboxCanonicalJsonV1)(identity.document) !== (0, record_contract_1.serializeRedboxCanonicalJsonV1)(expected.document) ||
|
|
1320
|
+
artifact.contractFormat !== expected.contractFormat ||
|
|
1321
|
+
artifact.completeness !== expected.completeness ||
|
|
1322
|
+
artifact.byteLength !== identity.byteLength) {
|
|
1323
|
+
return undefined;
|
|
1324
|
+
}
|
|
1325
|
+
const immutableDocument = (0, record_contract_1.normalizeRedboxCanonicalJsonV1)(identity.document);
|
|
1326
|
+
if (!isContractJsonObject(immutableDocument)) {
|
|
1327
|
+
return undefined;
|
|
1328
|
+
}
|
|
1329
|
+
return Object.freeze({
|
|
1330
|
+
digest: artifact.digest,
|
|
1331
|
+
document: immutableDocument,
|
|
1332
|
+
contractFormat: artifact.contractFormat,
|
|
1333
|
+
completeness: artifact.completeness,
|
|
1334
|
+
byteLength: artifact.byteLength,
|
|
1335
|
+
createdAt: artifact.createdAt,
|
|
1336
|
+
updatedAt: artifact.updatedAt,
|
|
1337
|
+
...(artifact.lastAccessedAt ? { lastAccessedAt: artifact.lastAccessedAt } : {}),
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
catch {
|
|
1341
|
+
return undefined;
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
function createGrantReference(artifact, context) {
|
|
1345
|
+
const common = {
|
|
1346
|
+
digest: artifact.digest,
|
|
1347
|
+
brand: context.brand,
|
|
1348
|
+
portal: context.portal,
|
|
1349
|
+
recordType: context.recordType,
|
|
1350
|
+
operation: context.operation,
|
|
1351
|
+
};
|
|
1352
|
+
const identity = (0, record_contract_1.serializeRedboxCanonicalJsonV1)({
|
|
1353
|
+
...common,
|
|
1354
|
+
kind: 'grant',
|
|
1355
|
+
schemaKind: 'create',
|
|
1356
|
+
});
|
|
1357
|
+
return Object.freeze({
|
|
1358
|
+
referenceKey: `grant:create:${(0, node_crypto_1.createHash)('sha256').update(identity, 'utf8').digest('hex')}`,
|
|
1359
|
+
...common,
|
|
1360
|
+
kind: 'grant',
|
|
1361
|
+
schemaKind: 'create',
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
function createUpdateGrantReference(artifact, context) {
|
|
1365
|
+
const common = {
|
|
1366
|
+
digest: artifact.digest,
|
|
1367
|
+
brand: context.publicContext.brand,
|
|
1368
|
+
portal: context.publicContext.portal,
|
|
1369
|
+
recordType: context.publicContext.recordType,
|
|
1370
|
+
operation: context.publicContext.operation,
|
|
1371
|
+
oid: context.resolution.oid,
|
|
1372
|
+
};
|
|
1373
|
+
const identity = (0, record_contract_1.serializeRedboxCanonicalJsonV1)({
|
|
1374
|
+
...common,
|
|
1375
|
+
kind: 'grant',
|
|
1376
|
+
schemaKind: 'update',
|
|
1377
|
+
});
|
|
1378
|
+
return Object.freeze({
|
|
1379
|
+
referenceKey: `grant:update:${(0, node_crypto_1.createHash)('sha256').update(identity, 'utf8').digest('hex')}`,
|
|
1380
|
+
...common,
|
|
1381
|
+
kind: 'grant',
|
|
1382
|
+
schemaKind: 'update',
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
function emptyDiagnostics() {
|
|
1386
|
+
return Object.freeze([]);
|
|
1387
|
+
}
|
|
1388
|
+
function emptyValidationIssues() {
|
|
1389
|
+
return Object.freeze([]);
|
|
1390
|
+
}
|
|
1391
|
+
var Services;
|
|
1392
|
+
(function (Services) {
|
|
1393
|
+
/** Performs record-schema lifecycle checks and caller-effective create/update/immutable resolution. */
|
|
1394
|
+
class RecordSchema extends CoreService_1.Services.Core.Service {
|
|
1395
|
+
_exportedMethods = [
|
|
1396
|
+
'init',
|
|
1397
|
+
'bootstrap',
|
|
1398
|
+
'resolveCreate',
|
|
1399
|
+
'resolveUpdate',
|
|
1400
|
+
'resolveImmutable',
|
|
1401
|
+
'describeStage',
|
|
1402
|
+
'validateResolvedArtifact',
|
|
1403
|
+
'persistSaveUsageReference',
|
|
1404
|
+
'materializeIntegrationPins',
|
|
1405
|
+
'bootstrapIntegrationPins',
|
|
1406
|
+
'reportRetention',
|
|
1407
|
+
];
|
|
1408
|
+
logHeader = 'RecordSchemaService::';
|
|
1409
|
+
dependencies;
|
|
1410
|
+
validatorCache = new Map();
|
|
1411
|
+
validatorCacheMaximum;
|
|
1412
|
+
constructor(overrides = {}) {
|
|
1413
|
+
super();
|
|
1414
|
+
this.dependencies = { ...DEFAULT_DEPENDENCIES, ...overrides };
|
|
1415
|
+
}
|
|
1416
|
+
safeLog(level, event, context, values = {}) {
|
|
1417
|
+
try {
|
|
1418
|
+
const logger = this.dependencies.telemetryLogger ?? this.logger;
|
|
1419
|
+
logger[level](event, Object.freeze({ event, context, ...values }));
|
|
1420
|
+
}
|
|
1421
|
+
catch {
|
|
1422
|
+
// Logging must never alter service results or startup failure ordering.
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
logUnexpected(context, error) {
|
|
1426
|
+
this.safeLog('error', 'record_schema_unexpected_failure', context, {
|
|
1427
|
+
error_type: safeErrorType(error),
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
clock() {
|
|
1431
|
+
try {
|
|
1432
|
+
const value = this.dependencies.clock();
|
|
1433
|
+
return Number.isFinite(value) ? value : 0;
|
|
1434
|
+
}
|
|
1435
|
+
catch {
|
|
1436
|
+
return 0;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
cachedValidator(digest, maximum) {
|
|
1440
|
+
if (this.validatorCacheMaximum !== maximum) {
|
|
1441
|
+
this.validatorCache.clear();
|
|
1442
|
+
this.validatorCacheMaximum = maximum;
|
|
1443
|
+
}
|
|
1444
|
+
const cached = this.validatorCache.get(digest);
|
|
1445
|
+
if (cached) {
|
|
1446
|
+
this.validatorCache.delete(digest);
|
|
1447
|
+
this.validatorCache.set(digest, cached);
|
|
1448
|
+
}
|
|
1449
|
+
return cached;
|
|
1450
|
+
}
|
|
1451
|
+
cacheValidator(artifact, maximum) {
|
|
1452
|
+
if (this.validatorCacheMaximum !== maximum) {
|
|
1453
|
+
this.validatorCache.clear();
|
|
1454
|
+
this.validatorCacheMaximum = maximum;
|
|
1455
|
+
}
|
|
1456
|
+
this.validatorCache.delete(artifact.digest);
|
|
1457
|
+
this.validatorCache.set(artifact.digest, artifact);
|
|
1458
|
+
if (this.validatorCache.size > maximum) {
|
|
1459
|
+
const oldest = this.validatorCache.keys().next();
|
|
1460
|
+
if (!oldest.done)
|
|
1461
|
+
this.validatorCache.delete(oldest.value);
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
observeResolver(schemaKind, result) {
|
|
1465
|
+
recordCounter(recordSchemaResolverOutcomes, {
|
|
1466
|
+
schema_kind: schemaKind,
|
|
1467
|
+
outcome: telemetryDimension(result.kind, RECORD_SCHEMA_RESOLVER_OUTCOMES, 'unexpected-failure'),
|
|
1468
|
+
});
|
|
1469
|
+
if (schemaKind !== 'unknown' && (result.kind === 'resolved' || result.kind === 'partial')) {
|
|
1470
|
+
recordCounter(recordSchemaCompleteness, {
|
|
1471
|
+
schema_kind: schemaKind,
|
|
1472
|
+
completeness: result.kind === 'partial' ? 'partial' : 'complete',
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
return result;
|
|
1476
|
+
}
|
|
1477
|
+
/** Resolve, compile, persist, and grant one caller-effective create schema. */
|
|
1478
|
+
async resolveCreate(request) {
|
|
1479
|
+
try {
|
|
1480
|
+
return this.observeResolver('create', await this.resolveCreateInternal(request));
|
|
1481
|
+
}
|
|
1482
|
+
catch (error) {
|
|
1483
|
+
this.logUnexpected('resolve-create', error);
|
|
1484
|
+
throw error;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
async resolveCreateInternal(request) {
|
|
1488
|
+
const config = this.resolveRuntimeConfig();
|
|
1489
|
+
if (!config) {
|
|
1490
|
+
return {
|
|
1491
|
+
kind: 'unavailable',
|
|
1492
|
+
stage: 'configuration',
|
|
1493
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
if (!config.enabled) {
|
|
1497
|
+
return {
|
|
1498
|
+
kind: 'unavailable',
|
|
1499
|
+
stage: 'configuration',
|
|
1500
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE,
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
let internalContext;
|
|
1504
|
+
try {
|
|
1505
|
+
const resolvedContext = await this.dependencies.resolveContractContext({
|
|
1506
|
+
kind: 'create',
|
|
1507
|
+
brand: request.brand,
|
|
1508
|
+
portal: request.portal,
|
|
1509
|
+
recordType: request.recordType,
|
|
1510
|
+
operation: request.operation,
|
|
1511
|
+
targetStep: request.targetStep,
|
|
1512
|
+
actor: callerActor(request.caller),
|
|
1513
|
+
});
|
|
1514
|
+
if (!isCreateContractContext(resolvedContext)) {
|
|
1515
|
+
return this.contextFailure('not-resolvable');
|
|
1516
|
+
}
|
|
1517
|
+
internalContext = resolvedContext;
|
|
1518
|
+
}
|
|
1519
|
+
catch (error) {
|
|
1520
|
+
if (error instanceof record_contract_1.RecordContractContextResolutionError) {
|
|
1521
|
+
return this.contextFailure(error.failureKind, error.diagnosticCodes);
|
|
1522
|
+
}
|
|
1523
|
+
this.logUnexpected('resolve-create-context', error);
|
|
1524
|
+
return this.contextFailure('unavailable');
|
|
1525
|
+
}
|
|
1526
|
+
let authorized = (0, internal_record_schema_authorization_1.isInternalRecordSchemaAuthorizationCapability)(request.internalAuthorizationCapability);
|
|
1527
|
+
if (!authorized) {
|
|
1528
|
+
try {
|
|
1529
|
+
authorized = await this.dependencies.authorizeCreate(internalContext, request.caller);
|
|
1530
|
+
}
|
|
1531
|
+
catch (error) {
|
|
1532
|
+
this.logUnexpected('resolve-create-authorization', error);
|
|
1533
|
+
return this.contextFailure('unavailable');
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
if (!authorized) {
|
|
1537
|
+
return this.contextFailure('forbidden');
|
|
1538
|
+
}
|
|
1539
|
+
const context = createContextWithPublicBrand(internalContext, publicBranding(request));
|
|
1540
|
+
const pipeline = await this.compileAndPersist(config, context, artifact => createGrantReference(artifact, context.publicContext));
|
|
1541
|
+
if (pipeline.kind !== 'resolved' && pipeline.kind !== 'partial') {
|
|
1542
|
+
return pipeline;
|
|
1543
|
+
}
|
|
1544
|
+
return resolvedPipelineResult(pipeline, 'create', context);
|
|
1545
|
+
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Read-only description of the metadata a record of `recordType` has at
|
|
1548
|
+
* `targetStep`, as seen by `caller`. Used as an authoring aid (for example
|
|
1549
|
+
* dashboard field pickers). Unlike {@link resolveCreate} it does not persist
|
|
1550
|
+
* an artifact or grant, and it does not require public schema resolution
|
|
1551
|
+
* to be enabled; it only needs a valid schema configuration.
|
|
1552
|
+
*/
|
|
1553
|
+
async describeStage(request) {
|
|
1554
|
+
const config = this.resolveRuntimeConfig();
|
|
1555
|
+
if (!config) {
|
|
1556
|
+
return { kind: 'unavailable', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID };
|
|
1557
|
+
}
|
|
1558
|
+
let internalContext;
|
|
1559
|
+
try {
|
|
1560
|
+
const resolvedContext = await this.dependencies.resolveContractContext({
|
|
1561
|
+
kind: 'create',
|
|
1562
|
+
brand: request.brand,
|
|
1563
|
+
portal: request.portal,
|
|
1564
|
+
recordType: request.recordType,
|
|
1565
|
+
targetStep: request.targetStep,
|
|
1566
|
+
actor: callerActor(request.caller),
|
|
1567
|
+
});
|
|
1568
|
+
if (!isCreateContractContext(resolvedContext)) {
|
|
1569
|
+
return { kind: 'unavailable', code: 'not-resolvable' };
|
|
1570
|
+
}
|
|
1571
|
+
internalContext = resolvedContext;
|
|
1572
|
+
}
|
|
1573
|
+
catch (error) {
|
|
1574
|
+
if (error instanceof record_contract_1.RecordContractContextResolutionError) {
|
|
1575
|
+
return { kind: 'unavailable', code: error.failureKind };
|
|
1576
|
+
}
|
|
1577
|
+
this.logUnexpected('resolve-create-context', error);
|
|
1578
|
+
return { kind: 'unavailable', code: 'unavailable' };
|
|
1579
|
+
}
|
|
1580
|
+
try {
|
|
1581
|
+
if (!(await this.dependencies.authorizeCreate(internalContext, request.caller))) {
|
|
1582
|
+
return { kind: 'unavailable', code: 'forbidden' };
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
catch (error) {
|
|
1586
|
+
this.logUnexpected('resolve-create-authorization', error);
|
|
1587
|
+
return { kind: 'unavailable', code: 'unavailable' };
|
|
1588
|
+
}
|
|
1589
|
+
const context = createContextWithPublicBrand(internalContext, publicBranding(request));
|
|
1590
|
+
const compilation = await this.compileContext(config, context);
|
|
1591
|
+
if (compilation.kind !== 'resolved' && compilation.kind !== 'partial') {
|
|
1592
|
+
return { kind: 'unavailable', code: 'code' in compilation ? String(compilation.code) : compilation.kind };
|
|
1593
|
+
}
|
|
1594
|
+
return { kind: compilation.kind, completeness: compilation.completeness, document: compilation.document };
|
|
1595
|
+
}
|
|
1596
|
+
/** Resolve, authorize, compile, persist, and grant one caller-effective update-delta schema. */
|
|
1597
|
+
async resolveUpdate(request) {
|
|
1598
|
+
try {
|
|
1599
|
+
return this.observeResolver('update', await this.resolveUpdateInternal(request));
|
|
1600
|
+
}
|
|
1601
|
+
catch (error) {
|
|
1602
|
+
this.logUnexpected('resolve-update', error);
|
|
1603
|
+
throw error;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
async resolveUpdateInternal(request) {
|
|
1607
|
+
const config = this.resolveRuntimeConfig();
|
|
1608
|
+
if (!config) {
|
|
1609
|
+
return {
|
|
1610
|
+
kind: 'unavailable',
|
|
1611
|
+
stage: 'configuration',
|
|
1612
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
if (!config.enabled) {
|
|
1616
|
+
return {
|
|
1617
|
+
kind: 'unavailable',
|
|
1618
|
+
stage: 'configuration',
|
|
1619
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE,
|
|
1620
|
+
};
|
|
1621
|
+
}
|
|
1622
|
+
let internalContext;
|
|
1623
|
+
try {
|
|
1624
|
+
const resolvedContext = await this.dependencies.resolveContractContext({
|
|
1625
|
+
kind: 'update',
|
|
1626
|
+
brand: request.brand,
|
|
1627
|
+
portal: request.portal,
|
|
1628
|
+
oid: request.oid,
|
|
1629
|
+
operation: request.operation,
|
|
1630
|
+
actor: callerActor(request.caller),
|
|
1631
|
+
});
|
|
1632
|
+
if (!isUpdateContractContext(resolvedContext)) {
|
|
1633
|
+
return this.contextFailure('not-resolvable');
|
|
1634
|
+
}
|
|
1635
|
+
internalContext = resolvedContext;
|
|
1636
|
+
}
|
|
1637
|
+
catch (error) {
|
|
1638
|
+
if (error instanceof record_contract_1.RecordContractContextResolutionError) {
|
|
1639
|
+
if (error.failureKind === 'not-found' && error.diagnosticCodes.length === 0) {
|
|
1640
|
+
return {
|
|
1641
|
+
kind: 'missing-oid',
|
|
1642
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.NOT_FOUND,
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
return this.contextFailure(error.failureKind, error.diagnosticCodes);
|
|
1646
|
+
}
|
|
1647
|
+
this.logUnexpected('resolve-update-context', error);
|
|
1648
|
+
return this.contextFailure('unavailable');
|
|
1649
|
+
}
|
|
1650
|
+
let authorized = (0, internal_record_schema_authorization_1.isInternalRecordSchemaAuthorizationCapability)(request.internalAuthorizationCapability);
|
|
1651
|
+
if (!authorized) {
|
|
1652
|
+
try {
|
|
1653
|
+
authorized = await this.dependencies.authorizeUpdate(internalContext, request.caller);
|
|
1654
|
+
}
|
|
1655
|
+
catch (error) {
|
|
1656
|
+
this.logUnexpected('resolve-update-authorization', error);
|
|
1657
|
+
return this.contextFailure('unavailable');
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
if (!authorized) {
|
|
1661
|
+
return {
|
|
1662
|
+
kind: 'denied',
|
|
1663
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.FORBIDDEN,
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
const context = updateContextWithPublicBrand(internalContext, publicBranding(request));
|
|
1667
|
+
const compilation = await this.compileContext(config, context, request.caller);
|
|
1668
|
+
if (compilation.kind !== 'resolved' && compilation.kind !== 'partial') {
|
|
1669
|
+
return compilation;
|
|
1670
|
+
}
|
|
1671
|
+
const ifMatch = (0, record_contract_1.parseRecordJsonSchemaEtag)(request.ifMatch);
|
|
1672
|
+
if (ifMatch.kind === 'invalid') {
|
|
1673
|
+
return Object.freeze({
|
|
1674
|
+
kind: 'invalid-precondition',
|
|
1675
|
+
condition: 'if-match',
|
|
1676
|
+
reason: ifMatch.reason,
|
|
1677
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_REQUEST,
|
|
1678
|
+
});
|
|
1679
|
+
}
|
|
1680
|
+
if (ifMatch.kind === 'parsed' && ifMatch.digest !== compilation.digest) {
|
|
1681
|
+
recordCounter(recordSchemaPreconditionMismatches, {
|
|
1682
|
+
schema_kind: 'update',
|
|
1683
|
+
condition: 'if-match',
|
|
1684
|
+
});
|
|
1685
|
+
return Object.freeze({
|
|
1686
|
+
kind: 'precondition-failed',
|
|
1687
|
+
condition: 'if-match',
|
|
1688
|
+
reason: 'mismatch',
|
|
1689
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.PRECONDITION_FAILED,
|
|
1690
|
+
});
|
|
1691
|
+
}
|
|
1692
|
+
const pipeline = await this.persistCompilation(compilation, artifact => createUpdateGrantReference(artifact, context));
|
|
1693
|
+
if (pipeline.kind !== 'resolved' && pipeline.kind !== 'partial') {
|
|
1694
|
+
return pipeline;
|
|
1695
|
+
}
|
|
1696
|
+
return resolvedPipelineResult(pipeline, 'update', context);
|
|
1697
|
+
}
|
|
1698
|
+
/** Retrieve one immutable artifact only after current equivalent authorization succeeds. */
|
|
1699
|
+
async resolveImmutable(request) {
|
|
1700
|
+
try {
|
|
1701
|
+
return this.observeResolver('unknown', await this.resolveImmutableInternal(request));
|
|
1702
|
+
}
|
|
1703
|
+
catch (error) {
|
|
1704
|
+
this.logUnexpected('resolve-immutable', error);
|
|
1705
|
+
throw error;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
async resolveImmutableInternal(request) {
|
|
1709
|
+
if (typeof request.digest !== 'string' || !DIGEST_PATTERN.test(request.digest)) {
|
|
1710
|
+
return invalidDigestResult(request);
|
|
1711
|
+
}
|
|
1712
|
+
const actor = callerActor(request.caller);
|
|
1713
|
+
const callerBrand = typeof request.caller.brand?.id === 'string' ? request.caller.brand.id.trim() : '';
|
|
1714
|
+
if (callerBrand !== request.brand || !actor.authenticated) {
|
|
1715
|
+
return immutableNotFoundResult(request);
|
|
1716
|
+
}
|
|
1717
|
+
const config = this.resolveRuntimeConfig();
|
|
1718
|
+
if (!config) {
|
|
1719
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID);
|
|
1720
|
+
}
|
|
1721
|
+
if (!config.enabled) {
|
|
1722
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE);
|
|
1723
|
+
}
|
|
1724
|
+
let storageValue;
|
|
1725
|
+
try {
|
|
1726
|
+
storageValue = this.dependencies.getStorageProvider();
|
|
1727
|
+
}
|
|
1728
|
+
catch (error) {
|
|
1729
|
+
this.logUnexpected('resolve-immutable-storage-provider', error);
|
|
1730
|
+
storageValue = undefined;
|
|
1731
|
+
}
|
|
1732
|
+
if (!isImmutableStorageProvider(storageValue)) {
|
|
1733
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE);
|
|
1734
|
+
}
|
|
1735
|
+
const storage = storageValue;
|
|
1736
|
+
let artifact;
|
|
1737
|
+
try {
|
|
1738
|
+
artifact = await storage.getRecordSchemaArtifact(request.digest);
|
|
1739
|
+
}
|
|
1740
|
+
catch (error) {
|
|
1741
|
+
this.logUnexpected('resolve-immutable-artifact-read', error);
|
|
1742
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE);
|
|
1743
|
+
}
|
|
1744
|
+
if (!artifact) {
|
|
1745
|
+
return immutableNotFoundResult(request);
|
|
1746
|
+
}
|
|
1747
|
+
if (!isObjectRecord(artifact) || ownDataProperty(artifact, 'digest') !== request.digest) {
|
|
1748
|
+
return immutableInvalidContractResult(request, 'unverified');
|
|
1749
|
+
}
|
|
1750
|
+
const authorizationQuery = immutableAuthorizationQuery(artifact, request);
|
|
1751
|
+
if (!authorizationQuery) {
|
|
1752
|
+
return immutableGrantInvalidContractResult(request);
|
|
1753
|
+
}
|
|
1754
|
+
let afterReferenceKey;
|
|
1755
|
+
let authorizedCompilation;
|
|
1756
|
+
// Each lookup is bounded and cursor-indexed; only null exhaustion is a conclusive denial.
|
|
1757
|
+
while (!authorizedCompilation) {
|
|
1758
|
+
let rawGrant;
|
|
1759
|
+
try {
|
|
1760
|
+
rawGrant = await storage.findRecordSchemaGrantForAuthorization(afterReferenceKey === undefined
|
|
1761
|
+
? authorizationQuery
|
|
1762
|
+
: Object.freeze({ ...authorizationQuery, afterReferenceKey }));
|
|
1763
|
+
}
|
|
1764
|
+
catch (error) {
|
|
1765
|
+
this.logUnexpected('resolve-immutable-grant-list', error);
|
|
1766
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE);
|
|
1767
|
+
}
|
|
1768
|
+
if (rawGrant === null) {
|
|
1769
|
+
return immutableNotFoundResult(request);
|
|
1770
|
+
}
|
|
1771
|
+
const parsedGrant = parseImmutableGrant(rawGrant, request);
|
|
1772
|
+
if (parsedGrant.kind !== 'grant' ||
|
|
1773
|
+
parsedGrant.grant.schemaKind !== authorizationQuery.schemaKind ||
|
|
1774
|
+
parsedGrant.grant.recordType !== authorizationQuery.recordType ||
|
|
1775
|
+
parsedGrant.grant.operation !== authorizationQuery.operation ||
|
|
1776
|
+
(afterReferenceKey !== undefined && compareText(parsedGrant.grant.referenceKey, afterReferenceKey) <= 0)) {
|
|
1777
|
+
this.safeLog('error', 'record_schema_unexpected_failure', 'resolve-immutable-grant-contract', {
|
|
1778
|
+
error_type: 'non-error',
|
|
1779
|
+
});
|
|
1780
|
+
return immutableGrantInvalidContractResult(request);
|
|
1781
|
+
}
|
|
1782
|
+
authorizedCompilation = await this.resolveImmutableGrant(config, artifact, parsedGrant.grant, request.caller, actor, request.brand);
|
|
1783
|
+
afterReferenceKey = parsedGrant.grant.referenceKey;
|
|
1784
|
+
}
|
|
1785
|
+
const immutableArtifact = verifiedImmutableArtifact(artifact, authorizedCompilation);
|
|
1786
|
+
if (!immutableArtifact) {
|
|
1787
|
+
return immutableInvalidContractResult(request, 'authorized');
|
|
1788
|
+
}
|
|
1789
|
+
const ifNoneMatch = (0, record_contract_1.parseRecordJsonSchemaEtag)(request.ifNoneMatch);
|
|
1790
|
+
if (ifNoneMatch.kind === 'invalid') {
|
|
1791
|
+
return invalidImmutableConditionalResult(request);
|
|
1792
|
+
}
|
|
1793
|
+
const notModified = ifNoneMatch.kind === 'parsed' && ifNoneMatch.digest === authorizedCompilation.digest;
|
|
1794
|
+
let touch;
|
|
1795
|
+
try {
|
|
1796
|
+
touch = await storage.touchRecordSchemaArtifact(request.digest);
|
|
1797
|
+
}
|
|
1798
|
+
catch (error) {
|
|
1799
|
+
this.logUnexpected('resolve-immutable-artifact-touch', error);
|
|
1800
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE);
|
|
1801
|
+
}
|
|
1802
|
+
if (!storageResponseSucceeded(touch)) {
|
|
1803
|
+
return immutableUnavailableResult(request, codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE);
|
|
1804
|
+
}
|
|
1805
|
+
return Object.freeze({
|
|
1806
|
+
kind: notModified ? 'not-modified' : 'resolved',
|
|
1807
|
+
artifact: immutableArtifact,
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
/** Validate raw input against an already resolved immutable artifact without exposing validator internals. */
|
|
1811
|
+
validateResolvedArtifact(request) {
|
|
1812
|
+
const parsed = parseResolvedSchemaValidationRequest(request);
|
|
1813
|
+
if (!parsed) {
|
|
1814
|
+
recordCounter(recordSchemaValidationResults, { schema_kind: 'unknown', result: 'invalid-input' });
|
|
1815
|
+
return Object.freeze({ kind: 'invalid-input', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_REQUEST });
|
|
1816
|
+
}
|
|
1817
|
+
const config = this.resolveRuntimeConfig();
|
|
1818
|
+
if (!config || !config.enabled) {
|
|
1819
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1820
|
+
schema_kind: parsed.schemaKind,
|
|
1821
|
+
result: 'unavailable',
|
|
1822
|
+
});
|
|
1823
|
+
return Object.freeze({
|
|
1824
|
+
kind: 'unavailable',
|
|
1825
|
+
code: config ? codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE : codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
let identity;
|
|
1829
|
+
try {
|
|
1830
|
+
identity = (0, record_contract_1.identifyRecordJsonSchema)(parsed.document, config.limits.maxDocumentBytes);
|
|
1831
|
+
}
|
|
1832
|
+
catch {
|
|
1833
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1834
|
+
schema_kind: parsed.schemaKind,
|
|
1835
|
+
result: 'unavailable',
|
|
1836
|
+
});
|
|
1837
|
+
recordCounter(recordSchemaValidationProblems, {
|
|
1838
|
+
schema_kind: parsed.schemaKind,
|
|
1839
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
1840
|
+
});
|
|
1841
|
+
return Object.freeze({ kind: 'unavailable', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT });
|
|
1842
|
+
}
|
|
1843
|
+
if (identity.digest !== parsed.digest) {
|
|
1844
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1845
|
+
schema_kind: parsed.schemaKind,
|
|
1846
|
+
result: 'unavailable',
|
|
1847
|
+
});
|
|
1848
|
+
recordCounter(recordSchemaValidationProblems, {
|
|
1849
|
+
schema_kind: parsed.schemaKind,
|
|
1850
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
1851
|
+
});
|
|
1852
|
+
return Object.freeze({ kind: 'unavailable', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT });
|
|
1853
|
+
}
|
|
1854
|
+
let cached = this.cachedValidator(parsed.digest, config.cacheMaxEntries);
|
|
1855
|
+
recordCounter(recordSchemaCacheResults, {
|
|
1856
|
+
schema_kind: parsed.schemaKind,
|
|
1857
|
+
result: cached ? 'hit' : 'miss',
|
|
1858
|
+
});
|
|
1859
|
+
if (!cached) {
|
|
1860
|
+
const startedAt = this.clock();
|
|
1861
|
+
try {
|
|
1862
|
+
const artifact = (0, record_contract_1.compileRecordJsonSchemaArtifact)(identity.document, {
|
|
1863
|
+
maxDocumentBytes: config.limits.maxDocumentBytes,
|
|
1864
|
+
maxValidationErrors: config.limits.maxDiagnostics,
|
|
1865
|
+
});
|
|
1866
|
+
this.cacheValidator(artifact, config.cacheMaxEntries);
|
|
1867
|
+
cached = artifact;
|
|
1868
|
+
recordDuration(this.clock() - startedAt, {
|
|
1869
|
+
schema_kind: parsed.schemaKind,
|
|
1870
|
+
phase: 'validation',
|
|
1871
|
+
outcome: 'resolved',
|
|
1872
|
+
});
|
|
1873
|
+
recordCounter(recordSchemaCompileOutcomes, {
|
|
1874
|
+
schema_kind: parsed.schemaKind,
|
|
1875
|
+
phase: 'validation',
|
|
1876
|
+
outcome: 'resolved',
|
|
1877
|
+
});
|
|
1878
|
+
}
|
|
1879
|
+
catch (error) {
|
|
1880
|
+
this.logUnexpected('validation-compile', error);
|
|
1881
|
+
recordDuration(this.clock() - startedAt, {
|
|
1882
|
+
schema_kind: parsed.schemaKind,
|
|
1883
|
+
phase: 'validation',
|
|
1884
|
+
outcome: 'failed',
|
|
1885
|
+
});
|
|
1886
|
+
recordCounter(recordSchemaCompileOutcomes, {
|
|
1887
|
+
schema_kind: parsed.schemaKind,
|
|
1888
|
+
phase: 'validation',
|
|
1889
|
+
outcome: 'failed',
|
|
1890
|
+
});
|
|
1891
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1892
|
+
schema_kind: parsed.schemaKind,
|
|
1893
|
+
result: 'unavailable',
|
|
1894
|
+
});
|
|
1895
|
+
return Object.freeze({ kind: 'unavailable', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT });
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
if (!cached) {
|
|
1899
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1900
|
+
schema_kind: parsed.schemaKind,
|
|
1901
|
+
result: 'unavailable',
|
|
1902
|
+
});
|
|
1903
|
+
return Object.freeze({ kind: 'unavailable', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT });
|
|
1904
|
+
}
|
|
1905
|
+
let validation;
|
|
1906
|
+
try {
|
|
1907
|
+
validation = cached.validator.validate(parsed.input);
|
|
1908
|
+
}
|
|
1909
|
+
catch (error) {
|
|
1910
|
+
this.logUnexpected('validation-run', error);
|
|
1911
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1912
|
+
schema_kind: parsed.schemaKind,
|
|
1913
|
+
result: 'unavailable',
|
|
1914
|
+
});
|
|
1915
|
+
return Object.freeze({ kind: 'unavailable', code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT });
|
|
1916
|
+
}
|
|
1917
|
+
recordCounter(recordSchemaValidationResults, {
|
|
1918
|
+
schema_kind: parsed.schemaKind,
|
|
1919
|
+
result: validation.valid ? 'valid' : 'invalid',
|
|
1920
|
+
});
|
|
1921
|
+
if (!validation.valid) {
|
|
1922
|
+
for (const code of new Set(validation.issues.map(issue => telemetryCode(issue.code)))) {
|
|
1923
|
+
recordCounter(recordSchemaValidationProblems, { schema_kind: parsed.schemaKind, code });
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
return Object.freeze({ kind: 'validated', ...validation });
|
|
1927
|
+
}
|
|
1928
|
+
/** Persist or refresh one post-save usage reference without changing the normal record-save path. */
|
|
1929
|
+
async persistSaveUsageReference(request) {
|
|
1930
|
+
let result;
|
|
1931
|
+
try {
|
|
1932
|
+
result = await this.persistSaveUsageReferenceInternal(request);
|
|
1933
|
+
}
|
|
1934
|
+
catch (error) {
|
|
1935
|
+
this.logUnexpected('save-reference', error);
|
|
1936
|
+
result = Object.freeze({
|
|
1937
|
+
kind: 'unavailable',
|
|
1938
|
+
stage: 'storage',
|
|
1939
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
1940
|
+
});
|
|
1941
|
+
}
|
|
1942
|
+
recordCounter(recordSchemaUsageReferences, {
|
|
1943
|
+
reference_kind: 'save',
|
|
1944
|
+
outcome: telemetryDimension(result.kind, RECORD_SCHEMA_USAGE_REFERENCE_OUTCOMES, 'unavailable'),
|
|
1945
|
+
code: telemetryCode('code' in result ? result.code : undefined),
|
|
1946
|
+
});
|
|
1947
|
+
return result;
|
|
1948
|
+
}
|
|
1949
|
+
async persistSaveUsageReferenceInternal(request) {
|
|
1950
|
+
const parsed = parseSaveUsageRequest(request);
|
|
1951
|
+
if (!parsed) {
|
|
1952
|
+
return Object.freeze({
|
|
1953
|
+
kind: 'invalid-input',
|
|
1954
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_REQUEST,
|
|
1955
|
+
});
|
|
1956
|
+
}
|
|
1957
|
+
const config = this.resolveRuntimeConfig();
|
|
1958
|
+
if (!config) {
|
|
1959
|
+
return Object.freeze({
|
|
1960
|
+
kind: 'unavailable',
|
|
1961
|
+
stage: 'configuration',
|
|
1962
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
if (!config.enabled) {
|
|
1966
|
+
return Object.freeze({
|
|
1967
|
+
kind: 'disabled',
|
|
1968
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE,
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
let storageValue;
|
|
1972
|
+
try {
|
|
1973
|
+
storageValue = this.dependencies.getStorageProvider();
|
|
1974
|
+
}
|
|
1975
|
+
catch (error) {
|
|
1976
|
+
this.logUnexpected('save-reference-storage-provider', error);
|
|
1977
|
+
storageValue = undefined;
|
|
1978
|
+
}
|
|
1979
|
+
if (!isReferenceStorageProvider(storageValue)) {
|
|
1980
|
+
return Object.freeze({
|
|
1981
|
+
kind: 'unavailable',
|
|
1982
|
+
stage: 'storage',
|
|
1983
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
1984
|
+
});
|
|
1985
|
+
}
|
|
1986
|
+
const reference = createSaveReference(parsed);
|
|
1987
|
+
const identity = Object.freeze({ digest: reference.digest, referenceKey: reference.referenceKey });
|
|
1988
|
+
let response;
|
|
1989
|
+
try {
|
|
1990
|
+
response = await storageValue.putRecordSchemaReference(reference);
|
|
1991
|
+
}
|
|
1992
|
+
catch (error) {
|
|
1993
|
+
this.logUnexpected('save-reference-storage', error);
|
|
1994
|
+
return Object.freeze({
|
|
1995
|
+
kind: 'write-failed',
|
|
1996
|
+
stage: 'save-reference',
|
|
1997
|
+
...referenceWriteFailure(),
|
|
1998
|
+
reference: identity,
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
if (!storageResponseSucceeded(response)) {
|
|
2002
|
+
return Object.freeze({
|
|
2003
|
+
kind: 'write-failed',
|
|
2004
|
+
stage: 'save-reference',
|
|
2005
|
+
...referenceWriteFailure(response),
|
|
2006
|
+
reference: identity,
|
|
2007
|
+
});
|
|
2008
|
+
}
|
|
2009
|
+
return Object.freeze({ kind: 'recorded', reference: identity });
|
|
2010
|
+
}
|
|
2011
|
+
/** Idempotently materialize the allowlisted fields of configured integration pins. */
|
|
2012
|
+
async materializeIntegrationPins() {
|
|
2013
|
+
let result;
|
|
2014
|
+
try {
|
|
2015
|
+
result = await this.materializeIntegrationPinsInternal();
|
|
2016
|
+
}
|
|
2017
|
+
catch (error) {
|
|
2018
|
+
this.logUnexpected('integration-pin-maintenance', error);
|
|
2019
|
+
result = Object.freeze({
|
|
2020
|
+
kind: 'unavailable',
|
|
2021
|
+
stage: 'storage',
|
|
2022
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2023
|
+
});
|
|
2024
|
+
}
|
|
2025
|
+
if (result.kind === 'materialized' || result.kind === 'failed') {
|
|
2026
|
+
for (const pin of result.pins) {
|
|
2027
|
+
recordCounter(recordSchemaUsageReferences, {
|
|
2028
|
+
reference_kind: 'pin',
|
|
2029
|
+
outcome: telemetryDimension(pin.status, RECORD_SCHEMA_USAGE_REFERENCE_OUTCOMES, 'unavailable'),
|
|
2030
|
+
code: telemetryCode(pin.status === 'write-failed' ? pin.code : undefined),
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
else {
|
|
2035
|
+
recordCounter(recordSchemaUsageReferences, {
|
|
2036
|
+
reference_kind: 'pin',
|
|
2037
|
+
outcome: telemetryDimension(result.kind, RECORD_SCHEMA_USAGE_REFERENCE_OUTCOMES, 'unavailable'),
|
|
2038
|
+
code: telemetryCode(result.code),
|
|
2039
|
+
});
|
|
2040
|
+
}
|
|
2041
|
+
return result;
|
|
2042
|
+
}
|
|
2043
|
+
async materializeIntegrationPinsInternal() {
|
|
2044
|
+
let rawConfig;
|
|
2045
|
+
try {
|
|
2046
|
+
rawConfig = this.dependencies.getConfig();
|
|
2047
|
+
}
|
|
2048
|
+
catch {
|
|
2049
|
+
return Object.freeze({
|
|
2050
|
+
kind: 'unavailable',
|
|
2051
|
+
stage: 'configuration',
|
|
2052
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
let validation;
|
|
2056
|
+
try {
|
|
2057
|
+
validation = (0, recordSchema_config_1.validateRecordSchemaConfig)(rawConfig);
|
|
2058
|
+
}
|
|
2059
|
+
catch {
|
|
2060
|
+
return Object.freeze({
|
|
2061
|
+
kind: 'unavailable',
|
|
2062
|
+
stage: 'configuration',
|
|
2063
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2066
|
+
if (!validation.valid) {
|
|
2067
|
+
const capped = validation.problems.some(problem => problem.path === 'recordSchema.integrationPins' && problem.reason === 'maximum-items');
|
|
2068
|
+
return capped
|
|
2069
|
+
? Object.freeze({
|
|
2070
|
+
kind: 'limit-exceeded',
|
|
2071
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED,
|
|
2072
|
+
maximum: recordSchema_config_1.MAX_RECORD_SCHEMA_INTEGRATION_PINS,
|
|
2073
|
+
})
|
|
2074
|
+
: Object.freeze({
|
|
2075
|
+
kind: 'unavailable',
|
|
2076
|
+
stage: 'configuration',
|
|
2077
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
let findings;
|
|
2081
|
+
try {
|
|
2082
|
+
findings = configuredFindings(rawConfig);
|
|
2083
|
+
}
|
|
2084
|
+
catch {
|
|
2085
|
+
return Object.freeze({
|
|
2086
|
+
kind: 'unavailable',
|
|
2087
|
+
stage: 'configuration',
|
|
2088
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2089
|
+
});
|
|
2090
|
+
}
|
|
2091
|
+
if (findings.length > 0) {
|
|
2092
|
+
return Object.freeze({
|
|
2093
|
+
kind: 'unavailable',
|
|
2094
|
+
stage: 'configuration',
|
|
2095
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2096
|
+
});
|
|
2097
|
+
}
|
|
2098
|
+
if (!validation.config.enabled) {
|
|
2099
|
+
return Object.freeze({
|
|
2100
|
+
kind: 'disabled',
|
|
2101
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE,
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
let storageValue;
|
|
2105
|
+
try {
|
|
2106
|
+
storageValue = this.dependencies.getStorageProvider();
|
|
2107
|
+
}
|
|
2108
|
+
catch (error) {
|
|
2109
|
+
this.logUnexpected('integration-pin-storage-provider', error);
|
|
2110
|
+
storageValue = undefined;
|
|
2111
|
+
}
|
|
2112
|
+
if (!isReferenceStorageProvider(storageValue)) {
|
|
2113
|
+
return Object.freeze({
|
|
2114
|
+
kind: 'unavailable',
|
|
2115
|
+
stage: 'storage',
|
|
2116
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
let references;
|
|
2120
|
+
try {
|
|
2121
|
+
references = configuredPinReferences(validation.config);
|
|
2122
|
+
}
|
|
2123
|
+
catch {
|
|
2124
|
+
return Object.freeze({
|
|
2125
|
+
kind: 'unavailable',
|
|
2126
|
+
stage: 'configuration',
|
|
2127
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
const pins = [];
|
|
2131
|
+
let failed = false;
|
|
2132
|
+
for (const reference of references) {
|
|
2133
|
+
let response;
|
|
2134
|
+
try {
|
|
2135
|
+
response = await storageValue.putRecordSchemaReference(reference);
|
|
2136
|
+
}
|
|
2137
|
+
catch (error) {
|
|
2138
|
+
this.logUnexpected('integration-pin-write', error);
|
|
2139
|
+
response = undefined;
|
|
2140
|
+
}
|
|
2141
|
+
if (storageResponseSucceeded(response)) {
|
|
2142
|
+
pins.push(Object.freeze({ digest: reference.digest, referenceKey: reference.referenceKey, status: 'materialized' }));
|
|
2143
|
+
}
|
|
2144
|
+
else {
|
|
2145
|
+
failed = true;
|
|
2146
|
+
pins.push(Object.freeze({
|
|
2147
|
+
digest: reference.digest,
|
|
2148
|
+
referenceKey: reference.referenceKey,
|
|
2149
|
+
status: 'write-failed',
|
|
2150
|
+
...referenceWriteFailure(response),
|
|
2151
|
+
}));
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
const immutablePins = Object.freeze(pins);
|
|
2155
|
+
return failed
|
|
2156
|
+
? Object.freeze({
|
|
2157
|
+
kind: 'failed',
|
|
2158
|
+
pins: immutablePins,
|
|
2159
|
+
})
|
|
2160
|
+
: Object.freeze({ kind: 'materialized', pins: immutablePins });
|
|
2161
|
+
}
|
|
2162
|
+
/** Awaited during core bootstrap so configured pins exist before application readiness. */
|
|
2163
|
+
async bootstrapIntegrationPins() {
|
|
2164
|
+
let result;
|
|
2165
|
+
try {
|
|
2166
|
+
result = await this.materializeIntegrationPins();
|
|
2167
|
+
}
|
|
2168
|
+
catch (error) {
|
|
2169
|
+
this.logUnexpected('integration-pin-startup', error);
|
|
2170
|
+
this.safeLog('info', 'record_schema_startup_check', 'integration-pins', { status: 'failed' });
|
|
2171
|
+
throw error;
|
|
2172
|
+
}
|
|
2173
|
+
if (result.kind === 'materialized' || result.kind === 'disabled') {
|
|
2174
|
+
this.safeLog('info', 'record_schema_startup_check', 'integration-pins', {
|
|
2175
|
+
status: result.kind === 'disabled' ? 'disabled' : 'passed',
|
|
2176
|
+
});
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2179
|
+
this.safeLog('info', 'record_schema_startup_check', 'integration-pins', { status: 'failed' });
|
|
2180
|
+
const codes = result.kind === 'failed'
|
|
2181
|
+
? result.pins
|
|
2182
|
+
.filter((pin) => pin.status === 'write-failed')
|
|
2183
|
+
.map(pin => pin.code)
|
|
2184
|
+
.sort(compareText)
|
|
2185
|
+
: [result.code];
|
|
2186
|
+
throw new Error(`Configured record schema integration pins were not materialized (${codes.join(',')}).`);
|
|
2187
|
+
}
|
|
2188
|
+
/** Produce a deterministic, non-destructive retention dry run for a bounded candidate digest set. */
|
|
2189
|
+
async reportRetention(request) {
|
|
2190
|
+
const parsed = parseRetentionReportRequest(request);
|
|
2191
|
+
if (!parsed.ok) {
|
|
2192
|
+
return Object.freeze({
|
|
2193
|
+
kind: 'invalid-input',
|
|
2194
|
+
reason: parsed.reason,
|
|
2195
|
+
code: parsed.reason === 'limit'
|
|
2196
|
+
? codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED
|
|
2197
|
+
: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_REQUEST,
|
|
2198
|
+
});
|
|
2199
|
+
}
|
|
2200
|
+
const config = this.resolveRuntimeConfig();
|
|
2201
|
+
if (!config) {
|
|
2202
|
+
return Object.freeze({
|
|
2203
|
+
kind: 'unavailable',
|
|
2204
|
+
stage: 'configuration',
|
|
2205
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.CONFIG_INVALID,
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
if (!config.enabled) {
|
|
2209
|
+
return Object.freeze({
|
|
2210
|
+
kind: 'disabled',
|
|
2211
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE,
|
|
2212
|
+
});
|
|
2213
|
+
}
|
|
2214
|
+
let storageValue;
|
|
2215
|
+
try {
|
|
2216
|
+
storageValue = this.dependencies.getStorageProvider();
|
|
2217
|
+
}
|
|
2218
|
+
catch (error) {
|
|
2219
|
+
this.logUnexpected('retention-storage-provider', error);
|
|
2220
|
+
storageValue = undefined;
|
|
2221
|
+
}
|
|
2222
|
+
let storage;
|
|
2223
|
+
if (parsed.request.kind === 'targeted') {
|
|
2224
|
+
if (!isTargetedRetentionStorageProvider(storageValue)) {
|
|
2225
|
+
return Object.freeze({
|
|
2226
|
+
kind: 'unavailable',
|
|
2227
|
+
stage: 'storage',
|
|
2228
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2229
|
+
});
|
|
2230
|
+
}
|
|
2231
|
+
storage = storageValue;
|
|
2232
|
+
}
|
|
2233
|
+
else {
|
|
2234
|
+
if (!isPagedRetentionStorageProvider(storageValue)) {
|
|
2235
|
+
return Object.freeze({
|
|
2236
|
+
kind: 'unavailable',
|
|
2237
|
+
stage: 'storage',
|
|
2238
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2239
|
+
});
|
|
2240
|
+
}
|
|
2241
|
+
storage = storageValue;
|
|
2242
|
+
}
|
|
2243
|
+
const artifacts = [];
|
|
2244
|
+
const missingDigests = [];
|
|
2245
|
+
let page;
|
|
2246
|
+
if (parsed.request.kind === 'targeted') {
|
|
2247
|
+
for (const digest of parsed.request.digests) {
|
|
2248
|
+
let artifact;
|
|
2249
|
+
try {
|
|
2250
|
+
artifact = await storage.getRecordSchemaArtifact?.(digest);
|
|
2251
|
+
}
|
|
2252
|
+
catch (error) {
|
|
2253
|
+
this.logUnexpected('retention-artifact-read', error);
|
|
2254
|
+
return Object.freeze({
|
|
2255
|
+
kind: 'unavailable',
|
|
2256
|
+
stage: 'storage',
|
|
2257
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2258
|
+
});
|
|
2259
|
+
}
|
|
2260
|
+
if (artifact === null) {
|
|
2261
|
+
missingDigests.push(digest);
|
|
2262
|
+
continue;
|
|
2263
|
+
}
|
|
2264
|
+
const summary = retentionArtifactSummary(artifact, digest);
|
|
2265
|
+
if (!summary) {
|
|
2266
|
+
return Object.freeze({
|
|
2267
|
+
kind: 'invalid-state',
|
|
2268
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2269
|
+
});
|
|
2270
|
+
}
|
|
2271
|
+
artifacts.push(summary);
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
else {
|
|
2275
|
+
let listedArtifacts;
|
|
2276
|
+
try {
|
|
2277
|
+
listedArtifacts = await storage.listRecordSchemaArtifacts?.({
|
|
2278
|
+
...(parsed.request.cursor ? { afterDigest: parsed.request.cursor } : {}),
|
|
2279
|
+
limit: parsed.request.limit + 1,
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
catch (error) {
|
|
2283
|
+
this.logUnexpected('retention-artifact-list', error);
|
|
2284
|
+
return Object.freeze({
|
|
2285
|
+
kind: 'unavailable',
|
|
2286
|
+
stage: 'storage',
|
|
2287
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
const boundedArtifacts = boundedArraySnapshot(listedArtifacts, parsed.request.limit + 1);
|
|
2291
|
+
if (boundedArtifacts.kind === 'invalid') {
|
|
2292
|
+
return Object.freeze({
|
|
2293
|
+
kind: 'invalid-state',
|
|
2294
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
if (boundedArtifacts.kind === 'overflow') {
|
|
2298
|
+
return Object.freeze({
|
|
2299
|
+
kind: 'limit-exceeded',
|
|
2300
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED,
|
|
2301
|
+
scope: 'artifact-page',
|
|
2302
|
+
});
|
|
2303
|
+
}
|
|
2304
|
+
let previousDigest = parsed.request.cursor;
|
|
2305
|
+
for (const artifact of boundedArtifacts.values) {
|
|
2306
|
+
const summary = retentionArtifactSummary(artifact);
|
|
2307
|
+
if (!summary || (previousDigest !== undefined && compareText(summary.digest, previousDigest) <= 0)) {
|
|
2308
|
+
return Object.freeze({
|
|
2309
|
+
kind: 'invalid-state',
|
|
2310
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2311
|
+
});
|
|
2312
|
+
}
|
|
2313
|
+
artifacts.push(summary);
|
|
2314
|
+
previousDigest = summary.digest;
|
|
2315
|
+
}
|
|
2316
|
+
const hasMore = artifacts.length > parsed.request.limit;
|
|
2317
|
+
if (hasMore)
|
|
2318
|
+
artifacts.pop();
|
|
2319
|
+
page = Object.freeze({
|
|
2320
|
+
limit: parsed.request.limit,
|
|
2321
|
+
...(hasMore && artifacts.length > 0 ? { nextCursor: artifacts[artifacts.length - 1].digest } : {}),
|
|
2322
|
+
});
|
|
2323
|
+
}
|
|
2324
|
+
const entries = [];
|
|
2325
|
+
for (const artifact of artifacts) {
|
|
2326
|
+
const digest = artifact.digest;
|
|
2327
|
+
let references;
|
|
2328
|
+
try {
|
|
2329
|
+
references = await storage.listRecordSchemaReferences({
|
|
2330
|
+
digest,
|
|
2331
|
+
includeExpiredPins: true,
|
|
2332
|
+
limit: RECORD_SCHEMA_RETENTION_REFERENCE_LIMIT,
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
catch (error) {
|
|
2336
|
+
this.logUnexpected('retention-reference-read', error);
|
|
2337
|
+
return Object.freeze({
|
|
2338
|
+
kind: 'unavailable',
|
|
2339
|
+
stage: 'storage',
|
|
2340
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2341
|
+
});
|
|
2342
|
+
}
|
|
2343
|
+
const boundedReferences = boundedArraySnapshot(references, RECORD_SCHEMA_RETENTION_REFERENCE_LIMIT);
|
|
2344
|
+
if (boundedReferences.kind === 'invalid') {
|
|
2345
|
+
return Object.freeze({
|
|
2346
|
+
kind: 'invalid-state',
|
|
2347
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
if (boundedReferences.kind === 'overflow') {
|
|
2351
|
+
return Object.freeze({
|
|
2352
|
+
kind: 'limit-exceeded',
|
|
2353
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED,
|
|
2354
|
+
digest,
|
|
2355
|
+
});
|
|
2356
|
+
}
|
|
2357
|
+
const referenceCount = boundedReferences.values.length;
|
|
2358
|
+
if (referenceCount === RECORD_SCHEMA_RETENTION_REFERENCE_LIMIT) {
|
|
2359
|
+
const lastReference = boundedReferences.values[boundedReferences.values.length - 1];
|
|
2360
|
+
const afterReferenceKey = isObjectRecord(lastReference)
|
|
2361
|
+
? boundedNormalizedText(lastReference, 'referenceKey')
|
|
2362
|
+
: undefined;
|
|
2363
|
+
if (!afterReferenceKey || !RECORD_SCHEMA_REFERENCE_KEY_PATTERN.test(afterReferenceKey)) {
|
|
2364
|
+
return Object.freeze({
|
|
2365
|
+
kind: 'invalid-state',
|
|
2366
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
let overflow;
|
|
2370
|
+
try {
|
|
2371
|
+
overflow = await storage.listRecordSchemaReferences({
|
|
2372
|
+
digest,
|
|
2373
|
+
includeExpiredPins: true,
|
|
2374
|
+
limit: 1,
|
|
2375
|
+
afterReferenceKey,
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
catch (error) {
|
|
2379
|
+
this.logUnexpected('retention-reference-overflow-read', error);
|
|
2380
|
+
return Object.freeze({
|
|
2381
|
+
kind: 'unavailable',
|
|
2382
|
+
stage: 'storage',
|
|
2383
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2384
|
+
});
|
|
2385
|
+
}
|
|
2386
|
+
const boundedOverflow = boundedArraySnapshot(overflow, 0);
|
|
2387
|
+
if (boundedOverflow.kind === 'invalid') {
|
|
2388
|
+
return Object.freeze({
|
|
2389
|
+
kind: 'invalid-state',
|
|
2390
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2393
|
+
if (boundedOverflow.kind === 'overflow') {
|
|
2394
|
+
return Object.freeze({
|
|
2395
|
+
kind: 'limit-exceeded',
|
|
2396
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED,
|
|
2397
|
+
digest,
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
const entry = retentionEntry(artifact, boundedReferences.values, digest, parsed.request.now, config.retention.minimumAgeDays);
|
|
2402
|
+
if (!entry) {
|
|
2403
|
+
return Object.freeze({
|
|
2404
|
+
kind: 'invalid-state',
|
|
2405
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2406
|
+
});
|
|
2407
|
+
}
|
|
2408
|
+
entries.push(entry);
|
|
2409
|
+
}
|
|
2410
|
+
return Object.freeze({
|
|
2411
|
+
kind: 'reported',
|
|
2412
|
+
now: new Date(parsed.request.now.getTime()),
|
|
2413
|
+
minimumAgeDays: config.retention.minimumAgeDays,
|
|
2414
|
+
entries: Object.freeze(entries),
|
|
2415
|
+
missingDigests: Object.freeze(missingDigests),
|
|
2416
|
+
...(page ? { page } : {}),
|
|
2417
|
+
});
|
|
2418
|
+
}
|
|
2419
|
+
async resolveImmutableGrant(config, artifact, grant, caller, actor, internalBrand) {
|
|
2420
|
+
let internalContext;
|
|
2421
|
+
try {
|
|
2422
|
+
internalContext = await this.dependencies.resolveContractContext(grant.schemaKind === 'create'
|
|
2423
|
+
? {
|
|
2424
|
+
kind: 'create',
|
|
2425
|
+
brand: internalBrand,
|
|
2426
|
+
portal: grant.portal,
|
|
2427
|
+
recordType: grant.recordType,
|
|
2428
|
+
operation: immutableGrantOperation(grant.operation),
|
|
2429
|
+
targetStep: immutableCreateTargetStep(artifact),
|
|
2430
|
+
actor,
|
|
2431
|
+
}
|
|
2432
|
+
: {
|
|
2433
|
+
kind: 'update',
|
|
2434
|
+
brand: internalBrand,
|
|
2435
|
+
portal: grant.portal,
|
|
2436
|
+
oid: grant.oid,
|
|
2437
|
+
operation: immutableGrantOperation(grant.operation),
|
|
2438
|
+
actor,
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
catch {
|
|
2442
|
+
return undefined;
|
|
2443
|
+
}
|
|
2444
|
+
let context;
|
|
2445
|
+
if (grant.schemaKind === 'create') {
|
|
2446
|
+
if (!isCreateContractContext(internalContext))
|
|
2447
|
+
return undefined;
|
|
2448
|
+
context = createContextWithPublicBrand(internalContext, grant.brand);
|
|
2449
|
+
}
|
|
2450
|
+
else {
|
|
2451
|
+
if (!isUpdateContractContext(internalContext))
|
|
2452
|
+
return undefined;
|
|
2453
|
+
context = updateContextWithPublicBrand(internalContext, grant.brand);
|
|
2454
|
+
}
|
|
2455
|
+
if (context.publicContext.kind !== grant.schemaKind ||
|
|
2456
|
+
context.publicContext.brand !== grant.brand ||
|
|
2457
|
+
context.publicContext.portal !== grant.portal ||
|
|
2458
|
+
context.publicContext.recordType !== grant.recordType ||
|
|
2459
|
+
context.publicContext.operation !== grant.operation) {
|
|
2460
|
+
return undefined;
|
|
2461
|
+
}
|
|
2462
|
+
let recordAccessContext;
|
|
2463
|
+
if (grant.schemaKind === 'create') {
|
|
2464
|
+
if (!isCreateContractContext(context) || !isCreateContractContext(internalContext)) {
|
|
2465
|
+
return undefined;
|
|
2466
|
+
}
|
|
2467
|
+
try {
|
|
2468
|
+
if (!(await this.dependencies.authorizeCreate(internalContext, caller))) {
|
|
2469
|
+
return undefined;
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
catch {
|
|
2473
|
+
return undefined;
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
else {
|
|
2477
|
+
if (!isUpdateContractContext(context) ||
|
|
2478
|
+
!isUpdateContractContext(internalContext) ||
|
|
2479
|
+
context.resolution.oid !== grant.oid) {
|
|
2480
|
+
return undefined;
|
|
2481
|
+
}
|
|
2482
|
+
try {
|
|
2483
|
+
if (!(await this.dependencies.authorizeUpdate(internalContext, caller))) {
|
|
2484
|
+
return undefined;
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
catch {
|
|
2488
|
+
return undefined;
|
|
2489
|
+
}
|
|
2490
|
+
recordAccessContext = caller;
|
|
2491
|
+
}
|
|
2492
|
+
const compilation = await this.compileContext(config, context, recordAccessContext);
|
|
2493
|
+
return (compilation.kind === 'resolved' || compilation.kind === 'partial') && compilation.digest === grant.digest
|
|
2494
|
+
? compilation
|
|
2495
|
+
: undefined;
|
|
2496
|
+
}
|
|
2497
|
+
async compileContext(config, context, recordAccessContext) {
|
|
2498
|
+
const schemaKind = metricKind(context.publicContext.kind);
|
|
2499
|
+
const startedAt = this.clock();
|
|
2500
|
+
try {
|
|
2501
|
+
const result = await this.compileContextUnobserved(config, context, recordAccessContext);
|
|
2502
|
+
const outcome = telemetryDimension(result.kind === 'resolved' || result.kind === 'partial' ? 'resolved' : result.kind, RECORD_SCHEMA_COMPILE_OUTCOMES, 'unexpected-failure');
|
|
2503
|
+
const attributes = { schema_kind: schemaKind, phase: 'resolution', outcome };
|
|
2504
|
+
recordDuration(this.clock() - startedAt, attributes);
|
|
2505
|
+
recordCounter(recordSchemaCompileOutcomes, attributes);
|
|
2506
|
+
return result;
|
|
2507
|
+
}
|
|
2508
|
+
catch (error) {
|
|
2509
|
+
this.logUnexpected('compile', error);
|
|
2510
|
+
const attributes = { schema_kind: schemaKind, phase: 'resolution', outcome: 'unexpected-failure' };
|
|
2511
|
+
recordDuration(this.clock() - startedAt, attributes);
|
|
2512
|
+
recordCounter(recordSchemaCompileOutcomes, attributes);
|
|
2513
|
+
throw error;
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
async compileContextUnobserved(config, context, recordAccessContext) {
|
|
2517
|
+
let formBuild;
|
|
2518
|
+
try {
|
|
2519
|
+
formBuild = await this.dependencies.buildContractFormConfig(context, recordAccessContext);
|
|
2520
|
+
}
|
|
2521
|
+
catch (error) {
|
|
2522
|
+
this.logUnexpected('compile-form-build', error);
|
|
2523
|
+
return this.contextFailure('not-resolvable');
|
|
2524
|
+
}
|
|
2525
|
+
if (!formBuild.ok) {
|
|
2526
|
+
return this.contextFailure('not-resolvable', [], formBuild.reason);
|
|
2527
|
+
}
|
|
2528
|
+
let registry;
|
|
2529
|
+
try {
|
|
2530
|
+
registry = this.dependencies.getContributorRegistry();
|
|
2531
|
+
}
|
|
2532
|
+
catch (error) {
|
|
2533
|
+
this.logUnexpected('compile-contributors', error);
|
|
2534
|
+
registry = undefined;
|
|
2535
|
+
}
|
|
2536
|
+
if (!registry) {
|
|
2537
|
+
return {
|
|
2538
|
+
kind: 'unavailable',
|
|
2539
|
+
stage: 'contributors',
|
|
2540
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.UNAVAILABLE,
|
|
2541
|
+
};
|
|
2542
|
+
}
|
|
2543
|
+
const compiler = new record_contract_1.RecordContractCompiler(registry, config.limits);
|
|
2544
|
+
const compileResult = await compiler.compile({
|
|
2545
|
+
form: formBuild.effectiveForm,
|
|
2546
|
+
context: context.publicContext,
|
|
2547
|
+
reusableFormDefinitions: context.resolution.reusableFormDefinitions,
|
|
2548
|
+
});
|
|
2549
|
+
if (compileResult.kind === 'failed') {
|
|
2550
|
+
if (compileResult.failureKind === 'limit-exceeded') {
|
|
2551
|
+
return {
|
|
2552
|
+
kind: 'limit-exceeded',
|
|
2553
|
+
stage: 'compiler',
|
|
2554
|
+
code: compileResult.code,
|
|
2555
|
+
diagnostics: compileResult.diagnostics,
|
|
2556
|
+
};
|
|
2557
|
+
}
|
|
2558
|
+
return {
|
|
2559
|
+
kind: 'compiler-failed',
|
|
2560
|
+
failureKind: compileResult.failureKind,
|
|
2561
|
+
code: compileResult.code,
|
|
2562
|
+
diagnostics: compileResult.diagnostics,
|
|
2563
|
+
};
|
|
2564
|
+
}
|
|
2565
|
+
if (Object.keys(compileResult.contract.root.properties).length === 0) {
|
|
2566
|
+
return this.contextFailure('not-resolvable', [], 'empty-effective-form');
|
|
2567
|
+
}
|
|
2568
|
+
let rendered;
|
|
2569
|
+
try {
|
|
2570
|
+
rendered = (0, record_contract_1.renderRecordJsonSchema)(compileResult.contract);
|
|
2571
|
+
}
|
|
2572
|
+
catch (error) {
|
|
2573
|
+
if (!(error instanceof record_contract_1.RecordJsonSchemaRendererError)) {
|
|
2574
|
+
this.logUnexpected('compile-renderer', error);
|
|
2575
|
+
}
|
|
2576
|
+
return {
|
|
2577
|
+
kind: 'compiler-failed',
|
|
2578
|
+
failureKind: 'renderer',
|
|
2579
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2580
|
+
diagnostics: error instanceof record_contract_1.RecordJsonSchemaRendererError
|
|
2581
|
+
? Object.freeze([
|
|
2582
|
+
Object.freeze({
|
|
2583
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2584
|
+
severity: 'error',
|
|
2585
|
+
message: 'The compiled record contract could not be rendered.',
|
|
2586
|
+
}),
|
|
2587
|
+
])
|
|
2588
|
+
: emptyDiagnostics(),
|
|
2589
|
+
};
|
|
2590
|
+
}
|
|
2591
|
+
let artifact;
|
|
2592
|
+
try {
|
|
2593
|
+
artifact = (0, record_contract_1.compileRecordJsonSchemaArtifact)(rendered, {
|
|
2594
|
+
maxDocumentBytes: config.limits.maxDocumentBytes,
|
|
2595
|
+
maxValidationErrors: config.limits.maxDiagnostics,
|
|
2596
|
+
});
|
|
2597
|
+
}
|
|
2598
|
+
catch (error) {
|
|
2599
|
+
if (error instanceof record_contract_1.RecordJsonSchemaDocumentLimitError) {
|
|
2600
|
+
return {
|
|
2601
|
+
kind: 'limit-exceeded',
|
|
2602
|
+
stage: 'artifact',
|
|
2603
|
+
code: error.code,
|
|
2604
|
+
diagnostics: emptyDiagnostics(),
|
|
2605
|
+
byteLength: error.byteLength,
|
|
2606
|
+
maximum: error.maxDocumentBytes,
|
|
2607
|
+
};
|
|
2608
|
+
}
|
|
2609
|
+
if (error instanceof record_contract_1.RecordJsonSchemaCompilationError) {
|
|
2610
|
+
return {
|
|
2611
|
+
kind: 'meta-validation-failed',
|
|
2612
|
+
reason: error.reason,
|
|
2613
|
+
code: error.code,
|
|
2614
|
+
issues: error.issues,
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
if (error instanceof record_contract_1.RecordJsonSchemaIdentityError && error.reason === 'invalid-limit') {
|
|
2618
|
+
return {
|
|
2619
|
+
kind: 'limit-exceeded',
|
|
2620
|
+
stage: 'artifact',
|
|
2621
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED,
|
|
2622
|
+
diagnostics: emptyDiagnostics(),
|
|
2623
|
+
};
|
|
2624
|
+
}
|
|
2625
|
+
this.logUnexpected('compile-artifact', error);
|
|
2626
|
+
return {
|
|
2627
|
+
kind: 'meta-validation-failed',
|
|
2628
|
+
reason: error instanceof record_contract_1.RecordJsonSchemaIdentityError ? 'identity' : 'artifact',
|
|
2629
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2630
|
+
issues: emptyValidationIssues(),
|
|
2631
|
+
};
|
|
2632
|
+
}
|
|
2633
|
+
try {
|
|
2634
|
+
this.cacheValidator(artifact, config.cacheMaxEntries);
|
|
2635
|
+
}
|
|
2636
|
+
catch (error) {
|
|
2637
|
+
this.logUnexpected('cache-populate', error);
|
|
2638
|
+
}
|
|
2639
|
+
let persistedDocumentValue;
|
|
2640
|
+
try {
|
|
2641
|
+
persistedDocumentValue = (0, record_contract_1.normalizeRedboxCanonicalJsonV1)(artifact.document);
|
|
2642
|
+
}
|
|
2643
|
+
catch (error) {
|
|
2644
|
+
this.logUnexpected('compile-normalization', error);
|
|
2645
|
+
return {
|
|
2646
|
+
kind: 'meta-validation-failed',
|
|
2647
|
+
reason: 'artifact',
|
|
2648
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2649
|
+
issues: emptyValidationIssues(),
|
|
2650
|
+
};
|
|
2651
|
+
}
|
|
2652
|
+
if (!isContractJsonObject(persistedDocumentValue)) {
|
|
2653
|
+
return {
|
|
2654
|
+
kind: 'meta-validation-failed',
|
|
2655
|
+
reason: 'artifact',
|
|
2656
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT,
|
|
2657
|
+
issues: emptyValidationIssues(),
|
|
2658
|
+
};
|
|
2659
|
+
}
|
|
2660
|
+
const artifactInput = Object.freeze({
|
|
2661
|
+
digest: artifact.digest,
|
|
2662
|
+
document: persistedDocumentValue,
|
|
2663
|
+
contractFormat: record_contract_1.RECORD_CONTRACT_FORMAT_V1,
|
|
2664
|
+
completeness: compileResult.contract.completeness,
|
|
2665
|
+
byteLength: artifact.byteLength,
|
|
2666
|
+
});
|
|
2667
|
+
const compilationBase = {
|
|
2668
|
+
document: artifact.document,
|
|
2669
|
+
digest: artifact.digest,
|
|
2670
|
+
artifactInput,
|
|
2671
|
+
contractFormat: record_contract_1.RECORD_CONTRACT_FORMAT_V1,
|
|
2672
|
+
byteLength: artifact.byteLength,
|
|
2673
|
+
etag: artifact.etag,
|
|
2674
|
+
};
|
|
2675
|
+
if (compileResult.contract.completeness === 'partial') {
|
|
2676
|
+
return Object.freeze({
|
|
2677
|
+
kind: 'partial',
|
|
2678
|
+
completeness: 'partial',
|
|
2679
|
+
...compilationBase,
|
|
2680
|
+
});
|
|
2681
|
+
}
|
|
2682
|
+
return Object.freeze({
|
|
2683
|
+
kind: 'resolved',
|
|
2684
|
+
completeness: 'complete',
|
|
2685
|
+
...compilationBase,
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2688
|
+
async compileAndPersist(config, context, createGrant, recordAccessContext) {
|
|
2689
|
+
const compilation = await this.compileContext(config, context, recordAccessContext);
|
|
2690
|
+
if (compilation.kind !== 'resolved' && compilation.kind !== 'partial') {
|
|
2691
|
+
return compilation;
|
|
2692
|
+
}
|
|
2693
|
+
return this.persistCompilation(compilation, createGrant);
|
|
2694
|
+
}
|
|
2695
|
+
async persistCompilation(compilation, createGrant) {
|
|
2696
|
+
let storageValue;
|
|
2697
|
+
try {
|
|
2698
|
+
storageValue = this.dependencies.getStorageProvider();
|
|
2699
|
+
}
|
|
2700
|
+
catch (error) {
|
|
2701
|
+
this.logUnexpected('persist-storage-provider', error);
|
|
2702
|
+
storageValue = undefined;
|
|
2703
|
+
}
|
|
2704
|
+
const storage = createStorageProvider(storageValue);
|
|
2705
|
+
if (!storage) {
|
|
2706
|
+
recordCounter(recordSchemaPersistence, {
|
|
2707
|
+
resource: 'artifact',
|
|
2708
|
+
outcome: 'failed',
|
|
2709
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2710
|
+
});
|
|
2711
|
+
return {
|
|
2712
|
+
kind: 'storage-failed',
|
|
2713
|
+
stage: 'artifact',
|
|
2714
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.STORAGE_UNAVAILABLE,
|
|
2715
|
+
};
|
|
2716
|
+
}
|
|
2717
|
+
let artifactWrite;
|
|
2718
|
+
try {
|
|
2719
|
+
artifactWrite = await storage.putRecordSchemaArtifact(compilation.artifactInput);
|
|
2720
|
+
}
|
|
2721
|
+
catch (error) {
|
|
2722
|
+
this.logUnexpected('persist-artifact', error);
|
|
2723
|
+
recordCounter(recordSchemaPersistence, {
|
|
2724
|
+
resource: 'artifact',
|
|
2725
|
+
outcome: 'failed',
|
|
2726
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.ARTIFACT_WRITE_FAILED,
|
|
2727
|
+
});
|
|
2728
|
+
return {
|
|
2729
|
+
kind: 'storage-failed',
|
|
2730
|
+
stage: 'artifact',
|
|
2731
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.ARTIFACT_WRITE_FAILED,
|
|
2732
|
+
};
|
|
2733
|
+
}
|
|
2734
|
+
if (!storageResponseSucceeded(artifactWrite)) {
|
|
2735
|
+
const code = storageResponseCode(artifactWrite) === codes_1.RECORD_SCHEMA_PROBLEM_CODES.DIGEST_COLLISION
|
|
2736
|
+
? codes_1.RECORD_SCHEMA_PROBLEM_CODES.DIGEST_COLLISION
|
|
2737
|
+
: codes_1.RECORD_SCHEMA_PROBLEM_CODES.ARTIFACT_WRITE_FAILED;
|
|
2738
|
+
recordCounter(recordSchemaPersistence, { resource: 'artifact', outcome: 'failed', code });
|
|
2739
|
+
return {
|
|
2740
|
+
kind: 'storage-failed',
|
|
2741
|
+
stage: 'artifact',
|
|
2742
|
+
code,
|
|
2743
|
+
};
|
|
2744
|
+
}
|
|
2745
|
+
recordCounter(recordSchemaPersistence, { resource: 'artifact', outcome: 'persisted', code: 'none' });
|
|
2746
|
+
const grant = createGrant(compilation.artifactInput);
|
|
2747
|
+
let grantWrite;
|
|
2748
|
+
try {
|
|
2749
|
+
grantWrite = await storage.putRecordSchemaReference(grant);
|
|
2750
|
+
}
|
|
2751
|
+
catch (error) {
|
|
2752
|
+
this.logUnexpected('persist-grant', error);
|
|
2753
|
+
recordCounter(recordSchemaPersistence, {
|
|
2754
|
+
resource: 'grant',
|
|
2755
|
+
outcome: 'failed',
|
|
2756
|
+
code: codes_1.RECORD_SCHEMA_PROBLEM_CODES.GRANT_WRITE_FAILED,
|
|
2757
|
+
});
|
|
2758
|
+
return {
|
|
2759
|
+
kind: 'storage-failed',
|
|
2760
|
+
stage: 'grant',
|
|
2761
|
+
...referenceWriteFailure(undefined, codes_1.RECORD_SCHEMA_PROBLEM_CODES.GRANT_WRITE_FAILED),
|
|
2762
|
+
artifact: Object.freeze({ digest: compilation.digest, persisted: true }),
|
|
2763
|
+
grantReferenceKey: grant.referenceKey,
|
|
2764
|
+
};
|
|
2765
|
+
}
|
|
2766
|
+
if (!storageResponseSucceeded(grantWrite)) {
|
|
2767
|
+
const failure = referenceWriteFailure(grantWrite, codes_1.RECORD_SCHEMA_PROBLEM_CODES.GRANT_WRITE_FAILED);
|
|
2768
|
+
recordCounter(recordSchemaPersistence, {
|
|
2769
|
+
resource: 'grant',
|
|
2770
|
+
outcome: 'failed',
|
|
2771
|
+
code: telemetryCode(failure.code),
|
|
2772
|
+
});
|
|
2773
|
+
return {
|
|
2774
|
+
kind: 'storage-failed',
|
|
2775
|
+
stage: 'grant',
|
|
2776
|
+
...failure,
|
|
2777
|
+
artifact: Object.freeze({ digest: compilation.digest, persisted: true }),
|
|
2778
|
+
grantReferenceKey: grant.referenceKey,
|
|
2779
|
+
};
|
|
2780
|
+
}
|
|
2781
|
+
recordCounter(recordSchemaPersistence, { resource: 'grant', outcome: 'persisted', code: 'none' });
|
|
2782
|
+
const resolutionBase = {
|
|
2783
|
+
document: compilation.document,
|
|
2784
|
+
digest: compilation.digest,
|
|
2785
|
+
grant,
|
|
2786
|
+
contractFormat: compilation.contractFormat,
|
|
2787
|
+
byteLength: compilation.byteLength,
|
|
2788
|
+
etag: compilation.etag,
|
|
2789
|
+
};
|
|
2790
|
+
if (compilation.kind === 'partial') {
|
|
2791
|
+
return Object.freeze({
|
|
2792
|
+
kind: 'partial',
|
|
2793
|
+
completeness: 'partial',
|
|
2794
|
+
...resolutionBase,
|
|
2795
|
+
});
|
|
2796
|
+
}
|
|
2797
|
+
return Object.freeze({
|
|
2798
|
+
kind: 'resolved',
|
|
2799
|
+
completeness: 'complete',
|
|
2800
|
+
...resolutionBase,
|
|
2801
|
+
});
|
|
2802
|
+
}
|
|
2803
|
+
async configuredFormFindings(config, registry) {
|
|
2804
|
+
let rawCandidates;
|
|
2805
|
+
try {
|
|
2806
|
+
rawCandidates = this.dependencies.getConfiguredFormCandidates();
|
|
2807
|
+
}
|
|
2808
|
+
catch (error) {
|
|
2809
|
+
this.logUnexpected('startup-configured-forms', error);
|
|
2810
|
+
rawCandidates = undefined;
|
|
2811
|
+
}
|
|
2812
|
+
const candidates = boundedArraySnapshot(rawCandidates, exports.RECORD_SCHEMA_CONFIGURED_FORM_MAX_CANDIDATES);
|
|
2813
|
+
if (candidates.kind !== 'values') {
|
|
2814
|
+
const code = candidates.kind === 'overflow'
|
|
2815
|
+
? codes_1.RECORD_SCHEMA_PROBLEM_CODES.LIMIT_EXCEEDED
|
|
2816
|
+
: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT;
|
|
2817
|
+
const findings = [configuredFormFinding('registry', 'candidate', code)];
|
|
2818
|
+
this.safeLog('info', 'record_schema_startup_check', 'startup-configured-forms', {
|
|
2819
|
+
status: 'failed',
|
|
2820
|
+
finding_count: findings.length,
|
|
2821
|
+
});
|
|
2822
|
+
return findings;
|
|
2823
|
+
}
|
|
2824
|
+
const compiler = new record_contract_1.RecordContractCompiler(registry, config.limits);
|
|
2825
|
+
const findings = [];
|
|
2826
|
+
for (const [index, value] of candidates.values.entries()) {
|
|
2827
|
+
const parsed = parseConfiguredFormCandidate(value);
|
|
2828
|
+
const fallbackName = `candidate-${index}`;
|
|
2829
|
+
if (!parsed) {
|
|
2830
|
+
findings.push(configuredFormFinding(fallbackName, 'candidate', codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT));
|
|
2831
|
+
continue;
|
|
2832
|
+
}
|
|
2833
|
+
const startedAt = this.clock();
|
|
2834
|
+
let outcome = 'resolved';
|
|
2835
|
+
try {
|
|
2836
|
+
const compiled = await compiler.compile({
|
|
2837
|
+
form: parsed.form,
|
|
2838
|
+
reusableFormDefinitions: parsed.reusableFormDefinitions,
|
|
2839
|
+
context: {
|
|
2840
|
+
brand: 'startup',
|
|
2841
|
+
portal: 'startup',
|
|
2842
|
+
kind: 'create',
|
|
2843
|
+
recordType: 'configured-form',
|
|
2844
|
+
workflowStep: 'startup',
|
|
2845
|
+
form: parsed.name,
|
|
2846
|
+
operation: RECORD_SCHEMA_STRICT_ALL_OPERATION,
|
|
2847
|
+
unknownProperties: config.unknownProperties,
|
|
2848
|
+
enforcement: 'shadow',
|
|
2849
|
+
},
|
|
2850
|
+
});
|
|
2851
|
+
if (compiled.kind === 'failed') {
|
|
2852
|
+
outcome = compiled.failureKind === 'limit-exceeded' ? 'limit-exceeded' : 'compiler-failed';
|
|
2853
|
+
findings.push(configuredFormFinding(parsed.name, 'compiler', compiled.code));
|
|
2854
|
+
continue;
|
|
2855
|
+
}
|
|
2856
|
+
let rendered;
|
|
2857
|
+
try {
|
|
2858
|
+
rendered = (0, record_contract_1.renderRecordJsonSchema)(compiled.contract);
|
|
2859
|
+
}
|
|
2860
|
+
catch (error) {
|
|
2861
|
+
if (!(error instanceof record_contract_1.RecordJsonSchemaRendererError)) {
|
|
2862
|
+
this.logUnexpected('compile-renderer', error);
|
|
2863
|
+
}
|
|
2864
|
+
outcome = 'compiler-failed';
|
|
2865
|
+
findings.push(configuredFormFinding(parsed.name, 'renderer', codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT));
|
|
2866
|
+
continue;
|
|
2867
|
+
}
|
|
2868
|
+
try {
|
|
2869
|
+
(0, record_contract_1.compileRecordJsonSchemaArtifact)(rendered, {
|
|
2870
|
+
maxDocumentBytes: config.limits.maxDocumentBytes,
|
|
2871
|
+
maxValidationErrors: config.limits.maxDiagnostics,
|
|
2872
|
+
});
|
|
2873
|
+
}
|
|
2874
|
+
catch (error) {
|
|
2875
|
+
outcome = error instanceof record_contract_1.RecordJsonSchemaDocumentLimitError ? 'limit-exceeded' : 'meta-validation-failed';
|
|
2876
|
+
findings.push(configuredFormFinding(parsed.name, 'artifact', error instanceof record_contract_1.RecordJsonSchemaDocumentLimitError
|
|
2877
|
+
? error.code
|
|
2878
|
+
: codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT));
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
catch (error) {
|
|
2882
|
+
this.logUnexpected('startup-configured-forms', error);
|
|
2883
|
+
outcome = 'unexpected-failure';
|
|
2884
|
+
findings.push(configuredFormFinding(parsed.name, 'compiler', codes_1.RECORD_SCHEMA_PROBLEM_CODES.INVALID_CONTRACT));
|
|
2885
|
+
}
|
|
2886
|
+
finally {
|
|
2887
|
+
const attributes = {
|
|
2888
|
+
schema_kind: 'unknown',
|
|
2889
|
+
phase: 'startup',
|
|
2890
|
+
outcome: telemetryDimension(outcome, RECORD_SCHEMA_COMPILE_OUTCOMES, 'unexpected-failure'),
|
|
2891
|
+
};
|
|
2892
|
+
recordDuration(this.clock() - startedAt, attributes);
|
|
2893
|
+
recordCounter(recordSchemaCompileOutcomes, attributes);
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
if (findings.length > 0) {
|
|
2897
|
+
this.safeLog('info', 'record_schema_startup_check', 'startup-configured-forms', {
|
|
2898
|
+
status: 'failed',
|
|
2899
|
+
finding_count: Math.min(findings.length, exports.RECORD_SCHEMA_STARTUP_LOG_FINDING_COUNT_MAX),
|
|
2900
|
+
...(findings.length > exports.RECORD_SCHEMA_STARTUP_LOG_FINDING_COUNT_MAX
|
|
2901
|
+
? { finding_count_bucket: 'overflow' }
|
|
2902
|
+
: {}),
|
|
2903
|
+
});
|
|
2904
|
+
return findings;
|
|
2905
|
+
}
|
|
2906
|
+
this.safeLog('info', 'record_schema_startup_check', 'startup-configured-forms', {
|
|
2907
|
+
status: 'passed',
|
|
2908
|
+
finding_count: 0,
|
|
2909
|
+
});
|
|
2910
|
+
return findings;
|
|
2911
|
+
}
|
|
2912
|
+
/** Run the complete enabled lifecycle gate after storage is ready and before application readiness. */
|
|
2913
|
+
async bootstrap() {
|
|
2914
|
+
const inspection = this.inspectLifecycle();
|
|
2915
|
+
if (inspection.disabled) {
|
|
2916
|
+
this.safeLog('info', 'record_schema_startup_check', 'lifecycle', {
|
|
2917
|
+
status: 'disabled',
|
|
2918
|
+
finding_count: 0,
|
|
2919
|
+
});
|
|
2920
|
+
return;
|
|
2921
|
+
}
|
|
2922
|
+
const findings = [...inspection.findings];
|
|
2923
|
+
if (inspection.config && inspection.registry) {
|
|
2924
|
+
findings.push(...(await this.configuredFormFindings(inspection.config, inspection.registry)));
|
|
2925
|
+
}
|
|
2926
|
+
if (findings.length > 0) {
|
|
2927
|
+
this.logLifecycleFailure(findings);
|
|
2928
|
+
throw new RecordSchemaLifecycleError(findings);
|
|
2929
|
+
}
|
|
2930
|
+
this.safeLog('info', 'record_schema_startup_check', 'lifecycle', {
|
|
2931
|
+
status: 'passed',
|
|
2932
|
+
finding_count: 0,
|
|
2933
|
+
});
|
|
2934
|
+
await this.bootstrapIntegrationPins();
|
|
2935
|
+
}
|
|
2936
|
+
resolveRuntimeConfig() {
|
|
2937
|
+
try {
|
|
2938
|
+
const validation = (0, recordSchema_config_1.validateRecordSchemaConfig)(this.dependencies.getConfig());
|
|
2939
|
+
return validation.valid ? validation.config : undefined;
|
|
2940
|
+
}
|
|
2941
|
+
catch (error) {
|
|
2942
|
+
this.logUnexpected('runtime-configuration', error);
|
|
2943
|
+
return undefined;
|
|
2944
|
+
}
|
|
2945
|
+
}
|
|
2946
|
+
contextFailure(failureKind, diagnosticCodes = [], reason) {
|
|
2947
|
+
return Object.freeze({
|
|
2948
|
+
kind: 'context-failed',
|
|
2949
|
+
failureKind,
|
|
2950
|
+
diagnosticCodes: Object.freeze([...diagnosticCodes]),
|
|
2951
|
+
...(reason ? { reason } : {}),
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2954
|
+
inspectLifecycle() {
|
|
2955
|
+
let config;
|
|
2956
|
+
let configReadFailed = false;
|
|
2957
|
+
try {
|
|
2958
|
+
config = this.dependencies.getConfig();
|
|
2959
|
+
if (isDisabled(config)) {
|
|
2960
|
+
return { disabled: true, findings: [] };
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
catch (error) {
|
|
2964
|
+
this.logUnexpected('startup-configuration', error);
|
|
2965
|
+
configReadFailed = true;
|
|
2966
|
+
}
|
|
2967
|
+
const findings = configReadFailed
|
|
2968
|
+
? [unreadableConfigurationFinding()]
|
|
2969
|
+
: configuredFindings(config);
|
|
2970
|
+
let validatedConfig;
|
|
2971
|
+
if (!configReadFailed) {
|
|
2972
|
+
try {
|
|
2973
|
+
const validation = (0, recordSchema_config_1.validateRecordSchemaConfig)(config);
|
|
2974
|
+
if (validation.valid)
|
|
2975
|
+
validatedConfig = validation.config;
|
|
2976
|
+
}
|
|
2977
|
+
catch (error) {
|
|
2978
|
+
this.logUnexpected('startup-configuration', error);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
let storageProvider;
|
|
2982
|
+
try {
|
|
2983
|
+
storageProvider = this.dependencies.getStorageProvider();
|
|
2984
|
+
}
|
|
2985
|
+
catch (error) {
|
|
2986
|
+
this.logUnexpected('startup-storage', error);
|
|
2987
|
+
storageProvider = undefined;
|
|
2988
|
+
}
|
|
2989
|
+
findings.push(...storageFindings(storageProvider));
|
|
2990
|
+
let contributorStateUnavailable = false;
|
|
2991
|
+
let registrationIssues = [];
|
|
2992
|
+
try {
|
|
2993
|
+
registrationIssues = this.dependencies.getContributorRegistrationIssues();
|
|
2994
|
+
}
|
|
2995
|
+
catch (error) {
|
|
2996
|
+
this.logUnexpected('startup-contributors', error);
|
|
2997
|
+
contributorStateUnavailable = true;
|
|
2998
|
+
}
|
|
2999
|
+
findings.push(...contributorFindings(registrationIssues));
|
|
3000
|
+
let registry;
|
|
3001
|
+
try {
|
|
3002
|
+
registry = this.dependencies.getContributorRegistry();
|
|
3003
|
+
}
|
|
3004
|
+
catch (error) {
|
|
3005
|
+
this.logUnexpected('startup-registry', error);
|
|
3006
|
+
registry = undefined;
|
|
3007
|
+
contributorStateUnavailable = true;
|
|
3008
|
+
}
|
|
3009
|
+
if (!registry && registrationIssues.length === 0) {
|
|
3010
|
+
contributorStateUnavailable = true;
|
|
3011
|
+
}
|
|
3012
|
+
let componentTypes = [];
|
|
3013
|
+
try {
|
|
3014
|
+
componentTypes = this.dependencies.getContributorComponentTypes();
|
|
3015
|
+
}
|
|
3016
|
+
catch (error) {
|
|
3017
|
+
this.logUnexpected('startup-coverage', error);
|
|
3018
|
+
contributorStateUnavailable = true;
|
|
3019
|
+
}
|
|
3020
|
+
if (contributorStateUnavailable) {
|
|
3021
|
+
findings.push(...contributorFindings([unavailableContributorStateIssue()]));
|
|
3022
|
+
}
|
|
3023
|
+
findings.push(...coverageFindings(componentTypes));
|
|
3024
|
+
return {
|
|
3025
|
+
disabled: false,
|
|
3026
|
+
...(validatedConfig ? { config: validatedConfig } : {}),
|
|
3027
|
+
...(registry ? { registry } : {}),
|
|
3028
|
+
findings,
|
|
3029
|
+
};
|
|
3030
|
+
}
|
|
3031
|
+
logLifecycleFailure(findings) {
|
|
3032
|
+
this.safeLog('info', 'record_schema_startup_check', 'lifecycle', {
|
|
3033
|
+
status: 'failed',
|
|
3034
|
+
finding_count: Math.min(findings.length, exports.RECORD_SCHEMA_STARTUP_LOG_FINDING_COUNT_MAX),
|
|
3035
|
+
...(findings.length > exports.RECORD_SCHEMA_STARTUP_LOG_FINDING_COUNT_MAX
|
|
3036
|
+
? { finding_count_bucket: 'overflow' }
|
|
3037
|
+
: {}),
|
|
3038
|
+
});
|
|
3039
|
+
}
|
|
3040
|
+
init() {
|
|
3041
|
+
const inspection = this.inspectLifecycle();
|
|
3042
|
+
if (inspection.disabled) {
|
|
3043
|
+
this.safeLog('info', 'record_schema_startup_check', 'lifecycle', {
|
|
3044
|
+
status: 'disabled',
|
|
3045
|
+
finding_count: 0,
|
|
3046
|
+
});
|
|
3047
|
+
return;
|
|
3048
|
+
}
|
|
3049
|
+
if (inspection.findings.length > 0) {
|
|
3050
|
+
this.logLifecycleFailure(inspection.findings);
|
|
3051
|
+
throw new RecordSchemaLifecycleError(inspection.findings);
|
|
3052
|
+
}
|
|
3053
|
+
this.safeLog('info', 'record_schema_startup_check', 'lifecycle', {
|
|
3054
|
+
status: 'passed',
|
|
3055
|
+
finding_count: 0,
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
Services.RecordSchema = RecordSchema;
|
|
3060
|
+
})(Services || (exports.Services = Services = {}));
|
|
3061
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVjb3JkU2NoZW1hU2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aWNlcy9SZWNvcmRTY2hlbWFTZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUF5QztBQUN6Qyw0Q0FBOEQ7QUFDOUQsc0VBQXdIO0FBRXhILGdEQUFzRDtBQUN0RCx1RUFRdUM7QUFldkMsd0RBeUM0QjtBQUM1QixzREFLMkI7QUFDM0Isb0RBQXVFO0FBSXZFLGlHQUF1RztBQUkxRixRQUFBLGtDQUFrQyxHQUFHLGdDQUF5QyxDQUFDO0FBNEU1RixNQUFNLGNBQWMsR0FBdUU7SUFDekYsYUFBYSxFQUFFLENBQUM7SUFDaEIsT0FBTyxFQUFFLENBQUM7SUFDVixXQUFXLEVBQUUsQ0FBQztJQUNkLFFBQVEsRUFBRSxDQUFDO0lBQ1gsSUFBSSxFQUFFLENBQUM7SUFDUCxHQUFHLEVBQUUsQ0FBQztDQUNQLENBQUM7QUFFRixNQUFNLDRCQUE0QixHQUFnRCxJQUFJLEdBQUcsQ0FBQztJQUN4RixvREFBa0MsQ0FBQyxhQUFhO0lBQ2hELG9EQUFrQyxDQUFDLG1CQUFtQjtDQUN2RCxDQUFDLENBQUM7QUFFSCxNQUFNLGNBQWMsR0FBRyxnQkFBZ0IsQ0FBQztBQUN4QyxNQUFNLDBCQUEwQixHQUFHLDRCQUE0QixDQUFDO0FBQ2hFLE1BQU0sbUNBQW1DLEdBQUcscUNBQXFDLENBQUM7QUFDckUsUUFBQSw0Q0FBNEMsR0FBRyxLQUFLLENBQUM7QUFDbEUsTUFBTSx1Q0FBdUMsR0FBRyxLQUFLLENBQUM7QUFDdEQsTUFBTSwwQ0FBMEMsR0FBRyxHQUFHLENBQUM7QUFDMUMsUUFBQSxnREFBZ0QsR0FBRyxHQUFHLENBQUM7QUFDdkQsUUFBQSw0Q0FBNEMsR0FBRyxHQUFHLENBQUM7QUFDaEUsTUFBTSxrQ0FBa0MsR0FBRyxZQUFZLENBQUM7QUFDeEQsTUFBTSxvQkFBb0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUs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
|