@contentful/react-apps-toolkit 0.6.0 → 1.0.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/README.md CHANGED
@@ -1,12 +1,8 @@
1
- # In development
2
-
3
- This library is still in development and should not be used in production.
4
-
5
1
  # React Toolkit for Contentful Apps
6
2
 
7
- This package consists of helpers and hooks to create a Contentful app with React.
3
+ React Hooks for the App Framework offer a simple way to bring frequently needed functionality into your react based [Contentful apps](/developers/docs/extensibility/app-framework/).
8
4
 
9
- This library can be used in apps created by [`create-contentful-app`](https://www.npmjs.com/package/create-contentful-app), but can also be used with any other React app using Contentful's [App SDK](https://www.npmjs.com/package/@contentful/app-sdk).
5
+ They can be used in apps created with [`create-contentful-app`](https://www.npmjs.com/package/@contentful/create-contentful-app), as well as any other React app using Contentful's [App SDK](https://www.npmjs.com/package/@contentful/app-sdk).
10
6
 
11
7
  ## Installation
12
8
 
@@ -20,52 +16,115 @@ yarn add @contentful/react-apps-toolkit
20
16
 
21
17
  The following hooks and utilities are exported from the package:
22
18
 
23
- ### `useSDK`
24
-
25
- This hook returns the App SDK.
19
+ ### SDKProvider
26
20
 
27
- The only requirement for using it is that the component that uses it is wrapped within the `SDKProvider`.
28
- If it is not, the hook will throw an error.
21
+ The `SDKProvider` is a wrapper component, which automatically makes the Contentful [App SDK](https://www.npmjs.com/package/@contentful/app-sdk) available to any child components using React Context. To use any of the hooks contained in this package, they must be wrapped in the `<SDKProvider>`, because all of the hooks depend on the App SDK.
29
22
 
30
- Here is an example of how you can use it:
23
+ Usage:
31
24
 
32
25
  ```tsx
33
- import { useSDK } from '@contentful/react-apps-toolkit'
26
+ import { SDKProvider, useSDK } from '@contentful/react-apps-toolkit';
34
27
 
35
- function App() {
28
+ function ChildComponentUsingHook() {
36
29
  const sdk = useSDK<FieldExtensionSDK>();
37
30
 
38
- return <>App Id: {sdk.ids.app}</>
31
+ return <>App Id: {sdk.ids.app}</>;
39
32
  }
40
33
 
34
+ function App() {
35
+ return (
36
+ <SDKProvider>
37
+ <ChildComponentUsingHook />
38
+ </SDKProvider>
39
+ );
40
+ }
41
41
  ```
42
42
 
43
- ### `useCMA`
43
+ ### useSDK
44
+
45
+ `useSDK` returns an instance of the Contentful [App SDK](https://www.npmjs.com/package/@contentful/app-sdk).
44
46
 
45
- Returns an initialized [plain client](https://github.com/contentful/contentful-management.js/#alternative-plain-api) for the Contentful Management API, which can immediately be used to communicate with the rest of your Contentful space. [Contentful Management API docs](https://www.contentful.com/developers/docs/references/content-management-api/).
47
+ It must be wrapped it within the `SDKProvider`, otherwise, it will throw an error.
46
48
 
49
+ Usage:
47
50
 
48
51
  ```tsx
49
- import { useCMA } from '@contentful/react-apps-toolkit'
52
+ import { SDKProvider, useSDK } from '@contentful/react-apps-toolkit';
53
+
54
+ function ComponentUsingSDK() {
55
+ const sdk = useSDK<FieldExtensionSDK>();
56
+
57
+ return <>App Id: {sdk.ids.app}</>;
58
+ }
50
59
 
51
60
  function App() {
61
+ return (
62
+ <SDKProvider>
63
+ <ChildComponentUsingSDK />
64
+ </SDKProvider>
65
+ );
66
+ }
67
+ ```
68
+
69
+ ### useCMA
70
+
71
+ `useCMA` returns an initialized [client for the Contentful Management API](https://www.npmjs.com/package/contentful-management). This can be used immediately to communicate with the environment the app is rendered in. [Contentful Management API docs](/developers/docs/references/content-management-api/).
72
+
73
+ **Note**: The CMA client instance returned by this hook is automatically scoped to the contentful space and environment in which it is called.
74
+
75
+ Usage:
76
+
77
+ ```tsx
78
+ import { SDKProvider, useCMA } from '@contentful/react-apps-toolkit';
79
+
80
+ function ComponentUsingCMA() {
52
81
  const cma = useCMA();
82
+ const [entries, setEntries] = useState();
53
83
 
54
84
  useEffect(() => {
55
- cma.entry.get({ entryId: '2VO9yOaeSyAFA19e649SxG' }).then((entry) => {
56
- console.log(entry);
57
- });
58
- }, []);
85
+ cma.entries.getMany().then(setEntries);
86
+ }, [cma]);
59
87
 
60
- return <>Hello world!</>
88
+ return <>{entries?.length}</>;
61
89
  }
62
90
 
91
+ function App() {
92
+ return (
93
+ <SDKProvider>
94
+ <ComponentUsingCMA />
95
+ </SDKProvider>
96
+ );
97
+ }
63
98
  ```
64
99
 
65
- #### SDKProvider
100
+ ### useFieldValue
101
+
102
+ `useFieldValue` provides the current value, and a setter function for updating the current value, of a given field in Contentful. If used in the [field location](/developers/docs/extensibility/app-framework/locations/#entry-field), it will initialize using the current field id by default.
103
+
104
+ If used in the [entry sidebar location](/developers/docs/extensibility/app-framework/locations/#entry-sidebar), or the [entry editor location](/developers/docs/extensibility/app-framework/locations/#entry-editor), it must be passed a field ID to initialize.
105
+
106
+ `useFieldValue` also optionally accepts a locale, if the field has multiple locales. If no locale is passed, it will use the environment's default locale.
107
+
108
+ Usage:
66
109
 
67
- Wrapper component, which makes the Apps SDK available to children via React Context. To use any of the hooks contained in this package, an application must be wrapped in the SDK provider, as all hooks depend on the Apps SDK.
110
+ ```tsx
111
+ import { SDKProvider, useFieldValue } from '@contentful/react-apps-toolkit';
112
+
113
+ function ComponentUsingFieldValue() {
114
+ const [value, setValue] = useFieldValue('slug', 'en-US');
115
+
116
+ return <input value={value} onChange={(e) => setValue(e.target.value)} />;
117
+ }
118
+
119
+ function App() {
120
+ return (
121
+ <SDKProvider>
122
+ <ComponentUsingFieldValue />
123
+ </SDKProvider>
124
+ );
125
+ }
126
+ ```
68
127
 
69
128
  ### Resources
70
129
 
71
- - [Create Contentful App](https://www.contentful.com/developers/docs/extensibility/app-framework/create-contentful-app/)
130
+ - [create-contentful-app](https://www.npmjs.com/package/create-contentful-app): A starter that makes it easy to bootstrap apps for Contentful.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/react-apps-toolkit",
3
- "version": "0.6.0",
3
+ "version": "1.0.0",
4
4
  "description": "Toolkit for building a Contentful app in React",
5
5
  "keywords": [],
6
6
  "author": "Contentful GmbH",
@@ -40,6 +40,7 @@
40
40
  "@types/react": "^17.0.39",
41
41
  "jest": "^27.5.0",
42
42
  "react": "^17.0.2",
43
+ "react-dom": "17.0.2",
43
44
  "ts-jest": "^27.1.3",
44
45
  "typescript": "^4.5.5"
45
46
  },
@@ -49,6 +50,5 @@
49
50
  "dependencies": {
50
51
  "@contentful/app-sdk": "^4.0.0",
51
52
  "contentful-management": ">=7.30.0"
52
- },
53
- "gitHead": "a279a7b92f12e6792e4c76d86a3277006143bff0"
53
+ }
54
54
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2020 Contentful
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,14 +0,0 @@
1
- import React, { FC, ReactElement } from 'react';
2
- import { KnownSDK } from '@contentful/app-sdk';
3
- export declare const SDKContext: React.Context<{
4
- sdk: KnownSDK | null;
5
- }>;
6
- interface SDKProviderProps {
7
- loading?: ReactElement;
8
- }
9
- /**
10
- * The Component providing the AppSdk, the useSDK hook can only be used within this Provider
11
- * @param props.loading an optional loading element that gets rendered while initializing the app
12
- */
13
- export declare const SDKProvider: FC<SDKProviderProps>;
14
- export {};
@@ -1,47 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.SDKProvider = exports.SDKContext = void 0;
18
- var jsx_runtime_1 = require("react/jsx-runtime");
19
- var react_1 = __importDefault(require("react"));
20
- var app_sdk_1 = require("@contentful/app-sdk");
21
- exports.SDKContext = react_1.default.createContext({ sdk: null });
22
- var DELAY_TIMEOUT = 4 * 1000;
23
- /**
24
- * The Component providing the AppSdk, the useSDK hook can only be used within this Provider
25
- * @param props.loading an optional loading element that gets rendered while initializing the app
26
- */
27
- var SDKProvider = function (props) {
28
- var _a = react_1.default.useState(), sdk = _a[0], setSDK = _a[1];
29
- react_1.default.useEffect(function () {
30
- var timeout = window.setTimeout(function () {
31
- console.warn("Your app is taking longer than expected to initialize. If you think this is an error with Contentful's App SDK, let us know: https://github.com/contentful/ui-extensions-sdk/issues");
32
- }, DELAY_TIMEOUT);
33
- (0, app_sdk_1.init)(function (sdk) {
34
- setSDK(sdk);
35
- window.clearTimeout(timeout);
36
- });
37
- return function () { return window.clearTimeout(timeout); };
38
- }, []);
39
- if (!sdk) {
40
- if (props.loading) {
41
- return props.loading;
42
- }
43
- return null;
44
- }
45
- return (0, jsx_runtime_1.jsx)(exports.SDKContext.Provider, __assign({ value: { sdk: sdk } }, { children: props.children }));
46
- };
47
- exports.SDKProvider = SDKProvider;
@@ -1 +0,0 @@
1
- export {};
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var jsx_runtime_1 = require("react/jsx-runtime");
4
- var react_1 = require("@testing-library/react");
5
- var SDKProvider_1 = require("./SDKProvider");
6
- var app_sdk_1 = require("@contentful/app-sdk");
7
- jest.useFakeTimers();
8
- jest.mock('@contentful/app-sdk', function () { return ({
9
- init: jest.fn(),
10
- }); });
11
- describe('SDKProvider', function () {
12
- var consoleWarnMock;
13
- beforeEach(function () {
14
- // @ts-ignore
15
- app_sdk_1.init.mockImplementation(function (callback) {
16
- callback({});
17
- });
18
- consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation();
19
- });
20
- afterEach(function () {
21
- consoleWarnMock === null || consoleWarnMock === void 0 ? void 0 : consoleWarnMock.mockRestore();
22
- });
23
- it('renders its children when sdk the init returns the sdk', function () {
24
- var getByText = (0, react_1.render)((0, jsx_runtime_1.jsx)(SDKProvider_1.SDKProvider, { children: (0, jsx_runtime_1.jsx)("div", { children: "children" }) })).getByText;
25
- expect(getByText('children')).toBeTruthy();
26
- });
27
- it('calls console warn after timeout if callback is not returning ', function () {
28
- // @ts-ignore
29
- app_sdk_1.init.mockImplementation(function () { });
30
- (0, react_1.render)((0, jsx_runtime_1.jsx)(SDKProvider_1.SDKProvider, { children: (0, jsx_runtime_1.jsx)("div", { children: "children" }) }));
31
- jest.runAllTimers();
32
- expect(consoleWarnMock).toHaveBeenCalled();
33
- });
34
- });
package/dist/index.d.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from './SDKProvider';
2
- export * from './useCMA';
3
- export * from './useFieldValue';
4
- export * from './useSDK';
package/dist/index.js DELETED
@@ -1,20 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./SDKProvider"), exports);
18
- __exportStar(require("./useCMA"), exports);
19
- __exportStar(require("./useFieldValue"), exports);
20
- __exportStar(require("./useSDK"), exports);
package/dist/useCMA.d.ts DELETED
@@ -1,6 +0,0 @@
1
- import { PlainClientAPI } from 'contentful-management';
2
- /**
3
- * React hook returning a CMA plain client instance.
4
- * Must be used in the `SDKProvider` component. Will throw error, if called outside of `SDKProvider`.
5
- */
6
- export declare function useCMA(): PlainClientAPI;
package/dist/useCMA.js DELETED
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useCMA = void 0;
4
- var contentful_management_1 = require("contentful-management");
5
- var react_1 = require("react");
6
- var useSDK_1 = require("./useSDK");
7
- /**
8
- * React hook returning a CMA plain client instance.
9
- * Must be used in the `SDKProvider` component. Will throw error, if called outside of `SDKProvider`.
10
- */
11
- function useCMA() {
12
- var sdk = (0, useSDK_1.useSDK)();
13
- var cma = (0, react_1.useMemo)(function () {
14
- var _a;
15
- return (0, contentful_management_1.createClient)({ apiAdapter: sdk.cmaAdapter }, {
16
- type: 'plain',
17
- defaults: {
18
- environmentId: (_a = sdk.ids.environmentAlias) !== null && _a !== void 0 ? _a : sdk.ids.environment,
19
- spaceId: sdk.ids.space,
20
- },
21
- });
22
- }, [sdk]);
23
- return cma;
24
- }
25
- exports.useCMA = useCMA;
@@ -1 +0,0 @@
1
- export {};
@@ -1,36 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- var react_hooks_1 = require("@testing-library/react-hooks");
15
- var useCMA_1 = require("./useCMA");
16
- var mockedCma = 'mocked-cma';
17
- var mockedSdk = {
18
- cmaAdapter: 'placholder',
19
- ids: {
20
- environment: 'placeholder',
21
- space: 'placeholder',
22
- },
23
- };
24
- jest.mock('./useSDK', function () { return (__assign(__assign({}, jest.requireActual('./useSDK')), { useSDK: function () { return mockedSdk; } })); });
25
- jest.mock('./SDKProvider', function () { return ({
26
- SDKContext: {},
27
- }); });
28
- jest.mock('contentful-management', function () {
29
- return __assign(__assign({}, jest.requireActual('contentful-management')), { createClient: function () { return mockedCma; } });
30
- });
31
- describe('useCMA', function () {
32
- test('should return cma client', function () {
33
- var result = (0, react_hooks_1.renderHook)(function () { return (0, useCMA_1.useCMA)(); }).result;
34
- expect(result.current).toBe(mockedCma);
35
- });
36
- });
@@ -1,15 +0,0 @@
1
- import { SerializedJSONValue } from '@contentful/app-sdk';
2
- export declare type UseFieldValueReturnValue<Value = unknown> = [
3
- value: Value | undefined,
4
- setValue: (newValue: Value | undefined) => Promise<SerializedJSONValue | undefined>
5
- ];
6
- /**
7
- * Returns field value and a function to update it.
8
- * Must be wrapped by SDKProvider.
9
- * Can only be used when app is rendered in field, sidebar or entry editor location.
10
- *
11
- * @param {string=} fieldId Id of the field to read and update. Can be omitted when app is rendered in field location.
12
- * @param {string=} locale Locale to read and update. When omitted, default locale is used.
13
- * @returns {UseFieldValueReturnValue} Field value, function to update it
14
- */
15
- export declare function useFieldValue<Value = unknown>(fieldId?: string, locale?: string): UseFieldValueReturnValue<Value>;
@@ -1,84 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (_) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.useFieldValue = void 0;
40
- var react_1 = require("react");
41
- var useSDK_1 = require("./useSDK");
42
- /**
43
- * Returns field value and a function to update it.
44
- * Must be wrapped by SDKProvider.
45
- * Can only be used when app is rendered in field, sidebar or entry editor location.
46
- *
47
- * @param {string=} fieldId Id of the field to read and update. Can be omitted when app is rendered in field location.
48
- * @param {string=} locale Locale to read and update. When omitted, default locale is used.
49
- * @returns {UseFieldValueReturnValue} Field value, function to update it
50
- */
51
- function useFieldValue(fieldId, locale) {
52
- var _this = this;
53
- var sdk = (0, useSDK_1.useSDK)();
54
- var entryFieldApi = (0, react_1.useMemo)(function () { return getEntryFieldApi(sdk, fieldId); }, [sdk, fieldId]);
55
- var localeWithDefault = locale !== null && locale !== void 0 ? locale : sdk.locales.default;
56
- var _a = (0, react_1.useState)(entryFieldApi.getValue(localeWithDefault)), value = _a[0], setValue = _a[1];
57
- (0, react_1.useEffect)(function () { return entryFieldApi.onValueChanged(localeWithDefault, setValue); }, [entryFieldApi, localeWithDefault]);
58
- var updateValue = (0, react_1.useCallback)(function (newValue) { return __awaiter(_this, void 0, void 0, function () {
59
- return __generator(this, function (_a) {
60
- switch (_a.label) {
61
- case 0:
62
- setValue(newValue);
63
- return [4 /*yield*/, entryFieldApi.setValue(newValue, localeWithDefault)];
64
- case 1: return [2 /*return*/, _a.sent()];
65
- }
66
- });
67
- }); }, [entryFieldApi, localeWithDefault]);
68
- return [value, updateValue];
69
- }
70
- exports.useFieldValue = useFieldValue;
71
- function getEntryFieldApi(sdk, fieldId) {
72
- if (!('entry' in sdk)) {
73
- throw new Error('`useFieldValue` can only be used in field, sidebar or entry editor location.');
74
- }
75
- var fieldIdWithDefault = fieldId !== null && fieldId !== void 0 ? fieldId : ('field' in sdk ? sdk.field.id : undefined);
76
- if (!fieldIdWithDefault) {
77
- throw new Error('Missing `fieldId`. The `fieldId` can only be omitted when your app is renderd in field location.');
78
- }
79
- var field = sdk.entry.fields[fieldIdWithDefault];
80
- if (!field) {
81
- throw new Error("Invalid `fieldId`. The current entry does not have a field \"".concat(fieldIdWithDefault, "\"."));
82
- }
83
- return field;
84
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,249 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (_) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- Object.defineProperty(exports, "__esModule", { value: true });
50
- var react_hooks_1 = require("@testing-library/react-hooks");
51
- var useFieldValue_1 = require("./useFieldValue");
52
- var useSDK_1 = require("./useSDK");
53
- var mockSDK = {
54
- field: {
55
- id: 'fieldId',
56
- },
57
- locales: {
58
- default: 'defaultLocale',
59
- },
60
- entry: {
61
- fields: {
62
- fieldId: {
63
- getValue: function (locale) { return "fieldId ".concat(locale, " value"); },
64
- onValueChanged: jest.fn(),
65
- setValue: jest.fn(),
66
- },
67
- otherFieldId: {
68
- getValue: function (locale) { return "otherFieldId ".concat(locale, " value"); },
69
- onValueChanged: jest.fn(),
70
- setValue: jest.fn(),
71
- },
72
- },
73
- },
74
- };
75
- jest.mock('./useSDK', function () { return (__assign(__assign({}, jest.requireActual('./useSDK')), { useSDK: jest.fn() })); });
76
- var useSDKMock = useSDK_1.useSDK;
77
- beforeEach(function () {
78
- jest.resetAllMocks();
79
- mockSDK.entry.fields.fieldId.onValueChanged.mockImplementation(function () { return function () { }; });
80
- mockSDK.entry.fields.fieldId.setValue.mockImplementation(function () { return Promise.resolve('return value'); });
81
- mockSDK.entry.fields.otherFieldId.onValueChanged.mockImplementation(function () { return function () { }; });
82
- mockSDK.entry.fields.otherFieldId.setValue.mockImplementation(function () {
83
- return Promise.resolve('other return value');
84
- });
85
- });
86
- describe('useFieldValue', function () {
87
- describe('throws error', function () {
88
- it('when rendered in wrong location', function () {
89
- useSDKMock.mockImplementation(function () { return ({}); });
90
- var result = (0, react_hooks_1.renderHook)(function () { return (0, useFieldValue_1.useFieldValue)(); }).result;
91
- expect(function () {
92
- expect(result.current).not.toBe(undefined);
93
- }).toThrowErrorMatchingInlineSnapshot("\"`useFieldValue` can only be used in field, sidebar or entry editor location.\"");
94
- });
95
- it('when rendered omitting `fieldId` outside of field location', function () {
96
- // @ts-expect-error
97
- useSDKMock.mockImplementation(function () { return ({
98
- entry: mockSDK.entry,
99
- }); });
100
- var result = (0, react_hooks_1.renderHook)(function () { return (0, useFieldValue_1.useFieldValue)(); }).result;
101
- expect(function () {
102
- expect(result.current).not.toBe(undefined);
103
- }).toThrowErrorMatchingInlineSnapshot("\"Missing `fieldId`. The `fieldId` can only be omitted when your app is renderd in field location.\"");
104
- });
105
- it('when providing unknown `fieldId`', function () {
106
- // @ts-expect-error
107
- useSDKMock.mockImplementation(function () { return mockSDK; });
108
- var result = (0, react_hooks_1.renderHook)(function () { return (0, useFieldValue_1.useFieldValue)('unknownFieldId'); }).result;
109
- expect(function () {
110
- expect(result.current).not.toBe(undefined);
111
- }).toThrowErrorMatchingInlineSnapshot("\"Invalid `fieldId`. The current entry does not have a field \\\"unknownFieldId\\\".\"");
112
- });
113
- });
114
- describe('with no params', function () {
115
- var result;
116
- beforeEach(function () {
117
- // @ts-expect-error
118
- useSDKMock.mockImplementation(function () { return mockSDK; });
119
- result = (0, react_hooks_1.renderHook)(function () { return (0, useFieldValue_1.useFieldValue)(); }).result;
120
- });
121
- it('returns initial value', function () {
122
- expect(result.current[0]).toBe('fieldId defaultLocale value');
123
- });
124
- it('updates value', function () { return __awaiter(void 0, void 0, void 0, function () {
125
- return __generator(this, function (_a) {
126
- switch (_a.label) {
127
- case 0: return [4 /*yield*/, (0, react_hooks_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
128
- return __generator(this, function (_a) {
129
- switch (_a.label) {
130
- case 0: return [4 /*yield*/, result.current[1]('new value')];
131
- case 1:
132
- _a.sent();
133
- return [2 /*return*/];
134
- }
135
- });
136
- }); })];
137
- case 1:
138
- _a.sent();
139
- expect(result.current[0]).toBe('new value');
140
- expect(mockSDK.entry.fields['fieldId'].setValue).toHaveBeenCalledWith('new value', 'defaultLocale');
141
- return [2 /*return*/];
142
- }
143
- });
144
- }); });
145
- it('updates value when `onValueChanged` is called', function () {
146
- var calls = mockSDK.entry.fields.fieldId.onValueChanged.mock.calls;
147
- expect(calls[0][0]).toBe('defaultLocale');
148
- (0, react_hooks_1.act)(function () { return calls[0][1]('new value'); });
149
- expect(result.current[0]).toBe('new value');
150
- });
151
- it('returns the updated value', function () { return __awaiter(void 0, void 0, void 0, function () {
152
- var returnedValue;
153
- return __generator(this, function (_a) {
154
- switch (_a.label) {
155
- case 0: return [4 /*yield*/, (0, react_hooks_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
156
- return __generator(this, function (_a) {
157
- switch (_a.label) {
158
- case 0: return [4 /*yield*/, result.current[1]('new value')];
159
- case 1:
160
- returnedValue = _a.sent();
161
- return [2 /*return*/];
162
- }
163
- });
164
- }); })];
165
- case 1:
166
- _a.sent();
167
- expect(returnedValue).toBe('return value');
168
- return [2 /*return*/];
169
- }
170
- });
171
- }); });
172
- });
173
- describe('with `fieldId`', function () {
174
- var result;
175
- beforeEach(function () {
176
- // @ts-expect-error
177
- useSDKMock.mockImplementation(function () { return mockSDK; });
178
- result = (0, react_hooks_1.renderHook)(function () { return (0, useFieldValue_1.useFieldValue)('otherFieldId'); }).result;
179
- });
180
- it('returns initial value', function () {
181
- expect(result.current[0]).toBe('otherFieldId defaultLocale value');
182
- });
183
- it('updates value', function () { return __awaiter(void 0, void 0, void 0, function () {
184
- return __generator(this, function (_a) {
185
- switch (_a.label) {
186
- case 0: return [4 /*yield*/, (0, react_hooks_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
187
- return __generator(this, function (_a) {
188
- switch (_a.label) {
189
- case 0: return [4 /*yield*/, result.current[1]('new value')];
190
- case 1:
191
- _a.sent();
192
- return [2 /*return*/];
193
- }
194
- });
195
- }); })];
196
- case 1:
197
- _a.sent();
198
- expect(result.current[0]).toBe('new value');
199
- expect(mockSDK.entry.fields['otherFieldId'].setValue).toHaveBeenCalledWith('new value', 'defaultLocale');
200
- return [2 /*return*/];
201
- }
202
- });
203
- }); });
204
- it('updates value when `onValueChanged` is called', function () {
205
- var calls = mockSDK.entry.fields.otherFieldId.onValueChanged.mock.calls;
206
- expect(calls[0][0]).toBe('defaultLocale');
207
- (0, react_hooks_1.act)(function () { return calls[0][1]('new value'); });
208
- expect(result.current[0]).toBe('new value');
209
- });
210
- });
211
- describe('with `locale`', function () {
212
- var result;
213
- beforeEach(function () {
214
- // @ts-expect-error
215
- useSDKMock.mockImplementation(function () { return mockSDK; });
216
- result = (0, react_hooks_1.renderHook)(function () { return (0, useFieldValue_1.useFieldValue)('fieldId', 'locale'); }).result;
217
- });
218
- it('returns initial value', function () {
219
- expect(result.current[0]).toBe('fieldId locale value');
220
- });
221
- it('updates value', function () { return __awaiter(void 0, void 0, void 0, function () {
222
- return __generator(this, function (_a) {
223
- switch (_a.label) {
224
- case 0: return [4 /*yield*/, (0, react_hooks_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
225
- return __generator(this, function (_a) {
226
- switch (_a.label) {
227
- case 0: return [4 /*yield*/, result.current[1]('new value')];
228
- case 1:
229
- _a.sent();
230
- return [2 /*return*/];
231
- }
232
- });
233
- }); })];
234
- case 1:
235
- _a.sent();
236
- expect(result.current[0]).toBe('new value');
237
- expect(mockSDK.entry.fields['fieldId'].setValue).toHaveBeenCalledWith('new value', 'locale');
238
- return [2 /*return*/];
239
- }
240
- });
241
- }); });
242
- it('updates value when `onValueChanged` is called', function () {
243
- var calls = mockSDK.entry.fields.fieldId.onValueChanged.mock.calls;
244
- expect(calls[0][0]).toBe('locale');
245
- (0, react_hooks_1.act)(function () { return calls[0][1]('new value'); });
246
- expect(result.current[0]).toBe('new value');
247
- });
248
- });
249
- });
package/dist/useSDK.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import { KnownSDK } from '@contentful/app-sdk';
2
- /**
3
- * A react hook returning the App SDK.
4
- * - The type of SDK varies depending on the location where it is used.
5
- * - As it is depending on the context providing the SDK, the hook can only be used within the SDKProvider
6
- */
7
- export declare function useSDK<SDK extends KnownSDK = KnownSDK>(): SDK;
package/dist/useSDK.js DELETED
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useSDK = void 0;
4
- var react_1 = require("react");
5
- var SDKProvider_1 = require("./SDKProvider");
6
- /**
7
- * A react hook returning the App SDK.
8
- * - The type of SDK varies depending on the location where it is used.
9
- * - As it is depending on the context providing the SDK, the hook can only be used within the SDKProvider
10
- */
11
- function useSDK() {
12
- var sdk = (0, react_1.useContext)(SDKProvider_1.SDKContext).sdk;
13
- if (!sdk) {
14
- throw new Error('SDKContext not found. Make sure this hook is used inside the SDKProvider');
15
- }
16
- return sdk;
17
- }
18
- exports.useSDK = useSDK;
@@ -1 +0,0 @@
1
- export {};
@@ -1,35 +0,0 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- var react_hooks_1 = require("@testing-library/react-hooks");
15
- var index_1 = require("./index");
16
- var mockedSdk = 'mocked-sdk';
17
- jest.mock('react', function () {
18
- return __assign(__assign({}, jest.requireActual('react')), { useContext: function () { return ({ sdk: mockedSdk }); } });
19
- });
20
- jest.mock('./SDKProvider', function () { return ({
21
- SDKContext: {},
22
- }); });
23
- describe('useSDK', function () {
24
- test('should return the sdk from the context', function () {
25
- var result = (0, react_hooks_1.renderHook)(function () { return (0, index_1.useSDK)(); }).result;
26
- expect(result.current).toBe('mocked-sdk');
27
- });
28
- test('should throw when the sdk is not in context', function () {
29
- mockedSdk = undefined;
30
- var result = (0, react_hooks_1.renderHook)(function () { return (0, index_1.useSDK)(); }).result;
31
- expect(function () {
32
- expect(result.current).not.toBe(undefined);
33
- }).toThrow();
34
- });
35
- });