@contentful/field-editor-shared 4.0.1-canary.14 → 4.0.1-canary.15

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.
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "useReleaseStatus", {
9
9
  }
10
10
  });
11
11
  const _react = require("react");
12
+ const _determineReleaseAction = require("../utils/determineReleaseAction");
12
13
  const _entityHelpers = require("../utils/entityHelpers");
13
14
  const _getReleaseStatusBadgeConfig = require("../utils/getReleaseStatusBadgeConfig");
14
15
  const _sanitizeLocales = require("../utils/sanitizeLocales");
@@ -34,8 +35,8 @@ function getReleaseItemLocaleStatus(releaseItem, locale, previousEntityOnTimelin
34
35
  ].includes(status) ? 'becomesDraft' : 'remainsDraft';
35
36
  }
36
37
  }
37
- const addedLocales = releaseItem.add?.fields['*'] || [];
38
- const removedLocales = releaseItem.remove?.fields['*'] || [];
38
+ const addedLocales = (0, _determineReleaseAction.normalizeReleaseLocaleFields)(releaseItem.add);
39
+ const removedLocales = (0, _determineReleaseAction.normalizeReleaseLocaleFields)(releaseItem.remove);
39
40
  if (addedLocales.includes(locale.code)) {
40
41
  return 'willPublish';
41
42
  }
@@ -30,6 +30,8 @@ const createEntityBuilder = (entityType, defaultId)=>{
30
30
  };
31
31
  const entryBuilder = ()=>createEntityBuilder('Entry', 'entry-1');
32
32
  const assetBuilder = ()=>createEntityBuilder('Asset', 'asset-1');
33
+ const fragmentBuilder = ()=>createEntityBuilder('Fragment', 'fragment-1');
34
+ const experienceBuilder = ()=>createEntityBuilder('Experience', 'experience-1');
33
35
  const createEntryBasedReleaseEntity = ({ entityId, action = 'publish', entityType })=>({
34
36
  entity: {
35
37
  sys: {
@@ -103,8 +105,34 @@ const expectEntityStatus = (result, expectedStatus)=>{
103
105
  };
104
106
  const ENTITY_TYPES = [
105
107
  'Entry',
106
- 'Asset'
108
+ 'Asset',
109
+ 'Fragment',
110
+ 'Experience'
107
111
  ];
112
+ const ENTITY_ID_BY_TYPE = {
113
+ Entry: {
114
+ default: 'entry-1',
115
+ different: 'entry-2'
116
+ },
117
+ Asset: {
118
+ default: 'asset-1',
119
+ different: 'asset-2'
120
+ },
121
+ Fragment: {
122
+ default: 'fragment-1',
123
+ different: 'fragment-2'
124
+ },
125
+ Experience: {
126
+ default: 'experience-1',
127
+ different: 'experience-2'
128
+ }
129
+ };
130
+ const BUILDER_BY_TYPE = {
131
+ Entry: entryBuilder,
132
+ Asset: assetBuilder,
133
+ Fragment: fragmentBuilder,
134
+ Experience: experienceBuilder
135
+ };
108
136
  describe('useReleaseStatus', ()=>{
109
137
  const locales = createDefaultLocales();
110
138
  describe('Guard clauses and invalid inputs', ()=>{
@@ -389,16 +417,86 @@ describe('useReleaseStatus', ()=>{
389
417
  });
390
418
  });
391
419
  });
420
+ describe('Flat array payload shape', ()=>{
421
+ const buildFlatShapeRelease = (verb, localeCodes)=>({
422
+ title: 'Release 1',
423
+ sys: {
424
+ id: 'release-1',
425
+ type: 'Release',
426
+ schemaVersion: 'Release.v2'
427
+ },
428
+ entities: {
429
+ items: [
430
+ {
431
+ entity: {
432
+ sys: {
433
+ type: 'Link',
434
+ linkType: 'Entry',
435
+ id: 'entry-1'
436
+ }
437
+ },
438
+ [verb]: localeCodes
439
+ }
440
+ ]
441
+ }
442
+ });
443
+ it('treats flat-array add as willPublish', ()=>{
444
+ const { result } = (0, _react.renderHook)(()=>(0, _useReleaseStatus.useReleaseStatus)({
445
+ locales,
446
+ release: buildFlatShapeRelease('add', [
447
+ 'en-US'
448
+ ]),
449
+ entity: entryBuilder().withStatus('draft')
450
+ }));
451
+ expectLocaleStatus(result.current, 'en-US', {
452
+ variant: 'positive',
453
+ status: 'willPublish',
454
+ label: 'Will publish',
455
+ locale: {
456
+ code: 'en-US'
457
+ }
458
+ });
459
+ });
460
+ it('treats flat-array remove as becomesDraft', ()=>{
461
+ const { result } = (0, _react.renderHook)(()=>(0, _useReleaseStatus.useReleaseStatus)({
462
+ locales,
463
+ previousEntityOnTimeline: entryBuilder().withStatus('published'),
464
+ release: buildFlatShapeRelease('remove', [
465
+ 'en-US'
466
+ ]),
467
+ entity: entryBuilder().withStatus('draft')
468
+ }));
469
+ expectLocaleStatus(result.current, 'en-US', {
470
+ variant: 'warning',
471
+ status: 'becomesDraft',
472
+ label: 'Becomes draft',
473
+ locale: {
474
+ code: 'en-US'
475
+ }
476
+ });
477
+ });
478
+ it('treats empty flat-array remove as remainsDraft', ()=>{
479
+ const { result } = (0, _react.renderHook)(()=>(0, _useReleaseStatus.useReleaseStatus)({
480
+ locales,
481
+ release: buildFlatShapeRelease('remove', []),
482
+ entity: entryBuilder().withStatus('draft')
483
+ }));
484
+ expectLocaleStatus(result.current, 'en-US', {
485
+ variant: 'warning',
486
+ status: 'remainsDraft',
487
+ label: 'Remains draft',
488
+ locale: {
489
+ code: 'en-US'
490
+ }
491
+ });
492
+ });
493
+ });
392
494
  const testPublishingScenarios = (config)=>{
393
495
  const { isReference, publishingModel } = config;
394
496
  const locales = createDefaultLocales();
395
497
  ENTITY_TYPES.forEach((entityType)=>{
396
- const defaultEntityId = entityType === 'Entry' ? 'entry-1' : 'asset-1';
397
- const differentEntityId = entityType === 'Entry' ? 'entry-2' : 'asset-2';
398
- const buildEntity = (status)=>{
399
- const builder = entityType === 'Entry' ? entryBuilder() : assetBuilder();
400
- return builder.withStatus(status);
401
- };
498
+ const { default: defaultEntityId, different: differentEntityId } = ENTITY_ID_BY_TYPE[entityType];
499
+ const buildEntity = (status)=>BUILDER_BY_TYPE[entityType]().withStatus(status);
402
500
  const createRelease = (options)=>{
403
501
  return publishingModel === 'entry-based' ? createEntryBasedRelease({
404
502
  entityId: options.entityId,
@@ -20,7 +20,7 @@ _export(exports, {
20
20
  }
21
21
  });
22
22
  const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
23
- const _reactquery = /*#__PURE__*/ _interop_require_wildcard(require("@tanstack/react-query"));
23
+ const _reactquery = require("@tanstack/react-query");
24
24
  function _getRequireWildcardCache(nodeInterop) {
25
25
  if (typeof WeakMap !== "function") return null;
26
26
  var cacheBabelInterop = new WeakMap();
@@ -62,7 +62,7 @@ function _interop_require_wildcard(obj, nodeInterop) {
62
62
  }
63
63
  return newObj;
64
64
  }
65
- const rqVersion = _reactquery.version;
65
+ const rqVersion = require('@tanstack/react-query').version;
66
66
  const RQ_MAJOR = parseInt(rqVersion ?? '4', 10);
67
67
  const IS_V5 = RQ_MAJOR >= 5;
68
68
  const clientContext = /*#__PURE__*/ _react.createContext(undefined);
@@ -2,21 +2,36 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "determineReleaseAction", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ determineReleaseAction: function() {
8
13
  return determineReleaseAction;
14
+ },
15
+ normalizeReleaseLocaleFields: function() {
16
+ return normalizeReleaseLocaleFields;
9
17
  }
10
18
  });
19
+ function normalizeReleaseLocaleFields(value) {
20
+ if (!value) {
21
+ return [];
22
+ }
23
+ if (Array.isArray(value)) {
24
+ return value;
25
+ }
26
+ return value.fields?.['*'] ?? [];
27
+ }
11
28
  function isEntryBasedAction(entityItem) {
12
29
  return 'action' in entityItem && (entityItem.action === 'publish' || entityItem.action === 'unpublish');
13
30
  }
14
31
  function getLocalesFromEntity(entityItem) {
15
- const addLocales = entityItem?.add?.fields?.['*'] ?? [];
16
- const removeLocales = entityItem?.remove?.fields?.['*'] ?? [];
17
32
  return {
18
- addLocales,
19
- removeLocales
33
+ addLocales: normalizeReleaseLocaleFields(entityItem?.add),
34
+ removeLocales: normalizeReleaseLocaleFields(entityItem?.remove)
20
35
  };
21
36
  }
22
37
  function getLocaleBasedAction(addLocales, removeLocales) {
@@ -1,4 +1,5 @@
1
1
  import { useMemo } from 'react';
2
+ import { normalizeReleaseLocaleFields } from '../utils/determineReleaseAction';
2
3
  import { getEntityStatus } from '../utils/entityHelpers';
3
4
  import { getReleaseStatusBadgeConfig } from '../utils/getReleaseStatusBadgeConfig';
4
5
  import { sanitizeLocales } from '../utils/sanitizeLocales';
@@ -24,8 +25,8 @@ function getReleaseItemLocaleStatus(releaseItem, locale, previousEntityOnTimelin
24
25
  ].includes(status) ? 'becomesDraft' : 'remainsDraft';
25
26
  }
26
27
  }
27
- const addedLocales = releaseItem.add?.fields['*'] || [];
28
- const removedLocales = releaseItem.remove?.fields['*'] || [];
28
+ const addedLocales = normalizeReleaseLocaleFields(releaseItem.add);
29
+ const removedLocales = normalizeReleaseLocaleFields(releaseItem.remove);
29
30
  if (addedLocales.includes(locale.code)) {
30
31
  return 'willPublish';
31
32
  }
@@ -26,6 +26,8 @@ const createEntityBuilder = (entityType, defaultId)=>{
26
26
  };
27
27
  const entryBuilder = ()=>createEntityBuilder('Entry', 'entry-1');
28
28
  const assetBuilder = ()=>createEntityBuilder('Asset', 'asset-1');
29
+ const fragmentBuilder = ()=>createEntityBuilder('Fragment', 'fragment-1');
30
+ const experienceBuilder = ()=>createEntityBuilder('Experience', 'experience-1');
29
31
  const createEntryBasedReleaseEntity = ({ entityId, action = 'publish', entityType })=>({
30
32
  entity: {
31
33
  sys: {
@@ -99,8 +101,34 @@ const expectEntityStatus = (result, expectedStatus)=>{
99
101
  };
100
102
  const ENTITY_TYPES = [
101
103
  'Entry',
102
- 'Asset'
104
+ 'Asset',
105
+ 'Fragment',
106
+ 'Experience'
103
107
  ];
108
+ const ENTITY_ID_BY_TYPE = {
109
+ Entry: {
110
+ default: 'entry-1',
111
+ different: 'entry-2'
112
+ },
113
+ Asset: {
114
+ default: 'asset-1',
115
+ different: 'asset-2'
116
+ },
117
+ Fragment: {
118
+ default: 'fragment-1',
119
+ different: 'fragment-2'
120
+ },
121
+ Experience: {
122
+ default: 'experience-1',
123
+ different: 'experience-2'
124
+ }
125
+ };
126
+ const BUILDER_BY_TYPE = {
127
+ Entry: entryBuilder,
128
+ Asset: assetBuilder,
129
+ Fragment: fragmentBuilder,
130
+ Experience: experienceBuilder
131
+ };
104
132
  describe('useReleaseStatus', ()=>{
105
133
  const locales = createDefaultLocales();
106
134
  describe('Guard clauses and invalid inputs', ()=>{
@@ -385,16 +413,86 @@ describe('useReleaseStatus', ()=>{
385
413
  });
386
414
  });
387
415
  });
416
+ describe('Flat array payload shape', ()=>{
417
+ const buildFlatShapeRelease = (verb, localeCodes)=>({
418
+ title: 'Release 1',
419
+ sys: {
420
+ id: 'release-1',
421
+ type: 'Release',
422
+ schemaVersion: 'Release.v2'
423
+ },
424
+ entities: {
425
+ items: [
426
+ {
427
+ entity: {
428
+ sys: {
429
+ type: 'Link',
430
+ linkType: 'Entry',
431
+ id: 'entry-1'
432
+ }
433
+ },
434
+ [verb]: localeCodes
435
+ }
436
+ ]
437
+ }
438
+ });
439
+ it('treats flat-array add as willPublish', ()=>{
440
+ const { result } = renderHook(()=>useReleaseStatus({
441
+ locales,
442
+ release: buildFlatShapeRelease('add', [
443
+ 'en-US'
444
+ ]),
445
+ entity: entryBuilder().withStatus('draft')
446
+ }));
447
+ expectLocaleStatus(result.current, 'en-US', {
448
+ variant: 'positive',
449
+ status: 'willPublish',
450
+ label: 'Will publish',
451
+ locale: {
452
+ code: 'en-US'
453
+ }
454
+ });
455
+ });
456
+ it('treats flat-array remove as becomesDraft', ()=>{
457
+ const { result } = renderHook(()=>useReleaseStatus({
458
+ locales,
459
+ previousEntityOnTimeline: entryBuilder().withStatus('published'),
460
+ release: buildFlatShapeRelease('remove', [
461
+ 'en-US'
462
+ ]),
463
+ entity: entryBuilder().withStatus('draft')
464
+ }));
465
+ expectLocaleStatus(result.current, 'en-US', {
466
+ variant: 'warning',
467
+ status: 'becomesDraft',
468
+ label: 'Becomes draft',
469
+ locale: {
470
+ code: 'en-US'
471
+ }
472
+ });
473
+ });
474
+ it('treats empty flat-array remove as remainsDraft', ()=>{
475
+ const { result } = renderHook(()=>useReleaseStatus({
476
+ locales,
477
+ release: buildFlatShapeRelease('remove', []),
478
+ entity: entryBuilder().withStatus('draft')
479
+ }));
480
+ expectLocaleStatus(result.current, 'en-US', {
481
+ variant: 'warning',
482
+ status: 'remainsDraft',
483
+ label: 'Remains draft',
484
+ locale: {
485
+ code: 'en-US'
486
+ }
487
+ });
488
+ });
489
+ });
388
490
  const testPublishingScenarios = (config)=>{
389
491
  const { isReference, publishingModel } = config;
390
492
  const locales = createDefaultLocales();
391
493
  ENTITY_TYPES.forEach((entityType)=>{
392
- const defaultEntityId = entityType === 'Entry' ? 'entry-1' : 'asset-1';
393
- const differentEntityId = entityType === 'Entry' ? 'entry-2' : 'asset-2';
394
- const buildEntity = (status)=>{
395
- const builder = entityType === 'Entry' ? entryBuilder() : assetBuilder();
396
- return builder.withStatus(status);
397
- };
494
+ const { default: defaultEntityId, different: differentEntityId } = ENTITY_ID_BY_TYPE[entityType];
495
+ const buildEntity = (status)=>BUILDER_BY_TYPE[entityType]().withStatus(status);
398
496
  const createRelease = (options)=>{
399
497
  return publishingModel === 'entry-based' ? createEntryBasedRelease({
400
498
  entityId: options.entityId,
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react';
2
- import * as ReactQuery from '@tanstack/react-query';
3
2
  import { QueryClient, QueryClientProvider, useQuery as useRQv4, useQueryClient as useHostQueryClientV4 } from '@tanstack/react-query';
4
- const rqVersion = ReactQuery.version;
3
+ const rqVersion = require('@tanstack/react-query').version;
5
4
  const RQ_MAJOR = parseInt(rqVersion ?? '4', 10);
6
5
  const IS_V5 = RQ_MAJOR >= 5;
7
6
  const clientContext = /*#__PURE__*/ React.createContext(undefined);
@@ -1,12 +1,19 @@
1
+ export function normalizeReleaseLocaleFields(value) {
2
+ if (!value) {
3
+ return [];
4
+ }
5
+ if (Array.isArray(value)) {
6
+ return value;
7
+ }
8
+ return value.fields?.['*'] ?? [];
9
+ }
1
10
  function isEntryBasedAction(entityItem) {
2
11
  return 'action' in entityItem && (entityItem.action === 'publish' || entityItem.action === 'unpublish');
3
12
  }
4
13
  function getLocalesFromEntity(entityItem) {
5
- const addLocales = entityItem?.add?.fields?.['*'] ?? [];
6
- const removeLocales = entityItem?.remove?.fields?.['*'] ?? [];
7
14
  return {
8
- addLocales,
9
- removeLocales
15
+ addLocales: normalizeReleaseLocaleFields(entityItem?.add),
16
+ removeLocales: normalizeReleaseLocaleFields(entityItem?.remove)
10
17
  };
11
18
  }
12
19
  function getLocaleBasedAction(addLocales, removeLocales) {
@@ -12,34 +12,32 @@ export type ValidationType = {
12
12
  min: number;
13
13
  max: number;
14
14
  };
15
+ export type ReleaseV2EntityLinkType = 'Entry' | 'Asset' | 'Fragment' | 'Experience';
15
16
  export type ReleaseV2Entity = {
16
17
  entity: {
17
18
  sys: {
18
19
  type: 'Link';
19
- linkType: 'Entry' | 'Asset';
20
+ linkType: ReleaseV2EntityLinkType;
20
21
  id: string;
21
22
  };
22
23
  };
23
24
  action: 'publish' | 'unpublish';
24
25
  };
26
+ export type ReleaseV2LocaleFields = string[] | {
27
+ fields: {
28
+ '*': string[];
29
+ };
30
+ };
25
31
  export type ReleaseV2EntityWithLocales = {
26
32
  entity: {
27
33
  sys: {
28
34
  type: 'Link';
29
- linkType: 'Entry' | 'Asset';
35
+ linkType: ReleaseV2EntityLinkType;
30
36
  id: string;
31
37
  };
32
38
  };
33
- add: {
34
- fields: {
35
- '*': string[];
36
- };
37
- };
38
- remove: {
39
- fields: {
40
- '*': string[];
41
- };
42
- };
39
+ add: ReleaseV2LocaleFields;
40
+ remove: ReleaseV2LocaleFields;
43
41
  };
44
42
  export type ReleaseV2AnnotationType = 'Hidden' | 'Ideation';
45
43
  export type ReleaseV2Annotations = {
@@ -1,4 +1,5 @@
1
- import type { ReleaseAction, ReleaseV2Entity, ReleaseV2EntityWithLocales, ReleaseV2Props } from '../types';
1
+ import type { ReleaseAction, ReleaseV2Entity, ReleaseV2EntityWithLocales, ReleaseV2LocaleFields, ReleaseV2Props } from '../types';
2
+ export declare function normalizeReleaseLocaleFields(value?: ReleaseV2LocaleFields): string[];
2
3
  type DetermineActionResult = {
3
4
  releaseAction: ReleaseAction;
4
5
  entityItem?: ReleaseV2Entity | ReleaseV2EntityWithLocales;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-shared",
3
- "version": "4.0.1-canary.14+b2660ed5",
3
+ "version": "4.0.1-canary.15+17e1a003",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -73,5 +73,5 @@
73
73
  "publishConfig": {
74
74
  "registry": "https://npm.pkg.github.com/"
75
75
  },
76
- "gitHead": "b2660ed5523c6c7be45bc67b2801220fb5393b86"
76
+ "gitHead": "17e1a003b6e3cccd22251c65b3c496b6ff1111a0"
77
77
  }