import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { createRequire } from 'node:module'; import { afterEach, describe, expect, it } from 'vitest'; const require = createRequire(import.meta.url); const afterPack = require('../../scripts/after-pack.cjs') as { assertNoPersistedUserData?: (appOutDir: string) => void; writeMeowaReleaseCredential?: (context: { appOutDir: string; packager: { getResourcesDir: (appOutDir: string) => string } }) => boolean; }; const tempDirs: string[] = []; function makeTempDir(): string { const dir = mkdtempSync(join(tmpdir(), 'niancode-after-pack-')); tempDirs.push(dir); return dir; } afterEach(() => { delete process.env.MEOWART_API_KEY; for (const dir of tempDirs.splice(0)) { rmSync(dir, { recursive: true, force: true }); } }); describe('after-pack package hygiene', () => { it('rejects persisted user provider data in packaged app output', () => { const appOutDir = makeTempDir(); const resourcesDir = join(appOutDir, 'resources'); mkdirSync(resourcesDir, { recursive: true }); writeFileSync( join(resourcesDir, 'niancode-providers.json'), JSON.stringify({ providerAccounts: { deepseek: { model: 'deepseek-v4-pro' }, }, apiKeys: { deepseek: 'sk-real-user-key', }, }), ); expect(() => afterPack.assertNoPersistedUserData?.(appOutDir)).toThrow( /Persisted Makelore user data must not be packaged/, ); }); it('allows normal package resources without persisted user data files', () => { const appOutDir = makeTempDir(); const resourcesDir = join(appOutDir, 'resources', 'resources', 'icons'); mkdirSync(resourcesDir, { recursive: true }); writeFileSync(join(resourcesDir, 'icon.png'), ''); expect(() => afterPack.assertNoPersistedUserData?.(appOutDir)).not.toThrow(); }); it('stages the release credential inside packaged resources when the build env provides it', () => { const appOutDir = makeTempDir(); process.env.MEOWART_API_KEY = 'release-secret'; const resourcesDir = join(appOutDir, 'resources'); expect(afterPack.writeMeowaReleaseCredential?.({ appOutDir, packager: { getResourcesDir: () => resourcesDir }, })).toBe(true); expect(JSON.parse(readFileSync( join(resourcesDir, 'resources', 'meowa-game-assets-credential.json'), 'utf8', ))).toEqual({ schemaVersion: 1, apiKey: 'release-secret' }); }); });