@reventlessdev/reventless-core 3.0.0-alpha.197 → 3.0.0-alpha.199
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/CHANGELOG.md +19 -0
- package/package.json +7 -7
- package/src/admin/Platform_AdminApi.res +23 -0
- package/src/admin/Platform_AdminApi.res.mjs +12 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res +12 -8
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Builder.res.mjs +7 -8
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res +27 -0
- package/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res.mjs +13 -0
- package/src/plugin/component/Plugin_Structure.res +8 -5
- package/tests/fixtures/plugin-lifecycle/2026-07-22-versionconnected-no-requiredstores.json +1 -0
- package/tests/fixtures/plugin-lifecycle/2026-07-22-versionsuperseded-nested-definitions.json +1 -0
- package/tests/fixtures/plugin-lifecycle/2026-07-28-versionconnected-requiredstores-only.json +1 -0
- package/tests/fixtures/plugin-lifecycle/2026-07-30-versionconnected-declarations-without-annotation.json +1 -0
- package/tests/fixtures/plugin-lifecycle/2026-07-30-versiondisconnected-declarations-without-annotation.json +1 -0
- package/tests/fixtures/plugin-lifecycle/README.md +36 -0
- package/tests/plugin/PluginDefinitionRequiredScalarsTest.res +42 -0
- package/tests/plugin/PluginDefinitionRequiredScalarsTest.res.mjs +45 -0
- package/tests/plugin/PluginDefinitionScalars.res +78 -0
- package/tests/plugin/PluginDefinitionScalars.res.mjs +110 -0
- package/tests/plugin/PluginLifecycleCorpus.res +42 -0
- package/tests/plugin/PluginLifecycleCorpus.res.mjs +39 -0
- package/tests/plugin/PluginLifecycleCorpusTest.res +50 -0
- package/tests/plugin/PluginLifecycleCorpusTest.res.mjs +42 -0
- package/tests/plugin/PluginStructureTest.res +3 -3
- package/tests/plugin/pluginDefinitionRequiredScalars.txt +103 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"event":"VersionConnected","data":{"_0":{"dcbEventLog":{"name":"CatalogDcbEventLog","eventTopicArn":"arn:aws:dynamodb:eu-west-1:000000000000:table/CatalogDcbEventLog-925103d/stream/2026-07-14T08:45:33.852"},"extensions":[{"name":"Ordering.Orders.Catalog","extensionPointName":"Ordering.Orders","dcbSources":[]}],"extensionProtocols":[],"extensionPoints":[{"name":"Catalog.Products","commandTopic":"https://sqs.eu-west-1.amazonaws.com/000000000000/CatalogProductsExtPointCmdTopic-1dd983b","eventTopic":"arn:aws:sns:eu-west-1:000000000000:CatalogProductsExtPointEventTopic-5cb0b5e"}],"kind":"Domain","name":"Catalog","apiTarget":"Domain","id":"Catalog@1.0.0-alpha.168","version":"1.0.0-alpha.168","apiSchemaFragment":{"protocol":"graphql","encoded":"{\"types\":[\"type Catalog_Category implements Node {\\n id: ID!\\n categoryId: ID!\\n name: String!\\n archived: Boolean!\\n}\",\"type Catalog_CategoryEdge {\\n node: Catalog_Category!\\n cursor: String!\\n}\",\"type Catalog_CategoryConnection {\\n edges: [Catalog_CategoryEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_CategoryFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"type Catalog_ProductDemand implements Node {\\n id: ID!\\n productId: ID!\\n name: String!\\n categoryId: ID!\\n orderCount: Float!\\n}\",\"type Catalog_ProductDemandEdge {\\n node: Catalog_ProductDemand!\\n cursor: String!\\n}\",\"type Catalog_ProductDemandConnection {\\n edges: [Catalog_ProductDemandEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_ProductDemandFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"type Catalog_Product implements Node {\\n id: ID!\\n productId: ID!\\n name: String!\\n description: String!\\n price: Float!\\n imageUrl: String!\\n categoryId: ID!\\n}\",\"type Catalog_ProductEdge {\\n node: Catalog_Product!\\n cursor: String!\\n}\",\"type Catalog_ProductConnection {\\n edges: [Catalog_ProductEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_ProductFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"enum Catalog_ImportProductAuditStatus {\\n Success\\n Failure\\n}\",\"type Catalog_ImportProductAudit implements Node {\\n id: ID!\\n input: String!\\n status: Catalog_ImportProductAuditStatus!\\n targetIds: [ID!]\\n commandCount: Float\\n error: String\\n receivedAt: String!\\n}\",\"type Catalog_ImportProductAuditEdge {\\n node: Catalog_ImportProductAudit!\\n cursor: String!\\n}\",\"type Catalog_ImportProductAuditConnection {\\n edges: [Catalog_ImportProductAuditEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_ImportProductAuditFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"union CommandResult = CommandAccepted | CommandRejected | CommandPending\",\"type CommandAccepted {\\n msgId: ID!\\n entityId: ID\\n eventCount: Int!\\n}\",\"type CommandRejected {\\n msgId: ID!\\n errorCode: String!\\n errorDetail: String\\n}\",\"type CommandPending {\\n msgId: ID!\\n}\",\"type CatalogEventLogEvent {\\n position: String!\\n eventType: String!\\n payload: AWSJSON!\\n}\",\"type Catalog_CatalogEventRecord {\\n position: String!\\n eventType: String!\\n payload: AWSJSON!\\n tags: [EventTag!]!\\n meta: EventMeta!\\n recordedAt: String!\\n}\",\"type Catalog_CatalogEventRecordEdge {\\n node: Catalog_CatalogEventRecord!\\n cursor: String!\\n}\",\"type Catalog_CatalogEventRecordConnection {\\n edges: [Catalog_CatalogEventRecordEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_CatalogEventHistoryFilter {\\n entityId: ID\\n tagKey: String\\n tagValue: String\\n eventTypes: [String!]\\n user: String\\n timeFrom: String\\n timeTo: String\\n}\",\"type EventMeta {\\n service: String!\\n time: String!\\n user: String\\n msgId: String!\\n correlationId: String!\\n causationId: String\\n}\",\"type EventTag {\\n key: String!\\n value: String!\\n}\"],\"mutations\":[\" Catalog_AddCategory(categoryId: ID!, name: String!): CommandResult!\",\" Catalog_AddProduct(productId: ID!, name: String!, description: String!, price: Float!, imageUrl: String!, categoryId: ID!): CommandResult!\",\" Catalog_ArchiveCategory(categoryId: ID!): CommandResult!\\n @aws_auth(cognito_groups: [\\\"Admin\\\"])\",\" Catalog_ChangeProductDescription(productId: ID!, description: String!): CommandResult!\",\" Catalog_ChangeProductImage(productId: ID!, imageUrl: String!): CommandResult!\",\" Catalog_ChangeProductName(productId: ID!, name: String!): CommandResult!\",\" Catalog_ChangeProductPrice(productId: ID!, price: Float!): CommandResult!\",\" Catalog_RenameCategory(categoryId: ID!, name: String!): CommandResult!\",\" Catalog_ImportProduct(sku: String!, title: String!, desc: String!, unitPrice: Float!, currency: String!, category: String!): CommandResult!\"],\"queries\":[\" Catalog_Category(id: ID!): Catalog_Category\",\" Catalog_CategoriesByIds(ids: [String!]!): [Catalog_Category!]!\",\" Catalog_Categories(filter: Catalog_CategoryFilter, first: Int, after: String, last: Int, before: String): Catalog_CategoryConnection!\",\" Catalog_ProductDemand(id: ID!): Catalog_ProductDemand\",\" Catalog_ProductDemandsByIds(ids: [String!]!): [Catalog_ProductDemand!]!\",\" Catalog_ProductDemands(filter: Catalog_ProductDemandFilter, first: Int, after: String, last: Int, before: String): Catalog_ProductDemandConnection!\",\" Catalog_Product(id: ID!): Catalog_Product\",\" Catalog_ProductsByIds(ids: [String!]!): [Catalog_Product!]!\",\" Catalog_Products(filter: Catalog_ProductFilter, first: Int, after: String, last: Int, before: String): Catalog_ProductConnection!\",\" Catalog_ImportProductAudit(id: ID!): Catalog_ImportProductAudit\",\" Catalog_ImportProductAuditsByIds(ids: [String!]!): [Catalog_ImportProductAudit!]!\",\" Catalog_ImportProductAudits(filter: Catalog_ImportProductAuditFilter, first: Int, after: String, last: Int, before: String): Catalog_ImportProductAuditConnection!\",\" Catalog_CatalogEventHistory(filter: Catalog_CatalogEventHistoryFilter, first: Int, after: String, last: Int, before: String): Catalog_CatalogEventRecordConnection!\"],\"subscriptions\":[\" onCatalog_AddCategory(id: ID): CommandResult\",\" onCatalog_AddProduct(id: ID): CommandResult\",\" onCatalog_ArchiveCategory(id: ID): CommandResult\",\" onCatalog_ChangeProductDescription(id: ID): CommandResult\",\" onCatalog_ChangeProductImage(id: ID): CommandResult\",\" onCatalog_ChangeProductName(id: ID): CommandResult\",\" onCatalog_ChangeProductPrice(id: ID): CommandResult\",\" onCatalog_RenameCategory(id: ID): CommandResult\",\" onCatalog_ImportProduct(id: ID): CommandResult\",\" onCatalogEventLog_eventAppended: CatalogEventLogEvent\"],\"subscriptionSources\":[{\"field\":\"onCatalog_AddCategory\",\"mutations\":[\"Catalog_AddCategory\"]},{\"field\":\"onCatalog_AddProduct\",\"mutations\":[\"Catalog_AddProduct\"]},{\"field\":\"onCatalog_ArchiveCategory\",\"mutations\":[\"Catalog_ArchiveCategory\"]},{\"field\":\"onCatalog_ChangeProductDescription\",\"mutations\":[\"Catalog_ChangeProductDescription\"]},{\"field\":\"onCatalog_ChangeProductImage\",\"mutations\":[\"Catalog_ChangeProductImage\"]},{\"field\":\"onCatalog_ChangeProductName\",\"mutations\":[\"Catalog_ChangeProductName\"]},{\"field\":\"onCatalog_ChangeProductPrice\",\"mutations\":[\"Catalog_ChangeProductPrice\"]},{\"field\":\"onCatalog_RenameCategory\",\"mutations\":[\"Catalog_RenameCategory\"]},{\"field\":\"onCatalog_ImportProduct\",\"mutations\":[\"Catalog_ImportProduct\"]}]}"},"eventCollector":"arn:aws:sqs:eu-west-1:000000000000:CatalogPluginEventColl-fc85d05","structure":{"outboundTranslationSlices":[],"extensions":[{"name":"Ordering.Orders","delegateNames":["RecordProductDemand"],"eventTypes":["Ordering.Orders.ItemOrdered","Ordering.Orders.ItemOrderCancelled"],"commandTypes":[]}],"stateChangeSlices":[{"consistencyRead":null,"chapter":"Category","linkedViews":["Categories"],"producedEventTypes":["Catalog.CategoryAdded"],"name":"AddCategory","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"AddCategory\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","aggregateIdField":"categoryId","mutationField":"Catalog_AddCategory","references":[],"level":"Collection","targetState":null,"apiExposed":true,"name":"AddCategory","allowedStates":null}],"events":[{"name":"CategoryAdded","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"CategoryAdded\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","references":[]}],"consumedEventTypes":[]},{"consistencyRead":"Categories","chapter":"Product","linkedViews":["ProductDemand","Products"],"producedEventTypes":["Catalog.ProductAdded"],"name":"AddProduct","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"AddProduct\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"},\"imageUrl\":{\"type\":\"string\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\",\"description\",\"price\",\"imageUrl\",\"categoryId\"]}","aggregateIdField":"productId","mutationField":"Catalog_AddProduct","references":[{"plugin":null,"entity":"Categories","fieldName":"categoryId"}],"level":"Collection","targetState":null,"apiExposed":true,"name":"AddProduct","allowedStates":null}],"events":[{"name":"ProductAdded","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductAdded\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"},\"imageUrl\":{\"type\":\"string\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\",\"description\",\"price\",\"imageUrl\",\"categoryId\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.CategoryAdded","Catalog.CategoryArchived"]},{"consistencyRead":null,"chapter":"Category","linkedViews":["Categories"],"producedEventTypes":["Catalog.CategoryArchived"],"name":"ArchiveCategory","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ArchiveCategory\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\"]}","aggregateIdField":"categoryId","mutationField":"Catalog_ArchiveCategory","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ArchiveCategory","allowedStates":null}],"events":[{"name":"CategoryArchived","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"CategoryArchived\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\"]}","references":[]}],"consumedEventTypes":[]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductDescriptionChanged"],"name":"ChangeProductDescription","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductDescription\"},\"productId\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"description\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductDescription","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductDescription","allowedStates":null}],"events":[{"name":"ProductDescriptionChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductDescriptionChanged\"},\"productId\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"description\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductDescriptionChanged"]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductImageChanged"],"name":"ChangeProductImage","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductImage\"},\"productId\":{\"type\":\"string\"},\"imageUrl\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"imageUrl\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductImage","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductImage","allowedStates":null}],"events":[{"name":"ProductImageChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductImageChanged\"},\"productId\":{\"type\":\"string\"},\"imageUrl\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"imageUrl\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductImageChanged"]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductNameChanged"],"name":"ChangeProductName","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductName\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductName","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductName","allowedStates":null}],"events":[{"name":"ProductNameChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductNameChanged\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductNameChanged"]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductPriceChanged"],"name":"ChangeProductPrice","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductPrice\"},\"productId\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"price\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductPrice","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductPrice","allowedStates":null}],"events":[{"name":"ProductPriceChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductPriceChanged\"},\"productId\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"price\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductPriceChanged"]},{"consistencyRead":"ProductDemand","chapter":"ProductDemand","linkedViews":["ProductDemand"],"producedEventTypes":["Catalog.ProductDemandRecorded","Catalog.ProductDemandRevoked"],"name":"RecordProductDemand","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"RecordDemand\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","aggregateIdField":"productId","mutationField":"","references":[],"level":"Instance","targetState":null,"apiExposed":false,"name":"RecordDemand","allowedStates":null},{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"RevokeDemand\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","aggregateIdField":"productId","mutationField":"","references":[],"level":"Instance","targetState":null,"apiExposed":false,"name":"RevokeDemand","allowedStates":null}],"events":[{"name":"ProductDemandRecorded","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductDemandRecorded\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","references":[]},{"name":"ProductDemandRevoked","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductDemandRevoked\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductDemandRecorded","Catalog.ProductDemandRevoked"]},{"consistencyRead":"Categories","chapter":"Category","linkedViews":["Categories"],"producedEventTypes":["Catalog.CategoryRenamed"],"name":"RenameCategory","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"RenameCategory\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","aggregateIdField":"categoryId","mutationField":"Catalog_RenameCategory","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"RenameCategory","allowedStates":null}],"events":[{"name":"CategoryRenamed","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"CategoryRenamed\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","references":[]}],"consumedEventTypes":["Catalog.CategoryAdded","Catalog.CategoryRenamed"]}],"extensionPoints":[{"name":"Catalog.Products","sourceEventTypes":["Catalog.ProductAdded","Catalog.ProductPriceChanged"],"delegateNames":["CatalogDcbEventLog"],"commandTypes":[]}],"readModels":[],"requiredStoreDeclarations":[{"field":"imageUrl","component":"AddProduct","store":"Catalog.productImages"},{"field":"imageUrl","component":"ChangeProductImage","store":"Catalog.productImages"},{"field":"imageUrl","component":"ImportProduct","store":"Catalog.productImages"},{"field":"imageUrl","component":"Products","store":"Catalog.productImages"}],"stateViewSlices":[{"schema":"{\"type\":\"object\",\"properties\":{\"categoryId\":{\"type\":\"string\",\"format\":\"uuid\"},\"name\":{\"type\":\"string\"},\"archived\":{\"type\":\"boolean\"}},\"required\":[\"categoryId\",\"name\",\"archived\"]}","searchableFields":["name"],"chapter":"Category","linkedWriteSide":["AddCategory","ArchiveCategory","RenameCategory"],"labelFieldSource":"convention","statusField":null,"visibility":null,"queryField":"Catalog_Categories","name":"Categories","consumedEventTypes":["Catalog.CategoryAdded","Catalog.CategoryRenamed","Catalog.CategoryArchived"],"labelField":"name"},{"schema":"{\"type\":\"object\",\"properties\":{\"productId\":{\"type\":\"string\",\"format\":\"uuid\"},\"name\":{\"type\":\"string\"},\"categoryId\":{\"type\":\"string\",\"format\":\"uuid\"},\"orderCount\":{\"type\":\"number\"}},\"required\":[\"productId\",\"name\",\"categoryId\",\"orderCount\"]}","searchableFields":["name"],"chapter":"Product","linkedWriteSide":["AddProduct","RecordProductDemand"],"labelFieldSource":"convention","statusField":null,"visibility":null,"queryField":"Catalog_ProductDemands","name":"ProductDemand","consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductDemandRecorded","Catalog.ProductDemandRevoked"],"labelField":"name"},{"schema":"{\"type\":\"object\",\"properties\":{\"productId\":{\"type\":\"string\",\"format\":\"uuid\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"},\"imageUrl\":{\"type\":\"string\",\"x-reventless-semantic\":\"storageRef\",\"x-reventless-semantic-source\":\"type\",\"x-reventless-semantic-target\":{\"store\":\"productImages\"}},\"categoryId\":{\"type\":\"string\",\"format\":\"uuid\"}},\"required\":[\"productId\",\"name\",\"description\",\"price\",\"imageUrl\",\"categoryId\"]}","searchableFields":["name"],"chapter":"Product","linkedWriteSide":["AddProduct","ChangeProductDescription","ChangeProductImage","ChangeProductName","ChangeProductPrice"],"labelFieldSource":"convention","statusField":null,"visibility":null,"queryField":"Catalog_Products","name":"Products","consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductNameChanged","Catalog.ProductDescriptionChanged","Catalog.ProductPriceChanged","Catalog.ProductImageChanged"],"labelField":"name"}],"aggregates":[],"inboundTranslationSlices":[{"name":"ImportProduct","chapter":"Product","targetName":"AddProduct","commandTypes":["Catalog.AddProduct"],"externalSystem":"SupplierFeed"}],"automationSlices":[],"requiredStores":["Catalog.productImages"]}}}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"event":"VersionDisconnected","data":{"_0":{"dcbEventLog":{"name":"CatalogDcbEventLog","eventTopicArn":"arn:aws:dynamodb:eu-west-1:000000000000:table/CatalogDcbEventLog-925103d/stream/2026-07-14T08:45:33.852"},"extensions":[{"name":"Ordering.Orders.Catalog","extensionPointName":"Ordering.Orders","dcbSources":[]}],"extensionProtocols":[],"extensionPoints":[{"name":"Catalog.Products","commandTopic":"https://sqs.eu-west-1.amazonaws.com/000000000000/CatalogProductsExtPointCmdTopic-1dd983b","eventTopic":"arn:aws:sns:eu-west-1:000000000000:CatalogProductsExtPointEventTopic-5cb0b5e"}],"kind":"Domain","name":"Catalog","apiTarget":"Domain","id":"Catalog@1.0.0-alpha.167","version":"1.0.0-alpha.167","apiSchemaFragment":{"protocol":"graphql","encoded":"{\"types\":[\"type Catalog_Category implements Node {\\n id: ID!\\n categoryId: ID!\\n name: String!\\n archived: Boolean!\\n}\",\"type Catalog_CategoryEdge {\\n node: Catalog_Category!\\n cursor: String!\\n}\",\"type Catalog_CategoryConnection {\\n edges: [Catalog_CategoryEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_CategoryFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"type Catalog_ProductDemand implements Node {\\n id: ID!\\n productId: ID!\\n name: String!\\n categoryId: ID!\\n orderCount: Float!\\n}\",\"type Catalog_ProductDemandEdge {\\n node: Catalog_ProductDemand!\\n cursor: String!\\n}\",\"type Catalog_ProductDemandConnection {\\n edges: [Catalog_ProductDemandEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_ProductDemandFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"type Catalog_Product implements Node {\\n id: ID!\\n productId: ID!\\n name: String!\\n description: String!\\n price: Float!\\n imageUrl: String!\\n categoryId: ID!\\n}\",\"type Catalog_ProductEdge {\\n node: Catalog_Product!\\n cursor: String!\\n}\",\"type Catalog_ProductConnection {\\n edges: [Catalog_ProductEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_ProductFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"enum Catalog_ImportProductAuditStatus {\\n Success\\n Failure\\n}\",\"type Catalog_ImportProductAudit implements Node {\\n id: ID!\\n input: String!\\n status: Catalog_ImportProductAuditStatus!\\n targetIds: [ID!]\\n commandCount: Float\\n error: String\\n receivedAt: String!\\n}\",\"type Catalog_ImportProductAuditEdge {\\n node: Catalog_ImportProductAudit!\\n cursor: String!\\n}\",\"type Catalog_ImportProductAuditConnection {\\n edges: [Catalog_ImportProductAuditEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_ImportProductAuditFilter {\\n search: String\\n searchPrefix: String\\n ids: [ID!]\\n}\",\"union CommandResult = CommandAccepted | CommandRejected | CommandPending\",\"type CommandAccepted {\\n msgId: ID!\\n entityId: ID\\n eventCount: Int!\\n}\",\"type CommandRejected {\\n msgId: ID!\\n errorCode: String!\\n errorDetail: String\\n}\",\"type CommandPending {\\n msgId: ID!\\n}\",\"type CatalogEventLogEvent {\\n position: String!\\n eventType: String!\\n payload: AWSJSON!\\n}\",\"type Catalog_CatalogEventRecord {\\n position: String!\\n eventType: String!\\n payload: AWSJSON!\\n tags: [EventTag!]!\\n meta: EventMeta!\\n recordedAt: String!\\n}\",\"type Catalog_CatalogEventRecordEdge {\\n node: Catalog_CatalogEventRecord!\\n cursor: String!\\n}\",\"type Catalog_CatalogEventRecordConnection {\\n edges: [Catalog_CatalogEventRecordEdge!]!\\n pageInfo: PageInfo!\\n}\",\"input Catalog_CatalogEventHistoryFilter {\\n entityId: ID\\n tagKey: String\\n tagValue: String\\n eventTypes: [String!]\\n user: String\\n timeFrom: String\\n timeTo: String\\n}\",\"type EventMeta {\\n service: String!\\n time: String!\\n user: String\\n msgId: String!\\n correlationId: String!\\n causationId: String\\n}\",\"type EventTag {\\n key: String!\\n value: String!\\n}\"],\"mutations\":[\" Catalog_AddCategory(categoryId: ID!, name: String!): CommandResult!\",\" Catalog_AddProduct(productId: ID!, name: String!, description: String!, price: Float!, imageUrl: String!, categoryId: ID!): CommandResult!\",\" Catalog_ArchiveCategory(categoryId: ID!): CommandResult!\\n @aws_auth(cognito_groups: [\\\"Admin\\\"])\",\" Catalog_ChangeProductDescription(productId: ID!, description: String!): CommandResult!\",\" Catalog_ChangeProductImage(productId: ID!, imageUrl: String!): CommandResult!\",\" Catalog_ChangeProductName(productId: ID!, name: String!): CommandResult!\",\" Catalog_ChangeProductPrice(productId: ID!, price: Float!): CommandResult!\",\" Catalog_RenameCategory(categoryId: ID!, name: String!): CommandResult!\",\" Catalog_ImportProduct(sku: String!, title: String!, desc: String!, unitPrice: Float!, currency: String!, category: String!): CommandResult!\"],\"queries\":[\" Catalog_Category(id: ID!): Catalog_Category\",\" Catalog_CategoriesByIds(ids: [String!]!): [Catalog_Category!]!\",\" Catalog_Categories(filter: Catalog_CategoryFilter, first: Int, after: String, last: Int, before: String): Catalog_CategoryConnection!\",\" Catalog_ProductDemand(id: ID!): Catalog_ProductDemand\",\" Catalog_ProductDemandsByIds(ids: [String!]!): [Catalog_ProductDemand!]!\",\" Catalog_ProductDemands(filter: Catalog_ProductDemandFilter, first: Int, after: String, last: Int, before: String): Catalog_ProductDemandConnection!\",\" Catalog_Product(id: ID!): Catalog_Product\",\" Catalog_ProductsByIds(ids: [String!]!): [Catalog_Product!]!\",\" Catalog_Products(filter: Catalog_ProductFilter, first: Int, after: String, last: Int, before: String): Catalog_ProductConnection!\",\" Catalog_ImportProductAudit(id: ID!): Catalog_ImportProductAudit\",\" Catalog_ImportProductAuditsByIds(ids: [String!]!): [Catalog_ImportProductAudit!]!\",\" Catalog_ImportProductAudits(filter: Catalog_ImportProductAuditFilter, first: Int, after: String, last: Int, before: String): Catalog_ImportProductAuditConnection!\",\" Catalog_CatalogEventHistory(filter: Catalog_CatalogEventHistoryFilter, first: Int, after: String, last: Int, before: String): Catalog_CatalogEventRecordConnection!\"],\"subscriptions\":[\" onCatalog_AddCategory(id: ID): CommandResult\",\" onCatalog_AddProduct(id: ID): CommandResult\",\" onCatalog_ArchiveCategory(id: ID): CommandResult\",\" onCatalog_ChangeProductDescription(id: ID): CommandResult\",\" onCatalog_ChangeProductImage(id: ID): CommandResult\",\" onCatalog_ChangeProductName(id: ID): CommandResult\",\" onCatalog_ChangeProductPrice(id: ID): CommandResult\",\" onCatalog_RenameCategory(id: ID): CommandResult\",\" onCatalog_ImportProduct(id: ID): CommandResult\",\" onCatalogEventLog_eventAppended: CatalogEventLogEvent\"],\"subscriptionSources\":[{\"field\":\"onCatalog_AddCategory\",\"mutations\":[\"Catalog_AddCategory\"]},{\"field\":\"onCatalog_AddProduct\",\"mutations\":[\"Catalog_AddProduct\"]},{\"field\":\"onCatalog_ArchiveCategory\",\"mutations\":[\"Catalog_ArchiveCategory\"]},{\"field\":\"onCatalog_ChangeProductDescription\",\"mutations\":[\"Catalog_ChangeProductDescription\"]},{\"field\":\"onCatalog_ChangeProductImage\",\"mutations\":[\"Catalog_ChangeProductImage\"]},{\"field\":\"onCatalog_ChangeProductName\",\"mutations\":[\"Catalog_ChangeProductName\"]},{\"field\":\"onCatalog_ChangeProductPrice\",\"mutations\":[\"Catalog_ChangeProductPrice\"]},{\"field\":\"onCatalog_RenameCategory\",\"mutations\":[\"Catalog_RenameCategory\"]},{\"field\":\"onCatalog_ImportProduct\",\"mutations\":[\"Catalog_ImportProduct\"]}]}"},"eventCollector":"arn:aws:sqs:eu-west-1:000000000000:CatalogPluginEventColl-fc85d05","structure":{"outboundTranslationSlices":[],"extensions":[{"name":"Ordering.Orders","delegateNames":["RecordProductDemand"],"eventTypes":["Ordering.Orders.ItemOrdered","Ordering.Orders.ItemOrderCancelled"],"commandTypes":[]}],"stateChangeSlices":[{"consistencyRead":null,"chapter":"Category","linkedViews":["Categories"],"producedEventTypes":["Catalog.CategoryAdded"],"name":"AddCategory","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"AddCategory\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","aggregateIdField":"categoryId","mutationField":"Catalog_AddCategory","references":[],"level":"Collection","targetState":null,"apiExposed":true,"name":"AddCategory","allowedStates":null}],"events":[{"name":"CategoryAdded","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"CategoryAdded\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","references":[]}],"consumedEventTypes":[]},{"consistencyRead":"Categories","chapter":"Product","linkedViews":["ProductDemand","Products"],"producedEventTypes":["Catalog.ProductAdded"],"name":"AddProduct","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"AddProduct\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"},\"imageUrl\":{\"type\":\"string\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\",\"description\",\"price\",\"imageUrl\",\"categoryId\"]}","aggregateIdField":"productId","mutationField":"Catalog_AddProduct","references":[{"plugin":null,"entity":"Categories","fieldName":"categoryId"}],"level":"Collection","targetState":null,"apiExposed":true,"name":"AddProduct","allowedStates":null}],"events":[{"name":"ProductAdded","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductAdded\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"},\"imageUrl\":{\"type\":\"string\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\",\"description\",\"price\",\"imageUrl\",\"categoryId\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.CategoryAdded","Catalog.CategoryArchived"]},{"consistencyRead":null,"chapter":"Category","linkedViews":["Categories"],"producedEventTypes":["Catalog.CategoryArchived"],"name":"ArchiveCategory","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ArchiveCategory\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\"]}","aggregateIdField":"categoryId","mutationField":"Catalog_ArchiveCategory","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ArchiveCategory","allowedStates":null}],"events":[{"name":"CategoryArchived","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"CategoryArchived\"},\"categoryId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\"]}","references":[]}],"consumedEventTypes":[]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductDescriptionChanged"],"name":"ChangeProductDescription","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductDescription\"},\"productId\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"description\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductDescription","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductDescription","allowedStates":null}],"events":[{"name":"ProductDescriptionChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductDescriptionChanged\"},\"productId\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"description\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductDescriptionChanged"]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductImageChanged"],"name":"ChangeProductImage","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductImage\"},\"productId\":{\"type\":\"string\"},\"imageUrl\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"imageUrl\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductImage","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductImage","allowedStates":null}],"events":[{"name":"ProductImageChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductImageChanged\"},\"productId\":{\"type\":\"string\"},\"imageUrl\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"imageUrl\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductImageChanged"]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductNameChanged"],"name":"ChangeProductName","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductName\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductName","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductName","allowedStates":null}],"events":[{"name":"ProductNameChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductNameChanged\"},\"productId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"name\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductNameChanged"]},{"consistencyRead":"Products","chapter":"Product","linkedViews":["Products"],"producedEventTypes":["Catalog.ProductPriceChanged"],"name":"ChangeProductPrice","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ChangeProductPrice\"},\"productId\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"price\"]}","aggregateIdField":"productId","mutationField":"Catalog_ChangeProductPrice","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"ChangeProductPrice","allowedStates":null}],"events":[{"name":"ProductPriceChanged","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductPriceChanged\"},\"productId\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"price\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductPriceChanged"]},{"consistencyRead":"ProductDemand","chapter":"ProductDemand","linkedViews":["ProductDemand"],"producedEventTypes":["Catalog.ProductDemandRecorded","Catalog.ProductDemandRevoked"],"name":"RecordProductDemand","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"RecordDemand\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","aggregateIdField":"productId","mutationField":"","references":[],"level":"Instance","targetState":null,"apiExposed":false,"name":"RecordDemand","allowedStates":null},{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"RevokeDemand\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","aggregateIdField":"productId","mutationField":"","references":[],"level":"Instance","targetState":null,"apiExposed":false,"name":"RevokeDemand","allowedStates":null}],"events":[{"name":"ProductDemandRecorded","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductDemandRecorded\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","references":[]},{"name":"ProductDemandRevoked","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"ProductDemandRevoked\"},\"productId\":{\"type\":\"string\"},\"orderId\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"productId\",\"orderId\"]}","references":[]}],"consumedEventTypes":["Catalog.ProductDemandRecorded","Catalog.ProductDemandRevoked"]},{"consistencyRead":"Categories","chapter":"Category","linkedViews":["Categories"],"producedEventTypes":["Catalog.CategoryRenamed"],"name":"RenameCategory","commands":[{"schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"RenameCategory\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","aggregateIdField":"categoryId","mutationField":"Catalog_RenameCategory","references":[],"level":"Instance","targetState":null,"apiExposed":true,"name":"RenameCategory","allowedStates":null}],"events":[{"name":"CategoryRenamed","schema":"{\"type\":\"object\",\"properties\":{\"TAG\":{\"type\":\"string\",\"const\":\"CategoryRenamed\"},\"categoryId\":{\"type\":\"string\"},\"name\":{\"type\":\"string\"}},\"additionalProperties\":true,\"required\":[\"TAG\",\"categoryId\",\"name\"]}","references":[]}],"consumedEventTypes":["Catalog.CategoryAdded","Catalog.CategoryRenamed"]}],"extensionPoints":[{"name":"Catalog.Products","sourceEventTypes":["Catalog.ProductAdded","Catalog.ProductPriceChanged"],"delegateNames":["CatalogDcbEventLog"],"commandTypes":[]}],"readModels":[],"requiredStoreDeclarations":[{"field":"imageUrl","component":"AddProduct","store":"Catalog.productImages"},{"field":"imageUrl","component":"ChangeProductImage","store":"Catalog.productImages"},{"field":"imageUrl","component":"ImportProduct","store":"Catalog.productImages"},{"field":"imageUrl","component":"Products","store":"Catalog.productImages"}],"stateViewSlices":[{"schema":"{\"type\":\"object\",\"properties\":{\"categoryId\":{\"type\":\"string\",\"format\":\"uuid\"},\"name\":{\"type\":\"string\"},\"archived\":{\"type\":\"boolean\"}},\"required\":[\"categoryId\",\"name\",\"archived\"]}","searchableFields":["name"],"chapter":"Category","linkedWriteSide":["AddCategory","ArchiveCategory","RenameCategory"],"labelFieldSource":"convention","statusField":null,"visibility":null,"queryField":"Catalog_Categories","name":"Categories","consumedEventTypes":["Catalog.CategoryAdded","Catalog.CategoryRenamed","Catalog.CategoryArchived"],"labelField":"name"},{"schema":"{\"type\":\"object\",\"properties\":{\"productId\":{\"type\":\"string\",\"format\":\"uuid\"},\"name\":{\"type\":\"string\"},\"categoryId\":{\"type\":\"string\",\"format\":\"uuid\"},\"orderCount\":{\"type\":\"number\"}},\"required\":[\"productId\",\"name\",\"categoryId\",\"orderCount\"]}","searchableFields":["name"],"chapter":"Product","linkedWriteSide":["AddProduct","RecordProductDemand"],"labelFieldSource":"convention","statusField":null,"visibility":null,"queryField":"Catalog_ProductDemands","name":"ProductDemand","consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductDemandRecorded","Catalog.ProductDemandRevoked"],"labelField":"name"},{"schema":"{\"type\":\"object\",\"properties\":{\"productId\":{\"type\":\"string\",\"format\":\"uuid\"},\"name\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"},\"price\":{\"type\":\"number\"},\"imageUrl\":{\"type\":\"string\",\"x-reventless-semantic\":\"storageRef\",\"x-reventless-semantic-source\":\"type\",\"x-reventless-semantic-target\":{\"store\":\"productImages\"}},\"categoryId\":{\"type\":\"string\",\"format\":\"uuid\"}},\"required\":[\"productId\",\"name\",\"description\",\"price\",\"imageUrl\",\"categoryId\"]}","searchableFields":["name"],"chapter":"Product","linkedWriteSide":["AddProduct","ChangeProductDescription","ChangeProductImage","ChangeProductName","ChangeProductPrice"],"labelFieldSource":"convention","statusField":null,"visibility":null,"queryField":"Catalog_Products","name":"Products","consumedEventTypes":["Catalog.ProductAdded","Catalog.ProductNameChanged","Catalog.ProductDescriptionChanged","Catalog.ProductPriceChanged","Catalog.ProductImageChanged"],"labelField":"name"}],"aggregates":[],"inboundTranslationSlices":[{"name":"ImportProduct","chapter":"Product","targetName":"AddProduct","commandTypes":["Catalog.AddProduct"],"externalSystem":"SupplierFeed"}],"automationSlices":[],"requiredStores":["Catalog.productImages"]}}}}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Plugin lifecycle payload corpus
|
|
2
|
+
|
|
3
|
+
Real `Plugin` aggregate event payloads, exactly as they were written to a deployed event log,
|
|
4
|
+
kept so that every one of them still decodes against the **current** `PluginSpec.eventSchema`.
|
|
5
|
+
|
|
6
|
+
Read by [`PluginLifecycleCorpusTest.res`](../../plugin/PluginLifecycleCorpusTest.res) through
|
|
7
|
+
[`PluginLifecycleCorpus.res`](../../plugin/PluginLifecycleCorpus.res).
|
|
8
|
+
|
|
9
|
+
## Never regenerate these files
|
|
10
|
+
|
|
11
|
+
They are frozen. A fixture rebuilt from today's ReScript types tests nothing — it tracks the schema
|
|
12
|
+
it is supposed to be pinning, which is exactly how the 2026-07-30 wedge got past the two
|
|
13
|
+
hand-constructed cases already in `MessageTest.res`.
|
|
14
|
+
|
|
15
|
+
**Adding** an entry is fine, and is what you do when a payload shape changes: take a real event from
|
|
16
|
+
a deployed log and append it. **Editing or re-encoding** an existing entry defeats the point.
|
|
17
|
+
|
|
18
|
+
## What each entry pins
|
|
19
|
+
|
|
20
|
+
| file | shape generation |
|
|
21
|
+
|---|---|
|
|
22
|
+
| `2026-07-22-versionconnected-no-requiredstores.json` | before `requiredStores` existed |
|
|
23
|
+
| `2026-07-22-versionsuperseded-nested-definitions.json` | the `VersionSuperseded` payload — two nested definitions, not one |
|
|
24
|
+
| `2026-07-28-versionconnected-requiredstores-only.json` | `requiredStores` present, `requiredStoreDeclarations` not yet |
|
|
25
|
+
| `2026-07-30-versionconnected-declarations-without-annotation.json` | declarations as `{store, component, field}` — the payload that froze the `Catalog` plugin when `annotation: string` was added as required |
|
|
26
|
+
| `2026-07-30-versiondisconnected-declarations-without-annotation.json` | same generation, the other variant the aggregate re-emits from stored state |
|
|
27
|
+
|
|
28
|
+
## Provenance
|
|
29
|
+
|
|
30
|
+
Recovered from the `Catalog` partition of a deployed `PluginAggrEventLog` table on 2026-08-01.
|
|
31
|
+
Each file is the decode-relevant part of the stored row — `{event, data}` — which is what
|
|
32
|
+
`EventLog_Operations.decodeEvent` reassembles via `Message.combineMessage` before decoding.
|
|
33
|
+
|
|
34
|
+
One transformation was applied at extraction: the AWS account id in embedded ARNs and queue URLs
|
|
35
|
+
was replaced with `000000000000`. The corpus asserts *shape*, and the shape of a string does not
|
|
36
|
+
depend on its contents.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Declaration-site tripwire for the schema-evolution rule documented on
|
|
2
|
+
// `Plugin.pluginStructure`.
|
|
3
|
+
//
|
|
4
|
+
// The sibling corpus test (PluginLifecycleCorpusTest) proves stored payloads still
|
|
5
|
+
// decode. It cannot catch a newly added required scalar, because since the healer
|
|
6
|
+
// learned to invent scalars they DO still decode — with a fabricated value and a
|
|
7
|
+
// runtime warning. A warning in a deployed log is roughly the signal that let the
|
|
8
|
+
// original two-day freeze go unnoticed, so the guard belongs here instead: in CI, at
|
|
9
|
+
// the moment the field is declared.
|
|
10
|
+
//
|
|
11
|
+
// Adding a `js_nullable` / array / enum / object field leaves this list untouched.
|
|
12
|
+
// Adding a bare required scalar changes it, and the diff is the conversation.
|
|
13
|
+
|
|
14
|
+
open JestGlobals
|
|
15
|
+
|
|
16
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
17
|
+
|
|
18
|
+
// The checked-in list. See the header of that file before changing it.
|
|
19
|
+
let golden = () =>
|
|
20
|
+
NodeFs.readFileSync(
|
|
21
|
+
NodePath.dirname(NodeUrl.fileURLToPath(moduleUrl)) ++ "/pluginDefinitionRequiredScalars.txt",
|
|
22
|
+
)
|
|
23
|
+
->String.split("\n")
|
|
24
|
+
->Array.map(String.trim)
|
|
25
|
+
->Array.filter(line => line != "" && !(line->String.startsWith("#")))
|
|
26
|
+
|
|
27
|
+
describe("pluginDefinition's required scalar fields", () => {
|
|
28
|
+
let actual = PluginDefinitionScalars.collect(Reventless.Plugin.pluginDefinitionSchema)
|
|
29
|
+
let expected = golden()
|
|
30
|
+
|
|
31
|
+
testSync("the golden list is populated (an empty read would pass vacuously)", () =>
|
|
32
|
+
expect(expected->Array.length > 0)->toBe(true)
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
testSync("no bare required scalar has been added or removed", () => {
|
|
36
|
+
let added = actual->Array.filter(f => !(expected->Array.includes(f)))
|
|
37
|
+
let removed = expected->Array.filter(f => !(actual->Array.includes(f)))
|
|
38
|
+
let describe = (label, fields) =>
|
|
39
|
+
fields->Array.length == 0 ? "" : `\n ${label}: ${fields->Array.join("\n ")}`
|
|
40
|
+
expect(describe("ADDED", added) ++ describe("REMOVED", removed))->toBe("")
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Nodefs from "node:fs";
|
|
4
|
+
import * as Nodeurl from "node:url";
|
|
5
|
+
import * as Nodepath from "node:path";
|
|
6
|
+
import * as Plugin$Reventless from "@reventlessdev/reventless-spec/src/components/Plugin.res.mjs";
|
|
7
|
+
import * as PluginDefinitionScalars$ReventlessCore from "./PluginDefinitionScalars.res.mjs";
|
|
8
|
+
|
|
9
|
+
let moduleUrl = import.meta.url;
|
|
10
|
+
|
|
11
|
+
function golden() {
|
|
12
|
+
return Nodefs.readFileSync(Nodepath.dirname(Nodeurl.fileURLToPath(moduleUrl)) + "/pluginDefinitionRequiredScalars.txt", "utf8").split("\n").map(prim => prim.trim()).filter(line => {
|
|
13
|
+
if (line !== "") {
|
|
14
|
+
return !line.startsWith("#");
|
|
15
|
+
} else {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
globalThis.describe("pluginDefinition's required scalar fields", () => {
|
|
22
|
+
let actual = PluginDefinitionScalars$ReventlessCore.collect(Plugin$Reventless.pluginDefinitionSchema);
|
|
23
|
+
let expected = golden();
|
|
24
|
+
globalThis.test("the golden list is populated (an empty read would pass vacuously)", () => {
|
|
25
|
+
globalThis.expect(expected.length !== 0).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
globalThis.test("no bare required scalar has been added or removed", () => {
|
|
28
|
+
let added = actual.filter(f => !expected.includes(f));
|
|
29
|
+
let removed = expected.filter(f => !actual.includes(f));
|
|
30
|
+
let describe = (label, fields) => {
|
|
31
|
+
if (fields.length === 0) {
|
|
32
|
+
return "";
|
|
33
|
+
} else {
|
|
34
|
+
return `\n ` + label + `: ` + fields.join("\n ");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
globalThis.expect(describe("ADDED", added) + describe("REMOVED", removed)).toBe("");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
moduleUrl,
|
|
43
|
+
golden,
|
|
44
|
+
}
|
|
45
|
+
/* moduleUrl Not a pure module */
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Collects every bare required scalar reachable from a sury schema.
|
|
2
|
+
//
|
|
3
|
+
// Walks sury's own tagged variant (`@tag("type") type t<'value>`), the same way
|
|
4
|
+
// `SchemaType.fromSury` does — so a change to sury's schema surface is a compile
|
|
5
|
+
// error here rather than a walker that silently returns nothing. That matters
|
|
6
|
+
// more than usual for this one: it backs a guard whose only job is to fail at
|
|
7
|
+
// the right moment, and a guard that quietly collects `[]` passes while checking
|
|
8
|
+
// nothing.
|
|
9
|
+
//
|
|
10
|
+
// A scalar is "bare required" when `Message.fillMissingDefaults` could not supply
|
|
11
|
+
// a value for it from the schema alone. Everything else it CAN supply is skipped:
|
|
12
|
+
//
|
|
13
|
+
// `T | null` union → null (the `js_nullable` shape the rule asks for)
|
|
14
|
+
// const / enum union → the literal
|
|
15
|
+
// array → []
|
|
16
|
+
// object → {} filled recursively
|
|
17
|
+
//
|
|
18
|
+
// A scalar arm of a nullable union is therefore not reported — but object and
|
|
19
|
+
// array arms are still descended, nullable or not: when an old payload happens to
|
|
20
|
+
// carry a nullable parent, a scalar added inside it still has to be invented.
|
|
21
|
+
// `requiredStoreDeclarations[].annotation`, a required string inside a nullable
|
|
22
|
+
// array, is exactly that case and is how a plugin's registration once froze.
|
|
23
|
+
|
|
24
|
+
let scalarName = (schema: S.t<unknown>): option<string> =>
|
|
25
|
+
switch schema {
|
|
26
|
+
| String({const: ?None}) => Some("string")
|
|
27
|
+
| Number({const: ?None}) => Some("number")
|
|
28
|
+
| Boolean({const: ?None}) => Some("boolean")
|
|
29
|
+
| BigInt({const: ?None}) => Some("bigint")
|
|
30
|
+
| _ => None
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let isScalar = (schema: S.t<unknown>): bool => scalarName(schema)->Option.isSome
|
|
34
|
+
|
|
35
|
+
let collect = (root: S.t<'a>): array<string> => {
|
|
36
|
+
let root = root->S.castToUnknown
|
|
37
|
+
let out = []
|
|
38
|
+
// Guards against a self-referential schema. Identity, not structure: sury
|
|
39
|
+
// shares one object per schema, so a cycle revisits the same reference.
|
|
40
|
+
let seen: Set.t<S.t<unknown>> = Set.make()
|
|
41
|
+
|
|
42
|
+
let rec walk = (schema: S.t<unknown>, path: string) =>
|
|
43
|
+
switch schema {
|
|
44
|
+
| Object({items}) =>
|
|
45
|
+
if !(seen->Set.has(schema)) {
|
|
46
|
+
seen->Set.add(schema)
|
|
47
|
+
items->Array.forEach(item => walk(item.schema, `${path}.${item.location}`))
|
|
48
|
+
seen->Set.delete(schema)->ignore
|
|
49
|
+
}
|
|
50
|
+
| Array({additionalItems: Schema(element)}) => walk(element, `${path}[]`)
|
|
51
|
+
| Union({anyOf, has}) =>
|
|
52
|
+
// A union of literals is an enum: absent heals to the first variant.
|
|
53
|
+
let isEnum = anyOf->Array.every(member =>
|
|
54
|
+
switch member {
|
|
55
|
+
| String({const: ?Some(_)})
|
|
56
|
+
| Number({const: ?Some(_)})
|
|
57
|
+
| Boolean({const: ?Some(_)})
|
|
58
|
+
| BigInt({const: ?Some(_)})
|
|
59
|
+
| Null(_) => true
|
|
60
|
+
| _ => false
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
if !isEnum {
|
|
64
|
+
let nullable = has.null->Option.getOr(false)
|
|
65
|
+
anyOf->Array.forEach(member =>
|
|
66
|
+
switch member {
|
|
67
|
+
| Null(_) => ()
|
|
68
|
+
| _ if nullable && isScalar(member) => ()
|
|
69
|
+
| _ => walk(member, path)
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
| _ => scalarName(schema)->Option.forEach(name => out->Array.push(`${path}: ${name}`))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
walk(root, "")
|
|
77
|
+
out->Array.toSorted(String.compare)
|
|
78
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
|
+
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
5
|
+
|
|
6
|
+
function scalarName(schema) {
|
|
7
|
+
switch (schema.type) {
|
|
8
|
+
case "string" :
|
|
9
|
+
if (schema.const !== undefined) {
|
|
10
|
+
return;
|
|
11
|
+
} else {
|
|
12
|
+
return "string";
|
|
13
|
+
}
|
|
14
|
+
case "number" :
|
|
15
|
+
if (schema.const !== undefined) {
|
|
16
|
+
return;
|
|
17
|
+
} else {
|
|
18
|
+
return "number";
|
|
19
|
+
}
|
|
20
|
+
case "bigint" :
|
|
21
|
+
if (schema.const !== undefined) {
|
|
22
|
+
return;
|
|
23
|
+
} else {
|
|
24
|
+
return "bigint";
|
|
25
|
+
}
|
|
26
|
+
case "boolean" :
|
|
27
|
+
if (schema.const !== undefined) {
|
|
28
|
+
return;
|
|
29
|
+
} else {
|
|
30
|
+
return "boolean";
|
|
31
|
+
}
|
|
32
|
+
default:
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isScalar(schema) {
|
|
38
|
+
return Stdlib_Option.isSome(scalarName(schema));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function collect(root) {
|
|
42
|
+
let out = [];
|
|
43
|
+
let seen = new Set();
|
|
44
|
+
let walk = (_schema, _path) => {
|
|
45
|
+
while (true) {
|
|
46
|
+
let path = _path;
|
|
47
|
+
let schema = _schema;
|
|
48
|
+
switch (schema.type) {
|
|
49
|
+
case "array" :
|
|
50
|
+
let element = schema.additionalItems;
|
|
51
|
+
if (element === "strip" || element === "strict") {
|
|
52
|
+
element === "strip";
|
|
53
|
+
} else {
|
|
54
|
+
_path = path + `[]`;
|
|
55
|
+
_schema = element;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
break;
|
|
59
|
+
case "object" :
|
|
60
|
+
if (!seen.has(schema)) {
|
|
61
|
+
seen.add(schema);
|
|
62
|
+
schema.items.forEach(item => walk(item.schema, path + `.` + item.location));
|
|
63
|
+
seen.delete(schema);
|
|
64
|
+
return;
|
|
65
|
+
} else {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
case "union" :
|
|
69
|
+
let anyOf = schema.anyOf;
|
|
70
|
+
let isEnum = anyOf.every(member => {
|
|
71
|
+
switch (member.type) {
|
|
72
|
+
case "string" :
|
|
73
|
+
case "number" :
|
|
74
|
+
case "bigint" :
|
|
75
|
+
case "boolean" :
|
|
76
|
+
return member.const !== undefined;
|
|
77
|
+
case "null" :
|
|
78
|
+
return true;
|
|
79
|
+
default:
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (isEnum) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
let nullable = Stdlib_Option.getOr(schema.has.null, false);
|
|
87
|
+
anyOf.forEach(member => {
|
|
88
|
+
if (member.type === "null" || nullable && Stdlib_Option.isSome(scalarName(member))) {
|
|
89
|
+
return;
|
|
90
|
+
} else {
|
|
91
|
+
return walk(member, path);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
return Stdlib_Option.forEach(scalarName(schema), name => {
|
|
97
|
+
out.push(path + `: ` + name);
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
walk(root, "");
|
|
102
|
+
return out.toSorted(Primitive_string.compare);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
scalarName,
|
|
107
|
+
isScalar,
|
|
108
|
+
collect,
|
|
109
|
+
}
|
|
110
|
+
/* No side effect */
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Loads the frozen plugin-lifecycle payload corpus off disk. See
|
|
2
|
+
// tests/fixtures/plugin-lifecycle/README.md.
|
|
3
|
+
//
|
|
4
|
+
// Reads the directory rather than listing the files here, so adding a fixture is
|
|
5
|
+
// a matter of dropping the JSON in — the point of the corpus is that it grows by
|
|
6
|
+
// appending real payloads.
|
|
7
|
+
|
|
8
|
+
type entry = {
|
|
9
|
+
name: string,
|
|
10
|
+
event: string,
|
|
11
|
+
data: dict<JSON.t>,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Resolved against this module rather than the working directory: the suite runs
|
|
15
|
+
// from the repo root and from the package, and the fixtures sit beside neither.
|
|
16
|
+
// `import.meta.url` is the repo's established way to ask (cf.
|
|
17
|
+
// CommandGeneratorFixtures) — a language constant, not reflection.
|
|
18
|
+
let moduleUrl: string = %raw(`import.meta.url`)
|
|
19
|
+
let dir = NodePath.dirname(NodeUrl.fileURLToPath(moduleUrl)) ++ "/../fixtures/plugin-lifecycle"
|
|
20
|
+
|
|
21
|
+
let parse = (~name: string, raw: string): option<entry> =>
|
|
22
|
+
raw
|
|
23
|
+
->JSON.parseOrThrow
|
|
24
|
+
->JSON.Decode.object
|
|
25
|
+
->Option.flatMap(obj =>
|
|
26
|
+
switch (
|
|
27
|
+
obj->Dict.get("event")->Option.flatMap(JSON.Decode.string),
|
|
28
|
+
obj->Dict.get("data")->Option.flatMap(JSON.Decode.object),
|
|
29
|
+
) {
|
|
30
|
+
| (Some(event), Some(data)) => Some({name, event, data})
|
|
31
|
+
| _ => None
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
// Sorted so the corpus reads in shape-generation order (filenames are
|
|
36
|
+
// date-prefixed) and a failure names the same entry on every machine.
|
|
37
|
+
let entries: array<entry> =
|
|
38
|
+
NodeFs.readdirSync(dir, {withFileTypes: true})
|
|
39
|
+
->Array.map(NodeFs.direntName)
|
|
40
|
+
->Array.filter(name => name->String.endsWith(".json"))
|
|
41
|
+
->Array.toSorted(String.compare)
|
|
42
|
+
->Array.filterMap(name => parse(~name, NodeFs.readFileSync(`${dir}/${name}`)))
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Nodefs from "node:fs";
|
|
4
|
+
import * as Nodeurl from "node:url";
|
|
5
|
+
import * as Nodepath from "node:path";
|
|
6
|
+
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
7
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
8
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
|
+
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
10
|
+
|
|
11
|
+
let moduleUrl = import.meta.url;
|
|
12
|
+
|
|
13
|
+
let dir = Nodepath.dirname(Nodeurl.fileURLToPath(moduleUrl)) + "/../fixtures/plugin-lifecycle";
|
|
14
|
+
|
|
15
|
+
function parse(name, raw) {
|
|
16
|
+
return Stdlib_Option.flatMap(Stdlib_JSON.Decode.object(JSON.parse(raw)), obj => {
|
|
17
|
+
let match = Stdlib_Option.flatMap(obj["event"], Stdlib_JSON.Decode.string);
|
|
18
|
+
let match$1 = Stdlib_Option.flatMap(obj["data"], Stdlib_JSON.Decode.object);
|
|
19
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
20
|
+
return {
|
|
21
|
+
name: name,
|
|
22
|
+
event: match,
|
|
23
|
+
data: match$1
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let entries = Stdlib_Array.filterMap(Nodefs.readdirSync(dir, {
|
|
30
|
+
withFileTypes: true
|
|
31
|
+
}).map(prim => prim.name).filter(name => name.endsWith(".json")).toSorted(Primitive_string.compare), name => parse(name, Nodefs.readFileSync(dir + `/` + name, "utf8")));
|
|
32
|
+
|
|
33
|
+
export {
|
|
34
|
+
moduleUrl,
|
|
35
|
+
dir,
|
|
36
|
+
parse,
|
|
37
|
+
entries,
|
|
38
|
+
}
|
|
39
|
+
/* moduleUrl Not a pure module */
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Frozen-payload compatibility corpus for the Plugin lifecycle aggregate.
|
|
2
|
+
//
|
|
3
|
+
// The Plugin aggregate replays its own event log before every decision, so ONE
|
|
4
|
+
// undecodable stored event freezes Heartbeat / Redetect / Connect for that plugin
|
|
5
|
+
// permanently — and it does so silently, surfacing only as a registration that
|
|
6
|
+
// stops tracking deploys. See docs/analysis/plugin-definition-schema-evolution-wedge.md.
|
|
7
|
+
//
|
|
8
|
+
// The two hand-constructed cases in MessageTest build a `pluginDefinition` from the
|
|
9
|
+
// CURRENT ReScript type and then strip keys. That literal recompiles with every
|
|
10
|
+
// schema change, so it can only test the fields whoever wrote it thought to strip —
|
|
11
|
+
// which is why it did not catch `annotation: string`. These fixtures are frozen JSON
|
|
12
|
+
// captured off a deployed log and are never regenerated; see the corpus README.
|
|
13
|
+
//
|
|
14
|
+
// What turns this suite red is a change no amount of healing can absorb: a field
|
|
15
|
+
// whose TYPE changed under stored data (`float` → an object, say), a `bigint`, or a
|
|
16
|
+
// genuinely corrupt payload. It names the fixture and the sury field path. The fix is
|
|
17
|
+
// to make the change decodable — never to re-cut the fixtures.
|
|
18
|
+
//
|
|
19
|
+
// A newly added required *scalar* does NOT land here: `fillMissingDefaults` invents a
|
|
20
|
+
// value for it, so these still decode. That case is caught by the sibling
|
|
21
|
+
// PluginDefinitionRequiredScalarsTest, at the declaration site.
|
|
22
|
+
|
|
23
|
+
open JestGlobals
|
|
24
|
+
|
|
25
|
+
let entries = PluginLifecycleCorpus.entries
|
|
26
|
+
|
|
27
|
+
// Mirrors EventLog_Operations.decodeEvent: reassemble the stored `{event, data}`
|
|
28
|
+
// pair into a variant and decode it — the exact call replay makes.
|
|
29
|
+
let decodeStored = (entry: PluginLifecycleCorpus.entry) =>
|
|
30
|
+
Message.combineMessage(entry.event, entry.data)->Message.decode(PluginSpec.eventSchema)
|
|
31
|
+
|
|
32
|
+
describe("The stored plugin-lifecycle payload corpus", () => {
|
|
33
|
+
testSync("is not empty (a corpus that loaded nothing would pass vacuously)", () =>
|
|
34
|
+
expect(entries->Array.length > 0)->toBe(true)
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
entries->Array.forEach(entry =>
|
|
38
|
+
testSync(`still decodes: ${entry.name}`, () => {
|
|
39
|
+
// Sury's own exception carries the field path, which is the whole value of
|
|
40
|
+
// this suite's failure message — report it verbatim rather than "it threw".
|
|
41
|
+
let outcome = switch decodeStored(entry) {
|
|
42
|
+
| _ => "decodes"
|
|
43
|
+
| exception S.Error(err) => err.message
|
|
44
|
+
| exception JsExn(e) => `threw: ${JsExn.message(e)->Option.getOr("no message")}`
|
|
45
|
+
| exception _ => "threw a non-JS exception"
|
|
46
|
+
}
|
|
47
|
+
expect(outcome)->toBe("decodes")
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as S from "sury/src/S.res.mjs";
|
|
4
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
5
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
7
|
+
import * as Message$ReventlessCore from "../../src/Message.res.mjs";
|
|
8
|
+
import * as PluginSpec$ReventlessCore from "../../src/plugin/lifecycle/PluginSpec.res.mjs";
|
|
9
|
+
import * as PluginLifecycleCorpus$ReventlessCore from "./PluginLifecycleCorpus.res.mjs";
|
|
10
|
+
|
|
11
|
+
function decodeStored(entry) {
|
|
12
|
+
return Message$ReventlessCore.decode(Message$ReventlessCore.combineMessage(entry.event, entry.data), PluginSpec$ReventlessCore.eventSchema);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
globalThis.describe("The stored plugin-lifecycle payload corpus", () => {
|
|
16
|
+
globalThis.test("is not empty (a corpus that loaded nothing would pass vacuously)", () => {
|
|
17
|
+
globalThis.expect(PluginLifecycleCorpus$ReventlessCore.entries.length !== 0).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
PluginLifecycleCorpus$ReventlessCore.entries.forEach(entry => {
|
|
20
|
+
globalThis.test(`still decodes: ` + entry.name, () => {
|
|
21
|
+
let outcome;
|
|
22
|
+
try {
|
|
23
|
+
decodeStored(entry);
|
|
24
|
+
outcome = "decodes";
|
|
25
|
+
} catch (raw_err) {
|
|
26
|
+
let err = Primitive_exceptions.internalToException(raw_err);
|
|
27
|
+
outcome = err.RE_EXN_ID === S.$$Error ? err._1.message : (
|
|
28
|
+
err.RE_EXN_ID === "JsExn" ? `threw: ` + Stdlib_Option.getOr(Stdlib_JsExn.message(err._1), "no message") : "threw a non-JS exception"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
globalThis.expect(outcome).toBe("decodes");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
let entries = PluginLifecycleCorpus$ReventlessCore.entries;
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
entries,
|
|
40
|
+
decodeStored,
|
|
41
|
+
}
|
|
42
|
+
/* Not a pure module */
|