@farukada/aws-langgraph-dynamodb-ts 1.0.0-rc.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +390 -193
- package/dist/{backfill → cjs/backfill}/backfill.d.ts +15 -12
- package/dist/cjs/backfill/backfill.js +177 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/delete-thread.d.ts +1 -1
- package/dist/cjs/checkpointer/actions/delete-thread.js +26 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/get-tuple.d.ts +4 -3
- package/dist/cjs/checkpointer/actions/get-tuple.js +22 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/list.d.ts +7 -4
- package/dist/cjs/checkpointer/actions/list.js +70 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/put-writes.d.ts +8 -6
- package/dist/cjs/checkpointer/actions/put-writes.js +21 -0
- package/dist/{checkpointer → cjs/checkpointer}/actions/put.d.ts +21 -15
- package/dist/cjs/checkpointer/actions/put.js +79 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/delta-history.d.ts +38 -26
- package/dist/cjs/checkpointer/internal/delta-history.js +131 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/listing.d.ts +4 -4
- package/dist/cjs/checkpointer/internal/listing.js +104 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/parse.d.ts +51 -15
- package/dist/cjs/checkpointer/internal/parse.js +184 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/pending-writes.d.ts +64 -25
- package/dist/cjs/checkpointer/internal/pending-writes.js +241 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/read.d.ts +15 -10
- package/dist/cjs/checkpointer/internal/read.js +132 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/rows.d.ts +94 -21
- package/dist/cjs/checkpointer/internal/rows.js +356 -0
- package/dist/{checkpointer → cjs/checkpointer}/internal/setup.d.ts +13 -20
- package/dist/cjs/checkpointer/internal/setup.js +25 -0
- package/dist/{checkpointer → cjs/checkpointer}/saver.d.ts +72 -36
- package/dist/cjs/checkpointer/saver.js +56 -0
- package/dist/{checkpointer → cjs/checkpointer}/types.d.ts +1 -1
- package/dist/cjs/checkpointer/types.js +2 -0
- package/dist/{factory → cjs/factory}/factory.d.ts +25 -20
- package/dist/cjs/factory/factory.js +137 -0
- package/dist/{factory → cjs/factory}/types.d.ts +12 -12
- package/dist/cjs/factory/types.js +2 -0
- package/dist/{history → cjs/history}/actions/add-messages.d.ts +18 -10
- package/dist/cjs/history/actions/add-messages.js +17 -0
- package/dist/{history → cjs/history}/actions/clear.d.ts +1 -1
- package/dist/cjs/history/actions/clear.js +29 -0
- package/dist/{history → cjs/history}/actions/get-messages.d.ts +11 -9
- package/dist/cjs/history/actions/get-messages.js +58 -0
- package/dist/{history → cjs/history}/actions/list-sessions.d.ts +3 -3
- package/dist/cjs/history/actions/list-sessions.js +67 -0
- package/dist/{history → cjs/history}/actions/reconcile-count.d.ts +13 -9
- package/dist/cjs/history/actions/reconcile-count.js +8 -0
- package/dist/{history → cjs/history}/chat-message-history.d.ts +62 -30
- package/dist/cjs/history/chat-message-history.js +61 -0
- package/dist/{history → cjs/history}/internal/append.d.ts +64 -32
- package/dist/cjs/history/internal/append.js +267 -0
- package/dist/{history → cjs/history}/internal/message-read.d.ts +3 -3
- package/dist/cjs/history/internal/message-read.js +93 -0
- package/dist/{history → cjs/history}/internal/parse.d.ts +2 -2
- package/dist/cjs/history/internal/parse.js +113 -0
- package/dist/{history → cjs/history}/internal/rows.d.ts +11 -10
- package/dist/cjs/history/internal/rows.js +96 -0
- package/dist/{history → cjs/history}/internal/session.d.ts +41 -22
- package/dist/cjs/history/internal/session.js +296 -0
- package/dist/{history → cjs/history}/internal/setup.d.ts +2 -2
- package/dist/cjs/history/internal/setup.js +60 -0
- package/dist/{history → cjs/history}/session-adapter.d.ts +0 -6
- package/dist/cjs/history/session-adapter.js +38 -0
- package/dist/{history → cjs/history}/types.d.ts +18 -15
- package/dist/cjs/history/types.js +2 -0
- package/dist/{index.d.ts → cjs/index.d.ts} +27 -27
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/package.json +1 -0
- package/dist/{shared → cjs/shared}/adapter.d.ts +27 -16
- package/dist/cjs/shared/adapter.js +70 -0
- package/dist/cjs/shared/clock.js +14 -0
- package/dist/{shared → cjs/shared}/codec/codec.d.ts +37 -20
- package/dist/cjs/shared/codec/codec.js +162 -0
- package/dist/{shared → cjs/shared}/codec/compression.d.ts +9 -4
- package/dist/cjs/shared/codec/compression.js +45 -0
- package/dist/cjs/shared/codec/json-serde.js +58 -0
- package/dist/{shared → cjs/shared}/codec/s3/client-types.d.ts +2 -1
- package/dist/cjs/shared/codec/s3/client-types.js +6 -0
- package/dist/{shared → cjs/shared}/codec/s3/client.d.ts +25 -7
- package/dist/cjs/shared/codec/s3/client.js +78 -0
- package/dist/{shared → cjs/shared}/codec/s3/config.d.ts +12 -7
- package/dist/cjs/shared/codec/s3/config.js +92 -0
- package/dist/{shared → cjs/shared}/codec/s3/lifecycle.d.ts +71 -17
- package/dist/cjs/shared/codec/s3/lifecycle.js +223 -0
- package/dist/{shared → cjs/shared}/codec/s3/offloader.d.ts +42 -29
- package/dist/cjs/shared/codec/s3/offloader.js +289 -0
- package/dist/cjs/shared/concurrency.js +31 -0
- package/dist/{shared → cjs/shared}/dynamodb/abort.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/abort.js +16 -0
- package/dist/{shared → cjs/shared}/dynamodb/batch-write.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/batch-write.js +79 -0
- package/dist/cjs/shared/dynamodb/cancellation.js +37 -0
- package/dist/{shared → cjs/shared}/dynamodb/client.d.ts +24 -22
- package/dist/cjs/shared/dynamodb/client.js +40 -0
- package/dist/{shared → cjs/shared}/dynamodb/idempotent-write.d.ts +64 -19
- package/dist/cjs/shared/dynamodb/idempotent-write.js +173 -0
- package/dist/{shared → cjs/shared}/dynamodb/paginate.d.ts +2 -2
- package/dist/cjs/shared/dynamodb/paginate.js +90 -0
- package/dist/{shared → cjs/shared}/dynamodb/partition-delete.d.ts +6 -6
- package/dist/cjs/shared/dynamodb/partition-delete.js +177 -0
- package/dist/{shared → cjs/shared}/dynamodb/recency-index.d.ts +27 -15
- package/dist/cjs/shared/dynamodb/recency-index.js +146 -0
- package/dist/{shared → cjs/shared}/dynamodb/retry.d.ts +37 -6
- package/dist/cjs/shared/dynamodb/retry.js +193 -0
- package/dist/cjs/shared/dynamodb/row-size.d.ts +33 -0
- package/dist/cjs/shared/dynamodb/row-size.js +30 -0
- package/dist/{shared → cjs/shared}/dynamodb/table-schema.d.ts +27 -18
- package/dist/cjs/shared/dynamodb/table-schema.js +52 -0
- package/dist/{shared → cjs/shared}/errors/base-error.d.ts +42 -7
- package/dist/cjs/shared/errors/base-error.js +73 -0
- package/dist/{shared → cjs/shared}/errors/boundary.d.ts +29 -14
- package/dist/cjs/shared/errors/boundary.js +61 -0
- package/dist/cjs/shared/errors/classify.d.ts +206 -0
- package/dist/cjs/shared/errors/classify.js +232 -0
- package/dist/{shared → cjs/shared}/errors/error-code.d.ts +17 -10
- package/dist/cjs/shared/errors/error-code.js +27 -0
- package/dist/{shared → cjs/shared}/errors/errors.d.ts +75 -9
- package/dist/cjs/shared/errors/errors.js +123 -0
- package/dist/cjs/shared/logging/logger.js +30 -0
- package/dist/{shared → cjs/shared}/logging/redaction.d.ts +8 -4
- package/dist/cjs/shared/logging/redaction.js +145 -0
- package/dist/{shared → cjs/shared}/logging/secret-patterns.d.ts +30 -7
- package/dist/cjs/shared/logging/secret-patterns.js +93 -0
- package/dist/cjs/shared/logging/truncate.js +31 -0
- package/dist/{shared → cjs/shared}/options.d.ts +27 -11
- package/dist/cjs/shared/options.js +2 -0
- package/dist/cjs/shared/ulid.js +83 -0
- package/dist/{shared → cjs/shared}/validation/collaborators.d.ts +21 -2
- package/dist/cjs/shared/validation/collaborators.js +79 -0
- package/dist/{shared → cjs/shared}/validation/option-shape.d.ts +7 -5
- package/dist/cjs/shared/validation/option-shape.js +31 -0
- package/dist/{shared → cjs/shared}/validation/options.d.ts +4 -4
- package/dist/cjs/shared/validation/options.js +166 -0
- package/dist/cjs/shared/validation/primitives.js +114 -0
- package/dist/{shared → cjs/shared}/validation/ttl.d.ts +26 -9
- package/dist/cjs/shared/validation/ttl.js +52 -0
- package/dist/{store → cjs/store}/actions/list-namespaces.d.ts +5 -5
- package/dist/cjs/store/actions/list-namespaces.js +92 -0
- package/dist/{store → cjs/store}/actions/put.d.ts +11 -4
- package/dist/cjs/store/actions/put.js +49 -0
- package/dist/{store → cjs/store}/actions/reconcile-vector-index.d.ts +5 -5
- package/dist/cjs/store/actions/reconcile-vector-index.js +13 -0
- package/dist/{store → cjs/store}/actions/search.d.ts +2 -2
- package/dist/cjs/store/actions/search.js +26 -0
- package/dist/cjs/store/internal/batch-plan.d.ts +56 -0
- package/dist/cjs/store/internal/batch-plan.js +32 -0
- package/dist/{store → cjs/store}/internal/filter.d.ts +3 -3
- package/dist/cjs/store/internal/filter.js +64 -0
- package/dist/cjs/store/internal/get-item.d.ts +77 -0
- package/dist/cjs/store/internal/get-item.js +58 -0
- package/dist/{store → cjs/store}/internal/item-write.d.ts +72 -32
- package/dist/cjs/store/internal/item-write.js +181 -0
- package/dist/{store → cjs/store}/internal/parse.d.ts +15 -10
- package/dist/cjs/store/internal/parse.js +180 -0
- package/dist/{store → cjs/store}/internal/rows.d.ts +38 -34
- package/dist/cjs/store/internal/rows.js +166 -0
- package/dist/{store → cjs/store}/internal/semantic-search.d.ts +2 -2
- package/dist/cjs/store/internal/semantic-search.js +211 -0
- package/dist/{store → cjs/store}/internal/setup.d.ts +10 -15
- package/dist/cjs/store/internal/setup.js +103 -0
- package/dist/{store → cjs/store}/internal/table-search.d.ts +5 -5
- package/dist/cjs/store/internal/table-search.js +123 -0
- package/dist/{store → cjs/store}/internal/vector-index.d.ts +26 -15
- package/dist/cjs/store/internal/vector-index.js +269 -0
- package/dist/{store → cjs/store}/store.d.ts +82 -39
- package/dist/cjs/store/store.js +97 -0
- package/dist/{store → cjs/store}/types.d.ts +25 -10
- package/dist/cjs/store/types.js +2 -0
- package/dist/cjs/store/vector-backend.js +4 -0
- package/dist/esm/backfill/backfill.d.ts +171 -0
- package/dist/esm/backfill/backfill.js +170 -0
- package/dist/{checkpointer/actions/delete-thread.js → esm/checkpointer/actions/delete-thread.d.ts} +4 -26
- package/dist/esm/checkpointer/actions/delete-thread.js +23 -0
- package/dist/{checkpointer/actions/get-tuple.js → esm/checkpointer/actions/get-tuple.d.ts} +7 -24
- package/dist/esm/checkpointer/actions/get-tuple.js +19 -0
- package/dist/esm/checkpointer/actions/list.d.ts +55 -0
- package/dist/esm/checkpointer/actions/list.js +67 -0
- package/dist/{checkpointer/actions/put-writes.js → esm/checkpointer/actions/put-writes.d.ts} +10 -37
- package/dist/esm/checkpointer/actions/put-writes.js +18 -0
- package/dist/esm/checkpointer/actions/put.d.ts +95 -0
- package/dist/esm/checkpointer/actions/put.js +75 -0
- package/dist/esm/checkpointer/internal/delta-history.d.ts +124 -0
- package/dist/esm/checkpointer/internal/delta-history.js +126 -0
- package/dist/{checkpointer/internal/listing.js → esm/checkpointer/internal/listing.d.ts} +22 -118
- package/dist/esm/checkpointer/internal/listing.js +95 -0
- package/dist/esm/checkpointer/internal/parse.d.ts +298 -0
- package/dist/esm/checkpointer/internal/parse.js +169 -0
- package/dist/esm/checkpointer/internal/pending-writes.d.ts +314 -0
- package/dist/esm/checkpointer/internal/pending-writes.js +229 -0
- package/dist/esm/checkpointer/internal/read.d.ts +135 -0
- package/dist/esm/checkpointer/internal/read.js +125 -0
- package/dist/esm/checkpointer/internal/rows.d.ts +644 -0
- package/dist/esm/checkpointer/internal/rows.js +323 -0
- package/dist/esm/checkpointer/internal/setup.d.ts +47 -0
- package/dist/esm/checkpointer/internal/setup.js +21 -0
- package/dist/{checkpointer/saver.js → esm/checkpointer/saver.d.ts} +84 -87
- package/dist/esm/checkpointer/saver.js +52 -0
- package/dist/esm/checkpointer/types.d.ts +51 -0
- package/dist/esm/checkpointer/types.js +1 -0
- package/dist/esm/factory/factory.d.ts +154 -0
- package/dist/esm/factory/factory.js +133 -0
- package/dist/esm/factory/types.d.ts +76 -0
- package/dist/esm/factory/types.js +1 -0
- package/dist/{history/actions/add-messages.js → esm/history/actions/add-messages.d.ts} +20 -26
- package/dist/esm/history/actions/add-messages.js +14 -0
- package/dist/{history/actions/clear.js → esm/history/actions/clear.d.ts} +4 -35
- package/dist/esm/history/actions/clear.js +26 -0
- package/dist/esm/history/actions/get-messages.d.ts +60 -0
- package/dist/esm/history/actions/get-messages.js +55 -0
- package/dist/esm/history/actions/list-sessions.d.ts +55 -0
- package/dist/esm/history/actions/list-sessions.js +64 -0
- package/dist/{history/actions/reconcile-count.js → esm/history/actions/reconcile-count.d.ts} +14 -16
- package/dist/esm/history/actions/reconcile-count.js +5 -0
- package/dist/{history/chat-message-history.js → esm/history/chat-message-history.d.ts} +76 -87
- package/dist/esm/history/chat-message-history.js +57 -0
- package/dist/esm/history/internal/append.d.ts +244 -0
- package/dist/esm/history/internal/append.js +259 -0
- package/dist/esm/history/internal/message-read.d.ts +84 -0
- package/dist/esm/history/internal/message-read.js +89 -0
- package/dist/esm/history/internal/parse.d.ts +153 -0
- package/dist/esm/history/internal/parse.js +105 -0
- package/dist/{history/internal/rows.js → esm/history/internal/rows.d.ts} +58 -112
- package/dist/esm/history/internal/rows.js +83 -0
- package/dist/esm/history/internal/session.d.ts +350 -0
- package/dist/esm/history/internal/session.js +285 -0
- package/dist/esm/history/internal/setup.d.ts +64 -0
- package/dist/esm/history/internal/setup.js +56 -0
- package/dist/{history/session-adapter.js → esm/history/session-adapter.d.ts} +25 -39
- package/dist/esm/history/session-adapter.js +34 -0
- package/dist/esm/history/types.d.ts +102 -0
- package/dist/esm/history/types.js +1 -0
- package/dist/esm/index.d.ts +53 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/shared/adapter.d.ts +146 -0
- package/dist/esm/shared/adapter.js +65 -0
- package/dist/{shared/clock.js → esm/shared/clock.d.ts} +3 -14
- package/dist/esm/shared/clock.js +9 -0
- package/dist/esm/shared/codec/codec.d.ts +336 -0
- package/dist/esm/shared/codec/codec.js +150 -0
- package/dist/esm/shared/codec/compression.d.ts +66 -0
- package/dist/esm/shared/codec/compression.js +40 -0
- package/dist/esm/shared/codec/json-serde.d.ts +80 -0
- package/dist/esm/shared/codec/json-serde.js +54 -0
- package/dist/esm/shared/codec/s3/client-types.d.ts +54 -0
- package/dist/esm/shared/codec/s3/client-types.js +3 -0
- package/dist/esm/shared/codec/s3/client.d.ts +63 -0
- package/dist/esm/shared/codec/s3/client.js +40 -0
- package/dist/{shared/codec/s3/config.js → esm/shared/codec/s3/config.d.ts} +45 -93
- package/dist/esm/shared/codec/s3/config.js +79 -0
- package/dist/esm/shared/codec/s3/lifecycle.d.ts +220 -0
- package/dist/esm/shared/codec/s3/lifecycle.js +214 -0
- package/dist/esm/shared/codec/s3/offloader.d.ts +428 -0
- package/dist/esm/shared/codec/s3/offloader.js +278 -0
- package/dist/{shared/concurrency.js → esm/shared/concurrency.d.ts} +2 -37
- package/dist/esm/shared/concurrency.js +27 -0
- package/dist/{shared/dynamodb/abort.js → esm/shared/dynamodb/abort.d.ts} +4 -16
- package/dist/esm/shared/dynamodb/abort.js +12 -0
- package/dist/esm/shared/dynamodb/batch-write.d.ts +86 -0
- package/dist/esm/shared/dynamodb/batch-write.js +74 -0
- package/dist/{shared/dynamodb/cancellation.js → esm/shared/dynamodb/cancellation.d.ts} +25 -53
- package/dist/esm/shared/dynamodb/cancellation.js +30 -0
- package/dist/{shared/dynamodb/client.js → esm/shared/dynamodb/client.d.ts} +74 -64
- package/dist/esm/shared/dynamodb/client.js +35 -0
- package/dist/{shared/dynamodb/idempotent-write.js → esm/shared/dynamodb/idempotent-write.d.ts} +172 -169
- package/dist/esm/shared/dynamodb/idempotent-write.js +153 -0
- package/dist/esm/shared/dynamodb/paginate.d.ts +111 -0
- package/dist/esm/shared/dynamodb/paginate.js +84 -0
- package/dist/esm/shared/dynamodb/partition-delete.d.ts +204 -0
- package/dist/esm/shared/dynamodb/partition-delete.js +171 -0
- package/dist/esm/shared/dynamodb/recency-index.d.ts +243 -0
- package/dist/esm/shared/dynamodb/recency-index.js +136 -0
- package/dist/esm/shared/dynamodb/retry.d.ts +317 -0
- package/dist/esm/shared/dynamodb/retry.js +180 -0
- package/dist/esm/shared/dynamodb/row-size.d.ts +33 -0
- package/dist/esm/shared/dynamodb/row-size.js +26 -0
- package/dist/{shared/dynamodb/table-schema.js → esm/shared/dynamodb/table-schema.d.ts} +57 -67
- package/dist/esm/shared/dynamodb/table-schema.js +43 -0
- package/dist/esm/shared/errors/base-error.d.ts +231 -0
- package/dist/esm/shared/errors/base-error.js +64 -0
- package/dist/esm/shared/errors/boundary.d.ts +86 -0
- package/dist/esm/shared/errors/boundary.js +54 -0
- package/dist/esm/shared/errors/classify.d.ts +206 -0
- package/dist/esm/shared/errors/classify.js +220 -0
- package/dist/{shared/errors/error-code.js → esm/shared/errors/error-code.d.ts} +39 -43
- package/dist/esm/shared/errors/error-code.js +24 -0
- package/dist/{shared/errors/errors.js → esm/shared/errors/errors.d.ts} +92 -98
- package/dist/esm/shared/errors/errors.js +110 -0
- package/dist/{shared/logging/logger.js → esm/shared/logging/logger.d.ts} +22 -52
- package/dist/esm/shared/logging/logger.js +25 -0
- package/dist/esm/shared/logging/redaction.d.ts +123 -0
- package/dist/esm/shared/logging/redaction.js +140 -0
- package/dist/{shared/logging/secret-patterns.js → esm/shared/logging/secret-patterns.d.ts} +46 -87
- package/dist/esm/shared/logging/secret-patterns.js +83 -0
- package/dist/{shared/logging/truncate.js → esm/shared/logging/truncate.d.ts} +6 -40
- package/dist/esm/shared/logging/truncate.js +25 -0
- package/dist/esm/shared/options.d.ts +100 -0
- package/dist/esm/shared/options.js +1 -0
- package/dist/{shared/ulid.js → esm/shared/ulid.d.ts} +4 -84
- package/dist/esm/shared/ulid.js +77 -0
- package/dist/{shared/validation/collaborators.js → esm/shared/validation/collaborators.d.ts} +37 -65
- package/dist/esm/shared/validation/collaborators.js +70 -0
- package/dist/{shared/validation/option-shape.js → esm/shared/validation/option-shape.d.ts} +14 -36
- package/dist/esm/shared/validation/option-shape.js +24 -0
- package/dist/esm/shared/validation/options.d.ts +145 -0
- package/dist/esm/shared/validation/options.js +156 -0
- package/dist/{shared/validation/primitives.js → esm/shared/validation/primitives.d.ts} +30 -125
- package/dist/esm/shared/validation/primitives.js +100 -0
- package/dist/esm/shared/validation/ttl.d.ts +94 -0
- package/dist/esm/shared/validation/ttl.js +46 -0
- package/dist/esm/store/actions/list-namespaces.d.ts +79 -0
- package/dist/esm/store/actions/list-namespaces.js +86 -0
- package/dist/esm/store/actions/put.d.ts +43 -0
- package/dist/esm/store/actions/put.js +46 -0
- package/dist/{store/actions/reconcile-vector-index.js → esm/store/actions/reconcile-vector-index.d.ts} +8 -16
- package/dist/esm/store/actions/reconcile-vector-index.js +10 -0
- package/dist/esm/store/actions/search.d.ts +38 -0
- package/dist/esm/store/actions/search.js +23 -0
- package/dist/esm/store/internal/batch-plan.d.ts +56 -0
- package/dist/esm/store/internal/batch-plan.js +28 -0
- package/dist/esm/store/internal/filter.d.ts +43 -0
- package/dist/esm/store/internal/filter.js +60 -0
- package/dist/esm/store/internal/get-item.d.ts +77 -0
- package/dist/esm/store/internal/get-item.js +54 -0
- package/dist/esm/store/internal/item-write.d.ts +270 -0
- package/dist/esm/store/internal/item-write.js +173 -0
- package/dist/esm/store/internal/parse.d.ts +230 -0
- package/dist/esm/store/internal/parse.js +169 -0
- package/dist/{store/internal/rows.js → esm/store/internal/rows.d.ts} +111 -199
- package/dist/esm/store/internal/rows.js +147 -0
- package/dist/esm/store/internal/semantic-search.d.ts +168 -0
- package/dist/esm/store/internal/semantic-search.js +200 -0
- package/dist/esm/store/internal/setup.d.ts +96 -0
- package/dist/esm/store/internal/setup.js +98 -0
- package/dist/esm/store/internal/table-search.d.ts +100 -0
- package/dist/esm/store/internal/table-search.js +119 -0
- package/dist/esm/store/internal/vector-index.d.ts +258 -0
- package/dist/esm/store/internal/vector-index.js +256 -0
- package/dist/{store/store.js → esm/store/store.d.ts} +99 -133
- package/dist/esm/store/store.js +93 -0
- package/dist/esm/store/types.d.ts +111 -0
- package/dist/esm/store/types.js +1 -0
- package/dist/esm/store/vector-backend.d.ts +104 -0
- package/dist/esm/store/vector-backend.js +1 -0
- package/package.json +50 -44
- package/dist/backfill/backfill.js +0 -393
- package/dist/checkpointer/actions/list.js +0 -142
- package/dist/checkpointer/actions/put.js +0 -195
- package/dist/checkpointer/internal/delta-history.js +0 -252
- package/dist/checkpointer/internal/parse.js +0 -372
- package/dist/checkpointer/internal/pending-writes.js +0 -588
- package/dist/checkpointer/internal/read.js +0 -264
- package/dist/checkpointer/internal/rows.js +0 -834
- package/dist/checkpointer/internal/setup.js +0 -72
- package/dist/checkpointer/types.js +0 -12
- package/dist/factory/factory.js +0 -266
- package/dist/factory/types.js +0 -10
- package/dist/history/actions/get-messages.js +0 -141
- package/dist/history/actions/list-sessions.js +0 -156
- package/dist/history/internal/append.js +0 -500
- package/dist/history/internal/message-read.js +0 -204
- package/dist/history/internal/parse.js +0 -252
- package/dist/history/internal/session.js +0 -628
- package/dist/history/internal/setup.js +0 -106
- package/dist/history/types.js +0 -12
- package/dist/index.js +0 -51
- package/dist/shared/adapter.js +0 -143
- package/dist/shared/codec/codec.js +0 -441
- package/dist/shared/codec/compression.js +0 -89
- package/dist/shared/codec/json-serde.js +0 -191
- package/dist/shared/codec/s3/client-types.js +0 -26
- package/dist/shared/codec/s3/client.js +0 -97
- package/dist/shared/codec/s3/lifecycle.js +0 -355
- package/dist/shared/codec/s3/offloader.js +0 -658
- package/dist/shared/dynamodb/batch-write.js +0 -173
- package/dist/shared/dynamodb/paginate.js +0 -188
- package/dist/shared/dynamodb/partition-delete.js +0 -340
- package/dist/shared/dynamodb/recency-index.js +0 -377
- package/dist/shared/dynamodb/retry.js +0 -463
- package/dist/shared/errors/base-error.js +0 -174
- package/dist/shared/errors/boundary.js +0 -143
- package/dist/shared/errors/classify.d.ts +0 -97
- package/dist/shared/errors/classify.js +0 -257
- package/dist/shared/logging/redaction.js +0 -316
- package/dist/shared/options.js +0 -11
- package/dist/shared/validation/options.js +0 -328
- package/dist/shared/validation/ttl.js +0 -132
- package/dist/store/actions/list-namespaces.js +0 -197
- package/dist/store/actions/put.js +0 -78
- package/dist/store/actions/search.js +0 -66
- package/dist/store/internal/batch-plan.d.ts +0 -26
- package/dist/store/internal/batch-plan.js +0 -109
- package/dist/store/internal/filter.js +0 -137
- package/dist/store/internal/get-item.d.ts +0 -45
- package/dist/store/internal/get-item.js +0 -115
- package/dist/store/internal/item-write.js +0 -463
- package/dist/store/internal/parse.js +0 -350
- package/dist/store/internal/semantic-search.js +0 -389
- package/dist/store/internal/setup.js +0 -223
- package/dist/store/internal/table-search.js +0 -213
- package/dist/store/internal/vector-index.js +0 -546
- package/dist/store/types.js +0 -15
- package/dist/store/vector-backend.js +0 -17
- /package/dist/{shared → cjs/shared}/clock.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/codec/json-serde.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/concurrency.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/dynamodb/cancellation.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/logging/logger.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/logging/truncate.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/ulid.d.ts +0 -0
- /package/dist/{shared → cjs/shared}/validation/primitives.d.ts +0 -0
- /package/dist/{store → cjs/store}/vector-backend.d.ts +0 -0
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Hides the JSON form: writing it, reading it, and recognising it.
|
|
4
|
-
*
|
|
5
|
-
* The default serde writes a value as JSON under the `json` type and reads
|
|
6
|
-
* back only that type; the codec also asks, when a serde refuses stored bytes,
|
|
7
|
-
* whether those bytes are still JSON at all, which tells a corrupt payload from
|
|
8
|
-
* a serde that would not reconstruct it.
|
|
9
|
-
*/
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.JSON_SERDE = void 0;
|
|
12
|
-
exports.bytesHoldDeclaredForm = bytesHoldDeclaredForm;
|
|
13
|
-
const base_error_1 = require("../errors/base-error");
|
|
14
|
-
const error_code_1 = require("../errors/error-code");
|
|
15
|
-
const errors_1 = require("../errors/errors");
|
|
16
|
-
const truncate_1 = require("../logging/truncate");
|
|
17
|
-
/**
|
|
18
|
-
* A plain JSON serializer implementing LangGraph's `SerializerProtocol`:
|
|
19
|
-
* the default `serde` of `DynamoDBStore` and `DynamoDBChatMessageHistory`, and
|
|
20
|
-
* the alternative a `DynamoDBSaver` can be given in place of LangGraph's
|
|
21
|
-
* `JsonPlusSerializer`.
|
|
22
|
-
*
|
|
23
|
-
* It is exported so that choice is available. The checkpointer's default
|
|
24
|
-
* revives a stored `{"lc": …}` record by instantiating the class the record
|
|
25
|
-
* names, so the row selects which constructor runs on read; this serializer
|
|
26
|
-
* runs `JSON.parse` and nothing else, and reconstructs no class at all.
|
|
27
|
-
* Reading with it is the narrower trust boundary, and the price is stated
|
|
28
|
-
* below: it stores the JSON projection of a value, not the value.
|
|
29
|
-
*
|
|
30
|
-
* `dumpsTyped` accepts any value `JSON.stringify` can represent and refuses the
|
|
31
|
-
* rest. A value it cannot represent — `undefined`, a function, a symbol —
|
|
32
|
-
* stringifies to `undefined` and would be stored as **zero bytes**, which reads
|
|
33
|
-
* back as a parse error; a circular structure or a `BigInt` makes it throw. Both
|
|
34
|
-
* are reported as `VALIDATION` naming `value`, at the write, rather than
|
|
35
|
-
* as an unreadable row later — with the refusal attached as `cause` and never
|
|
36
|
-
* quoted into the message, which for a circular structure names the caller's
|
|
37
|
-
* own properties and classes.
|
|
38
|
-
*
|
|
39
|
-
* What it represents, it represents as JSON, which is lossy in ways nothing
|
|
40
|
-
* records: a `Map` or `Set` stores as `{}`, an object key whose value is
|
|
41
|
-
* `undefined` is dropped and an array element is stored as `null`, `NaN` and
|
|
42
|
-
* `Infinity` store as `null`, `-0` as `0`, a `Uint8Array` as an index-keyed
|
|
43
|
-
* object and a `Date` as an ISO string. The README's *Table schema* section
|
|
44
|
-
* holds the whole table, against the checkpointer default column by column.
|
|
45
|
-
*
|
|
46
|
-
* `loadsTyped` reads only the `json` form it writes, and says
|
|
47
|
-
* so before it looks at a byte. Any other declared form is a `VALIDATION` error
|
|
48
|
-
* naming `serde`, because it says what *this* reader may rebuild and not that
|
|
49
|
-
* the payload is damaged. Bytes of that form which do not parse are
|
|
50
|
-
* `PAYLOAD_CORRUPT`, because they can never be read and the caller should
|
|
51
|
-
* report rather than retry; a `data` that is not bytes at all is a
|
|
52
|
-
* `VALIDATION` naming `data`, because that is the caller's mistake and
|
|
53
|
-
* not a row's.
|
|
54
|
-
*
|
|
55
|
-
* Frozen for the reason {@link ErrorCode} is: one object, shared by every
|
|
56
|
-
* adapter in the process that did not pass a `serde` of its own, and
|
|
57
|
-
* reachable from the package root. An assignment to `dumpsTyped` by any one
|
|
58
|
-
* consumer would silently change how every other one writes.
|
|
59
|
-
*/
|
|
60
|
-
exports.JSON_SERDE = {
|
|
61
|
-
async dumpsTyped(value) {
|
|
62
|
-
let text;
|
|
63
|
-
try {
|
|
64
|
-
text = JSON.stringify(value);
|
|
65
|
-
}
|
|
66
|
-
catch (error) {
|
|
67
|
-
// The refusal travels as `cause`, never as text. V8 writes the path it
|
|
68
|
-
// walked into the message it throws for a circular structure, quoting
|
|
69
|
-
// the caller's own property names and constructor names — and this
|
|
70
|
-
// package does not compose a public `err.message` out of a caller's
|
|
71
|
-
// identifiers, which an application may print, log or return in a
|
|
72
|
-
// response. `redactedMessage` removes credential shapes, not names, so
|
|
73
|
-
// it never covered this. A caller who wants the path reads `cause`.
|
|
74
|
-
throw (0, errors_1.validationError)('value cannot be serialized as JSON — a circular structure, or a value JSON has no ' +
|
|
75
|
-
'encoding for such as a BigInt; the refusal itself is attached as `cause`', 'value', (0, base_error_1.toError)(error));
|
|
76
|
-
}
|
|
77
|
-
if (text === undefined) {
|
|
78
|
-
throw (0, errors_1.validationError)('value has no JSON representation (undefined, a function or a symbol), so it cannot be ' +
|
|
79
|
-
'stored; store null instead to record an absent value', 'value');
|
|
80
|
-
}
|
|
81
|
-
// `dumpsTyped` stays `async` because the two throws above must reach a
|
|
82
|
-
// caller as a rejection even when it is called without `await` (a bare
|
|
83
|
-
// `.catch()`), which a plain synchronous throw would not do. Returning
|
|
84
|
-
// `Promise.resolve(...)` here — rather than the bare tuple — is what
|
|
85
|
-
// satisfies `require-await`: the rule accepts a `return` of a thenable
|
|
86
|
-
// value in place of an explicit `await`, and needs no `await` to do it.
|
|
87
|
-
return Promise.resolve([JSON_SERDE_TYPE, new TextEncoder().encode(text)]);
|
|
88
|
-
},
|
|
89
|
-
async loadsTyped(type, data) {
|
|
90
|
-
// The declared form is honoured, and honoured first. Ignoring it left this
|
|
91
|
-
// serializer answering for forms it has no grammar for: a row stamped
|
|
92
|
-
// `bytes` by the checkpointer's default — what that serializer writes for a
|
|
93
|
-
// raw `Uint8Array` — parsed here as JSON and returned a *different value*
|
|
94
|
-
// whenever those bytes happened to be valid JSON, and returned this
|
|
95
|
-
// serializer's own `PAYLOAD_CORRUPT` when they were not. The second reading
|
|
96
|
-
// is the one that cost data: the codec passes an already-branded refusal
|
|
97
|
-
// through untouched, so `bytesHoldDeclaredForm` never ran, the row was
|
|
98
|
-
// filed as permanent loss, and history's default `onCorruptMessage: 'skip'`
|
|
99
|
-
// dropped the message. The same row read through the checkpointer's own
|
|
100
|
-
// default was reported as a refusal instead, so which serde an adapter
|
|
101
|
-
// carried decided whether a turn survived the read.
|
|
102
|
-
//
|
|
103
|
-
// A form this serializer cannot rebuild a value from is a statement about
|
|
104
|
-
// this reader, not about the payload, so it names `serde` — the same brand
|
|
105
|
-
// the codec puts on `JsonPlusSerializer`'s `Unknown serialization type`,
|
|
106
|
-
// which is what makes the two agree. The type is quoted from the row, so it
|
|
107
|
-
// is bounded, for the reason `truncateForLog` states.
|
|
108
|
-
if (type !== JSON_SERDE_TYPE) {
|
|
109
|
-
throw (0, errors_1.validationError)(`this serializer reads only the \`${JSON_SERDE_TYPE}\` form it writes, and this payload ` +
|
|
110
|
-
`declares ${(0, truncate_1.truncateForLog)(String(JSON.stringify(type)))}; read the row with the ` +
|
|
111
|
-
'serializer that wrote it, or rewrite the row', 'serde');
|
|
112
|
-
}
|
|
113
|
-
let text;
|
|
114
|
-
// The decode is inside a guard of its own because it fails for a different
|
|
115
|
-
// reason than the parse does, and names it separately. UTF-8 decoding is
|
|
116
|
-
// lenient — a malformed byte becomes U+FFFD rather than an error — so the
|
|
117
|
-
// only way `TextDecoder` refuses is a `data` that is not bytes at all,
|
|
118
|
-
// which is the caller's mistake and not a corrupt row. The codec always
|
|
119
|
-
// passes a `Uint8Array`; a direct caller passing anything else would
|
|
120
|
-
// otherwise get a bare `TypeError` from Node naming an argument called
|
|
121
|
-
// "list".
|
|
122
|
-
try {
|
|
123
|
-
text = typeof data === 'string' ? data : new TextDecoder().decode(data);
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
throw (0, errors_1.validationError)('data must be the bytes or text this serializer wrote, as a Uint8Array or a string', 'data', error);
|
|
127
|
-
}
|
|
128
|
-
try {
|
|
129
|
-
// Same reasoning as `dumpsTyped`'s final return: see its comment.
|
|
130
|
-
return Promise.resolve(JSON.parse(text));
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
throw new base_error_1.DynamoDBLangGraphError('the stored payload is not the JSON this serializer wrote, so it cannot be decoded', error_code_1.ErrorCode.PAYLOAD_CORRUPT, {}, error);
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
};
|
|
137
|
-
Object.freeze(exports.JSON_SERDE);
|
|
138
|
-
/**
|
|
139
|
-
* The one `serdeType` whose grammar this package can check for itself: the type
|
|
140
|
-
* `JSON_SERDE` stamps on everything it writes, and the one LangGraph's
|
|
141
|
-
* own `JsonPlusSerializer` stamps on every value but a raw `Uint8Array`, which
|
|
142
|
-
* it stamps `bytes`.
|
|
143
|
-
*
|
|
144
|
-
* The one constant is shared by the serializer that writes this form and the
|
|
145
|
-
* check that re-derives it, within this module. They had each decided
|
|
146
|
-
* separately what they understood: the check took any other type at its
|
|
147
|
-
* word, while `JSON_SERDE` ignored the declared type and ran `JSON.parse` on
|
|
148
|
-
* whatever it was handed. A row declaring a form neither of them writes was
|
|
149
|
-
* therefore classified one way through one serializer and the opposite way
|
|
150
|
-
* through the other — and a row declaring `bytes`, which the checkpointer's
|
|
151
|
-
* default writes for a raw `Uint8Array`, decoded to a *different value*
|
|
152
|
-
* rather than failing at all when its bytes happened to parse as JSON.
|
|
153
|
-
*/
|
|
154
|
-
const JSON_SERDE_TYPE = 'json';
|
|
155
|
-
/**
|
|
156
|
-
* Whether stored bytes are still the form the row that holds them declares.
|
|
157
|
-
*
|
|
158
|
-
* This is the structural question behind the two ways a decode fails —
|
|
159
|
-
* `PAYLOAD_CORRUPT` for bytes no reader can decode, and the `serde` refusal for
|
|
160
|
-
* bytes *this* reader will not rebuild a value from — and it is the only one
|
|
161
|
-
* this package can answer on its own. `SerializerProtocol` offers no way to ask
|
|
162
|
-
* a serde whether it parsed the bytes before deciding not to reconstruct what
|
|
163
|
-
* they name, and the refusal it throws is a caller's object: its class, its
|
|
164
|
-
* fields and its prose are all whatever that caller chose. Classifying a
|
|
165
|
-
* payload by any of those would make the code mean "a third party said so",
|
|
166
|
-
* which is exactly what neither code may mean.
|
|
167
|
-
*
|
|
168
|
-
* Accepts: `serdeType` — the type stamped on the row, as the descriptor carries
|
|
169
|
-
* it. `bytes` — what the row stored, already decompressed.
|
|
170
|
-
*
|
|
171
|
-
* Returns: whether the bytes still parse as the declared form. A type this
|
|
172
|
-
* package has no grammar for is taken at its word and answers `true`, so its
|
|
173
|
-
* serde's refusal is reported rather than written off: dropping a payload this
|
|
174
|
-
* reader merely cannot check would lose data on nothing but its own ignorance.
|
|
175
|
-
*
|
|
176
|
-
* Throws: **nothing**, for any bytes. It is called from inside the `catch` that
|
|
177
|
-
* is classifying a decode failure, where a throw would replace the failure
|
|
178
|
-
* being reported — and the value it is handed came off a row, so it may be
|
|
179
|
-
* anything that row's writer stored.
|
|
180
|
-
*/
|
|
181
|
-
function bytesHoldDeclaredForm(serdeType, bytes) {
|
|
182
|
-
if (serdeType !== JSON_SERDE_TYPE)
|
|
183
|
-
return true;
|
|
184
|
-
try {
|
|
185
|
-
JSON.parse(new TextDecoder().decode(bytes));
|
|
186
|
-
return true;
|
|
187
|
-
}
|
|
188
|
-
catch {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Hides the S3 SDK's own types from this package's declarations.
|
|
4
|
-
*
|
|
5
|
-
* The S3 client, its config and a command are described by the members this
|
|
6
|
-
* package touches, so no shipped declaration imports the optional
|
|
7
|
-
* `@aws-sdk/client-s3` peer and a caller without it installed still compiles
|
|
8
|
-
* (record 1). A real `S3Client` or `S3ClientConfig` satisfies these shapes as
|
|
9
|
-
* it is, so a caller who has the SDK passes its own values unchanged.
|
|
10
|
-
*/
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.s3ClientOptions = s3ClientOptions;
|
|
13
|
-
/**
|
|
14
|
-
* The options of a config, read through the structural type.
|
|
15
|
-
*
|
|
16
|
-
* Accepts: a config as the caller gave it, or nothing.
|
|
17
|
-
*
|
|
18
|
-
* Returns: the same object seen as {@link S3ClientOptions} so `region` and
|
|
19
|
-
* `maxAttempts` can be read; an absent config reads as empty rather than
|
|
20
|
-
* needing a guard at every call site.
|
|
21
|
-
*
|
|
22
|
-
* Throws: nothing.
|
|
23
|
-
*/
|
|
24
|
-
function s3ClientOptions(config) {
|
|
25
|
-
return (config ?? {});
|
|
26
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Hides that the S3 SDK is loaded on first use, and how its client is set up.
|
|
4
|
-
*
|
|
5
|
-
* An adapter without offload never imports the optional peer; the first
|
|
6
|
-
* offload does, once, and a missing install surfaces as `VALIDATION` naming
|
|
7
|
-
* the remedy (record 1). The client built here defaults to no retries of its
|
|
8
|
-
* own — `maxAttempts: 1` — so this package's retry is the only layer unless a
|
|
9
|
-
* caller's own `maxAttempts` overrides it (record 14), and its idle timer
|
|
10
|
-
* bounds a stalled transfer without bounding a slow one.
|
|
11
|
-
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.loadS3Sdk = loadS3Sdk;
|
|
14
|
-
exports.createDefaultS3Client = createDefaultS3Client;
|
|
15
|
-
const client_1 = require("../../dynamodb/client");
|
|
16
|
-
const errors_1 = require("../../errors/errors");
|
|
17
|
-
/** Codes Node and bundlers use for an import that cannot be resolved. */
|
|
18
|
-
const MISSING_MODULE_CODES = ['ERR_MODULE_NOT_FOUND', 'MODULE_NOT_FOUND'];
|
|
19
|
-
let sdkPromise;
|
|
20
|
-
/**
|
|
21
|
-
* Convert a failed import of the optional peer into a typed error that names
|
|
22
|
-
* the remedy. Any other failure (a broken build, a syntax error inside the
|
|
23
|
-
* package) passes through unchanged.
|
|
24
|
-
*/
|
|
25
|
-
function wrapMissingPeer(error) {
|
|
26
|
-
const code = error.code;
|
|
27
|
-
if (code !== undefined && MISSING_MODULE_CODES.includes(code)) {
|
|
28
|
-
throw (0, errors_1.validationError)('S3 offload requires the optional peer @aws-sdk/client-s3 (npm install @aws-sdk/client-s3); ' +
|
|
29
|
-
'bundlers must keep it installed or external', 's3', error);
|
|
30
|
-
}
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* The optional `@aws-sdk/client-s3` peer, imported on first use.
|
|
35
|
-
*
|
|
36
|
-
* Accepts: nothing. Concurrent callers share one import.
|
|
37
|
-
*
|
|
38
|
-
* Returns: the module, cached for every later call.
|
|
39
|
-
*
|
|
40
|
-
* Throws: `VALIDATION` naming `s3` when the package is not installed,
|
|
41
|
-
* carrying the install command; any other import failure — a broken build, a
|
|
42
|
-
* syntax error inside the package — passes through unchanged. A failure is not
|
|
43
|
-
* cached, so an install or a fixed bundle succeeds on a later call.
|
|
44
|
-
*/
|
|
45
|
-
async function loadS3Sdk() {
|
|
46
|
-
if (!sdkPromise) {
|
|
47
|
-
sdkPromise = import('@aws-sdk/client-s3').catch((error) => {
|
|
48
|
-
sdkPromise = undefined;
|
|
49
|
-
return wrapMissingPeer(error);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
return sdkPromise;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* An `S3Client` built from `config` with the lazily-loaded SDK.
|
|
56
|
-
*
|
|
57
|
-
* Accepts: `config` — any `S3ClientConfig`; an explicit `maxAttempts` or
|
|
58
|
-
* `requestHandler` wins over the defaults below.
|
|
59
|
-
*
|
|
60
|
-
* Returns: the client. The caller owns it and destroys it.
|
|
61
|
-
*
|
|
62
|
-
* Throws: whatever {@link loadS3Sdk} throws.
|
|
63
|
-
*
|
|
64
|
-
* Guarantees: `maxAttempts` defaults to 1, so the SDK performs no retries of
|
|
65
|
-
* its own and this library's retry, backoff and classification are the only
|
|
66
|
-
* retry layer — the same default `resolveDynamoDBClient` applies on the
|
|
67
|
-
* DynamoDB side. A default request handler bounds a transfer that has
|
|
68
|
-
* stalled, which `maxAttempts` alone does not; a `requestHandler` in `config`
|
|
69
|
-
* replaces it whole rather than merging with it.
|
|
70
|
-
*/
|
|
71
|
-
async function createDefaultS3Client(config) {
|
|
72
|
-
const { S3Client: S3ClientCtor } = await loadS3Sdk();
|
|
73
|
-
// One field, where the DynamoDB client gets three, and the asymmetry is
|
|
74
|
-
// deliberate. `requestTimeout` bounds request creation until response
|
|
75
|
-
// *headers* arrive, and a `PutObject`'s headers arrive only once the whole
|
|
76
|
-
// body has been uploaded — so here it would be a bound on upload duration,
|
|
77
|
-
// over payloads running from the offload threshold to the download cap, and
|
|
78
|
-
// a legitimate large upload on a slow link would be destroyed for being
|
|
79
|
-
// slow. `socketTimeout` is an idle timer that any activity in either
|
|
80
|
-
// direction resets, so it separates a stalled transfer from a slow one.
|
|
81
|
-
// `throwOnRequestTimeout` is absent because without a request timeout it has
|
|
82
|
-
// nothing to act on, and `connectionTimeout` because its timer counts the
|
|
83
|
-
// wait behind the agent's sockets, which this path fans out across.
|
|
84
|
-
//
|
|
85
|
-
// What this bounds is a transfer stalled after its socket was assigned, not
|
|
86
|
-
// the whole attempt: nothing here bounds the time a request spends queued
|
|
87
|
-
// for a socket, and an idle timer is not a deadline, so a large upload's
|
|
88
|
-
// total duration stays unbounded. At or above 2 MiB the SDK sends
|
|
89
|
-
// `Expect: 100-continue` and the handler then waits six seconds for the
|
|
90
|
-
// continue on a throwaway agent, so the five-second idle timer is what
|
|
91
|
-
// fires first — the one place the two timers race.
|
|
92
|
-
return new S3ClientCtor({
|
|
93
|
-
maxAttempts: 1,
|
|
94
|
-
requestHandler: { socketTimeout: client_1.DEFAULT_SOCKET_TIMEOUT_MS },
|
|
95
|
-
...config,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Hides the bucket lifecycle configuration this package maintains.
|
|
4
|
-
*
|
|
5
|
-
* Two rules per prefix — one expiring objects a day after the ttl plus the
|
|
6
|
-
* sweep margin and keeping a released payload's noncurrent version for a grace
|
|
7
|
-
* window, one reclaiming expired delete markers — are written without
|
|
8
|
-
* disturbing any other rule on the bucket, rewritten only when they differ,
|
|
9
|
-
* and followed by a report of whether the bucket keeps versions at all.
|
|
10
|
-
*/
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.S3_RELEASE_GRACE_DAYS = void 0;
|
|
13
|
-
exports.ensureLifecycleRule = ensureLifecycleRule;
|
|
14
|
-
exports.ttlRule = ttlRule;
|
|
15
|
-
exports.markerRule = markerRule;
|
|
16
|
-
exports.assertNoIdCollision = assertNoIdCollision;
|
|
17
|
-
exports.alreadyCorrect = alreadyCorrect;
|
|
18
|
-
exports.reportBucketVersioning = reportBucketVersioning;
|
|
19
|
-
const classify_1 = require("../../errors/classify");
|
|
20
|
-
const errors_1 = require("../../errors/errors");
|
|
21
|
-
const truncate_1 = require("../../logging/truncate");
|
|
22
|
-
const client_1 = require("./client");
|
|
23
|
-
const config_1 = require("./config");
|
|
24
|
-
/**
|
|
25
|
-
* Days a released payload's noncurrent version survives behind its delete
|
|
26
|
-
* marker before S3 reclaims it. One day is the smallest the lifecycle API
|
|
27
|
-
* accepts and it rounds up to the next UTC midnight, so the window is 24-48 h:
|
|
28
|
-
* long enough to restore a payload released in error, short enough that a
|
|
29
|
-
* versioned bucket does not pay for every release it has ever made. It is a
|
|
30
|
-
* floor and never a cap — a longer retention the bucket already carries is
|
|
31
|
-
* kept, because this package has no business shortening someone else's
|
|
32
|
-
* recovery window. Inert on an unversioned bucket, which has no noncurrent
|
|
33
|
-
* versions to expire.
|
|
34
|
-
*/
|
|
35
|
-
exports.S3_RELEASE_GRACE_DAYS = 1;
|
|
36
|
-
async function readState(client, bucket) {
|
|
37
|
-
const { GetBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
|
|
38
|
-
try {
|
|
39
|
-
const existing = await client.send(new GetBucketLifecycleConfigurationCommand({ Bucket: bucket }));
|
|
40
|
-
return {
|
|
41
|
-
rules: existing.Rules ?? [],
|
|
42
|
-
transitionDefaultMinimumObjectSize: existing.TransitionDefaultMinimumObjectSize,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
if ((0, classify_1.isMissingLifecycleConfiguration)(error))
|
|
47
|
-
return { rules: [] };
|
|
48
|
-
throw error;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/** `rules` with `rule` replacing the one holding its id, or appended when none does. */
|
|
52
|
-
function upsert(rules, rule) {
|
|
53
|
-
return rules.some((held) => held.ID === rule.ID)
|
|
54
|
-
? rules.map((held) => (held.ID === rule.ID ? rule : held))
|
|
55
|
-
: [...rules, rule];
|
|
56
|
-
}
|
|
57
|
-
/** Replace the bucket's whole configuration with `rules`, carrying its own field back. */
|
|
58
|
-
async function putRules(client, bucket, state, rules) {
|
|
59
|
-
const { PutBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
|
|
60
|
-
await client.send(new PutBucketLifecycleConfigurationCommand({
|
|
61
|
-
Bucket: bucket,
|
|
62
|
-
LifecycleConfiguration: { Rules: rules },
|
|
63
|
-
...(state.transitionDefaultMinimumObjectSize === undefined
|
|
64
|
-
? {}
|
|
65
|
-
: { TransitionDefaultMinimumObjectSize: state.transitionDefaultMinimumObjectSize }),
|
|
66
|
-
}));
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Ensure the two rules scoped to `target.prefix` exist on `target.bucket`: a
|
|
70
|
-
* `target.days`-day expiration for current versions, and the reclaim that
|
|
71
|
-
* removes the delete marker a released payload leaves behind.
|
|
72
|
-
*
|
|
73
|
-
* Accepts: `target.prefix` — re-checked for scoping here, because these rules
|
|
74
|
-
* are the one place an unscoped prefix would destroy data outside this
|
|
75
|
-
* library's. `target.days` — the current-version expiry only. Released
|
|
76
|
-
* versions are governed by the release grace instead (see {@link ttlRule}),
|
|
77
|
-
* which is a floor measured against every rule already governing these keys.
|
|
78
|
-
* Both are inert on an unversioned bucket, which keeps no noncurrent version
|
|
79
|
-
* and leaves no marker.
|
|
80
|
-
*
|
|
81
|
-
* Returns: nothing. Idempotent: when both rules already say this, no write is
|
|
82
|
-
* issued. The bucket's versioning state is reported either way, because the
|
|
83
|
-
* containment a released payload depends on is missing or present regardless
|
|
84
|
-
* of whether this particular call had a rule to write.
|
|
85
|
-
*
|
|
86
|
-
* Throws: `VALIDATION` naming `s3.keyPrefix` for an unscoped prefix, or when
|
|
87
|
-
* either rule id this prefix produces is already held by a different prefix
|
|
88
|
-
* (see {@link assertNoIdCollision}); otherwise whatever the SDK rejects with. A
|
|
89
|
-
* bucket with no lifecycle configuration at all is not an error — S3 reports
|
|
90
|
-
* `NoSuchLifecycleConfiguration` and this starts from an empty rule set.
|
|
91
|
-
*
|
|
92
|
-
* Guarantees: rules this package did not write are preserved, and so is the
|
|
93
|
-
* bucket-level `TransitionDefaultMinimumObjectSize` — a Put replaces the whole
|
|
94
|
-
* configuration, so dropping it would silently reset the bucket to the default.
|
|
95
|
-
*/
|
|
96
|
-
async function ensureLifecycleRule(client, target, logger) {
|
|
97
|
-
(0, config_1.assertScopedKeyPrefix)(target.prefix);
|
|
98
|
-
const ttlId = (0, config_1.buildLifecycleRuleId)(target.prefix);
|
|
99
|
-
const markerId = (0, config_1.buildMarkerRuleId)(target.prefix);
|
|
100
|
-
const state = await readState(client, target.bucket);
|
|
101
|
-
const heldTtl = state.rules.find((rule) => rule.ID === ttlId);
|
|
102
|
-
const heldMarker = state.rules.find((rule) => rule.ID === markerId);
|
|
103
|
-
assertNoIdCollision(heldTtl, target.prefix, ttlId);
|
|
104
|
-
assertNoIdCollision(heldMarker, target.prefix, markerId);
|
|
105
|
-
const expiry = ttlRule({ id: ttlId, prefix: target.prefix, days: target.days }, state.rules, heldTtl);
|
|
106
|
-
const reclaim = markerRule(markerId, target.prefix, heldMarker);
|
|
107
|
-
if (!alreadyCorrect(heldTtl, expiry) || !alreadyCorrect(heldMarker, reclaim)) {
|
|
108
|
-
await putRules(client, target.bucket, state, upsert(upsert(state.rules, expiry), reclaim));
|
|
109
|
-
}
|
|
110
|
-
await reportBucketVersioning(client, target.bucket, logger);
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* The prefix a rule governs, wherever it names one: in its filter, nested
|
|
114
|
-
* under the filter's `And` beside tags or size bounds, or in the top-level
|
|
115
|
-
* `Prefix` of a rule written before `Filter` existed. `undefined` means the
|
|
116
|
-
* rule names no prefix at all — it is bucket-wide, or filtered only by tags or
|
|
117
|
-
* object size — and a rule like that governs every key here.
|
|
118
|
-
*/
|
|
119
|
-
function scopeOf(rule) {
|
|
120
|
-
return rule.Filter?.Prefix ?? rule.Filter?.And?.Prefix ?? rule.Prefix;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Whether `rule` governs every key under `prefix`.
|
|
124
|
-
*
|
|
125
|
-
* Only an enabled rule does. A disabled one expires nothing, so it cannot
|
|
126
|
-
* shorten anyone's window and must not lengthen this package's either: an
|
|
127
|
-
* operator who disables their own retention rule to hand the job over would
|
|
128
|
-
* otherwise pin this package at that rule's value for good. A rule scoped
|
|
129
|
-
* beside this prefix governs none of its keys and one scoped beneath it only
|
|
130
|
-
* some, so neither of them speaks for all of them.
|
|
131
|
-
*/
|
|
132
|
-
function governs(rule, prefix) {
|
|
133
|
-
const scope = scopeOf(rule);
|
|
134
|
-
return rule.Status === 'Enabled' && (scope === undefined || prefix.startsWith(scope));
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* The noncurrent retention to write: the longest one already governing these
|
|
138
|
-
* keys, and never less than the release grace.
|
|
139
|
-
*
|
|
140
|
-
* S3 honours the **shorter** of two overlapping expirations, so a rule this
|
|
141
|
-
* package does not own decides how long a released payload really survives
|
|
142
|
-
* under its prefix. Writing the grace beside a bucket-wide 90-day retention
|
|
143
|
-
* would cut that window to a day for every key here, which is the opposite of
|
|
144
|
-
* what a floor is for.
|
|
145
|
-
*
|
|
146
|
-
* The rule being replaced counts whatever its status, unlike every other rule
|
|
147
|
-
* here: that value is this package's own committed floor rather than a
|
|
148
|
-
* constraint someone else placed on these keys, and `Status` has nothing to say
|
|
149
|
-
* about it. An operator who disables the rule to pause expiry during an
|
|
150
|
-
* incident would otherwise find the recovery window cut to the grace on the
|
|
151
|
-
* next deploy — a second way down from the ratchet, and a silent one.
|
|
152
|
-
*
|
|
153
|
-
* The rule this package writes is itself in the set, so the floor ratchets: a
|
|
154
|
-
* value written once outlives the rule that justified it, and the way back
|
|
155
|
-
* down is to delete this package's rule and let it be written afresh.
|
|
156
|
-
*/
|
|
157
|
-
function noncurrentDays(rules, prefix, existing) {
|
|
158
|
-
const held = rules
|
|
159
|
-
.filter((rule) => governs(rule, prefix))
|
|
160
|
-
.map((rule) => rule.NoncurrentVersionExpiration?.NoncurrentDays ?? 0);
|
|
161
|
-
return Math.max(...held, existing?.NoncurrentVersionExpiration?.NoncurrentDays ?? 0, exports.S3_RELEASE_GRACE_DAYS);
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* What a rewrite carries over from the rule it replaces: everything this
|
|
165
|
-
* package does not set itself, less the top-level `Prefix`.
|
|
166
|
-
*
|
|
167
|
-
* That `Prefix` is how a rule written before `Filter` existed names its scope,
|
|
168
|
-
* and the two are alternatives rather than a pair — S3 refuses a rule carrying
|
|
169
|
-
* both, which would fail the provisioning call this package documents as a
|
|
170
|
-
* deployment step. Such a rule is upgraded to a filter, never merged with one.
|
|
171
|
-
*/
|
|
172
|
-
function carried(existing) {
|
|
173
|
-
const kept = { ...existing };
|
|
174
|
-
delete kept.Prefix;
|
|
175
|
-
return kept;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* The rule that expires current versions on the TTL's schedule and released
|
|
179
|
-
* ones on the grace.
|
|
180
|
-
*
|
|
181
|
-
* Accepts: `rules` — everything the bucket holds, which is what the grace is
|
|
182
|
-
* measured against. `existing` — the rule this one replaces, if any.
|
|
183
|
-
*
|
|
184
|
-
* Returns: the rule to write. Every field of `existing` this package does not
|
|
185
|
-
* manage is carried through, because the rewrite a changed TTL triggers is
|
|
186
|
-
* otherwise unrecoverable: the next call reads the rewritten rule as already
|
|
187
|
-
* correct and never restores what it dropped.
|
|
188
|
-
*
|
|
189
|
-
* Throws: nothing.
|
|
190
|
-
*
|
|
191
|
-
* Guarantees: the `Expiration` is replaced rather than merged. Merging this
|
|
192
|
-
* package's `Days` into a `Date` an operator set would change the expiry they
|
|
193
|
-
* configured, whatever the service made of the pair.
|
|
194
|
-
*/
|
|
195
|
-
function ttlRule(rule, rules, existing) {
|
|
196
|
-
return {
|
|
197
|
-
...carried(existing),
|
|
198
|
-
ID: rule.id,
|
|
199
|
-
Filter: { Prefix: rule.prefix },
|
|
200
|
-
Status: 'Enabled',
|
|
201
|
-
Expiration: { Days: rule.days },
|
|
202
|
-
NoncurrentVersionExpiration: {
|
|
203
|
-
...existing?.NoncurrentVersionExpiration,
|
|
204
|
-
NoncurrentDays: noncurrentDays(rules, rule.prefix, existing),
|
|
205
|
-
},
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* The rule that reclaims the delete marker a release leaves, once its last
|
|
210
|
-
* noncurrent version has expired.
|
|
211
|
-
*
|
|
212
|
-
* Accepts: `existing` — the rule this one replaces, if any.
|
|
213
|
-
*
|
|
214
|
-
* Returns: the rule to write, a second one rather than a field on the TTL
|
|
215
|
-
* rule: S3 refuses `ExpiredObjectDeleteMarker` inside an `Expiration` that
|
|
216
|
-
* also carries `Days`, so each rule's `Expiration` holds its own half and
|
|
217
|
-
* nothing of the other's. Fields this package does not manage are carried
|
|
218
|
-
* through as they are on the TTL rule — this id is one this package invented,
|
|
219
|
-
* but that is no reason to drop what an operator has since put on it.
|
|
220
|
-
*
|
|
221
|
-
* Throws: nothing.
|
|
222
|
-
*/
|
|
223
|
-
function markerRule(id, prefix, existing) {
|
|
224
|
-
return {
|
|
225
|
-
...carried(existing),
|
|
226
|
-
ID: id,
|
|
227
|
-
Filter: { Prefix: prefix },
|
|
228
|
-
Status: 'Enabled',
|
|
229
|
-
Expiration: { ExpiredObjectDeleteMarker: true },
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
/**
|
|
233
|
-
* Refuse to touch a rule that carries one of this prefix's ids but scopes a
|
|
234
|
-
* different prefix. Three shapes reach here: slugging maps every
|
|
235
|
-
* non-alphanumeric character to `-`, so `app/langgraph/` and `app-langgraph/`
|
|
236
|
-
* produce one id; the marker rule appends `-markers`, so `app/`'s marker id is
|
|
237
|
-
* the expiration id of `app-markers/`; and a rule written in the older schema
|
|
238
|
-
* holds an id this package would take while naming its scope in the top-level
|
|
239
|
-
* `Prefix`.
|
|
240
|
-
*
|
|
241
|
-
* Accepts: `rule` — the rule holding `id`, or nothing. `prefix` — the one this
|
|
242
|
-
* call scopes rules to.
|
|
243
|
-
*
|
|
244
|
-
* Returns: nothing: `rule` is kept under its declared type, and this checks
|
|
245
|
-
* it. A rule naming no scope anywhere is taken over, and so is one already
|
|
246
|
-
* scoping this prefix — including in the older schema, which is then upgraded
|
|
247
|
-
* to a filter.
|
|
248
|
-
*
|
|
249
|
-
* Throws: `VALIDATION` naming `s3.keyPrefix`. The id and the scope are
|
|
250
|
-
* both bounded by {@link truncateForLog}: the scope is whatever the bucket's
|
|
251
|
-
* lifecycle configuration holds, and the id is composed from an
|
|
252
|
-
* `s3.keyPrefix` checked for shape and never for length.
|
|
253
|
-
*
|
|
254
|
-
* Guarantees: the scope is read wherever the rule names it, through the same
|
|
255
|
-
* {@link scopeOf} the floor uses. Reading only `Filter.Prefix` would let a
|
|
256
|
-
* rule in the older schema through, and the rewrite would then replace its
|
|
257
|
-
* scope with this one's — so the objects that rule governs would silently
|
|
258
|
-
* lose their expiration, and a bucket-wide rule would narrow to this prefix.
|
|
259
|
-
*/
|
|
260
|
-
function assertNoIdCollision(rule, prefix, id) {
|
|
261
|
-
if (rule === undefined)
|
|
262
|
-
return;
|
|
263
|
-
const found = scopeOf(rule);
|
|
264
|
-
if (found === undefined || found === prefix)
|
|
265
|
-
return;
|
|
266
|
-
throw (0, errors_1.validationError)(`the S3 lifecycle rule id "${(0, truncate_1.truncateForLog)(id)}" is already used by the prefix ` +
|
|
267
|
-
`"${(0, truncate_1.truncateForLog)(found)}"; an id is the key ` +
|
|
268
|
-
'prefix with every non-alphanumeric character replaced by "-", and the marker rule appends ' +
|
|
269
|
-
'"-markers" to that, so "a/b/" takes the id of "a-b/" and "app/" takes the marker id of ' +
|
|
270
|
-
'"app-markers/" — choose an s3.keyPrefix that produces neither id of any other prefix on ' +
|
|
271
|
-
'this bucket', 's3.keyPrefix');
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* The fields this package manages on a rule, as one value two rules compare
|
|
275
|
-
* by. Comparing whole rules would issue a write on every call over a field S3
|
|
276
|
-
* reports and this package never sets.
|
|
277
|
-
*/
|
|
278
|
-
function managedShape(rule) {
|
|
279
|
-
return JSON.stringify([
|
|
280
|
-
rule?.Status,
|
|
281
|
-
rule?.Filter?.Prefix,
|
|
282
|
-
rule?.Expiration?.Days,
|
|
283
|
-
rule?.Expiration?.ExpiredObjectDeleteMarker,
|
|
284
|
-
rule?.NoncurrentVersionExpiration?.NoncurrentDays,
|
|
285
|
-
]);
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Whether the rule the bucket carries already says what would be written.
|
|
289
|
-
*
|
|
290
|
-
* Accepts: `existing` — the held rule, or nothing. `desired` — what a write
|
|
291
|
-
* would put there.
|
|
292
|
-
*
|
|
293
|
-
* Returns: whether a write can be skipped. A rule in the older schema never
|
|
294
|
-
* matches, because it names its prefix somewhere this does not read, so it is
|
|
295
|
-
* rewritten once into a filter and matches from then on.
|
|
296
|
-
*
|
|
297
|
-
* Throws: nothing.
|
|
298
|
-
*/
|
|
299
|
-
function alreadyCorrect(existing, desired) {
|
|
300
|
-
return managedShape(existing) === managedShape(desired);
|
|
301
|
-
}
|
|
302
|
-
/**
|
|
303
|
-
* Report whether `bucket` keeps versions, which is the whole of the recovery
|
|
304
|
-
* window behind a released payload.
|
|
305
|
-
*
|
|
306
|
-
* Accepts: `bucket` — the offload bucket. `logger` — the adapter's; silent by
|
|
307
|
-
* default, like every other event this package emits.
|
|
308
|
-
*
|
|
309
|
-
* Returns: nothing. A versioned bucket is silent; the other two states warn
|
|
310
|
-
* and name their own remedy, because those remedies differ — a bucket that
|
|
311
|
-
* never had versioning needs it enabled, while a suspended one needs it
|
|
312
|
-
* re-enabled *and* an accounting of what suspension has already destroyed.
|
|
313
|
-
*
|
|
314
|
-
* Throws: nothing, deliberately. A failure of the call itself is a `warn` too,
|
|
315
|
-
* including the `AccessDenied` of a role that provisioned lifecycle rules
|
|
316
|
-
* yesterday without this action: a permission the call did not need then must
|
|
317
|
-
* not break it now. This runs after the rules are written for the same reason
|
|
318
|
-
* — a bucket that cannot answer still gets them.
|
|
319
|
-
*
|
|
320
|
-
* Guarantees: a bucket that has never been versioned answers with an empty
|
|
321
|
-
* body, so the absent state is `Status === undefined`. It is never the string
|
|
322
|
-
* `'Disabled'`, which this API does not return, and testing for one would read
|
|
323
|
-
* an unversioned bucket as a versioned one.
|
|
324
|
-
*/
|
|
325
|
-
async function reportBucketVersioning(client, bucket, logger) {
|
|
326
|
-
const { GetBucketVersioningCommand } = await (0, client_1.loadS3Sdk)();
|
|
327
|
-
// `s3.bucketName` is checked for being a non-empty string and never for
|
|
328
|
-
// length, so it reaches these three lines as whatever the caller's options
|
|
329
|
-
// carried. It is quoted here as the identifier it is, cut at the log cap:
|
|
330
|
-
// the line's job is to say which bucket to go and look at, and the bucket
|
|
331
|
-
// holds the rest.
|
|
332
|
-
const named = (0, truncate_1.truncateForLog)(bucket);
|
|
333
|
-
let status;
|
|
334
|
-
try {
|
|
335
|
-
status = (await client.send(new GetBucketVersioningCommand({ Bucket: bucket }))).Status;
|
|
336
|
-
}
|
|
337
|
-
catch (error) {
|
|
338
|
-
// The error's name, never its message, which can carry credential text —
|
|
339
|
-
// and read off a shape rather than an Error, because a client seam can
|
|
340
|
-
// reject with anything at all and this function promises not to throw. Cut
|
|
341
|
-
// like the bucket beside it: a name is a string the SDK or a client seam
|
|
342
|
-
// produced, `message` is already bounded where `redactedMessage` relays
|
|
343
|
-
// it, and the two are one value.
|
|
344
|
-
const reason = (0, truncate_1.truncateForLog)(error?.name ?? 'unknown');
|
|
345
|
-
logger.warn('ensureS3LifecycleRule: could not read the offload bucket versioning state, so whether a released payload is recoverable is unknown; the lifecycle rules were written, and the role needs s3:GetBucketVersioning', { bucket: named, reason });
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
if (status === 'Enabled')
|
|
349
|
-
return;
|
|
350
|
-
if (status === undefined) {
|
|
351
|
-
logger.warn('ensureS3LifecycleRule: versioning is off on the offload bucket, so releasing a payload deletes it outright with no recovery window; enable bucket versioning to gain one', { bucket: named });
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
logger.warn('ensureS3LifecycleRule: versioning is suspended on the offload bucket, so releasing a payload deletes it outright; re-enable versioning, and note that the payloads released while it was suspended are already gone', { bucket: named });
|
|
355
|
-
}
|