unimal-jp / spear

The spear OSS repository
https://late-cloud-6411.spearly.app
MIT License
10 stars 1 forks source link

Make spear to be changeable the api client via plugin parameter. #189

Closed mantaroh closed 1 year ago

mantaroh commented 1 year ago

Changes

This PR make spear to support the Content Collection (#69). This feature collect content data from local files like mdx, unified eco system files(front-matter). [1][2]

In order to collect the content data from file, we need to replace the sdk-js client on spearly-cms-js-core[3].

This changes contains the two parts:

  1. Change the cms-js-core to be able to inject the sdk-js api client.
  2. Pass the cms-js-core generator to plugin via plugin parameter.

The (1) allow the changing customized client which returning local file. Hence this feature, user can replace the resource data without Spearly CMS. Then user can pass the this customized client via plugin by (2) changes.

After releasing this feature, we can implement the following plugin.

{
        "pluginName": "markdown-client",
        "configuration": null,
        "beforeBuild": async (state, option) => {
          try {
            state.jsGenerator.injectFakeApiClient({
              analytics: {
                pageView: (params) => {
                  console.log("Unimplemented");
                },
              },
              getList: (contentTypeId, params) => {
                console.log("Unimplemented");
              },
              // Generate content from markdown files
              getContent: async (contentTypeId, contentId, params) => {
                const fileStat = await fs.stat(`./data/${contentTypeId}/${contentId}.mdx`)
                const file = await fs.readFile(`./data/${contentTypeId}/${contentId}.mdx`)
                const {attributes, body} = fm(file.toString())
                const bodyHtml = await remark().use(html).process(body);
                const fields = [];
                for (const key of Object.keys(attributes)) {
                  fields.push({
                    key,
                    value: attributes[key]
                  })
                }
                fields.push({
                  key: "body",
                  value: bodyHtml.toString()
                })

                return generateContent(fields, contentId, fileStat.birthtime, fileStat.mtime)
              },
              getContentPreview: (contentTypeId, contentId, previewToken) => {
                console.log("Unimplemented");
              }
            })
          } catch (e) {
            console.error(e)
          }
        },
        "afterBuild": null,
        "bundle": null,
}

[1] https://unifiedjs.com/ [2] https://mdxjs.com/ [3] https://github.com/unimal-jp/spear/issues/69#issuecomment-1694177158


変更点

この PR では Spear 上で Content Collection をサポートさせるようにします(#69)。この機能は mdx や unified エコシステムのファイルのように、ローカルファイルからコンテンツデータを収集します[1][2]。

ファイルからデータを収集するために、 spearly-cms-js-coresdk-js のクライアントを置きかけ出来るようにします[3]。

この変更は2つのパートに分かれています。

  1. cms-js-coresdk-js API クライアントの差し替えを可能にする
  2. cms-js-core の Generator をプラグインのプラグイン引数で渡すようにする

(1) はローカルファイルを返すカスタムされたクライアントを変更できるようにしています。この機能により、ユーザーは Spearly CMS 抜きでリソースデータを置換可能です。
そして、ユーザーはこのカスタムされたクライアントをプラグイン経由で渡すことができます。

この機能をリリース後、以下のような MDX からコンテンツを取得するプラグインを書くことができます。

{
        "pluginName": "markdown-client",
        "configuration": null,
        "beforeBuild": async (state, option) => {
          try {
            state.jsGenerator.injectFakeApiClient({
              analytics: {
                pageView: (params) => {
                  console.log("Unimplemented");
                },
              },
              getList: (contentTypeId, params) => {
                console.log("Unimplemented");
              },
              // Generate content from markdown files
              getContent: async (contentTypeId, contentId, params) => {
                const fileStat = await fs.stat(`./data/${contentTypeId}/${contentId}.mdx`)
                const file = await fs.readFile(`./data/${contentTypeId}/${contentId}.mdx`)
                const {attributes, body} = fm(file.toString())
                const bodyHtml = await remark().use(html).process(body);
                const fields = [];
                for (const key of Object.keys(attributes)) {
                  fields.push({
                    key,
                    value: attributes[key]
                  })
                }
                fields.push({
                  key: "body",
                  value: bodyHtml.toString()
                })

                return generateContent(fields, contentId, fileStat.birthtime, fileStat.mtime)
              },
              getContentPreview: (contentTypeId, contentId, previewToken) => {
                console.log("Unimplemented");
              }
            })
          } catch (e) {
            console.error(e)
          }
        },
        "afterBuild": null,
        "bundle": null,
}

[1] https://unifiedjs.com/ [2] https://mdxjs.com/ [3] https://github.com/unimal-jp/spear/issues/69#issuecomment-1694177158