Refactored CMS packages to remove a circular dependency (#62)
This commit is contained in:
committed by
GitHub
parent
51a40b6d40
commit
d18f810c6e
@@ -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": {
|
||||
|
||||
@@ -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 ? <Renderer content={content} /> : 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 <KeystaticContentRenderer content={content} />;
|
||||
return KeystaticContentRenderer;
|
||||
}
|
||||
|
||||
case 'wordpress': {
|
||||
const { WordpressContentRenderer } = await import(
|
||||
'../../wordpress/src/content-renderer'
|
||||
'@kit/wordpress/renderer'
|
||||
);
|
||||
|
||||
return <WordpressContentRenderer content={content} />;
|
||||
return WordpressContentRenderer;
|
||||
}
|
||||
|
||||
default: {
|
||||
|
||||
@@ -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<CmsClient> {
|
||||
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<CmsClient>} A Promise that resolves to the created CMS client.
|
||||
*/
|
||||
async function cmsClientFactory(type: CmsType): Promise<CmsClient> {
|
||||
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);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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:*",
|
||||
|
||||
37
packages/cms/keystatic/src/create-keystatic-cms.ts
Normal file
37
packages/cms/keystatic/src/create-keystatic-cms.ts
Normal file
@@ -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);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
export * from './keystatic-client';
|
||||
export * from './content-renderer';
|
||||
export * from './keystatic.config';
|
||||
export * from './create-keystatic-cms';
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -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',
|
||||
|
||||
3
packages/cms/types/README.md
Normal file
3
packages/cms/types/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# CMS - @kit/cms
|
||||
|
||||
CMS abstraction layer for the Makerkit framework.
|
||||
34
packages/cms/types/package.json
Normal file
34
packages/cms/types/package.json
Normal file
@@ -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/*"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
2
packages/cms/types/src/index.ts
Normal file
2
packages/cms/types/src/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './cms-client';
|
||||
export * from './cms.type';
|
||||
8
packages/cms/types/tsconfig.json
Normal file
8
packages/cms/types/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@kit/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
@@ -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": {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import React from 'react';
|
||||
|
||||
export function WordpressContentRenderer(props: { content: unknown }) {
|
||||
return <div dangerouslySetInnerHTML={{ __html: props.content as string }} />;
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from './wp-client';
|
||||
export * from './wp-client';
|
||||
@@ -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,
|
||||
) {
|
||||
|
||||
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user