@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
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Hides which adapter-wide construction options are accepted.
|
|
4
|
+
*
|
|
5
|
+
* The table name, the client choice, the ttl, the retry policy, the recency
|
|
6
|
+
* index, the read concurrency, compression and S3 offload are checked here with
|
|
7
|
+
* their bounds, before an adapter builds anything, so a misconfiguration
|
|
8
|
+
* surfaces at construction rather than on the first call.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.MAX_READ_CONCURRENCY = exports.MAX_RETRY_DELAY_MS = exports.MAX_RETRY_ATTEMPTS = exports.MAX_PAYLOAD_BUFFER_BYTES = void 0;
|
|
12
|
+
exports.assertTableName = assertTableName;
|
|
13
|
+
exports.assertClientChoice = assertClientChoice;
|
|
14
|
+
exports.assertRetryBounds = assertRetryBounds;
|
|
15
|
+
exports.assertRetryPolicy = assertRetryPolicy;
|
|
16
|
+
exports.assertBaseAdapterOptions = assertBaseAdapterOptions;
|
|
17
|
+
exports.assertCompression = assertCompression;
|
|
18
|
+
exports.assertS3 = assertS3;
|
|
19
|
+
const codec_1 = require("../codec/codec");
|
|
20
|
+
const config_1 = require("../codec/s3/config");
|
|
21
|
+
const recency_index_1 = require("../dynamodb/recency-index");
|
|
22
|
+
const errors_1 = require("../errors/errors");
|
|
23
|
+
const option_shape_1 = require("./option-shape");
|
|
24
|
+
const primitives_1 = require("./primitives");
|
|
25
|
+
const ttl_1 = require("./ttl");
|
|
26
|
+
/** DynamoDB's table-name rule: 3–255 characters from `[A-Za-z0-9_.-]`. */
|
|
27
|
+
const TABLE_NAME_PATTERN = /^[A-Za-z0-9_.-]{3,255}$/;
|
|
28
|
+
/**
|
|
29
|
+
* Largest `s3.maxDownloadBytes`/`compression.maxDecompressedBytes` an adapter
|
|
30
|
+
* accepts (512 MiB): both hold one buffer fully resident while it is read or
|
|
31
|
+
* inflated, and `BaseAdapterOptions.readConcurrency`'s doc multiplies the two
|
|
32
|
+
* together into the package's memory ceiling, so an unbounded value here is an
|
|
33
|
+
* unbounded process, not just an unbounded object.
|
|
34
|
+
*/
|
|
35
|
+
exports.MAX_PAYLOAD_BUFFER_BYTES = 512 * 1024 * 1024;
|
|
36
|
+
/** Largest `retry.maxAttempts` an adapter accepts; beyond it a retry loop is a hang, not a policy. */
|
|
37
|
+
exports.MAX_RETRY_ATTEMPTS = 100;
|
|
38
|
+
/**
|
|
39
|
+
* Largest `retry.baseDelayMs`/`retry.maxDelayMs` an adapter accepts (one
|
|
40
|
+
* minute): combined with {@link MAX_RETRY_ATTEMPTS}, an unbounded per-attempt
|
|
41
|
+
* delay turns a bounded attempt count back into an effectively unbounded wait.
|
|
42
|
+
*/
|
|
43
|
+
exports.MAX_RETRY_DELAY_MS = 60_000;
|
|
44
|
+
/**
|
|
45
|
+
* Largest `readConcurrency` an adapter accepts: it is a multiplier on the
|
|
46
|
+
* memory-ceiling formula (see the option's own doc) and on requests fired at
|
|
47
|
+
* once, so an unbounded value turns a typo into an out-of-memory crash or a
|
|
48
|
+
* request storm against the table/bucket.
|
|
49
|
+
*/
|
|
50
|
+
exports.MAX_READ_CONCURRENCY = 128;
|
|
51
|
+
const RETRY_KEYS = (0, option_shape_1.allKeysOf)({
|
|
52
|
+
maxAttempts: 'maxAttempts',
|
|
53
|
+
baseDelayMs: 'baseDelayMs',
|
|
54
|
+
maxDelayMs: 'maxDelayMs',
|
|
55
|
+
});
|
|
56
|
+
/**
|
|
57
|
+
* Validate a table name against DynamoDB's own naming rule.
|
|
58
|
+
*
|
|
59
|
+
* Accepts: `tableName` — as the caller gave it.
|
|
60
|
+
*
|
|
61
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
62
|
+
* checks it.
|
|
63
|
+
*
|
|
64
|
+
* Throws: `VALIDATION` naming `tableName`.
|
|
65
|
+
*/
|
|
66
|
+
function assertTableName(tableName) {
|
|
67
|
+
if (typeof tableName !== 'string' || !TABLE_NAME_PATTERN.test(tableName)) {
|
|
68
|
+
throw (0, errors_1.validationError)('tableName must be 3-255 characters from [A-Za-z0-9_.-], as DynamoDB requires', 'tableName');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Reject a client choice that names two ways of getting one, or a
|
|
73
|
+
* `clientConfig` that is not an object.
|
|
74
|
+
*
|
|
75
|
+
* Accepts: the three client options, from an adapter or from the factory that
|
|
76
|
+
* defaults them. An injected `client` is used as-is, so a `clientConfig` or
|
|
77
|
+
* `createClient` given alongside it would be silently ignored — including a
|
|
78
|
+
* `region` the caller believes is in effect. `clientConfig`, when given, must
|
|
79
|
+
* be an object that is neither `null` nor an array; what it holds is the AWS
|
|
80
|
+
* SDK's to judge.
|
|
81
|
+
*
|
|
82
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
83
|
+
* checks it.
|
|
84
|
+
*
|
|
85
|
+
* Throws: `VALIDATION` naming `client` for both ways at once, then
|
|
86
|
+
* `clientConfig` for one that is not an object.
|
|
87
|
+
*/
|
|
88
|
+
function assertClientChoice(options) {
|
|
89
|
+
if (options.client &&
|
|
90
|
+
(options.clientConfig !== undefined || options.createClient !== undefined)) {
|
|
91
|
+
throw (0, errors_1.validationError)('provide either `client` or `clientConfig`/`createClient`, not both: an injected client ' +
|
|
92
|
+
'is used as-is and the configuration would be silently ignored', 'client');
|
|
93
|
+
}
|
|
94
|
+
// The shape only, never the keys, and on purpose: they are the AWS SDK's
|
|
95
|
+
// `DynamoDBClientConfig`, which gains keys between SDK releases, and an
|
|
96
|
+
// application may install a newer SDK than the one this package was
|
|
97
|
+
// compiled against, so a key list compiled in here would refuse valid
|
|
98
|
+
// configuration. The SDK reads each key itself.
|
|
99
|
+
if (options.clientConfig !== undefined)
|
|
100
|
+
(0, option_shape_1.assertObjectShape)(options.clientConfig, 'clientConfig');
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The three numeric bounds every retry policy shares, regardless of which
|
|
104
|
+
* other keys the caller's own type allows beyond them. Split out so a caller
|
|
105
|
+
* with a wider surface than {@link RetryPolicy} (`backfillRecencyIndex`'s
|
|
106
|
+
* `RetryOptions`, which also exposes `onRetry`, `isRetryable` and friends)
|
|
107
|
+
* can reuse the identical bounds without going through {@link
|
|
108
|
+
* assertRetryPolicy}'s narrower `assertShape`, which would refuse those
|
|
109
|
+
* extra keys outright.
|
|
110
|
+
*
|
|
111
|
+
* Accepts: `policy` — its `maxAttempts`, `baseDelayMs` and `maxDelayMs`, each
|
|
112
|
+
* optional.
|
|
113
|
+
*
|
|
114
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
115
|
+
* checks it.
|
|
116
|
+
*
|
|
117
|
+
* Throws: `VALIDATION` naming `retry.maxAttempts`, `retry.baseDelayMs` or
|
|
118
|
+
* `retry.maxDelayMs`.
|
|
119
|
+
*/
|
|
120
|
+
function assertRetryBounds(policy) {
|
|
121
|
+
if (policy.maxAttempts !== undefined) {
|
|
122
|
+
(0, primitives_1.assertInteger)(policy.maxAttempts, 'retry.maxAttempts', { min: 1, max: exports.MAX_RETRY_ATTEMPTS });
|
|
123
|
+
}
|
|
124
|
+
if (policy.baseDelayMs !== undefined) {
|
|
125
|
+
(0, primitives_1.assertInteger)(policy.baseDelayMs, 'retry.baseDelayMs', { min: 1, max: exports.MAX_RETRY_DELAY_MS });
|
|
126
|
+
}
|
|
127
|
+
if (policy.maxDelayMs !== undefined) {
|
|
128
|
+
(0, primitives_1.assertInteger)(policy.maxDelayMs, 'retry.maxDelayMs', {
|
|
129
|
+
min: policy.baseDelayMs ?? 1,
|
|
130
|
+
max: exports.MAX_RETRY_DELAY_MS,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validate a retry policy: shape, then each bound.
|
|
136
|
+
*
|
|
137
|
+
* Accepts: `policy` — must be an object naming only `maxAttempts`,
|
|
138
|
+
* `baseDelayMs` and `maxDelayMs`; each, if given, is a bounded integer.
|
|
139
|
+
*
|
|
140
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
141
|
+
* checks it.
|
|
142
|
+
*
|
|
143
|
+
* Throws: `VALIDATION` naming `retry` or `retry.<key>`.
|
|
144
|
+
*/
|
|
145
|
+
function assertRetryPolicy(policy) {
|
|
146
|
+
(0, option_shape_1.assertShape)(policy, RETRY_KEYS, 'retry');
|
|
147
|
+
assertRetryBounds(policy);
|
|
148
|
+
}
|
|
149
|
+
/** The recency index: a named GSI, and the partition count rows are sharded across. */
|
|
150
|
+
function assertRecencyIndex(options) {
|
|
151
|
+
if (options.indexShards !== undefined) {
|
|
152
|
+
(0, primitives_1.assertInteger)(options.indexShards, 'indexShards', { min: 1, max: recency_index_1.MAX_INDEX_SHARDS });
|
|
153
|
+
}
|
|
154
|
+
if (options.indexName !== undefined)
|
|
155
|
+
(0, primitives_1.assertNonEmptyString)(options.indexName, 'indexName');
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Validate the options every adapter shares, at construction.
|
|
159
|
+
*
|
|
160
|
+
* Accepts: `options` — must be an object. `tableName` is required; every other
|
|
161
|
+
* option is optional, and `undefined` means "not configured" for each. A
|
|
162
|
+
* nested `ttl`, `retry`, `compression` or `s3` must be an object whose keys
|
|
163
|
+
* this package reads: a misspelt key is rejected rather than ignored, because
|
|
164
|
+
* the caller would otherwise run on a default they believe they overrode.
|
|
165
|
+
* `clientConfig` and `s3.clientConfig` must be objects, but their keys belong
|
|
166
|
+
* to the AWS SDK and are not checked. Keys of `options` itself are not checked
|
|
167
|
+
* here — the adapter types differ and this validator sees only the shared ones.
|
|
168
|
+
*
|
|
169
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
170
|
+
* checks it.
|
|
171
|
+
*
|
|
172
|
+
* Throws: `VALIDATION` whose `context.field` names the offending option,
|
|
173
|
+
* dotted for a nested one (`s3.bucketName`). The order is `tableName`, client
|
|
174
|
+
* choice, `ttl`, `retry`, `compression`, `s3`, `readConcurrency`, then the
|
|
175
|
+
* index options.
|
|
176
|
+
*
|
|
177
|
+
* Guarantees: a misconfiguration surfaces at construction, naming the option,
|
|
178
|
+
* rather than as a raw AWS error on the first request.
|
|
179
|
+
*/
|
|
180
|
+
function assertBaseAdapterOptions(options) {
|
|
181
|
+
if (typeof options !== 'object' || options === null) {
|
|
182
|
+
throw (0, errors_1.validationError)('options must be an object naming at least a tableName', 'options');
|
|
183
|
+
}
|
|
184
|
+
assertTableName(options.tableName);
|
|
185
|
+
assertClientChoice(options);
|
|
186
|
+
if (options.ttl !== undefined)
|
|
187
|
+
(0, ttl_1.resolveTtlSeconds)(options.ttl);
|
|
188
|
+
if (options.retry !== undefined)
|
|
189
|
+
assertRetryPolicy(options.retry);
|
|
190
|
+
if (options.compression !== undefined)
|
|
191
|
+
assertCompression(options.compression);
|
|
192
|
+
if (options.s3 !== undefined)
|
|
193
|
+
assertS3(options.s3);
|
|
194
|
+
if (options.readConcurrency !== undefined) {
|
|
195
|
+
(0, primitives_1.assertInteger)(options.readConcurrency, 'readConcurrency', {
|
|
196
|
+
min: 1,
|
|
197
|
+
max: exports.MAX_READ_CONCURRENCY,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
assertRecencyIndex(options);
|
|
201
|
+
}
|
|
202
|
+
/** Server-side encryption algorithms S3 accepts for `PutObject`. */
|
|
203
|
+
const SSE_ALGORITHMS = ['AES256', 'aws:kms', 'aws:kms:dsse'];
|
|
204
|
+
const COMPRESSION_KEYS = (0, option_shape_1.allKeysOf)({
|
|
205
|
+
enabled: 'enabled',
|
|
206
|
+
level: 'level',
|
|
207
|
+
minSizeBytes: 'minSizeBytes',
|
|
208
|
+
maxDecompressedBytes: 'maxDecompressedBytes',
|
|
209
|
+
});
|
|
210
|
+
const S3_KEYS = (0, option_shape_1.allKeysOf)({
|
|
211
|
+
bucketName: 'bucketName',
|
|
212
|
+
keyPrefix: 'keyPrefix',
|
|
213
|
+
thresholdBytes: 'thresholdBytes',
|
|
214
|
+
serverSideEncryption: 'serverSideEncryption',
|
|
215
|
+
sseKmsKeyId: 'sseKmsKeyId',
|
|
216
|
+
maxDownloadBytes: 'maxDownloadBytes',
|
|
217
|
+
clientConfig: 'clientConfig',
|
|
218
|
+
createS3Client: 'createS3Client',
|
|
219
|
+
});
|
|
220
|
+
/**
|
|
221
|
+
* Validate a `compression` config, honoring its allowed key set.
|
|
222
|
+
*
|
|
223
|
+
* Accepts: `config` — an object naming only {@link CompressionConfig}'s keys.
|
|
224
|
+
*
|
|
225
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
226
|
+
* checks it.
|
|
227
|
+
*
|
|
228
|
+
* Throws: `VALIDATION` naming the offending field, dotted under
|
|
229
|
+
* `compression`.
|
|
230
|
+
*/
|
|
231
|
+
function assertCompression(config) {
|
|
232
|
+
(0, option_shape_1.assertShape)(config, COMPRESSION_KEYS, 'compression');
|
|
233
|
+
if (typeof config.enabled !== 'boolean') {
|
|
234
|
+
throw (0, errors_1.validationError)('compression.enabled must be a boolean', 'compression.enabled');
|
|
235
|
+
}
|
|
236
|
+
if (config.level !== undefined) {
|
|
237
|
+
(0, primitives_1.assertInteger)(config.level, 'compression.level', { min: 0, max: 9 });
|
|
238
|
+
}
|
|
239
|
+
if (config.minSizeBytes !== undefined) {
|
|
240
|
+
// Bounded by MAX_PAYLOAD_BUFFER_BYTES, not by MAX_INLINE_PAYLOAD_BYTES as
|
|
241
|
+
// `s3.thresholdBytes` is, because the two differ in kind. `encodePayload`
|
|
242
|
+
// compresses first and only then decides inline versus offload, on the
|
|
243
|
+
// compressed size — so `minSizeBytes` above the inline limit, paired with
|
|
244
|
+
// `s3`, is a meaningful configuration: compress only what will be offloaded
|
|
245
|
+
// anyway. A `thresholdBytes` above the inline limit is not: a payload
|
|
246
|
+
// between the two is too large to store inline and too small to offload,
|
|
247
|
+
// so its write fails. `minSizeBytes` only decides whether gzip runs; the
|
|
248
|
+
// only value it can never act on is one larger than any payload this
|
|
249
|
+
// package can read back.
|
|
250
|
+
(0, primitives_1.assertInteger)(config.minSizeBytes, 'compression.minSizeBytes', {
|
|
251
|
+
min: 0,
|
|
252
|
+
max: exports.MAX_PAYLOAD_BUFFER_BYTES,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (config.maxDecompressedBytes !== undefined) {
|
|
256
|
+
(0, primitives_1.assertInteger)(config.maxDecompressedBytes, 'compression.maxDecompressedBytes', {
|
|
257
|
+
min: 1,
|
|
258
|
+
max: exports.MAX_PAYLOAD_BUFFER_BYTES,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Validate the two `s3` options `PutObject` receives as they were given.
|
|
264
|
+
*
|
|
265
|
+
* Accepts: `config.serverSideEncryption` — absent, or an algorithm S3 accepts.
|
|
266
|
+
* `config.sseKmsKeyId` — absent, or a non-empty string. Only its type is
|
|
267
|
+
* checked; whether it names a real key, by id or by ARN, is for S3 to answer.
|
|
268
|
+
*
|
|
269
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
270
|
+
* checks it.
|
|
271
|
+
*
|
|
272
|
+
* Throws: `VALIDATION` naming `s3.serverSideEncryption` or
|
|
273
|
+
* `s3.sseKmsKeyId`. Unchecked, a truthy key id that is not a string was
|
|
274
|
+
* handed to `PutObject` at the first offload, and a falsy one (`''`, `null`,
|
|
275
|
+
* `0`) was dropped, uploading without the key the caller named.
|
|
276
|
+
*/
|
|
277
|
+
function assertS3Encryption(config) {
|
|
278
|
+
if (config.serverSideEncryption !== undefined &&
|
|
279
|
+
!SSE_ALGORITHMS.includes(config.serverSideEncryption)) {
|
|
280
|
+
throw (0, errors_1.validationError)(`s3.serverSideEncryption must be one of ${SSE_ALGORITHMS.join(', ')}`, 's3.serverSideEncryption');
|
|
281
|
+
}
|
|
282
|
+
if (config.sseKmsKeyId !== undefined) {
|
|
283
|
+
(0, primitives_1.assertNonEmptyString)(config.sseKmsKeyId, 's3.sseKmsKeyId');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Validate an `s3` offload config, honoring its allowed key set.
|
|
288
|
+
*
|
|
289
|
+
* Accepts: `config` — an object naming only {@link S3OffloadConfig}'s keys.
|
|
290
|
+
* `config.clientConfig`, when given, must be an object that is neither `null`
|
|
291
|
+
* nor an array; its own keys are not checked. `config.createS3Client`, when
|
|
292
|
+
* given, must be a function.
|
|
293
|
+
*
|
|
294
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
295
|
+
* checks it.
|
|
296
|
+
*
|
|
297
|
+
* Throws: `VALIDATION` naming the offending field, dotted under `s3`.
|
|
298
|
+
*/
|
|
299
|
+
function assertS3(config) {
|
|
300
|
+
(0, option_shape_1.assertShape)(config, S3_KEYS, 's3');
|
|
301
|
+
(0, primitives_1.assertNonEmptyString)(config.bucketName, 's3.bucketName');
|
|
302
|
+
// The shape only, never the keys: they are the AWS SDK's `S3ClientConfig`,
|
|
303
|
+
// which gains keys between SDK releases, and an application may install a
|
|
304
|
+
// newer SDK than the one this package was compiled against, so a key list
|
|
305
|
+
// compiled in here would refuse valid configuration.
|
|
306
|
+
if (config.clientConfig !== undefined)
|
|
307
|
+
(0, option_shape_1.assertObjectShape)(config.clientConfig, 's3.clientConfig');
|
|
308
|
+
if (config.thresholdBytes !== undefined) {
|
|
309
|
+
(0, primitives_1.assertInteger)(config.thresholdBytes, 's3.thresholdBytes', {
|
|
310
|
+
min: 1,
|
|
311
|
+
max: codec_1.MAX_INLINE_PAYLOAD_BYTES,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (config.keyPrefix !== undefined)
|
|
315
|
+
(0, config_1.assertScopedKeyPrefix)(config.keyPrefix);
|
|
316
|
+
if (config.maxDownloadBytes !== undefined) {
|
|
317
|
+
(0, primitives_1.assertInteger)(config.maxDownloadBytes, 's3.maxDownloadBytes', {
|
|
318
|
+
min: 1,
|
|
319
|
+
max: exports.MAX_PAYLOAD_BUFFER_BYTES,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
assertS3Encryption(config);
|
|
323
|
+
// Called to build the S3 client at the first offload, where a value that is
|
|
324
|
+
// not a function threw a bare `TypeError`.
|
|
325
|
+
if (config.createS3Client !== undefined && typeof config.createS3Client !== 'function') {
|
|
326
|
+
throw (0, errors_1.validationError)('s3.createS3Client must be a function', 's3.createS3Client');
|
|
327
|
+
}
|
|
328
|
+
}
|
|
@@ -1,25 +1,292 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Hides the rules every caller-supplied primitive must pass.
|
|
3
|
+
*
|
|
4
|
+
* What makes a string an identifier safe inside a key, an integer a page size
|
|
5
|
+
* this package serves, and an array a copy holding only strings is decided
|
|
6
|
+
* once here. Only `parseLimit` returns a branded type of its own —
|
|
7
|
+
* `PageLimit`, which only it can build (record 21); every other rule's
|
|
8
|
+
* `parse*` form returns the plain checked value, and a feature parser brands
|
|
9
|
+
* it into its own type. Feature parsers compose these rules rather than
|
|
10
|
+
* restate them, so tightening one changes every method at once.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Largest `limit` any read accepts, on every method that takes one.
|
|
14
|
+
*
|
|
15
|
+
* Chosen from what a page costs, which is linear in `limit` and amortised
|
|
16
|
+
* nowhere: every row of a page is held decoded and resident until the whole
|
|
17
|
+
* page is handed back, and an offloaded row is an S3 GET and a decompression
|
|
18
|
+
* of its own, `readConcurrency` at a time. A page of N rows is therefore N
|
|
19
|
+
* objects held at once and, in the worst case, N round trips before the caller
|
|
20
|
+
* sees the first of them.
|
|
21
|
+
*
|
|
22
|
+
* Ten thousand is where this package already says a read has stopped being one
|
|
23
|
+
* and become an export: `MAX_TOTAL_ROWS_IN_MEMORY`
|
|
24
|
+
* (`src/shared/dynamodb/paginate.ts`) refuses to collect more than that across
|
|
25
|
+
* a whole paginated query, and `LIST_SCAN_WARN_THRESHOLD`
|
|
26
|
+
* (`src/shared/dynamodb/paginate.ts`) tells an operator about a listing that
|
|
27
|
+
* walks that far. A single page allowed past either would hold more than every
|
|
28
|
+
* other path in the package may. Its own literal at the same value rather than
|
|
29
|
+
* an alias of them, for the reason `LIST_SCAN_WARN_THRESHOLD`
|
|
30
|
+
* (`src/shared/dynamodb/paginate.ts`) records.
|
|
31
|
+
*
|
|
32
|
+
* What it does *not* do is promise a memory figure: rows are the caller's own
|
|
33
|
+
* data, so ten thousand session summaries are a few megabytes while a hundred
|
|
34
|
+
* items at `MAX_INLINE_PAYLOAD_BYTES` (`src/shared/codec/codec.ts`) are forty.
|
|
35
|
+
* It bounds a typo — a `1e12` that would otherwise resolve — not a working set.
|
|
36
|
+
*
|
|
37
|
+
* What a caller loses at the ceiling is one large page, never the rows: every
|
|
38
|
+
* bounded read has a way to continue — `listSessions` a cursor, `search` an
|
|
39
|
+
* `offset`, `getMessages` a `before`, and `saver.list` streams and never
|
|
40
|
+
* accumulates — so an answer larger than this is paid for as pages.
|
|
41
|
+
*/
|
|
42
|
+
export declare const MAX_PAGE_LIMIT = 10000;
|
|
43
|
+
declare const pageLimitBrand: unique symbol;
|
|
44
|
+
/**
|
|
45
|
+
* A page size checked against the package-wide page rule: an integer from the
|
|
46
|
+
* call site's floor to {@link MAX_PAGE_LIMIT}. {@link parseLimit} is the only
|
|
47
|
+
* way to obtain one, so a reader that asks for a `PageLimit` cannot be handed a
|
|
48
|
+
* size nobody checked, and does not check it again. The brand is phantom: at
|
|
49
|
+
* run time it is the caller's own number.
|
|
50
|
+
*/
|
|
51
|
+
export type PageLimit = number & {
|
|
52
|
+
readonly [pageLimitBrand]: true;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* The value as a string, or a refusal.
|
|
56
|
+
*
|
|
57
|
+
* Accepts: `value` — anything. A JavaScript caller, or a TypeScript caller
|
|
58
|
+
* whose input came from JSON, can pass any type where a string is declared, and
|
|
59
|
+
* every rule after this one reaches a string method.
|
|
60
|
+
*
|
|
61
|
+
* Returns: `value`, typed as the string it was checked to be.
|
|
62
|
+
*
|
|
63
|
+
* Throws: `VALIDATION` naming `field`, for anything that is not a string.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseString(value: unknown, field: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* Throw `VALIDATION` unless `value` is a string holding at least one
|
|
68
|
+
* non-whitespace character.
|
|
69
|
+
*
|
|
70
|
+
* Accepts: `value` — any type; `''` and whitespace-only are rejected alongside
|
|
71
|
+
* non-strings. `field` — the option or identifier name carried on the error.
|
|
72
|
+
* The rule is {@link parseNonBlankString}'s; this form is for a value the
|
|
73
|
+
* caller keeps under its declared type.
|
|
74
|
+
*
|
|
75
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
76
|
+
* checks it.
|
|
77
|
+
*
|
|
78
|
+
* Throws: `VALIDATION` naming `field`.
|
|
79
|
+
*/
|
|
80
|
+
export declare function assertNonEmptyString(value: string, field: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* The value as an integer inside `bounds`.
|
|
83
|
+
*
|
|
84
|
+
* Accepts: `value` — anything; a non-number, a fraction, `NaN` and `Infinity`
|
|
85
|
+
* are all refused by the integer rule. `bounds` — omitted or `{}` bounds
|
|
86
|
+
* nothing; `min` and `max` are inclusive.
|
|
87
|
+
*
|
|
88
|
+
* Returns: `value`, typed as a number.
|
|
89
|
+
*
|
|
90
|
+
* Throws: `VALIDATION` naming `field`; the integer rule is reported before
|
|
91
|
+
* either bound.
|
|
92
|
+
*/
|
|
93
|
+
export declare function parseInteger(value: unknown, field: string, bounds?: {
|
|
94
|
+
min?: number;
|
|
95
|
+
max?: number;
|
|
96
|
+
}): number;
|
|
97
|
+
/**
|
|
98
|
+
* Throw `VALIDATION` unless `value` is an integer inside `bounds`.
|
|
99
|
+
*
|
|
100
|
+
* Accepts: `value` — any type; a non-number, a fraction, `NaN` and `Infinity`
|
|
101
|
+
* are all rejected by the integer rule. `bounds` — omitted or `{}` bounds
|
|
102
|
+
* nothing, `min` and `max` are inclusive and may be given together or alone.
|
|
103
|
+
* The rule is {@link parseInteger}'s; this form is for a value the caller
|
|
104
|
+
* keeps under its declared type.
|
|
105
|
+
*
|
|
106
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
107
|
+
* checks it.
|
|
108
|
+
*
|
|
109
|
+
* Throws: `VALIDATION` naming `field`; the integer rule is reported before
|
|
110
|
+
* either bound.
|
|
111
|
+
*/
|
|
112
|
+
export declare function assertInteger(value: number, field: string, bounds?: {
|
|
6
113
|
min?: number;
|
|
7
114
|
max?: number;
|
|
8
115
|
}): void;
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
116
|
+
/**
|
|
117
|
+
* The value as a page size this package will serve: an integer from `min` to
|
|
118
|
+
* {@link MAX_PAGE_LIMIT}.
|
|
119
|
+
*
|
|
120
|
+
* One rule for every `limit` a public method takes. Without it they would
|
|
121
|
+
* disagree three ways — no minimum on `saver.list`, so `limit: -1` would
|
|
122
|
+
* resolve; `0` refused by the history reads and accepted by the store — and
|
|
123
|
+
* none would have a ceiling, so `limit: 1e12` would resolve on five methods.
|
|
124
|
+
* The same mistake would be answered differently depending on which method a
|
|
125
|
+
* caller happened to reach for.
|
|
126
|
+
*
|
|
127
|
+
* What survives that unification is one message shape, one ceiling and two
|
|
128
|
+
* floors, because zero does not ask for the same thing on every method. A zero
|
|
129
|
+
* *page* is answered: the caller asked a listing for nothing, holds the empty
|
|
130
|
+
* array it returned, and can see that is what it got. A zero *conversation
|
|
131
|
+
* window* is refused: it feeds a model rather than a caller, an empty
|
|
132
|
+
* conversation is indistinguishable from one that never happened, and the
|
|
133
|
+
* answer the model gives is persisted as the transcript. So every call site
|
|
134
|
+
* passes its floor and says why; `1` is passed from exactly one place,
|
|
135
|
+
* `parseMessageWindow` in `src/history/internal/parse.ts`, which is the
|
|
136
|
+
* check behind `history.getMessages` and `history.forSession` alike.
|
|
137
|
+
*
|
|
138
|
+
* Accepts: `value` — any type; a non-number, a fraction, `NaN` and `Infinity`
|
|
139
|
+
* are all rejected by the integer rule. `min` — `0` where an empty result is a
|
|
140
|
+
* request the call site answers without issuing a read, `1` where an empty
|
|
141
|
+
* result would be mistaken for an empty conversation. A negative value is
|
|
142
|
+
* refused at either floor rather than read as zero: it is a page size that was
|
|
143
|
+
* computed, and the computation went wrong.
|
|
144
|
+
*
|
|
145
|
+
* Returns: `value` as a {@link PageLimit}.
|
|
146
|
+
*
|
|
147
|
+
* Throws: `VALIDATION` naming `limit`, quoting the bound broken — the floor
|
|
148
|
+
* or {@link MAX_PAGE_LIMIT} — so the caller is told what the rule is rather
|
|
149
|
+
* than only that it has one.
|
|
150
|
+
*/
|
|
151
|
+
export declare function parseLimit(value: unknown, min: 0 | 1): PageLimit;
|
|
152
|
+
/**
|
|
153
|
+
* The value as an array of strings, copied.
|
|
154
|
+
*
|
|
155
|
+
* Accepts: `value` — anything; a non-array is refused, as is an array holding
|
|
156
|
+
* anything but a string. An empty array is valid.
|
|
157
|
+
*
|
|
158
|
+
* Returns: a copy of `value`, so a caller changing its own array afterwards
|
|
159
|
+
* changes nothing this package acts on.
|
|
160
|
+
*
|
|
161
|
+
* Throws: `VALIDATION` naming `field`, its message identifying the offending
|
|
162
|
+
* index. Walked by position rather than `Array.prototype.some`, which skips a
|
|
163
|
+
* hole in a sparse array instead of visiting it, and copied by position rather
|
|
164
|
+
* than `Array.prototype.slice`, which carries a hole forward instead of
|
|
165
|
+
* filling it: unchecked, a hole passed as a string and reached a caller who
|
|
166
|
+
* declared `string[]`.
|
|
167
|
+
*/
|
|
168
|
+
export declare function parseStringArray(value: unknown, field: string): string[];
|
|
169
|
+
/**
|
|
170
|
+
* Throw `VALIDATION` unless `value` is an array of strings.
|
|
171
|
+
*
|
|
172
|
+
* Accepts: `value` — declared `readonly string[]` for a caller whose types
|
|
173
|
+
* hold; a non-array is rejected, as is an array holding anything but a
|
|
174
|
+
* string. An empty array is valid. The rule is {@link parseStringArray}'s;
|
|
175
|
+
* this form is for a value the caller keeps under its declared type.
|
|
176
|
+
*
|
|
177
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
178
|
+
* checks it.
|
|
179
|
+
*
|
|
180
|
+
* Throws: `VALIDATION` naming `field`.
|
|
181
|
+
*/
|
|
182
|
+
export declare function assertStringArray(value: readonly string[], field: string): void;
|
|
183
|
+
/**
|
|
184
|
+
* Throw `VALIDATION` unless `value` is free of control characters.
|
|
185
|
+
*
|
|
186
|
+
* Accepts: `value` — any type, non-strings rejected first by
|
|
187
|
+
* {@link parseString}. Rejected code points are C0 (`U+0000`–`U+001F`), DEL
|
|
188
|
+
* (`U+007F`) and C1 (`U+0080`–`U+009F`). The rule is this function's own:
|
|
189
|
+
* {@link parseKeySegment} applies it to every key segment and identifier by
|
|
190
|
+
* calling this one, and this form serves a value the caller keeps under its
|
|
191
|
+
* declared type.
|
|
192
|
+
*
|
|
193
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
194
|
+
* checks it.
|
|
195
|
+
*
|
|
196
|
+
* Throws: `VALIDATION` naming `field`.
|
|
197
|
+
*
|
|
198
|
+
* Guarantees: an accepted value cannot terminate a log line or open a terminal
|
|
199
|
+
* escape sequence — neither `ESC` (`U+001B`) nor the single-byte `CSI`
|
|
200
|
+
* (`U+009B`) survives this rule. Identifiers are written into log lines by this
|
|
201
|
+
* package, and unneutralised output is CWE-117
|
|
202
|
+
* (https://cwe.mitre.org/data/definitions/117.html).
|
|
203
|
+
*/
|
|
12
204
|
export declare function assertNoControlChars(value: string, field: string): void;
|
|
13
|
-
/**
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
205
|
+
/**
|
|
206
|
+
* Throw `VALIDATION` unless every surrogate in `value` is part of a
|
|
207
|
+
* pair.
|
|
208
|
+
*
|
|
209
|
+
* Accepts: `value` — any type, non-strings rejected first by
|
|
210
|
+
* {@link parseString}. The rule is this function's own:
|
|
211
|
+
* {@link parseKeySegment} applies it to every key segment and identifier by
|
|
212
|
+
* calling this one, and this form serves a value the caller keeps under its
|
|
213
|
+
* declared type.
|
|
214
|
+
*
|
|
215
|
+
* Returns: nothing: the value is kept under its declared type, and this
|
|
216
|
+
* checks it.
|
|
217
|
+
*
|
|
218
|
+
* Throws: `VALIDATION` naming `field`.
|
|
219
|
+
*
|
|
220
|
+
* Guarantees: the mapping from an accepted value to its UTF-8 encoding is
|
|
221
|
+
* injective. `Buffer.from(value, 'utf8')` replaces a lone surrogate with
|
|
222
|
+
* U+FFFD, so two values differing only there would encode identically and,
|
|
223
|
+
* where that encoding is a storage key, address one object.
|
|
224
|
+
*/
|
|
225
|
+
export declare function assertWellFormed(value: string, field: string): void;
|
|
226
|
+
/**
|
|
227
|
+
* One segment of a key, which may be empty: every rule of
|
|
228
|
+
* {@link parseIdentifier} except non-blank. The checkpoint namespace is the one
|
|
229
|
+
* such value — `''` *is* the root namespace — and it is still a segment of both
|
|
230
|
+
* the sort key and the offloaded object's key, so a lone surrogate or a control
|
|
231
|
+
* character in it is as damaging as in any other.
|
|
232
|
+
*
|
|
233
|
+
* Accepts: `value` — anything. `separator`, `field`, `maxBytes` — as
|
|
234
|
+
* {@link parseIdentifier}.
|
|
235
|
+
*
|
|
236
|
+
* Returns: `value`, typed as a string.
|
|
237
|
+
*
|
|
238
|
+
* Throws: `VALIDATION` naming `field`, in this order: string, at most
|
|
239
|
+
* `maxBytes` of UTF-8, free of `separator`, free of control characters,
|
|
240
|
+
* well-formed UTF-16.
|
|
241
|
+
*/
|
|
242
|
+
export declare function parseKeySegment(value: unknown, separator: string, field: string, maxBytes: number): string;
|
|
243
|
+
/**
|
|
244
|
+
* The value as a caller-supplied identifier that reaches a DynamoDB key or an
|
|
245
|
+
* S3 object key, checked.
|
|
246
|
+
*
|
|
247
|
+
* Accepts: `value` — any type. `separator`, `field`, `maxBytes` — as the rules
|
|
248
|
+
* below.
|
|
249
|
+
*
|
|
250
|
+
* Returns: `value`, typed as a string. The caller's parser brands it.
|
|
251
|
+
*
|
|
252
|
+
* Throws: `VALIDATION` naming `field`. The rules apply in this order, and
|
|
253
|
+
* the order is part of the contract because a caller branches on which one
|
|
254
|
+
* failed: string, non-blank, at most `maxBytes` of UTF-8, free of `separator`,
|
|
255
|
+
* free of control characters, well-formed UTF-16.
|
|
256
|
+
*
|
|
257
|
+
* Guarantees: every guarantee of {@link assertNoControlChars} and
|
|
258
|
+
* {@link assertWellFormed} holds for an accepted value, and it composes into a
|
|
259
|
+
* key segment without escaping.
|
|
260
|
+
*
|
|
261
|
+
* Not guaranteed, and deliberately so: an accepted identifier is **not**
|
|
262
|
+
* normalised, and Unicode format characters (`Cf` — `U+200B` ZERO WIDTH SPACE,
|
|
263
|
+
* `U+200C`/`U+200D` the zero-width non-joiner and joiner, `U+FEFF`, `U+202E`
|
|
264
|
+
* RIGHT-TO-LEFT OVERRIDE) and the separators `U+2028`/`U+2029` are all
|
|
265
|
+
* accepted. Two facts make that safe, and one makes it necessary.
|
|
266
|
+
*
|
|
267
|
+
* It is safe because none of them can produce a collision. DynamoDB orders and
|
|
268
|
+
* compares strings by their UTF-8 bytes, and {@link assertWellFormed} has
|
|
269
|
+
* already made the mapping from an accepted identifier to those bytes
|
|
270
|
+
* injective — so two identifiers differing anywhere address two different
|
|
271
|
+
* rows. An identifier that reaches an S3 key is base64url-encoded on the way
|
|
272
|
+
* (`encodeKeyPart`), so none of these characters appears in a key at all. What
|
|
273
|
+
* one actually costs is a log line, a terminal or a console that renders two
|
|
274
|
+
* distinct identifiers alike: confusion for a reader, not a row either of them
|
|
275
|
+
* can reach. Terminal escapes and line breaks, which *are* an injection rather
|
|
276
|
+
* than a rendering, are refused by {@link assertNoControlChars}.
|
|
277
|
+
*
|
|
278
|
+
* It is necessary because refusing `Cf` would refuse ordinary text rather than
|
|
279
|
+
* hostile text. `U+200C` and `U+200D` carry meaning in Persian, Hindi and the
|
|
280
|
+
* Indic scripts — the Persian for "goes" is spelled with a `U+200C` — and
|
|
281
|
+
* `U+200D` is what joins the code points of every multi-person emoji. A rule
|
|
282
|
+
* against `Cf` would reject a `thread_id` or a store `key` taken from ordinary
|
|
283
|
+
* user text, in a package whose identifiers are the caller's own.
|
|
284
|
+
*
|
|
285
|
+
* Normalising would be worse than breaking: `NFC` folds `e` + `U+0301` onto
|
|
286
|
+
* `U+00E9`, so a row written under one form would afterwards be addressed
|
|
287
|
+
* under the other and the caller's data would stop being found. That is silent
|
|
288
|
+
* loss on upgrade, bought with a rendering nicety. A caller who wants either
|
|
289
|
+
* rule can apply it to its own identifiers before passing them.
|
|
290
|
+
*/
|
|
291
|
+
export declare function parseIdentifier(value: unknown, separator: string, field: string, maxBytes: number): string;
|
|
292
|
+
export {};
|