decap-cms-backend-bitbucket 3.3.0 → 3.4.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
@@ -1,9 +1,9 @@
1
1
  import flow from 'lodash/flow';
2
2
  import get from 'lodash/get';
3
3
  import { localForage, unsentRequest, responseParser, then, basename, Cursor, APIError, readFile, CMS_BRANCH_PREFIX, generateContentKey, labelToStatus, isCMSLabel, EditorialWorkflowError, statusToLabel, DEFAULT_PR_BODY, MERGE_COMMIT_MESSAGE, PreviewState, parseContentKey, branchFromContentKey, requestWithBackoff, readFileMetadata, throwOnConflictingBranches } from 'decap-cms-lib-util';
4
- import { dirname } from 'path';
5
4
  import { oneLine } from 'common-tags';
6
5
  import { parse } from 'what-the-diff';
6
+ import { dirname } from 'path';
7
7
  var BitBucketPullRequestState = /*#__PURE__*/function (BitBucketPullRequestState) {
8
8
  BitBucketPullRequestState["MERGED"] = "MERGED";
9
9
  BitBucketPullRequestState["SUPERSEDED"] = "SUPERSEDED";
@@ -253,7 +253,8 @@ export default class API {
253
253
  async uploadFiles(files, {
254
254
  commitMessage,
255
255
  branch,
256
- parentSha
256
+ parentSha,
257
+ hasSubfolders = true
257
258
  }) {
258
259
  const formData = new FormData();
259
260
  const toMove = [];
@@ -266,7 +267,8 @@ export default class API {
266
267
  toMove.push({
267
268
  from: file.path,
268
269
  to: file.newPath,
269
- contentBlob
270
+ contentBlob,
271
+ hasSubfolders
270
272
  });
271
273
  } else {
272
274
  // add/modify the file
@@ -278,25 +280,39 @@ export default class API {
278
280
  for (const {
279
281
  from,
280
282
  to,
281
- contentBlob
283
+ contentBlob,
284
+ hasSubfolders
282
285
  } of toMove) {
283
- const sourceDir = dirname(from);
284
- const destDir = dirname(to);
285
- const filesBranch = parentSha ? this.branch : branch;
286
- const files = await this.listAllFiles(sourceDir, 100, filesBranch);
287
- for (const file of files) {
286
+ if (!hasSubfolders) {
287
+ // New behavior (subfolders: false): Only move the specific file
288
288
  // to move a file in Bitbucket we need to delete the old path
289
289
  // and upload the file content to the new path
290
290
  // NOTE: this is very wasteful, and also the Bitbucket `diff` API
291
291
  // reports these files as deleted+added instead of renamed
292
292
  // delete current path
293
- formData.append('files', file.path);
293
+ formData.append('files', from);
294
294
  // create in new path
295
- const content = file.path === from ? contentBlob : await this.readFile(file.path, null, {
296
- branch: filesBranch,
297
- parseText: false
298
- });
299
- formData.append(file.path.replace(sourceDir, destDir), content, basename(file.path));
295
+ formData.append(to, contentBlob, basename(to));
296
+ } else {
297
+ // Legacy behavior (subfolders: true, default): Move all files in the directory
298
+ const sourceDir = dirname(from);
299
+ const destDir = dirname(to);
300
+ const filesBranch = parentSha ? this.branch : branch;
301
+ const files = await this.listAllFiles(sourceDir, 100, filesBranch);
302
+ for (const file of files) {
303
+ // to move a file in Bitbucket we need to delete the old path
304
+ // and upload the file content to the new path
305
+ // NOTE: this is very wasteful, and also the Bitbucket `diff` API
306
+ // reports these files as deleted+added instead of renamed
307
+ // delete current path
308
+ formData.append('files', file.path);
309
+ // create in new path
310
+ const content = file.path === from ? contentBlob : await this.readFile(file.path, null, {
311
+ branch: filesBranch,
312
+ parseText: false
313
+ });
314
+ formData.append(file.path.replace(sourceDir, destDir), content, basename(file.path));
315
+ }
300
316
  }
301
317
  }
302
318
  if (commitMessage) {
@@ -331,13 +347,15 @@ export default class API {
331
347
  }
332
348
  async persistFiles(dataFiles, mediaFiles, options) {
333
349
  const files = [...dataFiles, ...mediaFiles];
350
+ const hasSubfolders = options.hasSubfolders !== false; // default to true
334
351
  if (options.useWorkflow) {
335
352
  const slug = dataFiles[0].slug;
336
353
  return this.editorialWorkflowGit(files, slug, options);
337
354
  } else {
338
355
  return this.uploadFiles(files, {
339
356
  commitMessage: options.commitMessage,
340
- branch: this.branch
357
+ branch: this.branch,
358
+ hasSubfolders
341
359
  });
342
360
  }
343
361
  }
@@ -419,12 +437,14 @@ export default class API {
419
437
  const contentKey = generateContentKey(options.collectionName, slug);
420
438
  const branch = branchFromContentKey(contentKey);
421
439
  const unpublished = options.unpublished || false;
440
+ const hasSubfolders = options.hasSubfolders !== false; // default to true
422
441
  if (!unpublished) {
423
442
  const defaultBranchSha = await this.branchCommitSha(this.branch);
424
443
  await this.uploadFiles(files, {
425
444
  commitMessage: options.commitMessage,
426
445
  branch,
427
- parentSha: defaultBranchSha
446
+ parentSha: defaultBranchSha,
447
+ hasSubfolders
428
448
  });
429
449
  await this.createPullRequest(branch, options.commitMessage, options.status || this.initialWorkflowStatus);
430
450
  } else {
@@ -441,7 +461,8 @@ export default class API {
441
461
  }
442
462
  await this.uploadFiles([...files, ...toDelete], {
443
463
  commitMessage: options.commitMessage,
444
- branch
464
+ branch,
465
+ hasSubfolders
445
466
  });
446
467
  }
447
468
  }
@@ -1,4 +1,4 @@
1
- import minimatch from 'minimatch';
1
+ import { minimatch } from 'minimatch';
2
2
  import { unsentRequest } from 'decap-cms-lib-util';
3
3
  export class GitLfsClient {
4
4
  static defaultContentHeaders = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "decap-cms-backend-bitbucket",
3
3
  "description": "Bitbucket backend for Decap CMS",
4
- "version": "3.3.0",
4
+ "version": "3.4.0",
5
5
  "repository": "https://github.com/decaporg/decap-cms/tree/main/packages/decap-cms-backend-bitbucket",
6
6
  "bugs": "https://github.com/decaporg/decap-cms/issues",
7
7
  "module": "dist/esm/index.js",
@@ -40,5 +40,5 @@
40
40
  "browser": {
41
41
  "path": "path-browserify"
42
42
  },
43
- "gitHead": "d3465f53b7f056ad5d872948a07eaa8e4ae63315"
43
+ "gitHead": "ae01ad6f2b139f93472c8f0d049d35277d8583ca"
44
44
  }
package/src/API.ts CHANGED
@@ -24,9 +24,9 @@ import {
24
24
  readFileMetadata,
25
25
  throwOnConflictingBranches,
26
26
  } from 'decap-cms-lib-util';
27
- import { dirname } from 'path';
28
27
  import { oneLine } from 'common-tags';
29
28
  import { parse } from 'what-the-diff';
29
+ import { dirname } from 'path';
30
30
 
31
31
  import type {
32
32
  ApiRequest,
@@ -432,17 +432,18 @@ export default class API {
432
432
  commitMessage,
433
433
  branch,
434
434
  parentSha,
435
- }: { commitMessage: string; branch: string; parentSha?: string },
435
+ hasSubfolders = true,
436
+ }: { commitMessage: string; branch: string; parentSha?: string; hasSubfolders?: boolean },
436
437
  ) {
437
438
  const formData = new FormData();
438
- const toMove: { from: string; to: string; contentBlob: Blob }[] = [];
439
+ const toMove: { from: string; to: string; contentBlob: Blob; hasSubfolders: boolean }[] = [];
439
440
  files.forEach(file => {
440
441
  if (file.delete) {
441
442
  // delete the file
442
443
  formData.append('files', file.path);
443
444
  } else if (file.newPath) {
444
445
  const contentBlob = get(file, 'fileObj', new Blob([(file as DataFile).raw]));
445
- toMove.push({ from: file.path, to: file.newPath, contentBlob });
446
+ toMove.push({ from: file.path, to: file.newPath, contentBlob, hasSubfolders });
446
447
  } else {
447
448
  // add/modify the file
448
449
  const contentBlob = get(file, 'fileObj', new Blob([(file as DataFile).raw]));
@@ -450,27 +451,44 @@ export default class API {
450
451
  formData.append(file.path, contentBlob, basename(file.path));
451
452
  }
452
453
  });
453
- for (const { from, to, contentBlob } of toMove) {
454
- const sourceDir = dirname(from);
455
- const destDir = dirname(to);
456
- const filesBranch = parentSha ? this.branch : branch;
457
- const files = await this.listAllFiles(sourceDir, 100, filesBranch);
458
- for (const file of files) {
454
+ for (const { from, to, contentBlob, hasSubfolders } of toMove) {
455
+ if (!hasSubfolders) {
456
+ // New behavior (subfolders: false): Only move the specific file
459
457
  // to move a file in Bitbucket we need to delete the old path
460
458
  // and upload the file content to the new path
461
459
  // NOTE: this is very wasteful, and also the Bitbucket `diff` API
462
460
  // reports these files as deleted+added instead of renamed
463
461
  // delete current path
464
- formData.append('files', file.path);
462
+ formData.append('files', from);
465
463
  // create in new path
466
- const content =
467
- file.path === from
468
- ? contentBlob
469
- : await this.readFile(file.path, null, {
470
- branch: filesBranch,
471
- parseText: false,
472
- });
473
- formData.append(file.path.replace(sourceDir, destDir), content, basename(file.path));
464
+ formData.append(to, contentBlob, basename(to));
465
+ } else {
466
+ // Legacy behavior (subfolders: true, default): Move all files in the directory
467
+ const sourceDir = dirname(from);
468
+ const destDir = dirname(to);
469
+ const filesBranch = parentSha ? this.branch : branch;
470
+ const files = await this.listAllFiles(sourceDir, 100, filesBranch);
471
+ for (const file of files) {
472
+ // to move a file in Bitbucket we need to delete the old path
473
+ // and upload the file content to the new path
474
+ // NOTE: this is very wasteful, and also the Bitbucket `diff` API
475
+ // reports these files as deleted+added instead of renamed
476
+ // delete current path
477
+ formData.append('files', file.path);
478
+ // create in new path
479
+ const content =
480
+ file.path === from
481
+ ? contentBlob
482
+ : await this.readFile(file.path, null, {
483
+ branch: filesBranch,
484
+ parseText: false,
485
+ });
486
+ formData.append(
487
+ file.path.replace(sourceDir, destDir),
488
+ content as Blob,
489
+ basename(file.path),
490
+ );
491
+ }
474
492
  }
475
493
  }
476
494
 
@@ -508,11 +526,16 @@ export default class API {
508
526
 
509
527
  async persistFiles(dataFiles: DataFile[], mediaFiles: AssetProxy[], options: PersistOptions) {
510
528
  const files = [...dataFiles, ...mediaFiles];
529
+ const hasSubfolders = options.hasSubfolders !== false; // default to true
511
530
  if (options.useWorkflow) {
512
531
  const slug = dataFiles[0].slug;
513
532
  return this.editorialWorkflowGit(files, slug, options);
514
533
  } else {
515
- return this.uploadFiles(files, { commitMessage: options.commitMessage, branch: this.branch });
534
+ return this.uploadFiles(files, {
535
+ commitMessage: options.commitMessage,
536
+ branch: this.branch,
537
+ hasSubfolders,
538
+ });
516
539
  }
517
540
  }
518
541
 
@@ -599,12 +622,14 @@ export default class API {
599
622
  const contentKey = generateContentKey(options.collectionName as string, slug);
600
623
  const branch = branchFromContentKey(contentKey);
601
624
  const unpublished = options.unpublished || false;
625
+ const hasSubfolders = options.hasSubfolders !== false; // default to true
602
626
  if (!unpublished) {
603
627
  const defaultBranchSha = await this.branchCommitSha(this.branch);
604
628
  await this.uploadFiles(files, {
605
629
  commitMessage: options.commitMessage,
606
630
  branch,
607
631
  parentSha: defaultBranchSha,
632
+ hasSubfolders,
608
633
  });
609
634
  await this.createPullRequest(
610
635
  branch,
@@ -624,6 +649,7 @@ export default class API {
624
649
  await this.uploadFiles([...files, ...toDelete], {
625
650
  commitMessage: options.commitMessage,
626
651
  branch,
652
+ hasSubfolders,
627
653
  });
628
654
  }
629
655
  }
@@ -1,4 +1,4 @@
1
- import minimatch from 'minimatch';
1
+ import { minimatch } from 'minimatch';
2
2
  import { unsentRequest } from 'decap-cms-lib-util';
3
3
 
4
4
  import type { ApiRequest, PointerFile } from 'decap-cms-lib-util';