diff --git a/js/package.json b/js/package.json index 71f25b2..3d1592a 100644 --- a/js/package.json +++ b/js/package.json @@ -4,12 +4,12 @@ "private": true, "prettier": "@flarum/prettier-config", "devDependencies": { - "flarum-webpack-config": "^2.0.2", - "flarum-tsconfig": "^1.0.3", "@flarum/prettier-config": "^1.0.0", + "flarum-tsconfig": "^1.0.3", + "flarum-webpack-config": "^2.0.2", + "prettier": "^3.3.3", "webpack": "^5.96.1", - "webpack-cli": "^5.1.4", - "prettier": "^3.3.3" + "webpack-cli": "^5.1.4" }, "scripts": { "dev": "webpack --mode development --watch", diff --git a/js/src/admin/components/S3SettingsPage.tsx b/js/src/admin/components/S3SettingsPage.tsx index 6a6d772..178aa47 100644 --- a/js/src/admin/components/S3SettingsPage.tsx +++ b/js/src/admin/components/S3SettingsPage.tsx @@ -2,7 +2,9 @@ import app from 'flarum/admin/app'; import ExtensionPage from 'flarum/admin/components/ExtensionPage'; import ItemList from 'flarum/common/utils/ItemList'; import Placeholder from 'flarum/common/components/Placeholder'; -import type Mithril from 'mithril'; +import Tooltip from 'flarum/common/components/Tooltip'; +import humanTime from 'flarum/common/utils/humanTime'; +import Mithril from 'mithril'; type AwsRegion = { value: string; @@ -69,6 +71,15 @@ export default class S3SettingsPage extends ExtensionPage { ); + items.add( + 'revManifest', +
+

{app.translator.trans('fof-s3-assets.admin.settings.revision-manifest.heading')}

+

{app.translator.trans('fof-s3-assets.admin.settings.revision-manifest.help')}

+ {this.revManifestItems().toArray()} +
+ ); + return items; } @@ -197,4 +208,41 @@ export default class S3SettingsPage extends ExtensionPage { return items; } + + revManifestItems(): ItemList { + const items = new ItemList(); + + const revManifest = this.setting('s3assets.revision'); + const timestamp = this.setting('s3assets.revision_last_updated'); + + // Parse JSON string into an object before pretty printing + let parsedManifest; + try { + parsedManifest = JSON.parse(revManifest()); + } catch (error) { + console.error('Error parsing JSON:', error); + parsedManifest = { error: 'Invalid JSON format' }; + } + const timestampText = timestamp(); + items.add( + 'revManifest-timestamp', +
+ {app.translator.trans('fof-s3-assets.admin.settings.revision-manifest.timestamp')} +

+ + {humanTime(timestamp())} + +

+
+ ); + + items.add( + 'revManifest-data', +
+
{JSON.stringify(parsedManifest, null, 2)}
+
+ ); + + return items; + } } diff --git a/js/yarn.lock b/js/yarn.lock index 5c98ff6..0496be9 100644 --- a/js/yarn.lock +++ b/js/yarn.lock @@ -1011,11 +1011,11 @@ integrity sha512-uetxoYizBMHPELl6DSZUfO6Q/aOm+h0NUCv9bVAX2iAxfrdBSOvU9KKFl+McTtxR13F+BReYLY814pJsZvnSxg== "@types/node@*": - version "22.9.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.9.1.tgz#bdf91c36e0e7ecfb7257b2d75bf1b206b308ca71" - integrity sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg== + version "22.10.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.1.tgz#41ffeee127b8975a05f8c4f83fb89bcb2987d766" + integrity sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ== dependencies: - undici-types "~6.19.8" + undici-types "~6.20.0" "@types/sizzle@*": version "2.3.9" @@ -1255,9 +1255,9 @@ buffer-from@^1.0.0: integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== caniuse-lite@^1.0.30001669: - version "1.0.30001683" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001683.tgz#7f026a2d5d319a9cf8915a1451173052caaadc81" - integrity sha512-iqmNnThZ0n70mNwvxpEC2nBJ037ZHZUoBI5Gorh1Mw6IlEAZujEoU1tXA628iZfzm7R9FvFzxbfdgml82a3k8Q== + version "1.0.30001685" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001685.tgz#2d10d36c540a9a5d47ad6ab9e1ed5f61fdeadd8c" + integrity sha512-e/kJN1EMyHQzgcMEEgoo+YTCO1NGCmIYHk5Qk8jT6AazWemS5QFKJ5ShCJlH3GZrNIdZofcNCEwZqbMjjKzmnA== chrome-trace-event@^1.0.2: version "1.0.4" @@ -1342,9 +1342,9 @@ duplexer@^0.1.2: integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== electron-to-chromium@^1.5.41: - version "1.5.63" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.63.tgz#69444d592fbbe628d129866c2355691ea93eda3e" - integrity sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA== + version "1.5.67" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.67.tgz#66ebd2be4a77469ac2760ef5e9e460ba9a43a845" + integrity sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ== emojis-list@^3.0.0: version "3.0.0" @@ -1735,9 +1735,9 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: find-up "^4.0.0" prettier@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105" - integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== + version "3.4.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.1.tgz#e211d451d6452db0a291672ca9154bc8c2579f7b" + integrity sha512-G+YdqtITVZmOJje6QkXQWzl3fSfMxFwm1tjTyo9exhkmWSqC4Yhd1+lug++IlR2mvRVAxEDDWYkQdeSztajqgg== punycode@^2.1.0: version "2.3.1" @@ -1783,14 +1783,14 @@ regenerator-transform@^0.15.2: "@babel/runtime" "^7.8.4" regexpu-core@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" - integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== + version "6.2.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.2.0.tgz#0e5190d79e542bf294955dccabae04d3c7d53826" + integrity sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA== dependencies: regenerate "^1.4.2" regenerate-unicode-properties "^10.2.0" regjsgen "^0.8.0" - regjsparser "^0.11.0" + regjsparser "^0.12.0" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" @@ -1799,10 +1799,10 @@ regjsgen@^0.8.0: resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== -regjsparser@^0.11.0: - version "0.11.2" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.2.tgz#7404ad42be00226d72bcf1f003f1f441861913d8" - integrity sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA== +regjsparser@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.12.0.tgz#0e846df6c6530586429377de56e0475583b088dc" + integrity sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ== dependencies: jsesc "~3.0.2" @@ -1951,10 +1951,10 @@ typescript@^4.4.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -undici-types@~6.19.8: - version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" - integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.1" diff --git a/locale/en.yml b/locale/en.yml index e414878..ed3bab0 100644 --- a/locale/en.yml +++ b/locale/en.yml @@ -8,6 +8,12 @@ fof-s3-assets: shareWithFoFUpload: label: Use FoF Upload S3 settings. help: Re-use the S3 settings from the FoF Upload extension. + + revision-manifest: + heading: Revision Manifest + help: Displays the revision manifest status. + timestamp: Last updated + s3: cache-control: label: Cache-Control diff --git a/src/Frontend/Versioner.php b/src/Frontend/Versioner.php index 76cef78..258dfc8 100644 --- a/src/Frontend/Versioner.php +++ b/src/Frontend/Versioner.php @@ -11,6 +11,7 @@ namespace FoF\S3Assets\Frontend; +use Carbon\Carbon; use Flarum\Frontend\Compiler\VersionerInterface; use Flarum\Settings\SettingsRepositoryInterface; use Illuminate\Support\Arr; @@ -18,6 +19,7 @@ class Versioner implements VersionerInterface { const REVISION_KEY = 's3assets.revision'; + const TIMESTAMP_KEY = 's3assets.revision_last_updated'; public function __construct( protected SettingsRepositoryInterface $settings @@ -35,6 +37,7 @@ public function putRevision(string $file, ?string $revision): void } $this->settings->set(self::REVISION_KEY, json_encode($manifest)); + $this->settings->set(self::TIMESTAMP_KEY, Carbon::now()); } public function getRevision(string $file): ?string diff --git a/src/Repository/S3Repository.php b/src/Repository/S3Repository.php index 4401291..c5ec4db 100644 --- a/src/Repository/S3Repository.php +++ b/src/Repository/S3Repository.php @@ -29,7 +29,7 @@ public function __construct( ) { } - public function cdnHost(): string + public function cdnHost(): ?string { return Arr::get($this->config->config(), 'url'); }