decap-cms-backend-github 2.15.0-beta.0
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.
- package/CHANGELOG.md +817 -0
- package/LICENSE +22 -0
- package/README.md +17 -0
- package/dist/decap-cms-backend-github.js +312 -0
- package/dist/decap-cms-backend-github.js.LICENSE.txt +23 -0
- package/dist/decap-cms-backend-github.js.map +1 -0
- package/dist/esm/API.js +1217 -0
- package/dist/esm/AuthenticationPage.js +192 -0
- package/dist/esm/GraphQLAPI.js +807 -0
- package/dist/esm/fragmentTypes.js +947 -0
- package/dist/esm/fragments.js +98 -0
- package/dist/esm/implementation.js +585 -0
- package/dist/esm/index.js +34 -0
- package/dist/esm/mutations.js +117 -0
- package/dist/esm/queries.js +212 -0
- package/dist/esm/types/semaphore.d.js +1 -0
- package/package.json +44 -0
- package/scripts/createFragmentTypes.js +48 -0
- package/src/API.ts +1468 -0
- package/src/AuthenticationPage.js +151 -0
- package/src/GraphQLAPI.ts +709 -0
- package/src/__tests__/API.spec.js +833 -0
- package/src/__tests__/GraphQLAPI.spec.js +69 -0
- package/src/__tests__/implementation.spec.js +361 -0
- package/src/fragmentTypes.js +1 -0
- package/src/fragments.ts +92 -0
- package/src/implementation.tsx +672 -0
- package/src/index.ts +10 -0
- package/src/mutations.ts +110 -0
- package/src/queries.ts +213 -0
- package/src/types/semaphore.d.ts +5 -0
- package/webpack.config.js +3 -0
|
@@ -0,0 +1,807 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _trimStart2 = _interopRequireDefault(require("lodash/trimStart"));
|
|
8
|
+
var _trim2 = _interopRequireDefault(require("lodash/trim"));
|
|
9
|
+
var _apolloClient = require("apollo-client");
|
|
10
|
+
var _apolloCacheInmemory = require("apollo-cache-inmemory");
|
|
11
|
+
var _apolloLinkHttp = require("apollo-link-http");
|
|
12
|
+
var _apolloLinkContext = require("apollo-link-context");
|
|
13
|
+
var _decapCmsLibUtil = require("decap-cms-lib-util");
|
|
14
|
+
var _fragmentTypes = _interopRequireDefault(require("./fragmentTypes"));
|
|
15
|
+
var _API = _interopRequireWildcard(require("./API"));
|
|
16
|
+
var queries = _interopRequireWildcard(require("./queries"));
|
|
17
|
+
var mutations = _interopRequireWildcard(require("./mutations"));
|
|
18
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
22
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
23
|
+
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; }
|
|
24
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
25
|
+
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); }
|
|
26
|
+
const NO_CACHE = 'no-cache';
|
|
27
|
+
const CACHE_FIRST = 'cache-first';
|
|
28
|
+
const fragmentMatcher = new _apolloCacheInmemory.IntrospectionFragmentMatcher({
|
|
29
|
+
introspectionQueryResultData: _fragmentTypes.default
|
|
30
|
+
});
|
|
31
|
+
function transformPullRequest(pr) {
|
|
32
|
+
return _objectSpread(_objectSpread({}, pr), {}, {
|
|
33
|
+
labels: pr.labels.nodes,
|
|
34
|
+
head: {
|
|
35
|
+
ref: pr.headRefName,
|
|
36
|
+
sha: pr.headRefOid,
|
|
37
|
+
repo: {
|
|
38
|
+
fork: pr.repository.isFork
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
base: {
|
|
42
|
+
ref: pr.baseRefName,
|
|
43
|
+
sha: pr.baseRefOid
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
class GraphQLAPI extends _API.default {
|
|
48
|
+
constructor(config) {
|
|
49
|
+
super(config);
|
|
50
|
+
_defineProperty(this, "client", void 0);
|
|
51
|
+
this.client = this.getApolloClient();
|
|
52
|
+
}
|
|
53
|
+
getApolloClient() {
|
|
54
|
+
const authLink = (0, _apolloLinkContext.setContext)((_, {
|
|
55
|
+
headers
|
|
56
|
+
}) => {
|
|
57
|
+
return {
|
|
58
|
+
headers: _objectSpread(_objectSpread({
|
|
59
|
+
'Content-Type': 'application/json; charset=utf-8'
|
|
60
|
+
}, headers), {}, {
|
|
61
|
+
authorization: this.token ? `token ${this.token}` : ''
|
|
62
|
+
})
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
const httpLink = (0, _apolloLinkHttp.createHttpLink)({
|
|
66
|
+
uri: `${this.apiRoot}/graphql`
|
|
67
|
+
});
|
|
68
|
+
return new _apolloClient.ApolloClient({
|
|
69
|
+
link: authLink.concat(httpLink),
|
|
70
|
+
cache: new _apolloCacheInmemory.InMemoryCache({
|
|
71
|
+
fragmentMatcher
|
|
72
|
+
}),
|
|
73
|
+
defaultOptions: {
|
|
74
|
+
watchQuery: {
|
|
75
|
+
fetchPolicy: NO_CACHE,
|
|
76
|
+
errorPolicy: 'ignore'
|
|
77
|
+
},
|
|
78
|
+
query: {
|
|
79
|
+
fetchPolicy: NO_CACHE,
|
|
80
|
+
errorPolicy: 'all'
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
reset() {
|
|
86
|
+
return this.client.resetStore();
|
|
87
|
+
}
|
|
88
|
+
async getRepository(owner, name) {
|
|
89
|
+
const {
|
|
90
|
+
data
|
|
91
|
+
} = await this.query({
|
|
92
|
+
query: queries.repository,
|
|
93
|
+
variables: {
|
|
94
|
+
owner,
|
|
95
|
+
name
|
|
96
|
+
},
|
|
97
|
+
fetchPolicy: CACHE_FIRST // repository id doesn't change
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
return data.repository;
|
|
101
|
+
}
|
|
102
|
+
query(options) {
|
|
103
|
+
return this.client.query(options).catch(error => {
|
|
104
|
+
throw new _decapCmsLibUtil.APIError(error.message, 500, 'GitHub');
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
async mutate(options) {
|
|
108
|
+
try {
|
|
109
|
+
const result = await this.client.mutate(options);
|
|
110
|
+
return result;
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const errors = error.graphQLErrors;
|
|
113
|
+
if (Array.isArray(errors) && errors.some(e => e.message === 'Ref cannot be created.')) {
|
|
114
|
+
var _options$variables, _options$variables$cr;
|
|
115
|
+
const refName = (options === null || options === void 0 ? void 0 : (_options$variables = options.variables) === null || _options$variables === void 0 ? void 0 : (_options$variables$cr = _options$variables.createRefInput) === null || _options$variables$cr === void 0 ? void 0 : _options$variables$cr.name) || '';
|
|
116
|
+
const branchName = (0, _trimStart2.default)(refName, 'refs/heads/');
|
|
117
|
+
if (branchName) {
|
|
118
|
+
await (0, _decapCmsLibUtil.throwOnConflictingBranches)(branchName, name => this.getBranch(name), _API.API_NAME);
|
|
119
|
+
}
|
|
120
|
+
} else if (Array.isArray(errors) && errors.some(e => new RegExp(`A ref named "refs/heads/${_decapCmsLibUtil.CMS_BRANCH_PREFIX}/.+?" already exists in the repository.`).test(e.message))) {
|
|
121
|
+
var _options$variables2, _options$variables2$c, _options$variables3, _options$variables3$c;
|
|
122
|
+
const refName = (options === null || options === void 0 ? void 0 : (_options$variables2 = options.variables) === null || _options$variables2 === void 0 ? void 0 : (_options$variables2$c = _options$variables2.createRefInput) === null || _options$variables2$c === void 0 ? void 0 : _options$variables2$c.name) || '';
|
|
123
|
+
const sha = (options === null || options === void 0 ? void 0 : (_options$variables3 = options.variables) === null || _options$variables3 === void 0 ? void 0 : (_options$variables3$c = _options$variables3.createRefInput) === null || _options$variables3$c === void 0 ? void 0 : _options$variables3$c.oid) || '';
|
|
124
|
+
const branchName = (0, _trimStart2.default)(refName, 'refs/heads/');
|
|
125
|
+
if (branchName && branchName.startsWith(`${_decapCmsLibUtil.CMS_BRANCH_PREFIX}/`) && sha) {
|
|
126
|
+
try {
|
|
127
|
+
// this can happen if the branch wasn't deleted when the PR was merged
|
|
128
|
+
// we backup the existing branch just in case an re-run the mutation
|
|
129
|
+
await this.backupBranch(branchName);
|
|
130
|
+
await this.deleteBranch(branchName);
|
|
131
|
+
const result = await this.client.mutate(options);
|
|
132
|
+
return result;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
console.log(e);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw new _decapCmsLibUtil.APIError(error.message, 500, 'GitHub');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async hasWriteAccess() {
|
|
142
|
+
const {
|
|
143
|
+
repoOwner: owner,
|
|
144
|
+
repoName: name
|
|
145
|
+
} = this;
|
|
146
|
+
try {
|
|
147
|
+
const {
|
|
148
|
+
data
|
|
149
|
+
} = await this.query({
|
|
150
|
+
query: queries.repoPermission,
|
|
151
|
+
variables: {
|
|
152
|
+
owner,
|
|
153
|
+
name
|
|
154
|
+
},
|
|
155
|
+
fetchPolicy: CACHE_FIRST // we can assume permission doesn't change often
|
|
156
|
+
});
|
|
157
|
+
// https://developer.github.com/v4/enum/repositorypermission/
|
|
158
|
+
const {
|
|
159
|
+
viewerPermission
|
|
160
|
+
} = data.repository;
|
|
161
|
+
return ['ADMIN', 'MAINTAIN', 'WRITE'].includes(viewerPermission);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.error('Problem fetching repo data from GitHub');
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async user() {
|
|
168
|
+
const {
|
|
169
|
+
data
|
|
170
|
+
} = await this.query({
|
|
171
|
+
query: queries.user,
|
|
172
|
+
fetchPolicy: CACHE_FIRST // we can assume user details don't change often
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return data.viewer;
|
|
176
|
+
}
|
|
177
|
+
async retrieveBlobObject(owner, name, expression, options = {}) {
|
|
178
|
+
const {
|
|
179
|
+
data
|
|
180
|
+
} = await this.query(_objectSpread({
|
|
181
|
+
query: queries.blob,
|
|
182
|
+
variables: {
|
|
183
|
+
owner,
|
|
184
|
+
name,
|
|
185
|
+
expression
|
|
186
|
+
}
|
|
187
|
+
}, options));
|
|
188
|
+
// https://developer.github.com/v4/object/blob/
|
|
189
|
+
if (data.repository.object) {
|
|
190
|
+
const {
|
|
191
|
+
is_binary: isBinary,
|
|
192
|
+
text
|
|
193
|
+
} = data.repository.object;
|
|
194
|
+
return {
|
|
195
|
+
isNull: false,
|
|
196
|
+
isBinary,
|
|
197
|
+
text
|
|
198
|
+
};
|
|
199
|
+
} else {
|
|
200
|
+
return {
|
|
201
|
+
isNull: true
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
getOwnerAndNameFromRepoUrl(repoURL) {
|
|
206
|
+
let {
|
|
207
|
+
repoOwner: owner,
|
|
208
|
+
repoName: name
|
|
209
|
+
} = this;
|
|
210
|
+
if (repoURL === this.originRepoURL) {
|
|
211
|
+
({
|
|
212
|
+
originRepoOwner: owner,
|
|
213
|
+
originRepoName: name
|
|
214
|
+
} = this);
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
owner,
|
|
218
|
+
name
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
async readFile(path, sha, {
|
|
222
|
+
branch = this.branch,
|
|
223
|
+
repoURL = this.repoURL,
|
|
224
|
+
parseText = true
|
|
225
|
+
} = {}) {
|
|
226
|
+
if (!sha) {
|
|
227
|
+
sha = await this.getFileSha(path, {
|
|
228
|
+
repoURL,
|
|
229
|
+
branch
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
const fetchContent = () => this.fetchBlobContent({
|
|
233
|
+
sha: sha,
|
|
234
|
+
repoURL,
|
|
235
|
+
parseText
|
|
236
|
+
});
|
|
237
|
+
const content = await (0, _decapCmsLibUtil.readFile)(sha, fetchContent, _decapCmsLibUtil.localForage, parseText);
|
|
238
|
+
return content;
|
|
239
|
+
}
|
|
240
|
+
async fetchBlobContent({
|
|
241
|
+
sha,
|
|
242
|
+
repoURL,
|
|
243
|
+
parseText
|
|
244
|
+
}) {
|
|
245
|
+
if (!parseText) {
|
|
246
|
+
return super.fetchBlobContent({
|
|
247
|
+
sha,
|
|
248
|
+
repoURL,
|
|
249
|
+
parseText
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
const {
|
|
253
|
+
owner,
|
|
254
|
+
name
|
|
255
|
+
} = this.getOwnerAndNameFromRepoUrl(repoURL);
|
|
256
|
+
const {
|
|
257
|
+
isNull,
|
|
258
|
+
isBinary,
|
|
259
|
+
text
|
|
260
|
+
} = await this.retrieveBlobObject(owner, name, sha, {
|
|
261
|
+
fetchPolicy: CACHE_FIRST
|
|
262
|
+
} // blob sha is derived from file content
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
if (isNull) {
|
|
266
|
+
throw new _decapCmsLibUtil.APIError('Not Found', 404, 'GitHub');
|
|
267
|
+
} else if (!isBinary) {
|
|
268
|
+
return text;
|
|
269
|
+
} else {
|
|
270
|
+
return super.fetchBlobContent({
|
|
271
|
+
sha,
|
|
272
|
+
repoURL,
|
|
273
|
+
parseText
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async getPullRequestAuthor(pullRequest) {
|
|
278
|
+
const user = pullRequest.user;
|
|
279
|
+
return (user === null || user === void 0 ? void 0 : user.name) || (user === null || user === void 0 ? void 0 : user.login);
|
|
280
|
+
}
|
|
281
|
+
async getPullRequests(head, state, predicate) {
|
|
282
|
+
const {
|
|
283
|
+
originRepoOwner: owner,
|
|
284
|
+
originRepoName: name
|
|
285
|
+
} = this;
|
|
286
|
+
let states;
|
|
287
|
+
if (state === _API.PullRequestState.Open) {
|
|
288
|
+
states = ['OPEN'];
|
|
289
|
+
} else if (state === _API.PullRequestState.Closed) {
|
|
290
|
+
states = ['CLOSED', 'MERGED'];
|
|
291
|
+
} else {
|
|
292
|
+
states = ['OPEN', 'CLOSED', 'MERGED'];
|
|
293
|
+
}
|
|
294
|
+
const {
|
|
295
|
+
data
|
|
296
|
+
} = await this.query({
|
|
297
|
+
query: queries.pullRequests,
|
|
298
|
+
variables: _objectSpread(_objectSpread({
|
|
299
|
+
owner,
|
|
300
|
+
name
|
|
301
|
+
}, head ? {
|
|
302
|
+
head
|
|
303
|
+
} : {}), {}, {
|
|
304
|
+
states
|
|
305
|
+
})
|
|
306
|
+
});
|
|
307
|
+
const {
|
|
308
|
+
pullRequests
|
|
309
|
+
} = data.repository;
|
|
310
|
+
const mapped = pullRequests.nodes.map(transformPullRequest);
|
|
311
|
+
return mapped.filter(pr => pr.head.ref.startsWith(`${_decapCmsLibUtil.CMS_BRANCH_PREFIX}/`) && predicate(pr));
|
|
312
|
+
}
|
|
313
|
+
async getOpenAuthoringBranches() {
|
|
314
|
+
const {
|
|
315
|
+
repoOwner: owner,
|
|
316
|
+
repoName: name
|
|
317
|
+
} = this;
|
|
318
|
+
const {
|
|
319
|
+
data
|
|
320
|
+
} = await this.query({
|
|
321
|
+
query: queries.openAuthoringBranches,
|
|
322
|
+
variables: {
|
|
323
|
+
owner,
|
|
324
|
+
name,
|
|
325
|
+
refPrefix: `refs/heads/cms/${this.repo}/`
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
return data.repository.refs.nodes.map(({
|
|
329
|
+
name,
|
|
330
|
+
prefix
|
|
331
|
+
}) => ({
|
|
332
|
+
ref: `${prefix}${name}`
|
|
333
|
+
}));
|
|
334
|
+
}
|
|
335
|
+
async getStatuses(collectionName, slug) {
|
|
336
|
+
const contentKey = this.generateContentKey(collectionName, slug);
|
|
337
|
+
const branch = (0, _decapCmsLibUtil.branchFromContentKey)(contentKey);
|
|
338
|
+
const pullRequest = await this.getBranchPullRequest(branch);
|
|
339
|
+
const sha = pullRequest.head.sha;
|
|
340
|
+
const {
|
|
341
|
+
originRepoOwner: owner,
|
|
342
|
+
originRepoName: name
|
|
343
|
+
} = this;
|
|
344
|
+
const {
|
|
345
|
+
data
|
|
346
|
+
} = await this.query({
|
|
347
|
+
query: queries.statues,
|
|
348
|
+
variables: {
|
|
349
|
+
owner,
|
|
350
|
+
name,
|
|
351
|
+
sha
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
if (data.repository.object) {
|
|
355
|
+
const {
|
|
356
|
+
status
|
|
357
|
+
} = data.repository.object;
|
|
358
|
+
const {
|
|
359
|
+
contexts
|
|
360
|
+
} = status || {
|
|
361
|
+
contexts: []
|
|
362
|
+
};
|
|
363
|
+
return contexts;
|
|
364
|
+
} else {
|
|
365
|
+
return [];
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
getAllFiles(entries, path) {
|
|
369
|
+
const allFiles = entries.reduce((acc, item) => {
|
|
370
|
+
if (item.type === 'tree') {
|
|
371
|
+
var _item$object;
|
|
372
|
+
const entries = ((_item$object = item.object) === null || _item$object === void 0 ? void 0 : _item$object.entries) || [];
|
|
373
|
+
return [...acc, ...this.getAllFiles(entries, `${path}/${item.name}`)];
|
|
374
|
+
} else if (item.type === 'blob') {
|
|
375
|
+
return [...acc, {
|
|
376
|
+
name: item.name,
|
|
377
|
+
type: item.type,
|
|
378
|
+
id: item.sha,
|
|
379
|
+
path: `${path}/${item.name}`,
|
|
380
|
+
size: item.blob ? item.blob.size : 0
|
|
381
|
+
}];
|
|
382
|
+
}
|
|
383
|
+
return acc;
|
|
384
|
+
}, []);
|
|
385
|
+
return allFiles;
|
|
386
|
+
}
|
|
387
|
+
async listFiles(path, {
|
|
388
|
+
repoURL = this.repoURL,
|
|
389
|
+
branch = this.branch,
|
|
390
|
+
depth = 1
|
|
391
|
+
} = {}) {
|
|
392
|
+
const {
|
|
393
|
+
owner,
|
|
394
|
+
name
|
|
395
|
+
} = this.getOwnerAndNameFromRepoUrl(repoURL);
|
|
396
|
+
const folder = (0, _trim2.default)(path, '/');
|
|
397
|
+
const {
|
|
398
|
+
data
|
|
399
|
+
} = await this.query({
|
|
400
|
+
query: queries.files(depth),
|
|
401
|
+
variables: {
|
|
402
|
+
owner,
|
|
403
|
+
name,
|
|
404
|
+
expression: `${branch}:${folder}`
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
if (data.repository.object) {
|
|
408
|
+
const allFiles = this.getAllFiles(data.repository.object.entries, folder);
|
|
409
|
+
return allFiles;
|
|
410
|
+
} else {
|
|
411
|
+
return [];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
getBranchQualifiedName(branch) {
|
|
415
|
+
return `refs/heads/${branch}`;
|
|
416
|
+
}
|
|
417
|
+
getBranchQuery(branch, owner, name) {
|
|
418
|
+
return {
|
|
419
|
+
query: queries.branch,
|
|
420
|
+
variables: {
|
|
421
|
+
owner,
|
|
422
|
+
name,
|
|
423
|
+
qualifiedName: this.getBranchQualifiedName(branch)
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
async getDefaultBranch() {
|
|
428
|
+
const {
|
|
429
|
+
data
|
|
430
|
+
} = await this.query(_objectSpread({}, this.getBranchQuery(this.branch, this.originRepoOwner, this.originRepoName)));
|
|
431
|
+
return data.repository.branch;
|
|
432
|
+
}
|
|
433
|
+
async getBranch(branch) {
|
|
434
|
+
const {
|
|
435
|
+
data
|
|
436
|
+
} = await this.query(_objectSpread(_objectSpread({}, this.getBranchQuery(branch, this.repoOwner, this.repoName)), {}, {
|
|
437
|
+
fetchPolicy: CACHE_FIRST
|
|
438
|
+
}));
|
|
439
|
+
if (!data.repository.branch) {
|
|
440
|
+
throw new _decapCmsLibUtil.APIError('Branch not found', 404, _API.API_NAME);
|
|
441
|
+
}
|
|
442
|
+
return data.repository.branch;
|
|
443
|
+
}
|
|
444
|
+
async patchRef(type, name, sha, opts = {}) {
|
|
445
|
+
if (type !== 'heads') {
|
|
446
|
+
return super.patchRef(type, name, sha, opts);
|
|
447
|
+
}
|
|
448
|
+
const force = opts.force || false;
|
|
449
|
+
const branch = await this.getBranch(name);
|
|
450
|
+
const {
|
|
451
|
+
data
|
|
452
|
+
} = await this.mutate({
|
|
453
|
+
mutation: mutations.updateBranch,
|
|
454
|
+
variables: {
|
|
455
|
+
input: {
|
|
456
|
+
oid: sha,
|
|
457
|
+
refId: branch.id,
|
|
458
|
+
force
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
return data.updateRef.branch;
|
|
463
|
+
}
|
|
464
|
+
async deleteBranch(branchName) {
|
|
465
|
+
const branch = await this.getBranch(branchName);
|
|
466
|
+
const {
|
|
467
|
+
data
|
|
468
|
+
} = await this.mutate({
|
|
469
|
+
mutation: mutations.deleteBranch,
|
|
470
|
+
variables: {
|
|
471
|
+
deleteRefInput: {
|
|
472
|
+
refId: branch.id
|
|
473
|
+
}
|
|
474
|
+
},
|
|
475
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
476
|
+
update: store => store.data.delete((0, _apolloCacheInmemory.defaultDataIdFromObject)(branch))
|
|
477
|
+
});
|
|
478
|
+
return data.deleteRef;
|
|
479
|
+
}
|
|
480
|
+
getPullRequestQuery(number) {
|
|
481
|
+
const {
|
|
482
|
+
originRepoOwner: owner,
|
|
483
|
+
originRepoName: name
|
|
484
|
+
} = this;
|
|
485
|
+
return {
|
|
486
|
+
query: queries.pullRequest,
|
|
487
|
+
variables: {
|
|
488
|
+
owner,
|
|
489
|
+
name,
|
|
490
|
+
number
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
async getPullRequest(number) {
|
|
495
|
+
const {
|
|
496
|
+
data
|
|
497
|
+
} = await this.query(_objectSpread(_objectSpread({}, this.getPullRequestQuery(number)), {}, {
|
|
498
|
+
fetchPolicy: CACHE_FIRST
|
|
499
|
+
}));
|
|
500
|
+
|
|
501
|
+
// https://developer.github.com/v4/enum/pullrequeststate/
|
|
502
|
+
// GraphQL state: [CLOSED, MERGED, OPEN]
|
|
503
|
+
// REST API state: [closed, open]
|
|
504
|
+
const state = data.repository.pullRequest.state === 'OPEN' ? _API.PullRequestState.Open : _API.PullRequestState.Closed;
|
|
505
|
+
return _objectSpread(_objectSpread({}, data.repository.pullRequest), {}, {
|
|
506
|
+
state
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
getPullRequestAndBranchQuery(branch, number) {
|
|
510
|
+
const {
|
|
511
|
+
repoOwner: owner,
|
|
512
|
+
repoName: name
|
|
513
|
+
} = this;
|
|
514
|
+
const {
|
|
515
|
+
originRepoOwner,
|
|
516
|
+
originRepoName
|
|
517
|
+
} = this;
|
|
518
|
+
return {
|
|
519
|
+
query: queries.pullRequestAndBranch,
|
|
520
|
+
variables: {
|
|
521
|
+
owner,
|
|
522
|
+
name,
|
|
523
|
+
originRepoOwner,
|
|
524
|
+
originRepoName,
|
|
525
|
+
number,
|
|
526
|
+
qualifiedName: this.getBranchQualifiedName(branch)
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
async getPullRequestAndBranch(branch, number) {
|
|
531
|
+
const {
|
|
532
|
+
data
|
|
533
|
+
} = await this.query(_objectSpread(_objectSpread({}, this.getPullRequestAndBranchQuery(branch, number)), {}, {
|
|
534
|
+
fetchPolicy: CACHE_FIRST
|
|
535
|
+
}));
|
|
536
|
+
const {
|
|
537
|
+
repository,
|
|
538
|
+
origin
|
|
539
|
+
} = data;
|
|
540
|
+
return {
|
|
541
|
+
branch: repository.branch,
|
|
542
|
+
pullRequest: origin.pullRequest
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
async openPR(number) {
|
|
546
|
+
const pullRequest = await this.getPullRequest(number);
|
|
547
|
+
const {
|
|
548
|
+
data
|
|
549
|
+
} = await this.mutate({
|
|
550
|
+
mutation: mutations.reopenPullRequest,
|
|
551
|
+
variables: {
|
|
552
|
+
reopenPullRequestInput: {
|
|
553
|
+
pullRequestId: pullRequest.id
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
update: (store, {
|
|
557
|
+
data: mutationResult
|
|
558
|
+
}) => {
|
|
559
|
+
const {
|
|
560
|
+
pullRequest
|
|
561
|
+
} = mutationResult.reopenPullRequest;
|
|
562
|
+
const pullRequestData = {
|
|
563
|
+
repository: _objectSpread(_objectSpread({}, pullRequest.repository), {}, {
|
|
564
|
+
pullRequest
|
|
565
|
+
})
|
|
566
|
+
};
|
|
567
|
+
store.writeQuery(_objectSpread(_objectSpread({}, this.getPullRequestQuery(pullRequest.number)), {}, {
|
|
568
|
+
data: pullRequestData
|
|
569
|
+
}));
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
return data.reopenPullRequest;
|
|
573
|
+
}
|
|
574
|
+
async closePR(number) {
|
|
575
|
+
const pullRequest = await this.getPullRequest(number);
|
|
576
|
+
const {
|
|
577
|
+
data
|
|
578
|
+
} = await this.mutate({
|
|
579
|
+
mutation: mutations.closePullRequest,
|
|
580
|
+
variables: {
|
|
581
|
+
closePullRequestInput: {
|
|
582
|
+
pullRequestId: pullRequest.id
|
|
583
|
+
}
|
|
584
|
+
},
|
|
585
|
+
update: (store, {
|
|
586
|
+
data: mutationResult
|
|
587
|
+
}) => {
|
|
588
|
+
const {
|
|
589
|
+
pullRequest
|
|
590
|
+
} = mutationResult.closePullRequest;
|
|
591
|
+
const pullRequestData = {
|
|
592
|
+
repository: _objectSpread(_objectSpread({}, pullRequest.repository), {}, {
|
|
593
|
+
pullRequest
|
|
594
|
+
})
|
|
595
|
+
};
|
|
596
|
+
store.writeQuery(_objectSpread(_objectSpread({}, this.getPullRequestQuery(pullRequest.number)), {}, {
|
|
597
|
+
data: pullRequestData
|
|
598
|
+
}));
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
return data.closePullRequest;
|
|
602
|
+
}
|
|
603
|
+
async deleteUnpublishedEntry(collectionName, slug) {
|
|
604
|
+
try {
|
|
605
|
+
const contentKey = this.generateContentKey(collectionName, slug);
|
|
606
|
+
const branchName = (0, _decapCmsLibUtil.branchFromContentKey)(contentKey);
|
|
607
|
+
const pr = await this.getBranchPullRequest(branchName);
|
|
608
|
+
if (pr.number !== _API.MOCK_PULL_REQUEST) {
|
|
609
|
+
const {
|
|
610
|
+
branch,
|
|
611
|
+
pullRequest
|
|
612
|
+
} = await this.getPullRequestAndBranch(branchName, pr.number);
|
|
613
|
+
const {
|
|
614
|
+
data
|
|
615
|
+
} = await this.mutate({
|
|
616
|
+
mutation: mutations.closePullRequestAndDeleteBranch,
|
|
617
|
+
variables: {
|
|
618
|
+
deleteRefInput: {
|
|
619
|
+
refId: branch.id
|
|
620
|
+
},
|
|
621
|
+
closePullRequestInput: {
|
|
622
|
+
pullRequestId: pullRequest.id
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
626
|
+
update: store => {
|
|
627
|
+
store.data.delete((0, _apolloCacheInmemory.defaultDataIdFromObject)(branch));
|
|
628
|
+
store.data.delete((0, _apolloCacheInmemory.defaultDataIdFromObject)(pullRequest));
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
return data.closePullRequest;
|
|
632
|
+
} else {
|
|
633
|
+
return await this.deleteBranch(branchName);
|
|
634
|
+
}
|
|
635
|
+
} catch (e) {
|
|
636
|
+
const {
|
|
637
|
+
graphQLErrors
|
|
638
|
+
} = e;
|
|
639
|
+
if (graphQLErrors && graphQLErrors.length > 0) {
|
|
640
|
+
const branchNotFound = graphQLErrors.some(e => e.type === 'NOT_FOUND');
|
|
641
|
+
if (branchNotFound) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
throw e;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
async createPR(title, head) {
|
|
649
|
+
const [repository, headReference] = await Promise.all([this.getRepository(this.originRepoOwner, this.originRepoName), this.useOpenAuthoring ? `${(await this.user()).login}:${head}` : head]);
|
|
650
|
+
const {
|
|
651
|
+
data
|
|
652
|
+
} = await this.mutate({
|
|
653
|
+
mutation: mutations.createPullRequest,
|
|
654
|
+
variables: {
|
|
655
|
+
createPullRequestInput: {
|
|
656
|
+
baseRefName: this.branch,
|
|
657
|
+
body: _decapCmsLibUtil.DEFAULT_PR_BODY,
|
|
658
|
+
title,
|
|
659
|
+
headRefName: headReference,
|
|
660
|
+
repositoryId: repository.id
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
update: (store, {
|
|
664
|
+
data: mutationResult
|
|
665
|
+
}) => {
|
|
666
|
+
const {
|
|
667
|
+
pullRequest
|
|
668
|
+
} = mutationResult.createPullRequest;
|
|
669
|
+
const pullRequestData = {
|
|
670
|
+
repository: _objectSpread(_objectSpread({}, pullRequest.repository), {}, {
|
|
671
|
+
pullRequest
|
|
672
|
+
})
|
|
673
|
+
};
|
|
674
|
+
store.writeQuery(_objectSpread(_objectSpread({}, this.getPullRequestQuery(pullRequest.number)), {}, {
|
|
675
|
+
data: pullRequestData
|
|
676
|
+
}));
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
const {
|
|
680
|
+
pullRequest
|
|
681
|
+
} = data.createPullRequest;
|
|
682
|
+
return _objectSpread(_objectSpread({}, pullRequest), {}, {
|
|
683
|
+
head: {
|
|
684
|
+
sha: pullRequest.headRefOid
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
async createBranch(branchName, sha) {
|
|
689
|
+
const owner = this.repoOwner;
|
|
690
|
+
const name = this.repoName;
|
|
691
|
+
const repository = await this.getRepository(owner, name);
|
|
692
|
+
const {
|
|
693
|
+
data
|
|
694
|
+
} = await this.mutate({
|
|
695
|
+
mutation: mutations.createBranch,
|
|
696
|
+
variables: {
|
|
697
|
+
createRefInput: {
|
|
698
|
+
name: this.getBranchQualifiedName(branchName),
|
|
699
|
+
oid: sha,
|
|
700
|
+
repositoryId: repository.id
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
update: (store, {
|
|
704
|
+
data: mutationResult
|
|
705
|
+
}) => {
|
|
706
|
+
const {
|
|
707
|
+
branch
|
|
708
|
+
} = mutationResult.createRef;
|
|
709
|
+
const branchData = {
|
|
710
|
+
repository: _objectSpread(_objectSpread({}, branch.repository), {}, {
|
|
711
|
+
branch
|
|
712
|
+
})
|
|
713
|
+
};
|
|
714
|
+
store.writeQuery(_objectSpread(_objectSpread({}, this.getBranchQuery(branchName, owner, name)), {}, {
|
|
715
|
+
data: branchData
|
|
716
|
+
}));
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
const {
|
|
720
|
+
branch
|
|
721
|
+
} = data.createRef;
|
|
722
|
+
return _objectSpread(_objectSpread({}, branch), {}, {
|
|
723
|
+
ref: `${branch.prefix}${branch.name}`
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
async createBranchAndPullRequest(branchName, sha, title) {
|
|
727
|
+
const owner = this.originRepoOwner;
|
|
728
|
+
const name = this.originRepoName;
|
|
729
|
+
const repository = await this.getRepository(owner, name);
|
|
730
|
+
const {
|
|
731
|
+
data
|
|
732
|
+
} = await this.mutate({
|
|
733
|
+
mutation: mutations.createBranchAndPullRequest,
|
|
734
|
+
variables: {
|
|
735
|
+
createRefInput: {
|
|
736
|
+
name: this.getBranchQualifiedName(branchName),
|
|
737
|
+
oid: sha,
|
|
738
|
+
repositoryId: repository.id
|
|
739
|
+
},
|
|
740
|
+
createPullRequestInput: {
|
|
741
|
+
baseRefName: this.branch,
|
|
742
|
+
body: _decapCmsLibUtil.DEFAULT_PR_BODY,
|
|
743
|
+
title,
|
|
744
|
+
headRefName: branchName,
|
|
745
|
+
repositoryId: repository.id
|
|
746
|
+
}
|
|
747
|
+
},
|
|
748
|
+
update: (store, {
|
|
749
|
+
data: mutationResult
|
|
750
|
+
}) => {
|
|
751
|
+
const {
|
|
752
|
+
branch
|
|
753
|
+
} = mutationResult.createRef;
|
|
754
|
+
const {
|
|
755
|
+
pullRequest
|
|
756
|
+
} = mutationResult.createPullRequest;
|
|
757
|
+
const branchData = {
|
|
758
|
+
repository: _objectSpread(_objectSpread({}, branch.repository), {}, {
|
|
759
|
+
branch
|
|
760
|
+
})
|
|
761
|
+
};
|
|
762
|
+
const pullRequestData = {
|
|
763
|
+
repository: _objectSpread(_objectSpread({}, pullRequest.repository), {}, {
|
|
764
|
+
branch
|
|
765
|
+
}),
|
|
766
|
+
origin: _objectSpread(_objectSpread({}, pullRequest.repository), {}, {
|
|
767
|
+
pullRequest
|
|
768
|
+
})
|
|
769
|
+
};
|
|
770
|
+
store.writeQuery(_objectSpread(_objectSpread({}, this.getBranchQuery(branchName, owner, name)), {}, {
|
|
771
|
+
data: branchData
|
|
772
|
+
}));
|
|
773
|
+
store.writeQuery(_objectSpread(_objectSpread({}, this.getPullRequestAndBranchQuery(branchName, pullRequest.number)), {}, {
|
|
774
|
+
data: pullRequestData
|
|
775
|
+
}));
|
|
776
|
+
}
|
|
777
|
+
});
|
|
778
|
+
const {
|
|
779
|
+
pullRequest
|
|
780
|
+
} = data.createPullRequest;
|
|
781
|
+
return transformPullRequest(pullRequest);
|
|
782
|
+
}
|
|
783
|
+
async getFileSha(path, {
|
|
784
|
+
repoURL = this.repoURL,
|
|
785
|
+
branch = this.branch
|
|
786
|
+
} = {}) {
|
|
787
|
+
const {
|
|
788
|
+
owner,
|
|
789
|
+
name
|
|
790
|
+
} = this.getOwnerAndNameFromRepoUrl(repoURL);
|
|
791
|
+
const {
|
|
792
|
+
data
|
|
793
|
+
} = await this.query({
|
|
794
|
+
query: queries.fileSha,
|
|
795
|
+
variables: {
|
|
796
|
+
owner,
|
|
797
|
+
name,
|
|
798
|
+
expression: `${branch}:${path}`
|
|
799
|
+
}
|
|
800
|
+
});
|
|
801
|
+
if (data.repository.file) {
|
|
802
|
+
return data.repository.file.sha;
|
|
803
|
+
}
|
|
804
|
+
throw new _decapCmsLibUtil.APIError('Not Found', 404, _API.API_NAME);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
exports.default = GraphQLAPI;
|