@littlepartytime/dev-kit 1.2.5 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=manifest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/manifest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const manifest_1 = require("../utils/manifest");
5
+ (0, vitest_1.describe)('getExtension', () => {
6
+ (0, vitest_1.it)('should return .png for png paths', () => {
7
+ (0, vitest_1.expect)((0, manifest_1.getExtension)('assets/icon.png')).toBe('.png');
8
+ (0, vitest_1.expect)((0, manifest_1.getExtension)('assets/ICON.PNG')).toBe('.png');
9
+ });
10
+ (0, vitest_1.it)('should return .webp for webp paths', () => {
11
+ (0, vitest_1.expect)((0, manifest_1.getExtension)('assets/icon.webp')).toBe('.webp');
12
+ });
13
+ (0, vitest_1.it)('should throw for unsupported formats', () => {
14
+ (0, vitest_1.expect)(() => (0, manifest_1.getExtension)('assets/icon.jpg')).toThrow('Unsupported image format');
15
+ (0, vitest_1.expect)(() => (0, manifest_1.getExtension)('assets/icon.gif')).toThrow('Unsupported image format');
16
+ (0, vitest_1.expect)(() => (0, manifest_1.getExtension)('assets/icon.svg')).toThrow('Unsupported image format');
17
+ });
18
+ });
19
+ (0, vitest_1.describe)('generateManifest', () => {
20
+ const baseConfig = {
21
+ name: 'Test Game',
22
+ description: 'A test game',
23
+ assets: {
24
+ icon: 'assets/icon.png',
25
+ banner: 'assets/banner.png',
26
+ cover: 'assets/cover.webp',
27
+ splash: 'assets/splash.png',
28
+ },
29
+ minPlayers: 2,
30
+ maxPlayers: 6,
31
+ tags: ['casual', 'party'],
32
+ version: '1.0.0',
33
+ sdkVersion: '2.0.0',
34
+ };
35
+ (0, vitest_1.it)('should produce correct manifest structure', () => {
36
+ const manifest = (0, manifest_1.generateManifest)(baseConfig);
37
+ (0, vitest_1.expect)(manifest).not.toHaveProperty('id');
38
+ (0, vitest_1.expect)(manifest.name).toBe('Test Game');
39
+ (0, vitest_1.expect)(manifest.description).toBe('A test game');
40
+ (0, vitest_1.expect)(manifest.minPlayers).toBe(2);
41
+ (0, vitest_1.expect)(manifest.maxPlayers).toBe(6);
42
+ (0, vitest_1.expect)(manifest.tags).toEqual(['casual', 'party']);
43
+ (0, vitest_1.expect)(manifest.version).toBe('1.0.0');
44
+ (0, vitest_1.expect)(manifest.sdkVersion).toBe('2.0.0');
45
+ (0, vitest_1.expect)(manifest.rules).toBe('rules.md');
46
+ });
47
+ (0, vitest_1.it)('should normalize asset filenames', () => {
48
+ const manifest = (0, manifest_1.generateManifest)(baseConfig);
49
+ (0, vitest_1.expect)(manifest.assets.icon).toBe('icon.png');
50
+ (0, vitest_1.expect)(manifest.assets.banner).toBe('banner.png');
51
+ (0, vitest_1.expect)(manifest.assets.cover).toBe('cover.webp');
52
+ (0, vitest_1.expect)(manifest.assets.splash).toBe('splash.png');
53
+ });
54
+ (0, vitest_1.it)('should omit price when undefined', () => {
55
+ const manifest = (0, manifest_1.generateManifest)(baseConfig);
56
+ (0, vitest_1.expect)(manifest).not.toHaveProperty('price');
57
+ });
58
+ (0, vitest_1.it)('should include price when defined', () => {
59
+ const manifest = (0, manifest_1.generateManifest)({ ...baseConfig, price: 9.99 });
60
+ (0, vitest_1.expect)(manifest.price).toBe(9.99);
61
+ });
62
+ });
63
+ //# sourceMappingURL=manifest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.test.js","sourceRoot":"","sources":["../../src/__tests__/manifest.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=validate-assets.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-assets.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/validate-assets.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const vitest_1 = require("vitest");
7
+ const validate_assets_1 = require("../utils/validate-assets");
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const os_1 = __importDefault(require("os"));
11
+ const zlib_1 = __importDefault(require("zlib"));
12
+ function makeTempDir() {
13
+ return fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'lpt-asset-test-'));
14
+ }
15
+ /**
16
+ * Generate a minimal valid PNG file with the given dimensions.
17
+ * Creates a valid PNG with: signature, IHDR, IDAT (empty deflate), IEND.
18
+ */
19
+ function createPng(width, height) {
20
+ const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
21
+ // IHDR chunk
22
+ const ihdrData = Buffer.alloc(13);
23
+ ihdrData.writeUInt32BE(width, 0);
24
+ ihdrData.writeUInt32BE(height, 4);
25
+ ihdrData[8] = 8; // bit depth
26
+ ihdrData[9] = 2; // color type: RGB
27
+ ihdrData[10] = 0; // compression
28
+ ihdrData[11] = 0; // filter
29
+ ihdrData[12] = 0; // interlace
30
+ const ihdr = makeChunk('IHDR', ihdrData);
31
+ // IDAT chunk — minimal: one row of filter-byte + zeros, deflated
32
+ const scanline = Buffer.alloc(1 + width * 3); // filter byte 0 + RGB pixels
33
+ const compressed = zlib_1.default.deflateSync(scanline);
34
+ const idat = makeChunk('IDAT', compressed);
35
+ // IEND chunk
36
+ const iend = makeChunk('IEND', Buffer.alloc(0));
37
+ return Buffer.concat([signature, ihdr, idat, iend]);
38
+ }
39
+ function makeChunk(type, data) {
40
+ const length = Buffer.alloc(4);
41
+ length.writeUInt32BE(data.length, 0);
42
+ const typeBuffer = Buffer.from(type, 'ascii');
43
+ const crcData = Buffer.concat([typeBuffer, data]);
44
+ const crc = crc32(crcData);
45
+ const crcBuffer = Buffer.alloc(4);
46
+ crcBuffer.writeUInt32BE(crc >>> 0, 0);
47
+ return Buffer.concat([length, typeBuffer, data, crcBuffer]);
48
+ }
49
+ function crc32(buf) {
50
+ let crc = 0xFFFFFFFF;
51
+ for (let i = 0; i < buf.length; i++) {
52
+ crc ^= buf[i];
53
+ for (let j = 0; j < 8; j++) {
54
+ crc = (crc >>> 1) ^ (crc & 1 ? 0xEDB88320 : 0);
55
+ }
56
+ }
57
+ return crc ^ 0xFFFFFFFF;
58
+ }
59
+ function setupAssets(dir, overrides) {
60
+ const defaults = {
61
+ icon: { width: 512, height: 512 },
62
+ banner: { width: 1600, height: 900 },
63
+ cover: { width: 2100, height: 900 },
64
+ splash: { width: 900, height: 2100 },
65
+ };
66
+ const assetsDir = path_1.default.join(dir, 'assets');
67
+ fs_1.default.mkdirSync(assetsDir, { recursive: true });
68
+ const config = {};
69
+ for (const [key, dims] of Object.entries(defaults)) {
70
+ const override = overrides?.[key];
71
+ if (override === null)
72
+ continue; // skip this asset
73
+ const { width, height } = override ?? dims;
74
+ const filePath = path_1.default.join(assetsDir, `${key}.png`);
75
+ fs_1.default.writeFileSync(filePath, createPng(width, height));
76
+ config[key] = `assets/${key}.png`;
77
+ }
78
+ return config;
79
+ }
80
+ (0, vitest_1.describe)('validateAssets', () => {
81
+ (0, vitest_1.it)('should pass with valid assets', () => {
82
+ const dir = makeTempDir();
83
+ const assets = setupAssets(dir);
84
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
85
+ (0, vitest_1.expect)(result.valid).toBe(true);
86
+ (0, vitest_1.expect)(result.errors).toHaveLength(0);
87
+ (0, vitest_1.expect)(result.resolvedPaths.size).toBe(4);
88
+ });
89
+ (0, vitest_1.it)('should fail when asset file is missing', () => {
90
+ const dir = makeTempDir();
91
+ const assets = {
92
+ icon: 'assets/icon.png',
93
+ banner: 'assets/banner.png',
94
+ cover: 'assets/cover.png',
95
+ splash: 'assets/splash.png',
96
+ };
97
+ // Don't create any files
98
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
99
+ (0, vitest_1.expect)(result.valid).toBe(false);
100
+ (0, vitest_1.expect)(result.errors.length).toBe(4);
101
+ (0, vitest_1.expect)(result.errors[0]).toContain('Asset not found');
102
+ });
103
+ (0, vitest_1.it)('should fail when asset key is missing from config', () => {
104
+ const dir = makeTempDir();
105
+ const assets = setupAssets(dir);
106
+ delete assets['splash'];
107
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
108
+ (0, vitest_1.expect)(result.valid).toBe(false);
109
+ (0, vitest_1.expect)(result.errors.some(e => e.includes('Missing asset: splash'))).toBe(true);
110
+ });
111
+ (0, vitest_1.it)('should fail for unsupported format', () => {
112
+ const dir = makeTempDir();
113
+ const assets = setupAssets(dir);
114
+ // Rename icon to .jpg
115
+ const assetsDir = path_1.default.join(dir, 'assets');
116
+ fs_1.default.renameSync(path_1.default.join(assetsDir, 'icon.png'), path_1.default.join(assetsDir, 'icon.jpg'));
117
+ assets['icon'] = 'assets/icon.jpg';
118
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
119
+ (0, vitest_1.expect)(result.valid).toBe(false);
120
+ (0, vitest_1.expect)(result.errors.some(e => e.includes('unsupported format'))).toBe(true);
121
+ });
122
+ (0, vitest_1.it)('should fail for empty file', () => {
123
+ const dir = makeTempDir();
124
+ const assets = setupAssets(dir);
125
+ fs_1.default.writeFileSync(path_1.default.join(dir, 'assets', 'icon.png'), '');
126
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
127
+ (0, vitest_1.expect)(result.valid).toBe(false);
128
+ (0, vitest_1.expect)(result.errors.some(e => e.includes('file is empty'))).toBe(true);
129
+ });
130
+ (0, vitest_1.it)('should fail when image is too small', () => {
131
+ const dir = makeTempDir();
132
+ const assets = setupAssets(dir, { icon: { width: 100, height: 100 } });
133
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
134
+ (0, vitest_1.expect)(result.valid).toBe(false);
135
+ (0, vitest_1.expect)(result.errors.some(e => e.includes('100x100') && e.includes('256x256'))).toBe(true);
136
+ });
137
+ (0, vitest_1.it)('should fail when aspect ratio is wrong', () => {
138
+ const dir = makeTempDir();
139
+ // banner should be 16:9, give it 1:1
140
+ const assets = setupAssets(dir, { banner: { width: 900, height: 900 } });
141
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
142
+ (0, vitest_1.expect)(result.valid).toBe(false);
143
+ (0, vitest_1.expect)(result.errors.some(e => e.includes('banner') && e.includes('aspect ratio'))).toBe(true);
144
+ });
145
+ (0, vitest_1.it)('should warn for large files', () => {
146
+ const dir = makeTempDir();
147
+ const assets = setupAssets(dir);
148
+ // Write a large file (>2MB) as icon
149
+ const largeBuf = createPng(512, 512);
150
+ const padded = Buffer.concat([largeBuf, Buffer.alloc(2.5 * 1024 * 1024)]);
151
+ fs_1.default.writeFileSync(path_1.default.join(dir, 'assets', 'icon.png'), padded);
152
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
153
+ // Dimensions won't read correctly from padded file, but let's check warnings exist
154
+ (0, vitest_1.expect)(result.warnings.some(w => w.includes('large'))).toBe(true);
155
+ });
156
+ (0, vitest_1.it)('should accept webp files', () => {
157
+ const dir = makeTempDir();
158
+ const assets = setupAssets(dir);
159
+ // We only test that .webp extension is accepted (PNG header reading for webp is separate)
160
+ // For this test, just check that the extension validation passes
161
+ const assetsDir = path_1.default.join(dir, 'assets');
162
+ const iconPng = path_1.default.join(assetsDir, 'icon.png');
163
+ const iconWebp = path_1.default.join(assetsDir, 'icon.webp');
164
+ fs_1.default.renameSync(iconPng, iconWebp);
165
+ assets['icon'] = 'assets/icon.webp';
166
+ const result = (0, validate_assets_1.validateAssets)(dir, assets);
167
+ // Will fail dimension check (wrong header for webp) but extension is accepted
168
+ // The important thing: no "unsupported format" error
169
+ (0, vitest_1.expect)(result.errors.every(e => !e.includes('unsupported format'))).toBe(true);
170
+ });
171
+ });
172
+ //# sourceMappingURL=validate-assets.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-assets.test.js","sourceRoot":"","sources":["../../src/__tests__/validate-assets.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAwEvG"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAgDA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,eAAe,CAAC,CAmFvG"}
@@ -9,6 +9,48 @@ const path_1 = __importDefault(require("path"));
9
9
  const vite_1 = require("vite");
10
10
  const socket_server_1 = require("../server/socket-server");
11
11
  const chokidar_1 = __importDefault(require("chokidar"));
12
+ function createEngineRebuilder(projectDir, silent) {
13
+ let building = false;
14
+ let pendingBuild = false;
15
+ let debounceTimer = null;
16
+ async function runBuild() {
17
+ if (building) {
18
+ pendingBuild = true;
19
+ return;
20
+ }
21
+ building = true;
22
+ if (!silent) {
23
+ console.log('[Dev] Source changed, rebuilding engine...');
24
+ }
25
+ try {
26
+ await (0, vite_1.build)({
27
+ configFile: path_1.default.join(projectDir, 'vite.config.ts'),
28
+ logLevel: 'warn',
29
+ });
30
+ if (!silent) {
31
+ console.log('[Dev] Engine rebuild complete.');
32
+ }
33
+ }
34
+ catch (err) {
35
+ console.error('[Dev] Engine rebuild failed:', err.message);
36
+ }
37
+ finally {
38
+ building = false;
39
+ if (pendingBuild) {
40
+ pendingBuild = false;
41
+ runBuild();
42
+ }
43
+ }
44
+ }
45
+ return (filePath) => {
46
+ if (debounceTimer)
47
+ clearTimeout(debounceTimer);
48
+ debounceTimer = setTimeout(() => {
49
+ debounceTimer = null;
50
+ runBuild();
51
+ }, 300);
52
+ };
53
+ }
12
54
  async function devCommand(projectDir, options = {}) {
13
55
  const port = options.port || 4000;
14
56
  const socketPort = options.socketPort || 4001;
@@ -23,15 +65,24 @@ async function devCommand(projectDir, options = {}) {
23
65
  port: socketPort,
24
66
  projectDir,
25
67
  });
26
- // Watch for engine changes
68
+ // Watch for engine build output changes (triggers reload)
27
69
  const enginePath = path_1.default.join(projectDir, 'dist', 'engine.cjs');
28
- const watcher = chokidar_1.default.watch(enginePath, { ignoreInitial: true });
29
- watcher.on('change', () => {
70
+ const distWatcher = chokidar_1.default.watch(enginePath, { ignoreInitial: true });
71
+ distWatcher.on('change', () => {
30
72
  if (!options.silent) {
31
73
  console.log('[Dev] Engine changed, reloading...');
32
74
  }
33
75
  reloadEngine();
34
76
  });
77
+ // Watch source files and auto-rebuild engine
78
+ const srcDir = path_1.default.join(projectDir, 'src');
79
+ const srcWatcher = chokidar_1.default.watch(srcDir, {
80
+ ignoreInitial: true,
81
+ ignored: /node_modules/,
82
+ });
83
+ const triggerRebuild = createEngineRebuilder(projectDir, !!options.silent);
84
+ srcWatcher.on('change', triggerRebuild);
85
+ srcWatcher.on('add', triggerRebuild);
35
86
  // Start Vite dev server
36
87
  const webappDir = path_1.default.join(__dirname, '..', 'webapp');
37
88
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -65,7 +116,8 @@ async function devCommand(projectDir, options = {}) {
65
116
  port,
66
117
  socketPort,
67
118
  async stop() {
68
- await watcher.close();
119
+ await distWatcher.close();
120
+ await srcWatcher.close();
69
121
  await vite.close();
70
122
  io.disconnectSockets(true);
71
123
  io.close();
@@ -1 +1 @@
1
- {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/commands/pack.ts"],"names":[],"mappings":"AAMA,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DnE"}
1
+ {"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/commands/pack.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsInE"}
@@ -9,6 +9,8 @@ const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
10
10
  const archiver_1 = __importDefault(require("archiver"));
11
11
  const validate_bundle_1 = require("../utils/validate-bundle");
12
+ const validate_assets_1 = require("../utils/validate-assets");
13
+ const manifest_1 = require("../utils/manifest");
12
14
  async function packCommand(projectDir) {
13
15
  const distDir = path_1.default.join(projectDir, 'dist');
14
16
  // Step 1: Run vite build
@@ -22,27 +24,81 @@ async function packCommand(projectDir) {
22
24
  }
23
25
  // Step 2: Validate bundle
24
26
  console.log('\nValidating build output...');
25
- const result = (0, validate_bundle_1.validateBundle)(distDir);
26
- for (const warning of result.warnings) {
27
+ const bundleResult = (0, validate_bundle_1.validateBundle)(distDir);
28
+ for (const warning of bundleResult.warnings) {
27
29
  console.log(` WARNING: ${warning}`);
28
30
  }
29
- if (!result.valid) {
30
- for (const error of result.errors) {
31
+ if (!bundleResult.valid) {
32
+ for (const error of bundleResult.errors) {
31
33
  console.error(` ERROR: ${error}`);
32
34
  }
33
35
  process.exit(1);
34
36
  }
35
- console.log(' Validation passed');
36
- // Step 3: Read gameId from lpt.config.ts or package.json
37
+ console.log(' Bundle validation passed');
38
+ // Step 3: Read gameId from lpt.config.ts (local project identifier for zip naming)
37
39
  let gameId = 'game';
38
- const configPath = path_1.default.join(projectDir, 'lpt.config.ts');
39
- if (fs_1.default.existsSync(configPath)) {
40
- const content = fs_1.default.readFileSync(configPath, 'utf-8');
40
+ const lptConfigPath = path_1.default.join(projectDir, 'lpt.config.ts');
41
+ if (fs_1.default.existsSync(lptConfigPath)) {
42
+ const content = fs_1.default.readFileSync(lptConfigPath, 'utf-8');
41
43
  const match = content.match(/gameId:\s*["']([^"']+)["']/);
42
44
  if (match)
43
45
  gameId = match[1];
44
46
  }
45
- // Step 4: Create zip
47
+ // Step 4: Load GameConfig from engine.cjs
48
+ console.log('\nReading game config...');
49
+ const enginePath = path_1.default.join(distDir, 'engine.cjs');
50
+ let config;
51
+ try {
52
+ const engineModule = require(enginePath);
53
+ config = engineModule.config || engineModule.default?.config;
54
+ // Clear require cache to avoid stale modules
55
+ delete require.cache[require.resolve(enginePath)];
56
+ }
57
+ catch (err) {
58
+ console.error(` ERROR: Failed to load engine.cjs: ${err.message}`);
59
+ process.exit(1);
60
+ }
61
+ if (!config || !config.name) {
62
+ console.error(' ERROR: Could not read GameConfig from engine.cjs.');
63
+ console.error(' Make sure src/index.ts exports config:');
64
+ console.error(' export { default as config } from "./config";');
65
+ process.exit(1);
66
+ }
67
+ console.log(` Game: ${config.name} v${config.version}`);
68
+ // Step 5: Validate image assets
69
+ console.log('\nValidating assets...');
70
+ const assets = config.assets;
71
+ if (!assets) {
72
+ console.error(' ERROR: GameConfig.assets is missing.');
73
+ console.error(' Add an assets object to your config.ts with icon, banner, cover, and splash paths.');
74
+ process.exit(1);
75
+ }
76
+ const assetResult = (0, validate_assets_1.validateAssets)(projectDir, assets);
77
+ for (const warning of assetResult.warnings) {
78
+ console.log(` WARNING: ${warning}`);
79
+ }
80
+ if (!assetResult.valid) {
81
+ for (const error of assetResult.errors) {
82
+ console.error(` ERROR: ${error}`);
83
+ }
84
+ process.exit(1);
85
+ }
86
+ console.log(' Asset validation passed');
87
+ // Step 6: Validate rules.md
88
+ const rulesPath = path_1.default.join(projectDir, 'rules.md');
89
+ if (!fs_1.default.existsSync(rulesPath)) {
90
+ console.error(' ERROR: rules.md not found in project root.');
91
+ console.error(' Create a rules.md file with your game rules in Markdown format.');
92
+ process.exit(1);
93
+ }
94
+ if (fs_1.default.statSync(rulesPath).size === 0) {
95
+ console.error(' ERROR: rules.md is empty.');
96
+ process.exit(1);
97
+ }
98
+ console.log(' rules.md found');
99
+ // Step 7: Generate manifest
100
+ const manifest = (0, manifest_1.generateManifest)(config);
101
+ // Step 8: Create zip
46
102
  const zipPath = path_1.default.join(distDir, `${gameId}.zip`);
47
103
  console.log(`\nPackaging to ${gameId}.zip...`);
48
104
  await new Promise((resolve, reject) => {
@@ -51,8 +107,19 @@ async function packCommand(projectDir) {
51
107
  output.on('close', resolve);
52
108
  archive.on('error', reject);
53
109
  archive.pipe(output);
110
+ // Build artifacts
54
111
  archive.file(path_1.default.join(distDir, 'bundle.js'), { name: 'bundle.js' });
55
112
  archive.file(path_1.default.join(distDir, 'engine.cjs'), { name: 'engine.cjs' });
113
+ // Manifest
114
+ archive.append(JSON.stringify(manifest, null, 2), { name: 'manifest.json' });
115
+ // Image assets (renamed to canonical names)
116
+ for (const spec of validate_assets_1.ASSET_SPECS) {
117
+ const srcPath = assetResult.resolvedPaths.get(spec.key);
118
+ const ext = (0, manifest_1.getExtension)(assets[spec.key]);
119
+ archive.file(srcPath, { name: `${spec.key}${ext}` });
120
+ }
121
+ // Rules
122
+ archive.file(rulesPath, { name: 'rules.md' });
56
123
  archive.finalize();
57
124
  });
58
125
  const zipSize = fs_1.default.statSync(zipPath).size;
@@ -1 +1 @@
1
- {"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/commands/pack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/commands/pack.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  export { validateBundle } from './utils/validate-bundle';
2
2
  export type { ValidationResult } from './utils/validate-bundle';
3
+ export { validateAssets, ASSET_SPECS } from './utils/validate-assets';
4
+ export type { AssetSpec, AssetValidationResult } from './utils/validate-assets';
5
+ export { generateManifest, getExtension } from './utils/manifest';
6
+ export type { GameManifest } from './utils/manifest';
3
7
  export { devCommand } from './commands/dev';
4
8
  export type { DevOptions, DevServerHandle } from './commands/dev';
5
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtE,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAClE,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.devCommand = exports.validateBundle = void 0;
3
+ exports.devCommand = exports.getExtension = exports.generateManifest = exports.ASSET_SPECS = exports.validateAssets = exports.validateBundle = void 0;
4
4
  var validate_bundle_1 = require("./utils/validate-bundle");
5
5
  Object.defineProperty(exports, "validateBundle", { enumerable: true, get: function () { return validate_bundle_1.validateBundle; } });
6
+ var validate_assets_1 = require("./utils/validate-assets");
7
+ Object.defineProperty(exports, "validateAssets", { enumerable: true, get: function () { return validate_assets_1.validateAssets; } });
8
+ Object.defineProperty(exports, "ASSET_SPECS", { enumerable: true, get: function () { return validate_assets_1.ASSET_SPECS; } });
9
+ var manifest_1 = require("./utils/manifest");
10
+ Object.defineProperty(exports, "generateManifest", { enumerable: true, get: function () { return manifest_1.generateManifest; } });
11
+ Object.defineProperty(exports, "getExtension", { enumerable: true, get: function () { return manifest_1.getExtension; } });
6
12
  var dev_1 = require("./commands/dev");
7
13
  Object.defineProperty(exports, "devCommand", { enumerable: true, get: function () { return dev_1.devCommand; } });
8
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,iHAAA,cAAc,OAAA;AAEvB,sCAA4C;AAAnC,iGAAA,UAAU,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,iHAAA,cAAc,OAAA;AAEvB,2DAAsE;AAA7D,iHAAA,cAAc,OAAA;AAAE,8GAAA,WAAW,OAAA;AAEpC,6CAAkE;AAAzD,4GAAA,gBAAgB,OAAA;AAAE,wGAAA,YAAY,OAAA;AAEvC,sCAA4C;AAAnC,iGAAA,UAAU,OAAA"}
@@ -0,0 +1,35 @@
1
+ export interface GameManifest {
2
+ name: string;
3
+ description: string;
4
+ minPlayers: number;
5
+ maxPlayers: number;
6
+ tags: string[];
7
+ version: string;
8
+ sdkVersion: string;
9
+ price?: number;
10
+ assets: {
11
+ icon: string;
12
+ banner: string;
13
+ cover: string;
14
+ splash: string;
15
+ };
16
+ rules: string;
17
+ }
18
+ export declare function getExtension(filePath: string): string;
19
+ export declare function generateManifest(config: {
20
+ name: string;
21
+ description: string;
22
+ assets: {
23
+ icon: string;
24
+ banner: string;
25
+ cover: string;
26
+ splash: string;
27
+ };
28
+ minPlayers: number;
29
+ maxPlayers: number;
30
+ tags: string[];
31
+ version: string;
32
+ sdkVersion: string;
33
+ price?: number;
34
+ }): GameManifest;
35
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMrD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,YAAY,CAuBf"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getExtension = getExtension;
7
+ exports.generateManifest = generateManifest;
8
+ const path_1 = __importDefault(require("path"));
9
+ function getExtension(filePath) {
10
+ const ext = path_1.default.extname(filePath).toLowerCase();
11
+ if (ext !== '.png' && ext !== '.webp') {
12
+ throw new Error(`Unsupported image format: ${filePath}. Use .png or .webp`);
13
+ }
14
+ return ext;
15
+ }
16
+ function generateManifest(config) {
17
+ const manifest = {
18
+ name: config.name,
19
+ description: config.description,
20
+ minPlayers: config.minPlayers,
21
+ maxPlayers: config.maxPlayers,
22
+ tags: config.tags,
23
+ version: config.version,
24
+ sdkVersion: config.sdkVersion,
25
+ assets: {
26
+ icon: `icon${getExtension(config.assets.icon)}`,
27
+ banner: `banner${getExtension(config.assets.banner)}`,
28
+ cover: `cover${getExtension(config.assets.cover)}`,
29
+ splash: `splash${getExtension(config.assets.splash)}`,
30
+ },
31
+ rules: 'rules.md',
32
+ };
33
+ if (config.price !== undefined) {
34
+ manifest.price = config.price;
35
+ }
36
+ return manifest;
37
+ }
38
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/utils/manifest.ts"],"names":[],"mappings":";;;;;AAoBA,oCAMC;AAED,4CAiCC;AA7DD,gDAAwB;AAoBxB,SAAgB,YAAY,CAAC,QAAgB;IAC3C,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,6BAA6B,QAAQ,qBAAqB,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,gBAAgB,CAAC,MAUhC;IACC,MAAM,QAAQ,GAAiB;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,MAAM,EAAE;YACN,IAAI,EAAE,OAAO,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;YAC/C,MAAM,EAAE,SAAS,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACrD,KAAK,EAAE,QAAQ,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAClD,MAAM,EAAE,SAAS,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;SACtD;QACD,KAAK,EAAE,UAAU;KAClB,CAAC;IAEF,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface AssetSpec {
2
+ key: string;
3
+ ratioWidth: number;
4
+ ratioHeight: number;
5
+ minWidth: number;
6
+ minHeight: number;
7
+ }
8
+ export declare const ASSET_SPECS: AssetSpec[];
9
+ export interface AssetValidationResult {
10
+ valid: boolean;
11
+ errors: string[];
12
+ warnings: string[];
13
+ resolvedPaths: Map<string, string>;
14
+ }
15
+ export declare function validateAssets(projectDir: string, assets: Record<string, string>): AssetValidationResult;
16
+ //# sourceMappingURL=validate-assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-assets.d.ts","sourceRoot":"","sources":["../../src/utils/validate-assets.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,WAAW,EAAE,SAAS,EAKlC,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,qBAAqB,CA0DvB"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ASSET_SPECS = void 0;
7
+ exports.validateAssets = validateAssets;
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const path_1 = __importDefault(require("path"));
10
+ exports.ASSET_SPECS = [
11
+ { key: 'icon', ratioWidth: 1, ratioHeight: 1, minWidth: 256, minHeight: 256 },
12
+ { key: 'banner', ratioWidth: 16, ratioHeight: 9, minWidth: 640, minHeight: 360 },
13
+ { key: 'cover', ratioWidth: 21, ratioHeight: 9, minWidth: 840, minHeight: 360 },
14
+ { key: 'splash', ratioWidth: 9, ratioHeight: 21, minWidth: 360, minHeight: 840 },
15
+ ];
16
+ function validateAssets(projectDir, assets) {
17
+ const errors = [];
18
+ const warnings = [];
19
+ const resolvedPaths = new Map();
20
+ for (const spec of exports.ASSET_SPECS) {
21
+ const relativePath = assets[spec.key];
22
+ if (!relativePath) {
23
+ errors.push(`Missing asset: ${spec.key} is required in config.assets`);
24
+ continue;
25
+ }
26
+ const absPath = path_1.default.resolve(projectDir, relativePath);
27
+ if (!fs_1.default.existsSync(absPath)) {
28
+ errors.push(`Asset not found: ${spec.key} -> ${relativePath}`);
29
+ continue;
30
+ }
31
+ const ext = path_1.default.extname(absPath).toLowerCase();
32
+ if (ext !== '.png' && ext !== '.webp') {
33
+ errors.push(`${spec.key}: unsupported format "${ext}". Use .png or .webp`);
34
+ continue;
35
+ }
36
+ const stat = fs_1.default.statSync(absPath);
37
+ if (stat.size === 0) {
38
+ errors.push(`${spec.key}: file is empty`);
39
+ continue;
40
+ }
41
+ if (stat.size > 2 * 1024 * 1024) {
42
+ warnings.push(`${spec.key}: file is large (${(stat.size / 1024 / 1024).toFixed(1)}MB). Consider optimizing.`);
43
+ }
44
+ const dimensions = readImageDimensions(absPath, ext);
45
+ if (dimensions) {
46
+ const { width, height } = dimensions;
47
+ if (width < spec.minWidth || height < spec.minHeight) {
48
+ errors.push(`${spec.key}: image is ${width}x${height}, minimum required is ${spec.minWidth}x${spec.minHeight}`);
49
+ }
50
+ const expectedRatio = spec.ratioWidth / spec.ratioHeight;
51
+ const actualRatio = width / height;
52
+ if (Math.abs(actualRatio - expectedRatio) > 0.01) {
53
+ errors.push(`${spec.key}: aspect ratio is ${actualRatio.toFixed(3)} (${width}x${height}), ` +
54
+ `expected ${spec.ratioWidth}:${spec.ratioHeight} (${expectedRatio.toFixed(3)})`);
55
+ }
56
+ }
57
+ resolvedPaths.set(spec.key, absPath);
58
+ }
59
+ return { valid: errors.length === 0, errors, warnings, resolvedPaths };
60
+ }
61
+ function readImageDimensions(filePath, ext) {
62
+ const fd = fs_1.default.openSync(filePath, 'r');
63
+ try {
64
+ const buffer = Buffer.alloc(30);
65
+ fs_1.default.readSync(fd, buffer, 0, 30, 0);
66
+ if (ext === '.png') {
67
+ // PNG signature check: bytes 1-3 = "PNG"
68
+ if (buffer.toString('ascii', 1, 4) !== 'PNG')
69
+ return null;
70
+ // IHDR chunk: width at offset 16, height at offset 20 (big-endian uint32)
71
+ return {
72
+ width: buffer.readUInt32BE(16),
73
+ height: buffer.readUInt32BE(20),
74
+ };
75
+ }
76
+ if (ext === '.webp') {
77
+ if (buffer.toString('ascii', 0, 4) !== 'RIFF')
78
+ return null;
79
+ if (buffer.toString('ascii', 8, 12) !== 'WEBP')
80
+ return null;
81
+ const chunk = buffer.toString('ascii', 12, 16);
82
+ if (chunk === 'VP8 ') {
83
+ // Lossy WebP
84
+ return {
85
+ width: buffer.readUInt16LE(26) & 0x3FFF,
86
+ height: buffer.readUInt16LE(28) & 0x3FFF,
87
+ };
88
+ }
89
+ if (chunk === 'VP8L') {
90
+ // Lossless WebP
91
+ const bits = buffer.readUInt32LE(21);
92
+ return {
93
+ width: (bits & 0x3FFF) + 1,
94
+ height: ((bits >> 14) & 0x3FFF) + 1,
95
+ };
96
+ }
97
+ if (chunk === 'VP8X') {
98
+ // Extended WebP: canvas size at bytes 24-29
99
+ return {
100
+ width: 1 + (buffer[24] | (buffer[25] << 8) | (buffer[26] << 16)),
101
+ height: 1 + (buffer[27] | (buffer[28] << 8) | (buffer[29] << 16)),
102
+ };
103
+ }
104
+ }
105
+ return null;
106
+ }
107
+ finally {
108
+ fs_1.default.closeSync(fd);
109
+ }
110
+ }
111
+ //# sourceMappingURL=validate-assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-assets.js","sourceRoot":"","sources":["../../src/utils/validate-assets.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@littlepartytime/dev-kit",
3
- "version": "1.2.5",
3
+ "version": "1.3.1",
4
4
  "description": "Development toolkit CLI for Little Party Time game developers",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",