UNPKG

shopify-accelerate

Version:

Shopify Theme development with full Typescript Support

243 lines (226 loc) 7.53 kB
import path from "path"; import { ShopifyBlock, ShopifySettingsInput } from "../../@types/shopify"; import { config } from "../../shopify-accelerate"; import { capitalize } from "../utils/capitalize"; import { writeCompareFile } from "../utils/fs"; export const generateBlocksTypes = () => { const { folders, sources } = config; const sections = sources.blockSchemas; const blockTypesPath = path.join(folders.types, "blocks.ts"); const imports = getImports(sections); let sectionUnionType = "export type ThemeBlocks ="; let typeContent = ""; for (const key in sections) { const schema = sections[key] as ShopifyBlock; typeContent += `${blockToTypes(schema, key)}\n`; sectionUnionType += `\n | ${capitalize(key)}Block`; } if (!typeContent) return; const finalContent = `${imports + typeContent + sectionUnionType};\n`; writeCompareFile(blockTypesPath, finalContent); }; export const getImports = (sections: { [T: string]: ShopifyBlock }) => { const localTypes = []; const analyseSetting = (setting) => { if (setting.type === "richtext") { if (localTypes.includes("_BlockTag")) return; localTypes.push("_BlockTag"); } if (setting.type === "article") { if (localTypes.includes("_Article_liquid")) return; localTypes.push("_Article_liquid"); } if (setting.type === "blog") { if (localTypes.includes("_Blog_liquid")) return; localTypes.push("_Blog_liquid"); } if (setting.type === "collection" && !setting.id.includes("__handle_only")) { if (localTypes.includes("_Collection_liquid")) return; localTypes.push("_Collection_liquid"); } if (setting.type === "collection_list" && !setting.id.includes("__handle_only")) { if (localTypes.includes("_Collection_liquid")) return; localTypes.push("_Collection_liquid"); } if (setting.type === "color") { if (localTypes.includes("_Color_liquid")) return; localTypes.push("_Color_liquid"); } if (setting.type === "image_picker") { if (localTypes.includes("_Image_liquid")) return; localTypes.push("_Image_liquid"); } if (setting.type === "font_picker") { if (localTypes.includes("_Font_liquid")) return; localTypes.push("_Font_liquid"); } if (setting.type === "font_picker") { if (localTypes.includes("_Font_options")) return; localTypes.push("_Font_options"); } if (setting.type === "link_list") { if (localTypes.includes("_Linklist_liquid")) return; localTypes.push("_Linklist_liquid"); } if (setting.type === "page") { if (localTypes.includes("_Page_liquid")) return; localTypes.push("_Page_liquid"); } if (setting.type === "product" && !setting.id.includes("__handle_only")) { if (localTypes.includes("_Product_liquid")) return; localTypes.push("_Product_liquid"); } if (setting.type === "product_list" && !setting.id.includes("__handle_only")) { if (localTypes.includes("_Product_liquid")) return; localTypes.push("_Product_liquid"); } if (setting.type === "video") { if (localTypes.includes("_Video_liquid")) return; localTypes.push("_Video_liquid"); } }; for (const key in sections) { const schema = sections[key]; schema.settings?.forEach(analyseSetting, localTypes); schema.blocks?.forEach((block) => { block?.settings?.forEach(analyseSetting, localTypes); }); } if (localTypes.length) { return `import { ${localTypes.join(", ")} } from "./shopify";\n\n`; } return ``; }; export const blockToTypes = (section, key) => { const filename = section.folder; const arr = []; const settings: ShopifySettingsInput[] = section.settings ?.filter((s) => s.type !== "header" && s.type !== "paragraph") .sort((a, b) => (a.id > b.id ? 1 : a.id < b.id ? -1 : 0)); arr.push(`export type ${capitalize(key)}Block = {`); if (section.blocks?.some((block) => block.type === "@theme")) { arr.push(` blocks: ThemeBlocks[];`); } arr.push(` id${config.headless ? "?" : ""}: string;`); if (settings?.length) { arr.push(` settings: {`); arr.push( settings .map( (setting) => ` /** Input type: ${setting.type} */\n ` + `${/[^\w_]/gi.test(setting.id) ? `"${setting.id}"` : `${setting.id}`}${getSettingsType( setting )};` ) .sort((a, b) => { const aX = a.split("\n")[1]; const bX = b.split("\n")[1]; if (aX.includes("?") && !bX.includes("?")) { return 1; } else if (!aX.includes("?") && bX.includes("?")) { return -1; } else if (aX > bX) { return 1; } else if (aX < bX) { return -1; } else { return 0; } }) .join("\n") ); arr.push(` };`); } arr.push(` type: "${filename}";`); arr.push(`};`); arr.push(""); return arr.join("\n"); }; export const getSettingsType = (setting: ShopifySettingsInput) => { switch (setting.type) { case "article": return "?: _Article_liquid | string"; case "checkbox": return ": boolean"; case "number": return "?: number"; case "radio": return `: ${setting.options.map(({ value }) => `"${value}"`).join(" | ")}`; case "range": return ": number"; case "select": return `: ${setting.options.map(({ value }) => `"${value}"`).join(" | ")}`; case "text": return "?: string"; case "textarea": return "?: string"; case "blog": return "?: _Blog_liquid | string"; case "collection": { if (setting.id.includes("__handle_only")) { return "?: string"; } return "?: _Collection_liquid"; } case "collection_list": { if (setting.id.includes("__handle_only")) { return "?: string[]"; } return "?: _Collection_liquid[]"; } case "color": return "?: _Color_liquid | string"; case "color_background": return "?: string"; case "font_picker": return ": _Font_liquid | _Font_options"; case "html": return "?: string"; case "image_picker": return "?: _Image_liquid | string"; case "link_list": return "?: _Linklist_liquid"; case "liquid": return "?: string"; case "page": return "?: _Page_liquid | string"; case "product": { if (setting.id.includes("__handle_only")) { return "?: string"; } return "?: _Product_liquid"; } case "product_list": { if (setting.id.includes("__handle_only")) { return "?: string[]"; } return "?: _Product_liquid[]"; } case "color_scheme_group": return `?: {\n [T:string]: {${setting.definition .map((option) => { if ("id" in option) { return `\n ${option.id}: string;`; } return ""; }) .join("")}\n }\n }`; case "richtext": return "?: `<${_BlockTag}${string}</${_BlockTag}>`"; case "inline_richtext": return "?: string"; case "url": return "?: string"; case "video": return "?: _Video_liquid"; case "video_url": return "?: `${string}youtube${string}` | `${string}vimeo${string}`"; case "font": return "?: string"; case "color_scheme": return "?: string"; case "text_alignment": return `: "left" | "center" | "right"`; } };