From c71898e1a0de6f412e59fd66ff2e84bdf4649d17 Mon Sep 17 00:00:00 2001 From: Will Freeman Date: Fri, 13 Feb 2026 11:16:10 -0700 Subject: [PATCH] directus extension for purging CF cache --- cms/.env.example | 2 + cms/docker-compose.yml | 19 +++++++++ cms/extensions/purge-cf-cache/README.md | 3 ++ cms/extensions/purge-cf-cache/package.json | 31 +++++++++++++++ cms/extensions/purge-cf-cache/src/index.js | 46 ++++++++++++++++++++++ 5 files changed, 101 insertions(+) create mode 100644 cms/.env.example create mode 100644 cms/docker-compose.yml create mode 100644 cms/extensions/purge-cf-cache/README.md create mode 100644 cms/extensions/purge-cf-cache/package.json create mode 100644 cms/extensions/purge-cf-cache/src/index.js diff --git a/cms/.env.example b/cms/.env.example new file mode 100644 index 0000000..e9f7e37 --- /dev/null +++ b/cms/.env.example @@ -0,0 +1,2 @@ +CF_API_KEY=your_cloudflare_api_key +CF_ZONE_ID=your_cloudflare_zone_id \ No newline at end of file diff --git a/cms/docker-compose.yml b/cms/docker-compose.yml new file mode 100644 index 0000000..eff9854 --- /dev/null +++ b/cms/docker-compose.yml @@ -0,0 +1,19 @@ +services: + directus: + image: directus/directus:11.5.1 + ports: + - 8055:8055 + volumes: + - ./database:/directus/database + - ./uploads:/directus/uploads + - ./extensions:/directus/extensions + environment: + SECRET: ${DIRECTUS_SECRET} + DB_CLIENT: "sqlite3" + DB_FILENAME: "/directus/database/directus.db" + WEBSOCKETS_ENABLED: "true" + CORS_ENABLED: true + CORS_ORIGIN: true + EXTENSIONS_AUTO_RELOAD: true + CF_API_KEY: ${CF_API_KEY} + CF_ZONE_ID: ${CF_ZONE_ID} \ No newline at end of file diff --git a/cms/extensions/purge-cf-cache/README.md b/cms/extensions/purge-cf-cache/README.md new file mode 100644 index 0000000..a25dcf7 --- /dev/null +++ b/cms/extensions/purge-cf-cache/README.md @@ -0,0 +1,3 @@ +# Purge Cloudflare Cache Directus Extension + +A Directus extension to purge Cloudflare cache when content is updated. This extension listens for content updates and sends a request to the Cloudflare API to clear the cache for the affected URLs. diff --git a/cms/extensions/purge-cf-cache/package.json b/cms/extensions/purge-cf-cache/package.json new file mode 100644 index 0000000..2721cb7 --- /dev/null +++ b/cms/extensions/purge-cf-cache/package.json @@ -0,0 +1,31 @@ +{ + "name": "purge-cf-cache", + "description": "A Directus extension to purge Cloudflare cache", + "icon": "extension", + "version": "1.0.0", + "license": "UNLICENSED", + "keywords": [ + "directus", + "directus-extension", + "directus-extension-hook" + ], + "type": "module", + "files": [ + "dist" + ], + "directus:extension": { + "type": "hook", + "path": "dist/index.js", + "source": "src/index.js", + "host": "^10.10.0" + }, + "scripts": { + "build": "directus-extension build", + "dev": "directus-extension build -w --no-minify", + "link": "directus-extension link", + "validate": "directus-extension validate" + }, + "devDependencies": { + "@directus/extensions-sdk": "^10.1.0" + } +} \ No newline at end of file diff --git a/cms/extensions/purge-cf-cache/src/index.js b/cms/extensions/purge-cf-cache/src/index.js new file mode 100644 index 0000000..9dd2a9c --- /dev/null +++ b/cms/extensions/purge-cf-cache/src/index.js @@ -0,0 +1,46 @@ +export default ({ action }, { env }) => { + const { CF_API_KEY, CF_ZONE_ID } = env; + const creds = { CF_API_KEY, CF_ZONE_ID }; + + action('items.create', async ({ collection, keys }) => { + await purgeCloudflareCache(collection, keys, creds); + }); + + action('items.update', async ({ collection, keys }) => { + await purgeCloudflareCache(collection, keys, creds); + }); + + action('items.delete', async ({ collection, keys }) => { + await purgeCloudflareCache(collection, keys, creds); + }); +}; + +async function purgeCloudflareCache(collectionName, ids, creds) { + const baseUrl = `cms.deflock.me/items/${collectionName}`; + const additionalUrls = ids ? ids.map(id => `${baseUrl}/${id}`) : []; + + console.log(baseUrl); + console.log(additionalUrls); + + const res = await fetch( + `https://api.cloudflare.com/client/v4/zones/${creds.CF_ZONE_ID}/purge_cache`, + { + method: "POST", + headers: { + "Authorization": `Bearer ${creds.CF_API_KEY}`, + "Content-Type": "application/json" + }, + body: JSON.stringify({ + prefixes: [ + baseUrl, + ...additionalUrls + ] + }) + } + ); + + if (res.status >= 200 && res.status < 300) { + console.log(`Cloudflare Cache Purged for updated items in collection: ${collectionName}`); + } else + console.error(res); +}