Files
medusa-store/packages/admin/admin-vite-plugin/src/widgets/generate-widget-hash.ts

60 lines
1.7 KiB
TypeScript

import fs from "fs/promises"
import { File, parse, ParseResult, traverse } from "../babel"
import { logger } from "../logger"
import {
generateHash,
getConfigObjectProperties,
getParserOptions,
} from "../utils"
import { getWidgetFilesFromSources } from "./helpers"
export async function generateWidgetHash(
sources: Set<string>
): Promise<string> {
const files = await getWidgetFilesFromSources(sources)
const contents = await Promise.all(files.map(getWidgetContents))
const totalContent = contents
.flatMap(({ config, defaultExport }) => [config, defaultExport])
.filter(Boolean)
.join("")
return generateHash(totalContent)
}
async function getWidgetContents(
file: string
): Promise<{ config: string | null; defaultExport: string | null }> {
const code = await fs.readFile(file, "utf-8")
let ast: ParseResult<File>
try {
ast = parse(code, getParserOptions(file))
} catch (e) {
logger.error(
`An error occurred while parsing the file. Due to the error we cannot validate whether the widget has changed. If your changes aren't correctly reflected try restarting the dev server.`,
{
file,
error: e,
}
)
return { config: null, defaultExport: null }
}
let configContent: string | null = null
let defaultExportContent: string | null = null
traverse(ast, {
ExportNamedDeclaration(path) {
const properties = getConfigObjectProperties(path)
if (properties) {
configContent = code.slice(path.node.start!, path.node.end!)
}
},
ExportDefaultDeclaration(path) {
defaultExportContent = code.slice(path.node.start!, path.node.end!)
},
})
return { config: configContent, defaultExport: defaultExportContent }
}