{"_id":"@bojidar-bg/tina-simple-media-store","_rev":"3-3ce144efbf84ed2f475e22907c21a205","name":"@bojidar-bg/tina-simple-media-store","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@bojidar-bg/tina-simple-media-store","version":"0.1.0","keywords":["tinacms","simple-git"],"author":{"name":"Bojidar Marinov","email":"bojidar.marinov.bg@gmail.com"},"license":"Apache-2.0","_id":"@bojidar-bg/tina-simple-media-store@0.1.0","maintainers":[{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"}],"dist":{"shasum":"0d3463a8fca1b232641fae5db74275a0f5277060","tarball":"https://registry.npmjs.org/@bojidar-bg/tina-simple-media-store/-/tina-simple-media-store-0.1.0.tgz","fileCount":9,"integrity":"sha512-S+W3kNV0TVMwEWLIfg2dJKRngqKsOd5pauM8cvW5zsTj1UDMUBhUwqslSXdwFa3hfx6c2Ou4Ay0Q/WcctVm2bA==","signatures":[{"sig":"MEQCIEW/YZm3rGQIEPTy5czzaNIffOLGRim8UDm2MRSmXducAiABr0ZaZdwYiFDbbXkJwTiT1fTX2VPwK7WSgolF4vsYPA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33826},"main":"dist/index.js","_from":"file:bojidar-bg-tina-simple-media-store-0.1.0.tgz","types":{".":"./dist/index.d.ts","./express":"./dist/express.d.ts"},"exports":{".":"./dist/index.js","./express":"./dist/express.js"},"scripts":{},"_npmUser":{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"},"_resolved":"/tmp/7a9a7790249e4fbea98510953e6f20c2/bojidar-bg-tina-simple-media-store-0.1.0.tgz","_integrity":"sha512-S+W3kNV0TVMwEWLIfg2dJKRngqKsOd5pauM8cvW5zsTj1UDMUBhUwqslSXdwFa3hfx6c2Ou4Ay0Q/WcctVm2bA==","_npmVersion":"10.9.2","description":"An alternative MediaStore for TinaCMS with better support for self-hosted installations.","directories":{},"_nodeVersion":"22.17.0","dependencies":{"busboy":"^1.6.0","express":"^4.21.2","tinacms":"^2.9.0","fs-extra":"^11.3.2"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^24.1.0","@types/busboy":"^1.5.4","@types/express":"^5.0.3","@types/fs-extra":"^11.0.4","@tinacms/datalayer":"^1.4.1"},"_npmOperationalInternal":{"tmp":"tmp/tina-simple-media-store_0.1.0_1760720269321_0.22565959235645616","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bojidar-bg/tina-simple-media-store","version":"0.1.1","keywords":["tinacms"],"author":{"name":"Bojidar Marinov","email":"bojidar.marinov.bg@gmail.com"},"license":"Apache-2.0","_id":"@bojidar-bg/tina-simple-media-store@0.1.1","maintainers":[{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"}],"dist":{"shasum":"552949bdb938a5ffca2e65c4b2c5863ed8a594ef","tarball":"https://registry.npmjs.org/@bojidar-bg/tina-simple-media-store/-/tina-simple-media-store-0.1.1.tgz","fileCount":9,"integrity":"sha512-k+sSyoUqoJvKp5xTu6ZYKyH9YP1TltkEaZlH+YHGBIKcFBBlKZVBcpvoZ84dsr1DbNbumkOaWvcc4wGKnNIjTw==","signatures":[{"sig":"MEUCIQCVtfLYVDpINHHfN9NP+6g/3HIUzE+gAQWrFqoR+8A/aAIgZQucxobw/Df/cUT7Z40SsMZkM9pJ+oPknMWTcS9+a6c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34996},"main":"dist/index.js","_from":"file:bojidar-bg-tina-simple-media-store-0.1.1.tgz","types":{".":"./dist/index.d.ts","./express":"./dist/express.d.ts"},"exports":{".":"./dist/index.js","./express":"./dist/express.js"},"scripts":{},"_npmUser":{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"},"_resolved":"/tmp/5138b5d807cffa3b7a3f8b72e236fc77/bojidar-bg-tina-simple-media-store-0.1.1.tgz","_integrity":"sha512-k+sSyoUqoJvKp5xTu6ZYKyH9YP1TltkEaZlH+YHGBIKcFBBlKZVBcpvoZ84dsr1DbNbumkOaWvcc4wGKnNIjTw==","_npmVersion":"10.9.2","description":"An alternative MediaStore for TinaCMS with better support for self-hosted installations.","directories":{},"_nodeVersion":"22.17.0","dependencies":{"busboy":"^1.6.0","express":"^4.21.2","tinacms":"^2.9.0","fs-extra":"^11.3.2"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^24.1.0","@types/busboy":"^1.5.4","@types/express":"^5.0.3","@types/fs-extra":"^11.0.4","@tinacms/datalayer":"^1.4.1"},"_npmOperationalInternal":{"tmp":"tmp/tina-simple-media-store_0.1.1_1761140211573_0.9343482416914946","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bojidar-bg/tina-simple-media-store","version":"0.1.2","description":"An alternative MediaStore for TinaCMS with better support for self-hosted installations.","author":{"name":"Bojidar Marinov","email":"bojidar.marinov.bg@gmail.com"},"license":"Apache-2.0","main":"dist/index.js","keywords":["tinacms"],"dependencies":{"busboy":"^1.6.0","express":"^4.21.2","fs-extra":"^11.3.2","tinacms":"^2.9.0"},"devDependencies":{"@tinacms/datalayer":"^1.4.1","@types/busboy":"^1.5.4","@types/express":"^5.0.3","@types/fs-extra":"^11.0.4","@types/node":"^24.1.0"},"exports":{".":"./dist/index.js","./express":"./dist/express.js"},"types":{".":"./dist/index.d.ts","./express":"./dist/express.d.ts"},"scripts":{},"_id":"@bojidar-bg/tina-simple-media-store@0.1.2","_integrity":"sha512-D/T5R6Wq6Ov/xq3R/xznpPVjQQZI/WvJaTq38jrHfySI8bcvJ6rp3Tm1aSZmx5mFYGktouUvVVarNDSvbUD6IA==","_resolved":"/tmp/c1689234e14edd1f9a28fa6c539038f4/bojidar-bg-tina-simple-media-store-0.1.2.tgz","_from":"file:bojidar-bg-tina-simple-media-store-0.1.2.tgz","_nodeVersion":"22.17.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-D/T5R6Wq6Ov/xq3R/xznpPVjQQZI/WvJaTq38jrHfySI8bcvJ6rp3Tm1aSZmx5mFYGktouUvVVarNDSvbUD6IA==","shasum":"b1d94c141a982228b286e78463ca9a66299ddfa5","tarball":"https://registry.npmjs.org/@bojidar-bg/tina-simple-media-store/-/tina-simple-media-store-0.1.2.tgz","fileCount":9,"unpackedSize":34996,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG7q74FgqoCqoF3kq1zre55mGhY8JiGRMpyslmcFNsfjAiBuvQLeBojGxrCFthPPdPlZ3NXYYqqXPQDRh15msE1KNQ=="}]},"_npmUser":{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"},"directories":{},"maintainers":[{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/tina-simple-media-store_0.1.2_1763491474219_0.7571050506862314"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-17T16:57:49.260Z","modified":"2025-11-18T18:44:34.662Z","0.1.0":"2025-10-17T16:57:49.516Z","0.1.1":"2025-10-22T13:36:51.761Z","0.1.2":"2025-11-18T18:44:34.455Z"},"author":{"name":"Bojidar Marinov","email":"bojidar.marinov.bg@gmail.com"},"license":"Apache-2.0","keywords":["tinacms"],"description":"An alternative MediaStore for TinaCMS with better support for self-hosted installations.","maintainers":[{"name":"bojidar-bg","email":"bojidar.marinov.bg@gmail.com"}],"readme":"# A cooler media store for TinaCMS\n\nSo.. we've all been there. You read that TinaCMS offers you [Repo-based Media storage](https://tina.io/docs/reference/media/repo-based)... however, when you look at [the issue list](https://github.com/tinacms/tinacms/issues/4486), you find out that, mysteriously, \"repo-stored media isn't currently supported when self-hosting\". What a pity!\n\nWell, `SimpleMediaStore` comes to the rescue, by implementing a TinaCMS-compatible MediaStore on top of a local folder, somewhere, anywhere you want, with optional integration for [`@bojidar-bg/tina-simple-git-provider`](https://www.npmjs.com/package/@bojidar-bg/tina-simple-git-provider)!\n\n(The need for this package would go away the moment Tina's built-in `MediaStore` starts supporting a custom URL for the media API and Tina's built-in media store backend is decoupled from the CLI.)\n\n## Usage\n\nTo use this media store in your [TinaCMS application](https://tina.io/docs/reference/), you need to do two things:\n1. Include the client-side part of the media store in your config.\n2. Import and configure the server-side part of the media store in your handlers.\n\n### Client-side part\n\nModify your TinaCMS `config.ts` like so:\n\n```ts\nimport { defineConfig } from \"tinacms\";\n// import type { SimpleMediaStoreConfig } from \"@bojidar-bg/tina-simple-media-store\";\n\nexport default defineConfig({\n  // ... Other config options\n  media: {\n    loadCustomStore: async () => (await import(\"@bojidar-bg/tina-simple-media-store\")).SimpleMediaStore,    \n  },\n  mediaStoreOptions: {\n    /// The URL to the media API backend.\n    mediaApiUrl: \"/api/media\",\n    // mediaApiUrl: \"https://my-tina-api.my-site.example/api/media\",\n    \n    /// The file path from the root of your website's repository to where media files can be found\n    mediaRoot: \"/\",\n    \n    /// Web address under which media thumbnails can be accessed\n    thumbnailBasePath: \"\" // Defaults to config.build.basePath\n    \n    /// An image `img.png` uploaded in folder `dir`, would be referenced as `/mediaRoot/dir/img.png` in the Tina editor, and displayed as a thumbnail from `/thumbnailBasePath/mediaRoot/dir/img.png`\n  },\n});\n```\n\n### Server-side part / backend API\n\nThe server-side handler, `SimpleMediaHandler`, expects to be registered under `/api/media` using Express.js, before TinaCMS's `TinaNodeBackend` gets registered.\nIf you have a setup similar to the [tina-true-selfhosted-example](https://github.com/bojidar-bg/tina-true-selfhosted-example), you can modify your `tina/handler.ts` to include the `SimpleMediaHandler` like so:\n\n```ts\nimport { TinaNodeBackend } from '@tinacms/datalayer'\nimport { SimpleMediaHandler } from '@bojidar-bg/tina-simple-media-store/express'\n\nimport { config } from './config'\n// import { gitProvider } from './database' // For the SimpleGitProvider integration\nimport databaseClient from './__generated__/databaseClient'\n\nlet authProvider = ... // Your Tina AuthProvider\n\nconst tinaHandler = TinaNodeBackend({\n  authProvider,\n  databaseClient,\n  options: {\n    basePath: '/tina/',\n    // ...\n  }\n})\n\nconst mediaHandler = SimpleMediaHandler({\n  authProvider, // An AuthProvider for authenticating media API usage\n  paths: {\n    // Paths to control where media files should be stored\n    rootPath: \"/path-to-a-repository-checkout-for-git-backed-media\",\n    // rootPath: gitProvider.options.repoDir // For the SimpleGitProvider integration\n    publicFolder: config.build.publicFolder,\n    mediaRoot: config.mediaStoreOptions?.mediaRoot ?? '',\n    // Media will be stored in ${rootPath}/${publicFolder}/${mediaRoot}\n    // You should ensure it's accessible over HTTP at /${mediaRoot} on your website\n  },\n  // onModifyFile: gitProvider.makeCommit // For the SimpleGitProvider integration\n  onModifyFile: (path) => {console.log(`Media file modified: ${path}`)},\n})\n\n// ...elsewhere, to link it all in express\n\nimport express from \"express\"\nimport cookieParser from \"cookie-parser\"\n\nexport default function createApp() {\n  let app = express()\n  app.use(cookieParser())\n  app.use(express.json())\n  app.use(express.urlencoded({ extended: true }))\n  \n  // Important: Include the SimpleMediaHandler before Tina's NodeBackend\n  app.use('/api/media/', mediaHandler)\n  app.use('/api/', tinaHandler)\n  \n  return app\n};\n```\n\nCurrently, there is no Next.js implementation of the `SimpleMediaHandler`--you might be able to integrate the Express.js code with your Next.js application, but the author of this package has not used Next.js enough to know exactly how. Contributions and examples welcome!\n\n## Credits\n\nThis package was initially created as part of [tina-true-selfhosted-example](https://github.com/bojidar-bg/tina-true-selfhosted-example).\n\nMost of the code for this package came directly [from the `@tinacms/cli` package](https://github.com/tinacms/tinacms/blob/455a033104100ef627871606bd59b7c6b3d9d016/packages/%40tinacms/cli/src/next/commands/dev-command/server/media.ts).\n","readmeFilename":"README.md"}