mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-21 18:01:36 +03:00
7b443d4b63
no issue The `config` service has been a source of confusion when writing with modern Ember patterns because it's use of the deprecated `ProxyMixin` forced all property access/setting to go via `.get()` and `.set()` whereas the rest of the system has mostly (there are a few other uses of ProxyObjects remaining) eliminated the use of the non-native get/set methods. - removed use of `ProxyMixin` in the `config` service by grabbing the API response after fetching and using `Object.defineProperty()` to add native getters/setters that pass through to a tracked object holding the API response data. Ember's autotracking automatically works across the native getters/setters so we can then use the service as if it was any other native object - updated all code to use `config.{attrName}` directly for getting/setting instead of `.get()` and `.set()` - removed unnecessary async around `config.availableTimezones` which wasn't making any async calls
91 lines
2.6 KiB
JavaScript
91 lines
2.6 KiB
JavaScript
import RSVP from 'rsvp';
|
|
import Service, {inject as service} from '@ember/service';
|
|
import timezoneData from '@tryghost/timezone-data';
|
|
import {TrackedObject} from 'tracked-built-ins';
|
|
import {tracked} from '@glimmer/tracking';
|
|
|
|
export default class ConfigService extends Service {
|
|
@service ajax;
|
|
@service ghostPaths;
|
|
@service session;
|
|
|
|
@tracked content = new TrackedObject();
|
|
|
|
availableTimezones = timezoneData;
|
|
|
|
fetch() {
|
|
let promises = [];
|
|
|
|
promises.push(this.fetchUnauthenticated());
|
|
|
|
if (this.session.isAuthenticated) {
|
|
promises.push(this.fetchAuthenticated());
|
|
}
|
|
|
|
return RSVP.all(promises);
|
|
}
|
|
|
|
async fetchUnauthenticated() {
|
|
const siteUrl = this.ghostPaths.url.api('site');
|
|
const {site} = await this.ajax.request(siteUrl);
|
|
|
|
// normalize url to non-trailing-slash
|
|
site.blogUrl = site.url.replace(/\/$/, '');
|
|
site.blogTitle = site.title;
|
|
delete site.url;
|
|
delete site.title;
|
|
|
|
Object.assign(this.content, site);
|
|
this._defineProperties(site);
|
|
}
|
|
|
|
async fetchAuthenticated() {
|
|
const configUrl = this.ghostPaths.url.api('config');
|
|
const {config} = await this.ajax.request(configUrl);
|
|
|
|
Object.assign(this.content, config);
|
|
this._defineProperties(config);
|
|
}
|
|
|
|
get blogDomain() {
|
|
const blogDomain = this.blogUrl
|
|
.replace(/^https?:\/\//, '')
|
|
.replace(/\/?$/, '');
|
|
|
|
return blogDomain;
|
|
}
|
|
|
|
get emailDomain() {
|
|
const blogDomain = this.blogDomain || '';
|
|
const domainExp = blogDomain.match(new RegExp('^([^/:?#]+)(?:[/:?#]|$)', 'i'));
|
|
const domain = (domainExp && domainExp[1]) || '';
|
|
if (domain.startsWith('www.')) {
|
|
return domain.replace(/^(www)\.(?=[^/]*\..{2,5})/, '');
|
|
}
|
|
return domain;
|
|
}
|
|
|
|
getSiteUrl(path) {
|
|
const siteUrl = new URL(this.blogUrl);
|
|
const subdir = siteUrl.pathname.endsWith('/') ? siteUrl.pathname : `${siteUrl.pathname}/`;
|
|
const fullPath = `${subdir}${path.replace(/^\//, '')}`;
|
|
|
|
return `${siteUrl.origin}${fullPath}`;
|
|
}
|
|
|
|
_defineProperties(obj) {
|
|
for (const name of Object.keys(obj)) {
|
|
if (!Object.prototype.hasOwnProperty.call(this, name)) {
|
|
Object.defineProperty(this, name, {
|
|
get() {
|
|
return this.content[name];
|
|
},
|
|
set(newValue) {
|
|
this.content[name] = newValue;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|