mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-07-15 15:41:48 +08:00
287 lines
10 KiB
JavaScript
287 lines
10 KiB
JavaScript
import { HTTP, ENV } from '@/vendor/open-api';
|
|
import { getPolicyDescriptor } from '@/utils';
|
|
import $ from '@/core/app';
|
|
import { SETTINGS_KEY } from '@/constants';
|
|
|
|
/**
|
|
* Gist backup
|
|
*/
|
|
export default class Gist {
|
|
constructor({ token, key, syncPlatform }) {
|
|
const { isStash, isLoon, isShadowRocket, isQX } = ENV();
|
|
const { defaultProxy, defaultTimeout: timeout } = $.read(SETTINGS_KEY);
|
|
let proxy = defaultProxy;
|
|
if ($.env.isNode) {
|
|
proxy =
|
|
proxy || eval('process.env.SUB_STORE_BACKEND_DEFAULT_PROXY');
|
|
}
|
|
|
|
if (syncPlatform === 'gitlab') {
|
|
this.headers = {
|
|
'PRIVATE-TOKEN': `${token}`,
|
|
'User-Agent':
|
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.141 Safari/537.36',
|
|
};
|
|
this.http = HTTP({
|
|
baseURL: 'https://gitlab.com/api/v4',
|
|
headers: {
|
|
...this.headers,
|
|
...(isStash && proxy
|
|
? {
|
|
'X-Stash-Selected-Proxy':
|
|
encodeURIComponent(proxy),
|
|
}
|
|
: {}),
|
|
...(isShadowRocket && proxy
|
|
? { 'X-Surge-Policy': proxy }
|
|
: {}),
|
|
},
|
|
|
|
...(proxy ? { proxy } : {}),
|
|
...(isLoon && proxy ? { node: proxy } : {}),
|
|
...(isQX && proxy ? { opts: { policy: proxy } } : {}),
|
|
...(proxy ? getPolicyDescriptor(proxy) : {}),
|
|
timeout: timeout || 8000,
|
|
|
|
events: {
|
|
onResponse: (resp) => {
|
|
if (/^[45]/.test(String(resp.statusCode))) {
|
|
const body = JSON.parse(resp.body);
|
|
return Promise.reject(
|
|
`ERROR: ${body.message?.error ?? body.message}`,
|
|
);
|
|
} else {
|
|
return resp;
|
|
}
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
this.headers = {
|
|
Authorization: `token ${token}`,
|
|
'User-Agent':
|
|
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.141 Safari/537.36',
|
|
};
|
|
this.http = HTTP({
|
|
baseURL: 'https://api.github.com',
|
|
headers: {
|
|
...this.headers,
|
|
...(isStash && proxy
|
|
? {
|
|
'X-Stash-Selected-Proxy':
|
|
encodeURIComponent(proxy),
|
|
}
|
|
: {}),
|
|
...(isShadowRocket && proxy
|
|
? { 'X-Surge-Policy': proxy }
|
|
: {}),
|
|
},
|
|
|
|
...(proxy ? { proxy } : {}),
|
|
...(isLoon && proxy ? { node: proxy } : {}),
|
|
...(isQX && proxy ? { opts: { policy: proxy } } : {}),
|
|
...(proxy ? getPolicyDescriptor(proxy) : {}),
|
|
timeout: timeout || 8000,
|
|
|
|
events: {
|
|
onResponse: (resp) => {
|
|
if (/^[45]/.test(String(resp.statusCode))) {
|
|
return Promise.reject(
|
|
`ERROR: ${JSON.parse(resp.body).message}`,
|
|
);
|
|
} else {
|
|
return resp;
|
|
}
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
this.key = key;
|
|
this.syncPlatform = syncPlatform;
|
|
}
|
|
|
|
async locate() {
|
|
if (this.syncPlatform === 'gitlab') {
|
|
return this.http.get('/snippets').then((response) => {
|
|
const gists = JSON.parse(response.body);
|
|
|
|
for (let g of gists) {
|
|
if (g.title === this.key) {
|
|
return g;
|
|
}
|
|
}
|
|
return;
|
|
});
|
|
} else {
|
|
return this.http
|
|
.get('/gists?per_page=100&page=1')
|
|
.then((response) => {
|
|
const gists = JSON.parse(response.body);
|
|
$.info(`获取到当前 GitHub 用户的 gist: ${gists.length} 个`);
|
|
for (let g of gists) {
|
|
if (g.description === this.key) {
|
|
return g;
|
|
}
|
|
}
|
|
return;
|
|
});
|
|
}
|
|
}
|
|
|
|
async upload(input) {
|
|
if (Object.keys(input).length === 0) {
|
|
return Promise.reject('未提供需上传的文件');
|
|
}
|
|
|
|
const gist = await this.locate();
|
|
|
|
let files = input;
|
|
|
|
if (gist?.id) {
|
|
if (this.syncPlatform === 'gitlab') {
|
|
gist.files = gist.files.reduce((acc, item) => {
|
|
acc[item.path] = item;
|
|
return acc;
|
|
}, {});
|
|
}
|
|
// console.log(`files`, files);
|
|
// console.log(`gist`, gist.files);
|
|
let actions = [];
|
|
const result = { ...gist.files };
|
|
Object.keys(files).map((key) => {
|
|
if (result[key]) {
|
|
if (
|
|
files[key].content == null ||
|
|
files[key].content === ''
|
|
) {
|
|
delete result[key];
|
|
actions.push({
|
|
action: 'delete',
|
|
file_path: key,
|
|
});
|
|
} else {
|
|
result[key] = files[key];
|
|
actions.push({
|
|
action: 'update',
|
|
file_path: key,
|
|
content: files[key].content,
|
|
});
|
|
}
|
|
} else {
|
|
if (
|
|
files[key].content == null ||
|
|
files[key].content === ''
|
|
) {
|
|
delete result[key];
|
|
delete files[key];
|
|
} else {
|
|
result[key] = files[key];
|
|
actions.push({
|
|
action: 'create',
|
|
file_path: key,
|
|
content: files[key].content,
|
|
});
|
|
}
|
|
}
|
|
});
|
|
// console.log(`result`, result);
|
|
// console.log(`files`, files);
|
|
// console.log(`actions`, actions);
|
|
|
|
if (this.syncPlatform === 'gitlab') {
|
|
if (Object.keys(result).length === 0) {
|
|
return Promise.reject(
|
|
'本次操作将导致所有文件的内容都为空, 无法更新 snippet',
|
|
);
|
|
}
|
|
if (Object.keys(result).length > 10) {
|
|
return Promise.reject(
|
|
'本次操作将导致 snippet 的文件数超过 10, 无法更新 snippet',
|
|
);
|
|
}
|
|
files = actions;
|
|
return this.http.put({
|
|
headers: {
|
|
...this.headers,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
url: `/snippets/${gist.id}`,
|
|
body: JSON.stringify({ files }),
|
|
});
|
|
} else {
|
|
if (Object.keys(result).length === 0) {
|
|
return Promise.reject(
|
|
'本次操作将导致所有文件的内容都为空, 无法更新 gist',
|
|
);
|
|
}
|
|
return this.http.patch({
|
|
url: `/gists/${gist.id}`,
|
|
body: JSON.stringify({ files }),
|
|
});
|
|
}
|
|
} else {
|
|
files = Object.entries(files).reduce((acc, [key, file]) => {
|
|
if (file.content !== null && file.content !== '') {
|
|
acc[key] = file;
|
|
}
|
|
return acc;
|
|
}, {});
|
|
if (this.syncPlatform === 'gitlab') {
|
|
if (Object.keys(files).length === 0) {
|
|
return Promise.reject(
|
|
'所有文件的内容都为空, 无法创建 snippet',
|
|
);
|
|
}
|
|
files = Object.keys(files).map((key) => ({
|
|
file_path: key,
|
|
content: files[key].content,
|
|
}));
|
|
return this.http.post({
|
|
headers: {
|
|
...this.headers,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
url: '/snippets',
|
|
body: JSON.stringify({
|
|
title: this.key,
|
|
visibility: 'private',
|
|
files,
|
|
}),
|
|
});
|
|
} else {
|
|
if (Object.keys(files).length === 0) {
|
|
return Promise.reject(
|
|
'所有文件的内容都为空, 无法创建 gist',
|
|
);
|
|
}
|
|
return this.http.post({
|
|
url: '/gists',
|
|
body: JSON.stringify({
|
|
description: this.key,
|
|
public: false,
|
|
files,
|
|
}),
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
async download(filename) {
|
|
const gist = await this.locate();
|
|
if (gist?.id) {
|
|
try {
|
|
const { files } = await this.http
|
|
.get(`/gists/${gist.id}`)
|
|
.then((resp) => JSON.parse(resp.body));
|
|
const url = files[filename].raw_url;
|
|
return await this.http.get(url).then((resp) => resp.body);
|
|
} catch (err) {
|
|
return Promise.reject(err);
|
|
}
|
|
} else {
|
|
return Promise.reject(`找不到 Sub-Store Gist (${this.key})`);
|
|
}
|
|
}
|
|
}
|