@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,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Filecoin provider configuration.
|
|
3
|
+
*
|
|
4
|
+
* `parseFilecoinProviderConfig(env)` is the only env reader inside
|
|
5
|
+
* `src/storage/providers/filecoin/*`. Central `src/config.ts`
|
|
6
|
+
* collects `process.env` into a plain object and hands it to this
|
|
7
|
+
* function; the provider module never reaches for `process.env`
|
|
8
|
+
* itself, matching the workspace rule against direct env access in
|
|
9
|
+
* business code.
|
|
10
|
+
*
|
|
11
|
+
* The cross-provider guard — rejecting any `RAW_STORAGE_FILECOIN_*`
|
|
12
|
+
* environment variable when `RAW_STORAGE_PROVIDER` is non-filecoin —
|
|
13
|
+
* lives in central `src/config.ts`. Reason:
|
|
14
|
+
* `parseFilecoinProviderConfig` is only invoked when the provider IS
|
|
15
|
+
* filecoin, so the cross-provider rejection has to fire at the
|
|
16
|
+
* central seam to catch the misconfiguration. This module exports
|
|
17
|
+
* `collectFilecoinProviderEnvKeys` so the central code can compute
|
|
18
|
+
* which RAW_STORAGE_FILECOIN_* keys an operator set without
|
|
19
|
+
* embedding the prefix string in two places.
|
|
20
|
+
*
|
|
21
|
+
* v1 credential model: operator-owned deployment credentials.
|
|
22
|
+
* Storage-profile / per-org / per-user credential ownership is
|
|
23
|
+
* deferred to a future release. `RAW_STORAGE_FILECOIN_PRIVATE_KEY` is
|
|
24
|
+
* validated syntactically (`^0x[a-fA-F0-9]{64}$`) at startup. The
|
|
25
|
+
* value is NEVER logged on rejection; no account derivation, no
|
|
26
|
+
* chain, balance, and provider checks are handled by the readiness
|
|
27
|
+
* probes in `./readiness.ts`.
|
|
28
|
+
*/
|
|
29
|
+
import { FILECOIN_METADATA_RESERVED_PREFIXES, FILECOIN_METADATA_DENYLIST, } from './metadata.js';
|
|
30
|
+
/** Prefix shared by every `RAW_STORAGE_FILECOIN_*` environment variable. */
|
|
31
|
+
const FILECOIN_PROVIDER_ENV_PREFIX = 'RAW_STORAGE_FILECOIN_';
|
|
32
|
+
const PRIVATE_KEY_PATTERN = /^0x[a-fA-F0-9]{64}$/;
|
|
33
|
+
/**
|
|
34
|
+
* DATA_SET_METADATA constraints mirror the Synapse SDK's
|
|
35
|
+
* `METADATA_LIMITS` (docs.filecoin.cloud/reference/filoz/synapse-
|
|
36
|
+
* core/utils/variables/metadata_limits/): MAX_KEYS_PER_DATASET=10,
|
|
37
|
+
* MAX_KEY_LENGTH=32, MAX_VALUE_LENGTH=128. We enforce these
|
|
38
|
+
* server-side so a misconfigured operator can't get past startup
|
|
39
|
+
* with values Synapse would later reject. The key-charset
|
|
40
|
+
* allowlist (`[A-Za-z0-9_.:-]+`) and the credential-shape rejection
|
|
41
|
+
* are AtomicMemory-additional safety rails on top of the Synapse
|
|
42
|
+
* limits.
|
|
43
|
+
*/
|
|
44
|
+
const MAX_METADATA_KEYS = 10;
|
|
45
|
+
const MAX_METADATA_KEY_LENGTH = 32;
|
|
46
|
+
const MAX_METADATA_VALUE_LENGTH = 128;
|
|
47
|
+
const METADATA_KEY_PATTERN = /^[A-Za-z0-9_.:-]+$/;
|
|
48
|
+
/**
|
|
49
|
+
* Patterns rejected in both keys AND string values. Matches credential
|
|
50
|
+
* shapes (private keys, bearer tokens, UCAN proofs, signed requests,
|
|
51
|
+
* authorization headers). Match is case-insensitive on the raw input.
|
|
52
|
+
*/
|
|
53
|
+
const CREDENTIAL_VALUE_PATTERNS = [
|
|
54
|
+
/private[_-]?key/i,
|
|
55
|
+
/\bbearer\b/i,
|
|
56
|
+
/authorization/i,
|
|
57
|
+
/\bucan\b/i,
|
|
58
|
+
/signed[_-]?request/i,
|
|
59
|
+
/\bauth[_-]?header\b/i,
|
|
60
|
+
/\bsynapse[_-]?response\b/i,
|
|
61
|
+
/^0x[a-fA-F0-9]{64}$/,
|
|
62
|
+
/^eyJ[A-Za-z0-9_=-]+\.[A-Za-z0-9_.+/=-]+\.[A-Za-z0-9_.+/=-]+$/, // JWT-shaped
|
|
63
|
+
];
|
|
64
|
+
/**
|
|
65
|
+
* Syntactic-only validator for `RAW_STORAGE_FILECOIN_PRIVATE_KEY`.
|
|
66
|
+
* Accepts a 32-byte hex string with `0x` prefix (case-insensitive).
|
|
67
|
+
* Throws on any other shape WITHOUT echoing the value — the message
|
|
68
|
+
* names only the env var and the expected pattern.
|
|
69
|
+
*/
|
|
70
|
+
export function parseFilecoinPrivateKey(value) {
|
|
71
|
+
if (!PRIVATE_KEY_PATTERN.test(value)) {
|
|
72
|
+
throw new Error("RAW_STORAGE_FILECOIN_PRIVATE_KEY must match '^0x[a-fA-F0-9]{64}$' " +
|
|
73
|
+
"(0x-prefixed 32-byte hex).");
|
|
74
|
+
}
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Return the names of every `RAW_STORAGE_FILECOIN_*` key the
|
|
79
|
+
* operator set to a non-empty value. Used by the central
|
|
80
|
+
* cross-provider guard in `src/config.ts` so non-filecoin
|
|
81
|
+
* deployments cannot accidentally carry Filecoin config.
|
|
82
|
+
*/
|
|
83
|
+
export function collectFilecoinProviderEnvKeys(env) {
|
|
84
|
+
const out = [];
|
|
85
|
+
for (const key of Object.keys(env)) {
|
|
86
|
+
if (!key.startsWith(FILECOIN_PROVIDER_ENV_PREFIX))
|
|
87
|
+
continue;
|
|
88
|
+
const value = env[key];
|
|
89
|
+
if (value !== undefined && value !== '')
|
|
90
|
+
out.push(key);
|
|
91
|
+
}
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Parse + validate the Synapse-shaped Filecoin provider env block.
|
|
96
|
+
* Only invoked when `RAW_STORAGE_PROVIDER=filecoin`; the cross-
|
|
97
|
+
* provider guard runs in `src/config.ts` before this function.
|
|
98
|
+
*/
|
|
99
|
+
export function parseFilecoinProviderConfig(env) {
|
|
100
|
+
const driver = requireDriver(env['RAW_STORAGE_FILECOIN_DRIVER']);
|
|
101
|
+
const network = requireNetwork(env['RAW_STORAGE_FILECOIN_NETWORK']);
|
|
102
|
+
const privateKey = requirePrivateKey(env['RAW_STORAGE_FILECOIN_PRIVATE_KEY']);
|
|
103
|
+
const source = requireSource(env['RAW_STORAGE_FILECOIN_SOURCE']);
|
|
104
|
+
const withCdn = requireStrictBool(env['RAW_STORAGE_FILECOIN_WITH_CDN'], 'RAW_STORAGE_FILECOIN_WITH_CDN');
|
|
105
|
+
return {
|
|
106
|
+
driver,
|
|
107
|
+
network,
|
|
108
|
+
privateKey,
|
|
109
|
+
source,
|
|
110
|
+
withCdn,
|
|
111
|
+
providerIds: parseProviderIds(env['RAW_STORAGE_FILECOIN_PROVIDER_IDS']),
|
|
112
|
+
copies: parsePositiveIntOrNull(env['RAW_STORAGE_FILECOIN_COPIES'], 'RAW_STORAGE_FILECOIN_COPIES'),
|
|
113
|
+
dataSetMetadata: parseDataSetMetadata(env['RAW_STORAGE_FILECOIN_DATA_SET_METADATA']),
|
|
114
|
+
maxUploadBytes: parsePositiveIntOrNull(env['RAW_STORAGE_FILECOIN_MAX_UPLOAD_BYTES'], 'RAW_STORAGE_FILECOIN_MAX_UPLOAD_BYTES'),
|
|
115
|
+
minUploadBytes: parsePositiveIntOrNull(env['RAW_STORAGE_FILECOIN_MIN_UPLOAD_BYTES'], 'RAW_STORAGE_FILECOIN_MIN_UPLOAD_BYTES'),
|
|
116
|
+
uploadTimeoutMs: parsePositiveIntOrNull(env['RAW_STORAGE_FILECOIN_UPLOAD_TIMEOUT_MS'], 'RAW_STORAGE_FILECOIN_UPLOAD_TIMEOUT_MS'),
|
|
117
|
+
retrievalTimeoutMs: parsePositiveIntOrNull(env['RAW_STORAGE_FILECOIN_RETRIEVAL_TIMEOUT_MS'], 'RAW_STORAGE_FILECOIN_RETRIEVAL_TIMEOUT_MS'),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function requireDriver(value) {
|
|
121
|
+
if (value === 'synapse' || value === 'filecoin_pin')
|
|
122
|
+
return value;
|
|
123
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DRIVER must equal 'synapse' or 'filecoin_pin' ` +
|
|
124
|
+
`(got '${value ?? '<unset>'}'). Phase 5 evaluation: 'synapse' is the ` +
|
|
125
|
+
"default direct driver; 'filecoin_pin' is the opt-in CAR-first driver " +
|
|
126
|
+
'backed by the `filecoin-pin` package. The driver choice is purely an ' +
|
|
127
|
+
'internal selector — neither value is exposed on any public surface.');
|
|
128
|
+
}
|
|
129
|
+
function requireNetwork(value) {
|
|
130
|
+
if (value === 'calibration' || value === 'mainnet')
|
|
131
|
+
return value;
|
|
132
|
+
throw new Error(`RAW_STORAGE_FILECOIN_NETWORK must be 'calibration' or 'mainnet' ` +
|
|
133
|
+
`(got '${value ?? '<unset>'}').`);
|
|
134
|
+
}
|
|
135
|
+
function requirePrivateKey(value) {
|
|
136
|
+
if (!value) {
|
|
137
|
+
throw new Error('RAW_STORAGE_FILECOIN_PRIVATE_KEY is required.');
|
|
138
|
+
}
|
|
139
|
+
return parseFilecoinPrivateKey(value);
|
|
140
|
+
}
|
|
141
|
+
function requireSource(value) {
|
|
142
|
+
const trimmed = value?.trim() ?? '';
|
|
143
|
+
if (trimmed.length === 0) {
|
|
144
|
+
throw new Error('RAW_STORAGE_FILECOIN_SOURCE is required (non-empty).');
|
|
145
|
+
}
|
|
146
|
+
return trimmed;
|
|
147
|
+
}
|
|
148
|
+
function requireStrictBool(value, name) {
|
|
149
|
+
if (value === 'true')
|
|
150
|
+
return true;
|
|
151
|
+
if (value === 'false')
|
|
152
|
+
return false;
|
|
153
|
+
throw new Error(`${name} must be 'true' or 'false' (got '${value ?? '<unset>'}').`);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Synapse SDK provider IDs are on-chain uint256 values; the wire
|
|
157
|
+
* encoding is a positive decimal bigint string. We validate the
|
|
158
|
+
* shape at startup (no leading zeros, no hex, no float, no zero,
|
|
159
|
+
* no negative) so the Synapse `BigInt(id)` cast inside
|
|
160
|
+
* `synapse-client.ts` can never throw a raw `SyntaxError` that
|
|
161
|
+
* escapes the provider boundary.
|
|
162
|
+
*/
|
|
163
|
+
const POSITIVE_DECIMAL_BIGINT = /^[1-9][0-9]*$/;
|
|
164
|
+
function parseProviderIds(value) {
|
|
165
|
+
if (!value)
|
|
166
|
+
return [];
|
|
167
|
+
const seen = new Set();
|
|
168
|
+
const out = [];
|
|
169
|
+
for (const raw of value.split(',')) {
|
|
170
|
+
const trimmed = raw.trim();
|
|
171
|
+
if (trimmed.length === 0)
|
|
172
|
+
continue;
|
|
173
|
+
if (!POSITIVE_DECIMAL_BIGINT.test(trimmed)) {
|
|
174
|
+
throw new Error(`RAW_STORAGE_FILECOIN_PROVIDER_IDS entry '${trimmed}' is not a positive ` +
|
|
175
|
+
'decimal bigint (Synapse provider IDs are on-chain uint256 values).');
|
|
176
|
+
}
|
|
177
|
+
if (seen.has(trimmed)) {
|
|
178
|
+
throw new Error(`RAW_STORAGE_FILECOIN_PROVIDER_IDS contains duplicate entry '${trimmed}'.`);
|
|
179
|
+
}
|
|
180
|
+
seen.add(trimmed);
|
|
181
|
+
out.push(trimmed);
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
function parsePositiveIntOrNull(value, name) {
|
|
186
|
+
if (value === undefined || value === '')
|
|
187
|
+
return null;
|
|
188
|
+
const parsed = Number.parseInt(value, 10);
|
|
189
|
+
if (!Number.isFinite(parsed) || parsed < 1 || String(parsed) !== value.trim()) {
|
|
190
|
+
throw new Error(`${name} must be a positive integer (got '${value}').`);
|
|
191
|
+
}
|
|
192
|
+
return parsed;
|
|
193
|
+
}
|
|
194
|
+
function parseDataSetMetadata(raw) {
|
|
195
|
+
if (!raw)
|
|
196
|
+
return {};
|
|
197
|
+
let parsed;
|
|
198
|
+
try {
|
|
199
|
+
parsed = JSON.parse(raw);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
throw new Error('RAW_STORAGE_FILECOIN_DATA_SET_METADATA must be valid JSON.');
|
|
203
|
+
}
|
|
204
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
205
|
+
throw new Error('RAW_STORAGE_FILECOIN_DATA_SET_METADATA must be a JSON object.');
|
|
206
|
+
}
|
|
207
|
+
const obj = parsed;
|
|
208
|
+
const keys = Object.keys(obj);
|
|
209
|
+
if (keys.length > MAX_METADATA_KEYS) {
|
|
210
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA exceeds ${MAX_METADATA_KEYS} keys.`);
|
|
211
|
+
}
|
|
212
|
+
const out = {};
|
|
213
|
+
for (const key of keys) {
|
|
214
|
+
rejectMetadataKey(key);
|
|
215
|
+
out[key] = coerceMetadataValue(key, obj[key]);
|
|
216
|
+
}
|
|
217
|
+
return out;
|
|
218
|
+
}
|
|
219
|
+
function rejectMetadataKey(key) {
|
|
220
|
+
rejectMetadataKeyShape(key);
|
|
221
|
+
rejectMetadataKeyReservedPrefix(key);
|
|
222
|
+
rejectMetadataKeyCredentialShape(key);
|
|
223
|
+
}
|
|
224
|
+
function rejectMetadataKeyShape(key) {
|
|
225
|
+
if (key.length === 0 || key.length > MAX_METADATA_KEY_LENGTH) {
|
|
226
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA key length must be 1..${MAX_METADATA_KEY_LENGTH}.`);
|
|
227
|
+
}
|
|
228
|
+
if (!METADATA_KEY_PATTERN.test(key)) {
|
|
229
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA key '${key}' contains disallowed characters. ` +
|
|
230
|
+
"Keys must match '[A-Za-z0-9_.:-]+'.");
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function rejectMetadataKeyReservedPrefix(key) {
|
|
234
|
+
for (const prefix of FILECOIN_METADATA_RESERVED_PREFIXES) {
|
|
235
|
+
if (key.startsWith(prefix)) {
|
|
236
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA key '${key}' uses reserved prefix '${prefix}'.`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function rejectMetadataKeyCredentialShape(key) {
|
|
241
|
+
const lower = key.toLowerCase();
|
|
242
|
+
for (const denied of FILECOIN_METADATA_DENYLIST) {
|
|
243
|
+
if (lower === denied || lower.includes(denied)) {
|
|
244
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA key '${key}' matches a denylisted credential shape.`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const pattern of CREDENTIAL_VALUE_PATTERNS) {
|
|
248
|
+
if (pattern.test(key)) {
|
|
249
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA key '${key}' matches a denylisted credential shape.`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function coerceMetadataValue(key, value) {
|
|
254
|
+
if (typeof value === 'string') {
|
|
255
|
+
if (value.length > MAX_METADATA_VALUE_LENGTH) {
|
|
256
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA value for '${key}' exceeds ` +
|
|
257
|
+
`${MAX_METADATA_VALUE_LENGTH} characters (got ${value.length}).`);
|
|
258
|
+
}
|
|
259
|
+
rejectCredentialShapedValue(key, value);
|
|
260
|
+
return value;
|
|
261
|
+
}
|
|
262
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
263
|
+
return value;
|
|
264
|
+
if (typeof value === 'boolean')
|
|
265
|
+
return value;
|
|
266
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA value for '${key}' must be a scalar ` +
|
|
267
|
+
'(string, finite number, or boolean).');
|
|
268
|
+
}
|
|
269
|
+
function rejectCredentialShapedValue(key, value) {
|
|
270
|
+
for (const pattern of CREDENTIAL_VALUE_PATTERNS) {
|
|
271
|
+
if (pattern.test(value)) {
|
|
272
|
+
throw new Error(`RAW_STORAGE_FILECOIN_DATA_SET_METADATA value for '${key}' matches a denylisted credential shape.`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Filecoin provider error hierarchy.
|
|
3
|
+
*
|
|
4
|
+
* Every error thrown out of `src/storage/providers/filecoin/*` extends
|
|
5
|
+
* `FilecoinProviderError` so the route + reconciler layers can pattern
|
|
6
|
+
* match a single base class instead of probing for vendor-shaped
|
|
7
|
+
* variants. Two concrete cases are defined here:
|
|
8
|
+
*
|
|
9
|
+
* - `FilecoinNotImplementedError` — thrown by test-only provider
|
|
10
|
+
* stubs. The route layer maps it onto a typed envelope so clients
|
|
11
|
+
* see a stable code.
|
|
12
|
+
* - `FilecoinProviderNotConfiguredError` — thrown at construction
|
|
13
|
+
* time when the test stub is asked to build a real client without
|
|
14
|
+
* the operator having supplied the Synapse config (see
|
|
15
|
+
* `./config.ts`). Surfaces at composition time, not first upload.
|
|
16
|
+
*
|
|
17
|
+
* Sanitization rule: any caller that wraps a vendor (Synapse, RPC,
|
|
18
|
+
* provider) error MUST replace the raw message with the public
|
|
19
|
+
* `errorCode` and discard the original `.message` / `.cause` chain
|
|
20
|
+
* before it crosses this boundary. Wallet addresses, private keys,
|
|
21
|
+
* provider IDs, balances, allowances, and signed-request payloads
|
|
22
|
+
* are not allowed in messages emitted from this module.
|
|
23
|
+
*/
|
|
24
|
+
export declare class FilecoinProviderError extends Error {
|
|
25
|
+
readonly errorCode: string;
|
|
26
|
+
constructor(errorCode: string, message: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Thrown by test-only provider stubs for provider operations
|
|
30
|
+
* (`put`, `get`, `head`, `delete`, `verify`). Carries a public
|
|
31
|
+
* `errorCode` so the route layer can map it onto a stable envelope
|
|
32
|
+
* without inspecting message strings.
|
|
33
|
+
*/
|
|
34
|
+
export declare class FilecoinNotImplementedError extends FilecoinProviderError {
|
|
35
|
+
constructor(operation: string);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Thrown at composition time when `createFilecoinStorageBackend` is
|
|
39
|
+
* called against a config that has not yet been populated with the
|
|
40
|
+
* Synapse fields. This error prevents a half-wired client from being
|
|
41
|
+
* built.
|
|
42
|
+
*/
|
|
43
|
+
export declare class FilecoinProviderNotConfiguredError extends FilecoinProviderError {
|
|
44
|
+
constructor(reason: string);
|
|
45
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Filecoin provider error hierarchy.
|
|
3
|
+
*
|
|
4
|
+
* Every error thrown out of `src/storage/providers/filecoin/*` extends
|
|
5
|
+
* `FilecoinProviderError` so the route + reconciler layers can pattern
|
|
6
|
+
* match a single base class instead of probing for vendor-shaped
|
|
7
|
+
* variants. Two concrete cases are defined here:
|
|
8
|
+
*
|
|
9
|
+
* - `FilecoinNotImplementedError` — thrown by test-only provider
|
|
10
|
+
* stubs. The route layer maps it onto a typed envelope so clients
|
|
11
|
+
* see a stable code.
|
|
12
|
+
* - `FilecoinProviderNotConfiguredError` — thrown at construction
|
|
13
|
+
* time when the test stub is asked to build a real client without
|
|
14
|
+
* the operator having supplied the Synapse config (see
|
|
15
|
+
* `./config.ts`). Surfaces at composition time, not first upload.
|
|
16
|
+
*
|
|
17
|
+
* Sanitization rule: any caller that wraps a vendor (Synapse, RPC,
|
|
18
|
+
* provider) error MUST replace the raw message with the public
|
|
19
|
+
* `errorCode` and discard the original `.message` / `.cause` chain
|
|
20
|
+
* before it crosses this boundary. Wallet addresses, private keys,
|
|
21
|
+
* provider IDs, balances, allowances, and signed-request payloads
|
|
22
|
+
* are not allowed in messages emitted from this module.
|
|
23
|
+
*/
|
|
24
|
+
export class FilecoinProviderError extends Error {
|
|
25
|
+
errorCode;
|
|
26
|
+
constructor(errorCode, message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = 'FilecoinProviderError';
|
|
29
|
+
this.errorCode = errorCode;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Thrown by test-only provider stubs for provider operations
|
|
34
|
+
* (`put`, `get`, `head`, `delete`, `verify`). Carries a public
|
|
35
|
+
* `errorCode` so the route layer can map it onto a stable envelope
|
|
36
|
+
* without inspecting message strings.
|
|
37
|
+
*/
|
|
38
|
+
export class FilecoinNotImplementedError extends FilecoinProviderError {
|
|
39
|
+
constructor(operation) {
|
|
40
|
+
super('filecoin_not_implemented', `Filecoin provider operation '${operation}' is not implemented in this build.`);
|
|
41
|
+
this.name = 'FilecoinNotImplementedError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Thrown at composition time when `createFilecoinStorageBackend` is
|
|
46
|
+
* called against a config that has not yet been populated with the
|
|
47
|
+
* Synapse fields. This error prevents a half-wired client from being
|
|
48
|
+
* built.
|
|
49
|
+
*/
|
|
50
|
+
// fallow-ignore-next-line unused-export
|
|
51
|
+
export class FilecoinProviderNotConfiguredError extends FilecoinProviderError {
|
|
52
|
+
constructor(reason) {
|
|
53
|
+
super('filecoin_provider_not_configured', `Filecoin provider not configured: ${reason}.`);
|
|
54
|
+
this.name = 'FilecoinProviderNotConfiguredError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file CAR-construction helpers for the filecoin-pin driver.
|
|
3
|
+
*
|
|
4
|
+
* The filecoin-pin path differs from the direct Synapse driver in
|
|
5
|
+
* one place: before handing bytes to the Synapse SDK it wraps them
|
|
6
|
+
* in a CAR file whose blocks form an IPFS UnixFS DAG. The Filecoin
|
|
7
|
+
* PieceCID is then computed over the CAR bytes (not the raw user
|
|
8
|
+
* content), and the IPFS root CID survives as a separate
|
|
9
|
+
* identifier — which is the value the Phase 4 `ipfs_cid` sidecar
|
|
10
|
+
* slot was designed to carry.
|
|
11
|
+
*
|
|
12
|
+
* Two seams live here:
|
|
13
|
+
*
|
|
14
|
+
* - `buildCarFromBytes(body)` — convert a `Buffer` of raw user
|
|
15
|
+
* bytes into a `{ carBytes, rootCid }` pair via Helia +
|
|
16
|
+
* `@helia/unixfs`. Used by `FilecoinPinFilecoinProviderClient.put`
|
|
17
|
+
* immediately before delegating to filecoin-pin's
|
|
18
|
+
* `executeUpload`.
|
|
19
|
+
*
|
|
20
|
+
* - `extractFileFromCar(carBytes, rootCid)` — the inverse:
|
|
21
|
+
* parse a CAR by streaming its blocks back into an in-memory
|
|
22
|
+
* blockstore, then unixfs-traverse from the root to materialise
|
|
23
|
+
* the original bytes. Used by
|
|
24
|
+
* `FilecoinPinFilecoinProviderClient.get` to reverse the CAR
|
|
25
|
+
* wrapping the upload path applied.
|
|
26
|
+
*
|
|
27
|
+
* Vendor isolation. Every CAR / Helia / blockstore import lives
|
|
28
|
+
* inside the function bodies as a runtime `await import(...)`
|
|
29
|
+
* against a `const`-stored specifier. That makes this file
|
|
30
|
+
* source-build-safe without the `optionalDependencies` graph
|
|
31
|
+
* present — the production build path
|
|
32
|
+
* (`tsc -p tsconfig.build.json` / `npm run build`) compiles even
|
|
33
|
+
* when none of `@ipld/car`, `@helia/unixfs`, or `blockstore-core`
|
|
34
|
+
* are installed. Local minimal type aliases below mirror just
|
|
35
|
+
* the surface we consume. (Dev-mode `tsc --noEmit` against the
|
|
36
|
+
* full `tsconfig.json` still requires the optional packages
|
|
37
|
+
* because TEST files import them directly — tests never run on
|
|
38
|
+
* omit-optional production installs; `tsconfig.build.json`
|
|
39
|
+
* excludes `__tests__`.) The runtime dynamic-import is the only
|
|
40
|
+
* resolution call site, so a synapse-only install
|
|
41
|
+
* (`npm ci --legacy-peer-deps --omit=optional`) never touches
|
|
42
|
+
* the CAR-first modules.
|
|
43
|
+
*
|
|
44
|
+
* Errors are not thrown directly from this file. The driver
|
|
45
|
+
* client wraps any failure into a typed
|
|
46
|
+
* `FilecoinProviderError('filecoin_pin_car_*', sanitized)` at the
|
|
47
|
+
* call site so vendor stack traces never escape the boundary.
|
|
48
|
+
*/
|
|
49
|
+
import { CID } from 'multiformats/cid';
|
|
50
|
+
export interface BuiltCar {
|
|
51
|
+
/** Serialized CAR bytes — what the upload path hands to Synapse. */
|
|
52
|
+
readonly carBytes: Buffer;
|
|
53
|
+
/** IPFS root CID (unixfs dag-pb / raw, CIDv1 base32). */
|
|
54
|
+
readonly rootCid: CID;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build a single-file UnixFS DAG from `body`, then serialise it
|
|
58
|
+
* as a CAR with the file's root as the sole CAR root. The
|
|
59
|
+
* returned `rootCid` is the canonical IPFS identity for the
|
|
60
|
+
* bytes — pass it through to `FilecoinPutResult.ipfsCid` so the
|
|
61
|
+
* sidecar carries a stable IPFS handle alongside the Filecoin
|
|
62
|
+
* PieceCID.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildCarFromBytes(body: Buffer): Promise<BuiltCar>;
|
|
65
|
+
/**
|
|
66
|
+
* Inverse of `buildCarFromBytes`: parse `carBytes` into an in-
|
|
67
|
+
* memory blockstore, then walk the UnixFS DAG from `rootCid` to
|
|
68
|
+
* recover the original file bytes. Returns a `Buffer` matching
|
|
69
|
+
* what was originally uploaded.
|
|
70
|
+
*
|
|
71
|
+
* `rootCid` may be passed as either a `multiformats/cid.CID`
|
|
72
|
+
* instance or its canonical string form. We accept the string
|
|
73
|
+
* form so callers that derived the root from `CarReader.getRoots()`
|
|
74
|
+
* (whose CID type lives in `@ipld/car`'s nested `multiformats`,
|
|
75
|
+
* not the top-level one) can interoperate without a manual
|
|
76
|
+
* cross-package cast.
|
|
77
|
+
*/
|
|
78
|
+
export declare function extractFileFromCar(carBytes: Buffer, rootCid: CID | string): Promise<Buffer>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file CAR-construction helpers for the filecoin-pin driver.
|
|
3
|
+
*
|
|
4
|
+
* The filecoin-pin path differs from the direct Synapse driver in
|
|
5
|
+
* one place: before handing bytes to the Synapse SDK it wraps them
|
|
6
|
+
* in a CAR file whose blocks form an IPFS UnixFS DAG. The Filecoin
|
|
7
|
+
* PieceCID is then computed over the CAR bytes (not the raw user
|
|
8
|
+
* content), and the IPFS root CID survives as a separate
|
|
9
|
+
* identifier — which is the value the Phase 4 `ipfs_cid` sidecar
|
|
10
|
+
* slot was designed to carry.
|
|
11
|
+
*
|
|
12
|
+
* Two seams live here:
|
|
13
|
+
*
|
|
14
|
+
* - `buildCarFromBytes(body)` — convert a `Buffer` of raw user
|
|
15
|
+
* bytes into a `{ carBytes, rootCid }` pair via Helia +
|
|
16
|
+
* `@helia/unixfs`. Used by `FilecoinPinFilecoinProviderClient.put`
|
|
17
|
+
* immediately before delegating to filecoin-pin's
|
|
18
|
+
* `executeUpload`.
|
|
19
|
+
*
|
|
20
|
+
* - `extractFileFromCar(carBytes, rootCid)` — the inverse:
|
|
21
|
+
* parse a CAR by streaming its blocks back into an in-memory
|
|
22
|
+
* blockstore, then unixfs-traverse from the root to materialise
|
|
23
|
+
* the original bytes. Used by
|
|
24
|
+
* `FilecoinPinFilecoinProviderClient.get` to reverse the CAR
|
|
25
|
+
* wrapping the upload path applied.
|
|
26
|
+
*
|
|
27
|
+
* Vendor isolation. Every CAR / Helia / blockstore import lives
|
|
28
|
+
* inside the function bodies as a runtime `await import(...)`
|
|
29
|
+
* against a `const`-stored specifier. That makes this file
|
|
30
|
+
* source-build-safe without the `optionalDependencies` graph
|
|
31
|
+
* present — the production build path
|
|
32
|
+
* (`tsc -p tsconfig.build.json` / `npm run build`) compiles even
|
|
33
|
+
* when none of `@ipld/car`, `@helia/unixfs`, or `blockstore-core`
|
|
34
|
+
* are installed. Local minimal type aliases below mirror just
|
|
35
|
+
* the surface we consume. (Dev-mode `tsc --noEmit` against the
|
|
36
|
+
* full `tsconfig.json` still requires the optional packages
|
|
37
|
+
* because TEST files import them directly — tests never run on
|
|
38
|
+
* omit-optional production installs; `tsconfig.build.json`
|
|
39
|
+
* excludes `__tests__`.) The runtime dynamic-import is the only
|
|
40
|
+
* resolution call site, so a synapse-only install
|
|
41
|
+
* (`npm ci --legacy-peer-deps --omit=optional`) never touches
|
|
42
|
+
* the CAR-first modules.
|
|
43
|
+
*
|
|
44
|
+
* Errors are not thrown directly from this file. The driver
|
|
45
|
+
* client wraps any failure into a typed
|
|
46
|
+
* `FilecoinProviderError('filecoin_pin_car_*', sanitized)` at the
|
|
47
|
+
* call site so vendor stack traces never escape the boundary.
|
|
48
|
+
*/
|
|
49
|
+
import { CID } from 'multiformats/cid';
|
|
50
|
+
// The specifiers below are stored as runtime values rather than
|
|
51
|
+
// inline string literals so `tsc` does NOT statically resolve the
|
|
52
|
+
// optional modules at type-check time. A synapse-only install
|
|
53
|
+
// (`npm ci --legacy-peer-deps --omit=optional`) successfully
|
|
54
|
+
// runs `tsc -p tsconfig.build.json`; the dynamic import only
|
|
55
|
+
// fails at runtime when an operator selects
|
|
56
|
+
// `RAW_STORAGE_FILECOIN_DRIVER=filecoin_pin` without the optional
|
|
57
|
+
// graph installed — which is the intended failure mode.
|
|
58
|
+
const VENDOR_IPLD_CAR = '@ipld/car';
|
|
59
|
+
const VENDOR_HELIA_UNIXFS = '@helia/unixfs';
|
|
60
|
+
const VENDOR_BLOCKSTORE_MEMORY = 'blockstore-core/memory';
|
|
61
|
+
async function loadCarWriter() {
|
|
62
|
+
const mod = (await import(VENDOR_IPLD_CAR));
|
|
63
|
+
return mod.CarWriter;
|
|
64
|
+
}
|
|
65
|
+
async function loadCarReader() {
|
|
66
|
+
const mod = (await import(VENDOR_IPLD_CAR));
|
|
67
|
+
return mod.CarReader;
|
|
68
|
+
}
|
|
69
|
+
async function loadUnixfs(blockstore) {
|
|
70
|
+
const mod = (await import(VENDOR_HELIA_UNIXFS));
|
|
71
|
+
return mod.unixfs({ blockstore });
|
|
72
|
+
}
|
|
73
|
+
async function loadMemoryBlockstore() {
|
|
74
|
+
const mod = (await import(VENDOR_BLOCKSTORE_MEMORY));
|
|
75
|
+
return new mod.MemoryBlockstore();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Flatten the blockstore's per-block byte iterable into a single
|
|
79
|
+
* `Uint8Array`. `MemoryBlockstore.getAll()` reports `bytes` as
|
|
80
|
+
* an `AwaitGenerator<Uint8Array>` even though concrete blocks are
|
|
81
|
+
* usually single-chunk; we collect whichever shape arrives.
|
|
82
|
+
*/
|
|
83
|
+
async function flattenBytes(value) {
|
|
84
|
+
if (value instanceof Uint8Array)
|
|
85
|
+
return new Uint8Array(value);
|
|
86
|
+
const chunks = [];
|
|
87
|
+
for await (const chunk of value)
|
|
88
|
+
chunks.push(chunk);
|
|
89
|
+
if (chunks.length === 1)
|
|
90
|
+
return new Uint8Array(chunks[0]);
|
|
91
|
+
return new Uint8Array(Buffer.concat(chunks));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Build a single-file UnixFS DAG from `body`, then serialise it
|
|
95
|
+
* as a CAR with the file's root as the sole CAR root. The
|
|
96
|
+
* returned `rootCid` is the canonical IPFS identity for the
|
|
97
|
+
* bytes — pass it through to `FilecoinPutResult.ipfsCid` so the
|
|
98
|
+
* sidecar carries a stable IPFS handle alongside the Filecoin
|
|
99
|
+
* PieceCID.
|
|
100
|
+
*/
|
|
101
|
+
export async function buildCarFromBytes(body) {
|
|
102
|
+
const blockstore = await loadMemoryBlockstore();
|
|
103
|
+
const fs = await loadUnixfs(blockstore);
|
|
104
|
+
const rootCid = await fs.addBytes(body);
|
|
105
|
+
const CarWriter = await loadCarWriter();
|
|
106
|
+
const { writer, out } = CarWriter.create([rootCid]);
|
|
107
|
+
const collected = [];
|
|
108
|
+
const collecting = (async () => {
|
|
109
|
+
for await (const chunk of out)
|
|
110
|
+
collected.push(chunk);
|
|
111
|
+
})();
|
|
112
|
+
try {
|
|
113
|
+
for await (const pair of blockstore.getAll()) {
|
|
114
|
+
const bytes = await flattenBytes(pair.bytes);
|
|
115
|
+
await writer.put({ cid: pair.cid, bytes });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
await writer.close();
|
|
120
|
+
}
|
|
121
|
+
await collecting;
|
|
122
|
+
return { carBytes: Buffer.concat(collected), rootCid };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Inverse of `buildCarFromBytes`: parse `carBytes` into an in-
|
|
126
|
+
* memory blockstore, then walk the UnixFS DAG from `rootCid` to
|
|
127
|
+
* recover the original file bytes. Returns a `Buffer` matching
|
|
128
|
+
* what was originally uploaded.
|
|
129
|
+
*
|
|
130
|
+
* `rootCid` may be passed as either a `multiformats/cid.CID`
|
|
131
|
+
* instance or its canonical string form. We accept the string
|
|
132
|
+
* form so callers that derived the root from `CarReader.getRoots()`
|
|
133
|
+
* (whose CID type lives in `@ipld/car`'s nested `multiformats`,
|
|
134
|
+
* not the top-level one) can interoperate without a manual
|
|
135
|
+
* cross-package cast.
|
|
136
|
+
*/
|
|
137
|
+
export async function extractFileFromCar(carBytes, rootCid) {
|
|
138
|
+
const CarReader = await loadCarReader();
|
|
139
|
+
const reader = await CarReader.fromBytes(carBytes);
|
|
140
|
+
const blockstore = await loadMemoryBlockstore();
|
|
141
|
+
for await (const { cid, bytes } of reader.blocks()) {
|
|
142
|
+
await blockstore.put(cid, bytes);
|
|
143
|
+
}
|
|
144
|
+
// Re-parse the root through the canonical `multiformats/cid`
|
|
145
|
+
// so the unixfs walker receives an instance with the prototype
|
|
146
|
+
// methods the helia/unixfs side expects. Avoids a "method does
|
|
147
|
+
// not exist" runtime failure when callers hand us a CID from
|
|
148
|
+
// `@ipld/car`'s nested multiformats version.
|
|
149
|
+
const canonicalRoot = CID.parse(typeof rootCid === 'string' ? rootCid : rootCid.toString());
|
|
150
|
+
const fs = await loadUnixfs(blockstore);
|
|
151
|
+
const chunks = [];
|
|
152
|
+
for await (const chunk of fs.cat(canonicalRoot))
|
|
153
|
+
chunks.push(chunk);
|
|
154
|
+
return Buffer.concat(chunks);
|
|
155
|
+
}
|