diff --git a/packages/cms/core/package.json b/packages/cms/core/package.json
index c3b70cba4..f172e9864 100644
--- a/packages/cms/core/package.json
+++ b/packages/cms/core/package.json
@@ -13,9 +13,12 @@
".": "./src/index.ts"
},
"devDependencies": {
+ "@kit/cms-types": "workspace:^",
"@kit/eslint-config": "workspace:*",
+ "@kit/keystatic": "workspace:^",
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
+ "@kit/wordpress": "workspace:^",
"@types/node": "^22.5.2"
},
"eslintConfig": {
diff --git a/packages/cms/core/src/content-renderer.tsx b/packages/cms/core/src/content-renderer.tsx
index 5ada07531..e8dfdbe38 100644
--- a/packages/cms/core/src/content-renderer.tsx
+++ b/packages/cms/core/src/content-renderer.tsx
@@ -1,4 +1,4 @@
-import type { CmsType } from './cms.type';
+import type { CmsType } from '@kit/cms-types';
const CMS_CLIENT = process.env.CMS_CLIENT as CmsType;
@@ -11,21 +11,32 @@ export async function ContentRenderer({
content,
type = CMS_CLIENT,
}: ContentRendererProps) {
+ const Renderer = await getContentRenderer(type);
+
+ return Renderer ? : null;
+}
+
+/**
+ * Gets the content renderer for the specified CMS client.
+ *
+ * @param {CmsType} type - The type of CMS client.
+ */
+async function getContentRenderer(type: CmsType) {
switch (type) {
case 'keystatic': {
const { KeystaticContentRenderer } = await import(
- '../../keystatic/src/content-renderer'
+ '@kit/keystatic/renderer'
);
- return ;
+ return KeystaticContentRenderer;
}
case 'wordpress': {
const { WordpressContentRenderer } = await import(
- '../../wordpress/src/content-renderer'
+ '@kit/wordpress/renderer'
);
- return ;
+ return WordpressContentRenderer;
}
default: {
diff --git a/packages/cms/core/src/create-cms-client.ts b/packages/cms/core/src/create-cms-client.ts
index 77b307224..0f824903c 100644
--- a/packages/cms/core/src/create-cms-client.ts
+++ b/packages/cms/core/src/create-cms-client.ts
@@ -1,5 +1,9 @@
-import { CmsClient } from './cms-client';
-import { CmsType } from './cms.type';
+import { CmsClient, CmsType } from '@kit/cms-types';
+
+/**
+ * The type of CMS client to use.
+ */
+const CMS_CLIENT = process.env.CMS_CLIENT as CmsType;
/**
* Creates a CMS client based on the specified type.
@@ -9,61 +13,32 @@ import { CmsType } from './cms.type';
* @throws {Error} If the specified CMS type is unknown.
*/
export async function createCmsClient(
- type: CmsType = process.env.CMS_CLIENT as CmsType,
+ type: CmsType = CMS_CLIENT,
): Promise {
return cmsClientFactory(type);
}
-async function cmsClientFactory(type: CmsType) {
+/**
+ * Creates a CMS client based on the specified type.
+ *
+ * @param {CmsType} type - The type of CMS client to create.
+ * @returns {Promise} A Promise that resolves to the created CMS client.
+ */
+async function cmsClientFactory(type: CmsType): Promise {
switch (type) {
- case 'wordpress':
- return getWordpressClient();
+ case 'wordpress': {
+ const { createWordpressClient } = await import('@kit/wordpress');
- case 'keystatic':
- return getKeystaticClient();
+ return createWordpressClient();
+ }
+
+ case 'keystatic': {
+ const { createKeystaticClient } = await import('@kit/keystatic');
+
+ return createKeystaticClient();
+ }
default:
throw new Error(`Unknown CMS type`);
}
}
-
-async function getWordpressClient() {
- const { createWordpressClient } = await import(
- '../../wordpress/src/wp-client'
- );
-
- return createWordpressClient();
-}
-
-async function getKeystaticClient() {
- if (
- process.env.NEXT_RUNTIME === 'nodejs' ||
- process.env.KEYSTATIC_STORAGE_KIND !== 'local'
- ) {
- const { createKeystaticClient } = await import(
- '../../keystatic/src/keystatic-client'
- );
-
- return createKeystaticClient();
- }
-
- console.error(
- `[CMS] Keystatic client using "Local" mode is only available in Node.js runtime. Please choose a different CMS client. Returning a mock client instead of throwing an error.`,
- );
-
- return mockCMSClient() as unknown as CmsClient;
-}
-
-function mockCMSClient() {
- return {
- getContentItems() {
- return Promise.resolve({
- items: [],
- total: 0,
- });
- },
- getContentItemBySlug() {
- return Promise.resolve(undefined);
- },
- };
-}
diff --git a/packages/cms/core/src/index.ts b/packages/cms/core/src/index.ts
index 3f75ccf29..3963ccfae 100644
--- a/packages/cms/core/src/index.ts
+++ b/packages/cms/core/src/index.ts
@@ -1,4 +1,6 @@
-export * from './cms-client';
+import { Cms } from '@kit/cms-types';
+
export * from './create-cms-client';
-export * from './cms.type';
export * from './content-renderer';
+
+export type { Cms };
diff --git a/packages/cms/keystatic/package.json b/packages/cms/keystatic/package.json
index 8b268aec4..1729d1dab 100644
--- a/packages/cms/keystatic/package.json
+++ b/packages/cms/keystatic/package.json
@@ -11,6 +11,7 @@
"prettier": "@kit/prettier-config",
"exports": {
".": "./src/index.ts",
+ "./renderer": "./src/content-renderer.tsx",
"./admin": "./src/keystatic-admin.tsx",
"./route-handler": "./src/keystatic-route-handler.ts"
},
@@ -20,7 +21,7 @@
"@markdoc/markdoc": "^0.4.0"
},
"devDependencies": {
- "@kit/cms": "workspace:^",
+ "@kit/cms-types": "workspace:^",
"@kit/eslint-config": "workspace:*",
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
diff --git a/packages/cms/keystatic/src/create-keystatic-cms.ts b/packages/cms/keystatic/src/create-keystatic-cms.ts
new file mode 100644
index 000000000..f8b626e3d
--- /dev/null
+++ b/packages/cms/keystatic/src/create-keystatic-cms.ts
@@ -0,0 +1,37 @@
+import { CmsClient } from '@kit/cms-types';
+
+/**
+ * Creates a new Keystatic client instance.
+ */
+export async function createKeystaticClient() {
+ if (
+ process.env.NEXT_RUNTIME === 'nodejs' ||
+ process.env.KEYSTATIC_STORAGE_KIND !== 'local'
+ ) {
+ const { createKeystaticClient: createClient } = await import(
+ './keystatic-client'
+ );
+
+ return createClient();
+ }
+
+ console.error(
+ `[CMS] Keystatic client using "Local" mode is only available in Node.js runtime. Please choose a different CMS client. Returning a mock client instead of throwing an error.`,
+ );
+
+ return mockCMSClient() as unknown as CmsClient;
+}
+
+function mockCMSClient() {
+ return {
+ getContentItems() {
+ return Promise.resolve({
+ items: [],
+ total: 0,
+ });
+ },
+ getContentItemBySlug() {
+ return Promise.resolve(undefined);
+ },
+ };
+}
diff --git a/packages/cms/keystatic/src/create-reader.ts b/packages/cms/keystatic/src/create-reader.ts
index 1f4cffa6f..c65e00a87 100644
--- a/packages/cms/keystatic/src/create-reader.ts
+++ b/packages/cms/keystatic/src/create-reader.ts
@@ -1,18 +1,22 @@
import { z } from 'zod';
+import { keyStaticConfig } from './keystatic.config';
+
+/**
+ * The kind of storage to use for the Keystatic reader.
+ */
const STORAGE_KIND = process.env.KEYSTATIC_STORAGE_KIND ?? 'local';
/**
- * Create a KeyStatic reader based on the storage kind.
+ * Creates a new Keystatic reader instance.
*/
export async function createKeystaticReader() {
switch (STORAGE_KIND) {
case 'local': {
if (process.env.NEXT_RUNTIME === 'nodejs') {
- const { default: config } = await import('./keystatic.config');
const { createReader } = await import('@keystatic/core/reader');
- return createReader(process.cwd(), config);
+ return createReader(process.cwd(), keyStaticConfig);
} else {
// we should never get here but the compiler requires the check
// to ensure we don't parse the package at build time
@@ -22,11 +26,11 @@ export async function createKeystaticReader() {
case 'github':
case 'cloud': {
- const { default: config } = await import('./keystatic.config');
-
const githubConfig = z
.object({
- token: z.string(),
+ token: z.string({
+ description: 'The GitHub token to use for authentication.',
+ }),
repo: z.custom<`${string}/${string}`>(),
pathPrefix: z.string().optional(),
})
@@ -40,7 +44,7 @@ export async function createKeystaticReader() {
'@keystatic/core/reader/github'
);
- return createGitHubReader(config, githubConfig);
+ return createGitHubReader(keyStaticConfig, githubConfig);
}
default:
diff --git a/packages/cms/keystatic/src/index.ts b/packages/cms/keystatic/src/index.ts
index a08c2867d..394dadc58 100644
--- a/packages/cms/keystatic/src/index.ts
+++ b/packages/cms/keystatic/src/index.ts
@@ -1,3 +1 @@
-export * from './keystatic-client';
-export * from './content-renderer';
-export * from './keystatic.config';
+export * from './create-keystatic-cms';
\ No newline at end of file
diff --git a/packages/cms/keystatic/src/keystatic-admin.tsx b/packages/cms/keystatic/src/keystatic-admin.tsx
index 39b23d171..d8b7a2e7f 100644
--- a/packages/cms/keystatic/src/keystatic-admin.tsx
+++ b/packages/cms/keystatic/src/keystatic-admin.tsx
@@ -2,6 +2,6 @@
import { makePage } from '@keystatic/next/ui/app';
-import config from './keystatic.config';
+import { keyStaticConfig } from './keystatic.config';
-export default makePage(config);
+export default makePage(keyStaticConfig);
diff --git a/packages/cms/keystatic/src/keystatic-client.ts b/packages/cms/keystatic/src/keystatic-client.ts
index bab46f055..27bb399e3 100644
--- a/packages/cms/keystatic/src/keystatic-client.ts
+++ b/packages/cms/keystatic/src/keystatic-client.ts
@@ -1,6 +1,6 @@
import React from 'react';
-import { Cms, CmsClient } from '@kit/cms';
+import { Cms, CmsClient } from '@kit/cms-types';
import { createKeystaticReader } from './create-reader';
import {
diff --git a/packages/cms/keystatic/src/keystatic-route-handler.ts b/packages/cms/keystatic/src/keystatic-route-handler.ts
index 081b1075e..d748415ef 100644
--- a/packages/cms/keystatic/src/keystatic-route-handler.ts
+++ b/packages/cms/keystatic/src/keystatic-route-handler.ts
@@ -1,9 +1,9 @@
import { makeRouteHandler } from '@keystatic/next/route-handler';
-import config from './keystatic.config';
+import { keyStaticConfig } from './keystatic.config';
const handlers = makeRouteHandler({
- config,
+ config: keyStaticConfig,
});
/**
diff --git a/packages/cms/keystatic/src/keystatic.config.ts b/packages/cms/keystatic/src/keystatic.config.ts
index 9716262df..2d208285c 100644
--- a/packages/cms/keystatic/src/keystatic.config.ts
+++ b/packages/cms/keystatic/src/keystatic.config.ts
@@ -43,12 +43,10 @@ const storage = z.union([local, cloud, github]).parse({
pathPrefix: process.env.KEYSTATIC_PATH_PREFIX,
});
-const keyStaticConfig = createKeyStaticConfig(
+export const keyStaticConfig = createKeyStaticConfig(
process.env.NEXT_PUBLIC_KEYSTATIC_CONTENT_PATH ?? '',
);
-export default keyStaticConfig;
-
function getContentField() {
return fields.markdoc({
label: 'Content',
diff --git a/packages/cms/types/README.md b/packages/cms/types/README.md
new file mode 100644
index 000000000..9f552a43e
--- /dev/null
+++ b/packages/cms/types/README.md
@@ -0,0 +1,3 @@
+# CMS - @kit/cms
+
+CMS abstraction layer for the Makerkit framework.
\ No newline at end of file
diff --git a/packages/cms/types/package.json b/packages/cms/types/package.json
new file mode 100644
index 000000000..6ed01784c
--- /dev/null
+++ b/packages/cms/types/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "@kit/cms-types",
+ "private": true,
+ "version": "0.1.0",
+ "scripts": {
+ "clean": "git clean -xdf .turbo node_modules",
+ "format": "prettier --check \"**/*.{ts,tsx}\"",
+ "lint": "eslint .",
+ "typecheck": "tsc --noEmit"
+ },
+ "prettier": "@kit/prettier-config",
+ "exports": {
+ ".": "./src/index.ts"
+ },
+ "devDependencies": {
+ "@kit/eslint-config": "workspace:*",
+ "@kit/prettier-config": "workspace:*",
+ "@kit/tsconfig": "workspace:*"
+ },
+ "eslintConfig": {
+ "root": true,
+ "extends": [
+ "@kit/eslint-config/base",
+ "@kit/eslint-config/react"
+ ]
+ },
+ "typesVersions": {
+ "*": {
+ "*": [
+ "src/*"
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/cms/core/src/cms-client.ts b/packages/cms/types/src/cms-client.ts
similarity index 100%
rename from packages/cms/core/src/cms-client.ts
rename to packages/cms/types/src/cms-client.ts
diff --git a/packages/cms/core/src/cms.type.ts b/packages/cms/types/src/cms.type.ts
similarity index 100%
rename from packages/cms/core/src/cms.type.ts
rename to packages/cms/types/src/cms.type.ts
diff --git a/packages/cms/types/src/index.ts b/packages/cms/types/src/index.ts
new file mode 100644
index 000000000..e24881f8d
--- /dev/null
+++ b/packages/cms/types/src/index.ts
@@ -0,0 +1,2 @@
+export * from './cms-client';
+export * from './cms.type';
\ No newline at end of file
diff --git a/packages/cms/types/tsconfig.json b/packages/cms/types/tsconfig.json
new file mode 100644
index 000000000..c92857ed3
--- /dev/null
+++ b/packages/cms/types/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "@kit/tsconfig/base.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
+ },
+ "include": ["src"],
+ "exclude": ["node_modules"]
+}
diff --git a/packages/cms/wordpress/package.json b/packages/cms/wordpress/package.json
index 773ec4afb..6bbe3f490 100644
--- a/packages/cms/wordpress/package.json
+++ b/packages/cms/wordpress/package.json
@@ -11,15 +11,17 @@
},
"prettier": "@kit/prettier-config",
"exports": {
- ".": "./src/index.ts"
+ ".": "./src/index.ts",
+ "./renderer": "./src/content-renderer.tsx"
},
"devDependencies": {
- "@kit/cms": "workspace:^",
+ "@kit/cms-types": "workspace:^",
"@kit/eslint-config": "workspace:*",
"@kit/prettier-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:^",
"@types/node": "^22.5.2",
+ "@types/react": "^18.3.5",
"wp-types": "^4.66.1"
},
"eslintConfig": {
diff --git a/packages/cms/wordpress/src/content-renderer.tsx b/packages/cms/wordpress/src/content-renderer.tsx
index 7e4578e7f..fd905a567 100644
--- a/packages/cms/wordpress/src/content-renderer.tsx
+++ b/packages/cms/wordpress/src/content-renderer.tsx
@@ -1,3 +1,5 @@
+import React from 'react';
+
export function WordpressContentRenderer(props: { content: unknown }) {
return ;
}
diff --git a/packages/cms/wordpress/src/index.ts b/packages/cms/wordpress/src/index.ts
index a7fab7906..3f535eac4 100644
--- a/packages/cms/wordpress/src/index.ts
+++ b/packages/cms/wordpress/src/index.ts
@@ -1 +1 @@
-export * from './wp-client';
+export * from './wp-client';
\ No newline at end of file
diff --git a/packages/cms/wordpress/src/wp-client.ts b/packages/cms/wordpress/src/wp-client.ts
index 775a599b7..60a7d191e 100644
--- a/packages/cms/wordpress/src/wp-client.ts
+++ b/packages/cms/wordpress/src/wp-client.ts
@@ -5,10 +5,16 @@ import type {
WP_REST_API_Tag,
} from 'wp-types';
-import { Cms, CmsClient } from '@kit/cms';
+import { Cms, CmsClient } from '@kit/cms-types';
import GetTagsOptions = Cms.GetTagsOptions;
+/**
+ * Creates a new WordpressClient instance.
+ *
+ * @param {string} apiUrl - The URL of the Wordpress API.
+ * @returns {WordpressClient} A new WordpressClient instance.
+ */
export function createWordpressClient(
apiUrl = process.env.WORDPRESS_API_URL as string,
) {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2e09d8117..a1dbd27e7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -420,15 +420,24 @@ importers:
packages/cms/core:
devDependencies:
+ '@kit/cms-types':
+ specifier: workspace:^
+ version: link:../types
'@kit/eslint-config':
specifier: workspace:*
version: link:../../../tooling/eslint
+ '@kit/keystatic':
+ specifier: workspace:^
+ version: link:../keystatic
'@kit/prettier-config':
specifier: workspace:*
version: link:../../../tooling/prettier
'@kit/tsconfig':
specifier: workspace:*
version: link:../../../tooling/typescript
+ '@kit/wordpress':
+ specifier: workspace:^
+ version: link:../wordpress
'@types/node':
specifier: ^22.5.2
version: 22.5.2
@@ -445,9 +454,9 @@ importers:
specifier: ^0.4.0
version: 0.4.0(@types/react@18.3.5)(react@18.3.1)
devDependencies:
- '@kit/cms':
+ '@kit/cms-types':
specifier: workspace:^
- version: link:../core
+ version: link:../types
'@kit/eslint-config':
specifier: workspace:*
version: link:../../../tooling/eslint
@@ -473,11 +482,23 @@ importers:
specifier: ^3.23.8
version: 3.23.8
+ packages/cms/types:
+ devDependencies:
+ '@kit/eslint-config':
+ specifier: workspace:*
+ version: link:../../../tooling/eslint
+ '@kit/prettier-config':
+ specifier: workspace:*
+ version: link:../../../tooling/prettier
+ '@kit/tsconfig':
+ specifier: workspace:*
+ version: link:../../../tooling/typescript
+
packages/cms/wordpress:
devDependencies:
- '@kit/cms':
+ '@kit/cms-types':
specifier: workspace:^
- version: link:../core
+ version: link:../types
'@kit/eslint-config':
specifier: workspace:*
version: link:../../../tooling/eslint
@@ -493,6 +514,9 @@ importers:
'@types/node':
specifier: ^22.5.2
version: 22.5.2
+ '@types/react':
+ specifier: ^18.3.5
+ version: 18.3.5
wp-types:
specifier: ^4.66.1
version: 4.66.1