@contentful/field-editor-validation-errors 1.1.10 → 1.2.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 CHANGED
@@ -3,6 +3,16 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.2.0](https://github.com/contentful/field-editors/compare/@contentful/field-editor-validation-errors@1.1.11...@contentful/field-editor-validation-errors@1.2.0) (2023-04-19)
7
+
8
+ ### Features
9
+
10
+ - upgrade cypress [TOL-1036] ([#1391](https://github.com/contentful/field-editors/issues/1391)) ([9c1aec9](https://github.com/contentful/field-editors/commit/9c1aec98aabbe464cdc3f1236c3bb1cc29b8208d))
11
+
12
+ ## [1.1.11](https://github.com/contentful/field-editors/compare/@contentful/field-editor-validation-errors@1.1.10...@contentful/field-editor-validation-errors@1.1.11) (2023-03-14)
13
+
14
+ **Note:** Version bump only for package @contentful/field-editor-validation-errors
15
+
6
16
  ## [1.1.10](https://github.com/contentful/field-editors/compare/@contentful/field-editor-validation-errors@1.1.9...@contentful/field-editor-validation-errors@1.1.10) (2023-03-10)
7
17
 
8
18
  **Note:** Version bump only for package @contentful/field-editor-validation-errors
@@ -5,116 +5,79 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
6
 
7
7
  var React = _interopDefault(require('react'));
8
- var fieldEditorShared = require('@contentful/field-editor-shared');
9
- var emotion = require('emotion');
10
- var tokens = _interopDefault(require('@contentful/f36-tokens'));
11
8
  var f36Components = require('@contentful/f36-components');
12
9
  var f36Icons = require('@contentful/f36-icons');
10
+ var fieldEditorShared = require('@contentful/field-editor-shared');
11
+ var tokens = _interopDefault(require('@contentful/f36-tokens'));
12
+ var emotion = require('emotion');
13
13
 
14
- function _extends() {
15
- _extends = Object.assign || function (target) {
16
- for (var i = 1; i < arguments.length; i++) {
17
- var source = arguments[i];
18
-
19
- for (var key in source) {
20
- if (Object.prototype.hasOwnProperty.call(source, key)) {
21
- target[key] = source[key];
22
- }
23
- }
24
- }
25
-
26
- return target;
27
- };
28
-
29
- return _extends.apply(this, arguments);
30
- }
31
-
32
- var errorList = /*#__PURE__*/emotion.css({
14
+ const errorList = /*#__PURE__*/emotion.css({
33
15
  padding: 0,
34
16
  wordWrap: 'break-word',
35
17
  marginTop: tokens.spacingS,
36
18
  color: tokens.red500,
37
19
  listStyleType: 'none'
38
20
  });
39
- var errorMessage = /*#__PURE__*/emotion.css({
21
+ const errorMessage = /*#__PURE__*/emotion.css({
40
22
  display: 'inline-flex',
41
23
  flexDirection: 'column',
42
24
  marginLeft: tokens.spacingXs
43
25
  });
44
- var errorItem = /*#__PURE__*/emotion.css({
26
+ const errorItem = /*#__PURE__*/emotion.css({
45
27
  display: 'flex',
46
28
  alignItems: 'center'
47
29
  });
48
- var entryLink = /*#__PURE__*/emotion.css({
30
+ const entryLink = /*#__PURE__*/emotion.css({
49
31
  fontWeight: /*#__PURE__*/Number(tokens.fontWeightDemiBold)
50
32
  });
51
33
 
52
34
  function UniquenessError(props) {
53
- var _React$useState = React.useState({
35
+ const [state, setState] = React.useState({
54
36
  loading: true,
55
37
  entries: []
56
- }),
57
- state = _React$useState[0],
58
- setState = _React$useState[1];
59
-
60
- var contentTypesById = React.useMemo(function () {
61
- return (// Maps ID => Content Type
62
- props.space.getCachedContentTypes().reduce(function (prev, ct) {
63
- var _extends2;
64
-
65
- return _extends({}, prev, (_extends2 = {}, _extends2[ct.sys.id] = ct, _extends2));
66
- }, {})
67
- );
68
- }, [props.space]);
69
- var getTitle = React.useCallback(function (entry) {
70
- return fieldEditorShared.entityHelpers.getEntryTitle({
71
- entry: entry,
72
- defaultTitle: 'Untitled',
73
- localeCode: props.localeCode,
74
- defaultLocaleCode: props.defaultLocaleCode,
75
- contentType: contentTypesById[entry.sys.contentType.sys.id]
76
- });
77
- }, [props.localeCode, props.defaultLocaleCode, contentTypesById]);
78
- var conflicting = [];
38
+ });
39
+ const contentTypesById = React.useMemo(() => // Maps ID => Content Type
40
+ props.space.getCachedContentTypes().reduce((prev, ct) => ({ ...prev,
41
+ [ct.sys.id]: ct
42
+ }), {}), [props.space]);
43
+ const getTitle = React.useCallback(entry => fieldEditorShared.entityHelpers.getEntryTitle({
44
+ entry,
45
+ defaultTitle: 'Untitled',
46
+ localeCode: props.localeCode,
47
+ defaultLocaleCode: props.defaultLocaleCode,
48
+ contentType: contentTypesById[entry.sys.contentType.sys.id]
49
+ }), [props.localeCode, props.defaultLocaleCode, contentTypesById]);
50
+ let conflicting = [];
79
51
 
80
52
  if ('conflicting' in props.error) {
81
53
  conflicting = props.error.conflicting;
82
54
  }
83
55
 
84
- React.useEffect(function () {
85
- var entryIds = state.entries.map(function (entry) {
86
- return entry.id;
87
- });
88
- var conflictIds = conflicting.map(function (entry) {
89
- return entry.sys.id;
90
- }); // Avoid unnecessary refetching
56
+ React.useEffect(() => {
57
+ const entryIds = state.entries.map(entry => entry.id);
58
+ const conflictIds = conflicting.map(entry => entry.sys.id); // Avoid unnecessary refetching
91
59
 
92
- if (conflictIds.every(function (id) {
93
- return entryIds.includes(id);
94
- })) {
60
+ if (conflictIds.every(id => entryIds.includes(id))) {
95
61
  return;
96
62
  }
97
63
 
98
- setState(function (state) {
99
- return _extends({}, state, {
100
- loading: true
101
- });
102
- });
103
- var query = {
64
+ setState(state => ({ ...state,
65
+ loading: true
66
+ }));
67
+ const query = {
104
68
  'sys.id[in]': conflictIds.join(',')
105
69
  };
106
- props.space.getEntries(query).then(function (_ref) {
107
- var items = _ref.items;
108
- var entries = items.map(function (entry) {
109
- return {
110
- id: entry.sys.id,
111
- title: getTitle(entry),
112
- href: props.getEntryURL(entry)
113
- };
114
- });
70
+ props.space.getEntries(query).then(({
71
+ items
72
+ }) => {
73
+ const entries = items.map(entry => ({
74
+ id: entry.sys.id,
75
+ title: getTitle(entry),
76
+ href: props.getEntryURL(entry)
77
+ }));
115
78
  setState({
116
79
  loading: false,
117
- entries: entries
80
+ entries
118
81
  });
119
82
  }); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies
120
83
  }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);
@@ -123,26 +86,21 @@ function UniquenessError(props) {
123
86
  testId: "validation-errors-uniqueness"
124
87
  }, React.createElement(f36Components.ListItem, {
125
88
  className: entryLink
126
- }, state.loading ? React.createElement("div", null, "Loading title for conflicting entry\u2026") : state.entries.map(function (entry) {
127
- return React.createElement(f36Components.TextLink, {
128
- key: entry.id,
129
- href: entry.href,
130
- icon: React.createElement(f36Icons.ExternalLinkIcon, null),
131
- alignIcon: "end",
132
- variant: "negative",
133
- target: "_blank",
134
- rel: "noopener noreferrer"
135
- }, entry.title);
136
- })));
89
+ }, state.loading ? React.createElement("div", null, "Loading title for conflicting entry\u2026") : state.entries.map(entry => React.createElement(f36Components.TextLink, {
90
+ key: entry.id,
91
+ href: entry.href,
92
+ icon: React.createElement(f36Icons.ExternalLinkIcon, null),
93
+ alignIcon: "end",
94
+ variant: "negative",
95
+ target: "_blank",
96
+ rel: "noopener noreferrer"
97
+ }, entry.title))));
137
98
  }
138
99
 
139
100
  function ValidationErrors(props) {
140
- var _React$useState2 = React.useState([]),
141
- errors = _React$useState2[0],
142
- setErrors = _React$useState2[1];
143
-
144
- React.useEffect(function () {
145
- var onErrors = function onErrors(errors) {
101
+ const [errors, setErrors] = React.useState([]);
102
+ React.useEffect(() => {
103
+ const onErrors = errors => {
146
104
  setErrors(errors || []);
147
105
  };
148
106
 
@@ -156,12 +114,12 @@ function ValidationErrors(props) {
156
114
  return React.createElement(f36Components.List, {
157
115
  className: errorList,
158
116
  testId: "validation-errors"
159
- }, errors.map(function (error, index) {
117
+ }, errors.map((error, index) => {
160
118
  return React.createElement("li", {
161
119
  key: index,
162
120
  role: "status",
163
121
  "aria-roledescription": "field-locale-schema",
164
- "data-error-code": "entry.schema." + error.name,
122
+ "data-error-code": `entry.schema.${error.name}`,
165
123
  className: errorItem
166
124
  }, React.createElement(f36Icons.InfoCircleIcon, {
167
125
  variant: "negative"
@@ -171,7 +129,7 @@ function ValidationErrors(props) {
171
129
  error: error,
172
130
  space: props.space,
173
131
  localeCode: props.field.locale,
174
- defaultLocaleCode: props.locales["default"],
132
+ defaultLocaleCode: props.locales.default,
175
133
  getEntryURL: props.getEntryURL
176
134
  })));
177
135
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"field-editor-validation-errors.cjs.development.js","sources":["../src/styles.ts","../src/ValidationErrors.tsx"],"sourcesContent":["import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const errorList = css({\n padding: 0,\n wordWrap: 'break-word',\n marginTop: tokens.spacingS,\n color: tokens.red500,\n listStyleType: 'none',\n});\n\nexport const errorMessage = css({\n display: 'inline-flex',\n flexDirection: 'column',\n marginLeft: tokens.spacingXs,\n});\n\nexport const errorItem = css({\n display: 'flex',\n alignItems: 'center',\n});\n\nexport const entryLink = css({\n fontWeight: Number(tokens.fontWeightDemiBold),\n});\n","import React from 'react';\nimport { ValidationError, Link } from '@contentful/app-sdk';\nimport type {\n SpaceAPI,\n Entry,\n ContentType,\n FieldAPI,\n LocalesAPI,\n} from '@contentful/field-editor-shared';\nimport { entityHelpers } from '@contentful/field-editor-shared';\n\nimport * as styles from './styles';\n\nimport { TextLink, List, ListItem } from '@contentful/f36-components';\n\nimport { ExternalLinkIcon, InfoCircleIcon } from '@contentful/f36-icons';\n\ntype UniquenessErrorProps = {\n error: ValidationError;\n space: SpaceAPI;\n localeCode: string;\n defaultLocaleCode: string;\n getEntryURL: (entry: Entry) => string;\n};\n\nfunction UniquenessError(props: UniquenessErrorProps) {\n const [state, setState] = React.useState<{\n loading: boolean;\n entries: { id: string; title: string; href: string }[];\n }>({\n loading: true,\n entries: [],\n });\n\n const contentTypesById = React.useMemo(\n (): Record<string, ContentType> =>\n // Maps ID => Content Type\n props.space.getCachedContentTypes().reduce(\n (prev, ct) => ({\n ...prev,\n [ct.sys.id]: ct,\n }),\n {}\n ),\n [props.space]\n );\n\n const getTitle = React.useCallback(\n (entry: Entry) =>\n entityHelpers.getEntryTitle({\n entry,\n defaultTitle: 'Untitled',\n localeCode: props.localeCode,\n defaultLocaleCode: props.defaultLocaleCode,\n contentType: contentTypesById[entry.sys.contentType.sys.id],\n }),\n [props.localeCode, props.defaultLocaleCode, contentTypesById]\n );\n\n let conflicting: Link<'Entry', 'Link'>[] = [];\n if ('conflicting' in props.error) {\n conflicting = props.error.conflicting;\n }\n React.useEffect(() => {\n const entryIds = state.entries.map((entry) => entry.id);\n const conflictIds = conflicting.map((entry) => entry.sys.id);\n\n // Avoid unnecessary refetching\n if (conflictIds.every((id) => entryIds.includes(id))) {\n return;\n }\n\n setState((state) => ({ ...state, loading: true }));\n\n const query = {\n 'sys.id[in]': conflictIds.join(','),\n };\n\n props.space.getEntries<Entry>(query).then(({ items }) => {\n const entries = items.map((entry) => ({\n id: entry.sys.id,\n title: getTitle(entry),\n href: props.getEntryURL(entry),\n }));\n\n setState({\n loading: false,\n entries,\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies\n }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);\n\n return (\n <List className={styles.errorList} testId=\"validation-errors-uniqueness\">\n <ListItem className={styles.entryLink}>\n {state.loading ? (\n <div>Loading title for conflicting entry…</div>\n ) : (\n state.entries.map((entry) => (\n <TextLink\n key={entry.id}\n href={entry.href}\n icon={<ExternalLinkIcon />}\n alignIcon=\"end\"\n variant=\"negative\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n {entry.title}\n </TextLink>\n ))\n )}\n </ListItem>\n </List>\n );\n}\n\nexport interface ValidationErrorsProps {\n field: FieldAPI;\n space: SpaceAPI;\n locales: LocalesAPI;\n getEntryURL: (entry: Entry) => string;\n}\n\nexport function ValidationErrors(props: ValidationErrorsProps) {\n const [errors, setErrors] = React.useState<ValidationError[]>([]);\n\n React.useEffect(() => {\n const onErrors = (errors?: ValidationError[]) => {\n setErrors(errors || []);\n };\n\n return props.field.onSchemaErrorsChanged(onErrors);\n }, [props.field]);\n\n if (errors.length === 0) {\n return null;\n }\n\n return (\n <List className={styles.errorList} testId=\"validation-errors\">\n {errors.map((error, index) => {\n return (\n <li\n key={index}\n role=\"status\"\n aria-roledescription=\"field-locale-schema\"\n data-error-code={`entry.schema.${error.name}`}\n className={styles.errorItem}>\n <InfoCircleIcon variant=\"negative\" />\n <div className={styles.errorMessage}>\n {error.message}\n {error.name === 'unique' && (\n <UniquenessError\n error={error}\n space={props.space}\n localeCode={props.field.locale}\n defaultLocaleCode={props.locales.default}\n getEntryURL={props.getEntryURL}\n />\n )}\n </div>\n </li>\n );\n })}\n </List>\n );\n}\n"],"names":["errorList","css","padding","wordWrap","marginTop","tokens","spacingS","color","red500","listStyleType","errorMessage","display","flexDirection","marginLeft","spacingXs","errorItem","alignItems","entryLink","fontWeight","Number","fontWeightDemiBold","UniquenessError","props","React","useState","loading","entries","state","setState","contentTypesById","useMemo","space","getCachedContentTypes","reduce","prev","ct","sys","id","getTitle","useCallback","entry","entityHelpers","getEntryTitle","defaultTitle","localeCode","defaultLocaleCode","contentType","conflicting","error","useEffect","entryIds","map","conflictIds","every","includes","query","join","getEntries","then","items","title","href","getEntryURL","List","className","styles","testId","ListItem","TextLink","key","icon","ExternalLinkIcon","alignIcon","variant","target","rel","ValidationErrors","errors","setErrors","onErrors","field","onSchemaErrorsChanged","length","index","role","name","InfoCircleIcon","message","locale","locales"],"mappings":"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"}
1
+ {"version":3,"file":"field-editor-validation-errors.cjs.development.js","sources":["../src/styles.ts","../src/ValidationErrors.tsx"],"sourcesContent":["import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport const errorList = css({\n padding: 0,\n wordWrap: 'break-word',\n marginTop: tokens.spacingS,\n color: tokens.red500,\n listStyleType: 'none',\n});\n\nexport const errorMessage = css({\n display: 'inline-flex',\n flexDirection: 'column',\n marginLeft: tokens.spacingXs,\n});\n\nexport const errorItem = css({\n display: 'flex',\n alignItems: 'center',\n});\n\nexport const entryLink = css({\n fontWeight: Number(tokens.fontWeightDemiBold),\n});\n","import React from 'react';\n\nimport { ValidationError, Link } from '@contentful/app-sdk';\nimport { TextLink, List, ListItem } from '@contentful/f36-components';\nimport { ExternalLinkIcon, InfoCircleIcon } from '@contentful/f36-icons';\nimport type {\n SpaceAPI,\n Entry,\n ContentType,\n FieldAPI,\n LocalesAPI,\n} from '@contentful/field-editor-shared';\nimport { entityHelpers } from '@contentful/field-editor-shared';\n\nimport * as styles from './styles';\n\ntype UniquenessErrorProps = {\n error: ValidationError;\n space: SpaceAPI;\n localeCode: string;\n defaultLocaleCode: string;\n getEntryURL: (entry: Entry) => string;\n};\n\nfunction UniquenessError(props: UniquenessErrorProps) {\n const [state, setState] = React.useState<{\n loading: boolean;\n entries: { id: string; title: string; href: string }[];\n }>({\n loading: true,\n entries: [],\n });\n\n const contentTypesById = React.useMemo(\n (): Record<string, ContentType> =>\n // Maps ID => Content Type\n props.space.getCachedContentTypes().reduce(\n (prev, ct) => ({\n ...prev,\n [ct.sys.id]: ct,\n }),\n {}\n ),\n [props.space]\n );\n\n const getTitle = React.useCallback(\n (entry: Entry) =>\n entityHelpers.getEntryTitle({\n entry,\n defaultTitle: 'Untitled',\n localeCode: props.localeCode,\n defaultLocaleCode: props.defaultLocaleCode,\n contentType: contentTypesById[entry.sys.contentType.sys.id],\n }),\n [props.localeCode, props.defaultLocaleCode, contentTypesById]\n );\n\n let conflicting: Link<'Entry', 'Link'>[] = [];\n if ('conflicting' in props.error) {\n conflicting = props.error.conflicting;\n }\n React.useEffect(() => {\n const entryIds = state.entries.map((entry) => entry.id);\n const conflictIds = conflicting.map((entry) => entry.sys.id);\n\n // Avoid unnecessary refetching\n if (conflictIds.every((id) => entryIds.includes(id))) {\n return;\n }\n\n setState((state) => ({ ...state, loading: true }));\n\n const query = {\n 'sys.id[in]': conflictIds.join(','),\n };\n\n props.space.getEntries<Entry>(query).then(({ items }) => {\n const entries = items.map((entry) => ({\n id: entry.sys.id,\n title: getTitle(entry),\n href: props.getEntryURL(entry),\n }));\n\n setState({\n loading: false,\n entries,\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies\n }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);\n\n return (\n <List className={styles.errorList} testId=\"validation-errors-uniqueness\">\n <ListItem className={styles.entryLink}>\n {state.loading ? (\n <div>Loading title for conflicting entry…</div>\n ) : (\n state.entries.map((entry) => (\n <TextLink\n key={entry.id}\n href={entry.href}\n icon={<ExternalLinkIcon />}\n alignIcon=\"end\"\n variant=\"negative\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n {entry.title}\n </TextLink>\n ))\n )}\n </ListItem>\n </List>\n );\n}\n\nexport interface ValidationErrorsProps {\n field: FieldAPI;\n space: SpaceAPI;\n locales: LocalesAPI;\n getEntryURL: (entry: Entry) => string;\n}\n\nexport function ValidationErrors(props: ValidationErrorsProps) {\n const [errors, setErrors] = React.useState<ValidationError[]>([]);\n\n React.useEffect(() => {\n const onErrors = (errors?: ValidationError[]) => {\n setErrors(errors || []);\n };\n\n return props.field.onSchemaErrorsChanged(onErrors);\n }, [props.field]);\n\n if (errors.length === 0) {\n return null;\n }\n\n return (\n <List className={styles.errorList} testId=\"validation-errors\">\n {errors.map((error, index) => {\n return (\n <li\n key={index}\n role=\"status\"\n aria-roledescription=\"field-locale-schema\"\n data-error-code={`entry.schema.${error.name}`}\n className={styles.errorItem}>\n <InfoCircleIcon variant=\"negative\" />\n <div className={styles.errorMessage}>\n {error.message}\n {error.name === 'unique' && (\n <UniquenessError\n error={error}\n space={props.space}\n localeCode={props.field.locale}\n defaultLocaleCode={props.locales.default}\n getEntryURL={props.getEntryURL}\n />\n )}\n </div>\n </li>\n );\n })}\n </List>\n );\n}\n"],"names":["errorList","css","padding","wordWrap","marginTop","tokens","spacingS","color","red500","listStyleType","errorMessage","display","flexDirection","marginLeft","spacingXs","errorItem","alignItems","entryLink","fontWeight","Number","fontWeightDemiBold","UniquenessError","props","state","setState","React","useState","loading","entries","contentTypesById","useMemo","space","getCachedContentTypes","reduce","prev","ct","sys","id","getTitle","useCallback","entry","entityHelpers","getEntryTitle","defaultTitle","localeCode","defaultLocaleCode","contentType","conflicting","error","useEffect","entryIds","map","conflictIds","every","includes","query","join","getEntries","then","items","title","href","getEntryURL","List","className","styles","testId","ListItem","TextLink","key","icon","ExternalLinkIcon","alignIcon","variant","target","rel","ValidationErrors","errors","setErrors","onErrors","field","onSchemaErrorsChanged","length","index","role","name","InfoCircleIcon","message","locale","locales","default"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("react")),n=require("@contentful/field-editor-shared"),r=require("emotion"),i=e(require("@contentful/f36-tokens")),a=require("@contentful/f36-components"),o=require("@contentful/f36-icons");function l(){return(l=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}var c=r.css({padding:0,wordWrap:"break-word",marginTop:i.spacingS,color:i.red500,listStyleType:"none"}),s=r.css({display:"inline-flex",flexDirection:"column",marginLeft:i.spacingXs}),u=r.css({display:"flex",alignItems:"center"}),f=r.css({fontWeight:Number(i.fontWeightDemiBold)});function d(e){var r=t.useState({loading:!0,entries:[]}),i=r[0],s=r[1],u=t.useMemo((function(){return e.space.getCachedContentTypes().reduce((function(e,t){var n;return l({},e,((n={})[t.sys.id]=t,n))}),{})}),[e.space]),d=t.useCallback((function(t){return n.entityHelpers.getEntryTitle({entry:t,defaultTitle:"Untitled",localeCode:e.localeCode,defaultLocaleCode:e.defaultLocaleCode,contentType:u[t.sys.contentType.sys.id]})}),[e.localeCode,e.defaultLocaleCode,u]),m=[];return"conflicting"in e.error&&(m=e.error.conflicting),t.useEffect((function(){var t=i.entries.map((function(e){return e.id})),n=m.map((function(e){return e.sys.id}));if(!n.every((function(e){return t.includes(e)}))){s((function(e){return l({},e,{loading:!0})}));var r={"sys.id[in]":n.join(",")};e.space.getEntries(r).then((function(t){var n=t.items.map((function(t){return{id:t.sys.id,title:d(t),href:e.getEntryURL(t)}}));s({loading:!1,entries:n})}))}}),[d,i.entries,m,e.space.getEntries,e.getEntryURL]),t.createElement(a.List,{className:c,testId:"validation-errors-uniqueness"},t.createElement(a.ListItem,{className:f},i.loading?t.createElement("div",null,"Loading title for conflicting entry…"):i.entries.map((function(e){return t.createElement(a.TextLink,{key:e.id,href:e.href,icon:t.createElement(o.ExternalLinkIcon,null),alignIcon:"end",variant:"negative",target:"_blank",rel:"noopener noreferrer"},e.title)}))))}exports.ValidationErrors=function(e){var n=t.useState([]),r=n[0],i=n[1];return t.useEffect((function(){return e.field.onSchemaErrorsChanged((function(e){i(e||[])}))}),[e.field]),0===r.length?null:t.createElement(a.List,{className:c,testId:"validation-errors"},r.map((function(n,r){return t.createElement("li",{key:r,role:"status","aria-roledescription":"field-locale-schema","data-error-code":"entry.schema."+n.name,className:u},t.createElement(o.InfoCircleIcon,{variant:"negative"}),t.createElement("div",{className:s},n.message,"unique"===n.name&&t.createElement(d,{error:n,space:e.space,localeCode:e.field.locale,defaultLocaleCode:e.locales.default,getEntryURL:e.getEntryURL})))})))};
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e.default:e}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("react")),n=require("@contentful/f36-components"),r=require("@contentful/f36-icons"),a=require("@contentful/field-editor-shared"),i=e(require("@contentful/f36-tokens")),l=require("emotion");const o=l.css({padding:0,wordWrap:"break-word",marginTop:i.spacingS,color:i.red500,listStyleType:"none"}),s=l.css({display:"inline-flex",flexDirection:"column",marginLeft:i.spacingXs}),c=l.css({display:"flex",alignItems:"center"}),d=l.css({fontWeight:Number(i.fontWeightDemiBold)});function u(e){const[i,l]=t.useState({loading:!0,entries:[]}),s=t.useMemo(()=>e.space.getCachedContentTypes().reduce((e,t)=>({...e,[t.sys.id]:t}),{}),[e.space]),c=t.useCallback(t=>a.entityHelpers.getEntryTitle({entry:t,defaultTitle:"Untitled",localeCode:e.localeCode,defaultLocaleCode:e.defaultLocaleCode,contentType:s[t.sys.contentType.sys.id]}),[e.localeCode,e.defaultLocaleCode,s]);let u=[];return"conflicting"in e.error&&(u=e.error.conflicting),t.useEffect(()=>{const t=i.entries.map(e=>e.id),n=u.map(e=>e.sys.id);if(n.every(e=>t.includes(e)))return;l(e=>({...e,loading:!0}));const r={"sys.id[in]":n.join(",")};e.space.getEntries(r).then(({items:t})=>{const n=t.map(t=>({id:t.sys.id,title:c(t),href:e.getEntryURL(t)}));l({loading:!1,entries:n})})},[c,i.entries,u,e.space.getEntries,e.getEntryURL]),t.createElement(n.List,{className:o,testId:"validation-errors-uniqueness"},t.createElement(n.ListItem,{className:d},i.loading?t.createElement("div",null,"Loading title for conflicting entry…"):i.entries.map(e=>t.createElement(n.TextLink,{key:e.id,href:e.href,icon:t.createElement(r.ExternalLinkIcon,null),alignIcon:"end",variant:"negative",target:"_blank",rel:"noopener noreferrer"},e.title))))}exports.ValidationErrors=function(e){const[a,i]=t.useState([]);return t.useEffect(()=>e.field.onSchemaErrorsChanged(e=>{i(e||[])}),[e.field]),0===a.length?null:t.createElement(n.List,{className:o,testId:"validation-errors"},a.map((n,a)=>t.createElement("li",{key:a,role:"status","aria-roledescription":"field-locale-schema","data-error-code":"entry.schema."+n.name,className:c},t.createElement(r.InfoCircleIcon,{variant:"negative"}),t.createElement("div",{className:s},n.message,"unique"===n.name&&t.createElement(u,{error:n,space:e.space,localeCode:e.field.locale,defaultLocaleCode:e.locales.default,getEntryURL:e.getEntryURL})))))};
2
2
  //# sourceMappingURL=field-editor-validation-errors.cjs.production.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"field-editor-validation-errors.cjs.production.min.js","sources":["../src/styles.ts","../src/ValidationErrors.tsx"],"sourcesContent":["import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const errorList = css({\n padding: 0,\n wordWrap: 'break-word',\n marginTop: tokens.spacingS,\n color: tokens.red500,\n listStyleType: 'none',\n});\n\nexport const errorMessage = css({\n display: 'inline-flex',\n flexDirection: 'column',\n marginLeft: tokens.spacingXs,\n});\n\nexport const errorItem = css({\n display: 'flex',\n alignItems: 'center',\n});\n\nexport const entryLink = css({\n fontWeight: Number(tokens.fontWeightDemiBold),\n});\n","import React from 'react';\nimport { ValidationError, Link } from '@contentful/app-sdk';\nimport type {\n SpaceAPI,\n Entry,\n ContentType,\n FieldAPI,\n LocalesAPI,\n} from '@contentful/field-editor-shared';\nimport { entityHelpers } from '@contentful/field-editor-shared';\n\nimport * as styles from './styles';\n\nimport { TextLink, List, ListItem } from '@contentful/f36-components';\n\nimport { ExternalLinkIcon, InfoCircleIcon } from '@contentful/f36-icons';\n\ntype UniquenessErrorProps = {\n error: ValidationError;\n space: SpaceAPI;\n localeCode: string;\n defaultLocaleCode: string;\n getEntryURL: (entry: Entry) => string;\n};\n\nfunction UniquenessError(props: UniquenessErrorProps) {\n const [state, setState] = React.useState<{\n loading: boolean;\n entries: { id: string; title: string; href: string }[];\n }>({\n loading: true,\n entries: [],\n });\n\n const contentTypesById = React.useMemo(\n (): Record<string, ContentType> =>\n // Maps ID => Content Type\n props.space.getCachedContentTypes().reduce(\n (prev, ct) => ({\n ...prev,\n [ct.sys.id]: ct,\n }),\n {}\n ),\n [props.space]\n );\n\n const getTitle = React.useCallback(\n (entry: Entry) =>\n entityHelpers.getEntryTitle({\n entry,\n defaultTitle: 'Untitled',\n localeCode: props.localeCode,\n defaultLocaleCode: props.defaultLocaleCode,\n contentType: contentTypesById[entry.sys.contentType.sys.id],\n }),\n [props.localeCode, props.defaultLocaleCode, contentTypesById]\n );\n\n let conflicting: Link<'Entry', 'Link'>[] = [];\n if ('conflicting' in props.error) {\n conflicting = props.error.conflicting;\n }\n React.useEffect(() => {\n const entryIds = state.entries.map((entry) => entry.id);\n const conflictIds = conflicting.map((entry) => entry.sys.id);\n\n // Avoid unnecessary refetching\n if (conflictIds.every((id) => entryIds.includes(id))) {\n return;\n }\n\n setState((state) => ({ ...state, loading: true }));\n\n const query = {\n 'sys.id[in]': conflictIds.join(','),\n };\n\n props.space.getEntries<Entry>(query).then(({ items }) => {\n const entries = items.map((entry) => ({\n id: entry.sys.id,\n title: getTitle(entry),\n href: props.getEntryURL(entry),\n }));\n\n setState({\n loading: false,\n entries,\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies\n }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);\n\n return (\n <List className={styles.errorList} testId=\"validation-errors-uniqueness\">\n <ListItem className={styles.entryLink}>\n {state.loading ? (\n <div>Loading title for conflicting entry…</div>\n ) : (\n state.entries.map((entry) => (\n <TextLink\n key={entry.id}\n href={entry.href}\n icon={<ExternalLinkIcon />}\n alignIcon=\"end\"\n variant=\"negative\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n {entry.title}\n </TextLink>\n ))\n )}\n </ListItem>\n </List>\n );\n}\n\nexport interface ValidationErrorsProps {\n field: FieldAPI;\n space: SpaceAPI;\n locales: LocalesAPI;\n getEntryURL: (entry: Entry) => string;\n}\n\nexport function ValidationErrors(props: ValidationErrorsProps) {\n const [errors, setErrors] = React.useState<ValidationError[]>([]);\n\n React.useEffect(() => {\n const onErrors = (errors?: ValidationError[]) => {\n setErrors(errors || []);\n };\n\n return props.field.onSchemaErrorsChanged(onErrors);\n }, [props.field]);\n\n if (errors.length === 0) {\n return null;\n }\n\n return (\n <List className={styles.errorList} testId=\"validation-errors\">\n {errors.map((error, index) => {\n return (\n <li\n key={index}\n role=\"status\"\n aria-roledescription=\"field-locale-schema\"\n data-error-code={`entry.schema.${error.name}`}\n className={styles.errorItem}>\n <InfoCircleIcon variant=\"negative\" />\n <div className={styles.errorMessage}>\n {error.message}\n {error.name === 'unique' && (\n <UniquenessError\n error={error}\n space={props.space}\n localeCode={props.field.locale}\n defaultLocaleCode={props.locales.default}\n getEntryURL={props.getEntryURL}\n />\n )}\n </div>\n </li>\n );\n })}\n </List>\n );\n}\n"],"names":["errorList","css","padding","wordWrap","marginTop","tokens","spacingS","color","red500","listStyleType","errorMessage","display","flexDirection","marginLeft","spacingXs","errorItem","alignItems","entryLink","fontWeight","Number","fontWeightDemiBold","UniquenessError","props","React","useState","loading","entries","state","setState","contentTypesById","useMemo","space","getCachedContentTypes","reduce","prev","ct","sys","id","getTitle","useCallback","entry","entityHelpers","getEntryTitle","defaultTitle","localeCode","defaultLocaleCode","contentType","conflicting","error","useEffect","entryIds","map","conflictIds","every","includes","query","join","getEntries","then","items","title","href","getEntryURL","List","className","styles","testId","ListItem","TextLink","key","icon","ExternalLinkIcon","alignIcon","variant","target","rel","errors","setErrors","field","onSchemaErrorsChanged","length","index","role","name","InfoCircleIcon","message","locale","locales"],"mappings":"uiBAGO,IAAMA,EAAYC,MAAI,CAC3BC,QAAS,EACTC,SAAU,aACVC,UAAWC,EAAOC,SAClBC,MAAOF,EAAOG,OACdC,cAAe,SAGJC,EAAeT,MAAI,CAC9BU,QAAS,cACTC,cAAe,SACfC,WAAYR,EAAOS,YAGRC,EAAYd,MAAI,CAC3BU,QAAS,OACTK,WAAY,WAGDC,EAAYhB,MAAI,CAC3BiB,WAAYC,OAAOd,EAAOe,sBCE5B,SAASC,EAAgBC,SACGC,EAAMC,SAG7B,CACDC,SAAS,EACTC,QAAS,KALJC,OAAOC,OAQRC,EAAmBN,EAAMO,SAC7B,kBAEER,EAAMS,MAAMC,wBAAwBC,QAClC,SAACC,EAAMC,qBACFD,UACFC,EAAGC,IAAIC,IAAKF,QAEf,MAEJ,CAACb,EAAMS,QAGHO,EAAWf,EAAMgB,aACrB,SAACC,UACCC,gBAAcC,cAAc,CAC1BF,MAAAA,EACAG,aAAc,WACdC,WAAYtB,EAAMsB,WAClBC,kBAAmBvB,EAAMuB,kBACzBC,YAAajB,EAAiBW,EAAMJ,IAAIU,YAAYV,IAAIC,QAE5D,CAACf,EAAMsB,WAAYtB,EAAMuB,kBAAmBhB,IAG1CkB,EAAuC,SACvC,gBAAiBzB,EAAM0B,QACzBD,EAAczB,EAAM0B,MAAMD,aAE5BxB,EAAM0B,WAAU,eACRC,EAAWvB,EAAMD,QAAQyB,KAAI,SAACX,UAAUA,EAAMH,MAC9Ce,EAAcL,EAAYI,KAAI,SAACX,UAAUA,EAAMJ,IAAIC,UAGrDe,EAAYC,OAAM,SAAChB,UAAOa,EAASI,SAASjB,OAIhDT,GAAS,SAACD,eAAgBA,GAAOF,SAAS,WAEpC8B,EAAQ,cACEH,EAAYI,KAAK,MAGjClC,EAAMS,MAAM0B,WAAkBF,GAAOG,MAAK,gBAClChC,IADqCiC,MACrBR,KAAI,SAACX,SAAW,CACpCH,GAAIG,EAAMJ,IAAIC,GACduB,MAAOtB,EAASE,GAChBqB,KAAMvC,EAAMwC,YAAYtB,OAG1BZ,EAAS,CACPH,SAAS,EACTC,QAAAA,UAIH,CAACY,EAAUX,EAAMD,QAASqB,EAAazB,EAAMS,MAAM0B,WAAYnC,EAAMwC,cAGtEvC,gBAACwC,QAAKC,UAAWC,EAAkBC,OAAO,gCACxC3C,gBAAC4C,YAASH,UAAWC,GAClBtC,EAAMF,QACLF,mEAEAI,EAAMD,QAAQyB,KAAI,SAACX,UACjBjB,gBAAC6C,YACCC,IAAK7B,EAAMH,GACXwB,KAAMrB,EAAMqB,KACZS,KAAM/C,gBAACgD,yBACPC,UAAU,MACVC,QAAQ,WACRC,OAAO,SACPC,IAAI,uBACHnC,EAAMoB,8CAgBYtC,SACHC,EAAMC,SAA4B,IAAvDoD,OAAQC,cAEftD,EAAM0B,WAAU,kBAKP3B,EAAMwD,MAAMC,uBAJF,SAACH,GAChBC,EAAUD,GAAU,SAIrB,CAACtD,EAAMwD,QAEY,IAAlBF,EAAOI,OACF,KAIPzD,gBAACwC,QAAKC,UAAWC,EAAkBC,OAAO,qBACvCU,EAAOzB,KAAI,SAACH,EAAOiC,UAEhB1D,sBACE8C,IAAKY,EACLC,KAAK,gCACgB,wDACYlC,EAAMmC,KACvCnB,UAAWC,GACX1C,gBAAC6D,kBAAeX,QAAQ,aACxBlD,uBAAKyC,UAAWC,GACbjB,EAAMqC,QACS,WAAfrC,EAAMmC,MACL5D,gBAACF,GACC2B,MAAOA,EACPjB,MAAOT,EAAMS,MACba,WAAYtB,EAAMwD,MAAMQ,OACxBzC,kBAAmBvB,EAAMiE,gBACzBzB,YAAaxC,EAAMwC"}
1
+ {"version":3,"file":"field-editor-validation-errors.cjs.production.min.js","sources":["../src/styles.ts","../src/ValidationErrors.tsx"],"sourcesContent":["import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport const errorList = css({\n padding: 0,\n wordWrap: 'break-word',\n marginTop: tokens.spacingS,\n color: tokens.red500,\n listStyleType: 'none',\n});\n\nexport const errorMessage = css({\n display: 'inline-flex',\n flexDirection: 'column',\n marginLeft: tokens.spacingXs,\n});\n\nexport const errorItem = css({\n display: 'flex',\n alignItems: 'center',\n});\n\nexport const entryLink = css({\n fontWeight: Number(tokens.fontWeightDemiBold),\n});\n","import React from 'react';\n\nimport { ValidationError, Link } from '@contentful/app-sdk';\nimport { TextLink, List, ListItem } from '@contentful/f36-components';\nimport { ExternalLinkIcon, InfoCircleIcon } from '@contentful/f36-icons';\nimport type {\n SpaceAPI,\n Entry,\n ContentType,\n FieldAPI,\n LocalesAPI,\n} from '@contentful/field-editor-shared';\nimport { entityHelpers } from '@contentful/field-editor-shared';\n\nimport * as styles from './styles';\n\ntype UniquenessErrorProps = {\n error: ValidationError;\n space: SpaceAPI;\n localeCode: string;\n defaultLocaleCode: string;\n getEntryURL: (entry: Entry) => string;\n};\n\nfunction UniquenessError(props: UniquenessErrorProps) {\n const [state, setState] = React.useState<{\n loading: boolean;\n entries: { id: string; title: string; href: string }[];\n }>({\n loading: true,\n entries: [],\n });\n\n const contentTypesById = React.useMemo(\n (): Record<string, ContentType> =>\n // Maps ID => Content Type\n props.space.getCachedContentTypes().reduce(\n (prev, ct) => ({\n ...prev,\n [ct.sys.id]: ct,\n }),\n {}\n ),\n [props.space]\n );\n\n const getTitle = React.useCallback(\n (entry: Entry) =>\n entityHelpers.getEntryTitle({\n entry,\n defaultTitle: 'Untitled',\n localeCode: props.localeCode,\n defaultLocaleCode: props.defaultLocaleCode,\n contentType: contentTypesById[entry.sys.contentType.sys.id],\n }),\n [props.localeCode, props.defaultLocaleCode, contentTypesById]\n );\n\n let conflicting: Link<'Entry', 'Link'>[] = [];\n if ('conflicting' in props.error) {\n conflicting = props.error.conflicting;\n }\n React.useEffect(() => {\n const entryIds = state.entries.map((entry) => entry.id);\n const conflictIds = conflicting.map((entry) => entry.sys.id);\n\n // Avoid unnecessary refetching\n if (conflictIds.every((id) => entryIds.includes(id))) {\n return;\n }\n\n setState((state) => ({ ...state, loading: true }));\n\n const query = {\n 'sys.id[in]': conflictIds.join(','),\n };\n\n props.space.getEntries<Entry>(query).then(({ items }) => {\n const entries = items.map((entry) => ({\n id: entry.sys.id,\n title: getTitle(entry),\n href: props.getEntryURL(entry),\n }));\n\n setState({\n loading: false,\n entries,\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies\n }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);\n\n return (\n <List className={styles.errorList} testId=\"validation-errors-uniqueness\">\n <ListItem className={styles.entryLink}>\n {state.loading ? (\n <div>Loading title for conflicting entry…</div>\n ) : (\n state.entries.map((entry) => (\n <TextLink\n key={entry.id}\n href={entry.href}\n icon={<ExternalLinkIcon />}\n alignIcon=\"end\"\n variant=\"negative\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n {entry.title}\n </TextLink>\n ))\n )}\n </ListItem>\n </List>\n );\n}\n\nexport interface ValidationErrorsProps {\n field: FieldAPI;\n space: SpaceAPI;\n locales: LocalesAPI;\n getEntryURL: (entry: Entry) => string;\n}\n\nexport function ValidationErrors(props: ValidationErrorsProps) {\n const [errors, setErrors] = React.useState<ValidationError[]>([]);\n\n React.useEffect(() => {\n const onErrors = (errors?: ValidationError[]) => {\n setErrors(errors || []);\n };\n\n return props.field.onSchemaErrorsChanged(onErrors);\n }, [props.field]);\n\n if (errors.length === 0) {\n return null;\n }\n\n return (\n <List className={styles.errorList} testId=\"validation-errors\">\n {errors.map((error, index) => {\n return (\n <li\n key={index}\n role=\"status\"\n aria-roledescription=\"field-locale-schema\"\n data-error-code={`entry.schema.${error.name}`}\n className={styles.errorItem}>\n <InfoCircleIcon variant=\"negative\" />\n <div className={styles.errorMessage}>\n {error.message}\n {error.name === 'unique' && (\n <UniquenessError\n error={error}\n space={props.space}\n localeCode={props.field.locale}\n defaultLocaleCode={props.locales.default}\n getEntryURL={props.getEntryURL}\n />\n )}\n </div>\n </li>\n );\n })}\n </List>\n );\n}\n"],"names":["errorList","css","padding","wordWrap","marginTop","tokens","spacingS","color","red500","listStyleType","errorMessage","display","flexDirection","marginLeft","spacingXs","errorItem","alignItems","entryLink","fontWeight","Number","fontWeightDemiBold","UniquenessError","props","state","setState","React","useState","loading","entries","contentTypesById","useMemo","space","getCachedContentTypes","reduce","prev","ct","sys","id","getTitle","useCallback","entry","entityHelpers","getEntryTitle","defaultTitle","localeCode","defaultLocaleCode","contentType","conflicting","error","useEffect","entryIds","map","conflictIds","every","includes","query","join","getEntries","then","items","title","href","getEntryURL","List","className","styles","testId","ListItem","TextLink","key","icon","ExternalLinkIcon","alignIcon","variant","target","rel","errors","setErrors","field","onSchemaErrorsChanged","length","index","role","name","InfoCircleIcon","message","locale","locales","default"],"mappings":"wVAGO,MAAMA,EAAYC,MAAI,CAC3BC,QAAS,EACTC,SAAU,aACVC,UAAWC,EAAOC,SAClBC,MAAOF,EAAOG,OACdC,cAAe,SAGJC,EAAeT,MAAI,CAC9BU,QAAS,cACTC,cAAe,SACfC,WAAYR,EAAOS,YAGRC,EAAYd,MAAI,CAC3BU,QAAS,OACTK,WAAY,WAGDC,EAAYhB,MAAI,CAC3BiB,WAAYC,OAAOd,EAAOe,sBCC5B,SAASC,EAAgBC,SAChBC,EAAOC,GAAYC,EAAMC,SAG7B,CACDC,SAAS,EACTC,QAAS,KAGLC,EAAmBJ,EAAMK,QAC7B,IAEER,EAAMS,MAAMC,wBAAwBC,OAClC,CAACC,EAAMC,SACFD,GACFC,EAAGC,IAAIC,IAAKF,IAEf,IAEJ,CAACb,EAAMS,QAGHO,EAAWb,EAAMc,YACpBC,GACCC,gBAAcC,cAAc,CAC1BF,MAAAA,EACAG,aAAc,WACdC,WAAYtB,EAAMsB,WAClBC,kBAAmBvB,EAAMuB,kBACzBC,YAAajB,EAAiBW,EAAMJ,IAAIU,YAAYV,IAAIC,MAE5D,CAACf,EAAMsB,WAAYtB,EAAMuB,kBAAmBhB,QAG1CkB,EAAuC,SACvC,gBAAiBzB,EAAM0B,QACzBD,EAAczB,EAAM0B,MAAMD,aAE5BtB,EAAMwB,UAAU,WACRC,EAAW3B,EAAMK,QAAQuB,IAAKX,GAAUA,EAAMH,IAC9Ce,EAAcL,EAAYI,IAAKX,GAAUA,EAAMJ,IAAIC,OAGrDe,EAAYC,MAAOhB,GAAOa,EAASI,SAASjB,WAIhDb,EAAUD,QAAgBA,EAAOI,SAAS,WAEpC4B,EAAQ,cACEH,EAAYI,KAAK,MAGjClC,EAAMS,MAAM0B,WAAkBF,GAAOG,KAAK,EAAGC,MAAAA,YACrC/B,EAAU+B,EAAMR,IAAKX,KACzBH,GAAIG,EAAMJ,IAAIC,GACduB,MAAOtB,EAASE,GAChBqB,KAAMvC,EAAMwC,YAAYtB,MAG1BhB,EAAS,CACPG,SAAS,EACTC,QAAAA,OAIH,CAACU,EAAUf,EAAMK,QAASmB,EAAazB,EAAMS,MAAM0B,WAAYnC,EAAMwC,cAGtErC,gBAACsC,QAAKC,UAAWC,EAAkBC,OAAO,gCACxCzC,gBAAC0C,YAASH,UAAWC,GAClB1C,EAAMI,QACLF,mEAEAF,EAAMK,QAAQuB,IAAKX,GACjBf,gBAAC2C,YACCC,IAAK7B,EAAMH,GACXwB,KAAMrB,EAAMqB,KACZS,KAAM7C,gBAAC8C,yBACPC,UAAU,MACVC,QAAQ,WACRC,OAAO,SACPC,IAAI,uBACHnC,EAAMoB,4CAgBYtC,SACxBsD,EAAQC,GAAapD,EAAMC,SAA4B,WAE9DD,EAAMwB,UAAU,IAKP3B,EAAMwD,MAAMC,sBAJDH,IAChBC,EAAUD,GAAU,MAIrB,CAACtD,EAAMwD,QAEY,IAAlBF,EAAOI,OACF,KAIPvD,gBAACsC,QAAKC,UAAWC,EAAkBC,OAAO,qBACvCU,EAAOzB,IAAI,CAACH,EAAOiC,IAEhBxD,sBACE4C,IAAKY,EACLC,KAAK,gCACgB,wDACYlC,EAAMmC,KACvCnB,UAAWC,GACXxC,gBAAC2D,kBAAeX,QAAQ,aACxBhD,uBAAKuC,UAAWC,GACbjB,EAAMqC,QACS,WAAfrC,EAAMmC,MACL1D,gBAACJ,GACC2B,MAAOA,EACPjB,MAAOT,EAAMS,MACba,WAAYtB,EAAMwD,MAAMQ,OACxBzC,kBAAmBvB,EAAMiE,QAAQC,QACjC1B,YAAaxC,EAAMwC"}
@@ -1,114 +1,77 @@
1
1
  import React from 'react';
2
- import { entityHelpers } from '@contentful/field-editor-shared';
3
- import { css } from 'emotion';
4
- import tokens from '@contentful/f36-tokens';
5
2
  import { List, ListItem, TextLink } from '@contentful/f36-components';
6
3
  import { InfoCircleIcon, ExternalLinkIcon } from '@contentful/f36-icons';
4
+ import { entityHelpers } from '@contentful/field-editor-shared';
5
+ import tokens from '@contentful/f36-tokens';
6
+ import { css } from 'emotion';
7
7
 
8
- function _extends() {
9
- _extends = Object.assign || function (target) {
10
- for (var i = 1; i < arguments.length; i++) {
11
- var source = arguments[i];
12
-
13
- for (var key in source) {
14
- if (Object.prototype.hasOwnProperty.call(source, key)) {
15
- target[key] = source[key];
16
- }
17
- }
18
- }
19
-
20
- return target;
21
- };
22
-
23
- return _extends.apply(this, arguments);
24
- }
25
-
26
- var errorList = /*#__PURE__*/css({
8
+ const errorList = /*#__PURE__*/css({
27
9
  padding: 0,
28
10
  wordWrap: 'break-word',
29
11
  marginTop: tokens.spacingS,
30
12
  color: tokens.red500,
31
13
  listStyleType: 'none'
32
14
  });
33
- var errorMessage = /*#__PURE__*/css({
15
+ const errorMessage = /*#__PURE__*/css({
34
16
  display: 'inline-flex',
35
17
  flexDirection: 'column',
36
18
  marginLeft: tokens.spacingXs
37
19
  });
38
- var errorItem = /*#__PURE__*/css({
20
+ const errorItem = /*#__PURE__*/css({
39
21
  display: 'flex',
40
22
  alignItems: 'center'
41
23
  });
42
- var entryLink = /*#__PURE__*/css({
24
+ const entryLink = /*#__PURE__*/css({
43
25
  fontWeight: /*#__PURE__*/Number(tokens.fontWeightDemiBold)
44
26
  });
45
27
 
46
28
  function UniquenessError(props) {
47
- var _React$useState = React.useState({
29
+ const [state, setState] = React.useState({
48
30
  loading: true,
49
31
  entries: []
50
- }),
51
- state = _React$useState[0],
52
- setState = _React$useState[1];
53
-
54
- var contentTypesById = React.useMemo(function () {
55
- return (// Maps ID => Content Type
56
- props.space.getCachedContentTypes().reduce(function (prev, ct) {
57
- var _extends2;
58
-
59
- return _extends({}, prev, (_extends2 = {}, _extends2[ct.sys.id] = ct, _extends2));
60
- }, {})
61
- );
62
- }, [props.space]);
63
- var getTitle = React.useCallback(function (entry) {
64
- return entityHelpers.getEntryTitle({
65
- entry: entry,
66
- defaultTitle: 'Untitled',
67
- localeCode: props.localeCode,
68
- defaultLocaleCode: props.defaultLocaleCode,
69
- contentType: contentTypesById[entry.sys.contentType.sys.id]
70
- });
71
- }, [props.localeCode, props.defaultLocaleCode, contentTypesById]);
72
- var conflicting = [];
32
+ });
33
+ const contentTypesById = React.useMemo(() => // Maps ID => Content Type
34
+ props.space.getCachedContentTypes().reduce((prev, ct) => ({ ...prev,
35
+ [ct.sys.id]: ct
36
+ }), {}), [props.space]);
37
+ const getTitle = React.useCallback(entry => entityHelpers.getEntryTitle({
38
+ entry,
39
+ defaultTitle: 'Untitled',
40
+ localeCode: props.localeCode,
41
+ defaultLocaleCode: props.defaultLocaleCode,
42
+ contentType: contentTypesById[entry.sys.contentType.sys.id]
43
+ }), [props.localeCode, props.defaultLocaleCode, contentTypesById]);
44
+ let conflicting = [];
73
45
 
74
46
  if ('conflicting' in props.error) {
75
47
  conflicting = props.error.conflicting;
76
48
  }
77
49
 
78
- React.useEffect(function () {
79
- var entryIds = state.entries.map(function (entry) {
80
- return entry.id;
81
- });
82
- var conflictIds = conflicting.map(function (entry) {
83
- return entry.sys.id;
84
- }); // Avoid unnecessary refetching
50
+ React.useEffect(() => {
51
+ const entryIds = state.entries.map(entry => entry.id);
52
+ const conflictIds = conflicting.map(entry => entry.sys.id); // Avoid unnecessary refetching
85
53
 
86
- if (conflictIds.every(function (id) {
87
- return entryIds.includes(id);
88
- })) {
54
+ if (conflictIds.every(id => entryIds.includes(id))) {
89
55
  return;
90
56
  }
91
57
 
92
- setState(function (state) {
93
- return _extends({}, state, {
94
- loading: true
95
- });
96
- });
97
- var query = {
58
+ setState(state => ({ ...state,
59
+ loading: true
60
+ }));
61
+ const query = {
98
62
  'sys.id[in]': conflictIds.join(',')
99
63
  };
100
- props.space.getEntries(query).then(function (_ref) {
101
- var items = _ref.items;
102
- var entries = items.map(function (entry) {
103
- return {
104
- id: entry.sys.id,
105
- title: getTitle(entry),
106
- href: props.getEntryURL(entry)
107
- };
108
- });
64
+ props.space.getEntries(query).then(({
65
+ items
66
+ }) => {
67
+ const entries = items.map(entry => ({
68
+ id: entry.sys.id,
69
+ title: getTitle(entry),
70
+ href: props.getEntryURL(entry)
71
+ }));
109
72
  setState({
110
73
  loading: false,
111
- entries: entries
74
+ entries
112
75
  });
113
76
  }); // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies
114
77
  }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);
@@ -117,26 +80,21 @@ function UniquenessError(props) {
117
80
  testId: "validation-errors-uniqueness"
118
81
  }, React.createElement(ListItem, {
119
82
  className: entryLink
120
- }, state.loading ? React.createElement("div", null, "Loading title for conflicting entry\u2026") : state.entries.map(function (entry) {
121
- return React.createElement(TextLink, {
122
- key: entry.id,
123
- href: entry.href,
124
- icon: React.createElement(ExternalLinkIcon, null),
125
- alignIcon: "end",
126
- variant: "negative",
127
- target: "_blank",
128
- rel: "noopener noreferrer"
129
- }, entry.title);
130
- })));
83
+ }, state.loading ? React.createElement("div", null, "Loading title for conflicting entry\u2026") : state.entries.map(entry => React.createElement(TextLink, {
84
+ key: entry.id,
85
+ href: entry.href,
86
+ icon: React.createElement(ExternalLinkIcon, null),
87
+ alignIcon: "end",
88
+ variant: "negative",
89
+ target: "_blank",
90
+ rel: "noopener noreferrer"
91
+ }, entry.title))));
131
92
  }
132
93
 
133
94
  function ValidationErrors(props) {
134
- var _React$useState2 = React.useState([]),
135
- errors = _React$useState2[0],
136
- setErrors = _React$useState2[1];
137
-
138
- React.useEffect(function () {
139
- var onErrors = function onErrors(errors) {
95
+ const [errors, setErrors] = React.useState([]);
96
+ React.useEffect(() => {
97
+ const onErrors = errors => {
140
98
  setErrors(errors || []);
141
99
  };
142
100
 
@@ -150,12 +108,12 @@ function ValidationErrors(props) {
150
108
  return React.createElement(List, {
151
109
  className: errorList,
152
110
  testId: "validation-errors"
153
- }, errors.map(function (error, index) {
111
+ }, errors.map((error, index) => {
154
112
  return React.createElement("li", {
155
113
  key: index,
156
114
  role: "status",
157
115
  "aria-roledescription": "field-locale-schema",
158
- "data-error-code": "entry.schema." + error.name,
116
+ "data-error-code": `entry.schema.${error.name}`,
159
117
  className: errorItem
160
118
  }, React.createElement(InfoCircleIcon, {
161
119
  variant: "negative"
@@ -165,7 +123,7 @@ function ValidationErrors(props) {
165
123
  error: error,
166
124
  space: props.space,
167
125
  localeCode: props.field.locale,
168
- defaultLocaleCode: props.locales["default"],
126
+ defaultLocaleCode: props.locales.default,
169
127
  getEntryURL: props.getEntryURL
170
128
  })));
171
129
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"field-editor-validation-errors.esm.js","sources":["../src/styles.ts","../src/ValidationErrors.tsx"],"sourcesContent":["import { css } from 'emotion';\nimport tokens from '@contentful/f36-tokens';\n\nexport const errorList = css({\n padding: 0,\n wordWrap: 'break-word',\n marginTop: tokens.spacingS,\n color: tokens.red500,\n listStyleType: 'none',\n});\n\nexport const errorMessage = css({\n display: 'inline-flex',\n flexDirection: 'column',\n marginLeft: tokens.spacingXs,\n});\n\nexport const errorItem = css({\n display: 'flex',\n alignItems: 'center',\n});\n\nexport const entryLink = css({\n fontWeight: Number(tokens.fontWeightDemiBold),\n});\n","import React from 'react';\nimport { ValidationError, Link } from '@contentful/app-sdk';\nimport type {\n SpaceAPI,\n Entry,\n ContentType,\n FieldAPI,\n LocalesAPI,\n} from '@contentful/field-editor-shared';\nimport { entityHelpers } from '@contentful/field-editor-shared';\n\nimport * as styles from './styles';\n\nimport { TextLink, List, ListItem } from '@contentful/f36-components';\n\nimport { ExternalLinkIcon, InfoCircleIcon } from '@contentful/f36-icons';\n\ntype UniquenessErrorProps = {\n error: ValidationError;\n space: SpaceAPI;\n localeCode: string;\n defaultLocaleCode: string;\n getEntryURL: (entry: Entry) => string;\n};\n\nfunction UniquenessError(props: UniquenessErrorProps) {\n const [state, setState] = React.useState<{\n loading: boolean;\n entries: { id: string; title: string; href: string }[];\n }>({\n loading: true,\n entries: [],\n });\n\n const contentTypesById = React.useMemo(\n (): Record<string, ContentType> =>\n // Maps ID => Content Type\n props.space.getCachedContentTypes().reduce(\n (prev, ct) => ({\n ...prev,\n [ct.sys.id]: ct,\n }),\n {}\n ),\n [props.space]\n );\n\n const getTitle = React.useCallback(\n (entry: Entry) =>\n entityHelpers.getEntryTitle({\n entry,\n defaultTitle: 'Untitled',\n localeCode: props.localeCode,\n defaultLocaleCode: props.defaultLocaleCode,\n contentType: contentTypesById[entry.sys.contentType.sys.id],\n }),\n [props.localeCode, props.defaultLocaleCode, contentTypesById]\n );\n\n let conflicting: Link<'Entry', 'Link'>[] = [];\n if ('conflicting' in props.error) {\n conflicting = props.error.conflicting;\n }\n React.useEffect(() => {\n const entryIds = state.entries.map((entry) => entry.id);\n const conflictIds = conflicting.map((entry) => entry.sys.id);\n\n // Avoid unnecessary refetching\n if (conflictIds.every((id) => entryIds.includes(id))) {\n return;\n }\n\n setState((state) => ({ ...state, loading: true }));\n\n const query = {\n 'sys.id[in]': conflictIds.join(','),\n };\n\n props.space.getEntries<Entry>(query).then(({ items }) => {\n const entries = items.map((entry) => ({\n id: entry.sys.id,\n title: getTitle(entry),\n href: props.getEntryURL(entry),\n }));\n\n setState({\n loading: false,\n entries,\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies\n }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);\n\n return (\n <List className={styles.errorList} testId=\"validation-errors-uniqueness\">\n <ListItem className={styles.entryLink}>\n {state.loading ? (\n <div>Loading title for conflicting entry…</div>\n ) : (\n state.entries.map((entry) => (\n <TextLink\n key={entry.id}\n href={entry.href}\n icon={<ExternalLinkIcon />}\n alignIcon=\"end\"\n variant=\"negative\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n {entry.title}\n </TextLink>\n ))\n )}\n </ListItem>\n </List>\n );\n}\n\nexport interface ValidationErrorsProps {\n field: FieldAPI;\n space: SpaceAPI;\n locales: LocalesAPI;\n getEntryURL: (entry: Entry) => string;\n}\n\nexport function ValidationErrors(props: ValidationErrorsProps) {\n const [errors, setErrors] = React.useState<ValidationError[]>([]);\n\n React.useEffect(() => {\n const onErrors = (errors?: ValidationError[]) => {\n setErrors(errors || []);\n };\n\n return props.field.onSchemaErrorsChanged(onErrors);\n }, [props.field]);\n\n if (errors.length === 0) {\n return null;\n }\n\n return (\n <List className={styles.errorList} testId=\"validation-errors\">\n {errors.map((error, index) => {\n return (\n <li\n key={index}\n role=\"status\"\n aria-roledescription=\"field-locale-schema\"\n data-error-code={`entry.schema.${error.name}`}\n className={styles.errorItem}>\n <InfoCircleIcon variant=\"negative\" />\n <div className={styles.errorMessage}>\n {error.message}\n {error.name === 'unique' && (\n <UniquenessError\n error={error}\n space={props.space}\n localeCode={props.field.locale}\n defaultLocaleCode={props.locales.default}\n getEntryURL={props.getEntryURL}\n />\n )}\n </div>\n </li>\n );\n })}\n </List>\n );\n}\n"],"names":["errorList","css","padding","wordWrap","marginTop","tokens","spacingS","color","red500","listStyleType","errorMessage","display","flexDirection","marginLeft","spacingXs","errorItem","alignItems","entryLink","fontWeight","Number","fontWeightDemiBold","UniquenessError","props","React","useState","loading","entries","state","setState","contentTypesById","useMemo","space","getCachedContentTypes","reduce","prev","ct","sys","id","getTitle","useCallback","entry","entityHelpers","getEntryTitle","defaultTitle","localeCode","defaultLocaleCode","contentType","conflicting","error","useEffect","entryIds","map","conflictIds","every","includes","query","join","getEntries","then","items","title","href","getEntryURL","List","className","styles","testId","ListItem","TextLink","key","icon","ExternalLinkIcon","alignIcon","variant","target","rel","ValidationErrors","errors","setErrors","onErrors","field","onSchemaErrorsChanged","length","index","role","name","InfoCircleIcon","message","locale","locales"],"mappings":"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"}
1
+ {"version":3,"file":"field-editor-validation-errors.esm.js","sources":["../src/styles.ts","../src/ValidationErrors.tsx"],"sourcesContent":["import tokens from '@contentful/f36-tokens';\nimport { css } from 'emotion';\n\nexport const errorList = css({\n padding: 0,\n wordWrap: 'break-word',\n marginTop: tokens.spacingS,\n color: tokens.red500,\n listStyleType: 'none',\n});\n\nexport const errorMessage = css({\n display: 'inline-flex',\n flexDirection: 'column',\n marginLeft: tokens.spacingXs,\n});\n\nexport const errorItem = css({\n display: 'flex',\n alignItems: 'center',\n});\n\nexport const entryLink = css({\n fontWeight: Number(tokens.fontWeightDemiBold),\n});\n","import React from 'react';\n\nimport { ValidationError, Link } from '@contentful/app-sdk';\nimport { TextLink, List, ListItem } from '@contentful/f36-components';\nimport { ExternalLinkIcon, InfoCircleIcon } from '@contentful/f36-icons';\nimport type {\n SpaceAPI,\n Entry,\n ContentType,\n FieldAPI,\n LocalesAPI,\n} from '@contentful/field-editor-shared';\nimport { entityHelpers } from '@contentful/field-editor-shared';\n\nimport * as styles from './styles';\n\ntype UniquenessErrorProps = {\n error: ValidationError;\n space: SpaceAPI;\n localeCode: string;\n defaultLocaleCode: string;\n getEntryURL: (entry: Entry) => string;\n};\n\nfunction UniquenessError(props: UniquenessErrorProps) {\n const [state, setState] = React.useState<{\n loading: boolean;\n entries: { id: string; title: string; href: string }[];\n }>({\n loading: true,\n entries: [],\n });\n\n const contentTypesById = React.useMemo(\n (): Record<string, ContentType> =>\n // Maps ID => Content Type\n props.space.getCachedContentTypes().reduce(\n (prev, ct) => ({\n ...prev,\n [ct.sys.id]: ct,\n }),\n {}\n ),\n [props.space]\n );\n\n const getTitle = React.useCallback(\n (entry: Entry) =>\n entityHelpers.getEntryTitle({\n entry,\n defaultTitle: 'Untitled',\n localeCode: props.localeCode,\n defaultLocaleCode: props.defaultLocaleCode,\n contentType: contentTypesById[entry.sys.contentType.sys.id],\n }),\n [props.localeCode, props.defaultLocaleCode, contentTypesById]\n );\n\n let conflicting: Link<'Entry', 'Link'>[] = [];\n if ('conflicting' in props.error) {\n conflicting = props.error.conflicting;\n }\n React.useEffect(() => {\n const entryIds = state.entries.map((entry) => entry.id);\n const conflictIds = conflicting.map((entry) => entry.sys.id);\n\n // Avoid unnecessary refetching\n if (conflictIds.every((id) => entryIds.includes(id))) {\n return;\n }\n\n setState((state) => ({ ...state, loading: true }));\n\n const query = {\n 'sys.id[in]': conflictIds.join(','),\n };\n\n props.space.getEntries<Entry>(query).then(({ items }) => {\n const entries = items.map((entry) => ({\n id: entry.sys.id,\n title: getTitle(entry),\n href: props.getEntryURL(entry),\n }));\n\n setState({\n loading: false,\n entries,\n });\n });\n // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: Evaluate these dependencies\n }, [getTitle, state.entries, conflicting, props.space.getEntries, props.getEntryURL]);\n\n return (\n <List className={styles.errorList} testId=\"validation-errors-uniqueness\">\n <ListItem className={styles.entryLink}>\n {state.loading ? (\n <div>Loading title for conflicting entry…</div>\n ) : (\n state.entries.map((entry) => (\n <TextLink\n key={entry.id}\n href={entry.href}\n icon={<ExternalLinkIcon />}\n alignIcon=\"end\"\n variant=\"negative\"\n target=\"_blank\"\n rel=\"noopener noreferrer\">\n {entry.title}\n </TextLink>\n ))\n )}\n </ListItem>\n </List>\n );\n}\n\nexport interface ValidationErrorsProps {\n field: FieldAPI;\n space: SpaceAPI;\n locales: LocalesAPI;\n getEntryURL: (entry: Entry) => string;\n}\n\nexport function ValidationErrors(props: ValidationErrorsProps) {\n const [errors, setErrors] = React.useState<ValidationError[]>([]);\n\n React.useEffect(() => {\n const onErrors = (errors?: ValidationError[]) => {\n setErrors(errors || []);\n };\n\n return props.field.onSchemaErrorsChanged(onErrors);\n }, [props.field]);\n\n if (errors.length === 0) {\n return null;\n }\n\n return (\n <List className={styles.errorList} testId=\"validation-errors\">\n {errors.map((error, index) => {\n return (\n <li\n key={index}\n role=\"status\"\n aria-roledescription=\"field-locale-schema\"\n data-error-code={`entry.schema.${error.name}`}\n className={styles.errorItem}>\n <InfoCircleIcon variant=\"negative\" />\n <div className={styles.errorMessage}>\n {error.message}\n {error.name === 'unique' && (\n <UniquenessError\n error={error}\n space={props.space}\n localeCode={props.field.locale}\n defaultLocaleCode={props.locales.default}\n getEntryURL={props.getEntryURL}\n />\n )}\n </div>\n </li>\n );\n })}\n </List>\n );\n}\n"],"names":["errorList","css","padding","wordWrap","marginTop","tokens","spacingS","color","red500","listStyleType","errorMessage","display","flexDirection","marginLeft","spacingXs","errorItem","alignItems","entryLink","fontWeight","Number","fontWeightDemiBold","UniquenessError","props","state","setState","React","useState","loading","entries","contentTypesById","useMemo","space","getCachedContentTypes","reduce","prev","ct","sys","id","getTitle","useCallback","entry","entityHelpers","getEntryTitle","defaultTitle","localeCode","defaultLocaleCode","contentType","conflicting","error","useEffect","entryIds","map","conflictIds","every","includes","query","join","getEntries","then","items","title","href","getEntryURL","List","className","styles","testId","ListItem","TextLink","key","icon","ExternalLinkIcon","alignIcon","variant","target","rel","ValidationErrors","errors","setErrors","onErrors","field","onSchemaErrorsChanged","length","index","role","name","InfoCircleIcon","message","locale","locales","default"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/field-editor-validation-errors",
3
- "version": "1.1.10",
3
+ "version": "1.2.0",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/field-editor-validation-errors.esm.js",
6
6
  "typings": "dist/index.d.ts",
@@ -24,24 +24,14 @@
24
24
  "@contentful/f36-components": "^4.0.27",
25
25
  "@contentful/f36-icons": "^4.1.0",
26
26
  "@contentful/f36-tokens": "^4.0.0",
27
- "@contentful/field-editor-shared": "^1.1.7",
27
+ "@contentful/field-editor-shared": "^1.2.0",
28
28
  "emotion": "^10.0.17"
29
29
  },
30
30
  "devDependencies": {
31
- "@contentful/field-editor-test-utils": "^1.2.6"
31
+ "@contentful/field-editor-test-utils": "^1.3.0"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": ">=16.8.0"
35
35
  },
36
- "jest": {
37
- "testMatch": [
38
- "**/?(*.)+(spec|test).[jt]s?(x)"
39
- ],
40
- "globals": {
41
- "ts-jest": {
42
- "diagnostics": false
43
- }
44
- }
45
- },
46
- "gitHead": "1e4a7d92c48f0e1949f2b48b3c9974da1602fd5c"
36
+ "gitHead": "de7e74e3485dd69c240cfe9c545e6e50e41fb295"
47
37
  }