Skip to content

Commit

Permalink
Make spear to be changeable the api client via plugin parameter. (#189)
Browse files Browse the repository at this point in the history
* Enable Api Client to be changeable

* Pass cms-js-core genrator to plugin via parameter

* drop unnecessary function of declaration
  • Loading branch information
mantaroh authored Aug 29, 2023
1 parent fe102ff commit c7502f2
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 34 deletions.
16 changes: 8 additions & 8 deletions packages/spear-cli/src/browser/InMemoryMagic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ export default async function inMemoryMagic(
const logger = new SpearLog(settings.quiteMode);
settings.targetPagesPathList = settings.targetPagesPathList || [];

const jsGenerator = new SpearlyJSGenerator(
settings.spearlyAuthKey,
settings.apiDomain,
settings.analysysDomain || "analytics.spearly.com",
);
let state: State = {
pagesList: [],
componentsList: [],
Expand All @@ -36,6 +31,11 @@ export default async function inMemoryMagic(
out: {
assetsFiles: [],
},
jsGenerator: new SpearlyJSGenerator(
settings.spearlyAuthKey,
settings.apiDomain,
settings.analysysDomain || "analytics.spearly.com",
)
};

// If directory has the same name, it will be removed.
Expand Down Expand Up @@ -114,7 +114,7 @@ export default async function inMemoryMagic(
const parsedNode = (await parseElements(
state,
component.node.childNodes as Element[],
jsGenerator,
state.jsGenerator,
settings
)) as Element[];
componentsList.push({
Expand All @@ -132,7 +132,7 @@ export default async function inMemoryMagic(
page.node.childNodes = await parseElements(
state,
page.node.childNodes as Element[],
jsGenerator,
state.jsGenerator,
settings
);
}
Expand Down Expand Up @@ -167,7 +167,7 @@ export default async function inMemoryMagic(
}

// generate static routing files.
state.pagesList = await generateAliasPagesFromPagesList(state, jsGenerator, settings);
state.pagesList = await generateAliasPagesFromPagesList(state, state.jsGenerator, settings);

// Embed assets
const asettsUrlAndRaw: {[key: string]: string} = {};
Expand Down
2 changes: 2 additions & 0 deletions packages/spear-cli/src/interfaces/HookCallbackInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DefaultSettings } from "./SettingsInterfaces"
import { HTMLElement } from "node-html-parser"
import { FileUtil } from "../utils/file"
import { SpearLog } from "../utils/log"
import { SpearlyJSGenerator } from "@spearly/cms-js-core"

export type SpearSettings = DefaultSettings

Expand All @@ -28,6 +29,7 @@ export interface SpearState {
out: {
assetsFiles: AssetFile[]
}
jsGenerator: SpearlyJSGenerator
}

export interface SpearOption {
Expand Down
2 changes: 2 additions & 0 deletions packages/spear-cli/src/interfaces/MagicInterfaces.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SpearlyJSGenerator } from "@spearly/cms-js-core"
import { HTMLElement } from "node-html-parser"

export type Element = HTMLElement & { props: { [key: string]: string } }
Expand All @@ -23,6 +24,7 @@ export interface State {
out: {
assetsFiles: AssetFile[]
}
jsGenerator: SpearlyJSGenerator
}

export interface SiteMapURL {
Expand Down
13 changes: 6 additions & 7 deletions packages/spear-cli/src/magic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const fileUtil = new FileUtil(new LocalFileManipulator(), logger)

let dirname = process.cwd()
let Settings: DefaultSettings
let jsGenerator: SpearlyJSGenerator

function initializeArgument(args: Args) {
if (args.src) {
Expand Down Expand Up @@ -59,9 +58,9 @@ async function bundle(): Promise<boolean> {
out: {
assetsFiles: [],
},
}

jsGenerator = new SpearlyJSGenerator(Settings.spearlyAuthKey, Settings.apiDomain, Settings.analysysDomain)
jsGenerator: new SpearlyJSGenerator(Settings.spearlyAuthKey, Settings.apiDomain, Settings.analysysDomain)
}

// Hook API: beforeBuild
for (const plugin of Settings.plugins) {
Expand Down Expand Up @@ -105,7 +104,7 @@ async function bundle(): Promise<boolean> {
// Due to support nested components.
const componentsList = [] as Component[]
for (const component of state.componentsList) {
const parsedNode = await parseElements(state, component.node.childNodes as Element[], jsGenerator, Settings) as Element[]
const parsedNode = await parseElements(state, component.node.childNodes as Element[], state.jsGenerator, Settings) as Element[]
componentsList.push({
"fname": component.fname,
"rawData": parsedNode[0].outerHTML,
Expand All @@ -118,13 +117,13 @@ async function bundle(): Promise<boolean> {

// Run list again to parse children of the pages
for (const page of state.pagesList) {
page.node.childNodes = await parseElements(state, page.node.childNodes as Element[], jsGenerator, Settings)
page.node.childNodes = await parseElements(state, page.node.childNodes as Element[], state.jsGenerator, Settings)
// We need to parseElement twice due to embed nested component.
page.node.childNodes = await parseElements(state, page.node.childNodes as Element[], jsGenerator, Settings)
page.node.childNodes = await parseElements(state, page.node.childNodes as Element[], state.jsGenerator, Settings)
}

// generate static routing files.
state.pagesList = await generateAliasPagesFromPagesList(state, jsGenerator, Settings)
state.pagesList = await generateAliasPagesFromPagesList(state, state.jsGenerator, Settings)

// Hook API: afterBuild
for (const plugin of Settings.plugins) {
Expand Down
3 changes: 2 additions & 1 deletion packages/spear-cli/src/utils/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export function stateDeepCopy(state: State): State {
globalProps: JSON.parse(JSON.stringify(state.globalProps)),
out: {
assetsFiles: assetsDeepCopy(state.out.assetsFiles)
}
},
jsGenerator: state.jsGenerator,
}
}

Expand Down
57 changes: 39 additions & 18 deletions packages/spearly-cms-js-core/src/Generator.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,69 @@
import { HTMLElement, Node, parse } from 'node-html-parser';
import { FieldTypeTags, SpearlyApiClient } from '@spearly/sdk-js';
import getFieldsValuesDefinitions, { generateGetParamsFromAPIOptions, getCustomDateString, ReplaceDefinition } from './Utils.js'
import type { AnalyticsPostParams, Content } from '@spearly/sdk-js'
import type { AnalyticsPostParams, Content, List } from '@spearly/sdk-js'

/**
* FakeSpearlyApiClient is a fake implementation of SpearlyApiClient.
* We can inject api client for using local file system, like markdown files.
*/
export interface FakeSpearlyApiClient {
analytics: {
pageView: (params: any) => Promise<void>;
};
getList(contentTypeId: string, params?: any): Promise<List>;
getContent(contentTypeId: string, contentId: string, params?: any): Promise<Content>;
getContentPreview(contentTypeId: string, contentId: string, previewToken: string): Promise<Content>;
}

export type DateFormatter = (date: Date, dateOnly?: boolean) => string

export type SpearlyJSGeneratorOption = {
linkBaseUrl: string | undefined;
dateFormatter: DateFormatter | undefined;
}
type SpearlyJSGeneratorInternalOption = {
linkBaseUrl: string;
dateFormatter: DateFormatter;
}

export type GetContentOption = {
patternName: string,
previewToken?: string,
}

export type GeneratedContent = {
alias : string,
generatedHtml: string,
tag: string[],
}

export type GeneratedListContent = {
generatedHtml: string,
tag: string
}

export type APIOption = Map<string, string | Date | number | string[] | { [key: string]: string | string[] } >

type SpearlyJSGeneratorInternalOption = {
linkBaseUrl: string;
dateFormatter: DateFormatter;
}

export class SpearlyJSGenerator {
client: SpearlyApiClient
client: SpearlyApiClient | FakeSpearlyApiClient
options: SpearlyJSGeneratorInternalOption

constructor(apiKey: string, domain: string, analyticsDomain: string, options: SpearlyJSGeneratorOption | undefined = undefined) {
this.client = new SpearlyApiClient(apiKey, domain, analyticsDomain)
this.options = {
linkBaseUrl: options?.linkBaseUrl || "",
dateFormatter: options?.dateFormatter || function japaneseDateFormatter(date: Date, dateOnly?: boolean) {
dateFormatter: options?.dateFormatter || function japaneseDateFormatter(date: Date, dateOnly?: boolean) {
return getCustomDateString(`YYYY年MM月DD日${!dateOnly ? " hh時mm分ss秒" : ""}`, date)
}
}
}

injectFakeApiClient(fakeClient: FakeSpearlyApiClient) {
this.client = fakeClient;
}

convertFromFieldsValueDefinitions(templateHtml: string, replacementArray: ReplaceDefinition[], content: Content, contentType: string): string {
let result = templateHtml
replacementArray.forEach(r => {
Expand All @@ -60,7 +81,7 @@ export class SpearlyJSGenerator {

const linkMatchResult = result.match(`{%= ${contentType}_#link %}`)
if (!!linkMatchResult && linkMatchResult.length > 0) {
result = result.split(linkMatchResult[0]).join("./" + this.options.linkBaseUrl + "?contentId=" + alias);
result = result.split(linkMatchResult[0]).join("./" + this.options.linkBaseUrl + "?contentId=" + alias);
}

const aliasMatchResult = result.match(`{%= ${contentType}_#alias %}`)
Expand Down Expand Up @@ -91,16 +112,16 @@ export class SpearlyJSGenerator {
return result
}

async generateContent(templateHtml: string, contentType: string, contentId: string, option: GetContentOption, insertDebugInfo: boolean): Promise<[html: string, uid:string, patternName: string | null]> {
async generateContent(templateHtml: string, contentType: string, contentId: string, option: GetContentOption, insertDebugInfo: boolean): Promise<[html: string, uid: string, patternName: string | null]> {
try {
const result = option.previewToken
? await this.client.getContentPreview(contentType, contentId, option.previewToken)
: await this.client.getContent(contentType, contentId,
option.patternName
? {
patternName: option.patternName
}
: {}
? {
patternName: option.patternName
}
: {}
);
const replacementArray = getFieldsValuesDefinitions(result.attributes.fields.data, contentType, 2, true, this.options.dateFormatter, insertDebugInfo);
const uid = result.attributes.publicUid;
Expand Down Expand Up @@ -132,7 +153,7 @@ export class SpearlyJSGenerator {
}
if (node.childNodes.length > 0) {
node.childNodes = await this.traverseInjectionSubLoop(node.childNodes as HTMLElement[], apiOptions, insertDebugInfo)
}
}
resultNode.appendChild(node)
}
return resultNode.childNodes
Expand All @@ -153,7 +174,7 @@ export class SpearlyJSGenerator {
const result = await this.client.getList(contentType, generateGetParamsFromAPIOptions(apiOptions))
let resultHtml = ""
result.data.forEach(c => {
const replacementArray = getFieldsValuesDefinitions(c.attributes.fields.data, variableName || contentType, 2, true, this.options.dateFormatter, insertDebugInfo);
const replacementArray = getFieldsValuesDefinitions(c.attributes.fields.data, variableName || contentType, 2, true, this.options.dateFormatter, insertDebugInfo);
resultHtml += this.convertFromFieldsValueDefinitions(templateHtml, replacementArray, c, contentType)
})

Expand Down Expand Up @@ -190,7 +211,7 @@ export class SpearlyJSGenerator {
})
let resultHtml = ""
targetContents.forEach(c => {
const replacementArray = getFieldsValuesDefinitions(c.attributes.fields.data, variableName || contentType, 2, true, this.options.dateFormatter, insertDebugInfo);
const replacementArray = getFieldsValuesDefinitions(c.attributes.fields.data, variableName || contentType, 2, true, this.options.dateFormatter, insertDebugInfo);
// Special replacement string
replacementArray.push({
definitionString: `{%= ${contentType}_#tag %}`,
Expand All @@ -204,12 +225,12 @@ export class SpearlyJSGenerator {
})
})
return contentsByTag
} catch(e) {
} catch (e) {
return Promise.reject(e)
}
}

async generateEachContentFromList(templateHtml: string, contentType: string, apiOptions: APIOption, tagFieldName: string, insertDebugInfo: boolean) : Promise<GeneratedContent[]> {
async generateEachContentFromList(templateHtml: string, contentType: string, apiOptions: APIOption, tagFieldName: string, insertDebugInfo: boolean): Promise<GeneratedContent[]> {
try {
const generatedContents: GeneratedContent[] = []
const result = await this.client.getList(contentType, generateGetParamsFromAPIOptions(apiOptions))
Expand Down

0 comments on commit c7502f2

Please sign in to comment.