UNPKG

wcz-layout

Version:

1 lines 11.6 kB
{"version":3,"file":"vite.mjs","names":[],"sources":["../src/models/VaultConfig.ts","../src/lib/vite-plugin.ts"],"sourcesContent":["import z from \"zod\";\n\nexport const VaultConfigSchema = z.object({\n VAULT_ADDRESS: z.url(),\n VAULT_USERNAME: z.string().min(1),\n VAULT_PASSWORD: z.string().min(1),\n VAULT_SECRET_PATH: z.string().min(1),\n VAULT_MOUNT_POINT: z.string().default(\"release\"),\n});\n\nexport type VaultConfig = z.infer<typeof VaultConfigSchema>;\n","import fs from \"node:fs\";\nimport https from \"node:https\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport axios from \"axios\";\nimport { loadEnv } from \"vite\";\nimport { VaultConfigSchema } from \"../models/VaultConfig\";\nimport type { Resource } from \"i18next\";\nimport type { Plugin } from \"vite\";\n\nasync function fetchVaultSecrets(env: Record<string, string>): Promise<Record<string, string>> {\n const config = VaultConfigSchema.parse(env);\n const { VAULT_ADDRESS, VAULT_USERNAME, VAULT_PASSWORD, VAULT_SECRET_PATH, VAULT_MOUNT_POINT } =\n config;\n\n const client = axios.create({\n baseURL: VAULT_ADDRESS,\n httpsAgent: new https.Agent({ rejectUnauthorized: false }),\n });\n\n const { data: loginData } = await client.post(`/v1/auth/userpass/login/${VAULT_USERNAME}`, {\n password: VAULT_PASSWORD,\n });\n\n const { data: secretData } = await client.get(\n `/v1/${VAULT_MOUNT_POINT}/data/${VAULT_SECRET_PATH}`,\n {\n headers: { \"X-Vault-Token\": loginData.auth.client_token },\n },\n );\n\n const secrets = secretData?.data?.data;\n if (!secrets) throw new Error(\"No secrets found\");\n\n return Object.fromEntries(\n Object.entries(secrets).map(([key, value]) => [\n key,\n typeof value === \"string\" ? value : JSON.stringify(value),\n ]),\n );\n}\n\nasync function loadVaultSecrets(command: string): Promise<void> {\n if (command !== \"serve\") return;\n\n const env = loadEnv(\"development\", process.cwd(), \"\");\n if (!env.VAULT_ADDRESS) return;\n\n try {\n const secrets = await fetchVaultSecrets(env);\n Object.entries(secrets).forEach(([key, value]) => {\n process.env[key] = env[key]?.trim() ? env[key] : value;\n });\n } catch (e) {\n console.warn(\"[vite:wcz-layout] Vault failed:\", e instanceof Error ? e.message : e);\n }\n}\n\nfunction loadLocaleResources(localesPath: string, addWatchFile: (path: string) => void): Resource {\n if (!fs.existsSync(localesPath)) fs.mkdirSync(localesPath, { recursive: true });\n\n const enPath = path.join(localesPath, \"en.json\");\n if (!fs.existsSync(enPath)) fs.writeFileSync(enPath, JSON.stringify({}));\n\n const files = fs.readdirSync(localesPath);\n const resources: Resource = {};\n\n for (const file of files.filter((f) => f.endsWith(\".json\"))) {\n const lang = path.basename(file, \".json\");\n const filePath = path.join(localesPath, file);\n try {\n resources[lang] = { translation: JSON.parse(fs.readFileSync(filePath, \"utf-8\")) };\n } catch {\n resources[lang] = { translation: {} };\n }\n addWatchFile(filePath);\n }\n\n return resources;\n}\n\nconst require = createRequire(import.meta.url);\n\nfunction dayjsLocaleImports(resources: Resource): string {\n return Object.keys(resources)\n .map((lang) => lang.toLowerCase())\n .filter((lang) => {\n try {\n require.resolve(`dayjs/locale/${lang}.js`);\n return true;\n } catch {\n return false;\n }\n })\n .map((lang) => `import \"dayjs/locale/${lang}\";`)\n .join(\"\\n\");\n}\n\nfunction ensurePermissionsFile(\n permissionsPath: string,\n addWatchFile: (path: string) => void,\n): void {\n const dir = path.dirname(permissionsPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n if (!fs.existsSync(permissionsPath)) {\n fs.writeFileSync(\n permissionsPath,\n 'export const permissions = {\\n admin: [\"wcz-developers\"]\\n} as const;',\n );\n }\n addWatchFile(permissionsPath);\n}\n\nfunction ensureScopesFile(scopesPath: string, addWatchFile: (path: string) => void): void {\n const dir = path.dirname(scopesPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n if (!fs.existsSync(scopesPath)) {\n fs.writeFileSync(scopesPath, \"export const scopes = {\\n} as const;\");\n }\n addWatchFile(scopesPath);\n}\n\nfunction loadManifest(\n manifestPath: string,\n addWatchFile: (path: string) => void,\n): { name: string } & Record<string, unknown> {\n addWatchFile(manifestPath);\n try {\n return JSON.parse(fs.readFileSync(manifestPath, \"utf-8\"));\n } catch {\n return { name: \"\" };\n }\n}\n\nexport function viteWczLayout(): Plugin {\n const virtualModuleId = \"virtual:wcz-layout\";\n const resolvedVirtualModuleId = \"\\0\" + virtualModuleId;\n\n let localesPath: string;\n let permissionsPath: string;\n let scopesPath: string;\n let envPath: string;\n let manifestPath: string;\n\n return {\n name: \"vite:wcz-layout\",\n enforce: \"pre\",\n configResolved(resolvedConfig) {\n localesPath = path.resolve(resolvedConfig.root, \"src/lib/locales\");\n permissionsPath = path.resolve(resolvedConfig.root, \"src/lib/auth/permissions.ts\");\n scopesPath = path.resolve(resolvedConfig.root, \"src/lib/auth/scopes.ts\");\n envPath = path.resolve(resolvedConfig.root, \"src/env.ts\");\n manifestPath = path.resolve(resolvedConfig.root, \"public/manifest.json\");\n },\n async config(_, { command }) {\n await loadVaultSecrets(command);\n },\n configureServer(server) {\n const refresh = (filePath: string) => {\n if (\n filePath.includes(localesPath) ||\n filePath === permissionsPath ||\n filePath === scopesPath ||\n filePath === envPath ||\n filePath === manifestPath\n ) {\n const module = server.moduleGraph.getModuleById(resolvedVirtualModuleId);\n if (module) server.moduleGraph.invalidateModule(module);\n server.ws.send({ type: \"full-reload\", path: \"*\" });\n }\n };\n\n server.watcher.add([localesPath, permissionsPath, scopesPath, envPath, manifestPath]);\n server.watcher.on(\"add\", refresh);\n server.watcher.on(\"change\", refresh);\n server.watcher.on(\"unlink\", refresh);\n },\n resolveId(id) {\n if (id === virtualModuleId) return resolvedVirtualModuleId;\n return null;\n },\n load(id) {\n if (id !== resolvedVirtualModuleId) return null;\n\n const resources = loadLocaleResources(localesPath, this.addWatchFile.bind(this));\n ensurePermissionsFile(permissionsPath, this.addWatchFile.bind(this));\n ensureScopesFile(scopesPath, this.addWatchFile.bind(this));\n const manifest = loadManifest(manifestPath, this.addWatchFile.bind(this));\n\n const normalizedPermissionsPath = permissionsPath.split(path.sep).join(path.posix.sep);\n const normalizedScopesPath = scopesPath.split(path.sep).join(path.posix.sep);\n const normalizedEnvPath = envPath.split(path.sep).join(path.posix.sep);\n return `\n ${dayjsLocaleImports(resources)}\n export const resources = ${JSON.stringify(resources)};\n export const manifest = ${JSON.stringify(manifest)};\n export { permissions } from \"${normalizedPermissionsPath}\";\n export { scopes } from \"${normalizedScopesPath}\";\n export { serverEnv } from \"${normalizedEnvPath}\";\n `;\n },\n };\n}\n"],"mappings":";;;;;;;;AAEA,MAAa,oBAAoB,EAAE,OAAO;CACxC,eAAe,EAAE,IAAI;CACrB,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CAChC,gBAAgB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CAChC,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACnC,mBAAmB,EAAE,OAAO,CAAC,CAAC,QAAQ,SAAS;AACjD,CAAC;;;ACED,eAAe,kBAAkB,KAA8D;CAE7F,MAAM,EAAE,eAAe,gBAAgB,gBAAgB,mBAAmB,sBAD3D,kBAAkB,MAAM,GAErC;CAEF,MAAM,SAAS,MAAM,OAAO;EAC1B,SAAS;EACT,YAAY,IAAI,MAAM,MAAM,EAAE,oBAAoB,MAAM,CAAC;CAC3D,CAAC;CAED,MAAM,EAAE,MAAM,cAAc,MAAM,OAAO,KAAK,2BAA2B,kBAAkB,EACzF,UAAU,eACZ,CAAC;CAED,MAAM,EAAE,MAAM,eAAe,MAAM,OAAO,IACxC,OAAO,kBAAiB,QAAS,qBACjC,EACE,SAAS,EAAE,iBAAiB,UAAU,KAAK,aAAa,EAC1D,CACF;CAEA,MAAM,UAAU,YAAY,MAAM;CAClC,IAAI,CAAC,SAAS,MAAM,IAAI,MAAM,kBAAkB;CAEhD,OAAO,OAAO,YACZ,OAAO,QAAQ,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAC5C,KACA,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK,CAAC,CAC1D,CACH;AACF;AAEA,eAAe,iBAAiB,SAAgC;CAC9D,IAAI,YAAY,SAAS;CAEzB,MAAM,MAAM,QAAQ,eAAe,QAAQ,IAAI,GAAG,EAAE;CACpD,IAAI,CAAC,IAAI,eAAe;CAExB,IAAI;EACF,MAAM,UAAU,MAAM,kBAAkB,GAAG;EAC3C,OAAO,QAAQ,OAAO,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;GAChD,QAAQ,IAAI,OAAO,IAAI,IAAI,EAAE,KAAK,IAAI,IAAI,OAAO;EACnD,CAAC;CACH,SAAS,GAAG;EACV,QAAQ,KAAK,mCAAmC,aAAa,QAAQ,EAAE,UAAU,CAAC;CACpF;AACF;AAEA,SAAS,oBAAoB,aAAqB,cAAgD;CAChG,IAAI,CAAC,GAAG,WAAW,WAAW,GAAG,GAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;CAE9E,MAAM,SAAS,KAAK,KAAK,aAAa,SAAS;CAC/C,IAAI,CAAC,GAAG,WAAW,MAAM,GAAG,GAAG,cAAc,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC;CAEvE,MAAM,QAAQ,GAAG,YAAY,WAAW;CACxC,MAAM,YAAsB,CAAC;CAE7B,KAAK,MAAM,QAAQ,MAAM,QAAQ,MAAM,EAAE,SAAS,OAAO,CAAC,GAAG;EAC3D,MAAM,OAAO,KAAK,SAAS,MAAM,OAAO;EACxC,MAAM,WAAW,KAAK,KAAK,aAAa,IAAI;EAC5C,IAAI;GACF,UAAU,QAAQ,EAAE,aAAa,KAAK,MAAM,GAAG,aAAa,UAAU,OAAO,CAAC,EAAE;EAClF,QAAQ;GACN,UAAU,QAAQ,EAAE,aAAa,CAAC,EAAE;EACtC;EACA,aAAa,QAAQ;CACvB;CAEA,OAAO;AACT;AAEA,MAAM,UAAU,cAAc,YAAY,GAAG;AAE7C,SAAS,mBAAmB,WAA6B;CACvD,OAAO,OAAO,KAAK,SAAS,CAAC,CAC1B,KAAK,SAAS,KAAK,YAAY,CAAC,CAAC,CACjC,QAAQ,SAAS;EAChB,IAAI;GACF,QAAQ,QAAQ,gBAAgB,KAAI,IAAK;GACzC,OAAO;EACT,QAAQ;GACN,OAAO;EACT;CACF,CAAC,CAAC,CACD,KAAK,SAAS,wBAAwB,KAAI,GAAI,CAAC,CAC/C,KAAK,IAAI;AACd;AAEA,SAAS,sBACP,iBACA,cACM;CACN,MAAM,MAAM,KAAK,QAAQ,eAAe;CACxC,IAAI,CAAC,GAAG,WAAW,GAAG,GAAG,GAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;CAC9D,IAAI,CAAC,GAAG,WAAW,eAAe,GAChC,GAAG,cACD,iBACA,0EACF;CAEF,aAAa,eAAe;AAC9B;AAEA,SAAS,iBAAiB,YAAoB,cAA4C;CACxF,MAAM,MAAM,KAAK,QAAQ,UAAU;CACnC,IAAI,CAAC,GAAG,WAAW,GAAG,GAAG,GAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;CAC9D,IAAI,CAAC,GAAG,WAAW,UAAU,GAC3B,GAAG,cAAc,YAAY,sCAAsC;CAErE,aAAa,UAAU;AACzB;AAEA,SAAS,aACP,cACA,cAC4C;CAC5C,aAAa,YAAY;CACzB,IAAI;EACF,OAAO,KAAK,MAAM,GAAG,aAAa,cAAc,OAAO,CAAC;CAC1D,QAAQ;EACN,OAAO,EAAE,MAAM,GAAG;CACpB;AACF;AAEA,SAAgB,gBAAwB;CACtC,MAAM,kBAAkB;CACxB,MAAM,0BAA0B;CAEhC,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,OAAO;EACL,MAAM;EACN,SAAS;EACT,eAAe,gBAAgB;GAC7B,cAAc,KAAK,QAAQ,eAAe,MAAM,iBAAiB;GACjE,kBAAkB,KAAK,QAAQ,eAAe,MAAM,6BAA6B;GACjF,aAAa,KAAK,QAAQ,eAAe,MAAM,wBAAwB;GACvE,UAAU,KAAK,QAAQ,eAAe,MAAM,YAAY;GACxD,eAAe,KAAK,QAAQ,eAAe,MAAM,sBAAsB;EACzE;EACA,MAAM,OAAO,GAAG,EAAE,WAAW;GAC3B,MAAM,iBAAiB,OAAO;EAChC;EACA,gBAAgB,QAAQ;GACtB,MAAM,WAAW,aAAqB;IACpC,IACE,SAAS,SAAS,WAAW,KAC7B,aAAa,mBACb,aAAa,cACb,aAAa,WACb,aAAa,cACb;KACA,MAAM,SAAS,OAAO,YAAY,cAAc,uBAAuB;KACvE,IAAI,QAAQ,OAAO,YAAY,iBAAiB,MAAM;KACtD,OAAO,GAAG,KAAK;MAAE,MAAM;MAAe,MAAM;KAAI,CAAC;IACnD;GACF;GAEA,OAAO,QAAQ,IAAI;IAAC;IAAa;IAAiB;IAAY;IAAS;GAAY,CAAC;GACpF,OAAO,QAAQ,GAAG,OAAO,OAAO;GAChC,OAAO,QAAQ,GAAG,UAAU,OAAO;GACnC,OAAO,QAAQ,GAAG,UAAU,OAAO;EACrC;EACA,UAAU,IAAI;GACZ,IAAI,OAAO,iBAAiB,OAAO;GACnC,OAAO;EACT;EACA,KAAK,IAAI;GACP,IAAI,OAAO,yBAAyB,OAAO;GAE3C,MAAM,YAAY,oBAAoB,aAAa,KAAK,aAAa,KAAK,IAAI,CAAC;GAC/E,sBAAsB,iBAAiB,KAAK,aAAa,KAAK,IAAI,CAAC;GACnE,iBAAiB,YAAY,KAAK,aAAa,KAAK,IAAI,CAAC;GACzD,MAAM,WAAW,aAAa,cAAc,KAAK,aAAa,KAAK,IAAI,CAAC;GAExE,MAAM,4BAA4B,gBAAgB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG;GACrF,MAAM,uBAAuB,WAAW,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG;GAC3E,MAAM,oBAAoB,QAAQ,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG;GACrE,OAAO;cACC,mBAAmB,SAAS,EAAC;uCACJ,KAAK,UAAU,SAAS,EAAC;sCAC1B,KAAK,UAAU,QAAQ,EAAC;2CACnB,0BAAyB;sCAC9B,qBAAoB;yCACjB,kBAAiB;;EAEtD;CACF;AACF"}