@remvst/asset-catalog 1.3.1 → 1.5.0
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.
- package/.idea/asset-catalog.iml +12 -0
- package/.idea/copilot.data.migration.ask2agent.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/lib/generate-file-catalog.d.ts +2 -0
- package/lib/generate-file-catalog.js +131 -0
- package/lib/generate-image-catalog.js +14 -1
- package/lib/tree.js +1 -1
- package/lib/utils.js +1 -1
- package/package.json +5 -3
- package/src/generate-file-catalog.ts +141 -0
- package/src/generate-image-catalog.ts +15 -1
- package/src/tree.ts +1 -1
- package/src/utils.ts +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$">
|
|
5
|
+
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
6
|
+
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
7
|
+
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
+
</content>
|
|
9
|
+
<orderEntry type="inheritedJdk" />
|
|
10
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
11
|
+
</component>
|
|
12
|
+
</module>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="ProjectModuleManager">
|
|
4
|
+
<modules>
|
|
5
|
+
<module fileurl="file://$PROJECT_DIR$/.idea/asset-catalog.iml" filepath="$PROJECT_DIR$/.idea/asset-catalog.iml" />
|
|
6
|
+
</modules>
|
|
7
|
+
</component>
|
|
8
|
+
</project>
|
package/.idea/vcs.xml
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const yargs_1 = __importDefault(require("yargs/yargs"));
|
|
11
|
+
const helpers_1 = require("yargs/helpers");
|
|
12
|
+
const tree_1 = require("./tree");
|
|
13
|
+
function importName(assetDir, file) {
|
|
14
|
+
let importName = file;
|
|
15
|
+
importName = (0, path_1.resolve)(file);
|
|
16
|
+
const prefix = (0, path_1.resolve)(assetDir);
|
|
17
|
+
const prefixIndex = importName.indexOf(prefix);
|
|
18
|
+
if (prefixIndex >= 0) {
|
|
19
|
+
importName = importName.slice(prefixIndex + prefix.length);
|
|
20
|
+
}
|
|
21
|
+
importName = (0, utils_1.sanitize)(importName);
|
|
22
|
+
return importName;
|
|
23
|
+
}
|
|
24
|
+
function generatedTemplateInterface(tree, indent = '') {
|
|
25
|
+
let generated = '{\n';
|
|
26
|
+
for (const [subname, item] of tree.entries()) {
|
|
27
|
+
if (item instanceof Map) {
|
|
28
|
+
const generatedSub = generatedTemplateInterface(item, indent + ' ');
|
|
29
|
+
generated += indent + ` ${(0, utils_1.lowerCamelize)(subname)}: ${generatedSub}`;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
const name = (0, path_1.basename)(subname);
|
|
33
|
+
generated += indent + ` ${(0, utils_1.lowerCamelize)(name)}: T,\n`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
generated += indent + '}\n';
|
|
37
|
+
return generated;
|
|
38
|
+
}
|
|
39
|
+
async function generatedCreateCatalogFunction(assetDir, tree) {
|
|
40
|
+
async function rec(tree, indent = '') {
|
|
41
|
+
let generated = '{\n';
|
|
42
|
+
for (const [subname, item] of tree.entries()) {
|
|
43
|
+
if (item instanceof Map) {
|
|
44
|
+
const generatedSub = await rec(item, indent + ' ');
|
|
45
|
+
generated += indent + ` ${(0, utils_1.lowerCamelize)(subname)}: ${generatedSub},\n`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const stats = await fs_1.promises.stat(item);
|
|
49
|
+
const name = (0, path_1.basename)(subname);
|
|
50
|
+
generated += indent + ` ${(0, utils_1.lowerCamelize)(name)}: createItem(expand(
|
|
51
|
+
${importName(assetDir, item)},
|
|
52
|
+
${stats.size},
|
|
53
|
+
)),\n`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
generated += indent + '}';
|
|
57
|
+
return generated;
|
|
58
|
+
}
|
|
59
|
+
let generated = '';
|
|
60
|
+
generated += 'export function createFileCatalog<T>(createItem: (opts: CreateItemOptions) => T): FileCatalog<T> {\n';
|
|
61
|
+
generated += ` return ${await rec(tree, ' ')};\n`;
|
|
62
|
+
generated += '}\n';
|
|
63
|
+
return generated;
|
|
64
|
+
}
|
|
65
|
+
function generateExpandFunction() {
|
|
66
|
+
let generated = '';
|
|
67
|
+
generated += 'function expand(path: string, size: number): CreateItemOptions {\n';
|
|
68
|
+
generated += ` return { path, size };\n`;
|
|
69
|
+
generated += '}\n';
|
|
70
|
+
return generated;
|
|
71
|
+
}
|
|
72
|
+
function generateResolveFunction() {
|
|
73
|
+
let generated = '';
|
|
74
|
+
generated += 'export function resolveFromCatalog<T>(catalog: FileCatalog<T>, path: string[]): T {\n';
|
|
75
|
+
generated += ' let current: any = catalog;\n';
|
|
76
|
+
generated += ` for (const component of path) {\n`;
|
|
77
|
+
generated += ` if (!(component in current)) throw new Error('Unresolvable catalog path: ' + path.join('.'));\n`;
|
|
78
|
+
generated += ` current = current[component];\n`;
|
|
79
|
+
generated += ` }\n`;
|
|
80
|
+
generated += ` return current as T;\n`;
|
|
81
|
+
generated += '}\n';
|
|
82
|
+
return generated;
|
|
83
|
+
}
|
|
84
|
+
async function main() {
|
|
85
|
+
const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv))
|
|
86
|
+
.options({
|
|
87
|
+
'outFile': {
|
|
88
|
+
type: 'string',
|
|
89
|
+
default: 'files.ts',
|
|
90
|
+
alias: 'o',
|
|
91
|
+
describe: 'Directory to generate the files into',
|
|
92
|
+
},
|
|
93
|
+
'dir': {
|
|
94
|
+
type: 'string',
|
|
95
|
+
default: '.',
|
|
96
|
+
alias: 'd',
|
|
97
|
+
describe: 'Asset directory where all the PNGs are located',
|
|
98
|
+
},
|
|
99
|
+
})
|
|
100
|
+
.argv;
|
|
101
|
+
const filesRoot = argv.dir;
|
|
102
|
+
const generatedTs = argv.outFile;
|
|
103
|
+
try {
|
|
104
|
+
await fs_1.promises.rm(generatedTs, { 'recursive': true });
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
}
|
|
108
|
+
const files = await (0, utils_1.allFiles)(filesRoot);
|
|
109
|
+
const imports = [];
|
|
110
|
+
const tree = await (0, tree_1.generateTree)(argv.dir, files);
|
|
111
|
+
for (const file of files) {
|
|
112
|
+
const importPath = (0, path_1.relative)((0, path_1.dirname)(argv.outFile), file).replace(/\\/g, '/');
|
|
113
|
+
imports.push(`import ${importName(argv.dir, file)} from './${importPath}';`);
|
|
114
|
+
}
|
|
115
|
+
let generatedFileContent = '';
|
|
116
|
+
generatedFileContent += imports.join('\n');
|
|
117
|
+
generatedFileContent += '\n\n';
|
|
118
|
+
generatedFileContent += `export interface CreateItemOptions {
|
|
119
|
+
path: string;
|
|
120
|
+
size: number;
|
|
121
|
+
}\n\n`;
|
|
122
|
+
generatedFileContent += 'export type FileCatalog<T> = ' + generatedTemplateInterface(tree);
|
|
123
|
+
generatedFileContent += '\n';
|
|
124
|
+
generatedFileContent += generateExpandFunction();
|
|
125
|
+
generatedFileContent += '\n';
|
|
126
|
+
generatedFileContent += generateResolveFunction();
|
|
127
|
+
generatedFileContent += '\n';
|
|
128
|
+
generatedFileContent += await generatedCreateCatalogFunction(argv.dir, tree);
|
|
129
|
+
await fs_1.promises.writeFile(generatedTs, generatedFileContent);
|
|
130
|
+
}
|
|
131
|
+
main();
|
|
@@ -84,6 +84,18 @@ function generateExpandFunction() {
|
|
|
84
84
|
generated += '}\n';
|
|
85
85
|
return generated;
|
|
86
86
|
}
|
|
87
|
+
function generateResolveFunction() {
|
|
88
|
+
let generated = '\n';
|
|
89
|
+
generated += 'export function resolveFromCatalog<T>(catalog: TextureCatalog<T>, path: string[]): T {\n';
|
|
90
|
+
generated += ' let current = catalog;\n';
|
|
91
|
+
generated += ` for (const component of path) {\n`;
|
|
92
|
+
generated += ` if (!(component in current)) throw new Error('Unresolvable catalog path: ' + path.join('.'));\n`;
|
|
93
|
+
generated += ` current = current[component];\n`;
|
|
94
|
+
generated += ` }\n`;
|
|
95
|
+
generated += ` return current as T;\n`;
|
|
96
|
+
generated += '}\n';
|
|
97
|
+
return generated;
|
|
98
|
+
}
|
|
87
99
|
async function createSpritesheet(tree, outFile, excludes) {
|
|
88
100
|
const bins = [];
|
|
89
101
|
const padding = 1;
|
|
@@ -196,11 +208,12 @@ async function main() {
|
|
|
196
208
|
width: number;
|
|
197
209
|
height: number;
|
|
198
210
|
size: number;
|
|
199
|
-
spriteData: SpriteData | null;
|
|
211
|
+
spriteData: SpriteData | null;
|
|
200
212
|
}\n\n`;
|
|
201
213
|
generatedFileContent += 'export type TextureCatalog<T> = ' + generatedTemplateInterface(tree, 'TextureCatalog');
|
|
202
214
|
generatedFileContent += '\n\n';
|
|
203
215
|
generatedFileContent += generateExpandFunction();
|
|
216
|
+
generatedFileContent += generateResolveFunction();
|
|
204
217
|
generatedFileContent += await generatedCreateCatalogFunction(argv.assetDir, tree, spritesheet);
|
|
205
218
|
await fs_1.promises.writeFile(generatedTs, generatedFileContent);
|
|
206
219
|
}
|
package/lib/tree.js
CHANGED
package/lib/utils.js
CHANGED
|
@@ -30,7 +30,7 @@ function camelize(str) {
|
|
|
30
30
|
}
|
|
31
31
|
exports.camelize = camelize;
|
|
32
32
|
function lowerCamelize(str) {
|
|
33
|
-
const camelized =
|
|
33
|
+
const camelized = camelize(str);
|
|
34
34
|
return camelized.slice(0, 1).toLowerCase() + camelized.slice(1);
|
|
35
35
|
}
|
|
36
36
|
exports.lowerCamelize = lowerCamelize;
|
package/package.json
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remvst/asset-catalog",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"bin": {
|
|
6
6
|
"generate-image-catalog": "./lib/generate-image-catalog.js",
|
|
7
|
-
"generate-sound-catalog": "./lib/generate-sound-catalog.js"
|
|
7
|
+
"generate-sound-catalog": "./lib/generate-sound-catalog.js",
|
|
8
|
+
"generate-file-catalog": "./lib/generate-file-catalog.js"
|
|
8
9
|
},
|
|
9
10
|
"scripts": {
|
|
10
11
|
"build": "rm -rf lib && tsc && chmod +x lib/generate-image-catalog.js lib/generate-sound-catalog.js",
|
|
11
12
|
"test:images": "ts-node src/generate-image-catalog.ts --assetDir=./testData --outFile=testOut/images.ts --outSpritesheet=testOut/spritesheet.png",
|
|
12
13
|
"test:sounds": "ts-node src/generate-sound-catalog.ts --assetDir=./testData/sounds --outFile=testOut/sounds.ts --outSpritesheet=testData/sounds/sprites --spritesheetExcludeCategory=jump",
|
|
13
|
-
"test": "
|
|
14
|
+
"test:files": "ts-node src/generate-file-catalog.ts --dir=./testData --outFile=testOut/files.ts",
|
|
15
|
+
"test": "npm run test:images && npm run test:sounds && npm run test:files",
|
|
14
16
|
"prepublishOnly": "npm i && npm run build"
|
|
15
17
|
},
|
|
16
18
|
"author": "Rémi Vansteelandt",
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {promises as fs} from 'fs';
|
|
4
|
+
import {allFiles, lowerCamelize, sanitize} from './utils';
|
|
5
|
+
import {basename, dirname, extname, relative, resolve} from 'path';
|
|
6
|
+
import yargs from 'yargs/yargs';
|
|
7
|
+
import {hideBin} from 'yargs/helpers';
|
|
8
|
+
import {generateTree, Tree} from './tree';
|
|
9
|
+
|
|
10
|
+
function importName(assetDir: string, file: string): string {
|
|
11
|
+
let importName = file;
|
|
12
|
+
importName = resolve(file);
|
|
13
|
+
|
|
14
|
+
const prefix = resolve(assetDir);
|
|
15
|
+
const prefixIndex = importName.indexOf(prefix);
|
|
16
|
+
if (prefixIndex >= 0) {
|
|
17
|
+
importName = importName.slice(prefixIndex + prefix.length);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
importName = sanitize(importName);
|
|
21
|
+
return importName;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function generatedTemplateInterface(tree: Tree, indent: string = ''): string {
|
|
25
|
+
let generated = '{\n';
|
|
26
|
+
for (const [subname, item] of tree.entries()) {
|
|
27
|
+
if (item instanceof Map) {
|
|
28
|
+
const generatedSub = generatedTemplateInterface(item, indent + ' ');
|
|
29
|
+
generated += indent + ` ${lowerCamelize(subname)}: ${generatedSub}`;
|
|
30
|
+
} else {
|
|
31
|
+
const name = basename(subname);
|
|
32
|
+
generated += indent + ` ${lowerCamelize(name)}: T,\n`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
generated += indent + '}\n';
|
|
36
|
+
return generated;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function generatedCreateCatalogFunction(assetDir: string, tree: Tree): Promise<string> {
|
|
40
|
+
async function rec(tree: Tree, indent: string = '') {
|
|
41
|
+
let generated = '{\n';
|
|
42
|
+
for (const [subname, item] of tree.entries()) {
|
|
43
|
+
if (item instanceof Map) {
|
|
44
|
+
const generatedSub = await rec(item, indent + ' ');
|
|
45
|
+
generated += indent + ` ${lowerCamelize(subname)}: ${generatedSub},\n`;
|
|
46
|
+
} else {
|
|
47
|
+
const stats = await fs.stat(item);
|
|
48
|
+
const name = basename(subname);
|
|
49
|
+
|
|
50
|
+
generated += indent + ` ${lowerCamelize(name)}: createItem(expand(
|
|
51
|
+
${importName(assetDir, item)},
|
|
52
|
+
${stats.size},
|
|
53
|
+
)),\n`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
generated += indent + '}';
|
|
57
|
+
return generated;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let generated = '';
|
|
61
|
+
generated += 'export function createFileCatalog<T>(createItem: (opts: CreateItemOptions) => T): FileCatalog<T> {\n';
|
|
62
|
+
generated += ` return ${await rec(tree, ' ')};\n`;
|
|
63
|
+
generated += '}\n';
|
|
64
|
+
return generated;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function generateExpandFunction() {
|
|
68
|
+
let generated = '';
|
|
69
|
+
generated += 'function expand(path: string, size: number): CreateItemOptions {\n';
|
|
70
|
+
generated += ` return { path, size };\n`;
|
|
71
|
+
generated += '}\n';
|
|
72
|
+
return generated;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function generateResolveFunction() {
|
|
76
|
+
let generated = '';
|
|
77
|
+
generated += 'export function resolveFromCatalog<T>(catalog: FileCatalog<T>, path: string[]): T {\n';
|
|
78
|
+
generated += ' let current: any = catalog;\n';
|
|
79
|
+
generated += ` for (const component of path) {\n`;
|
|
80
|
+
generated += ` if (!(component in current)) throw new Error('Unresolvable catalog path: ' + path.join('.'));\n`;
|
|
81
|
+
generated += ` current = current[component];\n`;
|
|
82
|
+
generated += ` }\n`;
|
|
83
|
+
generated += ` return current as T;\n`;
|
|
84
|
+
generated += '}\n';
|
|
85
|
+
return generated;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function main() {
|
|
89
|
+
const argv = await yargs(hideBin(process.argv))
|
|
90
|
+
.options({
|
|
91
|
+
'outFile': {
|
|
92
|
+
type: 'string',
|
|
93
|
+
default: 'files.ts',
|
|
94
|
+
alias: 'o',
|
|
95
|
+
describe: 'Directory to generate the files into',
|
|
96
|
+
},
|
|
97
|
+
'dir': {
|
|
98
|
+
type: 'string',
|
|
99
|
+
default: '.',
|
|
100
|
+
alias: 'd',
|
|
101
|
+
describe: 'Asset directory where all the PNGs are located',
|
|
102
|
+
},
|
|
103
|
+
})
|
|
104
|
+
.argv;
|
|
105
|
+
|
|
106
|
+
const filesRoot = argv.dir;
|
|
107
|
+
const generatedTs = argv.outFile;
|
|
108
|
+
try {
|
|
109
|
+
await fs.rm(generatedTs, {'recursive': true});
|
|
110
|
+
} catch (e) {
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const files = await allFiles(filesRoot);
|
|
114
|
+
|
|
115
|
+
const imports = [];
|
|
116
|
+
const tree = await generateTree(argv.dir, files);
|
|
117
|
+
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
const importPath = relative(dirname(argv.outFile), file).replace(/\\/g, '/');
|
|
120
|
+
imports.push(`import ${importName(argv.dir, file)} from './${importPath}';`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let generatedFileContent = '';
|
|
124
|
+
generatedFileContent += imports.join('\n');
|
|
125
|
+
generatedFileContent += '\n\n';
|
|
126
|
+
generatedFileContent += `export interface CreateItemOptions {
|
|
127
|
+
path: string;
|
|
128
|
+
size: number;
|
|
129
|
+
}\n\n`;
|
|
130
|
+
generatedFileContent += 'export type FileCatalog<T> = ' + generatedTemplateInterface(tree);
|
|
131
|
+
generatedFileContent += '\n';
|
|
132
|
+
generatedFileContent += generateExpandFunction();
|
|
133
|
+
generatedFileContent += '\n';
|
|
134
|
+
generatedFileContent += generateResolveFunction();
|
|
135
|
+
generatedFileContent += '\n';
|
|
136
|
+
generatedFileContent += await generatedCreateCatalogFunction(argv.dir, tree);
|
|
137
|
+
|
|
138
|
+
await fs.writeFile(generatedTs, generatedFileContent);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
main();
|
|
@@ -90,6 +90,19 @@ function generateExpandFunction() {
|
|
|
90
90
|
return generated;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
function generateResolveFunction() {
|
|
94
|
+
let generated = '\n';
|
|
95
|
+
generated += 'export function resolveFromCatalog<T>(catalog: TextureCatalog<T>, path: string[]): T {\n';
|
|
96
|
+
generated += ' let current = catalog;\n';
|
|
97
|
+
generated += ` for (const component of path) {\n`;
|
|
98
|
+
generated += ` if (!(component in current)) throw new Error('Unresolvable catalog path: ' + path.join('.'));\n`;
|
|
99
|
+
generated += ` current = current[component];\n`;
|
|
100
|
+
generated += ` }\n`;
|
|
101
|
+
generated += ` return current as T;\n`;
|
|
102
|
+
generated += '}\n';
|
|
103
|
+
return generated;
|
|
104
|
+
}
|
|
105
|
+
|
|
93
106
|
async function createSpritesheet(tree: Tree, outFile: string, excludes: string[]): Promise<SpritesheetResult> {
|
|
94
107
|
const bins: (pack.Bin & {path: string})[] = [];
|
|
95
108
|
|
|
@@ -217,11 +230,12 @@ async function main() {
|
|
|
217
230
|
width: number;
|
|
218
231
|
height: number;
|
|
219
232
|
size: number;
|
|
220
|
-
spriteData: SpriteData | null;
|
|
233
|
+
spriteData: SpriteData | null;
|
|
221
234
|
}\n\n`;
|
|
222
235
|
generatedFileContent += 'export type TextureCatalog<T> = ' + generatedTemplateInterface(tree, 'TextureCatalog');
|
|
223
236
|
generatedFileContent += '\n\n';
|
|
224
237
|
generatedFileContent += generateExpandFunction();
|
|
238
|
+
generatedFileContent += generateResolveFunction();
|
|
225
239
|
generatedFileContent += await generatedCreateCatalogFunction(argv.assetDir, tree, spritesheet);
|
|
226
240
|
|
|
227
241
|
await fs.writeFile(generatedTs, generatedFileContent);
|
package/src/tree.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -30,7 +30,7 @@ export function camelize(str: string) {
|
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export function lowerCamelize(str: string): string {
|
|
33
|
-
const camelized =
|
|
33
|
+
const camelized = camelize(str);
|
|
34
34
|
return camelized.slice(0, 1).toLowerCase() + camelized.slice(1);
|
|
35
35
|
}
|
|
36
36
|
|