decap-cms-backend-github 3.6.0 → 3.7.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/dist/esm/API.js CHANGED
@@ -7,8 +7,8 @@ import result from 'lodash/result';
7
7
  import trimStart from 'lodash/trimStart';
8
8
  import trim from 'lodash/trim';
9
9
  import { oneLine } from 'common-tags';
10
- import { getAllResponses, APIError, EditorialWorkflowError, localForage, basename, readFileMetadata, CMS_BRANCH_PREFIX, generateContentKey, DEFAULT_PR_BODY, MERGE_COMMIT_MESSAGE, PreviewState, parseContentKey, branchFromContentKey, isCMSLabel, labelToStatus, statusToLabel, contentKeyFromBranch, requestWithBackoff, unsentRequest, throwOnConflictingBranches } from 'decap-cms-lib-util';
11
10
  import { dirname } from 'path';
11
+ import { getAllResponses, APIError, EditorialWorkflowError, localForage, basename, readFileMetadata, CMS_BRANCH_PREFIX, generateContentKey, DEFAULT_PR_BODY, MERGE_COMMIT_MESSAGE, PreviewState, parseContentKey, branchFromContentKey, isCMSLabel, labelToStatus, statusToLabel, contentKeyFromBranch, requestWithBackoff, unsentRequest, throwOnConflictingBranches } from 'decap-cms-lib-util';
12
12
  export const API_NAME = 'GitHub';
13
13
  export const MOCK_PULL_REQUEST = -1;
14
14
  var GitHubCommitStatusState = /*#__PURE__*/function (GitHubCommitStatusState) {
@@ -758,9 +758,10 @@ export default class API {
758
758
  const contentKey = this.generateContentKey(options.collectionName, slug);
759
759
  const branch = branchFromContentKey(contentKey);
760
760
  const unpublished = options.unpublished || false;
761
+ const hasSubfolders = options.hasSubfolders !== false; // default to true
761
762
  if (!unpublished) {
762
763
  const branchData = await this.getDefaultBranch();
763
- const changeTree = await this.updateTree(branchData.commit.sha, files);
764
+ const changeTree = await this.updateTree(branchData.commit.sha, files, this.branch, hasSubfolders);
764
765
  const commitResponse = await this.commit(options.commitMessage, changeTree);
765
766
  if (this.useOpenAuthoring) {
766
767
  await this.createBranch(branch, commitResponse.sha);
@@ -788,7 +789,7 @@ export default class API {
788
789
  // rebase the branch before applying new changes
789
790
  const rebasedHead = await this.rebaseBranch(branch);
790
791
  const treeFiles = mediaFilesToRemove.concat(files);
791
- const changeTree = await this.updateTree(rebasedHead.sha, treeFiles, branch);
792
+ const changeTree = await this.updateTree(rebasedHead.sha, treeFiles, branch, hasSubfolders);
792
793
  const commit = await this.commit(options.commitMessage, changeTree);
793
794
  return this.patchBranch(branch, commit.sha, {
794
795
  force: true
@@ -1104,7 +1105,7 @@ export default class API {
1104
1105
  item.sha = response.sha;
1105
1106
  return item;
1106
1107
  }
1107
- async updateTree(baseSha, files, branch = this.branch) {
1108
+ async updateTree(baseSha, files, branch = this.branch, hasSubfolders = true) {
1108
1109
  const toMove = [];
1109
1110
  const tree = files.reduce((acc, file) => {
1110
1111
  const entry = {
@@ -1129,27 +1130,47 @@ export default class API {
1129
1130
  to,
1130
1131
  sha
1131
1132
  } of toMove) {
1132
- const sourceDir = dirname(from);
1133
- const destDir = dirname(to);
1134
- const files = await this.listFiles(sourceDir, {
1135
- branch,
1136
- depth: 100
1137
- });
1138
- for (const file of files) {
1139
- // delete current path
1133
+ if (!hasSubfolders) {
1134
+ // New behavior (subfolders: false): Only move the specific file
1135
+ // Delete the file at the old path
1140
1136
  tree.push({
1141
- path: file.path,
1137
+ path: trimStart(from, '/'),
1142
1138
  mode: '100644',
1143
1139
  type: 'blob',
1144
1140
  sha: null
1145
1141
  });
1146
- // create in new path
1142
+ // Create the file at the new path
1147
1143
  tree.push({
1148
- path: file.path.replace(sourceDir, destDir),
1144
+ path: trimStart(to, '/'),
1149
1145
  mode: '100644',
1150
1146
  type: 'blob',
1151
- sha: file.path === from ? sha : file.id
1147
+ sha
1148
+ });
1149
+ } else {
1150
+ // Legacy behavior (subfolders: true, default): Move all files in the directory
1151
+ // This is for collections where all files in a folder represent a single entry
1152
+ const sourceDir = dirname(from);
1153
+ const destDir = dirname(to);
1154
+ const files = await this.listFiles(sourceDir, {
1155
+ branch,
1156
+ depth: 100
1152
1157
  });
1158
+ for (const file of files) {
1159
+ // delete current path
1160
+ tree.push({
1161
+ path: file.path,
1162
+ mode: '100644',
1163
+ type: 'blob',
1164
+ sha: null
1165
+ });
1166
+ // create in new path
1167
+ tree.push({
1168
+ path: file.path.replace(sourceDir, destDir),
1169
+ mode: '100644',
1170
+ type: 'blob',
1171
+ sha: file.path === from ? sha : file.id
1172
+ });
1173
+ }
1153
1174
  }
1154
1175
  }
1155
1176
  const newTree = await this.createTree(baseSha, tree);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "decap-cms-backend-github",
3
3
  "description": "GitHub backend for Decap CMS",
4
- "version": "3.6.0",
4
+ "version": "3.7.0",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-github",
7
7
  "bugs": "https://github.com/decaporg/decap-cms/issues",
@@ -44,5 +44,5 @@
44
44
  "browser": {
45
45
  "path": "path-browserify"
46
46
  },
47
- "gitHead": "45c9f5b9a1a12f74321ce4658b71ec88d6365ec1"
47
+ "gitHead": "ae01ad6f2b139f93472c8f0d049d35277d8583ca"
48
48
  }
package/src/API.ts CHANGED
@@ -7,6 +7,7 @@ import result from 'lodash/result';
7
7
  import trimStart from 'lodash/trimStart';
8
8
  import trim from 'lodash/trim';
9
9
  import { oneLine } from 'common-tags';
10
+ import { dirname } from 'path';
10
11
  import {
11
12
  getAllResponses,
12
13
  APIError,
@@ -29,7 +30,6 @@ import {
29
30
  unsentRequest,
30
31
  throwOnConflictingBranches,
31
32
  } from 'decap-cms-lib-util';
32
- import { dirname } from 'path';
33
33
 
34
34
  import type {
35
35
  AssetProxy,
@@ -1011,9 +1011,15 @@ export default class API {
1011
1011
  const contentKey = this.generateContentKey(options.collectionName as string, slug);
1012
1012
  const branch = branchFromContentKey(contentKey);
1013
1013
  const unpublished = options.unpublished || false;
1014
+ const hasSubfolders = options.hasSubfolders !== false; // default to true
1014
1015
  if (!unpublished) {
1015
1016
  const branchData = await this.getDefaultBranch();
1016
- const changeTree = await this.updateTree(branchData.commit.sha, files);
1017
+ const changeTree = await this.updateTree(
1018
+ branchData.commit.sha,
1019
+ files,
1020
+ this.branch,
1021
+ hasSubfolders,
1022
+ );
1017
1023
  const commitResponse = await this.commit(options.commitMessage, changeTree);
1018
1024
 
1019
1025
  if (this.useOpenAuthoring) {
@@ -1048,7 +1054,7 @@ export default class API {
1048
1054
  // rebase the branch before applying new changes
1049
1055
  const rebasedHead = await this.rebaseBranch(branch);
1050
1056
  const treeFiles = mediaFilesToRemove.concat(files);
1051
- const changeTree = await this.updateTree(rebasedHead.sha, treeFiles, branch);
1057
+ const changeTree = await this.updateTree(rebasedHead.sha, treeFiles, branch, hasSubfolders);
1052
1058
  const commit = await this.commit(options.commitMessage, changeTree);
1053
1059
 
1054
1060
  return this.patchBranch(branch, commit.sha, { force: true });
@@ -1418,6 +1424,7 @@ export default class API {
1418
1424
  baseSha: string,
1419
1425
  files: { path: string; sha: string | null; newPath?: string }[],
1420
1426
  branch = this.branch,
1427
+ hasSubfolders = true,
1421
1428
  ) {
1422
1429
  const toMove: { from: string; to: string; sha: string }[] = [];
1423
1430
  const tree = files.reduce((acc, file) => {
@@ -1438,24 +1445,44 @@ export default class API {
1438
1445
  }, [] as TreeEntry[]);
1439
1446
 
1440
1447
  for (const { from, to, sha } of toMove) {
1441
- const sourceDir = dirname(from);
1442
- const destDir = dirname(to);
1443
- const files = await this.listFiles(sourceDir, { branch, depth: 100 });
1444
- for (const file of files) {
1445
- // delete current path
1448
+ if (!hasSubfolders) {
1449
+ // New behavior (subfolders: false): Only move the specific file
1450
+ // Delete the file at the old path
1446
1451
  tree.push({
1447
- path: file.path,
1452
+ path: trimStart(from, '/'),
1448
1453
  mode: '100644',
1449
1454
  type: 'blob',
1450
1455
  sha: null,
1451
1456
  });
1452
- // create in new path
1457
+ // Create the file at the new path
1453
1458
  tree.push({
1454
- path: file.path.replace(sourceDir, destDir),
1459
+ path: trimStart(to, '/'),
1455
1460
  mode: '100644',
1456
1461
  type: 'blob',
1457
- sha: file.path === from ? sha : file.id,
1462
+ sha,
1458
1463
  });
1464
+ } else {
1465
+ // Legacy behavior (subfolders: true, default): Move all files in the directory
1466
+ // This is for collections where all files in a folder represent a single entry
1467
+ const sourceDir = dirname(from);
1468
+ const destDir = dirname(to);
1469
+ const files = await this.listFiles(sourceDir, { branch, depth: 100 });
1470
+ for (const file of files) {
1471
+ // delete current path
1472
+ tree.push({
1473
+ path: file.path,
1474
+ mode: '100644',
1475
+ type: 'blob',
1476
+ sha: null,
1477
+ });
1478
+ // create in new path
1479
+ tree.push({
1480
+ path: file.path.replace(sourceDir, destDir),
1481
+ mode: '100644',
1482
+ type: 'blob',
1483
+ sha: file.path === from ? sha : file.id,
1484
+ });
1485
+ }
1459
1486
  }
1460
1487
  }
1461
1488