From 14ddf562a3ab3005849bc8f1dc045c59a1bcde6d Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 30 Sep 2025 08:11:58 -0400 Subject: [PATCH 1/7] feat: allow overriding withCDN via env-var --- README.md | 3 ++- src/common/env-vars.ts | 11 +++++++++++ src/synapse/service.ts | 3 ++- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/common/env-vars.ts diff --git a/README.md b/README.md index c484921..c4ce187 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ PORT=3456 # Daemon port DATABASE_PATH=./pins.db # SQLite database CAR_STORAGE_PATH=./cars # CAR file directory LOG_LEVEL=info # Logging level +WITH_CDN=true # Enable/Disable CDN for content uploads ``` ### Default Directories @@ -193,4 +194,4 @@ Dual-licensed under [MIT](LICENSE-MIT) + [Apache 2.0](LICENSE-APACHE) - [IPFS Pinning Service API](https://ipfs.github.io/pinning-services-api-spec/) - [Synapse SDK](https://github.com/filecoin-project/synapse-sdk) -- [USDFC Documentation](https://docs.secured.finance/usdfc-stablecoin) \ No newline at end of file +- [USDFC Documentation](https://docs.secured.finance/usdfc-stablecoin) diff --git a/src/common/env-vars.ts b/src/common/env-vars.ts new file mode 100644 index 0000000..1f55a71 --- /dev/null +++ b/src/common/env-vars.ts @@ -0,0 +1,11 @@ +/** + * Generic helpers for environment variable parsing and validation. + */ + +export const envToBool = (value: string | undefined, defaultValue: boolean): boolean => { + if (value === undefined) return defaultValue + const normalized = value.trim().toLowerCase() + if (['1', 'true', 'yes', 'on'].includes(normalized)) return true + if (['0', 'false', 'no', 'off'].includes(normalized)) return false + return defaultValue +} diff --git a/src/synapse/service.ts b/src/synapse/service.ts index de52907..5ad55e8 100644 --- a/src/synapse/service.ts +++ b/src/synapse/service.ts @@ -9,6 +9,7 @@ import { } from '@filoz/synapse-sdk' import type { Logger } from 'pino' import type { Config } from '../config.js' +import { envToBool } from '../common/env-vars.js' /** * Default metadata for Synapse data sets created by filecoin-pin @@ -22,7 +23,7 @@ const DEFAULT_DATA_SET_METADATA = { * Default configuration for creating storage contexts */ const DEFAULT_STORAGE_CONTEXT_CONFIG = { - withCDN: false, // CDN not needed for Filecoin Pin currently + withCDN: envToBool(process.env.WITH_CDN, false), metadata: DEFAULT_DATA_SET_METADATA, } as const From 0b82e200ebcc9838ca372f2276bd31c3707f31c5 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 30 Sep 2025 08:12:36 -0400 Subject: [PATCH 2/7] chore: fix lint --- src/synapse/service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/synapse/service.ts b/src/synapse/service.ts index 5ad55e8..ba25ded 100644 --- a/src/synapse/service.ts +++ b/src/synapse/service.ts @@ -8,8 +8,8 @@ import { type SynapseOptions, } from '@filoz/synapse-sdk' import type { Logger } from 'pino' -import type { Config } from '../config.js' import { envToBool } from '../common/env-vars.js' +import type { Config } from '../config.js' /** * Default metadata for Synapse data sets created by filecoin-pin From e37c582b31f60d85a1424f8ab31036fefafb487c Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 30 Sep 2025 08:17:37 -0400 Subject: [PATCH 3/7] docs: indicate default value for WITH_CDN --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4ce187..f2c4c3c 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ PORT=3456 # Daemon port DATABASE_PATH=./pins.db # SQLite database CAR_STORAGE_PATH=./cars # CAR file directory LOG_LEVEL=info # Logging level -WITH_CDN=true # Enable/Disable CDN for content uploads +WITH_CDN=true # Enable/Disable CDN for content uploads (default: false) ``` ### Default Directories From e687b57396b956a3796349ae716b5cd2fc36d8ed Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:18:54 -0400 Subject: [PATCH 4/7] fix: Warn users when enabling WITH_CDN --- src/add/add.ts | 13 +++++++++++++ src/common/cdn-warning.ts | 28 ++++++++++++++++++++++++++++ src/import/import.ts | 13 +++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/common/cdn-warning.ts diff --git a/src/add/add.ts b/src/add/add.ts index 1d4f307..6074d87 100644 --- a/src/add/add.ts +++ b/src/add/add.ts @@ -9,6 +9,8 @@ import { readFile, stat } from 'node:fs/promises' import { RPC_URLS } from '@filoz/synapse-sdk' import pc from 'picocolors' import pino from 'pino' +import { warnAboutCDNPricingLimitations } from '../common/cdn-warning.js' +import { envToBool } from '../common/env-vars.js' import { displayUploadResults, performUpload, validatePaymentSetup } from '../common/upload-flow.js' import { cleanupSynapseService, @@ -71,6 +73,17 @@ export async function runAdd(options: AddOptions): Promise { level: process.env.LOG_LEVEL || 'error', }) + // Check CDN status and warn if enabled + const withCDN = envToBool(process.env.WITH_CDN, false) + if (withCDN) { + const proceed = await warnAboutCDNPricingLimitations() + if (!proceed) { + cancel('Add cancelled') + process.exitCode = 1 + throw new Error('CDN pricing limitations warning cancelled') + } + } + let tempCarPath: string | undefined try { diff --git a/src/common/cdn-warning.ts b/src/common/cdn-warning.ts new file mode 100644 index 0000000..0a803dc --- /dev/null +++ b/src/common/cdn-warning.ts @@ -0,0 +1,28 @@ +import { cancel, confirm } from '@clack/prompts' +import pc from 'picocolors' +import { log } from '../utils/cli-logger.js' + +export async function warnAboutCDNPricingLimitations(): Promise { + log.warn(pc.red('CDN Pricing Notice')) + log.newline() + log.line('Filecoin-pin currently does not support CDN pricing in payment calculations.') + log.newline() + log.line('This means:') + log.indent('• Deposit calculations may not be accurate for CDN storage') + log.indent('• You may need additional USDFC deposits for CDN-enabled uploads') + log.indent('• Filcdn is transitioning to egress-based billing (from fixed fees)') + log.newline() + log.flush() + + const shouldProceed = await confirm({ + message: 'Do you want to proceed with CDN-enabled upload?', + initialValue: false, + }) + + if (shouldProceed === null) { + cancel('Operation cancelled') + process.exitCode = 1 + } + + return Boolean(shouldProceed) +} diff --git a/src/import/import.ts b/src/import/import.ts index d3e5c59..0c78299 100644 --- a/src/import/import.ts +++ b/src/import/import.ts @@ -12,6 +12,8 @@ import { CarReader } from '@ipld/car' import { CID } from 'multiformats/cid' import pc from 'picocolors' import pino from 'pino' +import { warnAboutCDNPricingLimitations } from '../common/cdn-warning.js' +import { envToBool } from '../common/env-vars.js' import { displayUploadResults, performUpload, validatePaymentSetup } from '../common/upload-flow.js' import { cleanupSynapseService, @@ -130,6 +132,17 @@ export async function runCarImport(options: ImportOptions): Promise Date: Fri, 10 Oct 2025 07:08:23 -0400 Subject: [PATCH 5/7] docs: update readme Co-authored-by: Rod Vagg --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index f2c4c3c..0db8067 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,6 @@ PORT=3456 # Daemon port DATABASE_PATH=./pins.db # SQLite database CAR_STORAGE_PATH=./cars # CAR file directory LOG_LEVEL=info # Logging level -WITH_CDN=true # Enable/Disable CDN for content uploads (default: false) ``` ### Default Directories From 2351d1b9cb567f17696ffcfdc5bc1e176d0e5e0c Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Fri, 17 Oct 2025 08:10:35 -0400 Subject: [PATCH 6/7] chore: fix bad merge --- README.md | 8 +- src/synapse/service.ts | 387 ----------------------------------------- 2 files changed, 4 insertions(+), 391 deletions(-) delete mode 100644 src/synapse/service.ts diff --git a/README.md b/README.md index 228066e..b0446b7 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Filecoin Pin offers multiple affordances to integrate Filecoin storage into your Upload IPFS files directly to Filecoin via the command line. Perfect for developers who want to integrate Filecoin storage into scripts, workflows, or local development environments. - **Repository**: This repo ([filecoin-project/filecoin-pin](https://github.com/filecoin-project/filecoin-pin)) -- **Documentation**: +- **Documentation**: - Run `filecoin-pin --help` to see all available commands and options. - [CLI Walkthrough](https://docs.filecoin.io/builder-cookbook/filecoin-pin/filecoin-pin-cli) - **Installation**: `npm install -g filecoin-pin` @@ -43,7 +43,7 @@ Upload IPFS files directly to Filecoin via the command line. Perfect for develop Automatically publish websites or build artifacts to IPFS and Filecoin as part of your CI/CD pipeline. Ideal for static websites, documentation sites, and automated deployment workflows. - **Repository**: This repo ([see upload-action/](./upload-action)) -- **Documentation**: +- **Documentation**: - [GitHub Action Walkthrough](https://docs.filecoin.io/builder-cookbook/filecoin-pin/github-action) - **Example in Production**: [filecoin-pin-website CI pipeline](https://github.com/filecoin-project/filecoin-pin-website/tree/main/.github/workflows) @@ -59,13 +59,13 @@ Run a localhost IPFS Pinning Service API server that implements the [IPFS Pinnin - **Repository**: This repo (`filecoin-pin server` command in CLI) - **Usage**: `PRIVATE_KEY=0x... npx filecoin-pin server` -- **Status**: Works and is tested, but hasn't received as many features as the CLI. If it would benefit your usecase, please comment on [tracking issue](https://github.com/filecoin-project/filecoin-pin/issues/46) so we can be better informed when it comes to prioritizing. +- **Status**: Works and is tested, but hasn't received as many features as the CLI. If it would benefit your usecase, please comment on [tracking issue](https://github.com/filecoin-project/filecoin-pin/issues/46) so we can be better informed when it comes to prioritizing. ### Management Console GUI Web-based management console for monitoring and managing your Filecoin Pin deployments. This is effectively a Web UI equivalent to the [CLI](#cli). - **Status**: Planned -- **Tracking**: See [issue #74](https://github.com/filecoin-project/filecoin-pin/issues/74) for updates. Please leave a comment about your usecase if this would be particularly beneficial. +- **Tracking**: See [issue #74](https://github.com/filecoin-project/filecoin-pin/issues/74) for updates. Please leave a comment about your usecase if this would be particularly beneficial. ## Examples in Production diff --git a/src/synapse/service.ts b/src/synapse/service.ts deleted file mode 100644 index ba25ded..0000000 --- a/src/synapse/service.ts +++ /dev/null @@ -1,387 +0,0 @@ -import { - METADATA_KEYS, - type ProviderInfo, - RPC_URLS, - type StorageContext, - type StorageServiceOptions, - Synapse, - type SynapseOptions, -} from '@filoz/synapse-sdk' -import type { Logger } from 'pino' -import { envToBool } from '../common/env-vars.js' -import type { Config } from '../config.js' - -/** - * Default metadata for Synapse data sets created by filecoin-pin - */ -const DEFAULT_DATA_SET_METADATA = { - [METADATA_KEYS.WITH_IPFS_INDEXING]: '', // Enable IPFS indexing for all data sets - source: 'filecoin-pin', // Identify the source application -} as const - -/** - * Default configuration for creating storage contexts - */ -const DEFAULT_STORAGE_CONTEXT_CONFIG = { - withCDN: envToBool(process.env.WITH_CDN, false), - metadata: DEFAULT_DATA_SET_METADATA, -} as const - -let synapseInstance: Synapse | null = null -let storageInstance: StorageContext | null = null -let currentProviderInfo: ProviderInfo | null = null -let activeProvider: any = null // Track the provider for cleanup - -/** - * Reset the service instances (for testing) - */ -export function resetSynapseService(): void { - synapseInstance = null - storageInstance = null - currentProviderInfo = null - activeProvider = null -} - -export interface SynapseService { - synapse: Synapse - storage: StorageContext - providerInfo: ProviderInfo -} - -/** - * Initialize the Synapse SDK without creating storage context - * - * This function initializes the Synapse SDK connection without creating - * a storage context. This method is primarily a wrapper for handling our - * custom configuration needs and adding detailed logging. - * - * @param config - Application configuration with privateKey and RPC URL - * @param logger - Logger instance for detailed operation tracking - * @returns Initialized Synapse instance - */ -export async function initializeSynapse(config: Config, logger: Logger): Promise { - try { - // Log the configuration status - logger.info( - { - hasPrivateKey: config.privateKey != null, - rpcUrl: config.rpcUrl, - }, - 'Initializing Synapse' - ) - - // IMPORTANT: Private key is required for transaction signing - // In production, this should come from secure environment variables, or a wallet integration - if (config.privateKey == null) { - const error = new Error('PRIVATE_KEY environment variable is required for Synapse integration') - logger.error( - { - event: 'synapse.init.failed', - error: error.message, - }, - 'Synapse initialization failed: missing PRIVATE_KEY' - ) - throw error - } - logger.info({ event: 'synapse.init' }, 'Initializing Synapse SDK') - - // Configure Synapse with network settings - // Network options: 314 (mainnet) or 314159 (calibration testnet) - const synapseOptions: SynapseOptions = { - privateKey: config.privateKey, - rpcURL: config.rpcUrl ?? RPC_URLS.calibration.websocket, // Default to calibration testnet - } - - // Optional: Override the default Warm Storage contract address - // Useful for testing with custom deployments - if (config.warmStorageAddress != null) { - synapseOptions.warmStorageAddress = config.warmStorageAddress - } - - const synapse = await Synapse.create(synapseOptions) - - // Store reference to the provider for cleanup if it's a WebSocket provider - if (synapseOptions.rpcURL && /^ws(s)?:\/\//i.test(synapseOptions.rpcURL)) { - activeProvider = synapse.getProvider() - } - - // Get network info for logging - const network = synapse.getNetwork() - logger.info( - { - event: 'synapse.init', - network, - rpcUrl: synapseOptions.rpcURL, - }, - 'Synapse SDK initialized' - ) - - // Store instance for cleanup - synapseInstance = synapse - - return synapse - } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) - logger.error( - { - event: 'synapse.init.failed', - error: errorMessage, - }, - `Failed to initialize Synapse SDK: ${errorMessage}` - ) - throw error - } -} - -/** - * Create storage context for an initialized Synapse instance - * - * This creates a storage context with comprehensive callbacks for tracking - * the data set creation and provider selection process. This is primarily - * a wrapper around the Synapse SDK's storage context creation, adding logging - * and progress callbacks for better observability. - * - * @param synapse - Initialized Synapse instance - * @param logger - Logger instance for detailed operation tracking - * @param progressCallbacks - Optional callbacks for progress tracking - * @returns Storage context and provider information - */ -export async function createStorageContext( - synapse: Synapse, - logger: Logger, - progressCallbacks?: { - onProviderSelected?: (provider: any) => void - onDataSetCreationStarted?: (transaction: any) => void - onDataSetResolved?: (info: { dataSetId: number; isExisting: boolean }) => void - } -): Promise<{ storage: StorageContext; providerInfo: ProviderInfo }> { - try { - // Create storage context with comprehensive event tracking - // The storage context manages the data set and provider interactions - logger.info({ event: 'synapse.storage.create' }, 'Creating storage context') - - // Optional override: allow selecting a specific provider via env vars - const envProviderAddress = process.env.PROVIDER_ADDRESS?.trim() - const envProviderIdRaw = process.env.PROVIDER_ID?.trim() - const envProviderId = envProviderIdRaw != null && envProviderIdRaw !== '' ? Number(envProviderIdRaw) : undefined - - const createOptions: StorageServiceOptions = { - ...DEFAULT_STORAGE_CONTEXT_CONFIG, - // Callbacks provide visibility into the storage lifecycle - // These are crucial for debugging and monitoring in production - callbacks: { - onProviderSelected: (provider) => { - // Store the provider info for later use - currentProviderInfo = provider - - logger.info( - { - event: 'synapse.storage.provider_selected', - provider: { - id: provider.id, - serviceProvider: provider.serviceProvider, - name: provider.name, - serviceURL: provider.products?.PDP?.data?.serviceURL, - }, - }, - 'Selected storage provider' - ) - - // Call progress callback if provided - if (progressCallbacks?.onProviderSelected) { - progressCallbacks.onProviderSelected(provider) - } - }, - onDataSetResolved: (info) => { - logger.info( - { - event: 'synapse.storage.data_set_resolved', - dataSetId: info.dataSetId, - isExisting: info.isExisting, - }, - info.isExisting ? 'Using existing data set' : 'Created new data set' - ) - - // Call progress callback if provided - if (progressCallbacks?.onDataSetResolved) { - progressCallbacks.onDataSetResolved(info) - } - }, - onDataSetCreationStarted: (transaction, statusUrl) => { - logger.info( - { - event: 'synapse.storage.data_set_creation_started', - txHash: transaction.hash, - statusUrl, - }, - 'Data set creation transaction submitted' - ) - - // Call progress callback if provided - if (progressCallbacks?.onDataSetCreationStarted) { - progressCallbacks.onDataSetCreationStarted(transaction) - } - }, - onDataSetCreationProgress: (status) => { - logger.info( - { - event: 'synapse.storage.data_set_creation_progress', - transactionMined: status.transactionMined, - dataSetLive: status.dataSetLive, - elapsedMs: status.elapsedMs, - }, - 'Data set creation progress' - ) - }, - }, - } - - // Apply provider override if present - if (envProviderAddress) { - createOptions.providerAddress = envProviderAddress - logger.info( - { event: 'synapse.storage.provider_override', by: 'env', providerAddress: envProviderAddress }, - 'Overriding provider via PROVIDER_ADDRESS' - ) - } else if (envProviderId != null && Number.isFinite(envProviderId)) { - createOptions.providerId = envProviderId - logger.info( - { event: 'synapse.storage.provider_override', by: 'env', providerId: envProviderId }, - 'Overriding provider via PROVIDER_ID' - ) - } - - const storage = await synapse.storage.createContext(createOptions) - - logger.info( - { - event: 'synapse.storage.created', - dataSetId: storage.dataSetId, - serviceProvider: storage.serviceProvider, - }, - 'Storage context created successfully' - ) - - // Store instance - storageInstance = storage - - // Ensure we always have provider info - if (!currentProviderInfo) { - // This should not happen as provider is selected during context creation - throw new Error('Provider information not available after storage context creation') - } - - return { storage, providerInfo: currentProviderInfo } - } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error) - logger.error( - { - event: 'synapse.storage.create.failed', - error: errorMessage, - }, - `Failed to create storage context: ${errorMessage}` - ) - throw error - } -} - -/** - * Set up complete Synapse service with SDK and storage context - * - * This function demonstrates the complete setup flow for Synapse: - * 1. Validates required configuration (private key) - * 2. Creates Synapse instance with network configuration - * 3. Creates a storage context with comprehensive callbacks - * 4. Returns a service object for application use - * - * Our wrapping of Synapse initialization and storage context creation is - * primarily to handle our custom configuration needs and add detailed logging - * and progress tracking. - * - * @param config - Application configuration with privateKey and RPC URL - * @param logger - Logger instance for detailed operation tracking - * @param progressCallbacks - Optional callbacks for progress tracking - * @returns SynapseService with initialized Synapse and storage context - */ -export async function setupSynapse( - config: Config, - logger: Logger, - progressCallbacks?: { - onProviderSelected?: (provider: any) => void - onDataSetCreationStarted?: (transaction: any) => void - onDataSetResolved?: (info: { dataSetId: number; isExisting: boolean }) => void - } -): Promise { - // Initialize SDK - const synapse = await initializeSynapse(config, logger) - - // Create storage context - const { storage, providerInfo } = await createStorageContext(synapse, logger, progressCallbacks) - - return { synapse, storage, providerInfo } -} - -/** - * Get default storage context configuration for consistent data set creation - * - * @param overrides - Optional overrides to merge with defaults - * @returns Storage context configuration with defaults - */ -export function getDefaultStorageContextConfig(overrides: any = {}) { - return { - ...DEFAULT_STORAGE_CONTEXT_CONFIG, - ...overrides, - metadata: { - ...DEFAULT_DATA_SET_METADATA, - ...overrides.metadata, - }, - } -} - -/** - * Clean up a WebSocket provider connection. - * This is important for allowing the Node.js process to exit cleanly. - * - * @param provider - The provider to clean up - */ -export async function cleanupProvider(provider: any): Promise { - if (provider && typeof provider.destroy === 'function') { - try { - await provider.destroy() - } catch { - // Ignore cleanup errors - } - } -} - -/** - * Clean up WebSocket providers and other resources - * - * Call this when CLI commands are finishing to ensure proper cleanup - * and allow the process to terminate. - */ -export async function cleanupSynapseService(): Promise { - if (activeProvider) { - await cleanupProvider(activeProvider) - } - - // Clear references - synapseInstance = null - storageInstance = null - currentProviderInfo = null - activeProvider = null -} - -/** - * Get the initialized Synapse service - */ -export function getSynapseService(): SynapseService | null { - if (synapseInstance == null || storageInstance == null || currentProviderInfo == null) { - return null - } - return { - synapse: synapseInstance, - storage: storageInstance, - providerInfo: currentProviderInfo, - } -} From 5e25fd085eb0a9fb1ac34ea42f068b2a9d56e971 Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Fri, 17 Oct 2025 08:12:21 -0400 Subject: [PATCH 7/7] chore: remove envToBool --- src/add/add.ts | 3 +-- src/common/env-vars.ts | 11 ----------- src/import/import.ts | 3 +-- 3 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 src/common/env-vars.ts diff --git a/src/add/add.ts b/src/add/add.ts index ce56866..c325ea1 100644 --- a/src/add/add.ts +++ b/src/add/add.ts @@ -9,7 +9,6 @@ import { readFile, stat } from 'node:fs/promises' import pc from 'picocolors' import pino from 'pino' import { warnAboutCDNPricingLimitations } from '../common/cdn-warning.js' -import { envToBool } from '../common/env-vars.js' import { displayUploadResults, performAutoFunding, performUpload, validatePaymentSetup } from '../common/upload-flow.js' import { cleanupSynapseService, @@ -74,7 +73,7 @@ export async function runAdd(options: AddOptions): Promise { }) // Check CDN status and warn if enabled - const withCDN = envToBool(process.env.WITH_CDN, false) + const withCDN = process.env.WITH_CDN === 'true' if (withCDN) { const proceed = await warnAboutCDNPricingLimitations() if (!proceed) { diff --git a/src/common/env-vars.ts b/src/common/env-vars.ts deleted file mode 100644 index 1f55a71..0000000 --- a/src/common/env-vars.ts +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Generic helpers for environment variable parsing and validation. - */ - -export const envToBool = (value: string | undefined, defaultValue: boolean): boolean => { - if (value === undefined) return defaultValue - const normalized = value.trim().toLowerCase() - if (['1', 'true', 'yes', 'on'].includes(normalized)) return true - if (['0', 'false', 'no', 'off'].includes(normalized)) return false - return defaultValue -} diff --git a/src/import/import.ts b/src/import/import.ts index 22352ce..7dd134f 100644 --- a/src/import/import.ts +++ b/src/import/import.ts @@ -12,7 +12,6 @@ import { CID } from 'multiformats/cid' import pc from 'picocolors' import pino from 'pino' import { warnAboutCDNPricingLimitations } from '../common/cdn-warning.js' -import { envToBool } from '../common/env-vars.js' import { displayUploadResults, performAutoFunding, performUpload, validatePaymentSetup } from '../common/upload-flow.js' import { cleanupSynapseService, @@ -133,7 +132,7 @@ export async function runCarImport(options: ImportOptions): Promise