UNPKG

wcz-layout

Version:

1 lines 13.4 kB
{"version":3,"file":"vite.mjs","names":["z","VaultConfigSchema","object","VAULT_ADDRESS","url","VAULT_USERNAME","string","min","VAULT_PASSWORD","VAULT_SECRET_PATH","VAULT_MOUNT_POINT","default","VaultConfig","infer","fs","https","path","axios","loadEnv","VaultConfigSchema","Resource","Plugin","fetchVaultSecrets","env","Record","Promise","config","parse","VAULT_ADDRESS","VAULT_USERNAME","VAULT_PASSWORD","VAULT_SECRET_PATH","VAULT_MOUNT_POINT","client","create","baseURL","httpsAgent","Agent","rejectUnauthorized","data","loginData","post","password","secretData","get","headers","auth","client_token","secrets","Error","Object","fromEntries","entries","map","key","value","JSON","stringify","loadVaultSecrets","command","process","cwd","forEach","trim","e","console","warn","message","loadLocaleResources","localesPath","addWatchFile","existsSync","mkdirSync","recursive","enPath","join","writeFileSync","files","readdirSync","resources","file","filter","f","endsWith","lang","basename","filePath","translation","readFileSync","ensurePermissionsFile","permissionsPath","dir","dirname","ensureScopesFile","scopesPath","loadManifest","manifestPath","name","viteWczLayout","virtualModuleId","resolvedVirtualModuleId","envPath","enforce","configResolved","resolvedConfig","resolve","root","_","ssr","noExternal","configureServer","server","refresh","includes","module","moduleGraph","getModuleById","invalidateModule","ws","send","type","watcher","add","on","resolveId","id","load","bind","manifest","normalizedPermissionsPath","split","sep","posix","normalizedScopesPath","normalizedEnvPath"],"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\";\r\nimport https from \"node:https\";\r\nimport path from \"node:path\";\r\nimport axios from \"axios\";\r\nimport { loadEnv } from \"vite\";\r\nimport { VaultConfigSchema } from \"../models/VaultConfig\";\r\nimport type { Resource } from \"i18next\";\r\nimport type { Plugin } from \"vite\";\r\n\r\nasync function fetchVaultSecrets(env: Record<string, string>): Promise<Record<string, string>> {\r\n const config = VaultConfigSchema.parse(env);\r\n const { VAULT_ADDRESS, VAULT_USERNAME, VAULT_PASSWORD, VAULT_SECRET_PATH, VAULT_MOUNT_POINT } =\r\n config;\r\n\r\n const client = axios.create({\r\n baseURL: VAULT_ADDRESS,\r\n httpsAgent: new https.Agent({ rejectUnauthorized: false }),\r\n });\r\n\r\n const { data: loginData } = await client.post(`/v1/auth/userpass/login/${VAULT_USERNAME}`, {\r\n password: VAULT_PASSWORD,\r\n });\r\n\r\n const { data: secretData } = await client.get(\r\n `/v1/${VAULT_MOUNT_POINT}/data/${VAULT_SECRET_PATH}`,\r\n {\r\n headers: { \"X-Vault-Token\": loginData.auth.client_token },\r\n },\r\n );\r\n\r\n const secrets = secretData?.data?.data;\r\n if (!secrets) throw new Error(\"No secrets found\");\r\n\r\n return Object.fromEntries(\r\n Object.entries(secrets).map(([key, value]) => [\r\n key,\r\n typeof value === \"string\" ? value : JSON.stringify(value),\r\n ]),\r\n );\r\n}\r\n\r\nasync function loadVaultSecrets(command: string): Promise<void> {\r\n if (command !== \"serve\") return;\r\n\r\n const env = loadEnv(\"development\", process.cwd(), \"\");\r\n if (!env.VAULT_ADDRESS) return;\r\n\r\n try {\r\n const secrets = await fetchVaultSecrets(env);\r\n Object.entries(secrets).forEach(([key, value]) => {\r\n process.env[key] = env[key]?.trim() ? env[key] : value;\r\n });\r\n } catch (e) {\r\n console.warn(\"[vite:wcz-layout] Vault failed:\", e instanceof Error ? e.message : e);\r\n }\r\n}\r\n\r\nfunction loadLocaleResources(localesPath: string, addWatchFile: (path: string) => void): Resource {\r\n if (!fs.existsSync(localesPath)) fs.mkdirSync(localesPath, { recursive: true });\r\n\r\n const enPath = path.join(localesPath, \"en.json\");\r\n if (!fs.existsSync(enPath)) fs.writeFileSync(enPath, JSON.stringify({}));\r\n\r\n const files = fs.readdirSync(localesPath);\r\n const resources: Resource = {};\r\n\r\n for (const file of files.filter((f) => f.endsWith(\".json\"))) {\r\n const lang = path.basename(file, \".json\");\r\n const filePath = path.join(localesPath, file);\r\n try {\r\n resources[lang] = { translation: JSON.parse(fs.readFileSync(filePath, \"utf-8\")) };\r\n } catch {\r\n resources[lang] = { translation: {} };\r\n }\r\n addWatchFile(filePath);\r\n }\r\n\r\n return resources;\r\n}\r\n\r\nfunction ensurePermissionsFile(\r\n permissionsPath: string,\r\n addWatchFile: (path: string) => void,\r\n): void {\r\n const dir = path.dirname(permissionsPath);\r\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\r\n if (!fs.existsSync(permissionsPath)) {\r\n fs.writeFileSync(\r\n permissionsPath,\r\n 'export const permissions = {\\n admin: [\"wcz-developers\"]\\n} as const;',\r\n );\r\n }\r\n addWatchFile(permissionsPath);\r\n}\r\n\r\nfunction ensureScopesFile(scopesPath: string, addWatchFile: (path: string) => void): void {\r\n const dir = path.dirname(scopesPath);\r\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\r\n if (!fs.existsSync(scopesPath)) {\r\n fs.writeFileSync(scopesPath, \"export const scopes = {\\n} as const;\");\r\n }\r\n addWatchFile(scopesPath);\r\n}\r\n\r\nfunction loadManifest(\r\n manifestPath: string,\r\n addWatchFile: (path: string) => void,\r\n): { name: string } & Record<string, unknown> {\r\n addWatchFile(manifestPath);\r\n try {\r\n return JSON.parse(fs.readFileSync(manifestPath, \"utf-8\"));\r\n } catch {\r\n return { name: \"\" };\r\n }\r\n}\r\n\r\nexport function viteWczLayout(): Plugin {\r\n const virtualModuleId = \"virtual:wcz-layout\";\r\n const resolvedVirtualModuleId = \"\\0\" + virtualModuleId;\r\n\r\n let localesPath: string;\r\n let permissionsPath: string;\r\n let scopesPath: string;\r\n let envPath: string;\r\n let manifestPath: string;\r\n\r\n return {\r\n name: \"vite:wcz-layout\",\r\n enforce: \"pre\",\r\n configResolved(resolvedConfig) {\r\n localesPath = path.resolve(resolvedConfig.root, \"src/lib/locales\");\r\n permissionsPath = path.resolve(resolvedConfig.root, \"src/lib/auth/permissions.ts\");\r\n scopesPath = path.resolve(resolvedConfig.root, \"src/lib/auth/scopes.ts\");\r\n envPath = path.resolve(resolvedConfig.root, \"src/env.ts\");\r\n manifestPath = path.resolve(resolvedConfig.root, \"public/manifest.json\");\r\n },\r\n async config(_, { command }) {\r\n await loadVaultSecrets(command);\r\n return {\r\n ssr: {\r\n noExternal: [\"wcz-layout\"],\r\n },\r\n };\r\n },\r\n configureServer(server) {\r\n const refresh = (filePath: string) => {\r\n if (\r\n filePath.includes(localesPath) ||\r\n filePath === permissionsPath ||\r\n filePath === scopesPath ||\r\n filePath === envPath ||\r\n filePath === manifestPath\r\n ) {\r\n const module = server.moduleGraph.getModuleById(resolvedVirtualModuleId);\r\n if (module) server.moduleGraph.invalidateModule(module);\r\n server.ws.send({ type: \"full-reload\", path: \"*\" });\r\n }\r\n };\r\n\r\n server.watcher.add([localesPath, permissionsPath, scopesPath, envPath, manifestPath]);\r\n server.watcher.on(\"add\", refresh);\r\n server.watcher.on(\"change\", refresh);\r\n server.watcher.on(\"unlink\", refresh);\r\n },\r\n resolveId(id) {\r\n if (id === virtualModuleId) return resolvedVirtualModuleId;\r\n return null;\r\n },\r\n load(id) {\r\n if (id !== resolvedVirtualModuleId) return null;\r\n\r\n const resources = loadLocaleResources(localesPath, this.addWatchFile.bind(this));\r\n ensurePermissionsFile(permissionsPath, this.addWatchFile.bind(this));\r\n ensureScopesFile(scopesPath, this.addWatchFile.bind(this));\r\n const manifest = loadManifest(manifestPath, this.addWatchFile.bind(this));\r\n\r\n const normalizedPermissionsPath = permissionsPath.split(path.sep).join(path.posix.sep);\r\n const normalizedScopesPath = scopesPath.split(path.sep).join(path.posix.sep);\r\n const normalizedEnvPath = envPath.split(path.sep).join(path.posix.sep);\r\n return `\r\n export const resources = ${JSON.stringify(resources)};\r\n export const manifest = ${JSON.stringify(manifest)};\r\n export { permissions } from \"${normalizedPermissionsPath}\";\r\n export { scopes } from \"${normalizedScopesPath}\";\r\n export { serverEnv } from \"${normalizedEnvPath}\";\r\n `;\r\n },\r\n };\r\n}\r\n"],"mappings":"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"}