decap-cms-backend-gitea 3.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,397 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _commonTags = require("common-tags");
8
+ var _trimStart = _interopRequireDefault(require("lodash/trimStart"));
9
+ var _semaphore = _interopRequireDefault(require("semaphore"));
10
+ var _decapCmsLibUtil = require("decap-cms-lib-util");
11
+ var _API = _interopRequireWildcard(require("./API"));
12
+ var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage"));
13
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+ 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; }
17
+ 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; }
18
+ 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; }
19
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
20
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
21
+ const MAX_CONCURRENT_DOWNLOADS = 10;
22
+ const {
23
+ fetchWithTimeout: fetch
24
+ } = _decapCmsLibUtil.unsentRequest;
25
+ class Gitea {
26
+ constructor(config, options = {}) {
27
+ var _config$backend$branc;
28
+ _defineProperty(this, "lock", void 0);
29
+ _defineProperty(this, "api", void 0);
30
+ _defineProperty(this, "options", void 0);
31
+ _defineProperty(this, "originRepo", void 0);
32
+ _defineProperty(this, "repo", void 0);
33
+ _defineProperty(this, "branch", void 0);
34
+ _defineProperty(this, "apiRoot", void 0);
35
+ _defineProperty(this, "mediaFolder", void 0);
36
+ _defineProperty(this, "token", void 0);
37
+ _defineProperty(this, "_currentUserPromise", void 0);
38
+ _defineProperty(this, "_userIsOriginMaintainerPromises", void 0);
39
+ _defineProperty(this, "_mediaDisplayURLSem", void 0);
40
+ _defineProperty(this, "getCursorAndFiles", (files, page) => {
41
+ const pageSize = 20;
42
+ const count = files.length;
43
+ const pageCount = Math.ceil(files.length / pageSize);
44
+ const actions = [];
45
+ if (page > 1) {
46
+ actions.push('prev');
47
+ actions.push('first');
48
+ }
49
+ if (page < pageCount) {
50
+ actions.push('next');
51
+ actions.push('last');
52
+ }
53
+ const cursor = _decapCmsLibUtil.Cursor.create({
54
+ actions,
55
+ meta: {
56
+ page,
57
+ count,
58
+ pageSize,
59
+ pageCount
60
+ },
61
+ data: {
62
+ files
63
+ }
64
+ });
65
+ const pageFiles = files.slice((page - 1) * pageSize, page * pageSize);
66
+ return {
67
+ cursor,
68
+ files: pageFiles
69
+ };
70
+ });
71
+ this.options = _objectSpread({
72
+ proxied: false,
73
+ API: null,
74
+ useWorkflow: false
75
+ }, options);
76
+ if (!this.options.proxied && (config.backend.repo === null || config.backend.repo === undefined)) {
77
+ throw new Error('The Gitea backend needs a "repo" in the backend configuration.');
78
+ }
79
+ if (this.options.useWorkflow) {
80
+ throw new Error('The Gitea backend does not support editorial workflow.');
81
+ }
82
+ this.api = this.options.API || null;
83
+ this.repo = this.originRepo = config.backend.repo || '';
84
+ this.branch = ((_config$backend$branc = config.backend.branch) === null || _config$backend$branc === void 0 ? void 0 : _config$backend$branc.trim()) || 'master';
85
+ this.apiRoot = config.backend.api_root || 'https://try.gitea.io/api/v1';
86
+ this.token = '';
87
+ this.mediaFolder = config.media_folder;
88
+ this.lock = (0, _decapCmsLibUtil.asyncLock)();
89
+ }
90
+ isGitBackend() {
91
+ return true;
92
+ }
93
+ async status() {
94
+ var _this$api;
95
+ const auth = (await ((_this$api = this.api) === null || _this$api === void 0 ? void 0 : _this$api.user().then(user => !!user).catch(e => {
96
+ console.warn('[StaticCMS] Failed getting Gitea user', e);
97
+ return false;
98
+ }))) || false;
99
+ return {
100
+ auth: {
101
+ status: auth
102
+ },
103
+ api: {
104
+ status: true,
105
+ statusPage: ''
106
+ }
107
+ };
108
+ }
109
+ authComponent() {
110
+ return _AuthenticationPage.default;
111
+ }
112
+ restoreUser(user) {
113
+ return this.authenticate(user);
114
+ }
115
+ async currentUser({
116
+ token
117
+ }) {
118
+ if (!this._currentUserPromise) {
119
+ this._currentUserPromise = fetch(`${this.apiRoot}/user`, {
120
+ headers: {
121
+ Authorization: `token ${token}`
122
+ }
123
+ }).then(res => res.json());
124
+ }
125
+ return this._currentUserPromise;
126
+ }
127
+ async userIsOriginMaintainer({
128
+ username: usernameArg,
129
+ token
130
+ }) {
131
+ const username = usernameArg || (await this.currentUser({
132
+ token
133
+ })).login;
134
+ this._userIsOriginMaintainerPromises = this._userIsOriginMaintainerPromises || {};
135
+ if (!this._userIsOriginMaintainerPromises[username]) {
136
+ this._userIsOriginMaintainerPromises[username] = fetch(`${this.apiRoot}/repos/${this.originRepo}/collaborators/${username}/permission`, {
137
+ headers: {
138
+ Authorization: `token ${token}`
139
+ }
140
+ }).then(res => res.json()).then(({
141
+ permission
142
+ }) => permission === 'admin' || permission === 'write');
143
+ }
144
+ return this._userIsOriginMaintainerPromises[username];
145
+ }
146
+ async authenticate(state) {
147
+ this.token = state.token;
148
+ const apiCtor = _API.default;
149
+ this.api = new apiCtor({
150
+ token: this.token,
151
+ branch: this.branch,
152
+ repo: this.repo,
153
+ originRepo: this.originRepo,
154
+ apiRoot: this.apiRoot
155
+ });
156
+ const user = await this.api.user();
157
+ const isCollab = await this.api.hasWriteAccess().catch(error => {
158
+ error.message = (0, _commonTags.stripIndent)`
159
+ Repo "${this.repo}" not found.
160
+
161
+ Please ensure the repo information is spelled correctly.
162
+
163
+ If the repo is private, make sure you're logged into a Gitea account with access.
164
+
165
+ If your repo is under an organization, ensure the organization has granted access to Static
166
+ CMS.
167
+ `;
168
+ throw error;
169
+ });
170
+
171
+ // Unauthorized user
172
+ if (!isCollab) {
173
+ throw new Error('Your Gitea user account does not have access to this repo.');
174
+ }
175
+
176
+ // Authorized user
177
+ return {
178
+ name: user.full_name,
179
+ login: user.login,
180
+ avatar_url: user.avatar_url,
181
+ token: state.token
182
+ };
183
+ }
184
+ logout() {
185
+ this.token = null;
186
+ if (this.api && this.api.reset && typeof this.api.reset === 'function') {
187
+ return this.api.reset();
188
+ }
189
+ }
190
+ getToken() {
191
+ return Promise.resolve(this.token);
192
+ }
193
+ async entriesByFolder(folder, extension, depth) {
194
+ const repoURL = this.api.originRepoURL;
195
+ let cursor;
196
+ const listFiles = () => this.api.listFiles(folder, {
197
+ repoURL,
198
+ depth
199
+ }).then(files => {
200
+ const filtered = files.filter(file => (0, _decapCmsLibUtil.filterByExtension)(file, extension));
201
+ const result = this.getCursorAndFiles(filtered, 1);
202
+ cursor = result.cursor;
203
+ return result.files;
204
+ });
205
+ const readFile = (path, id) => this.api.readFile(path, id, {
206
+ repoURL
207
+ });
208
+ const files = await (0, _decapCmsLibUtil.entriesByFolder)(listFiles, readFile, this.api.readFileMetadata.bind(this.api), _API.API_NAME);
209
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
210
+ // @ts-ignore
211
+ files[_decapCmsLibUtil.CURSOR_COMPATIBILITY_SYMBOL] = cursor;
212
+ return files;
213
+ }
214
+ async allEntriesByFolder(folder, extension, depth) {
215
+ const repoURL = this.api.originRepoURL;
216
+ const listFiles = () => this.api.listFiles(folder, {
217
+ repoURL,
218
+ depth
219
+ }).then(files => files.filter(file => (0, _decapCmsLibUtil.filterByExtension)(file, extension)));
220
+ const readFile = (path, id) => {
221
+ return this.api.readFile(path, id, {
222
+ repoURL
223
+ });
224
+ };
225
+ const files = await (0, _decapCmsLibUtil.entriesByFolder)(listFiles, readFile, this.api.readFileMetadata.bind(this.api), _API.API_NAME);
226
+ return files;
227
+ }
228
+ entriesByFiles(files) {
229
+ const repoURL = this.api.repoURL;
230
+ const readFile = (path, id) => this.api.readFile(path, id, {
231
+ repoURL
232
+ }).catch(() => '');
233
+ return (0, _decapCmsLibUtil.entriesByFiles)(files, readFile, this.api.readFileMetadata.bind(this.api), _API.API_NAME);
234
+ }
235
+
236
+ // Fetches a single entry.
237
+ getEntry(path) {
238
+ const repoURL = this.api.originRepoURL;
239
+ return this.api.readFile(path, null, {
240
+ repoURL
241
+ }).then(data => ({
242
+ file: {
243
+ path,
244
+ id: null
245
+ },
246
+ data: data
247
+ })).catch(() => ({
248
+ file: {
249
+ path,
250
+ id: null
251
+ },
252
+ data: ''
253
+ }));
254
+ }
255
+ async getMedia(mediaFolder = this.mediaFolder, folderSupport) {
256
+ if (!mediaFolder) {
257
+ return [];
258
+ }
259
+ return this.api.listFiles(mediaFolder, undefined, folderSupport).then(files => files.map(({
260
+ id,
261
+ name,
262
+ size,
263
+ path,
264
+ type
265
+ }) => {
266
+ return {
267
+ id,
268
+ name,
269
+ size,
270
+ displayURL: {
271
+ id,
272
+ path
273
+ },
274
+ path,
275
+ isDirectory: type === 'tree'
276
+ };
277
+ }));
278
+ }
279
+ async getMediaFile(path) {
280
+ const blob = await (0, _decapCmsLibUtil.getMediaAsBlob)(path, null, this.api.readFile.bind(this.api));
281
+ const name = (0, _decapCmsLibUtil.basename)(path);
282
+ const fileObj = (0, _decapCmsLibUtil.blobToFileObj)(name, blob);
283
+ const url = URL.createObjectURL(fileObj);
284
+ const id = await (0, _decapCmsLibUtil.getBlobSHA)(blob);
285
+ return {
286
+ id,
287
+ displayURL: url,
288
+ path,
289
+ name,
290
+ size: fileObj.size,
291
+ file: fileObj,
292
+ url
293
+ };
294
+ }
295
+ getMediaDisplayURL(displayURL) {
296
+ this._mediaDisplayURLSem = this._mediaDisplayURLSem || (0, _semaphore.default)(MAX_CONCURRENT_DOWNLOADS);
297
+ return (0, _decapCmsLibUtil.getMediaDisplayURL)(displayURL, this.api.readFile.bind(this.api), this._mediaDisplayURLSem);
298
+ }
299
+ persistEntry(entry, options) {
300
+ // persistEntry is a transactional operation
301
+ return (0, _decapCmsLibUtil.runWithLock)(this.lock, () => this.api.persistFiles(entry.dataFiles, entry.assets, options), 'Failed to acquire persist entry lock');
302
+ }
303
+ async persistMedia(mediaFile, options) {
304
+ try {
305
+ await this.api.persistFiles([], [mediaFile], options);
306
+ const {
307
+ sha,
308
+ path,
309
+ fileObj
310
+ } = mediaFile;
311
+ const displayURL = URL.createObjectURL(fileObj);
312
+ return {
313
+ id: sha,
314
+ name: fileObj.name,
315
+ size: fileObj.size,
316
+ displayURL,
317
+ path: (0, _trimStart.default)(path, '/')
318
+ };
319
+ } catch (error) {
320
+ console.error(error);
321
+ throw error;
322
+ }
323
+ }
324
+ deleteFiles(paths, commitMessage) {
325
+ return this.api.deleteFiles(paths, commitMessage);
326
+ }
327
+ async traverseCursor(cursor, action) {
328
+ const meta = cursor.meta;
329
+ const files = cursor.data.get('files').toJS();
330
+ let result;
331
+ switch (action) {
332
+ case 'first':
333
+ {
334
+ result = this.getCursorAndFiles(files, 1);
335
+ break;
336
+ }
337
+ case 'last':
338
+ {
339
+ result = this.getCursorAndFiles(files, meta.get('pageCount'));
340
+ break;
341
+ }
342
+ case 'next':
343
+ {
344
+ result = this.getCursorAndFiles(files, meta.get('page') + 1);
345
+ break;
346
+ }
347
+ case 'prev':
348
+ {
349
+ result = this.getCursorAndFiles(files, meta.get('page') - 1);
350
+ break;
351
+ }
352
+ default:
353
+ {
354
+ result = this.getCursorAndFiles(files, 1);
355
+ break;
356
+ }
357
+ }
358
+ const readFile = (path, id) => this.api.readFile(path, id, {
359
+ repoURL: this.api.originRepoURL
360
+ }).catch(() => '');
361
+ const entries = await (0, _decapCmsLibUtil.entriesByFiles)(result.files, readFile, this.api.readFileMetadata.bind(this.api), _API.API_NAME);
362
+ return {
363
+ entries,
364
+ cursor: result.cursor
365
+ };
366
+ }
367
+ async unpublishedEntries() {
368
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
369
+ return {};
370
+ }
371
+ async unpublishedEntry() {
372
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
373
+ return {};
374
+ }
375
+ async unpublishedEntryDataFile() {
376
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
377
+ return {};
378
+ }
379
+ async unpublishedEntryMediaFile() {
380
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
381
+ return {};
382
+ }
383
+ async updateUnpublishedEntryStatus() {
384
+ return;
385
+ }
386
+ async publishUnpublishedEntry() {
387
+ return;
388
+ }
389
+ async deleteUnpublishedEntry() {
390
+ return;
391
+ }
392
+ async getDeployPreview() {
393
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
394
+ return {};
395
+ }
396
+ }
397
+ exports.default = Gitea;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "API", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _API.default;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "AuthenticationPage", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _AuthenticationPage.default;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "GiteaBackend", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _implementation.default;
22
+ }
23
+ });
24
+ var _implementation = _interopRequireDefault(require("./implementation"));
25
+ var _API = _interopRequireDefault(require("./API"));
26
+ var _AuthenticationPage = _interopRequireDefault(require("./AuthenticationPage"));
27
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "decap-cms-backend-gitea",
3
+ "description": "Gitea backend for Decap CMS",
4
+ "version": "3.0.4",
5
+ "repository": "https://github.com/decaporg/decap-cms/tree/master/packages/decap-cms-backend-gitea",
6
+ "bugs": "https://github.com/decaporg/decap-cms/issues",
7
+ "license": "MIT",
8
+ "module": "dist/esm/index.js",
9
+ "main": "dist/decap-cms-backend-gitea.js",
10
+ "keywords": [
11
+ "decap-cms",
12
+ "backend",
13
+ "gitea"
14
+ ],
15
+ "sideEffects": false,
16
+ "scripts": {
17
+ "develop": "yarn build:esm --watch",
18
+ "build": "cross-env NODE_ENV=production webpack",
19
+ "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\""
20
+ },
21
+ "dependencies": {
22
+ "js-base64": "^3.0.0",
23
+ "semaphore": "^1.1.0"
24
+ },
25
+ "peerDependencies": {
26
+ "@emotion/react": "^11.11.1",
27
+ "@emotion/styled": "^11.11.0",
28
+ "decap-cms-lib-auth": "^3.0.0",
29
+ "decap-cms-lib-util": "^3.0.0",
30
+ "decap-cms-ui-default": "^3.0.0",
31
+ "immutable": "^3.7.6",
32
+ "lodash": "^4.17.11",
33
+ "prop-types": "^15.7.2",
34
+ "react": "^16.8.4 || ^17.0.0"
35
+ },
36
+ "gitHead": "94b054fc6a6615ae24d39ea46882c85ff39c99b8"
37
+ }