feat: add S3-compatible storage provider (MinIO, Ceph, R2, etc.)
Adds a new 'S3-Compatible Storage' provider that works with any
S3-API-compatible object storage service, including MinIO, Ceph,
Cloudflare R2, Backblaze B2, and others.
Changes:
- New provider class: classes/providers/storage/s3-compatible-provider.php
- Provider key: s3compatible
- Reads user-configured endpoint URL from settings
- Uses path-style URL access (required by most S3-compatible services)
- Supports credentials via AS3CF_S3COMPAT_ACCESS_KEY_ID /
AS3CF_S3COMPAT_SECRET_ACCESS_KEY wp-config.php constants
- Disables AWS-specific features (Block Public Access, Object Ownership)
- New provider SVG icons (s3compatible.svg, -link.svg, -round.svg)
- Registered provider in main plugin class with endpoint setting support
- Updated StorageProviderSubPage to show endpoint URL input for S3-compatible
- Built pro settings bundle with rollup (Svelte 4.2.19)
- Added package.json and updated rollup.config.mjs for pro-only builds
This commit is contained in:
117
ui/js/routes.js
Normal file
117
ui/js/routes.js
Normal file
@@ -0,0 +1,117 @@
|
||||
import {derived, writable, get} from "svelte/store";
|
||||
import {wrap} from "svelte-spa-router/wrap";
|
||||
|
||||
/**
|
||||
* Creates store of default pages.
|
||||
*
|
||||
* Having a title means inclusion in main tabs.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
function createPages() {
|
||||
// NOTE: get() only resolves after initialization, hence arrow functions for getting titles.
|
||||
const { subscribe, set, update } = writable( [] );
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set,
|
||||
add( page ) {
|
||||
update( $pages => {
|
||||
return [...$pages, page]
|
||||
.sort( ( a, b ) => {
|
||||
return a.position - b.position;
|
||||
} );
|
||||
} );
|
||||
},
|
||||
withPrefix( prefix = null ) {
|
||||
return get( this ).filter( ( page ) => {
|
||||
return (prefix && page.route.startsWith( prefix )) || !prefix;
|
||||
} );
|
||||
},
|
||||
routes( prefix = null ) {
|
||||
let defaultComponent = null;
|
||||
let defaultUserData = null;
|
||||
const routes = new Map();
|
||||
|
||||
// If a page can be enabled/disabled, check whether it is enabled before displaying.
|
||||
const conditions = [
|
||||
( detail ) => {
|
||||
if (
|
||||
detail.hasOwnProperty( "userData" ) &&
|
||||
detail.userData.hasOwnProperty( "page" ) &&
|
||||
detail.userData.page.hasOwnProperty( "enabled" )
|
||||
) {
|
||||
return detail.userData.page.enabled();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
];
|
||||
|
||||
for ( const page of this.withPrefix( prefix ) ) {
|
||||
const userData = { page: page };
|
||||
|
||||
let route = page.route;
|
||||
|
||||
if ( prefix && route !== prefix + "/*" ) {
|
||||
route = route.replace( prefix, "" );
|
||||
}
|
||||
|
||||
routes.set( route, wrap( {
|
||||
component: page.component,
|
||||
userData: userData,
|
||||
conditions: conditions
|
||||
} ) );
|
||||
|
||||
if ( !defaultComponent && page.default ) {
|
||||
defaultComponent = page.component;
|
||||
defaultUserData = userData;
|
||||
}
|
||||
}
|
||||
|
||||
if ( defaultComponent ) {
|
||||
routes.set( "*", wrap( {
|
||||
component: defaultComponent,
|
||||
userData: defaultUserData,
|
||||
conditions: conditions
|
||||
} ) );
|
||||
}
|
||||
|
||||
return routes;
|
||||
},
|
||||
handleRouteEvent( detail ) {
|
||||
if ( detail.hasOwnProperty( "event" ) ) {
|
||||
if ( !detail.hasOwnProperty( "data" ) ) {
|
||||
detail.data = {};
|
||||
}
|
||||
|
||||
// Find the first page that wants to handle the event
|
||||
// , but also let other pages see the event
|
||||
// so they can set any initial state etc.
|
||||
let route = false;
|
||||
for ( const page of get( this ).values() ) {
|
||||
if ( page.events && page.events[ detail.event ] && page.events[ detail.event ]( detail.data ) && !route ) {
|
||||
route = page.route;
|
||||
}
|
||||
}
|
||||
|
||||
if ( route ) {
|
||||
return route;
|
||||
}
|
||||
}
|
||||
|
||||
if ( detail.hasOwnProperty( "default" ) ) {
|
||||
return detail.default;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const pages = createPages();
|
||||
|
||||
// Convenience readable store of all routes.
|
||||
export const routes = derived( pages, () => {
|
||||
return pages.routes();
|
||||
} );
|
||||
Reference in New Issue
Block a user