@farukada/aws-langgraph-dynamodb-ts 0.9.0 → 1.0.0-rc.2
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 +1720 -154
- package/dist/backfill/backfill.d.ts +168 -0
- package/dist/backfill/backfill.js +393 -0
- package/dist/checkpointer/actions/delete-thread.d.ts +47 -6
- package/dist/checkpointer/actions/delete-thread.js +58 -21
- package/dist/checkpointer/actions/get-tuple.d.ts +29 -4
- package/dist/checkpointer/actions/get-tuple.js +44 -10
- package/dist/checkpointer/actions/list.d.ts +46 -4
- package/dist/checkpointer/actions/list.js +121 -66
- package/dist/checkpointer/actions/put-writes.d.ts +41 -9
- package/dist/checkpointer/actions/put-writes.js +62 -77
- package/dist/checkpointer/actions/put.d.ts +83 -4
- package/dist/checkpointer/actions/put.js +177 -25
- package/dist/checkpointer/internal/delta-history.d.ts +112 -0
- package/dist/checkpointer/internal/delta-history.js +252 -0
- package/dist/checkpointer/internal/listing.d.ts +149 -0
- package/dist/checkpointer/internal/listing.js +245 -0
- package/dist/checkpointer/internal/parse.d.ts +262 -0
- package/dist/checkpointer/internal/parse.js +372 -0
- package/dist/checkpointer/internal/pending-writes.d.ts +275 -0
- package/dist/checkpointer/internal/pending-writes.js +588 -0
- package/dist/checkpointer/internal/read.d.ts +130 -0
- package/dist/checkpointer/internal/read.js +264 -0
- package/dist/checkpointer/internal/rows.d.ts +571 -0
- package/dist/checkpointer/internal/rows.js +834 -0
- package/dist/checkpointer/internal/setup.d.ts +42 -19
- package/dist/checkpointer/internal/setup.js +65 -29
- package/dist/checkpointer/saver.d.ts +256 -16
- package/dist/checkpointer/saver.js +275 -29
- package/dist/checkpointer/types.d.ts +39 -39
- package/dist/checkpointer/types.js +10 -1
- package/dist/factory/factory.d.ts +134 -28
- package/dist/factory/factory.js +240 -21
- package/dist/factory/types.d.ts +76 -0
- package/dist/factory/types.js +10 -0
- package/dist/history/actions/add-messages.d.ts +31 -4
- package/dist/history/actions/add-messages.js +38 -58
- package/dist/history/actions/clear.d.ts +49 -6
- package/dist/history/actions/clear.js +66 -14
- package/dist/history/actions/get-messages.d.ts +54 -6
- package/dist/history/actions/get-messages.js +126 -43
- package/dist/history/actions/list-sessions.d.ts +52 -10
- package/dist/history/actions/list-sessions.js +139 -40
- package/dist/history/actions/reconcile-count.d.ts +42 -10
- package/dist/history/actions/reconcile-count.js +45 -45
- package/dist/history/chat-message-history.d.ts +220 -33
- package/dist/history/chat-message-history.js +240 -43
- package/dist/history/internal/append.d.ts +212 -0
- package/dist/history/internal/append.js +500 -0
- package/dist/history/internal/message-read.d.ts +84 -0
- package/dist/history/internal/message-read.js +204 -0
- package/dist/history/internal/parse.d.ts +153 -0
- package/dist/history/internal/parse.js +252 -0
- package/dist/history/internal/rows.d.ts +195 -0
- package/dist/history/internal/rows.js +250 -0
- package/dist/history/internal/session.d.ts +331 -0
- package/dist/history/internal/session.js +628 -0
- package/dist/history/internal/setup.d.ts +52 -17
- package/dist/history/internal/setup.js +92 -21
- package/dist/history/session-adapter.d.ts +102 -7
- package/dist/history/session-adapter.js +103 -9
- package/dist/history/types.d.ts +80 -29
- package/dist/history/types.js +10 -1
- package/dist/index.d.ts +42 -11
- package/dist/index.js +33 -12
- package/dist/shared/adapter.d.ts +135 -0
- package/dist/shared/adapter.js +143 -0
- package/dist/shared/clock.d.ts +51 -2
- package/dist/shared/clock.js +57 -2
- package/dist/shared/codec/codec.d.ts +288 -13
- package/dist/shared/codec/codec.js +416 -19
- package/dist/shared/codec/compression.d.ts +43 -7
- package/dist/shared/codec/compression.js +53 -13
- package/dist/shared/codec/json-serde.d.ts +76 -4
- package/dist/shared/codec/json-serde.js +181 -8
- package/dist/shared/codec/s3/client-types.d.ts +53 -0
- package/dist/shared/codec/s3/client-types.js +26 -0
- package/dist/shared/codec/s3/client.d.ts +43 -10
- package/dist/shared/codec/s3/client.js +82 -9
- package/dist/shared/codec/s3/config.d.ts +242 -11
- package/dist/shared/codec/s3/config.js +293 -11
- package/dist/shared/codec/s3/lifecycle.d.ts +164 -6
- package/dist/shared/codec/s3/lifecycle.js +335 -27
- package/dist/shared/codec/s3/offloader.d.ts +393 -18
- package/dist/shared/codec/s3/offloader.js +595 -37
- package/dist/shared/concurrency.d.ts +43 -0
- package/dist/shared/concurrency.js +78 -0
- package/dist/shared/dynamodb/abort.d.ts +47 -0
- package/dist/shared/dynamodb/abort.js +59 -0
- package/dist/shared/dynamodb/batch-write.d.ts +77 -14
- package/dist/shared/dynamodb/batch-write.js +146 -27
- package/dist/shared/dynamodb/cancellation.d.ts +121 -4
- package/dist/shared/dynamodb/cancellation.js +147 -3
- package/dist/shared/dynamodb/client.d.ts +162 -8
- package/dist/shared/dynamodb/client.js +153 -5
- package/dist/shared/dynamodb/idempotent-write.d.ts +551 -0
- package/dist/shared/dynamodb/idempotent-write.js +593 -0
- package/dist/shared/dynamodb/paginate.d.ts +105 -9
- package/dist/shared/dynamodb/paginate.js +175 -7
- package/dist/shared/dynamodb/partition-delete.d.ts +185 -14
- package/dist/shared/dynamodb/partition-delete.js +314 -44
- package/dist/shared/dynamodb/recency-index.d.ts +231 -0
- package/dist/shared/dynamodb/recency-index.js +377 -0
- package/dist/shared/dynamodb/retry.d.ts +276 -8
- package/dist/shared/dynamodb/retry.js +433 -23
- package/dist/shared/dynamodb/table-schema.d.ts +190 -0
- package/dist/shared/dynamodb/table-schema.js +209 -0
- package/dist/shared/errors/base-error.d.ts +184 -10
- package/dist/shared/errors/base-error.js +160 -14
- package/dist/shared/errors/boundary.d.ts +71 -0
- package/dist/shared/errors/boundary.js +143 -0
- package/dist/shared/errors/classify.d.ts +97 -0
- package/dist/shared/errors/classify.js +257 -0
- package/dist/shared/errors/error-code.d.ts +77 -2
- package/dist/shared/errors/error-code.js +83 -1
- package/dist/shared/errors/errors.d.ts +158 -59
- package/dist/shared/errors/errors.js +219 -92
- package/dist/shared/logging/logger.d.ts +69 -3
- package/dist/shared/logging/logger.js +97 -3
- package/dist/shared/logging/redaction.d.ts +92 -8
- package/dist/shared/logging/redaction.js +273 -17
- package/dist/shared/logging/secret-patterns.d.ts +149 -19
- package/dist/shared/logging/secret-patterns.js +188 -27
- package/dist/shared/logging/truncate.d.ts +197 -0
- package/dist/shared/logging/truncate.js +231 -0
- package/dist/shared/options.d.ts +59 -7
- package/dist/shared/options.js +9 -1
- package/dist/shared/ulid.d.ts +77 -7
- package/dist/shared/ulid.js +103 -8
- package/dist/shared/validation/collaborators.d.ts +141 -0
- package/dist/shared/validation/collaborators.js +188 -0
- package/dist/shared/validation/option-shape.d.ts +89 -0
- package/dist/shared/validation/option-shape.js +113 -0
- package/dist/shared/validation/options.d.ts +145 -0
- package/dist/shared/validation/options.js +328 -0
- package/dist/shared/validation/primitives.d.ts +288 -21
- package/dist/shared/validation/primitives.js +353 -50
- package/dist/shared/validation/ttl.d.ts +66 -10
- package/dist/shared/validation/ttl.js +113 -15
- package/dist/store/actions/list-namespaces.d.ts +76 -6
- package/dist/store/actions/list-namespaces.js +166 -24
- package/dist/store/actions/put.d.ts +33 -8
- package/dist/store/actions/put.js +53 -60
- package/dist/store/actions/reconcile-vector-index.d.ts +31 -10
- package/dist/store/actions/reconcile-vector-index.js +34 -15
- package/dist/store/actions/search.d.ts +34 -6
- package/dist/store/actions/search.js +56 -51
- package/dist/store/internal/batch-plan.d.ts +26 -0
- package/dist/store/internal/batch-plan.js +109 -0
- package/dist/store/internal/filter.d.ts +36 -3
- package/dist/store/internal/filter.js +66 -15
- package/dist/store/internal/get-item.d.ts +45 -0
- package/dist/store/internal/get-item.js +115 -0
- package/dist/store/internal/item-write.d.ts +230 -0
- package/dist/store/internal/item-write.js +463 -0
- package/dist/store/internal/parse.d.ts +225 -0
- package/dist/store/internal/parse.js +350 -0
- package/dist/store/internal/rows.d.ts +355 -0
- package/dist/store/internal/rows.js +447 -0
- package/dist/store/internal/semantic-search.d.ts +161 -6
- package/dist/store/internal/semantic-search.js +360 -18
- package/dist/store/internal/setup.d.ts +77 -20
- package/dist/store/internal/setup.js +178 -47
- package/dist/store/internal/table-search.d.ts +100 -0
- package/dist/store/internal/table-search.js +213 -0
- package/dist/store/internal/vector-index.d.ts +247 -0
- package/dist/store/internal/vector-index.js +546 -0
- package/dist/store/store.d.ts +270 -17
- package/dist/store/store.js +329 -38
- package/dist/store/types.d.ts +76 -26
- package/dist/store/types.js +13 -1
- package/dist/store/vector-backend.d.ts +64 -4
- package/dist/store/vector-backend.js +15 -1
- package/package.json +58 -36
- package/dist/checkpointer/actions/delete-thread.d.ts.map +0 -1
- package/dist/checkpointer/actions/delete-thread.js.map +0 -1
- package/dist/checkpointer/actions/get-tuple.d.ts.map +0 -1
- package/dist/checkpointer/actions/get-tuple.js.map +0 -1
- package/dist/checkpointer/actions/list.d.ts.map +0 -1
- package/dist/checkpointer/actions/list.js.map +0 -1
- package/dist/checkpointer/actions/put-writes.d.ts.map +0 -1
- package/dist/checkpointer/actions/put-writes.js.map +0 -1
- package/dist/checkpointer/actions/put.d.ts.map +0 -1
- package/dist/checkpointer/actions/put.js.map +0 -1
- package/dist/checkpointer/internal/assemble.d.ts +0 -10
- package/dist/checkpointer/internal/assemble.d.ts.map +0 -1
- package/dist/checkpointer/internal/assemble.js +0 -37
- package/dist/checkpointer/internal/assemble.js.map +0 -1
- package/dist/checkpointer/internal/configurable.d.ts +0 -13
- package/dist/checkpointer/internal/configurable.d.ts.map +0 -1
- package/dist/checkpointer/internal/configurable.js +0 -23
- package/dist/checkpointer/internal/configurable.js.map +0 -1
- package/dist/checkpointer/internal/fetch.d.ts +0 -10
- package/dist/checkpointer/internal/fetch.d.ts.map +0 -1
- package/dist/checkpointer/internal/fetch.js +0 -46
- package/dist/checkpointer/internal/fetch.js.map +0 -1
- package/dist/checkpointer/internal/filter-match.d.ts +0 -12
- package/dist/checkpointer/internal/filter-match.d.ts.map +0 -1
- package/dist/checkpointer/internal/filter-match.js +0 -14
- package/dist/checkpointer/internal/filter-match.js.map +0 -1
- package/dist/checkpointer/internal/item-reader.d.ts +0 -55
- package/dist/checkpointer/internal/item-reader.d.ts.map +0 -1
- package/dist/checkpointer/internal/item-reader.js +0 -88
- package/dist/checkpointer/internal/item-reader.js.map +0 -1
- package/dist/checkpointer/internal/item-writer.d.ts +0 -26
- package/dist/checkpointer/internal/item-writer.d.ts.map +0 -1
- package/dist/checkpointer/internal/item-writer.js +0 -92
- package/dist/checkpointer/internal/item-writer.js.map +0 -1
- package/dist/checkpointer/internal/keys.d.ts +0 -31
- package/dist/checkpointer/internal/keys.d.ts.map +0 -1
- package/dist/checkpointer/internal/keys.js +0 -87
- package/dist/checkpointer/internal/keys.js.map +0 -1
- package/dist/checkpointer/internal/query.d.ts +0 -20
- package/dist/checkpointer/internal/query.d.ts.map +0 -1
- package/dist/checkpointer/internal/query.js +0 -36
- package/dist/checkpointer/internal/query.js.map +0 -1
- package/dist/checkpointer/internal/setup.d.ts.map +0 -1
- package/dist/checkpointer/internal/setup.js.map +0 -1
- package/dist/checkpointer/internal/special-write-cas.d.ts +0 -30
- package/dist/checkpointer/internal/special-write-cas.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-cas.js +0 -104
- package/dist/checkpointer/internal/special-write-cas.js.map +0 -1
- package/dist/checkpointer/internal/special-write-cleanup.d.ts +0 -24
- package/dist/checkpointer/internal/special-write-cleanup.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-cleanup.js +0 -47
- package/dist/checkpointer/internal/special-write-cleanup.js.map +0 -1
- package/dist/checkpointer/internal/special-write-verify.d.ts +0 -54
- package/dist/checkpointer/internal/special-write-verify.d.ts.map +0 -1
- package/dist/checkpointer/internal/special-write-verify.js +0 -65
- package/dist/checkpointer/internal/special-write-verify.js.map +0 -1
- package/dist/checkpointer/internal/validation.d.ts +0 -13
- package/dist/checkpointer/internal/validation.d.ts.map +0 -1
- package/dist/checkpointer/internal/validation.js +0 -30
- package/dist/checkpointer/internal/validation.js.map +0 -1
- package/dist/checkpointer/internal/write-guard.d.ts +0 -13
- package/dist/checkpointer/internal/write-guard.d.ts.map +0 -1
- package/dist/checkpointer/internal/write-guard.js +0 -39
- package/dist/checkpointer/internal/write-guard.js.map +0 -1
- package/dist/checkpointer/internal/write-index.d.ts +0 -37
- package/dist/checkpointer/internal/write-index.d.ts.map +0 -1
- package/dist/checkpointer/internal/write-index.js +0 -42
- package/dist/checkpointer/internal/write-index.js.map +0 -1
- package/dist/checkpointer/saver.d.ts.map +0 -1
- package/dist/checkpointer/saver.js.map +0 -1
- package/dist/checkpointer/types.d.ts.map +0 -1
- package/dist/checkpointer/types.js.map +0 -1
- package/dist/factory/factory.d.ts.map +0 -1
- package/dist/factory/factory.js.map +0 -1
- package/dist/history/actions/add-messages.d.ts.map +0 -1
- package/dist/history/actions/add-messages.js.map +0 -1
- package/dist/history/actions/clear.d.ts.map +0 -1
- package/dist/history/actions/clear.js.map +0 -1
- package/dist/history/actions/get-messages.d.ts.map +0 -1
- package/dist/history/actions/get-messages.js.map +0 -1
- package/dist/history/actions/list-sessions.d.ts.map +0 -1
- package/dist/history/actions/list-sessions.js.map +0 -1
- package/dist/history/actions/reconcile-count.d.ts.map +0 -1
- package/dist/history/actions/reconcile-count.js.map +0 -1
- package/dist/history/chat-message-history.d.ts.map +0 -1
- package/dist/history/chat-message-history.js.map +0 -1
- package/dist/history/internal/append-saga.d.ts +0 -20
- package/dist/history/internal/append-saga.d.ts.map +0 -1
- package/dist/history/internal/append-saga.js +0 -35
- package/dist/history/internal/append-saga.js.map +0 -1
- package/dist/history/internal/compensation.d.ts +0 -21
- package/dist/history/internal/compensation.d.ts.map +0 -1
- package/dist/history/internal/compensation.js +0 -84
- package/dist/history/internal/compensation.js.map +0 -1
- package/dist/history/internal/item-mapper.d.ts +0 -12
- package/dist/history/internal/item-mapper.d.ts.map +0 -1
- package/dist/history/internal/item-mapper.js +0 -33
- package/dist/history/internal/item-mapper.js.map +0 -1
- package/dist/history/internal/keys.d.ts +0 -17
- package/dist/history/internal/keys.d.ts.map +0 -1
- package/dist/history/internal/keys.js +0 -49
- package/dist/history/internal/keys.js.map +0 -1
- package/dist/history/internal/message-chunker.d.ts +0 -14
- package/dist/history/internal/message-chunker.d.ts.map +0 -1
- package/dist/history/internal/message-chunker.js +0 -68
- package/dist/history/internal/message-chunker.js.map +0 -1
- package/dist/history/internal/message-transaction.d.ts +0 -26
- package/dist/history/internal/message-transaction.d.ts.map +0 -1
- package/dist/history/internal/message-transaction.js +0 -60
- package/dist/history/internal/message-transaction.js.map +0 -1
- package/dist/history/internal/query.d.ts +0 -10
- package/dist/history/internal/query.d.ts.map +0 -1
- package/dist/history/internal/query.js +0 -31
- package/dist/history/internal/query.js.map +0 -1
- package/dist/history/internal/session-count.d.ts +0 -41
- package/dist/history/internal/session-count.d.ts.map +0 -1
- package/dist/history/internal/session-count.js +0 -109
- package/dist/history/internal/session-count.js.map +0 -1
- package/dist/history/internal/session-title.d.ts +0 -20
- package/dist/history/internal/session-title.d.ts.map +0 -1
- package/dist/history/internal/session-title.js +0 -44
- package/dist/history/internal/session-title.js.map +0 -1
- package/dist/history/internal/session-update.d.ts +0 -28
- package/dist/history/internal/session-update.d.ts.map +0 -1
- package/dist/history/internal/session-update.js +0 -70
- package/dist/history/internal/session-update.js.map +0 -1
- package/dist/history/internal/setup.d.ts.map +0 -1
- package/dist/history/internal/setup.js.map +0 -1
- package/dist/history/internal/title-generator.d.ts +0 -13
- package/dist/history/internal/title-generator.d.ts.map +0 -1
- package/dist/history/internal/title-generator.js +0 -25
- package/dist/history/internal/title-generator.js.map +0 -1
- package/dist/history/internal/ttl-anchor.d.ts +0 -25
- package/dist/history/internal/ttl-anchor.d.ts.map +0 -1
- package/dist/history/internal/ttl-anchor.js +0 -38
- package/dist/history/internal/ttl-anchor.js.map +0 -1
- package/dist/history/internal/validation.d.ts +0 -9
- package/dist/history/internal/validation.d.ts.map +0 -1
- package/dist/history/internal/validation.js +0 -16
- package/dist/history/internal/validation.js.map +0 -1
- package/dist/history/session-adapter.d.ts.map +0 -1
- package/dist/history/session-adapter.js.map +0 -1
- package/dist/history/types.d.ts.map +0 -1
- package/dist/history/types.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/shared/clock.d.ts.map +0 -1
- package/dist/shared/clock.js.map +0 -1
- package/dist/shared/codec/codec.d.ts.map +0 -1
- package/dist/shared/codec/codec.js.map +0 -1
- package/dist/shared/codec/compression.d.ts.map +0 -1
- package/dist/shared/codec/compression.js.map +0 -1
- package/dist/shared/codec/descriptor-keys.d.ts +0 -4
- package/dist/shared/codec/descriptor-keys.d.ts.map +0 -1
- package/dist/shared/codec/descriptor-keys.js +0 -14
- package/dist/shared/codec/descriptor-keys.js.map +0 -1
- package/dist/shared/codec/json-serde.d.ts.map +0 -1
- package/dist/shared/codec/json-serde.js.map +0 -1
- package/dist/shared/codec/s3/client.d.ts.map +0 -1
- package/dist/shared/codec/s3/client.js.map +0 -1
- package/dist/shared/codec/s3/config.d.ts.map +0 -1
- package/dist/shared/codec/s3/config.js.map +0 -1
- package/dist/shared/codec/s3/delete.d.ts +0 -8
- package/dist/shared/codec/s3/delete.d.ts.map +0 -1
- package/dist/shared/codec/s3/delete.js +0 -29
- package/dist/shared/codec/s3/delete.js.map +0 -1
- package/dist/shared/codec/s3/lifecycle.d.ts.map +0 -1
- package/dist/shared/codec/s3/lifecycle.js.map +0 -1
- package/dist/shared/codec/s3/offloader.d.ts.map +0 -1
- package/dist/shared/codec/s3/offloader.js.map +0 -1
- package/dist/shared/codec/s3/orphans.d.ts +0 -18
- package/dist/shared/codec/s3/orphans.d.ts.map +0 -1
- package/dist/shared/codec/s3/orphans.js +0 -58
- package/dist/shared/codec/s3/orphans.js.map +0 -1
- package/dist/shared/codec/s3/read-write.d.ts +0 -14
- package/dist/shared/codec/s3/read-write.d.ts.map +0 -1
- package/dist/shared/codec/s3/read-write.js +0 -43
- package/dist/shared/codec/s3/read-write.js.map +0 -1
- package/dist/shared/codec/s3/retry.d.ts +0 -5
- package/dist/shared/codec/s3/retry.d.ts.map +0 -1
- package/dist/shared/codec/s3/retry.js +0 -25
- package/dist/shared/codec/s3/retry.js.map +0 -1
- package/dist/shared/constants.d.ts +0 -64
- package/dist/shared/constants.d.ts.map +0 -1
- package/dist/shared/constants.js +0 -67
- package/dist/shared/constants.js.map +0 -1
- package/dist/shared/dynamodb/backoff.d.ts +0 -15
- package/dist/shared/dynamodb/backoff.d.ts.map +0 -1
- package/dist/shared/dynamodb/backoff.js +0 -48
- package/dist/shared/dynamodb/backoff.js.map +0 -1
- package/dist/shared/dynamodb/batch-write.d.ts.map +0 -1
- package/dist/shared/dynamodb/batch-write.js.map +0 -1
- package/dist/shared/dynamodb/cancellation.d.ts.map +0 -1
- package/dist/shared/dynamodb/cancellation.js.map +0 -1
- package/dist/shared/dynamodb/client.d.ts.map +0 -1
- package/dist/shared/dynamodb/client.js.map +0 -1
- package/dist/shared/dynamodb/conditional-put.d.ts +0 -51
- package/dist/shared/dynamodb/conditional-put.d.ts.map +0 -1
- package/dist/shared/dynamodb/conditional-put.js +0 -59
- package/dist/shared/dynamodb/conditional-put.js.map +0 -1
- package/dist/shared/dynamodb/drain-unprocessed.d.ts +0 -19
- package/dist/shared/dynamodb/drain-unprocessed.d.ts.map +0 -1
- package/dist/shared/dynamodb/drain-unprocessed.js +0 -44
- package/dist/shared/dynamodb/drain-unprocessed.js.map +0 -1
- package/dist/shared/dynamodb/paginate-core.d.ts +0 -22
- package/dist/shared/dynamodb/paginate-core.d.ts.map +0 -1
- package/dist/shared/dynamodb/paginate-core.js +0 -52
- package/dist/shared/dynamodb/paginate-core.js.map +0 -1
- package/dist/shared/dynamodb/paginate.d.ts.map +0 -1
- package/dist/shared/dynamodb/paginate.js.map +0 -1
- package/dist/shared/dynamodb/partition-delete.d.ts.map +0 -1
- package/dist/shared/dynamodb/partition-delete.js.map +0 -1
- package/dist/shared/dynamodb/retry-classifier.d.ts +0 -9
- package/dist/shared/dynamodb/retry-classifier.d.ts.map +0 -1
- package/dist/shared/dynamodb/retry-classifier.js +0 -87
- package/dist/shared/dynamodb/retry-classifier.js.map +0 -1
- package/dist/shared/dynamodb/retry.d.ts.map +0 -1
- package/dist/shared/dynamodb/retry.js.map +0 -1
- package/dist/shared/dynamodb/scan.d.ts +0 -15
- package/dist/shared/dynamodb/scan.d.ts.map +0 -1
- package/dist/shared/dynamodb/scan.js +0 -20
- package/dist/shared/dynamodb/scan.js.map +0 -1
- package/dist/shared/dynamodb/types.d.ts +0 -24
- package/dist/shared/dynamodb/types.d.ts.map +0 -1
- package/dist/shared/dynamodb/types.js +0 -3
- package/dist/shared/dynamodb/types.js.map +0 -1
- package/dist/shared/errors/base-error.d.ts.map +0 -1
- package/dist/shared/errors/base-error.js.map +0 -1
- package/dist/shared/errors/error-code.d.ts.map +0 -1
- package/dist/shared/errors/error-code.js.map +0 -1
- package/dist/shared/errors/errors.d.ts.map +0 -1
- package/dist/shared/errors/errors.js.map +0 -1
- package/dist/shared/errors/wrap-error.d.ts +0 -16
- package/dist/shared/errors/wrap-error.d.ts.map +0 -1
- package/dist/shared/errors/wrap-error.js +0 -30
- package/dist/shared/errors/wrap-error.js.map +0 -1
- package/dist/shared/logging/logger.d.ts.map +0 -1
- package/dist/shared/logging/logger.js.map +0 -1
- package/dist/shared/logging/redaction-walk.d.ts +0 -23
- package/dist/shared/logging/redaction-walk.d.ts.map +0 -1
- package/dist/shared/logging/redaction-walk.js +0 -92
- package/dist/shared/logging/redaction-walk.js.map +0 -1
- package/dist/shared/logging/redaction.d.ts.map +0 -1
- package/dist/shared/logging/redaction.js.map +0 -1
- package/dist/shared/logging/secret-patterns.d.ts.map +0 -1
- package/dist/shared/logging/secret-patterns.js.map +0 -1
- package/dist/shared/options.d.ts.map +0 -1
- package/dist/shared/options.js.map +0 -1
- package/dist/shared/ulid.d.ts.map +0 -1
- package/dist/shared/ulid.js.map +0 -1
- package/dist/shared/validation/primitives.d.ts.map +0 -1
- package/dist/shared/validation/primitives.js.map +0 -1
- package/dist/shared/validation/ttl.d.ts.map +0 -1
- package/dist/shared/validation/ttl.js.map +0 -1
- package/dist/store/actions/get.d.ts +0 -5
- package/dist/store/actions/get.d.ts.map +0 -1
- package/dist/store/actions/get.js +0 -35
- package/dist/store/actions/get.js.map +0 -1
- package/dist/store/actions/list-namespaces.d.ts.map +0 -1
- package/dist/store/actions/list-namespaces.js.map +0 -1
- package/dist/store/actions/put.d.ts.map +0 -1
- package/dist/store/actions/put.js.map +0 -1
- package/dist/store/actions/reconcile-vector-index.d.ts.map +0 -1
- package/dist/store/actions/reconcile-vector-index.js.map +0 -1
- package/dist/store/actions/search.d.ts.map +0 -1
- package/dist/store/actions/search.js.map +0 -1
- package/dist/store/internal/backend-search.d.ts +0 -5
- package/dist/store/internal/backend-search.d.ts.map +0 -1
- package/dist/store/internal/backend-search.js +0 -68
- package/dist/store/internal/backend-search.js.map +0 -1
- package/dist/store/internal/filter.d.ts.map +0 -1
- package/dist/store/internal/filter.js.map +0 -1
- package/dist/store/internal/index-reconcile.d.ts +0 -22
- package/dist/store/internal/index-reconcile.d.ts.map +0 -1
- package/dist/store/internal/index-reconcile.js +0 -105
- package/dist/store/internal/index-reconcile.js.map +0 -1
- package/dist/store/internal/index-sync.d.ts +0 -11
- package/dist/store/internal/index-sync.d.ts.map +0 -1
- package/dist/store/internal/index-sync.js +0 -26
- package/dist/store/internal/index-sync.js.map +0 -1
- package/dist/store/internal/item-mapper.d.ts +0 -25
- package/dist/store/internal/item-mapper.d.ts.map +0 -1
- package/dist/store/internal/item-mapper.js +0 -53
- package/dist/store/internal/item-mapper.js.map +0 -1
- package/dist/store/internal/keys.d.ts +0 -18
- package/dist/store/internal/keys.d.ts.map +0 -1
- package/dist/store/internal/keys.js +0 -42
- package/dist/store/internal/keys.js.map +0 -1
- package/dist/store/internal/namespace-match.d.ts +0 -12
- package/dist/store/internal/namespace-match.d.ts.map +0 -1
- package/dist/store/internal/namespace-match.js +0 -41
- package/dist/store/internal/namespace-match.js.map +0 -1
- package/dist/store/internal/overwrite-swap.d.ts +0 -33
- package/dist/store/internal/overwrite-swap.d.ts.map +0 -1
- package/dist/store/internal/overwrite-swap.js +0 -62
- package/dist/store/internal/overwrite-swap.js.map +0 -1
- package/dist/store/internal/persist.d.ts +0 -27
- package/dist/store/internal/persist.d.ts.map +0 -1
- package/dist/store/internal/persist.js +0 -59
- package/dist/store/internal/persist.js.map +0 -1
- package/dist/store/internal/query.d.ts +0 -6
- package/dist/store/internal/query.d.ts.map +0 -1
- package/dist/store/internal/query.js +0 -32
- package/dist/store/internal/query.js.map +0 -1
- package/dist/store/internal/ranker.d.ts +0 -13
- package/dist/store/internal/ranker.d.ts.map +0 -1
- package/dist/store/internal/ranker.js +0 -31
- package/dist/store/internal/ranker.js.map +0 -1
- package/dist/store/internal/read-existing.d.ts +0 -19
- package/dist/store/internal/read-existing.d.ts.map +0 -1
- package/dist/store/internal/read-existing.js +0 -29
- package/dist/store/internal/read-existing.js.map +0 -1
- package/dist/store/internal/score-direction.d.ts +0 -32
- package/dist/store/internal/score-direction.d.ts.map +0 -1
- package/dist/store/internal/score-direction.js +0 -39
- package/dist/store/internal/score-direction.js.map +0 -1
- package/dist/store/internal/search-filter.d.ts +0 -4
- package/dist/store/internal/search-filter.d.ts.map +0 -1
- package/dist/store/internal/search-filter.js +0 -11
- package/dist/store/internal/search-filter.js.map +0 -1
- package/dist/store/internal/semantic-search.d.ts.map +0 -1
- package/dist/store/internal/semantic-search.js.map +0 -1
- package/dist/store/internal/setup.d.ts.map +0 -1
- package/dist/store/internal/setup.js.map +0 -1
- package/dist/store/internal/validation.d.ts +0 -13
- package/dist/store/internal/validation.d.ts.map +0 -1
- package/dist/store/internal/validation.js +0 -35
- package/dist/store/internal/validation.js.map +0 -1
- package/dist/store/internal/write-verify.d.ts +0 -37
- package/dist/store/internal/write-verify.d.ts.map +0 -1
- package/dist/store/internal/write-verify.js +0 -68
- package/dist/store/internal/write-verify.js.map +0 -1
- package/dist/store/store.d.ts.map +0 -1
- package/dist/store/store.js.map +0 -1
- package/dist/store/types.d.ts.map +0 -1
- package/dist/store/types.js.map +0 -1
- package/dist/store/vector-backend.d.ts.map +0 -1
- package/dist/store/vector-backend.js.map +0 -1
|
@@ -1,8 +1,166 @@
|
|
|
1
|
-
import type { S3Client } from '@aws-sdk/client-s3';
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Hides the bucket lifecycle configuration this package maintains.
|
|
3
|
+
*
|
|
4
|
+
* Two rules per prefix — one expiring objects a day after the ttl plus the
|
|
5
|
+
* sweep margin and keeping a released payload's noncurrent version for a grace
|
|
6
|
+
* window, one reclaiming expired delete markers — are written without
|
|
7
|
+
* disturbing any other rule on the bucket, rewritten only when they differ,
|
|
8
|
+
* and followed by a report of whether the bucket keeps versions at all.
|
|
6
9
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
import type { LifecycleRule, S3Client } from '@aws-sdk/client-s3';
|
|
11
|
+
import type { Logger } from '../../logging/logger';
|
|
12
|
+
/**
|
|
13
|
+
* Days a released payload's noncurrent version survives behind its delete
|
|
14
|
+
* marker before S3 reclaims it. One day is the smallest the lifecycle API
|
|
15
|
+
* accepts and it rounds up to the next UTC midnight, so the window is 24-48 h:
|
|
16
|
+
* long enough to restore a payload released in error, short enough that a
|
|
17
|
+
* versioned bucket does not pay for every release it has ever made. It is a
|
|
18
|
+
* floor and never a cap — a longer retention the bucket already carries is
|
|
19
|
+
* kept, because this package has no business shortening someone else's
|
|
20
|
+
* recovery window. Inert on an unversioned bucket, which has no noncurrent
|
|
21
|
+
* versions to expire.
|
|
22
|
+
*/
|
|
23
|
+
export declare const S3_RELEASE_GRACE_DAYS = 1;
|
|
24
|
+
/** The rules to ensure: on which bucket, for which prefix, expiring after how many days. */
|
|
25
|
+
export interface LifecycleTarget {
|
|
26
|
+
readonly bucket: string;
|
|
27
|
+
readonly prefix: string;
|
|
28
|
+
readonly days: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Ensure the two rules scoped to `target.prefix` exist on `target.bucket`: a
|
|
32
|
+
* `target.days`-day expiration for current versions, and the reclaim that
|
|
33
|
+
* removes the delete marker a released payload leaves behind.
|
|
34
|
+
*
|
|
35
|
+
* Accepts: `target.prefix` — re-checked for scoping here, because these rules
|
|
36
|
+
* are the one place an unscoped prefix would destroy data outside this
|
|
37
|
+
* library's. `target.days` — the current-version expiry only. Released
|
|
38
|
+
* versions are governed by the release grace instead (see {@link ttlRule}),
|
|
39
|
+
* which is a floor measured against every rule already governing these keys.
|
|
40
|
+
* Both are inert on an unversioned bucket, which keeps no noncurrent version
|
|
41
|
+
* and leaves no marker.
|
|
42
|
+
*
|
|
43
|
+
* Returns: nothing. Idempotent: when both rules already say this, no write is
|
|
44
|
+
* issued. The bucket's versioning state is reported either way, because the
|
|
45
|
+
* containment a released payload depends on is missing or present regardless
|
|
46
|
+
* of whether this particular call had a rule to write.
|
|
47
|
+
*
|
|
48
|
+
* Throws: `VALIDATION` naming `s3.keyPrefix` for an unscoped prefix, or when
|
|
49
|
+
* either rule id this prefix produces is already held by a different prefix
|
|
50
|
+
* (see {@link assertNoIdCollision}); otherwise whatever the SDK rejects with. A
|
|
51
|
+
* bucket with no lifecycle configuration at all is not an error — S3 reports
|
|
52
|
+
* `NoSuchLifecycleConfiguration` and this starts from an empty rule set.
|
|
53
|
+
*
|
|
54
|
+
* Guarantees: rules this package did not write are preserved, and so is the
|
|
55
|
+
* bucket-level `TransitionDefaultMinimumObjectSize` — a Put replaces the whole
|
|
56
|
+
* configuration, so dropping it would silently reset the bucket to the default.
|
|
57
|
+
*/
|
|
58
|
+
export declare function ensureLifecycleRule(client: S3Client, target: LifecycleTarget, logger: Logger): Promise<void>;
|
|
59
|
+
/** The rule to build: its id, its prefix, and the days after which current versions expire. */
|
|
60
|
+
interface RuleTarget {
|
|
61
|
+
readonly id: string;
|
|
62
|
+
readonly prefix: string;
|
|
63
|
+
readonly days: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The rule that expires current versions on the TTL's schedule and released
|
|
67
|
+
* ones on the grace.
|
|
68
|
+
*
|
|
69
|
+
* Accepts: `rules` — everything the bucket holds, which is what the grace is
|
|
70
|
+
* measured against. `existing` — the rule this one replaces, if any.
|
|
71
|
+
*
|
|
72
|
+
* Returns: the rule to write. Every field of `existing` this package does not
|
|
73
|
+
* manage is carried through, because the rewrite a changed TTL triggers is
|
|
74
|
+
* otherwise unrecoverable: the next call reads the rewritten rule as already
|
|
75
|
+
* correct and never restores what it dropped.
|
|
76
|
+
*
|
|
77
|
+
* Throws: nothing.
|
|
78
|
+
*
|
|
79
|
+
* Guarantees: the `Expiration` is replaced rather than merged. Merging this
|
|
80
|
+
* package's `Days` into a `Date` an operator set would change the expiry they
|
|
81
|
+
* configured, whatever the service made of the pair.
|
|
82
|
+
*/
|
|
83
|
+
export declare function ttlRule(rule: RuleTarget, rules: readonly LifecycleRule[], existing?: LifecycleRule): LifecycleRule;
|
|
84
|
+
/**
|
|
85
|
+
* The rule that reclaims the delete marker a release leaves, once its last
|
|
86
|
+
* noncurrent version has expired.
|
|
87
|
+
*
|
|
88
|
+
* Accepts: `existing` — the rule this one replaces, if any.
|
|
89
|
+
*
|
|
90
|
+
* Returns: the rule to write, a second one rather than a field on the TTL
|
|
91
|
+
* rule: S3 refuses `ExpiredObjectDeleteMarker` inside an `Expiration` that
|
|
92
|
+
* also carries `Days`, so each rule's `Expiration` holds its own half and
|
|
93
|
+
* nothing of the other's. Fields this package does not manage are carried
|
|
94
|
+
* through as they are on the TTL rule — this id is one this package invented,
|
|
95
|
+
* but that is no reason to drop what an operator has since put on it.
|
|
96
|
+
*
|
|
97
|
+
* Throws: nothing.
|
|
98
|
+
*/
|
|
99
|
+
export declare function markerRule(id: string, prefix: string, existing?: LifecycleRule): LifecycleRule;
|
|
100
|
+
/**
|
|
101
|
+
* Refuse to touch a rule that carries one of this prefix's ids but scopes a
|
|
102
|
+
* different prefix. Three shapes reach here: slugging maps every
|
|
103
|
+
* non-alphanumeric character to `-`, so `app/langgraph/` and `app-langgraph/`
|
|
104
|
+
* produce one id; the marker rule appends `-markers`, so `app/`'s marker id is
|
|
105
|
+
* the expiration id of `app-markers/`; and a rule written in the older schema
|
|
106
|
+
* holds an id this package would take while naming its scope in the top-level
|
|
107
|
+
* `Prefix`.
|
|
108
|
+
*
|
|
109
|
+
* Accepts: `rule` — the rule holding `id`, or nothing. `prefix` — the one this
|
|
110
|
+
* call scopes rules to.
|
|
111
|
+
*
|
|
112
|
+
* Returns: nothing: `rule` is kept under its declared type, and this checks
|
|
113
|
+
* it. A rule naming no scope anywhere is taken over, and so is one already
|
|
114
|
+
* scoping this prefix — including in the older schema, which is then upgraded
|
|
115
|
+
* to a filter.
|
|
116
|
+
*
|
|
117
|
+
* Throws: `VALIDATION` naming `s3.keyPrefix`. The id and the scope are
|
|
118
|
+
* both bounded by {@link truncateForLog}: the scope is whatever the bucket's
|
|
119
|
+
* lifecycle configuration holds, and the id is composed from an
|
|
120
|
+
* `s3.keyPrefix` checked for shape and never for length.
|
|
121
|
+
*
|
|
122
|
+
* Guarantees: the scope is read wherever the rule names it, through the same
|
|
123
|
+
* {@link scopeOf} the floor uses. Reading only `Filter.Prefix` would let a
|
|
124
|
+
* rule in the older schema through, and the rewrite would then replace its
|
|
125
|
+
* scope with this one's — so the objects that rule governs would silently
|
|
126
|
+
* lose their expiration, and a bucket-wide rule would narrow to this prefix.
|
|
127
|
+
*/
|
|
128
|
+
export declare function assertNoIdCollision(rule: LifecycleRule | undefined, prefix: string, id: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Whether the rule the bucket carries already says what would be written.
|
|
131
|
+
*
|
|
132
|
+
* Accepts: `existing` — the held rule, or nothing. `desired` — what a write
|
|
133
|
+
* would put there.
|
|
134
|
+
*
|
|
135
|
+
* Returns: whether a write can be skipped. A rule in the older schema never
|
|
136
|
+
* matches, because it names its prefix somewhere this does not read, so it is
|
|
137
|
+
* rewritten once into a filter and matches from then on.
|
|
138
|
+
*
|
|
139
|
+
* Throws: nothing.
|
|
140
|
+
*/
|
|
141
|
+
export declare function alreadyCorrect(existing: LifecycleRule | undefined, desired: LifecycleRule): boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Report whether `bucket` keeps versions, which is the whole of the recovery
|
|
144
|
+
* window behind a released payload.
|
|
145
|
+
*
|
|
146
|
+
* Accepts: `bucket` — the offload bucket. `logger` — the adapter's; silent by
|
|
147
|
+
* default, like every other event this package emits.
|
|
148
|
+
*
|
|
149
|
+
* Returns: nothing. A versioned bucket is silent; the other two states warn
|
|
150
|
+
* and name their own remedy, because those remedies differ — a bucket that
|
|
151
|
+
* never had versioning needs it enabled, while a suspended one needs it
|
|
152
|
+
* re-enabled *and* an accounting of what suspension has already destroyed.
|
|
153
|
+
*
|
|
154
|
+
* Throws: nothing, deliberately. A failure of the call itself is a `warn` too,
|
|
155
|
+
* including the `AccessDenied` of a role that provisioned lifecycle rules
|
|
156
|
+
* yesterday without this action: a permission the call did not need then must
|
|
157
|
+
* not break it now. This runs after the rules are written for the same reason
|
|
158
|
+
* — a bucket that cannot answer still gets them.
|
|
159
|
+
*
|
|
160
|
+
* Guarantees: a bucket that has never been versioned answers with an empty
|
|
161
|
+
* body, so the absent state is `Status === undefined`. It is never the string
|
|
162
|
+
* `'Disabled'`, which this API does not return, and testing for one would read
|
|
163
|
+
* an unversioned bucket as a versioned one.
|
|
164
|
+
*/
|
|
165
|
+
export declare function reportBucketVersioning(client: S3Client, bucket: string, logger: Logger): Promise<void>;
|
|
166
|
+
export {};
|
|
@@ -1,47 +1,355 @@
|
|
|
1
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
|
+
*/
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.S3_RELEASE_GRACE_DAYS = void 0;
|
|
3
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");
|
|
4
22
|
const client_1 = require("./client");
|
|
5
23
|
const config_1 = require("./config");
|
|
6
|
-
|
|
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) {
|
|
7
37
|
const { GetBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
|
|
8
38
|
try {
|
|
9
39
|
const existing = await client.send(new GetBucketLifecycleConfigurationCommand({ Bucket: bucket }));
|
|
10
|
-
return
|
|
40
|
+
return {
|
|
41
|
+
rules: existing.Rules ?? [],
|
|
42
|
+
transitionDefaultMinimumObjectSize: existing.TransitionDefaultMinimumObjectSize,
|
|
43
|
+
};
|
|
11
44
|
}
|
|
12
45
|
catch (error) {
|
|
13
|
-
if (
|
|
14
|
-
return [];
|
|
46
|
+
if ((0, classify_1.isMissingLifecycleConfiguration)(error))
|
|
47
|
+
return { rules: [] };
|
|
15
48
|
throw error;
|
|
16
49
|
}
|
|
17
50
|
}
|
|
18
|
-
|
|
19
|
-
|
|
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
|
+
}));
|
|
20
67
|
}
|
|
21
68
|
/**
|
|
22
|
-
*
|
|
23
|
-
* `
|
|
24
|
-
*
|
|
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.
|
|
25
95
|
*/
|
|
26
|
-
async function ensureLifecycleRule(client,
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
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,
|
|
34
227
|
Filter: { Prefix: prefix },
|
|
35
228
|
Status: 'Enabled',
|
|
36
|
-
Expiration: {
|
|
229
|
+
Expiration: { ExpiredObjectDeleteMarker: true },
|
|
37
230
|
};
|
|
38
|
-
const merged = existing
|
|
39
|
-
? rules.map((rule) => (rule.ID === ruleId ? newRule : rule))
|
|
40
|
-
: [...rules, newRule];
|
|
41
|
-
const { PutBucketLifecycleConfigurationCommand } = await (0, client_1.loadS3Sdk)();
|
|
42
|
-
await client.send(new PutBucketLifecycleConfigurationCommand({
|
|
43
|
-
Bucket: bucket,
|
|
44
|
-
LifecycleConfiguration: { Rules: merged },
|
|
45
|
-
}));
|
|
46
231
|
}
|
|
47
|
-
|
|
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
|
+
}
|