Skip to content

Commit

Permalink
feat: make lib browser aware
Browse files Browse the repository at this point in the history
  • Loading branch information
davidenke committed Oct 20, 2024
1 parent 025ea3f commit 317108e
Showing 1 changed file with 27 additions and 21 deletions.
48 changes: 27 additions & 21 deletions src/utils/decap.utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { existsSync } from 'node:fs';
import { readFile } from 'node:fs/promises';

import type { CmsCollection, CmsConfig } from 'decap-cms-core';

// TODO use the CmsField['widget'] type from decap-cms-core but exclude the generic string somehow
Expand All @@ -23,35 +20,44 @@ export type DecapWidgetType =
| 'text';

export async function loadDecapConfig(ymlPath: string): Promise<CmsConfig> {
const { existsSync } = await import('node:fs');
const { readFile } = await import('node:fs/promises');

// does the config file exist?
if (!existsSync(ymlPath)) {
return Promise.reject(new Error(`File not found: ${ymlPath}`));
}

// in order to use the config utils from Decap CMS, we need to mock some globals first
(globalThis as any).__store = {};
(globalThis as any).localStorage = {
getItem: (k: string): string => globalThis.__store[k],
setItem: (k: string, v: string) => (globalThis.__store[k] = v),
removeItem: (k: string) => delete globalThis.__store[k],
};

(globalThis as any).window = {
document: { createElement: () => ({}) },
navigator: { userAgent: 'Node.js' },
history: { pushState: () => {}, replaceState: () => {} },
location: { href: 'http://localhost', replace: () => {} },
URL: { createObjectURL: URL.createObjectURL } as any,
};
// ... and use it to process the config file
const configRaw = await readFile(ymlPath, 'utf8');
return parseConfig(configRaw);
}

export async function parseConfig(ymlData: string): Promise<CmsConfig> {
// in order to use the config utils from Decap CMS in Node,
// we need to mock some globals first
if (!('window' in globalThis)) {
(globalThis as any).__store = {};
(globalThis as any).localStorage = {
getItem: (k: string): string => globalThis.__store[k],
setItem: (k: string, v: string) => (globalThis.__store[k] = v),
removeItem: (k: string) => delete globalThis.__store[k],
};
(globalThis as any).window = {
document: { createElement: () => ({}) },
navigator: { userAgent: 'Node.js' },
history: { pushState: () => {}, replaceState: () => {} },
location: { href: 'http://localhost', replace: () => {} },
URL: { createObjectURL: URL.createObjectURL } as any,
};
}

// load the original tooling...
const { parseConfig, normalizeConfig } = await import(
'decap-cms-core/dist/esm/actions/config.js'
);

// ... and use it to process the config file
const configRaw = await readFile(ymlPath, 'utf8');
return normalizeConfig(parseConfig(configRaw));
return normalizeConfig(parseConfig(ymlData));
}

export function getCollection(config: CmsConfig, name: string): CmsCollection | undefined {
Expand Down

0 comments on commit 317108e

Please sign in to comment.