@contentful/app-sdk 5.0.0-alpha.1 → 5.0.0-alpha.2
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 +1 -7
- package/dist/api.js +109 -0
- package/dist/app.js +99 -0
- package/dist/channel.js +111 -0
- package/dist/cma.js +16 -0
- package/dist/cmaAdapter.js +12 -0
- package/dist/dialogs.js +37 -0
- package/dist/editor.js +29 -0
- package/dist/entry.js +60 -0
- package/dist/field-locale.js +70 -0
- package/dist/field.js +77 -0
- package/dist/index.js +23 -0
- package/dist/initialize.js +64 -0
- package/dist/locations.js +13 -0
- package/dist/navigator.js +62 -0
- package/dist/signal.js +51 -0
- package/dist/types/api.types.d.ts +0 -8
- package/dist/types/api.types.js +2 -0
- package/dist/types/app.types.d.ts +0 -4
- package/dist/types/app.types.js +2 -0
- package/dist/types/cmaClient.types.js +2 -0
- package/dist/types/dialogs.types.js +2 -0
- package/dist/types/entities.js +2 -0
- package/dist/types/entry.types.d.ts +0 -5
- package/dist/types/entry.types.js +2 -0
- package/dist/types/field-locale.types.js +2 -0
- package/dist/types/field.types.js +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/navigator.types.d.ts +12 -2
- package/dist/types/navigator.types.js +2 -0
- package/dist/types/utils.js +2 -0
- package/dist/types/validation-error.js +2 -0
- package/dist/types/window.types.js +2 -0
- package/dist/utils/deferred.js +20 -0
- package/dist/window.js +106 -0
- package/package.json +118 -1
- package/dist/README.md +0 -9
- package/dist/cf-extension-api.bundled.js +0 -1
- package/dist/cf-extension-api.js +0 -1
- package/dist/cf-extension.css +0 -600
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ for the Contentful Web App. Every Contentful App has to include the library in i
|
|
|
16
16
|
- [Forma 36: The Contentful Design System](https://f36.contentful.com/)
|
|
17
17
|
- [Forma 36 guide for Contentful Apps](https://www.contentful.com/developers/docs/extensibility/ui-extensions/component-library/)
|
|
18
18
|
- [`create-contentful-app`](https://github.com/contentful/create-contentful-app) - CLI tool for developing apps without the hassle of managing build configurations
|
|
19
|
-
- [
|
|
19
|
+
- [`@contentful/app-sdk` at npm](https://www.npmjs.com/package/@contentful/app-sdk)
|
|
20
20
|
|
|
21
21
|
## Getting help
|
|
22
22
|
|
|
@@ -31,8 +31,6 @@ information needs to be discussed, then the conversation should be handled via o
|
|
|
31
31
|
|
|
32
32
|
A new package version is automatically published to npm using [semantic-release](https://github.com/semantic-release/semantic-release).
|
|
33
33
|
|
|
34
|
-
To manually publish the package, run `npm run publish-all`.
|
|
35
|
-
|
|
36
34
|
This repository is published as `@contentful/app-sdk` package.
|
|
37
35
|
|
|
38
36
|
#### Canary releases
|
|
@@ -71,10 +69,6 @@ All the typings are in the [`types`](./lib/types) folder and they map 1-to-1 API
|
|
|
71
69
|
The [`entities`](./lib/types/entities.ts) file maps Contentful entities in TypeScript.
|
|
72
70
|
[`utils`](./lib/types/utils.ts) includes utility types, meant to save on characters to type.
|
|
73
71
|
|
|
74
|
-
#### `scripts`
|
|
75
|
-
|
|
76
|
-
Includes utility tools for maintainers.
|
|
77
|
-
|
|
78
72
|
#### `test`
|
|
79
73
|
|
|
80
74
|
Includes unit tests (run by [mocha](https://mochajs.org/))
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const field_1 = require("./field");
|
|
4
|
+
const field_locale_1 = require("./field-locale");
|
|
5
|
+
const window_1 = require("./window");
|
|
6
|
+
const entry_1 = require("./entry");
|
|
7
|
+
const dialogs_1 = require("./dialogs");
|
|
8
|
+
const editor_1 = require("./editor");
|
|
9
|
+
const navigator_1 = require("./navigator");
|
|
10
|
+
const app_1 = require("./app");
|
|
11
|
+
const locations_1 = require("./locations");
|
|
12
|
+
const cmaAdapter_1 = require("./cmaAdapter");
|
|
13
|
+
const cma_1 = require("./cma");
|
|
14
|
+
const DEFAULT_API_PRODUCERS = [
|
|
15
|
+
makeSharedAPI,
|
|
16
|
+
makeEntryAPI,
|
|
17
|
+
makeFieldAPI,
|
|
18
|
+
makeEditorAPI,
|
|
19
|
+
makeWindowAPI,
|
|
20
|
+
];
|
|
21
|
+
const LOCATION_TO_API_PRODUCERS = {
|
|
22
|
+
[locations_1.default.LOCATION_ENTRY_FIELD]: DEFAULT_API_PRODUCERS,
|
|
23
|
+
[locations_1.default.LOCATION_ENTRY_FIELD_SIDEBAR]: DEFAULT_API_PRODUCERS,
|
|
24
|
+
[locations_1.default.LOCATION_ENTRY_SIDEBAR]: [makeSharedAPI, makeEntryAPI, makeEditorAPI, makeWindowAPI],
|
|
25
|
+
[locations_1.default.LOCATION_ENTRY_EDITOR]: [makeSharedAPI, makeEntryAPI, makeEditorAPI],
|
|
26
|
+
[locations_1.default.LOCATION_DIALOG]: [makeSharedAPI, makeDialogAPI, makeWindowAPI],
|
|
27
|
+
[locations_1.default.LOCATION_PAGE]: [makeSharedAPI],
|
|
28
|
+
[locations_1.default.LOCATION_HOME]: [makeSharedAPI],
|
|
29
|
+
[locations_1.default.LOCATION_APP_CONFIG]: [makeSharedAPI, makeAppAPI],
|
|
30
|
+
};
|
|
31
|
+
function createAPI(channel, data, currentGlobal) {
|
|
32
|
+
const producers = LOCATION_TO_API_PRODUCERS[data.location] || DEFAULT_API_PRODUCERS;
|
|
33
|
+
return producers.reduce((api, produce) => {
|
|
34
|
+
return { ...api, ...produce(channel, data, currentGlobal) };
|
|
35
|
+
}, {});
|
|
36
|
+
}
|
|
37
|
+
exports.default = createAPI;
|
|
38
|
+
function makeSharedAPI(channel, data) {
|
|
39
|
+
const { user, parameters, locales, ids } = data;
|
|
40
|
+
const currentLocation = data.location || locations_1.default.LOCATION_ENTRY_FIELD;
|
|
41
|
+
return {
|
|
42
|
+
cma: (0, cma_1.createCMAClient)(ids, channel),
|
|
43
|
+
cmaAdapter: (0, cmaAdapter_1.createAdapter)(channel),
|
|
44
|
+
location: {
|
|
45
|
+
current: currentLocation,
|
|
46
|
+
is: (tested) => currentLocation === tested,
|
|
47
|
+
},
|
|
48
|
+
user,
|
|
49
|
+
parameters,
|
|
50
|
+
locales: {
|
|
51
|
+
available: locales.available,
|
|
52
|
+
default: locales.default,
|
|
53
|
+
names: locales.names,
|
|
54
|
+
fallbacks: locales.fallbacks,
|
|
55
|
+
optional: locales.optional,
|
|
56
|
+
direction: locales.direction,
|
|
57
|
+
},
|
|
58
|
+
dialogs: (0, dialogs_1.default)(channel, ids),
|
|
59
|
+
// Typecast because promises returned by navigator methods aren't typed
|
|
60
|
+
navigator: (0, navigator_1.default)(channel, ids),
|
|
61
|
+
notifier: {
|
|
62
|
+
success: (message) => channel.send('notify', { type: 'success', message }),
|
|
63
|
+
error: (message) => channel.send('notify', { type: 'error', message }),
|
|
64
|
+
warning: (message) => channel.send('notify', { type: 'warning', message }),
|
|
65
|
+
},
|
|
66
|
+
ids,
|
|
67
|
+
access: {
|
|
68
|
+
can: (action, entity, patch) => channel.call('checkAccess', action, entity, patch),
|
|
69
|
+
canEditAppConfig: () => channel.call('checkAppConfigAccess'),
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function makeWindowAPI(channel, _data, currentGlobal) {
|
|
74
|
+
return {
|
|
75
|
+
window: (0, window_1.default)(currentGlobal, channel),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function makeEditorAPI(channel, data) {
|
|
79
|
+
const { editorInterface, editor } = data;
|
|
80
|
+
return {
|
|
81
|
+
editor: (0, editor_1.default)(channel, editorInterface, editor),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function makeEntryAPI(channel, { locales, contentType, entry, fieldInfo }) {
|
|
85
|
+
const createEntryField = (info) => new field_1.default(channel, info, locales.default);
|
|
86
|
+
return {
|
|
87
|
+
contentType,
|
|
88
|
+
entry: (0, entry_1.default)(channel, entry, fieldInfo, createEntryField),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function makeFieldAPI(channel, { field }) {
|
|
92
|
+
if (!field) {
|
|
93
|
+
throw new Error('FieldAPI called for location without "field" property defined.');
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
field: new field_locale_1.default(channel, field),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function makeDialogAPI(channel) {
|
|
100
|
+
return {
|
|
101
|
+
close: (data) => channel.send('closeDialog', data),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function makeAppAPI(channel) {
|
|
105
|
+
const app = (0, app_1.default)(channel);
|
|
106
|
+
return {
|
|
107
|
+
app,
|
|
108
|
+
};
|
|
109
|
+
}
|
package/dist/app.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const HOOK_STAGE_PRE_INSTALL = 'preInstall';
|
|
4
|
+
const HOOK_STAGE_POST_INSTALL = 'postInstall';
|
|
5
|
+
const isObject = (o) => typeof o === 'object' && o !== null && !Array.isArray(o);
|
|
6
|
+
const isFunction = (f) => typeof f === 'function';
|
|
7
|
+
const isPromise = (p) => isObject(p) && isFunction(p.then);
|
|
8
|
+
const handleHandlerError = (err) => {
|
|
9
|
+
console.error(err);
|
|
10
|
+
return Promise.resolve(false);
|
|
11
|
+
};
|
|
12
|
+
const runHandler = (handler, defaultResult, handlerArg) => {
|
|
13
|
+
// Handler was not registered. Registering a handler is not
|
|
14
|
+
// required. We resolve with the default provided in this case.
|
|
15
|
+
if (!isFunction(handler)) {
|
|
16
|
+
return Promise.resolve(defaultResult);
|
|
17
|
+
}
|
|
18
|
+
// If handler is synchronous it can throw and we need to
|
|
19
|
+
// catch it. We resolve with `false` in this case.
|
|
20
|
+
let maybeResultPromise;
|
|
21
|
+
try {
|
|
22
|
+
maybeResultPromise = typeof handlerArg === 'undefined' ? handler() : handler(handlerArg);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
return handleHandlerError(err);
|
|
26
|
+
}
|
|
27
|
+
// If handler is synchronous, we wrap the result with a promise
|
|
28
|
+
// and deal only with Promises API below.
|
|
29
|
+
let resultPromise = maybeResultPromise;
|
|
30
|
+
if (!isPromise(resultPromise)) {
|
|
31
|
+
resultPromise = Promise.resolve(resultPromise);
|
|
32
|
+
}
|
|
33
|
+
return resultPromise
|
|
34
|
+
.then((result) => {
|
|
35
|
+
if (result instanceof Error) {
|
|
36
|
+
return Promise.reject(result);
|
|
37
|
+
}
|
|
38
|
+
else if (result === false) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
else if (!isObject(result)) {
|
|
42
|
+
return defaultResult;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
}, handleHandlerError)
|
|
48
|
+
.catch(handleHandlerError);
|
|
49
|
+
};
|
|
50
|
+
function createApp(channel) {
|
|
51
|
+
const handlers = {
|
|
52
|
+
[HOOK_STAGE_PRE_INSTALL]: null,
|
|
53
|
+
[HOOK_STAGE_POST_INSTALL]: null,
|
|
54
|
+
};
|
|
55
|
+
const setHandler = (stage, handler) => {
|
|
56
|
+
if (!isFunction(handler)) {
|
|
57
|
+
throw new Error('Handler must be a function.');
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
handlers[stage] = handler;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
channel.addHandler('appHook', ({ stage, installationRequestId, err, }) => {
|
|
64
|
+
if (stage === HOOK_STAGE_PRE_INSTALL) {
|
|
65
|
+
return runHandler(handlers[stage], {}).then((result) => {
|
|
66
|
+
return channel.send('appHookResult', { stage, installationRequestId, result });
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (stage === HOOK_STAGE_POST_INSTALL) {
|
|
70
|
+
return runHandler(handlers[stage], undefined, err || null).then(() => {
|
|
71
|
+
return channel.send('appHookResult', { stage, installationRequestId });
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return Promise.resolve();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
setReady() {
|
|
80
|
+
return channel.call('callAppMethod', 'setReady');
|
|
81
|
+
},
|
|
82
|
+
isInstalled() {
|
|
83
|
+
return channel.call('callAppMethod', 'isInstalled');
|
|
84
|
+
},
|
|
85
|
+
getParameters() {
|
|
86
|
+
return channel.call('callAppMethod', 'getParameters');
|
|
87
|
+
},
|
|
88
|
+
getCurrentState() {
|
|
89
|
+
return channel.call('callAppMethod', 'getCurrentState');
|
|
90
|
+
},
|
|
91
|
+
onConfigure(handler) {
|
|
92
|
+
setHandler(HOOK_STAGE_PRE_INSTALL, handler);
|
|
93
|
+
},
|
|
94
|
+
onConfigurationCompleted(handler) {
|
|
95
|
+
setHandler(HOOK_STAGE_POST_INSTALL, handler);
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
exports.default = createApp;
|
package/dist/channel.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendInitMessage = exports.Channel = exports.connect = void 0;
|
|
4
|
+
const signal_1 = require("./signal");
|
|
5
|
+
function connect(currentGlobal, onConnect) {
|
|
6
|
+
waitForConnect(currentGlobal, (params, messageQueue) => {
|
|
7
|
+
const channel = new Channel(params.id, currentGlobal);
|
|
8
|
+
onConnect(channel, params, messageQueue);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
exports.connect = connect;
|
|
12
|
+
function waitForConnect(currentGlobal, onConnect) {
|
|
13
|
+
currentGlobal.addEventListener('message', listener);
|
|
14
|
+
function listener(event) {
|
|
15
|
+
const message = event.data;
|
|
16
|
+
if (message.method === 'connect') {
|
|
17
|
+
currentGlobal.removeEventListener('message', listener);
|
|
18
|
+
onConnect(...message.params);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class Channel {
|
|
23
|
+
constructor(sourceId, currentGlobal) {
|
|
24
|
+
this._messageHandlers = {};
|
|
25
|
+
this._responseHandlers = {};
|
|
26
|
+
this._send = createSender(sourceId, currentGlobal.parent);
|
|
27
|
+
currentGlobal.addEventListener('message', (event) => {
|
|
28
|
+
this._handleMessage(event.data);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// call method with name `method` exposed by contentful web app `window`
|
|
32
|
+
call(method, ...params) {
|
|
33
|
+
const messageId = this._send(method, params);
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
this._responseHandlers[messageId] = { resolve, reject };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
send(method, ...params) {
|
|
39
|
+
this._send(method, params);
|
|
40
|
+
}
|
|
41
|
+
addHandler(method, handler) {
|
|
42
|
+
if (!(method in this._messageHandlers)) {
|
|
43
|
+
this._messageHandlers[method] = new signal_1.Signal();
|
|
44
|
+
}
|
|
45
|
+
return this._messageHandlers[method].attach(handler);
|
|
46
|
+
}
|
|
47
|
+
_handleMessage(message) {
|
|
48
|
+
if (message.method) {
|
|
49
|
+
const { method, params } = message;
|
|
50
|
+
const handlers = this._messageHandlers[method];
|
|
51
|
+
if (handlers) {
|
|
52
|
+
handlers.dispatch(...params);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const { id } = message;
|
|
57
|
+
const responseHandler = this._responseHandlers[id];
|
|
58
|
+
if (!responseHandler) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if ('result' in message) {
|
|
62
|
+
responseHandler.resolve(message.result);
|
|
63
|
+
}
|
|
64
|
+
else if ('error' in message) {
|
|
65
|
+
// TODO We should wrap this in an Error instance
|
|
66
|
+
responseHandler.reject(message.error);
|
|
67
|
+
}
|
|
68
|
+
delete this._responseHandlers[id];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.Channel = Channel;
|
|
73
|
+
const messageCounter = createMessageCounter();
|
|
74
|
+
function createMessageCounter() {
|
|
75
|
+
let messageCount = 0;
|
|
76
|
+
return {
|
|
77
|
+
getMessageId: () => messageCount++,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function createSender(sourceId, targetWindow) {
|
|
81
|
+
return function send(method, params) {
|
|
82
|
+
const messageId = messageCounter.getMessageId();
|
|
83
|
+
try {
|
|
84
|
+
targetWindow.postMessage({
|
|
85
|
+
source: sourceId,
|
|
86
|
+
id: messageId,
|
|
87
|
+
method,
|
|
88
|
+
params,
|
|
89
|
+
}, '*');
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
if (e instanceof DOMException && e.name === 'DataCloneError' && method === 'openDialog') {
|
|
93
|
+
console.error('Error: openCurrent[App] parameters could not be parsed. You likely tried to pass functions or DOM elements as a parameter. Tip: Use the App SDK directly within the dialog location.\n\nLearn more about the dialog location: https://ctfl.io/app-sdk-dialog');
|
|
94
|
+
}
|
|
95
|
+
throw e;
|
|
96
|
+
}
|
|
97
|
+
return messageId;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function sendInitMessage(currentGlobal) {
|
|
101
|
+
const messageId = messageCounter.getMessageId();
|
|
102
|
+
const targetWindow = currentGlobal.parent;
|
|
103
|
+
// The app is not connected yet so we can't provide a `source`
|
|
104
|
+
targetWindow.postMessage({
|
|
105
|
+
id: messageId,
|
|
106
|
+
method: 'init',
|
|
107
|
+
params: [],
|
|
108
|
+
}, '*');
|
|
109
|
+
return messageId;
|
|
110
|
+
}
|
|
111
|
+
exports.sendInitMessage = sendInitMessage;
|
package/dist/cma.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCMAClient = void 0;
|
|
4
|
+
const contentful_management_1 = require("contentful-management");
|
|
5
|
+
const cmaAdapter_1 = require("./cmaAdapter");
|
|
6
|
+
function createCMAClient(ids, channel) {
|
|
7
|
+
return (0, contentful_management_1.createClient)({ apiAdapter: (0, cmaAdapter_1.createAdapter)(channel) }, {
|
|
8
|
+
type: 'plain',
|
|
9
|
+
defaults: {
|
|
10
|
+
environmentId: ids.environmentAlias ?? ids.environment,
|
|
11
|
+
spaceId: ids.space,
|
|
12
|
+
organizationId: ids.organization,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
exports.createCMAClient = createCMAClient;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAdapter = void 0;
|
|
4
|
+
const createMakeRequestCall = (channel) => {
|
|
5
|
+
return (opts) => channel.call('CMAAdapterCall', opts);
|
|
6
|
+
};
|
|
7
|
+
function createAdapter(channel) {
|
|
8
|
+
return {
|
|
9
|
+
makeRequest: createMakeRequestCall(channel),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
exports.createAdapter = createAdapter;
|
package/dist/dialogs.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const isObject = (o) => typeof o === 'object' && o !== null && !Array.isArray(o);
|
|
4
|
+
const prepareOptions = (options) => (isObject(options) ? options : {});
|
|
5
|
+
function createDialogs(channel, ids) {
|
|
6
|
+
return {
|
|
7
|
+
openAlert: openSimpleDialog.bind(null, 'alert'),
|
|
8
|
+
openConfirm: openSimpleDialog.bind(null, 'confirm'),
|
|
9
|
+
openPrompt: openSimpleDialog.bind(null, 'prompt'),
|
|
10
|
+
open: open,
|
|
11
|
+
selectSingleEntry: openEntitySelector.bind(null, 'Entry', false),
|
|
12
|
+
selectSingleAsset: openEntitySelector.bind(null, 'Asset', false),
|
|
13
|
+
selectMultipleEntries: openEntitySelector.bind(null, 'Entry', true),
|
|
14
|
+
selectMultipleAssets: openEntitySelector.bind(null, 'Asset', true),
|
|
15
|
+
};
|
|
16
|
+
function openSimpleDialog(type, options) {
|
|
17
|
+
return channel.call('openDialog', type, prepareOptions(options));
|
|
18
|
+
}
|
|
19
|
+
function open(options) {
|
|
20
|
+
options = prepareOptions(options);
|
|
21
|
+
if (ids.app) {
|
|
22
|
+
// Force ID of the current app.
|
|
23
|
+
const withForcedId = { ...options, id: ids.app };
|
|
24
|
+
return channel.call('openDialog', 'app', withForcedId);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
throw new Error('Not in the app context.');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function openEntitySelector(entityType, multiple, options) {
|
|
31
|
+
options = prepareOptions(options);
|
|
32
|
+
options.entityType = entityType;
|
|
33
|
+
options.multiple = multiple;
|
|
34
|
+
return channel.call('openDialog', 'entitySelector', options);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.default = createDialogs;
|
package/dist/editor.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const signal_1 = require("./signal");
|
|
4
|
+
function createEditor(channel, editorInterface, editorData) {
|
|
5
|
+
const localeSettingsSignal = new signal_1.MemoizedSignal(editorData.localeSettings);
|
|
6
|
+
const showHiddenFieldsSignal = new signal_1.MemoizedSignal(editorData.showHiddenFields);
|
|
7
|
+
channel.addHandler('localeSettingsChanged', (settings) => {
|
|
8
|
+
localeSettingsSignal.dispatch(settings);
|
|
9
|
+
});
|
|
10
|
+
channel.addHandler('showHiddenFieldsChanged', (showHiddenFields) => {
|
|
11
|
+
showHiddenFieldsSignal.dispatch(showHiddenFields);
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
editorInterface,
|
|
15
|
+
getLocaleSettings() {
|
|
16
|
+
return localeSettingsSignal.getMemoizedArgs()[0];
|
|
17
|
+
},
|
|
18
|
+
onLocaleSettingsChanged: (handler) => {
|
|
19
|
+
return localeSettingsSignal.attach(handler);
|
|
20
|
+
},
|
|
21
|
+
getShowHiddenFields() {
|
|
22
|
+
return showHiddenFieldsSignal.getMemoizedArgs()[0];
|
|
23
|
+
},
|
|
24
|
+
onShowHiddenFieldsChanged: (handler) => {
|
|
25
|
+
return showHiddenFieldsSignal.attach(handler);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
exports.default = createEditor;
|
package/dist/entry.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const signal_1 = require("./signal");
|
|
4
|
+
const taskMethods = [
|
|
5
|
+
'getTask',
|
|
6
|
+
'getTasks',
|
|
7
|
+
'createTask',
|
|
8
|
+
'updateTask',
|
|
9
|
+
'deleteTask',
|
|
10
|
+
];
|
|
11
|
+
function createEntry(channel, entryData, fieldInfo, createEntryField) {
|
|
12
|
+
let sys = entryData.sys;
|
|
13
|
+
const sysChanged = new signal_1.MemoizedSignal(sys);
|
|
14
|
+
let metadata = entryData.metadata;
|
|
15
|
+
const metadataChanged = new signal_1.MemoizedSignal(metadata);
|
|
16
|
+
channel.addHandler('sysChanged', (newSys) => {
|
|
17
|
+
sys = newSys;
|
|
18
|
+
sysChanged.dispatch(sys);
|
|
19
|
+
});
|
|
20
|
+
channel.addHandler('metadataChanged', (newMetadata) => {
|
|
21
|
+
metadata = newMetadata;
|
|
22
|
+
metadataChanged.dispatch(metadata);
|
|
23
|
+
});
|
|
24
|
+
const taskApi = {};
|
|
25
|
+
taskMethods.forEach((methodName) => {
|
|
26
|
+
taskApi[methodName] = function (...args) {
|
|
27
|
+
return channel.call('callEntryMethod', methodName, args);
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
getSys() {
|
|
32
|
+
return sys;
|
|
33
|
+
},
|
|
34
|
+
publish(options) {
|
|
35
|
+
return channel.call('callEntryMethod', 'publish', [options]);
|
|
36
|
+
},
|
|
37
|
+
unpublish() {
|
|
38
|
+
return channel.call('callEntryMethod', 'unpublish');
|
|
39
|
+
},
|
|
40
|
+
save() {
|
|
41
|
+
return channel.call('callEntryMethod', 'save');
|
|
42
|
+
},
|
|
43
|
+
onSysChanged(handler) {
|
|
44
|
+
return sysChanged.attach(handler);
|
|
45
|
+
},
|
|
46
|
+
fields: fieldInfo.reduce((acc, info) => {
|
|
47
|
+
acc[info.id] = createEntryField(info);
|
|
48
|
+
return acc;
|
|
49
|
+
}, {}),
|
|
50
|
+
...(metadata ? { metadata } : {}),
|
|
51
|
+
getMetadata() {
|
|
52
|
+
return metadata;
|
|
53
|
+
},
|
|
54
|
+
onMetadataChanged(handler) {
|
|
55
|
+
return metadataChanged.attach(handler);
|
|
56
|
+
},
|
|
57
|
+
...taskApi,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
exports.default = createEntry;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const signal_1 = require("./signal");
|
|
4
|
+
class FieldLocale {
|
|
5
|
+
constructor(channel, info) {
|
|
6
|
+
this.id = info.id;
|
|
7
|
+
this.name = info.name;
|
|
8
|
+
this.locale = info.locale;
|
|
9
|
+
this.type = info.type;
|
|
10
|
+
this.required = info.required;
|
|
11
|
+
this.validations = info.validations;
|
|
12
|
+
if (info.type === 'Array') {
|
|
13
|
+
this.items = info.items;
|
|
14
|
+
}
|
|
15
|
+
if (info.type === 'Link') {
|
|
16
|
+
this.linkType = info.linkType;
|
|
17
|
+
}
|
|
18
|
+
this._value = info.value;
|
|
19
|
+
this._valueSignal = new signal_1.MemoizedSignal(this._value);
|
|
20
|
+
this._isDisabledSignal = new signal_1.MemoizedSignal(info.isDisabled);
|
|
21
|
+
this._schemaErrorsChangedSignal = new signal_1.MemoizedSignal(info.schemaErrors);
|
|
22
|
+
this._channel = channel;
|
|
23
|
+
channel.addHandler('valueChanged', (id, locale, value) => {
|
|
24
|
+
if (id === this.id && (!locale || locale === this.locale)) {
|
|
25
|
+
this._value = value;
|
|
26
|
+
this._valueSignal.dispatch(value);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
channel.addHandler('isDisabledChangedForFieldLocale', (id, locale, isDisabled) => {
|
|
30
|
+
if (id === this.id && locale === this.locale) {
|
|
31
|
+
this._isDisabledSignal.dispatch(isDisabled);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
channel.addHandler('schemaErrorsChangedForFieldLocale', (id, locale, errors) => {
|
|
35
|
+
if (id === this.id && locale === this.locale) {
|
|
36
|
+
this._schemaErrorsChangedSignal.dispatch(errors);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
getValue() {
|
|
41
|
+
return this._value;
|
|
42
|
+
}
|
|
43
|
+
async setValue(value) {
|
|
44
|
+
this._value = value;
|
|
45
|
+
return await this._channel.call('setValue', this.id, this.locale, value);
|
|
46
|
+
}
|
|
47
|
+
async removeValue() {
|
|
48
|
+
this._value = undefined;
|
|
49
|
+
await this._channel.call('removeValue', this.id, this.locale);
|
|
50
|
+
}
|
|
51
|
+
setInvalid(isInvalid) {
|
|
52
|
+
return this._channel.call('setInvalid', isInvalid, this.locale);
|
|
53
|
+
}
|
|
54
|
+
onValueChanged(handler) {
|
|
55
|
+
return this._valueSignal.attach(handler);
|
|
56
|
+
}
|
|
57
|
+
getIsDisabled() {
|
|
58
|
+
return this._isDisabledSignal.getMemoizedArgs()[0];
|
|
59
|
+
}
|
|
60
|
+
onIsDisabledChanged(handler) {
|
|
61
|
+
return this._isDisabledSignal.attach(handler);
|
|
62
|
+
}
|
|
63
|
+
getSchemaErrors() {
|
|
64
|
+
return this._schemaErrorsChangedSignal.getMemoizedArgs()[0];
|
|
65
|
+
}
|
|
66
|
+
onSchemaErrorsChanged(handler) {
|
|
67
|
+
return this._schemaErrorsChangedSignal.attach(handler);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.default = FieldLocale;
|
package/dist/field.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const field_locale_1 = require("./field-locale");
|
|
4
|
+
class Field {
|
|
5
|
+
constructor(channel, info, defaultLocale) {
|
|
6
|
+
this.id = info.id;
|
|
7
|
+
this.name = info.name;
|
|
8
|
+
this.locales = info.locales;
|
|
9
|
+
this.type = info.type;
|
|
10
|
+
this.required = info.required;
|
|
11
|
+
this.validations = info.validations;
|
|
12
|
+
if (info.type === 'Array') {
|
|
13
|
+
this.items = info.items;
|
|
14
|
+
}
|
|
15
|
+
if (info.type === 'Link') {
|
|
16
|
+
this.linkType = info.linkType;
|
|
17
|
+
}
|
|
18
|
+
this._defaultLocale = defaultLocale;
|
|
19
|
+
this._fieldLocales = info.locales.reduce((acc, locale) => {
|
|
20
|
+
const fieldLocale = new field_locale_1.default(channel, {
|
|
21
|
+
id: info.id,
|
|
22
|
+
name: info.name,
|
|
23
|
+
type: info.type,
|
|
24
|
+
required: info.required,
|
|
25
|
+
validations: info.validations,
|
|
26
|
+
locale,
|
|
27
|
+
items: info.type === 'Array' ? info.items : undefined,
|
|
28
|
+
linkType: info.type === 'Link' ? info.linkType : undefined,
|
|
29
|
+
value: info.values[locale],
|
|
30
|
+
isDisabled: info.isDisabled[locale],
|
|
31
|
+
schemaErrors: info.schemaErrors[locale],
|
|
32
|
+
});
|
|
33
|
+
return { ...acc, [locale]: fieldLocale };
|
|
34
|
+
}, {});
|
|
35
|
+
this.assertHasLocale(defaultLocale);
|
|
36
|
+
}
|
|
37
|
+
getValue(locale) {
|
|
38
|
+
return this._getFieldLocale(locale).getValue();
|
|
39
|
+
}
|
|
40
|
+
async setValue(value, locale) {
|
|
41
|
+
return await this._getFieldLocale(locale).setValue(value);
|
|
42
|
+
}
|
|
43
|
+
async removeValue(locale) {
|
|
44
|
+
await this.setValue(undefined, locale);
|
|
45
|
+
}
|
|
46
|
+
onValueChanged(locale, handler) {
|
|
47
|
+
const h = handler || locale;
|
|
48
|
+
if (!handler) {
|
|
49
|
+
locale = '';
|
|
50
|
+
}
|
|
51
|
+
return this._getFieldLocale(locale).onValueChanged(h);
|
|
52
|
+
}
|
|
53
|
+
onIsDisabledChanged(locale, handler) {
|
|
54
|
+
const h = handler || locale;
|
|
55
|
+
if (!handler) {
|
|
56
|
+
locale = '';
|
|
57
|
+
}
|
|
58
|
+
return this._getFieldLocale(locale).onIsDisabledChanged(h);
|
|
59
|
+
}
|
|
60
|
+
_getFieldLocale(locale) {
|
|
61
|
+
locale = locale || this._defaultLocale;
|
|
62
|
+
this.assertHasLocale(locale);
|
|
63
|
+
return this._fieldLocales[locale];
|
|
64
|
+
}
|
|
65
|
+
getForLocale(locale) {
|
|
66
|
+
if (!locale) {
|
|
67
|
+
throw new Error('getForLocale must be passed a locale');
|
|
68
|
+
}
|
|
69
|
+
return this._getFieldLocale(locale);
|
|
70
|
+
}
|
|
71
|
+
assertHasLocale(locale) {
|
|
72
|
+
if (!this._fieldLocales[locale]) {
|
|
73
|
+
throw new Error(`Unknown locale "${locale}" for field "${this.id}"`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.default = Field;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
exports.init = exports.locations = void 0;
|
|
18
|
+
const initialize_1 = require("./initialize");
|
|
19
|
+
const api_1 = require("./api");
|
|
20
|
+
__exportStar(require("./types"), exports);
|
|
21
|
+
var locations_1 = require("./locations");
|
|
22
|
+
Object.defineProperty(exports, "locations", { enumerable: true, get: function () { return locations_1.default; } });
|
|
23
|
+
exports.init = (0, initialize_1.createInitializer)(globalThis, api_1.default);
|