@atomicmemory/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/LICENSE +201 -0
- package/README.md +314 -0
- package/dist/app/bind-ephemeral.d.ts +18 -0
- package/dist/app/bind-ephemeral.js +22 -0
- package/dist/app/cors-headers.d.ts +12 -0
- package/dist/app/cors-headers.js +18 -0
- package/dist/app/create-app.d.ts +25 -0
- package/dist/app/create-app.js +156 -0
- package/dist/app/runtime-config-route-snapshot.d.ts +27 -0
- package/dist/app/runtime-config-route-snapshot.js +27 -0
- package/dist/app/runtime-container.d.ts +281 -0
- package/dist/app/runtime-container.js +297 -0
- package/dist/app/startup-checks.d.ts +28 -0
- package/dist/app/startup-checks.js +45 -0
- package/dist/bin.d.ts +17 -0
- package/dist/bin.js +128 -0
- package/dist/config.d.ts +680 -0
- package/dist/config.js +808 -0
- package/dist/db/agent-trust-repository.d.ts +49 -0
- package/dist/db/agent-trust-repository.js +66 -0
- package/dist/db/belief-edges-repository.d.ts +68 -0
- package/dist/db/belief-edges-repository.js +124 -0
- package/dist/db/claim-repository.d.ts +6 -0
- package/dist/db/claim-repository.js +4 -0
- package/dist/db/contradictions-repository.d.ts +56 -0
- package/dist/db/contradictions-repository.js +88 -0
- package/dist/db/document-chunk-repository.d.ts +48 -0
- package/dist/db/document-chunk-repository.js +145 -0
- package/dist/db/document-chunk-types.d.ts +35 -0
- package/dist/db/document-chunk-types.js +9 -0
- package/dist/db/document-list-cursor.d.ts +45 -0
- package/dist/db/document-list-cursor.js +111 -0
- package/dist/db/document-list-repository.d.ts +103 -0
- package/dist/db/document-list-repository.js +204 -0
- package/dist/db/entity-cards-repository.d.ts +37 -0
- package/dist/db/entity-cards-repository.js +46 -0
- package/dist/db/entity-values-repository.d.ts +26 -0
- package/dist/db/entity-values-repository.js +57 -0
- package/dist/db/link-repository.d.ts +30 -0
- package/dist/db/link-repository.js +54 -0
- package/dist/db/memory-repository.d.ts +163 -0
- package/dist/db/memory-repository.js +232 -0
- package/dist/db/migrate.d.ts +6 -0
- package/dist/db/migrate.js +36 -0
- package/dist/db/mmr.d.ts +14 -0
- package/dist/db/mmr.js +57 -0
- package/dist/db/passport-feed-repository.d.ts +91 -0
- package/dist/db/passport-feed-repository.js +198 -0
- package/dist/db/pg-episode-store.d.ts +19 -0
- package/dist/db/pg-episode-store.js +17 -0
- package/dist/db/pg-link-store.d.ts +17 -0
- package/dist/db/pg-link-store.js +14 -0
- package/dist/db/pg-memory-store.d.ts +68 -0
- package/dist/db/pg-memory-store.js +53 -0
- package/dist/db/pg-recap-store.d.ts +13 -0
- package/dist/db/pg-recap-store.js +19 -0
- package/dist/db/pg-representation-store.d.ts +17 -0
- package/dist/db/pg-representation-store.js +17 -0
- package/dist/db/pg-search-store.d.ts +29 -0
- package/dist/db/pg-search-store.js +47 -0
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +21 -0
- package/dist/db/ppr.d.ts +56 -0
- package/dist/db/ppr.js +178 -0
- package/dist/db/query-helpers.d.ts +44 -0
- package/dist/db/query-helpers.js +60 -0
- package/dist/db/raw-doc-artifact-sync.d.ts +128 -0
- package/dist/db/raw-doc-artifact-sync.js +259 -0
- package/dist/db/raw-document-blob-repository.d.ts +148 -0
- package/dist/db/raw-document-blob-repository.js +300 -0
- package/dist/db/raw-document-repository.d.ts +104 -0
- package/dist/db/raw-document-repository.js +410 -0
- package/dist/db/raw-document-status-repository.d.ts +122 -0
- package/dist/db/raw-document-status-repository.js +183 -0
- package/dist/db/raw-document-types.d.ts +236 -0
- package/dist/db/raw-document-types.js +10 -0
- package/dist/db/raw-storage-reconciliation-repository.d.ts +110 -0
- package/dist/db/raw-storage-reconciliation-repository.js +200 -0
- package/dist/db/reflection-jobs-repository.d.ts +33 -0
- package/dist/db/reflection-jobs-repository.js +48 -0
- package/dist/db/reflections-repository.d.ts +41 -0
- package/dist/db/reflections-repository.js +83 -0
- package/dist/db/repository-claims.d.ts +141 -0
- package/dist/db/repository-claims.js +376 -0
- package/dist/db/repository-deferred-audn.d.ts +33 -0
- package/dist/db/repository-deferred-audn.js +69 -0
- package/dist/db/repository-document-delete.d.ts +53 -0
- package/dist/db/repository-document-delete.js +156 -0
- package/dist/db/repository-entities.d.ts +114 -0
- package/dist/db/repository-entities.js +317 -0
- package/dist/db/repository-entity-attributes.d.ts +41 -0
- package/dist/db/repository-entity-attributes.js +65 -0
- package/dist/db/repository-entity-graph.d.ts +32 -0
- package/dist/db/repository-entity-graph.js +87 -0
- package/dist/db/repository-first-mentions.d.ts +41 -0
- package/dist/db/repository-first-mentions.js +79 -0
- package/dist/db/repository-lessons.d.ts +51 -0
- package/dist/db/repository-lessons.js +90 -0
- package/dist/db/repository-links.d.ts +26 -0
- package/dist/db/repository-links.js +105 -0
- package/dist/db/repository-observation.d.ts +26 -0
- package/dist/db/repository-observation.js +51 -0
- package/dist/db/repository-read.d.ts +56 -0
- package/dist/db/repository-read.js +271 -0
- package/dist/db/repository-recaps.d.ts +59 -0
- package/dist/db/repository-recaps.js +158 -0
- package/dist/db/repository-representations.d.ts +48 -0
- package/dist/db/repository-representations.js +162 -0
- package/dist/db/repository-temporal-state.d.ts +35 -0
- package/dist/db/repository-temporal-state.js +46 -0
- package/dist/db/repository-tll.d.ts +88 -0
- package/dist/db/repository-tll.js +179 -0
- package/dist/db/repository-types.d.ts +313 -0
- package/dist/db/repository-types.js +142 -0
- package/dist/db/repository-user-profiles.d.ts +17 -0
- package/dist/db/repository-user-profiles.js +28 -0
- package/dist/db/repository-vector-search.d.ts +33 -0
- package/dist/db/repository-vector-search.js +373 -0
- package/dist/db/repository-wipe.d.ts +34 -0
- package/dist/db/repository-wipe.js +94 -0
- package/dist/db/repository-write.d.ts +61 -0
- package/dist/db/repository-write.js +279 -0
- package/dist/db/schema.sql +1355 -0
- package/dist/db/storage-artifact-delete-tx.d.ts +56 -0
- package/dist/db/storage-artifact-delete-tx.js +123 -0
- package/dist/db/storage-artifact-providers.d.ts +21 -0
- package/dist/db/storage-artifact-providers.js +21 -0
- package/dist/db/storage-artifact-recovery-repository.d.ts +66 -0
- package/dist/db/storage-artifact-recovery-repository.js +58 -0
- package/dist/db/storage-artifact-repository.d.ts +329 -0
- package/dist/db/storage-artifact-repository.js +497 -0
- package/dist/db/stores.d.ts +220 -0
- package/dist/db/stores.js +12 -0
- package/dist/db/summaries-repository.d.ts +74 -0
- package/dist/db/summaries-repository.js +125 -0
- package/dist/eval/beam-10m-loader.d.ts +98 -0
- package/dist/eval/beam-10m-loader.js +128 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +17 -0
- package/dist/middleware/require-bearer.d.ts +27 -0
- package/dist/middleware/require-bearer.js +60 -0
- package/dist/middleware/validate-response.d.ts +33 -0
- package/dist/middleware/validate-response.js +55 -0
- package/dist/middleware/validate.d.ts +43 -0
- package/dist/middleware/validate.js +85 -0
- package/dist/routes/agents.d.ts +13 -0
- package/dist/routes/agents.js +89 -0
- package/dist/routes/document-response-formatters.d.ts +98 -0
- package/dist/routes/document-response-formatters.js +243 -0
- package/dist/routes/documents.d.ts +74 -0
- package/dist/routes/documents.js +425 -0
- package/dist/routes/memories.d.ts +29 -0
- package/dist/routes/memories.js +725 -0
- package/dist/routes/memory-response-formatters.d.ts +179 -0
- package/dist/routes/memory-response-formatters.js +210 -0
- package/dist/routes/public-raw-storage-metadata.d.ts +54 -0
- package/dist/routes/public-raw-storage-metadata.js +56 -0
- package/dist/routes/reflect.d.ts +14 -0
- package/dist/routes/reflect.js +19 -0
- package/dist/routes/response-schema-map.d.ts +14 -0
- package/dist/routes/response-schema-map.js +69 -0
- package/dist/routes/route-errors.d.ts +12 -0
- package/dist/routes/route-errors.js +30 -0
- package/dist/routes/storage-error-handlers.d.ts +34 -0
- package/dist/routes/storage-error-handlers.js +185 -0
- package/dist/routes/storage-response-formatters.d.ts +44 -0
- package/dist/routes/storage-response-formatters.js +155 -0
- package/dist/routes/storage.d.ts +38 -0
- package/dist/routes/storage.js +369 -0
- package/dist/routes/upstream-provider-errors.d.ts +19 -0
- package/dist/routes/upstream-provider-errors.js +95 -0
- package/dist/schemas/agents.d.ts +79 -0
- package/dist/schemas/agents.js +126 -0
- package/dist/schemas/common.d.ts +110 -0
- package/dist/schemas/common.js +190 -0
- package/dist/schemas/document-list-responses.d.ts +102 -0
- package/dist/schemas/document-list-responses.js +87 -0
- package/dist/schemas/document-list-schemas.d.ts +123 -0
- package/dist/schemas/document-list-schemas.js +174 -0
- package/dist/schemas/document-response-schemas.d.ts +610 -0
- package/dist/schemas/document-response-schemas.js +264 -0
- package/dist/schemas/document-status-envelope.d.ts +48 -0
- package/dist/schemas/document-status-envelope.js +54 -0
- package/dist/schemas/documents.d.ts +292 -0
- package/dist/schemas/documents.js +449 -0
- package/dist/schemas/errors.d.ts +75 -0
- package/dist/schemas/errors.js +105 -0
- package/dist/schemas/memories.d.ts +378 -0
- package/dist/schemas/memories.js +542 -0
- package/dist/schemas/openapi.d.ts +24 -0
- package/dist/schemas/openapi.js +1038 -0
- package/dist/schemas/response-scalars.d.ts +10 -0
- package/dist/schemas/response-scalars.js +10 -0
- package/dist/schemas/responses.d.ts +536 -0
- package/dist/schemas/responses.js +350 -0
- package/dist/schemas/search-response-parts.d.ts +97 -0
- package/dist/schemas/search-response-parts.js +103 -0
- package/dist/schemas/storage-schemas.d.ts +175 -0
- package/dist/schemas/storage-schemas.js +277 -0
- package/dist/schemas/zod-setup.d.ts +15 -0
- package/dist/schemas/zod-setup.js +17 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +57 -0
- package/dist/services/abstract-query-policy.d.ts +13 -0
- package/dist/services/abstract-query-policy.js +50 -0
- package/dist/services/affinity-clustering.d.ts +66 -0
- package/dist/services/affinity-clustering.js +125 -0
- package/dist/services/agentic-retrieval.d.ts +38 -0
- package/dist/services/agentic-retrieval.js +126 -0
- package/dist/services/answer-format.d.ts +56 -0
- package/dist/services/answer-format.js +118 -0
- package/dist/services/answer-rescue.d.ts +72 -0
- package/dist/services/answer-rescue.js +177 -0
- package/dist/services/answer-verifier.d.ts +24 -0
- package/dist/services/answer-verifier.js +73 -0
- package/dist/services/api-retry.d.ts +6 -0
- package/dist/services/api-retry.js +41 -0
- package/dist/services/assistant-turn-filter.d.ts +20 -0
- package/dist/services/assistant-turn-filter.js +69 -0
- package/dist/services/atomicmem-uri.d.ts +33 -0
- package/dist/services/atomicmem-uri.js +86 -0
- package/dist/services/audit-events.d.ts +54 -0
- package/dist/services/audit-events.js +56 -0
- package/dist/services/chunked-extraction.d.ts +21 -0
- package/dist/services/chunked-extraction.js +108 -0
- package/dist/services/claim-slotting.d.ts +27 -0
- package/dist/services/claim-slotting.js +38 -0
- package/dist/services/claude-code-llm.d.ts +19 -0
- package/dist/services/claude-code-llm.js +96 -0
- package/dist/services/composite-dedup.d.ts +50 -0
- package/dist/services/composite-dedup.js +153 -0
- package/dist/services/composite-grouping.d.ts +41 -0
- package/dist/services/composite-grouping.js +111 -0
- package/dist/services/composite-staleness.d.ts +20 -0
- package/dist/services/composite-staleness.js +50 -0
- package/dist/services/conciseness-preference.d.ts +14 -0
- package/dist/services/conciseness-preference.js +42 -0
- package/dist/services/conflict-policy.d.ts +20 -0
- package/dist/services/conflict-policy.js +335 -0
- package/dist/services/consensus-extraction.d.ts +39 -0
- package/dist/services/consensus-extraction.js +147 -0
- package/dist/services/consensus-validation.d.ts +52 -0
- package/dist/services/consensus-validation.js +206 -0
- package/dist/services/consolidation-service.d.ts +60 -0
- package/dist/services/consolidation-service.js +171 -0
- package/dist/services/content-detection.d.ts +18 -0
- package/dist/services/content-detection.js +25 -0
- package/dist/services/contradiction-surfacing.d.ts +62 -0
- package/dist/services/contradiction-surfacing.js +111 -0
- package/dist/services/cost-telemetry.d.ts +39 -0
- package/dist/services/cost-telemetry.js +58 -0
- package/dist/services/counter-evidence.d.ts +34 -0
- package/dist/services/counter-evidence.js +92 -0
- package/dist/services/current-state-ranking.d.ts +21 -0
- package/dist/services/current-state-ranking.js +152 -0
- package/dist/services/deferred-audn.d.ts +47 -0
- package/dist/services/deferred-audn.js +162 -0
- package/dist/services/document-chunker.d.ts +50 -0
- package/dist/services/document-chunker.js +153 -0
- package/dist/services/document-failure-markers.d.ts +91 -0
- package/dist/services/document-failure-markers.js +305 -0
- package/dist/services/document-indexer.d.ts +122 -0
- package/dist/services/document-indexer.js +405 -0
- package/dist/services/document-service.d.ts +245 -0
- package/dist/services/document-service.js +325 -0
- package/dist/services/document-upload-artifact-sync.d.ts +80 -0
- package/dist/services/document-upload-artifact-sync.js +162 -0
- package/dist/services/document-upload-beta2-recovery.d.ts +72 -0
- package/dist/services/document-upload-beta2-recovery.js +94 -0
- package/dist/services/document-upload.d.ts +44 -0
- package/dist/services/document-upload.js +353 -0
- package/dist/services/embedding.d.ts +57 -0
- package/dist/services/embedding.js +416 -0
- package/dist/services/entity-attribute-extractor.d.ts +34 -0
- package/dist/services/entity-attribute-extractor.js +117 -0
- package/dist/services/entity-card-synthesis.d.ts +54 -0
- package/dist/services/entity-card-synthesis.js +92 -0
- package/dist/services/entity-dedup.d.ts +9 -0
- package/dist/services/entity-dedup.js +14 -0
- package/dist/services/entity-graph.d.ts +17 -0
- package/dist/services/entity-graph.js +135 -0
- package/dist/services/entropy-gate.d.ts +52 -0
- package/dist/services/entropy-gate.js +56 -0
- package/dist/services/episode-fetcher.d.ts +47 -0
- package/dist/services/episode-fetcher.js +128 -0
- package/dist/services/event-anchor-facts.d.ts +8 -0
- package/dist/services/event-anchor-facts.js +205 -0
- package/dist/services/event-chain-detector.d.ts +52 -0
- package/dist/services/event-chain-detector.js +83 -0
- package/dist/services/extraction-cache.d.ts +9 -0
- package/dist/services/extraction-cache.js +54 -0
- package/dist/services/extraction-enrichment.d.ts +9 -0
- package/dist/services/extraction-enrichment.js +223 -0
- package/dist/services/extraction.d.ts +69 -0
- package/dist/services/extraction.js +596 -0
- package/dist/services/fact-normalization.d.ts +12 -0
- package/dist/services/fact-normalization.js +248 -0
- package/dist/services/filecoin-observability.d.ts +127 -0
- package/dist/services/filecoin-observability.js +200 -0
- package/dist/services/first-mention-service.d.ts +76 -0
- package/dist/services/first-mention-service.js +186 -0
- package/dist/services/hierarchical-retrieval.d.ts +49 -0
- package/dist/services/hierarchical-retrieval.js +50 -0
- package/dist/services/ingest-fact-pipeline.d.ts +32 -0
- package/dist/services/ingest-fact-pipeline.js +212 -0
- package/dist/services/ingest-post-write.d.ts +50 -0
- package/dist/services/ingest-post-write.js +117 -0
- package/dist/services/ingest-trace.d.ts +32 -0
- package/dist/services/ingest-trace.js +60 -0
- package/dist/services/input-sanitizer.d.ts +41 -0
- package/dist/services/input-sanitizer.js +135 -0
- package/dist/services/iterative-retrieval.d.ts +26 -0
- package/dist/services/iterative-retrieval.js +139 -0
- package/dist/services/keyword-expansion.d.ts +10 -0
- package/dist/services/keyword-expansion.js +26 -0
- package/dist/services/lesson-service.d.ts +68 -0
- package/dist/services/lesson-service.js +178 -0
- package/dist/services/literal-extractor.d.ts +16 -0
- package/dist/services/literal-extractor.js +74 -0
- package/dist/services/literal-list-protection.d.ts +17 -0
- package/dist/services/literal-list-protection.js +134 -0
- package/dist/services/literal-query-expansion.d.ts +20 -0
- package/dist/services/literal-query-expansion.js +181 -0
- package/dist/services/llm.d.ts +61 -0
- package/dist/services/llm.js +265 -0
- package/dist/services/memcell-projection.d.ts +17 -0
- package/dist/services/memcell-projection.js +41 -0
- package/dist/services/memory-audn.d.ts +43 -0
- package/dist/services/memory-audn.js +419 -0
- package/dist/services/memory-crud.d.ts +93 -0
- package/dist/services/memory-crud.js +255 -0
- package/dist/services/memory-ingest.d.ts +21 -0
- package/dist/services/memory-ingest.js +249 -0
- package/dist/services/memory-lifecycle.d.ts +75 -0
- package/dist/services/memory-lifecycle.js +108 -0
- package/dist/services/memory-lineage.d.ts +181 -0
- package/dist/services/memory-lineage.js +232 -0
- package/dist/services/memory-network.d.ts +40 -0
- package/dist/services/memory-network.js +75 -0
- package/dist/services/memory-search-types.d.ts +25 -0
- package/dist/services/memory-search-types.js +10 -0
- package/dist/services/memory-search.d.ts +48 -0
- package/dist/services/memory-search.js +505 -0
- package/dist/services/memory-service-types.d.ts +371 -0
- package/dist/services/memory-service-types.js +8 -0
- package/dist/services/memory-service.d.ts +152 -0
- package/dist/services/memory-service.js +225 -0
- package/dist/services/memory-storage.d.ts +33 -0
- package/dist/services/memory-storage.js +328 -0
- package/dist/services/msr-aggregator.d.ts +38 -0
- package/dist/services/msr-aggregator.js +97 -0
- package/dist/services/msr-detector.d.ts +35 -0
- package/dist/services/msr-detector.js +65 -0
- package/dist/services/namespace-retrieval.d.ts +60 -0
- package/dist/services/namespace-retrieval.js +180 -0
- package/dist/services/observation-date-extraction.d.ts +12 -0
- package/dist/services/observation-date-extraction.js +50 -0
- package/dist/services/observation-service.d.ts +27 -0
- package/dist/services/observation-service.js +84 -0
- package/dist/services/packaging-observability.d.ts +29 -0
- package/dist/services/packaging-observability.js +146 -0
- package/dist/services/query-expansion.d.ts +83 -0
- package/dist/services/query-expansion.js +242 -0
- package/dist/services/query-keyword-matches.d.ts +6 -0
- package/dist/services/query-keyword-matches.js +56 -0
- package/dist/services/query-term-visibility.d.ts +28 -0
- package/dist/services/query-term-visibility.js +100 -0
- package/dist/services/quick-extraction.d.ts +25 -0
- package/dist/services/quick-extraction.js +431 -0
- package/dist/services/quoted-entity-extraction.d.ts +10 -0
- package/dist/services/quoted-entity-extraction.js +161 -0
- package/dist/services/raw-storage-reconciler-backoff.d.ts +8 -0
- package/dist/services/raw-storage-reconciler-backoff.js +14 -0
- package/dist/services/raw-storage-reconciler-scheduler.d.ts +29 -0
- package/dist/services/raw-storage-reconciler-scheduler.js +43 -0
- package/dist/services/raw-storage-reconciler.d.ts +71 -0
- package/dist/services/raw-storage-reconciler.js +278 -0
- package/dist/services/recap-builder.d.ts +49 -0
- package/dist/services/recap-builder.js +157 -0
- package/dist/services/reflect-jobs.d.ts +23 -0
- package/dist/services/reflect-jobs.js +36 -0
- package/dist/services/reflect-prompts.d.ts +71 -0
- package/dist/services/reflect-prompts.js +99 -0
- package/dist/services/reflect-retrieval.d.ts +33 -0
- package/dist/services/reflect-retrieval.js +30 -0
- package/dist/services/reflect.d.ts +49 -0
- package/dist/services/reflect.js +84 -0
- package/dist/services/relative-temporal.d.ts +14 -0
- package/dist/services/relative-temporal.js +163 -0
- package/dist/services/relevance-policy.d.ts +37 -0
- package/dist/services/relevance-policy.js +109 -0
- package/dist/services/rerank.d.ts +32 -0
- package/dist/services/rerank.js +118 -0
- package/dist/services/reranker.d.ts +20 -0
- package/dist/services/reranker.js +99 -0
- package/dist/services/retrieval-channel-rules.d.ts +34 -0
- package/dist/services/retrieval-channel-rules.js +41 -0
- package/dist/services/retrieval-config-overlay.d.ts +36 -0
- package/dist/services/retrieval-config-overlay.js +44 -0
- package/dist/services/retrieval-format.d.ts +119 -0
- package/dist/services/retrieval-format.js +559 -0
- package/dist/services/retrieval-policy.d.ts +69 -0
- package/dist/services/retrieval-policy.js +275 -0
- package/dist/services/retrieval-profiles.d.ts +37 -0
- package/dist/services/retrieval-profiles.js +90 -0
- package/dist/services/retrieval-side-effects.d.ts +14 -0
- package/dist/services/retrieval-side-effects.js +26 -0
- package/dist/services/retrieval-trace.d.ts +108 -0
- package/dist/services/retrieval-trace.js +147 -0
- package/dist/services/rrf-fusion.d.ts +18 -0
- package/dist/services/rrf-fusion.js +34 -0
- package/dist/services/search-pipeline.d.ts +71 -0
- package/dist/services/search-pipeline.js +788 -0
- package/dist/services/session-date.d.ts +20 -0
- package/dist/services/session-date.js +61 -0
- package/dist/services/session-packaging.d.ts +53 -0
- package/dist/services/session-packaging.js +182 -0
- package/dist/services/session-summary-generator.d.ts +53 -0
- package/dist/services/session-summary-generator.js +134 -0
- package/dist/services/specialists/cr-specialist.d.ts +52 -0
- package/dist/services/specialists/cr-specialist.js +121 -0
- package/dist/services/specialists/dispatch.d.ts +53 -0
- package/dist/services/specialists/dispatch.js +102 -0
- package/dist/services/specialists/ie-ku-specialist.d.ts +37 -0
- package/dist/services/specialists/ie-ku-specialist.js +63 -0
- package/dist/services/specialists/msr-specialist.d.ts +61 -0
- package/dist/services/specialists/msr-specialist.js +162 -0
- package/dist/services/specialists/tr-specialist.d.ts +37 -0
- package/dist/services/specialists/tr-specialist.js +146 -0
- package/dist/services/storage-key-prefix.d.ts +42 -0
- package/dist/services/storage-key-prefix.js +45 -0
- package/dist/services/storage-put-recovery.d.ts +71 -0
- package/dist/services/storage-put-recovery.js +269 -0
- package/dist/services/storage-service-errors.d.ts +124 -0
- package/dist/services/storage-service-errors.js +189 -0
- package/dist/services/storage-service.d.ts +176 -0
- package/dist/services/storage-service.js +423 -0
- package/dist/services/subject-aware-ranking.d.ts +19 -0
- package/dist/services/subject-aware-ranking.js +161 -0
- package/dist/services/supplemental-extraction.d.ts +7 -0
- package/dist/services/supplemental-extraction.js +116 -0
- package/dist/services/tbc-execution.d.ts +49 -0
- package/dist/services/tbc-execution.js +284 -0
- package/dist/services/temporal-classifier.d.ts +56 -0
- package/dist/services/temporal-classifier.js +94 -0
- package/dist/services/temporal-endpoint-evidence.d.ts +12 -0
- package/dist/services/temporal-endpoint-evidence.js +313 -0
- package/dist/services/temporal-fingerprint.d.ts +6 -0
- package/dist/services/temporal-fingerprint.js +12 -0
- package/dist/services/temporal-format.d.ts +9 -0
- package/dist/services/temporal-format.js +21 -0
- package/dist/services/temporal-intent.d.ts +39 -0
- package/dist/services/temporal-intent.js +78 -0
- package/dist/services/temporal-query-constraints.d.ts +16 -0
- package/dist/services/temporal-query-constraints.js +107 -0
- package/dist/services/temporal-query-expansion.d.ts +14 -0
- package/dist/services/temporal-query-expansion.js +131 -0
- package/dist/services/temporal-rerank.d.ts +22 -0
- package/dist/services/temporal-rerank.js +47 -0
- package/dist/services/temporal-result-protection.d.ts +7 -0
- package/dist/services/temporal-result-protection.js +60 -0
- package/dist/services/temporal-state-write.d.ts +57 -0
- package/dist/services/temporal-state-write.js +45 -0
- package/dist/services/tiered-context.d.ts +87 -0
- package/dist/services/tiered-context.js +214 -0
- package/dist/services/tiered-loading.d.ts +88 -0
- package/dist/services/tiered-loading.js +263 -0
- package/dist/services/timeline-pack.d.ts +36 -0
- package/dist/services/timeline-pack.js +50 -0
- package/dist/services/timing.d.ts +13 -0
- package/dist/services/timing.js +72 -0
- package/dist/services/tll-augmentation.d.ts +20 -0
- package/dist/services/tll-augmentation.js +125 -0
- package/dist/services/tll-retrieval.d.ts +55 -0
- package/dist/services/tll-retrieval.js +101 -0
- package/dist/services/topic-abstraction.d.ts +36 -0
- package/dist/services/topic-abstraction.js +105 -0
- package/dist/services/trust-scoring.d.ts +43 -0
- package/dist/services/trust-scoring.js +89 -0
- package/dist/services/typed-belief-calculus.d.ts +126 -0
- package/dist/services/typed-belief-calculus.js +204 -0
- package/dist/services/upload-config.d.ts +34 -0
- package/dist/services/upload-config.js +23 -0
- package/dist/services/upload-decision.d.ts +65 -0
- package/dist/services/upload-decision.js +98 -0
- package/dist/services/upload-helpers.d.ts +107 -0
- package/dist/services/upload-helpers.js +148 -0
- package/dist/services/user-profile-builder.d.ts +22 -0
- package/dist/services/user-profile-builder.js +109 -0
- package/dist/services/voyage-embedding.d.ts +22 -0
- package/dist/services/voyage-embedding.js +77 -0
- package/dist/services/write-security.d.ts +31 -0
- package/dist/services/write-security.js +64 -0
- package/dist/storage/artifact-public-redaction.d.ts +34 -0
- package/dist/storage/artifact-public-redaction.js +83 -0
- package/dist/storage/cleanup.d.ts +103 -0
- package/dist/storage/cleanup.js +138 -0
- package/dist/storage/codec-factory.d.ts +17 -0
- package/dist/storage/codec-factory.js +33 -0
- package/dist/storage/codecs/aes-gcm-codec.d.ts +44 -0
- package/dist/storage/codecs/aes-gcm-codec.js +108 -0
- package/dist/storage/codecs/noop-codec.d.ts +16 -0
- package/dist/storage/codecs/noop-codec.js +23 -0
- package/dist/storage/factory.d.ts +44 -0
- package/dist/storage/factory.js +99 -0
- package/dist/storage/filecoin-cid-validation.d.ts +82 -0
- package/dist/storage/filecoin-cid-validation.js +122 -0
- package/dist/storage/filecoin-public-metadata.d.ts +73 -0
- package/dist/storage/filecoin-public-metadata.js +110 -0
- package/dist/storage/local-fs-store.d.ts +39 -0
- package/dist/storage/local-fs-store.js +145 -0
- package/dist/storage/pointer-uri-allowlist.d.ts +38 -0
- package/dist/storage/pointer-uri-allowlist.js +70 -0
- package/dist/storage/provider-metadata-projection.d.ts +27 -0
- package/dist/storage/provider-metadata-projection.js +68 -0
- package/dist/storage/providers/filecoin/backend.d.ts +42 -0
- package/dist/storage/providers/filecoin/backend.js +250 -0
- package/dist/storage/providers/filecoin/config.d.ts +70 -0
- package/dist/storage/providers/filecoin/config.js +275 -0
- package/dist/storage/providers/filecoin/errors.d.ts +45 -0
- package/dist/storage/providers/filecoin/errors.js +56 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.d.ts +78 -0
- package/dist/storage/providers/filecoin/filecoin-pin-car.js +155 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.d.ts +92 -0
- package/dist/storage/providers/filecoin/filecoin-pin-client.js +199 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.d.ts +58 -0
- package/dist/storage/providers/filecoin/filecoin-pin-mapping.js +103 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.d.ts +30 -0
- package/dist/storage/providers/filecoin/filecoin-pin-timeout.js +53 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.d.ts +111 -0
- package/dist/storage/providers/filecoin/filecoin-pin-vendor.js +87 -0
- package/dist/storage/providers/filecoin/hints.d.ts +71 -0
- package/dist/storage/providers/filecoin/hints.js +123 -0
- package/dist/storage/providers/filecoin/index.d.ts +51 -0
- package/dist/storage/providers/filecoin/index.js +103 -0
- package/dist/storage/providers/filecoin/ipfs-cid.d.ts +50 -0
- package/dist/storage/providers/filecoin/ipfs-cid.js +64 -0
- package/dist/storage/providers/filecoin/metadata.d.ts +72 -0
- package/dist/storage/providers/filecoin/metadata.js +137 -0
- package/dist/storage/providers/filecoin/piece-cid.d.ts +48 -0
- package/dist/storage/providers/filecoin/piece-cid.js +57 -0
- package/dist/storage/providers/filecoin/provider-client.d.ts +234 -0
- package/dist/storage/providers/filecoin/provider-client.js +27 -0
- package/dist/storage/providers/filecoin/readiness.d.ts +62 -0
- package/dist/storage/providers/filecoin/readiness.js +85 -0
- package/dist/storage/providers/filecoin/retriever.d.ts +82 -0
- package/dist/storage/providers/filecoin/retriever.js +63 -0
- package/dist/storage/providers/filecoin/skeleton-client.d.ts +36 -0
- package/dist/storage/providers/filecoin/skeleton-client.js +55 -0
- package/dist/storage/providers/filecoin/synapse-client.d.ts +169 -0
- package/dist/storage/providers/filecoin/synapse-client.js +343 -0
- package/dist/storage/providers/filecoin/synapse-construction.d.ts +26 -0
- package/dist/storage/providers/filecoin/synapse-construction.js +47 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.d.ts +23 -0
- package/dist/storage/providers/filecoin/synapse-error-mapping.js +49 -0
- package/dist/storage/providers/filecoin/synapse-readiness.d.ts +37 -0
- package/dist/storage/providers/filecoin/synapse-readiness.js +231 -0
- package/dist/storage/providers/filecoin/uri.d.ts +49 -0
- package/dist/storage/providers/filecoin/uri.js +84 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.d.ts +77 -0
- package/dist/storage/providers/filecoin/verified-fetch-lifecycle.js +196 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.d.ts +54 -0
- package/dist/storage/providers/filecoin/verified-fetch-retriever.js +81 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.d.ts +71 -0
- package/dist/storage/providers/filecoin/verified-fetch-vendor.js +94 -0
- package/dist/storage/raw-content-codec.d.ts +89 -0
- package/dist/storage/raw-content-codec.js +47 -0
- package/dist/storage/raw-content-store-backend-adapter.d.ts +28 -0
- package/dist/storage/raw-content-store-backend-adapter.js +67 -0
- package/dist/storage/raw-content-store.d.ts +228 -0
- package/dist/storage/raw-content-store.js +27 -0
- package/dist/storage/s3-store.d.ts +42 -0
- package/dist/storage/s3-store.js +181 -0
- package/dist/storage/storage-backend-registry.d.ts +58 -0
- package/dist/storage/storage-backend-registry.js +56 -0
- package/dist/storage/storage-backend.d.ts +82 -0
- package/dist/storage/storage-backend.js +14 -0
- package/dist/storage/storage-capabilities.d.ts +56 -0
- package/dist/storage/storage-capabilities.js +170 -0
- package/dist/storage/store-registry.d.ts +67 -0
- package/dist/storage/store-registry.js +77 -0
- package/dist/vector-math.d.ts +15 -0
- package/dist/vector-math.js +31 -0
- package/dist/xml-escape.d.ts +5 -0
- package/dist/xml-escape.js +7 -0
- package/openapi.json +15395 -0
- package/openapi.yaml +10794 -0
- package/package.json +119 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Shared Filecoin / IPFS CID structural-SHAPE gates for the
|
|
3
|
+
* public-projection seam.
|
|
4
|
+
*
|
|
5
|
+
* These are NOT codec-aware validators. They are
|
|
6
|
+
* regex-on-multibase-prefix gates whose only job is to silently
|
|
7
|
+
* drop adversarial / legacy / manually-planted JSONB column
|
|
8
|
+
* values before they cross the public projection wire boundary.
|
|
9
|
+
* True PieceCIDv2 validation — CIDv1, raw codec (0x55),
|
|
10
|
+
* multihash code 0x1011 — lives at the provider boundary in
|
|
11
|
+
* `providers/filecoin/piece-cid.ts`, which wraps the live Synapse
|
|
12
|
+
* SDK parser (`@filoz/synapse-core/piece.asPieceCID`). Write-path
|
|
13
|
+
* inputs that fail the SDK parser are rejected before they ever
|
|
14
|
+
* reach `storage_artifacts.uri` or
|
|
15
|
+
* `raw_storage_metadata.filecoin.piece_cid`, so by induction any
|
|
16
|
+
* value the public projector sees in a recent row already
|
|
17
|
+
* round-trips through the SDK.
|
|
18
|
+
*
|
|
19
|
+
* Why a separate shape gate exists:
|
|
20
|
+
*
|
|
21
|
+
* - The public projector (`filecoin-public-metadata.ts`) is on
|
|
22
|
+
* the EAGER import path. Importing `@filoz/synapse-core` from
|
|
23
|
+
* it would defeat the Phase 2 lazy-loading invariant that
|
|
24
|
+
* keeps the Synapse SDK out of non-Filecoin-provider
|
|
25
|
+
* startups.
|
|
26
|
+
*
|
|
27
|
+
* - Legacy rows from before Phase 3, direct DB writes by
|
|
28
|
+
* operators, and adversarial test planting can still place
|
|
29
|
+
* non-parseable strings in `raw_storage_metadata`. The shape
|
|
30
|
+
* gate is a belt-and-suspenders silent drop so such values
|
|
31
|
+
* never make it onto the wire.
|
|
32
|
+
*
|
|
33
|
+
* Predicates:
|
|
34
|
+
*
|
|
35
|
+
* - `isPieceCidShape(value)` — accepts strings whose multibase
|
|
36
|
+
* prefix is a known PieceCID encoding (legacy `baga…` or
|
|
37
|
+
* modern PieceCIDv2 `bafkzci…`) followed by enough base32-lower
|
|
38
|
+
* characters to plausibly carry a digest. Does NOT decode
|
|
39
|
+
* the bytes or verify the codec/multihash.
|
|
40
|
+
*
|
|
41
|
+
* - `isIpfsCidShape(value)` — broader CIDv1 base32-lower shape;
|
|
42
|
+
* reserved for the Phase 4 `ipfs_cid` / CAR-root field. No
|
|
43
|
+
* production caller emits the field yet.
|
|
44
|
+
*
|
|
45
|
+
* The functions are named `isPieceCid` / `isIpfsCid` (historical
|
|
46
|
+
* names retained to avoid churn at call sites) but the file
|
|
47
|
+
* header is the source of truth on what they actually do —
|
|
48
|
+
* "structural shape only, no codec validation."
|
|
49
|
+
*
|
|
50
|
+
* Layering rule: this module sits at the shared-storage layer
|
|
51
|
+
* and has ZERO dependencies on `providers/filecoin/*` or any
|
|
52
|
+
* Filecoin vendor package. The boundary test
|
|
53
|
+
* (`import-boundary-helpers.ts:SHARED_STORAGE_ALLOWLIST`)
|
|
54
|
+
* explicitly permits provider files to import it via
|
|
55
|
+
* `../../filecoin-cid-validation.js` — that allowance now exists
|
|
56
|
+
* only for the public projector's `import { isPieceCid }` (the
|
|
57
|
+
* provider boundary uses the SDK parser instead).
|
|
58
|
+
*
|
|
59
|
+
* Errors: this file does NOT throw — predicates return booleans.
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* Returns `true` if `value` has the surface shape of a PieceCID
|
|
63
|
+
* string (legacy `baga…` or modern PieceCIDv2 `bafkzci…`
|
|
64
|
+
* multibase prefix + sufficient base32-lower length). Does NOT
|
|
65
|
+
* decode the multihash bytes, verify the codec, or confirm the
|
|
66
|
+
* value parses through the Synapse SDK — see this file's
|
|
67
|
+
* header for why the codec-aware check lives at the provider
|
|
68
|
+
* boundary instead.
|
|
69
|
+
*
|
|
70
|
+
* Used at the public-projection seam (`filecoin-public-metadata`)
|
|
71
|
+
* to silently drop adversarial / legacy / manually-planted
|
|
72
|
+
* column values before the wire.
|
|
73
|
+
*/
|
|
74
|
+
export declare function isPieceCid(value: unknown): value is string;
|
|
75
|
+
/**
|
|
76
|
+
* Returns `true` if `value` has the surface shape of a CIDv1
|
|
77
|
+
* base32-lower string (any multicodec). Reserved for the
|
|
78
|
+
* `ipfs_cid` / CAR-root identity Phase 4 will plumb through; no
|
|
79
|
+
* production caller emits the field yet. Same shape-only
|
|
80
|
+
* semantics as {@link isPieceCid}.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isIpfsCid(value: unknown): value is string;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Shared Filecoin / IPFS CID structural-SHAPE gates for the
|
|
3
|
+
* public-projection seam.
|
|
4
|
+
*
|
|
5
|
+
* These are NOT codec-aware validators. They are
|
|
6
|
+
* regex-on-multibase-prefix gates whose only job is to silently
|
|
7
|
+
* drop adversarial / legacy / manually-planted JSONB column
|
|
8
|
+
* values before they cross the public projection wire boundary.
|
|
9
|
+
* True PieceCIDv2 validation — CIDv1, raw codec (0x55),
|
|
10
|
+
* multihash code 0x1011 — lives at the provider boundary in
|
|
11
|
+
* `providers/filecoin/piece-cid.ts`, which wraps the live Synapse
|
|
12
|
+
* SDK parser (`@filoz/synapse-core/piece.asPieceCID`). Write-path
|
|
13
|
+
* inputs that fail the SDK parser are rejected before they ever
|
|
14
|
+
* reach `storage_artifacts.uri` or
|
|
15
|
+
* `raw_storage_metadata.filecoin.piece_cid`, so by induction any
|
|
16
|
+
* value the public projector sees in a recent row already
|
|
17
|
+
* round-trips through the SDK.
|
|
18
|
+
*
|
|
19
|
+
* Why a separate shape gate exists:
|
|
20
|
+
*
|
|
21
|
+
* - The public projector (`filecoin-public-metadata.ts`) is on
|
|
22
|
+
* the EAGER import path. Importing `@filoz/synapse-core` from
|
|
23
|
+
* it would defeat the Phase 2 lazy-loading invariant that
|
|
24
|
+
* keeps the Synapse SDK out of non-Filecoin-provider
|
|
25
|
+
* startups.
|
|
26
|
+
*
|
|
27
|
+
* - Legacy rows from before Phase 3, direct DB writes by
|
|
28
|
+
* operators, and adversarial test planting can still place
|
|
29
|
+
* non-parseable strings in `raw_storage_metadata`. The shape
|
|
30
|
+
* gate is a belt-and-suspenders silent drop so such values
|
|
31
|
+
* never make it onto the wire.
|
|
32
|
+
*
|
|
33
|
+
* Predicates:
|
|
34
|
+
*
|
|
35
|
+
* - `isPieceCidShape(value)` — accepts strings whose multibase
|
|
36
|
+
* prefix is a known PieceCID encoding (legacy `baga…` or
|
|
37
|
+
* modern PieceCIDv2 `bafkzci…`) followed by enough base32-lower
|
|
38
|
+
* characters to plausibly carry a digest. Does NOT decode
|
|
39
|
+
* the bytes or verify the codec/multihash.
|
|
40
|
+
*
|
|
41
|
+
* - `isIpfsCidShape(value)` — broader CIDv1 base32-lower shape;
|
|
42
|
+
* reserved for the Phase 4 `ipfs_cid` / CAR-root field. No
|
|
43
|
+
* production caller emits the field yet.
|
|
44
|
+
*
|
|
45
|
+
* The functions are named `isPieceCid` / `isIpfsCid` (historical
|
|
46
|
+
* names retained to avoid churn at call sites) but the file
|
|
47
|
+
* header is the source of truth on what they actually do —
|
|
48
|
+
* "structural shape only, no codec validation."
|
|
49
|
+
*
|
|
50
|
+
* Layering rule: this module sits at the shared-storage layer
|
|
51
|
+
* and has ZERO dependencies on `providers/filecoin/*` or any
|
|
52
|
+
* Filecoin vendor package. The boundary test
|
|
53
|
+
* (`import-boundary-helpers.ts:SHARED_STORAGE_ALLOWLIST`)
|
|
54
|
+
* explicitly permits provider files to import it via
|
|
55
|
+
* `../../filecoin-cid-validation.js` — that allowance now exists
|
|
56
|
+
* only for the public projector's `import { isPieceCid }` (the
|
|
57
|
+
* provider boundary uses the SDK parser instead).
|
|
58
|
+
*
|
|
59
|
+
* Errors: this file does NOT throw — predicates return booleans.
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* PieceCID structural shape: CIDv1 base32-lower. Two canonical
|
|
63
|
+
* multicodec encodings are accepted:
|
|
64
|
+
*
|
|
65
|
+
* - **Legacy `baga…`** — multicodec `fil-commitment-unsealed`
|
|
66
|
+
* (0xf101) + sha2-256. Historical Filecoin storage identity;
|
|
67
|
+
* ~59–62 chars overall.
|
|
68
|
+
*
|
|
69
|
+
* - **Modern `bafkzci…`** — CIDv1 raw codec (0x55) + multihash
|
|
70
|
+
* code 0x1011 (`fr32-sha2-256-trunc254-padded-binary-tree`,
|
|
71
|
+
* from `@web3-storage/data-segment`). This is the PieceCIDv2
|
|
72
|
+
* shape the live Synapse SDK emits today
|
|
73
|
+
* (`@filoz/synapse-core` `isPieceCID`). ~63–66 chars overall.
|
|
74
|
+
*
|
|
75
|
+
* The regex requires the `(baga|bafkzci)` prefix and at least 50
|
|
76
|
+
* additional base32-lower characters, rejecting obvious sentinels
|
|
77
|
+
* (`baga-test`, `bafkzci-x`) while leaving room for digest-length
|
|
78
|
+
* variants within either codec family. Codec semantics (CID
|
|
79
|
+
* version, codec byte, multihash code) are NOT decoded here — the
|
|
80
|
+
* SDK enforces them on its side. This validator's job is to gate
|
|
81
|
+
* adversarial JSONB / placeholders / wire-format garbage before
|
|
82
|
+
* the value reaches the URI parser, the sidecar persister, or the
|
|
83
|
+
* public projector.
|
|
84
|
+
*
|
|
85
|
+
* Charset is base32 lowercase per multibase `b`: `[a-z2-7]`.
|
|
86
|
+
*/
|
|
87
|
+
const PIECE_CID_RE = /^(baga|bafkzci)[a-z2-7]{50,}$/;
|
|
88
|
+
/**
|
|
89
|
+
* Generic CIDv1 base32-lower shape. Multibase prefix `b` followed
|
|
90
|
+
* by 55+ base32-lower characters (typical CIDv1 base32 length is
|
|
91
|
+
* 59 chars; floor at 55 to accommodate variant multihashes).
|
|
92
|
+
* Accepts both IPFS-style `bafy...` / `bafk...` and PieceCID-style
|
|
93
|
+
* `baga...`. Phase 4 / filecoin-pin uses this for the `ipfs_cid`
|
|
94
|
+
* / CAR-root metadata field.
|
|
95
|
+
*/
|
|
96
|
+
const IPFS_CID_RE = /^b[a-z2-7]{55,}$/;
|
|
97
|
+
/**
|
|
98
|
+
* Returns `true` if `value` has the surface shape of a PieceCID
|
|
99
|
+
* string (legacy `baga…` or modern PieceCIDv2 `bafkzci…`
|
|
100
|
+
* multibase prefix + sufficient base32-lower length). Does NOT
|
|
101
|
+
* decode the multihash bytes, verify the codec, or confirm the
|
|
102
|
+
* value parses through the Synapse SDK — see this file's
|
|
103
|
+
* header for why the codec-aware check lives at the provider
|
|
104
|
+
* boundary instead.
|
|
105
|
+
*
|
|
106
|
+
* Used at the public-projection seam (`filecoin-public-metadata`)
|
|
107
|
+
* to silently drop adversarial / legacy / manually-planted
|
|
108
|
+
* column values before the wire.
|
|
109
|
+
*/
|
|
110
|
+
export function isPieceCid(value) {
|
|
111
|
+
return typeof value === 'string' && PIECE_CID_RE.test(value);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Returns `true` if `value` has the surface shape of a CIDv1
|
|
115
|
+
* base32-lower string (any multicodec). Reserved for the
|
|
116
|
+
* `ipfs_cid` / CAR-root identity Phase 4 will plumb through; no
|
|
117
|
+
* production caller emits the field yet. Same shape-only
|
|
118
|
+
* semantics as {@link isPieceCid}.
|
|
119
|
+
*/
|
|
120
|
+
export function isIpfsCid(value) {
|
|
121
|
+
return typeof value === 'string' && IPFS_CID_RE.test(value);
|
|
122
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Provider-neutral public projection of the Filecoin
|
|
3
|
+
* `raw_documents.raw_storage_metadata.filecoin` sidecar.
|
|
4
|
+
*
|
|
5
|
+
* Routes, document services, and SDK packages MUST import the
|
|
6
|
+
* public projector from this module — NOT from
|
|
7
|
+
* `src/storage/providers/filecoin/`. The provider directory is the
|
|
8
|
+
* implementation seam (upload allowlist, denylist, provider-client
|
|
9
|
+
* wiring); leaking it through route imports would couple the route
|
|
10
|
+
* layer to the eventual provider package boundary.
|
|
11
|
+
*
|
|
12
|
+
* Mirror rule: the upload-side allowlist + denylist in
|
|
13
|
+
* `providers/filecoin/metadata.ts` is the SOURCE of truth for what
|
|
14
|
+
* fields the upload implementation may stamp on outgoing uploads;
|
|
15
|
+
* this module is the SOURCE of truth for what survives onto the
|
|
16
|
+
* wire when reading those rows back. The two contracts overlap by
|
|
17
|
+
* design (CIDs + copy state) but live in different files so the
|
|
18
|
+
* route layer never has to learn the provider package shape.
|
|
19
|
+
*
|
|
20
|
+
* Synapse public shape:
|
|
21
|
+
*
|
|
22
|
+
* {
|
|
23
|
+
* ipfs_cid?: string,
|
|
24
|
+
* piece_cid?: string,
|
|
25
|
+
* copy_count?: number,
|
|
26
|
+
* provider_ids?: string[],
|
|
27
|
+
* copy_statuses?: string[],
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* Phase 4 renamed the legacy ambiguous `cid` slot to `ipfs_cid`
|
|
31
|
+
* — see harvest plan §Phase 4. The slot is optional and only
|
|
32
|
+
* populated by drivers that emit an IPFS / CAR-root identity
|
|
33
|
+
* alongside the PieceCID (today: none; planned: filecoin-pin).
|
|
34
|
+
* The canonical storage URI stays `filecoin://piece/<pieceCid>`
|
|
35
|
+
* regardless of whether `ipfs_cid` is present — IPFS CID is a
|
|
36
|
+
* resolution-hint field, not a row-identity field.
|
|
37
|
+
*
|
|
38
|
+
* The internal `copies: [{ provider_id, status }]` shape is
|
|
39
|
+
* flattened by `projectFilecoinPublicMetadata`; legacy onramp keys
|
|
40
|
+
* (`onramp`, `gateway_url`, `deal_ids`, `onramp_status`, etc.) are
|
|
41
|
+
* NOT emitted by this projector.
|
|
42
|
+
*/
|
|
43
|
+
export interface FilecoinPublicMetadata {
|
|
44
|
+
readonly ipfs_cid?: string;
|
|
45
|
+
readonly piece_cid?: string;
|
|
46
|
+
readonly copy_count?: number;
|
|
47
|
+
readonly provider_ids?: ReadonlyArray<string>;
|
|
48
|
+
readonly copy_statuses?: ReadonlyArray<string>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Reduce the internal Filecoin sidecar to a wire-safe public
|
|
52
|
+
* projection. Returns an empty object when the input is malformed
|
|
53
|
+
* or the projection has no recognised content; callers can drop
|
|
54
|
+
* the empty object from the wire response.
|
|
55
|
+
*
|
|
56
|
+
* Phase 3 hardening: `piece_cid` is gated by the shared codec-
|
|
57
|
+
* blind shape predicate (`isPieceCid` in
|
|
58
|
+
* `./filecoin-cid-validation.ts`) before crossing the public
|
|
59
|
+
* boundary — adversarial / legacy / manually-planted JSONB values
|
|
60
|
+
* that don't match the structural shape are silently dropped
|
|
61
|
+
* rather than echoed onto the wire. The shape gate is a belt-and-
|
|
62
|
+
* suspenders defence; on the WRITE path the provider boundary
|
|
63
|
+
* already rejected anything that doesn't round-trip through the
|
|
64
|
+
* Synapse SDK parser, so for rows written via the normal pipeline
|
|
65
|
+
* this gate is a no-op. The `ipfs_cid` slot uses the broader
|
|
66
|
+
* CIDv1 base32 shape predicate (`isIpfsCid`) — real codec-aware
|
|
67
|
+
* parsing happens on the WRITE path inside
|
|
68
|
+
* `providers/filecoin/ipfs-cid.ts` via `multiformats/cid`. The
|
|
69
|
+
* projector intentionally stays eager-import-safe and vendor-light
|
|
70
|
+
* here, defeating any attempt to leak adversarial JSONB onto the
|
|
71
|
+
* wire even on legacy rows the SDK parser never gated.
|
|
72
|
+
*/
|
|
73
|
+
export declare function projectFilecoinPublicMetadata(internal: unknown): FilecoinPublicMetadata;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Provider-neutral public projection of the Filecoin
|
|
3
|
+
* `raw_documents.raw_storage_metadata.filecoin` sidecar.
|
|
4
|
+
*
|
|
5
|
+
* Routes, document services, and SDK packages MUST import the
|
|
6
|
+
* public projector from this module — NOT from
|
|
7
|
+
* `src/storage/providers/filecoin/`. The provider directory is the
|
|
8
|
+
* implementation seam (upload allowlist, denylist, provider-client
|
|
9
|
+
* wiring); leaking it through route imports would couple the route
|
|
10
|
+
* layer to the eventual provider package boundary.
|
|
11
|
+
*
|
|
12
|
+
* Mirror rule: the upload-side allowlist + denylist in
|
|
13
|
+
* `providers/filecoin/metadata.ts` is the SOURCE of truth for what
|
|
14
|
+
* fields the upload implementation may stamp on outgoing uploads;
|
|
15
|
+
* this module is the SOURCE of truth for what survives onto the
|
|
16
|
+
* wire when reading those rows back. The two contracts overlap by
|
|
17
|
+
* design (CIDs + copy state) but live in different files so the
|
|
18
|
+
* route layer never has to learn the provider package shape.
|
|
19
|
+
*
|
|
20
|
+
* Synapse public shape:
|
|
21
|
+
*
|
|
22
|
+
* {
|
|
23
|
+
* ipfs_cid?: string,
|
|
24
|
+
* piece_cid?: string,
|
|
25
|
+
* copy_count?: number,
|
|
26
|
+
* provider_ids?: string[],
|
|
27
|
+
* copy_statuses?: string[],
|
|
28
|
+
* }
|
|
29
|
+
*
|
|
30
|
+
* Phase 4 renamed the legacy ambiguous `cid` slot to `ipfs_cid`
|
|
31
|
+
* — see harvest plan §Phase 4. The slot is optional and only
|
|
32
|
+
* populated by drivers that emit an IPFS / CAR-root identity
|
|
33
|
+
* alongside the PieceCID (today: none; planned: filecoin-pin).
|
|
34
|
+
* The canonical storage URI stays `filecoin://piece/<pieceCid>`
|
|
35
|
+
* regardless of whether `ipfs_cid` is present — IPFS CID is a
|
|
36
|
+
* resolution-hint field, not a row-identity field.
|
|
37
|
+
*
|
|
38
|
+
* The internal `copies: [{ provider_id, status }]` shape is
|
|
39
|
+
* flattened by `projectFilecoinPublicMetadata`; legacy onramp keys
|
|
40
|
+
* (`onramp`, `gateway_url`, `deal_ids`, `onramp_status`, etc.) are
|
|
41
|
+
* NOT emitted by this projector.
|
|
42
|
+
*/
|
|
43
|
+
import { isIpfsCid, isPieceCid } from './filecoin-cid-validation.js';
|
|
44
|
+
/**
|
|
45
|
+
* Reduce the internal Filecoin sidecar to a wire-safe public
|
|
46
|
+
* projection. Returns an empty object when the input is malformed
|
|
47
|
+
* or the projection has no recognised content; callers can drop
|
|
48
|
+
* the empty object from the wire response.
|
|
49
|
+
*
|
|
50
|
+
* Phase 3 hardening: `piece_cid` is gated by the shared codec-
|
|
51
|
+
* blind shape predicate (`isPieceCid` in
|
|
52
|
+
* `./filecoin-cid-validation.ts`) before crossing the public
|
|
53
|
+
* boundary — adversarial / legacy / manually-planted JSONB values
|
|
54
|
+
* that don't match the structural shape are silently dropped
|
|
55
|
+
* rather than echoed onto the wire. The shape gate is a belt-and-
|
|
56
|
+
* suspenders defence; on the WRITE path the provider boundary
|
|
57
|
+
* already rejected anything that doesn't round-trip through the
|
|
58
|
+
* Synapse SDK parser, so for rows written via the normal pipeline
|
|
59
|
+
* this gate is a no-op. The `ipfs_cid` slot uses the broader
|
|
60
|
+
* CIDv1 base32 shape predicate (`isIpfsCid`) — real codec-aware
|
|
61
|
+
* parsing happens on the WRITE path inside
|
|
62
|
+
* `providers/filecoin/ipfs-cid.ts` via `multiformats/cid`. The
|
|
63
|
+
* projector intentionally stays eager-import-safe and vendor-light
|
|
64
|
+
* here, defeating any attempt to leak adversarial JSONB onto the
|
|
65
|
+
* wire even on legacy rows the SDK parser never gated.
|
|
66
|
+
*/
|
|
67
|
+
export function projectFilecoinPublicMetadata(internal) {
|
|
68
|
+
if (!isRecord(internal))
|
|
69
|
+
return {};
|
|
70
|
+
const out = {};
|
|
71
|
+
if (isIpfsCid(internal['ipfs_cid'])) {
|
|
72
|
+
out.ipfs_cid = internal['ipfs_cid'];
|
|
73
|
+
}
|
|
74
|
+
if (isPieceCid(internal['piece_cid'])) {
|
|
75
|
+
out.piece_cid = internal['piece_cid'];
|
|
76
|
+
}
|
|
77
|
+
const copiesProjection = projectCopies(internal['copies']);
|
|
78
|
+
if (copiesProjection !== null) {
|
|
79
|
+
out.copy_count = copiesProjection.copy_count;
|
|
80
|
+
if (copiesProjection.provider_ids.length > 0) {
|
|
81
|
+
out.provider_ids = copiesProjection.provider_ids;
|
|
82
|
+
}
|
|
83
|
+
if (copiesProjection.copy_statuses.length > 0) {
|
|
84
|
+
out.copy_statuses = copiesProjection.copy_statuses;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
89
|
+
function projectCopies(value) {
|
|
90
|
+
if (!Array.isArray(value))
|
|
91
|
+
return null;
|
|
92
|
+
const provider_ids = [];
|
|
93
|
+
const copy_statuses = [];
|
|
94
|
+
for (const entry of value) {
|
|
95
|
+
if (!isRecord(entry))
|
|
96
|
+
continue;
|
|
97
|
+
const providerId = entry['provider_id'];
|
|
98
|
+
if (typeof providerId === 'string' && providerId.length > 0) {
|
|
99
|
+
provider_ids.push(providerId);
|
|
100
|
+
}
|
|
101
|
+
const status = entry['status'];
|
|
102
|
+
if (typeof status === 'string' && status.length > 0) {
|
|
103
|
+
copy_statuses.push(status);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return { copy_count: value.length, provider_ids, copy_statuses };
|
|
107
|
+
}
|
|
108
|
+
function isRecord(value) {
|
|
109
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
110
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `local_fs` adapter for `RawContentStore`.
|
|
3
|
+
*
|
|
4
|
+
* Stores blobs on the local filesystem under a configured root. Used for
|
|
5
|
+
* development and single-node test deployments — production setups
|
|
6
|
+
* configure the S3 adapter instead.
|
|
7
|
+
*
|
|
8
|
+
* Storage URI shape: `local-fs://<adapter-relative-key>`. The key is the
|
|
9
|
+
* same string the caller passed to `put()`; the absolute filesystem path
|
|
10
|
+
* is reconstructed by joining `root + key`. We never persist the absolute
|
|
11
|
+
* path on the wire so the same DB row stays portable when the root moves.
|
|
12
|
+
*
|
|
13
|
+
* Atomicity: writes go through a `<key>.tmp.<nonce>` sibling and are
|
|
14
|
+
* promoted with `fs.rename`, so a crash mid-write never leaves a
|
|
15
|
+
* partial blob at the final key. `delete` is idempotent — `ENOENT`
|
|
16
|
+
* surfaces as `{ deleted: false }` rather than an error.
|
|
17
|
+
*
|
|
18
|
+
* Path safety: every adapter-relative key resolves through `path.resolve`
|
|
19
|
+
* and is rejected if it escapes `root`. That keeps a malicious or
|
|
20
|
+
* mistaken `..`-laden key from writing/reading outside the configured
|
|
21
|
+
* sandbox.
|
|
22
|
+
*/
|
|
23
|
+
import { type PutRawContentInput, type RawContentDeleteResult, type RawContentGetResult, type RawContentHeadResult, type RawContentHints, type RawContentStore, type RawContentStoreCapabilities, type StoredRawContent } from './raw-content-store.js';
|
|
24
|
+
export interface LocalFsRawContentStoreOptions {
|
|
25
|
+
/** Absolute or relative path to the storage root. Resolved at construction. */
|
|
26
|
+
root: string;
|
|
27
|
+
}
|
|
28
|
+
export declare class LocalFsRawContentStore implements RawContentStore {
|
|
29
|
+
readonly provider: "local_fs";
|
|
30
|
+
readonly capabilities: RawContentStoreCapabilities;
|
|
31
|
+
private readonly root;
|
|
32
|
+
constructor(options: LocalFsRawContentStoreOptions);
|
|
33
|
+
put(input: PutRawContentInput): Promise<StoredRawContent>;
|
|
34
|
+
get(storageUri: string): Promise<RawContentGetResult>;
|
|
35
|
+
head(storageUri: string, _hints?: RawContentHints): Promise<RawContentHeadResult>;
|
|
36
|
+
delete(storageUri: string, _hints?: RawContentHints): Promise<RawContentDeleteResult>;
|
|
37
|
+
private resolveKey;
|
|
38
|
+
private resolveUri;
|
|
39
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `local_fs` adapter for `RawContentStore`.
|
|
3
|
+
*
|
|
4
|
+
* Stores blobs on the local filesystem under a configured root. Used for
|
|
5
|
+
* development and single-node test deployments — production setups
|
|
6
|
+
* configure the S3 adapter instead.
|
|
7
|
+
*
|
|
8
|
+
* Storage URI shape: `local-fs://<adapter-relative-key>`. The key is the
|
|
9
|
+
* same string the caller passed to `put()`; the absolute filesystem path
|
|
10
|
+
* is reconstructed by joining `root + key`. We never persist the absolute
|
|
11
|
+
* path on the wire so the same DB row stays portable when the root moves.
|
|
12
|
+
*
|
|
13
|
+
* Atomicity: writes go through a `<key>.tmp.<nonce>` sibling and are
|
|
14
|
+
* promoted with `fs.rename`, so a crash mid-write never leaves a
|
|
15
|
+
* partial blob at the final key. `delete` is idempotent — `ENOENT`
|
|
16
|
+
* surfaces as `{ deleted: false }` rather than an error.
|
|
17
|
+
*
|
|
18
|
+
* Path safety: every adapter-relative key resolves through `path.resolve`
|
|
19
|
+
* and is rejected if it escapes `root`. That keeps a malicious or
|
|
20
|
+
* mistaken `..`-laden key from writing/reading outside the configured
|
|
21
|
+
* sandbox.
|
|
22
|
+
*/
|
|
23
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
24
|
+
import { promises as fs } from 'node:fs';
|
|
25
|
+
import { dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
26
|
+
import { RawStorageUriError, } from './raw-content-store.js';
|
|
27
|
+
const PROVIDER = 'local_fs';
|
|
28
|
+
const URI_PREFIX = 'local-fs://';
|
|
29
|
+
/**
|
|
30
|
+
* `local_fs` is path-addressed (the URI is the on-disk path under the
|
|
31
|
+
* configured root — a subsequent `put` to the same key replaces the
|
|
32
|
+
* bytes that path resolves to), bytes are retrievable the instant
|
|
33
|
+
* `put` resolves, and `deleteSemantics: 'delete'` means the adapter
|
|
34
|
+
* issues `fs.unlink` for the managed file. Filesystem-level
|
|
35
|
+
* snapshots, backup tooling, or undeletion utilities live outside
|
|
36
|
+
* the adapter contract; AtomicMemory does not assert what they do
|
|
37
|
+
* with the deleted inode.
|
|
38
|
+
*/
|
|
39
|
+
const CAPABILITIES = Object.freeze({
|
|
40
|
+
addressing: 'location',
|
|
41
|
+
retrievalConsistency: 'immediate',
|
|
42
|
+
deleteSemantics: 'delete',
|
|
43
|
+
supportsHead: true,
|
|
44
|
+
supportsGet: true,
|
|
45
|
+
});
|
|
46
|
+
export class LocalFsRawContentStore {
|
|
47
|
+
provider = PROVIDER;
|
|
48
|
+
capabilities = CAPABILITIES;
|
|
49
|
+
root;
|
|
50
|
+
constructor(options) {
|
|
51
|
+
if (!options.root || options.root.length === 0) {
|
|
52
|
+
throw new Error('LocalFsRawContentStore: root is required');
|
|
53
|
+
}
|
|
54
|
+
this.root = resolve(options.root);
|
|
55
|
+
}
|
|
56
|
+
async put(input) {
|
|
57
|
+
const target = this.resolveKey(input.key);
|
|
58
|
+
await fs.mkdir(dirname(target), { recursive: true });
|
|
59
|
+
const tmp = `${target}.tmp.${randomBytes(8).toString('hex')}`;
|
|
60
|
+
try {
|
|
61
|
+
await fs.writeFile(tmp, input.body);
|
|
62
|
+
await fs.rename(tmp, target);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
await fs.rm(tmp, { force: true }).catch(() => undefined);
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
storageUri: `${URI_PREFIX}${input.key}`,
|
|
70
|
+
storageProvider: PROVIDER,
|
|
71
|
+
contentHash: sha256Hex(input.body),
|
|
72
|
+
sizeBytes: input.body.length,
|
|
73
|
+
status: 'stored',
|
|
74
|
+
providerMetadata: {},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async get(storageUri) {
|
|
78
|
+
const target = this.resolveUri(storageUri);
|
|
79
|
+
const body = await fs.readFile(target);
|
|
80
|
+
return {
|
|
81
|
+
body,
|
|
82
|
+
metadata: {
|
|
83
|
+
contentLength: body.length,
|
|
84
|
+
contentType: null,
|
|
85
|
+
contentHash: sha256Hex(body),
|
|
86
|
+
providerMetadata: {},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
async head(storageUri, _hints) {
|
|
91
|
+
const target = this.resolveUri(storageUri);
|
|
92
|
+
try {
|
|
93
|
+
const stat = await fs.stat(target);
|
|
94
|
+
return {
|
|
95
|
+
exists: true,
|
|
96
|
+
metadata: {
|
|
97
|
+
contentLength: stat.size,
|
|
98
|
+
contentType: null,
|
|
99
|
+
contentHash: null,
|
|
100
|
+
providerMetadata: { mtime: stat.mtime.toISOString() },
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
if (isNotFound(err))
|
|
106
|
+
return { exists: false, metadata: null };
|
|
107
|
+
throw err;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async delete(storageUri, _hints) {
|
|
111
|
+
const target = this.resolveUri(storageUri);
|
|
112
|
+
try {
|
|
113
|
+
await fs.unlink(target);
|
|
114
|
+
return { deleted: true, semantics: 'deleted' };
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
if (isNotFound(err))
|
|
118
|
+
return { deleted: false, semantics: 'deleted' };
|
|
119
|
+
throw err;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
resolveKey(key) {
|
|
123
|
+
if (isAbsolute(key)) {
|
|
124
|
+
throw new RawStorageUriError(`local_fs key must be relative: ${key}`);
|
|
125
|
+
}
|
|
126
|
+
const target = resolve(this.root, key);
|
|
127
|
+
const inside = relative(this.root, target);
|
|
128
|
+
if (inside.startsWith('..') || isAbsolute(inside)) {
|
|
129
|
+
throw new RawStorageUriError(`local_fs key escapes root: ${key}`);
|
|
130
|
+
}
|
|
131
|
+
return target;
|
|
132
|
+
}
|
|
133
|
+
resolveUri(storageUri) {
|
|
134
|
+
if (!storageUri.startsWith(URI_PREFIX)) {
|
|
135
|
+
throw new RawStorageUriError(`expected local-fs:// URI, got: ${storageUri}`);
|
|
136
|
+
}
|
|
137
|
+
return this.resolveKey(storageUri.slice(URI_PREFIX.length));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function sha256Hex(buf) {
|
|
141
|
+
return createHash('sha256').update(buf).digest('hex');
|
|
142
|
+
}
|
|
143
|
+
function isNotFound(err) {
|
|
144
|
+
return typeof err === 'object' && err !== null && err.code === 'ENOENT';
|
|
145
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pointer-URI scheme allowlist + validator.
|
|
3
|
+
*
|
|
4
|
+
* Step 5 of the storage-sibling plan. Pointer-mode artifacts carry a
|
|
5
|
+
* caller-supplied URI that the server stores but NEVER fetches; even
|
|
6
|
+
* so, narrowing what schemes can be persisted protects downstream
|
|
7
|
+
* consumers (browser UIs, future server-side prefetchers) from
|
|
8
|
+
* unauthenticated or weak references. Default allowlist is
|
|
9
|
+
* `https://`, `s3://`, `gs://`, `ipfs://`. Operators can opt in
|
|
10
|
+
* `http://` or `local-fs://` via the `RAW_STORAGE_POINTER_URI_SCHEMES`
|
|
11
|
+
* csv knob — adding a scheme is the operator attesting that
|
|
12
|
+
* downstream consumers are safe against that scheme's specific
|
|
13
|
+
* risks.
|
|
14
|
+
*
|
|
15
|
+
* The startup parser fails closed on unknown scheme tokens so
|
|
16
|
+
* typos surface deterministically.
|
|
17
|
+
*/
|
|
18
|
+
declare const KNOWN_SCHEMES: readonly ["https", "s3", "gs", "ipfs", "http", "local-fs"];
|
|
19
|
+
type KnownScheme = (typeof KNOWN_SCHEMES)[number];
|
|
20
|
+
/**
|
|
21
|
+
* Parse the `RAW_STORAGE_POINTER_URI_SCHEMES` env value. Empty /
|
|
22
|
+
* undefined → defaults. Unknown tokens → throw.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parsePointerUriSchemes(value: string | undefined): ReadonlyArray<KnownScheme>;
|
|
25
|
+
/**
|
|
26
|
+
* Extract the URI scheme (lowercase, no trailing colon) without
|
|
27
|
+
* relying on `URL` parsing — `s3://` and `ipfs://` are not
|
|
28
|
+
* recognised by the WHATWG URL parser. Returns null when the input
|
|
29
|
+
* does not start with a scheme.
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractScheme(uri: string): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* Test whether `uri` carries an allowlisted scheme. The active
|
|
34
|
+
* allowlist is captured at startup and passed in from the route
|
|
35
|
+
* layer — keeps this module free of any config singleton import.
|
|
36
|
+
*/
|
|
37
|
+
export declare function isAllowlistedPointerUri(uri: string, allowlist: ReadonlyArray<KnownScheme>): boolean;
|
|
38
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pointer-URI scheme allowlist + validator.
|
|
3
|
+
*
|
|
4
|
+
* Step 5 of the storage-sibling plan. Pointer-mode artifacts carry a
|
|
5
|
+
* caller-supplied URI that the server stores but NEVER fetches; even
|
|
6
|
+
* so, narrowing what schemes can be persisted protects downstream
|
|
7
|
+
* consumers (browser UIs, future server-side prefetchers) from
|
|
8
|
+
* unauthenticated or weak references. Default allowlist is
|
|
9
|
+
* `https://`, `s3://`, `gs://`, `ipfs://`. Operators can opt in
|
|
10
|
+
* `http://` or `local-fs://` via the `RAW_STORAGE_POINTER_URI_SCHEMES`
|
|
11
|
+
* csv knob — adding a scheme is the operator attesting that
|
|
12
|
+
* downstream consumers are safe against that scheme's specific
|
|
13
|
+
* risks.
|
|
14
|
+
*
|
|
15
|
+
* The startup parser fails closed on unknown scheme tokens so
|
|
16
|
+
* typos surface deterministically.
|
|
17
|
+
*/
|
|
18
|
+
const KNOWN_SCHEMES = ['https', 's3', 'gs', 'ipfs', 'http', 'local-fs'];
|
|
19
|
+
const DEFAULT_SCHEMES = ['https', 's3', 'gs', 'ipfs'];
|
|
20
|
+
/**
|
|
21
|
+
* Parse the `RAW_STORAGE_POINTER_URI_SCHEMES` env value. Empty /
|
|
22
|
+
* undefined → defaults. Unknown tokens → throw.
|
|
23
|
+
*/
|
|
24
|
+
export function parsePointerUriSchemes(value) {
|
|
25
|
+
if (value === undefined || value.trim().length === 0)
|
|
26
|
+
return DEFAULT_SCHEMES;
|
|
27
|
+
const entries = value.split(',').map((s) => s.trim()).filter((s) => s.length > 0);
|
|
28
|
+
if (entries.length === 0)
|
|
29
|
+
return DEFAULT_SCHEMES;
|
|
30
|
+
const out = [];
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
if (!isKnownScheme(entry)) {
|
|
34
|
+
throw new Error(`Invalid RAW_STORAGE_POINTER_URI_SCHEMES entry '${entry}'. ` +
|
|
35
|
+
`Must be one of: ${KNOWN_SCHEMES.join(', ')}.`);
|
|
36
|
+
}
|
|
37
|
+
if (seen.has(entry)) {
|
|
38
|
+
throw new Error(`Duplicate scheme '${entry}' in RAW_STORAGE_POINTER_URI_SCHEMES.`);
|
|
39
|
+
}
|
|
40
|
+
seen.add(entry);
|
|
41
|
+
out.push(entry);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Extract the URI scheme (lowercase, no trailing colon) without
|
|
47
|
+
* relying on `URL` parsing — `s3://` and `ipfs://` are not
|
|
48
|
+
* recognised by the WHATWG URL parser. Returns null when the input
|
|
49
|
+
* does not start with a scheme.
|
|
50
|
+
*/
|
|
51
|
+
export function extractScheme(uri) {
|
|
52
|
+
const match = /^([a-zA-Z][a-zA-Z0-9+.\-]*):\/\//.exec(uri);
|
|
53
|
+
if (match === null)
|
|
54
|
+
return null;
|
|
55
|
+
return match[1].toLowerCase();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Test whether `uri` carries an allowlisted scheme. The active
|
|
59
|
+
* allowlist is captured at startup and passed in from the route
|
|
60
|
+
* layer — keeps this module free of any config singleton import.
|
|
61
|
+
*/
|
|
62
|
+
export function isAllowlistedPointerUri(uri, allowlist) {
|
|
63
|
+
const scheme = extractScheme(uri);
|
|
64
|
+
if (scheme === null)
|
|
65
|
+
return false;
|
|
66
|
+
return allowlist.includes(scheme);
|
|
67
|
+
}
|
|
68
|
+
function isKnownScheme(value) {
|
|
69
|
+
return KNOWN_SCHEMES.includes(value);
|
|
70
|
+
}
|