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');
}