planning
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s

This commit is contained in:
2024-10-14 09:15:30 +02:00
parent bcba00a730
commit 6e64e138e2
21059 changed files with 2317811 additions and 1 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _decapCmsBackendGithub = require("decap-cms-backend-github");
var _decapCmsLibUtil = require("decap-cms-lib-util");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
class API extends _decapCmsBackendGithub.API {
constructor(config) {
super(_objectSpread({
getUser: () => Promise.reject('Never used')
}, config));
_defineProperty(this, "tokenPromise", void 0);
_defineProperty(this, "commitAuthor", void 0);
_defineProperty(this, "isLargeMedia", void 0);
this.apiRoot = config.apiRoot;
this.tokenPromise = config.tokenPromise;
this.commitAuthor = config.commitAuthor;
this.isLargeMedia = config.isLargeMedia;
this.repoURL = '';
this.originRepoURL = '';
}
hasWriteAccess() {
return this.getDefaultBranch().then(() => true).catch(error => {
if (error.status === 401) {
if (error.message === 'Bad credentials') {
throw new _decapCmsLibUtil.APIError('Git Gateway Error: Please ask your site administrator to reissue the Git Gateway token.', error.status, 'Git Gateway');
} else {
return false;
}
} else if (error.status === 404 && (error.message === undefined || error.message === 'Unable to locate site configuration')) {
throw new _decapCmsLibUtil.APIError(`Git Gateway Error: Please make sure Git Gateway is enabled on your site.`, error.status, 'Git Gateway');
} else {
console.error('Problem fetching repo data from Git Gateway');
throw error;
}
});
}
requestHeaders(headers = {}) {
return this.tokenPromise().then(jwtToken => {
const baseHeader = _objectSpread({
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json; charset=utf-8'
}, headers);
return baseHeader;
});
}
handleRequestError(error, responseStatus) {
throw new _decapCmsLibUtil.APIError(error.message || error.msg, responseStatus, 'Git Gateway');
}
user() {
return Promise.resolve(_objectSpread({
login: ''
}, this.commitAuthor));
}
async getHeadReference(head) {
if (!this.repoOwner) {
// get the repo owner from the branch url
// this is required for returning the full head reference, e.g. owner:head
// when filtering pull requests based on the head
const branch = await this.getDefaultBranch();
const self = branch._links.self;
const regex = new RegExp('https?://.+?/repos/(.+?)/');
const owner = self.match(regex);
this.repoOwner = owner ? owner[1] : '';
}
return super.getHeadReference(head);
}
commit(message, changeTree) {
const commitParams = {
message,
tree: changeTree.sha,
parents: changeTree.parentSha ? [changeTree.parentSha] : []
};
if (this.commitAuthor) {
commitParams.author = _objectSpread(_objectSpread({}, this.commitAuthor), {}, {
date: new Date().toISOString()
});
}
return this.request('/git/commits', {
method: 'POST',
body: JSON.stringify(commitParams)
});
}
nextUrlProcessor() {
return url => url.replace(/^(?:[a-z]+:\/\/.+?\/.+?\/.+?\/)/, `${this.apiRoot}/`);
}
async diffFromFile(file) {
const diff = await super.diffFromFile(file);
return _objectSpread(_objectSpread({}, diff), {}, {
binary: diff.binary || (await this.isLargeMedia(file.filename))
});
}
}
exports.default = API;

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _decapCmsBackendGitlab = require("decap-cms-backend-gitlab");
var _decapCmsLibUtil = require("decap-cms-lib-util");
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
class API extends _decapCmsBackendGitlab.API {
constructor(config) {
super(config);
_defineProperty(this, "tokenPromise", void 0);
_defineProperty(this, "withAuthorizationHeaders", async req => {
const token = await this.tokenPromise();
return _decapCmsLibUtil.unsentRequest.withHeaders({
Authorization: `Bearer ${token}`
}, req);
});
_defineProperty(this, "hasWriteAccess", () => Promise.resolve(true));
this.tokenPromise = config.tokenPromise;
this.commitAuthor = config.commitAuthor;
this.repoURL = '';
}
}
exports.default = API;

View File

@@ -0,0 +1,589 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _intersection2 = _interopRequireDefault(require("lodash/intersection"));
var _pick2 = _interopRequireDefault(require("lodash/pick"));
var _get2 = _interopRequireDefault(require("lodash/get"));
var _gotrueJs = _interopRequireDefault(require("gotrue-js"));
var _jwtDecode = _interopRequireDefault(require("jwt-decode"));
var _ini = _interopRequireDefault(require("ini"));
var _decapCmsLibUtil = require("decap-cms-lib-util");
var _decapCmsBackendGithub = require("decap-cms-backend-github");
var _decapCmsBackendGitlab = require("decap-cms-backend-gitlab");
var _decapCmsBackendBitbucket = require("decap-cms-backend-bitbucket");
var _GitHubAPI = _interopRequireDefault(require("./GitHubAPI"));
var _GitLabAPI = _interopRequireDefault(require("./GitLabAPI"));
var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage"));
var _netlifyLfsClient = require("./netlify-lfs-client");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
const STATUS_PAGE = 'https://www.netlifystatus.com';
const GIT_GATEWAY_STATUS_ENDPOINT = `${STATUS_PAGE}/api/v2/components.json`;
const GIT_GATEWAY_OPERATIONAL_UNITS = ['Git Gateway'];
const localHosts = {
localhost: true,
'127.0.0.1': true,
'0.0.0.0': true
};
const defaults = {
identity: '/.netlify/identity',
gateway: '/.netlify/git',
largeMedia: '/.netlify/large-media'
};
function getEndpoint(endpoint, netlifySiteURL) {
if (localHosts[document.location.host.split(':').shift()] && netlifySiteURL && endpoint.match(/^\/\.netlify\//)) {
const parts = [];
if (netlifySiteURL) {
parts.push(netlifySiteURL);
if (!netlifySiteURL.match(/\/$/)) {
parts.push('/');
}
}
parts.push(endpoint.replace(/^\//, ''));
return parts.join('');
}
return endpoint;
}
// wait for identity widget to initialize
// force init on timeout
let initPromise = Promise.resolve();
if (window.netlifyIdentity) {
let initialized = false;
initPromise = Promise.race([new Promise(resolve => {
var _window$netlifyIdenti;
(_window$netlifyIdenti = window.netlifyIdentity) === null || _window$netlifyIdenti === void 0 ? void 0 : _window$netlifyIdenti.on('init', () => {
initialized = true;
resolve();
});
}), new Promise(resolve => setTimeout(resolve, 2500)).then(() => {
if (!initialized) {
var _window$netlifyIdenti2;
console.log('Manually initializing identity widget');
(_window$netlifyIdenti2 = window.netlifyIdentity) === null || _window$netlifyIdenti2 === void 0 ? void 0 : _window$netlifyIdenti2.init();
}
})]);
}
async function apiGet(path) {
const apiRoot = 'https://api.netlify.com/api/v1/sites';
const response = await fetch(`${apiRoot}/${path}`).then(res => res.json());
return response;
}
class GitGateway {
constructor(config, options = {}) {
var _config$backend$branc;
_defineProperty(this, "config", void 0);
_defineProperty(this, "api", void 0);
_defineProperty(this, "branch", void 0);
_defineProperty(this, "squashMerges", void 0);
_defineProperty(this, "cmsLabelPrefix", void 0);
_defineProperty(this, "mediaFolder", void 0);
_defineProperty(this, "transformImages", void 0);
_defineProperty(this, "gatewayUrl", void 0);
_defineProperty(this, "netlifyLargeMediaURL", void 0);
_defineProperty(this, "backendType", void 0);
_defineProperty(this, "apiUrl", void 0);
_defineProperty(this, "authClient", void 0);
_defineProperty(this, "backend", void 0);
_defineProperty(this, "acceptRoles", void 0);
_defineProperty(this, "tokenPromise", void 0);
_defineProperty(this, "_largeMediaClientPromise", void 0);
_defineProperty(this, "options", void 0);
_defineProperty(this, "requestFunction", req => this.tokenPromise().then(token => _decapCmsLibUtil.unsentRequest.withHeaders({
Authorization: `Bearer ${token}`
}, req)).then(_decapCmsLibUtil.unsentRequest.performRequest));
this.options = _objectSpread({
proxied: true,
API: null,
initialWorkflowStatus: ''
}, options);
this.config = config;
this.branch = ((_config$backend$branc = config.backend.branch) === null || _config$backend$branc === void 0 ? void 0 : _config$backend$branc.trim()) || 'master';
this.squashMerges = config.backend.squash_merges || false;
this.cmsLabelPrefix = config.backend.cms_label_prefix || '';
this.mediaFolder = config.media_folder;
const {
use_large_media_transforms_in_media_library: transformImages = true
} = config.backend;
this.transformImages = transformImages;
const netlifySiteURL = localStorage.getItem('netlifySiteURL');
this.apiUrl = getEndpoint(config.backend.identity_url || defaults.identity, netlifySiteURL);
this.gatewayUrl = getEndpoint(config.backend.gateway_url || defaults.gateway, netlifySiteURL);
this.netlifyLargeMediaURL = getEndpoint(config.backend.large_media_url || defaults.largeMedia, netlifySiteURL);
const backendTypeRegex = /\/(github|gitlab|bitbucket)\/?$/;
const backendTypeMatches = this.gatewayUrl.match(backendTypeRegex);
if (backendTypeMatches) {
this.backendType = backendTypeMatches[1];
this.gatewayUrl = this.gatewayUrl.replace(backendTypeRegex, '');
} else {
this.backendType = null;
}
this.backend = null;
_AuthenticationPage.default.authClient = () => this.getAuthClient();
}
isGitBackend() {
return true;
}
async status() {
const api = await fetch(GIT_GATEWAY_STATUS_ENDPOINT).then(res => res.json()).then(res => {
return res['components'].filter(statusComponent => GIT_GATEWAY_OPERATIONAL_UNITS.includes(statusComponent.name)).every(statusComponent => statusComponent.status === 'operational');
}).catch(e => {
console.warn('Failed getting Git Gateway status', e);
return true;
});
let auth = false;
// no need to check auth if api is down
if (api) {
var _this$tokenPromise;
auth = (await ((_this$tokenPromise = this.tokenPromise) === null || _this$tokenPromise === void 0 ? void 0 : _this$tokenPromise.call(this).then(token => !!token).catch(e => {
console.warn('Failed getting Identity token', e);
return false;
}))) || false;
}
return {
auth: {
status: auth
},
api: {
status: api,
statusPage: STATUS_PAGE
}
};
}
async getAuthClient() {
if (this.authClient) {
return this.authClient;
}
await initPromise;
if (window.netlifyIdentity) {
this.authClient = {
logout: () => {
var _window$netlifyIdenti3;
return (_window$netlifyIdenti3 = window.netlifyIdentity) === null || _window$netlifyIdenti3 === void 0 ? void 0 : _window$netlifyIdenti3.logout();
},
currentUser: () => {
var _window$netlifyIdenti4;
return (_window$netlifyIdenti4 = window.netlifyIdentity) === null || _window$netlifyIdenti4 === void 0 ? void 0 : _window$netlifyIdenti4.currentUser();
},
clearStore: () => {
var _window$netlifyIdenti5;
const store = (_window$netlifyIdenti5 = window.netlifyIdentity) === null || _window$netlifyIdenti5 === void 0 ? void 0 : _window$netlifyIdenti5.store;
if (store) {
store.user = null;
store.modal.page = 'login';
store.saving = false;
}
}
};
} else {
const goTrue = new _gotrueJs.default({
APIUrl: this.apiUrl
});
this.authClient = {
logout: () => {
const user = goTrue.currentUser();
if (user) {
return user.logout();
}
},
currentUser: () => goTrue.currentUser(),
login: goTrue.login.bind(goTrue),
clearStore: () => undefined
};
}
return this.authClient;
}
authenticate(credentials) {
const user = credentials;
this.tokenPromise = async () => {
try {
const func = user.jwt.bind(user);
const token = await func();
return token;
} catch (error) {
throw new _decapCmsLibUtil.AccessTokenError(`Failed getting access token: ${error.message}`);
}
};
return this.tokenPromise().then(async token => {
if (!this.backendType) {
const {
github_enabled: githubEnabled,
gitlab_enabled: gitlabEnabled,
bitbucket_enabled: bitbucketEnabled,
roles
} = await _decapCmsLibUtil.unsentRequest.fetchWithTimeout(`${this.gatewayUrl}/settings`, {
headers: {
Authorization: `Bearer ${token}`
}
}).then(async res => {
const contentType = res.headers.get('Content-Type') || '';
if (!contentType.includes('application/json') && !contentType.includes('text/json')) {
throw new _decapCmsLibUtil.APIError(`Your Git Gateway backend is not returning valid settings. Please make sure it is enabled.`, res.status, 'Git Gateway');
}
const body = await res.json();
if (!res.ok) {
throw new _decapCmsLibUtil.APIError(`Git Gateway Error: ${body.message ? body.message : body}`, res.status, 'Git Gateway');
}
return body;
});
this.acceptRoles = roles;
if (githubEnabled) {
this.backendType = 'github';
} else if (gitlabEnabled) {
this.backendType = 'gitlab';
} else if (bitbucketEnabled) {
this.backendType = 'bitbucket';
}
}
if (this.acceptRoles && this.acceptRoles.length > 0) {
const userRoles = (0, _get2.default)((0, _jwtDecode.default)(token), 'app_metadata.roles', []);
const validRole = (0, _intersection2.default)(userRoles, this.acceptRoles).length > 0;
if (!validRole) {
throw new Error("You don't have sufficient permissions to access Decap CMS");
}
}
const userData = {
name: user.user_metadata.full_name || user.email.split('@').shift(),
email: user.email,
avatar_url: user.user_metadata.avatar_url,
metadata: user.user_metadata
};
const apiConfig = {
apiRoot: `${this.gatewayUrl}/${this.backendType}`,
branch: this.branch,
tokenPromise: this.tokenPromise,
commitAuthor: (0, _pick2.default)(userData, ['name', 'email']),
isLargeMedia: filename => this.isLargeMediaFile(filename),
squashMerges: this.squashMerges,
cmsLabelPrefix: this.cmsLabelPrefix,
initialWorkflowStatus: this.options.initialWorkflowStatus
};
if (this.backendType === 'github') {
this.api = new _GitHubAPI.default(apiConfig);
this.backend = new _decapCmsBackendGithub.GitHubBackend(this.config, _objectSpread(_objectSpread({}, this.options), {}, {
API: this.api
}));
} else if (this.backendType === 'gitlab') {
this.api = new _GitLabAPI.default(apiConfig);
this.backend = new _decapCmsBackendGitlab.GitLabBackend(this.config, _objectSpread(_objectSpread({}, this.options), {}, {
API: this.api
}));
} else if (this.backendType === 'bitbucket') {
this.api = new _decapCmsBackendBitbucket.API(_objectSpread(_objectSpread({}, apiConfig), {}, {
requestFunction: this.requestFunction,
hasWriteAccess: async () => true
}));
this.backend = new _decapCmsBackendBitbucket.BitbucketBackend(this.config, _objectSpread(_objectSpread({}, this.options), {}, {
API: this.api
}));
}
if (!(await this.api.hasWriteAccess())) {
throw new Error("You don't have sufficient permissions to access Decap CMS");
}
return {
name: userData.name,
login: userData.email,
avatar_url: userData.avatar_url
};
});
}
async restoreUser() {
const client = await this.getAuthClient();
const user = client.currentUser();
if (!user) return Promise.reject();
return this.authenticate(user);
}
authComponent() {
return _AuthenticationPage.default;
}
async logout() {
const client = await this.getAuthClient();
try {
client.logout();
} catch (e) {
// due to a bug in the identity widget (gotrue-js actually) the store is not reset if logout fails
// TODO: remove after https://github.com/netlify/gotrue-js/pull/83 is merged
client.clearStore();
}
}
getToken() {
return this.tokenPromise();
}
async entriesByFolder(folder, extension, depth) {
return this.backend.entriesByFolder(folder, extension, depth);
}
allEntriesByFolder(folder, extension, depth, pathRegex) {
return this.backend.allEntriesByFolder(folder, extension, depth, pathRegex);
}
entriesByFiles(files) {
return this.backend.entriesByFiles(files);
}
getEntry(path) {
return this.backend.getEntry(path);
}
async unpublishedEntryDataFile(collection, slug, path, id) {
return this.backend.unpublishedEntryDataFile(collection, slug, path, id);
}
async isLargeMediaFile(path) {
const client = await this.getLargeMediaClient();
return client.enabled && client.matchPath(path);
}
async unpublishedEntryMediaFile(collection, slug, path, id) {
const isLargeMedia = await this.isLargeMediaFile(path);
if (isLargeMedia) {
const branch = this.backend.getBranch(collection, slug);
const {
url,
blob
} = await this.getLargeMediaDisplayURL({
path,
id
}, branch);
return {
id,
name: (0, _decapCmsLibUtil.basename)(path),
path,
url,
displayURL: url,
file: new File([blob], (0, _decapCmsLibUtil.basename)(path)),
size: blob.size
};
} else {
return this.backend.unpublishedEntryMediaFile(collection, slug, path, id);
}
}
getMedia(mediaFolder = this.mediaFolder) {
return this.backend.getMedia(mediaFolder);
}
// this method memoizes this._getLargeMediaClient so that there can
// only be one client at a time
getLargeMediaClient() {
if (this._largeMediaClientPromise) {
return this._largeMediaClientPromise;
}
this._largeMediaClientPromise = this._getLargeMediaClient();
return this._largeMediaClientPromise;
}
_getLargeMediaClient() {
const netlifyLargeMediaEnabledPromise = this.api.readFile('.lfsconfig').then(config => _ini.default.decode(config)).then(({
lfs: {
url
}
}) => new URL(url)).then(lfsURL => ({
enabled: lfsURL.hostname.endsWith('netlify.com') || lfsURL.hostname.endsWith('netlify.app')
})).catch(err => ({
enabled: false,
err
}));
const lfsPatternsPromise = this.api.readFile('.gitattributes').then(attributes => (0, _decapCmsLibUtil.getLargeMediaPatternsFromGitAttributesFile)(attributes)).then(patterns => ({
err: null,
patterns
})).catch(err => {
if (err.message.includes('404')) {
console.log('This 404 was expected and handled appropriately.');
return {
err: null,
patterns: []
};
} else {
return {
err,
patterns: []
};
}
});
return Promise.all([netlifyLargeMediaEnabledPromise, lfsPatternsPromise]).then(([{
enabled: maybeEnabled
}, {
patterns,
err: patternsErr
}]) => {
const enabled = maybeEnabled && !patternsErr;
// We expect LFS patterns to exist when the .lfsconfig states
// that we're using Netlify Large Media
if (maybeEnabled && patternsErr) {
console.error(patternsErr);
}
return (0, _netlifyLfsClient.getClient)({
enabled,
rootURL: this.netlifyLargeMediaURL,
makeAuthorizedRequest: this.requestFunction,
patterns,
transformImages: this.transformImages ? {
nf_resize: 'fit',
w: 560,
h: 320
} : false
});
});
}
async getLargeMediaDisplayURL({
path,
id
}, branch = this.branch) {
const readFile = (path, id, {
parseText
}) => this.api.readFile(path, id, {
branch,
parseText
});
const items = await (0, _decapCmsLibUtil.entriesByFiles)([{
path,
id
}], readFile, this.api.readFileMetadata.bind(this.api), 'Git-Gateway');
const entry = items[0];
const pointerFile = (0, _decapCmsLibUtil.parsePointerFile)(entry.data);
if (!pointerFile.sha) {
console.warn(`Failed parsing pointer file ${path}`);
return {
url: path,
blob: new Blob()
};
}
const client = await this.getLargeMediaClient();
const {
url,
blob
} = await client.getDownloadURL(pointerFile);
return {
url,
blob
};
}
async getMediaDisplayURL(displayURL) {
const {
path,
id
} = displayURL;
const isLargeMedia = await this.isLargeMediaFile(path);
if (isLargeMedia) {
const {
url
} = await this.getLargeMediaDisplayURL({
path,
id
});
return url;
}
if (typeof displayURL === 'string') {
return displayURL;
}
const url = await this.backend.getMediaDisplayURL(displayURL);
return url;
}
async getMediaFile(path) {
const isLargeMedia = await this.isLargeMediaFile(path);
if (isLargeMedia) {
const {
url,
blob
} = await this.getLargeMediaDisplayURL({
path,
id: null
});
return {
id: url,
name: (0, _decapCmsLibUtil.basename)(path),
path,
url,
displayURL: url,
file: new File([blob], (0, _decapCmsLibUtil.basename)(path)),
size: blob.size
};
}
return this.backend.getMediaFile(path);
}
async persistEntry(entry, options) {
const client = await this.getLargeMediaClient();
if (client.enabled) {
const assets = await (0, _decapCmsLibUtil.getLargeMediaFilteredMediaFiles)(client, entry.assets);
return this.backend.persistEntry(_objectSpread(_objectSpread({}, entry), {}, {
assets
}), options);
} else {
return this.backend.persistEntry(entry, options);
}
}
async persistMedia(mediaFile, options) {
const {
fileObj,
path
} = mediaFile;
const displayURL = fileObj ? URL.createObjectURL(fileObj) : '';
const client = await this.getLargeMediaClient();
const fixedPath = path.startsWith('/') ? path.slice(1) : path;
const isLargeMedia = await this.isLargeMediaFile(fixedPath);
if (isLargeMedia) {
const persistMediaArgument = await (0, _decapCmsLibUtil.getPointerFileForMediaFileObj)(client, fileObj, path);
return _objectSpread(_objectSpread({}, await this.backend.persistMedia(persistMediaArgument, options)), {}, {
displayURL
});
}
return await this.backend.persistMedia(mediaFile, options);
}
deleteFiles(paths, commitMessage) {
return this.backend.deleteFiles(paths, commitMessage);
}
async getDeployPreview(collection, slug) {
let preview = await this.backend.getDeployPreview(collection, slug);
if (!preview) {
try {
// if the commit doesn't have a status, try to use Netlify API directly
// this is useful when builds are queue up in Netlify and don't have a commit status yet
// and only works with public logs at the moment
// TODO: get Netlify API Token and use it to access private logs
const siteId = new URL(localStorage.getItem('netlifySiteURL') || '').hostname;
const site = await apiGet(siteId);
const deploys = await apiGet(`${site.id}/deploys?per_page=100`);
if (deploys.length > 0) {
const ref = await this.api.getUnpublishedEntrySha(collection, slug);
const deploy = deploys.find(d => d.commit_ref === ref);
if (deploy) {
preview = {
status: deploy.state === 'ready' ? _decapCmsLibUtil.PreviewState.Success : _decapCmsLibUtil.PreviewState.Other,
url: deploy.deploy_url
};
}
}
// eslint-disable-next-line no-empty
} catch (e) {}
}
return preview;
}
unpublishedEntries() {
return this.backend.unpublishedEntries();
}
unpublishedEntry({
id,
collection,
slug
}) {
return this.backend.unpublishedEntry({
id,
collection,
slug
});
}
updateUnpublishedEntryStatus(collection, slug, newStatus) {
return this.backend.updateUnpublishedEntryStatus(collection, slug, newStatus);
}
deleteUnpublishedEntry(collection, slug) {
return this.backend.deleteUnpublishedEntry(collection, slug);
}
publishUnpublishedEntry(collection, slug) {
return this.backend.publishUnpublishedEntry(collection, slug);
}
traverseCursor(cursor, action) {
return this.backend.traverseCursor(cursor, action);
}
}
exports.default = GitGateway;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AuthenticationPage", {
enumerable: true,
get: function () {
return _AuthenticationPage.default;
}
});
exports.DecapCmsBackendGitGateway = void 0;
Object.defineProperty(exports, "GitGatewayBackend", {
enumerable: true,
get: function () {
return _implementation.default;
}
});
var _implementation = _interopRequireDefault(require("./implementation"));
var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const DecapCmsBackendGitGateway = exports.DecapCmsBackendGitGateway = {
GitGatewayBackend: _implementation.default,
AuthenticationPage: _AuthenticationPage.default
};

View File

@@ -0,0 +1,186 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getClient = getClient;
exports.matchPath = matchPath;
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
var _map2 = _interopRequireDefault(require("lodash/fp/map"));
var _fromPairs2 = _interopRequireDefault(require("lodash/fp/fromPairs"));
var _flow2 = _interopRequireDefault(require("lodash/fp/flow"));
var _minimatch = _interopRequireDefault(require("minimatch"));
var _decapCmsLibUtil = require("decap-cms-lib-util");
const _excluded = ["sha"];
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function matchPath({
patterns
}, path) {
return patterns.some(pattern => (0, _minimatch.default)(path, pattern, {
matchBase: true
}));
}
//
// API interactions
const defaultContentHeaders = {
Accept: 'application/vnd.git-lfs+json',
['Content-Type']: 'application/vnd.git-lfs+json'
};
async function resourceExists({
rootURL,
makeAuthorizedRequest
}, {
sha,
size
}) {
const response = await makeAuthorizedRequest({
url: `${rootURL}/verify`,
method: 'POST',
headers: defaultContentHeaders,
body: JSON.stringify({
oid: sha,
size
})
});
if (response.ok) {
return true;
}
if (response.status === 404) {
return false;
}
// TODO: what kind of error to throw here? APIError doesn't seem
// to fit
}
function getTransofrmationsParams(t) {
if ((0, _isPlainObject2.default)(t) && !(0, _isEmpty2.default)(t)) {
const {
nf_resize: resize,
w,
h
} = t;
return `?nf_resize=${resize}&w=${w}&h=${h}`;
}
return '';
}
async function getDownloadURL({
rootURL,
transformImages: t,
makeAuthorizedRequest
}, {
sha
}) {
try {
const transformation = getTransofrmationsParams(t);
const transformedPromise = makeAuthorizedRequest(`${rootURL}/origin/${sha}${transformation}`);
const [transformed, original] = await Promise.all([transformedPromise,
// if transformation is defined, we need to load the original so we have the correct meta data
transformation ? makeAuthorizedRequest(`${rootURL}/origin/${sha}`) : transformedPromise]);
if (!transformed.ok) {
const error = await transformed.json();
throw new Error(`Failed getting large media for sha '${sha}': '${error.code} - ${error.msg}'`);
}
const transformedBlob = await transformed.blob();
const url = URL.createObjectURL(transformedBlob);
return {
url,
blob: transformation ? await original.blob() : transformedBlob
};
} catch (error) {
console.error(error);
return {
url: '',
blob: new Blob()
};
}
}
function uploadOperation(objects) {
return {
operation: 'upload',
transfers: ['basic'],
objects: objects.map(_ref => {
let {
sha
} = _ref,
rest = _objectWithoutProperties(_ref, _excluded);
return _objectSpread(_objectSpread({}, rest), {}, {
oid: sha
});
})
};
}
async function getResourceUploadURLs({
rootURL,
makeAuthorizedRequest
}, pointerFiles) {
const response = await makeAuthorizedRequest({
url: `${rootURL}/objects/batch`,
method: 'POST',
headers: defaultContentHeaders,
body: JSON.stringify(uploadOperation(pointerFiles))
});
const {
objects
} = await response.json();
const uploadUrls = objects.map(object => {
if (object.error) {
throw new Error(object.error.message);
}
return object.actions.upload.href;
});
return uploadUrls;
}
function uploadBlob(uploadURL, blob) {
return _decapCmsLibUtil.unsentRequest.fetchWithTimeout(uploadURL, {
method: 'PUT',
body: blob
});
}
async function uploadResource(clientConfig, {
sha,
size
}, resource) {
const existingFile = await resourceExists(clientConfig, {
sha,
size
});
if (existingFile) {
return sha;
}
const [uploadURL] = await getResourceUploadURLs(clientConfig, [{
sha,
size
}]);
await uploadBlob(uploadURL, resource);
return sha;
}
//
// Create Large Media client
function configureFn(config, fn) {
return (...args) => fn(config, ...args);
}
const clientFns = {
resourceExists,
getResourceUploadURLs,
getDownloadURL,
uploadResource,
matchPath
};
function getClient(clientConfig) {
return (0, _flow2.default)([Object.keys, (0, _map2.default)(key => [key, configureFn(clientConfig, clientFns[key])]), _fromPairs2.default, configuredFns => _objectSpread(_objectSpread({}, configuredFns), {}, {
patterns: clientConfig.patterns,
enabled: clientConfig.enabled
})])(clientFns);
}

View File

@@ -0,0 +1 @@
"use strict";