feat: events (#717)
This commit is contained in:
parent
455bcdc0f2
commit
79877fcd1f
@ -49,7 +49,7 @@ function getConfigUrl() {
|
||||
};
|
||||
const configLinkEl = document.querySelector<HTMLLinkElement>('link[rel="cms-config-url"]');
|
||||
if (configLinkEl && validTypes[configLinkEl.type] && configLinkEl.href) {
|
||||
console.info(`Using config file path: "${configLinkEl.href}"`);
|
||||
console.info(`[StaticCMS] Using config file path: "${configLinkEl.href}"`);
|
||||
return configLinkEl.href;
|
||||
}
|
||||
return 'config.yml';
|
||||
@ -294,7 +294,7 @@ async function getConfigYaml(file: string): Promise<Config> {
|
||||
const contentType = response.headers.get('Content-Type') ?? 'Not-Found';
|
||||
const isYaml = contentType.indexOf('yaml') !== -1;
|
||||
if (!isYaml) {
|
||||
console.info(`Response for ${file} was not yaml. (Content-Type: ${contentType})`);
|
||||
console.info(`[StaticCMS] Response for ${file} was not yaml. (Content-Type: ${contentType})`);
|
||||
}
|
||||
return parseConfig(await response.text());
|
||||
}
|
||||
@ -338,7 +338,7 @@ export async function detectProxyServer(localBackend?: boolean | LocalBackend) {
|
||||
: localBackend.url || defaultUrl.replace('localhost', location.hostname);
|
||||
|
||||
try {
|
||||
console.info(`Looking for Static CMS Proxy Server at '${proxyUrl}'`);
|
||||
console.info(`[StaticCMS] Looking for Static CMS Proxy Server at '${proxyUrl}'`);
|
||||
const res = await fetch(`${proxyUrl}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@ -349,14 +349,16 @@ export async function detectProxyServer(localBackend?: boolean | LocalBackend) {
|
||||
type?: string;
|
||||
};
|
||||
if (typeof repo === 'string' && typeof type === 'string') {
|
||||
console.info(`Detected Static CMS Proxy Server at '${proxyUrl}' with repo: '${repo}'`);
|
||||
console.info(
|
||||
`[StaticCMS] Detected Static CMS Proxy Server at '${proxyUrl}' with repo: '${repo}'`,
|
||||
);
|
||||
return { proxyUrl, type };
|
||||
} else {
|
||||
console.info(`Static CMS Proxy Server not detected at '${proxyUrl}'`);
|
||||
console.info(`[StaticCMS] Static CMS Proxy Server not detected at '${proxyUrl}'`);
|
||||
return {};
|
||||
}
|
||||
} catch {
|
||||
console.info(`Static CMS Proxy Server not detected at '${proxyUrl}'`);
|
||||
console.info(`[StaticCMS] Static CMS Proxy Server not detected at '${proxyUrl}'`);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,7 @@ export function loadMedia(
|
||||
.catch((error: { status?: number }) => {
|
||||
console.error(error);
|
||||
if (error.status === 404) {
|
||||
console.info('This 404 was expected and handled appropriately.');
|
||||
console.info('[StaticCMS] This 404 was expected and handled appropriately.');
|
||||
dispatch(mediaLoaded([]));
|
||||
} else {
|
||||
dispatch(mediaLoadFailed());
|
||||
|
@ -29,7 +29,7 @@ export async function waitUntilWithTimeout<T>(
|
||||
if (waitDone) {
|
||||
resolve(null);
|
||||
} else {
|
||||
console.warn('Wait Action timed out');
|
||||
console.warn('[StaticCMS] Wait Action timed out');
|
||||
resolve(null);
|
||||
}
|
||||
}, timeout);
|
||||
|
@ -676,7 +676,7 @@ export class Backend<EF extends BaseField = UnknownField, BC extends BackendClas
|
||||
const result = await localForage.setItem(getEntryBackupKey(), raw);
|
||||
return result;
|
||||
} catch (e) {
|
||||
console.warn('persistLocalDraftBackup', e);
|
||||
console.warn('[StaticCMS] persistLocalDraftBackup', e);
|
||||
} finally {
|
||||
this.backupSync.release();
|
||||
}
|
||||
@ -691,7 +691,7 @@ export class Backend<EF extends BaseField = UnknownField, BC extends BackendClas
|
||||
const result = await this.deleteAnonymousBackup();
|
||||
return result;
|
||||
} catch (e) {
|
||||
console.warn('deleteLocalDraftBackup', e);
|
||||
console.warn('[StaticCMS] deleteLocalDraftBackup', e);
|
||||
} finally {
|
||||
this.backupSync.release();
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ export const API_NAME = 'Bitbucket';
|
||||
|
||||
function replace404WithEmptyResponse(err: FetchError) {
|
||||
if (err && err.status === 404) {
|
||||
console.info('This 404 was expected and handled appropriately.');
|
||||
console.info('[StaticCMS] This 404 was expected and handled appropriately.');
|
||||
return { size: 0, values: [] as BitBucketFile[] } as BitBucketSrcResult;
|
||||
} else {
|
||||
return Promise.reject(err);
|
||||
@ -235,7 +235,7 @@ export default class API {
|
||||
url: `${this.repoURL}/commits`,
|
||||
params: { include: branch, pagelen: '100' },
|
||||
}).catch(e => {
|
||||
console.info(`Failed getting commits for branch '${branch}'`, e);
|
||||
console.info(`[StaticCMS] Failed getting commits for branch '${branch}'`, e);
|
||||
return [];
|
||||
});
|
||||
|
||||
|
@ -126,7 +126,7 @@ export default class BitbucketBackend implements BackendClass {
|
||||
);
|
||||
})
|
||||
.catch(e => {
|
||||
console.warn('Failed getting BitBucket status', e);
|
||||
console.warn('[StaticCMS] Failed getting BitBucket status', e);
|
||||
return true;
|
||||
});
|
||||
|
||||
@ -138,7 +138,7 @@ export default class BitbucketBackend implements BackendClass {
|
||||
?.user()
|
||||
.then(user => !!user)
|
||||
.catch(e => {
|
||||
console.warn('Failed getting Bitbucket user', e);
|
||||
console.warn('[StaticCMS] Failed getting Bitbucket user', e);
|
||||
return false;
|
||||
})) || false;
|
||||
}
|
||||
@ -373,7 +373,7 @@ export default class BitbucketBackend implements BackendClass {
|
||||
.then(attributes => getLargeMediaPatternsFromGitAttributesFile(attributes as string))
|
||||
.catch((err: FetchError) => {
|
||||
if (err.status === 404) {
|
||||
console.info('This 404 was expected and handled appropriately.');
|
||||
console.info('[StaticCMS] This 404 was expected and handled appropriately.');
|
||||
} else {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ const GitGatewayAuthenticationPage = ({ onLogin, t }: GitGatewayAuthenticationPa
|
||||
}
|
||||
|
||||
if (window.netlifyIdentity) {
|
||||
console.info('Manually initializing identity widget');
|
||||
console.info('[StaticCMS] Manually initializing identity widget');
|
||||
initialized = true;
|
||||
window.netlifyIdentity.init();
|
||||
clearInterval(interval);
|
||||
|
@ -175,7 +175,7 @@ export default class GitGateway implements BackendClass {
|
||||
.every((statusComponent: GitGatewayStatus) => statusComponent.status === 'operational');
|
||||
})
|
||||
.catch(e => {
|
||||
console.warn('Failed getting Git Gateway status', e);
|
||||
console.warn('[StaticCMS] Failed getting Git Gateway status', e);
|
||||
return true;
|
||||
});
|
||||
|
||||
@ -186,7 +186,7 @@ export default class GitGateway implements BackendClass {
|
||||
(await this.tokenPromise?.()
|
||||
.then(token => !!token)
|
||||
.catch(e => {
|
||||
console.warn('Failed getting Identity token', e);
|
||||
console.warn('[StaticCMS] Failed getting Identity token', e);
|
||||
return false;
|
||||
})) || false;
|
||||
}
|
||||
@ -415,7 +415,7 @@ export default class GitGateway implements BackendClass {
|
||||
.then((patterns: string[]) => ({ err: null, patterns }))
|
||||
.catch((err: Error) => {
|
||||
if (err.message.includes('404')) {
|
||||
console.info('This 404 was expected and handled appropriately.');
|
||||
console.info('[StaticCMS] This 404 was expected and handled appropriately.');
|
||||
return { err: null, patterns: [] as string[] };
|
||||
} else {
|
||||
return { err, patterns: [] as string[] };
|
||||
@ -461,7 +461,7 @@ export default class GitGateway implements BackendClass {
|
||||
const entry = items[0];
|
||||
const pointerFile = parsePointerFile(entry.data);
|
||||
if (!pointerFile.sha) {
|
||||
console.warn(`Failed parsing pointer file ${path}`);
|
||||
console.warn(`[StaticCMS] Failed parsing pointer file ${path}`);
|
||||
return { url: path, blob: new Blob() };
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ export default class API {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
if (err && err.status === 404) {
|
||||
console.info('This 404 was expected and handled appropriately.');
|
||||
console.info('[StaticCMS] This 404 was expected and handled appropriately.');
|
||||
return [];
|
||||
} else {
|
||||
throw err;
|
||||
|
@ -93,7 +93,7 @@ export default class Gitea implements BackendClass {
|
||||
?.user()
|
||||
.then(user => !!user)
|
||||
.catch(e => {
|
||||
console.warn('Failed getting Gitea user', e);
|
||||
console.warn('[StaticCMS] Failed getting Gitea user', e);
|
||||
return false;
|
||||
})) || false;
|
||||
|
||||
|
@ -369,7 +369,7 @@ export default class API {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
if (err && err.status === 404) {
|
||||
console.info('This 404 was expected and handled appropriately.');
|
||||
console.info('[StaticCMS] This 404 was expected and handled appropriately.');
|
||||
return [];
|
||||
} else {
|
||||
throw err;
|
||||
|
@ -109,7 +109,7 @@ export default class GitHub implements BackendClass {
|
||||
);
|
||||
})
|
||||
.catch(e => {
|
||||
console.warn('Failed getting GitHub status', e);
|
||||
console.warn('[StaticCMS] Failed getting GitHub status', e);
|
||||
return true;
|
||||
});
|
||||
|
||||
@ -121,7 +121,7 @@ export default class GitHub implements BackendClass {
|
||||
?.getUser()
|
||||
.then(user => !!user)
|
||||
.catch(e => {
|
||||
console.warn('Failed getting GitHub user', e);
|
||||
console.warn('[StaticCMS] Failed getting GitHub user', e);
|
||||
return false;
|
||||
})) || false;
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ export default class GitLab implements BackendClass {
|
||||
?.user()
|
||||
.then(user => !!user)
|
||||
.catch(e => {
|
||||
console.warn('Failed getting GitLab user', e);
|
||||
console.warn('[StaticCMS] Failed getting GitLab user', e);
|
||||
return false;
|
||||
})) || false;
|
||||
|
||||
|
@ -40,6 +40,7 @@ const ROOT_ID = 'nc-root';
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, import/order
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.usingClientEntryPoint = true;
|
||||
@ -79,7 +80,7 @@ function bootstrap<F extends BaseField = UnknownField>(opts?: {
|
||||
* Log the version number.
|
||||
*/
|
||||
if (typeof STATIC_CMS_CORE_VERSION === 'string') {
|
||||
console.info(`static-cms-core ${STATIC_CMS_CORE_VERSION}`);
|
||||
console.info(`[StaticCMS] Using @staticcms/core ${STATIC_CMS_CORE_VERSION}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ import { loginUser as loginUserAction } from '@staticcms/core/actions/auth';
|
||||
import { discardDraft } from '@staticcms/core/actions/entries';
|
||||
import { currentBackend } from '@staticcms/core/backend';
|
||||
import { changeTheme } from '../actions/globalUI';
|
||||
import { invokeEvent } from '../lib/registry';
|
||||
import { getDefaultPath } from '../lib/util/collection.util';
|
||||
import { selectTheme } from '../reducers/selectors/globalUI';
|
||||
import { useAppDispatch, useAppSelector } from '../store/hooks';
|
||||
@ -229,6 +230,12 @@ const App = ({
|
||||
);
|
||||
}, [authenticationPage, collections, defaultPath, isFetching, user]);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
invokeEvent({ name: 'mounted' });
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (!config.config) {
|
||||
return configError(t('app.app.configNotFound'));
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ function buildIssueUrl(title: string, config?: Config) {
|
||||
|
||||
return `${ISSUE_URL}${params.toString()}`;
|
||||
} catch (e) {
|
||||
console.info(e);
|
||||
console.error(e);
|
||||
return `${ISSUE_URL}template=bug_report.md`;
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,7 @@ interface RecoveredEntryProps {
|
||||
}
|
||||
|
||||
const RecoveredEntry = ({ entry, t }: TranslatedProps<RecoveredEntryProps>) => {
|
||||
console.info(entry);
|
||||
console.info('[StaticCMS] Recovered entry', entry);
|
||||
return (
|
||||
<>
|
||||
<hr />
|
||||
@ -134,7 +134,7 @@ class ErrorBoundary extends Component<TranslatedProps<ErrorBoundaryProps>, Error
|
||||
if (this.props.showBackup) {
|
||||
const backup = await localForage.getItem<string>('backup');
|
||||
if (backup) {
|
||||
console.info(backup);
|
||||
console.info('[StaticCMS] Recovered backup', backup);
|
||||
this.setState({ backup });
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ function inferFrontmatterFormat(str: string) {
|
||||
case '{':
|
||||
return getFormatOpts(Languages.JSON);
|
||||
default:
|
||||
console.warn('Unrecognized front-matter format.');
|
||||
console.warn('[StaticCMS] Unrecognized front-matter format.');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,7 +821,7 @@ export interface EventData {
|
||||
export type EventListenerOptions = Record<string, unknown>;
|
||||
|
||||
export type EventListenerHandler = (
|
||||
data: EventData,
|
||||
data: EventData | undefined,
|
||||
options: EventListenerOptions,
|
||||
) => Promise<EntryData | undefined | null | void>;
|
||||
|
||||
|
@ -54,7 +54,9 @@ export function commitMessageFormatter<EF extends BaseField>(
|
||||
case 'author-name':
|
||||
return authorName || '';
|
||||
default:
|
||||
console.warn(`Ignoring unknown variable “${variable}” in commit message template.`);
|
||||
console.warn(
|
||||
`[StaticCMS] Ignoring unknown variable “${variable}” in commit message template.`,
|
||||
);
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
@ -246,7 +246,7 @@ function mergeValues<EF extends BaseField>(
|
||||
let defaultEntry = values.find(e => e.locale === defaultLocale);
|
||||
if (!defaultEntry) {
|
||||
defaultEntry = values[0];
|
||||
console.warn(`Could not locale entry for default locale '${defaultLocale}'`);
|
||||
console.warn(`[StaticCMS] Could not locale entry for default locale '${defaultLocale}'`);
|
||||
}
|
||||
const i18n = values
|
||||
.filter(e => e.locale !== defaultEntry!.locale)
|
||||
|
@ -26,7 +26,7 @@ import type {
|
||||
WidgetValueSerializer,
|
||||
} from '../interface';
|
||||
|
||||
export const allowedEvents = ['preSave', 'postSave'] as const;
|
||||
export const allowedEvents = ['mounted', 'preSave', 'postSave'] as const;
|
||||
export type AllowedEvent = (typeof allowedEvents)[number];
|
||||
|
||||
const eventHandlers = allowedEvents.reduce((acc, e) => {
|
||||
@ -219,7 +219,7 @@ export function registerWidget<T = unknown, F extends BaseField = UnknownField>(
|
||||
} = nameOrWidgetOrWidgets;
|
||||
if (registry.widgets[widgetName]) {
|
||||
console.warn(oneLine`
|
||||
Multiple widgets registered with name "${widgetName}". Only the last widget registered with
|
||||
[StaticCMS] Multiple widgets registered with name "${widgetName}". Only the last widget registered with
|
||||
this name will be used.
|
||||
`);
|
||||
}
|
||||
@ -323,22 +323,24 @@ export function registerEventListener(
|
||||
registry.eventHandlers[name].push({ handler, options });
|
||||
}
|
||||
|
||||
export async function invokeEvent({ name, data }: { name: AllowedEvent; data: EventData }) {
|
||||
export async function invokeEvent({ name, data }: { name: AllowedEvent; data?: EventData }) {
|
||||
validateEventName(name);
|
||||
const handlers = registry.eventHandlers[name];
|
||||
|
||||
let _data = { ...data };
|
||||
console.info(`[StaticCMS] Firing event ${name}`, data);
|
||||
|
||||
let _data = data ? { ...data } : undefined;
|
||||
for (const { handler, options } of handlers) {
|
||||
const result = await handler(_data, options);
|
||||
if (result !== undefined) {
|
||||
if (_data !== undefined && result !== undefined) {
|
||||
const entry = {
|
||||
..._data.entry,
|
||||
data: result,
|
||||
} as Entry;
|
||||
_data = { ...data, entry };
|
||||
_data = { ..._data, entry };
|
||||
}
|
||||
}
|
||||
return _data.entry.data;
|
||||
return _data?.entry.data;
|
||||
}
|
||||
|
||||
export function removeEventListener({ name, handler }: EventListener) {
|
||||
|
@ -83,7 +83,7 @@ export async function requestWithBackoff(
|
||||
if (!api.rateLimiter) {
|
||||
const timeout = error.resetSeconds || attempt * attempt;
|
||||
console.info(
|
||||
`Pausing requests for ${timeout} ${
|
||||
`[StaticCMS] Pausing requests for ${timeout} ${
|
||||
attempt === 1 ? 'second' : 'seconds'
|
||||
} due to fetch failures:`,
|
||||
error.message,
|
||||
@ -93,7 +93,7 @@ export async function requestWithBackoff(
|
||||
setTimeout(() => {
|
||||
api.rateLimiter?.release();
|
||||
api.rateLimiter = undefined;
|
||||
console.info(`Done pausing requests`);
|
||||
console.info('[StaticCMS] Done pausing requests');
|
||||
}, 1000 * timeout);
|
||||
}
|
||||
return requestWithBackoff(api, req, attempt + 1);
|
||||
|
@ -33,7 +33,7 @@ export function asyncLock(): AsyncLock {
|
||||
if (e instanceof Error && e.message !== 'leave called too many times.') {
|
||||
throw e;
|
||||
} else {
|
||||
console.warn('leave called too many times.');
|
||||
console.warn('[StaticCMS] Leave called too many times.');
|
||||
lock = semaphore(1);
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ export async function runWithLock(lock: AsyncLock, func: Function, message: stri
|
||||
try {
|
||||
const acquired = await lock.acquire();
|
||||
if (!acquired) {
|
||||
console.warn(message);
|
||||
console.warn('[StaticCMS]', message);
|
||||
}
|
||||
|
||||
const result = await func();
|
||||
@ -315,7 +315,7 @@ export async function allEntriesByFolder({
|
||||
const localTreeInBranch = await isShaExistsInBranch(branch.name, localTree.head);
|
||||
if (!localTreeInBranch) {
|
||||
console.info(
|
||||
`Can't find local tree head '${localTree.head}' in branch '${branch.name}', rebuilding local tree`,
|
||||
`[StaticCMS] Can't find local tree head '${localTree.head}' in branch '${branch.name}', rebuilding local tree`,
|
||||
);
|
||||
return listAllFilesAndPersist();
|
||||
}
|
||||
@ -329,12 +329,12 @@ export async function allEntriesByFolder({
|
||||
getFileId,
|
||||
filterFile,
|
||||
}).catch(e => {
|
||||
console.info('Failed getting diff from local tree:', e);
|
||||
console.info('[StaticCMS] Failed getting diff from local tree:', e);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (!diff) {
|
||||
console.info(`Diff is null, rebuilding local tree`);
|
||||
console.info(`[StaticCMS] Diff is null, rebuilding local tree`);
|
||||
return listAllFilesAndPersist();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ function localForageTest() {
|
||||
.catch(err => {
|
||||
if (err.code === 22) {
|
||||
const message = 'Unable to set localStorage key. Quota exceeded! Full disk?';
|
||||
console.warn(message);
|
||||
console.warn('[StaticCMS]', message);
|
||||
}
|
||||
console.info(err);
|
||||
});
|
||||
|
@ -89,7 +89,7 @@ export function getGroup(entry: Entry, selectedGroup: GroupMap) {
|
||||
value = matched[0];
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
console.warn(`Invalid view group pattern '${pattern}' for field '${field}'`, e);
|
||||
console.warn(`[StaticCMS] Invalid view group pattern '${pattern}' for field '${field}'`, e);
|
||||
}
|
||||
return {
|
||||
id: `${label}${value}`,
|
||||
|
@ -50,7 +50,9 @@ function validateItem(field: ListField, item: ValueOrNestedValue) {
|
||||
|
||||
if (typeof item !== 'object') {
|
||||
console.warn(
|
||||
`'${field.name}' field item value value should be an object but is a '${typeof item}'`,
|
||||
`[StaticCMS] '${
|
||||
field.name
|
||||
}' field item value value should be an object but is a '${typeof item}'`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ ${bodyRows.join('\n')}`;
|
||||
)}${shortcodeConfig.closeTag}`;
|
||||
|
||||
default:
|
||||
console.warn('Unrecognized slate node, proceeding as text', `"${type}"`, chunk);
|
||||
console.warn('[StaticCMS] Unrecognized slate node, proceeding as text', `"${type}"`, chunk);
|
||||
return children;
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
|
||||
case 'br':
|
||||
return { type: NodeTypes.paragraph, children: [{ text: '' }] };
|
||||
default:
|
||||
console.warn('unrecognized mdx flow element', node);
|
||||
console.warn('[StaticCMS] Unrecognized mdx flow element', node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -335,7 +335,7 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
|
||||
...persistLeafFormats(children as Array<MdastNode>),
|
||||
} as TextNode;
|
||||
default:
|
||||
console.warn('unrecognized mdx text element', node);
|
||||
console.warn('[StaticCMS] Unrecognized mdx text element', node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -356,7 +356,7 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
|
||||
return nodes.map(node => (node.type === 'text' ? { text: node.value ?? '' } : node));
|
||||
|
||||
default:
|
||||
console.warn('Unrecognized mdast node, proceeding as text', node);
|
||||
console.warn('[StaticCMS] Unrecognized mdast node, proceeding as text', node);
|
||||
return { text: node.value || '' };
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ CMS.registerEventListener({
|
||||
});
|
||||
```
|
||||
|
||||
Supported events are `preSave` and `postSave`. The `preSave` hook can be used to modify the entry data like so:
|
||||
Supported events are `mounted`, `preSave` and `postSave`. The `preSave` hook can be used to modify the entry data like so:
|
||||
|
||||
```javascript
|
||||
CMS.registerEventListener({
|
||||
|
Loading…
x
Reference in New Issue
Block a user