@hubol/smooch 1.0.0-beta.2 → 1.0.0-beta.4

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/README.md ADDED
@@ -0,0 +1,54 @@
1
+ Opinionated asset transformer and aggregator.
2
+
3
+ ----------------
4
+
5
+ When creating computer games, certain assets need to be destructively transformed in order for the game engine to consume them. For example; textures must be packed into texture atlases, and sound files need to be converted to formats digestible by modern browsers. **smooch** supports transforming directories of assets based on configuration.
6
+
7
+ In addition, it is much more pleasurable to work in environments with a type system. To this end, **smooch** supports generating code files from asset files using configurable template programs.
8
+
9
+ ## Usage
10
+
11
+ <!-- smooch commands -->
12
+ `smooch`
13
+
14
+ Start in watch mode. Aggregates and transforms assets as file changes are detected.
15
+ Probably should be used while developing!
16
+
17
+ `smooch init`
18
+
19
+ Initialize a **smooch.json** configuration file.
20
+
21
+ `smooch copy-program <program> <dst>`
22
+
23
+ Copy a default template JavaScript program **program** to **dst**. Available programs are
24
+ - texture-pack
25
+ - json-aggregate
26
+ - audio-convert
27
+
28
+ `smooch build`
29
+
30
+ Aggregate and transform assets according to your **smooch.json**. Probably should be used on a CI server!
31
+
32
+ `smooch init-native-deps`
33
+
34
+ Produce a **smooch-native-deps.json** configuration file.
35
+ This is for a bizarre subsystem that sidesteps your **package-lock.json**.
36
+ You probably won't need to touch this!
37
+
38
+ `smooch help`
39
+
40
+ List these commands!
41
+ <!-- smooch commands end -->
42
+
43
+ ## Design goals
44
+
45
+ - Not slow
46
+ - Simple installation
47
+ - Zero dependencies
48
+ - Informative console output
49
+ - Watches directories
50
+ - Recovers gracefully from IO errors
51
+ - Supports configurable templates
52
+ - Keeps a cache for faster start-up
53
+ - Build tool agnostic
54
+ - Config file with schema
package/index.js CHANGED
@@ -61408,7 +61408,7 @@ class AudioFileConverter {
61408
61408
  constructor() { }
61409
61409
  static convert(srcFile, dstFile) {
61410
61410
  const start = now_1.Now.ms;
61411
- logger.log(`Converting ${chalk_1.default.blue(srcFile)}
61411
+ logger.log(`Converting ${chalk_1.default.blue(srcFile)}
61412
61412
  => ${chalk_1.default.green(dstFile)}...`);
61413
61413
  return new Promise((resolve, reject) => {
61414
61414
  (0, fluent_ffmpeg_1.default)(this._ffmpegOptions)
@@ -61522,7 +61522,7 @@ function validateOptions(options) {
61522
61522
  if (convert.directory)
61523
61523
  continue;
61524
61524
  convert.directory = path_1.Path.Directory.create(fs_1.Fs.resolve(global_1.Global.cacheDir, makeDirectoryName(options.glob, (_a = convert.zip) !== null && _a !== void 0 ? _a : 'nozip', (0, hubhash_1.hubhash)(`${options.glob}%${convert.zip}`))));
61525
- logger.log(`Generated directory name in cache folder for audio conversion:
61525
+ logger.log(`Generated directory name in cache folder for audio conversion:
61526
61526
  ${chalk_1.default.blue(options.glob)} -> ${chalk_1.default.white(convert.format)} -> ${chalk_1.default[convert.zip ? 'gray' : 'green'](convert.directory)}${convert.zip ? ` -> ${chalk_1.default.green(convert.zip)}` : ''}`);
61527
61527
  }
61528
61528
  return options;
@@ -61545,9 +61545,9 @@ function createZipFileGlobCommands(commands) {
61545
61545
  const previous = zipFilesToGlob[zipFile];
61546
61546
  const current = path_1.Path.Glob.create(command.directory, '**/*');
61547
61547
  if (previous && previous !== current) {
61548
- logger.warn(`Zip file ${zipFile} needs more than one glob to be created:
61549
- - ${previous}
61550
- - ${current}
61548
+ logger.warn(`Zip file ${zipFile} needs more than one glob to be created:
61549
+ - ${previous}
61550
+ - ${current}
61551
61551
  This should not be possible!`);
61552
61552
  }
61553
61553
  zipFilesToGlob[zipFile] = current;
@@ -61785,10 +61785,10 @@ class ErrorPrinter {
61785
61785
  .join(', ');
61786
61786
  const properties = propertiesList ? `[ ${propertiesList} ]` : `<No Additional Properties>`;
61787
61787
  const stack = (_e = error === null || error === void 0 ? void 0 : error.stack) !== null && _e !== void 0 ? _e : '<No Stack>';
61788
- return `${chalk_1.default.gray `Constructor: `}${constructor}
61789
- ${chalk_1.default.gray `Name: `}${name}
61790
- ${chalk_1.default.gray `Message: `}${(0, indent_1.indent)(message, 'Message: '.length)}
61791
- ${chalk_1.default.gray `Properties: `}${properties}
61788
+ return `${chalk_1.default.gray `Constructor: `}${constructor}
61789
+ ${chalk_1.default.gray `Name: `}${name}
61790
+ ${chalk_1.default.gray `Message: `}${(0, indent_1.indent)(message, 'Message: '.length)}
61791
+ ${chalk_1.default.gray `Properties: `}${properties}
61792
61792
  ${chalk_1.default.gray `Stack: `}${(0, indent_1.indent)(stack, 'Stack: '.length)}`;
61793
61793
  }
61794
61794
  }
@@ -62067,14 +62067,14 @@ class Logger {
62067
62067
  }
62068
62068
  error(message, error) {
62069
62069
  if (error)
62070
- this._print('error', `${message}
62070
+ this._print('error', `${message}
62071
62071
  ${error_printer_1.ErrorPrinter.toPrintable(error)}`, []);
62072
62072
  else
62073
62073
  this._print('error', message, []);
62074
62074
  }
62075
62075
  warn(message, error) {
62076
62076
  if (error)
62077
- this._print('warn', `${message}
62077
+ this._print('warn', `${message}
62078
62078
  ${error_printer_1.ErrorPrinter.toPrintable(error)}`, []);
62079
62079
  else
62080
62080
  this._print('warn', message, []);
@@ -62253,7 +62253,7 @@ class NativeDependencies {
62253
62253
  var _a;
62254
62254
  return __awaiter(this, void 0, void 0, function* () {
62255
62255
  const configuredVersions = yield json_file_1.JsonFile.read(global_1.Global.nativeDepsJsonFile).catch(() => {
62256
- logger.log(`Could not read ${chalk_1.default.white(global_1.Global.nativeDepsJsonFile)}
62256
+ logger.log(`Could not read ${chalk_1.default.white(global_1.Global.nativeDepsJsonFile)}
62257
62257
  This is fine unless you want to set explicit versions of native dependencies.`);
62258
62258
  return NativeDependencies.defaultVersions;
62259
62259
  });
@@ -62640,7 +62640,7 @@ class JsTemplate {
62640
62640
  }
62641
62641
  }
62642
62642
  try {
62643
- logger.log(`Rendering ${chalk_1.default.blue(this._srcFile)} with context ${chalk_1.default.magenta((0, describe_brief_1.describeBrief)(context))}
62643
+ logger.log(`Rendering ${chalk_1.default.blue(this._srcFile)} with context ${chalk_1.default.magenta((0, describe_brief_1.describeBrief)(context))}
62644
62644
  => ${chalk_1.default.green(outputFile)}...`);
62645
62645
  const text = yield this._render(context);
62646
62646
  yield fs_1.Fs.writeFile(outputFile, text);
@@ -62867,7 +62867,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
62867
62867
  return (mod && mod.__esModule) ? mod : { "default": mod };
62868
62868
  };
62869
62869
  Object.defineProperty(exports, "__esModule", ({ value: true }));
62870
- exports.runCliUtilCommand = void 0;
62870
+ exports.runCliUtilCommand = exports.getCommandMetadatas = void 0;
62871
62871
  const chalk_1 = __importDefault(__webpack_require__(4061));
62872
62872
  const logger_1 = __webpack_require__(6266);
62873
62873
  const path_1 = __webpack_require__(2947);
@@ -62875,18 +62875,49 @@ const build_1 = __webpack_require__(6898);
62875
62875
  const copy_template_program_1 = __webpack_require__(1047);
62876
62876
  const initialize_1 = __webpack_require__(9446);
62877
62877
  const initialize_native_deps_1 = __webpack_require__(6909);
62878
+ const fs_1 = __webpack_require__(1942);
62878
62879
  const logger = new logger_1.Logger('Commands', 'yellow');
62879
- const help = () => {
62880
- logger.log(`The following commands are available:
62881
- ${Object.keys(cliUtilsCommands).map(x => `- ${chalk_1.default.yellow(x)}`).join('\n')}`);
62882
- return Promise.resolve();
62883
- };
62880
+ const help = () => __awaiter(void 0, void 0, void 0, function* () {
62881
+ const commandMetadatas = yield getCommandMetadatas();
62882
+ logger.log(`The following commands are available:
62883
+ ${commandMetadatas.map(({ name, args, description }) => `${chalk_1.default.yellow(name)}${args ? ` ${args}` : ''}
62884
+ ${description}`).join('\n\n')}`);
62885
+ });
62886
+ function getCommandMetadatas() {
62887
+ return __awaiter(this, void 0, void 0, function* () {
62888
+ return yield Promise.all(Object.entries(cliUtilsCommands)
62889
+ .map(([name, { args, description }]) => __awaiter(this, void 0, void 0, function* () {
62890
+ return ({
62891
+ name,
62892
+ args: yield args,
62893
+ description: yield description,
62894
+ });
62895
+ })));
62896
+ });
62897
+ }
62898
+ exports.getCommandMetadatas = getCommandMetadatas;
62899
+ function cmd(fn, argsOrDescription, description) {
62900
+ return {
62901
+ fn,
62902
+ args: Promise.resolve(description && argsOrDescription),
62903
+ description: Promise.resolve(description !== null && description !== void 0 ? description : argsOrDescription),
62904
+ };
62905
+ }
62884
62906
  const cliUtilsCommands = {
62885
- 'copy-program': (src, dst) => (0, copy_template_program_1.copyTemplateProgram)(src, path_1.Path.File.create(dst)),
62886
- 'init': initialize_1.initializeSmoochConfig,
62887
- 'build': build_1.build,
62888
- 'init-native-deps': initialize_native_deps_1.initializeNativeDepsConfig,
62889
- 'help': help,
62907
+ 'init': cmd(initialize_1.initializeSmoochConfig, `Initialize a **smooch.json** configuration file.`),
62908
+ 'copy-program': cmd((src, dst) => (0, copy_template_program_1.copyTemplateProgram)(src, path_1.Path.File.create(dst)), '<program> <dst>', (() => __awaiter(void 0, void 0, void 0, function* () {
62909
+ const defaultsList = (yield (0, copy_template_program_1.getAvailableTemplatePrograms)())
62910
+ .map(path => fs_1.Fs.parse(path).name)
62911
+ .map(name => `- ${name}`)
62912
+ .join('\n');
62913
+ return `Copy a default template JavaScript program **program** to **dst**. Available programs are
62914
+ ${defaultsList}`;
62915
+ }))()),
62916
+ 'build': cmd(build_1.build, `Aggregate and transform assets according to your **smooch.json**. Probably should be used on a CI server!`),
62917
+ 'init-native-deps': cmd(initialize_native_deps_1.initializeNativeDepsConfig, `Produce a **smooch-native-deps.json** configuration file.
62918
+ This is for a bizarre subsystem that sidesteps your **package-lock.json**.
62919
+ You probably won't need to touch this!`),
62920
+ 'help': cmd(help, `List these commands!`),
62890
62921
  };
62891
62922
  function runCliUtilCommand() {
62892
62923
  return __awaiter(this, void 0, void 0, function* () {
@@ -62897,7 +62928,7 @@ function runCliUtilCommand() {
62897
62928
  if (index === -1)
62898
62929
  continue;
62899
62930
  const commandArgs = args.slice(index + 1);
62900
- yield cliUtilsCommands[command](...commandArgs);
62931
+ yield cliUtilsCommands[command].fn(...commandArgs);
62901
62932
  return true;
62902
62933
  }
62903
62934
  return false;
@@ -62926,7 +62957,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
62926
62957
  return (mod && mod.__esModule) ? mod : { "default": mod };
62927
62958
  };
62928
62959
  Object.defineProperty(exports, "__esModule", ({ value: true }));
62929
- exports.copyTemplateProgram = void 0;
62960
+ exports.getAvailableTemplatePrograms = exports.copyTemplateProgram = void 0;
62930
62961
  const chalk_1 = __importDefault(__webpack_require__(4061));
62931
62962
  const describe_list_1 = __webpack_require__(7353);
62932
62963
  const environment_1 = __webpack_require__(3685);
@@ -62947,17 +62978,23 @@ function copyTemplateProgram(src, dstFile) {
62947
62978
  });
62948
62979
  }
62949
62980
  exports.copyTemplateProgram = copyTemplateProgram;
62950
- function findTemplateProgramFile(src) {
62981
+ function getAvailableTemplatePrograms() {
62951
62982
  return __awaiter(this, void 0, void 0, function* () {
62952
62983
  const glob = path_1.Path.Glob.create(templateProgramDirectory, '*.js');
62953
- const files = yield gwob_1.Gwob.files(glob);
62984
+ return yield gwob_1.Gwob.files(glob);
62985
+ });
62986
+ }
62987
+ exports.getAvailableTemplatePrograms = getAvailableTemplatePrograms;
62988
+ function findTemplateProgramFile(src) {
62989
+ return __awaiter(this, void 0, void 0, function* () {
62990
+ const files = yield getAvailableTemplatePrograms();
62954
62991
  for (const file of files) {
62955
62992
  const { base } = fs_1.Fs.parse(file);
62956
62993
  if (base.includes(src))
62957
62994
  return file;
62958
62995
  }
62959
62996
  const list = (0, describe_list_1.describeList)(files.map(file => fs_1.Fs.parse(file).name));
62960
- logger.log(`Could not find template program to copy.
62997
+ logger.log(`Could not find template program to copy.
62961
62998
  Available template programs: ${chalk_1.default.white(list)}`);
62962
62999
  return null;
62963
63000
  });
@@ -63575,7 +63612,7 @@ class SmoochEffectiveConfig {
63575
63612
  logger.log(`${chalk_1.default.yellow('Hey cutie!')} Configuration appears to have changed.`);
63576
63613
  }
63577
63614
  catch (e) {
63578
- logger.log(`Got an error while reading ${this._file}, assuming configuration changed.
63615
+ logger.log(`Got an error while reading ${this._file}, assuming configuration changed.
63579
63616
  This may be normal if your cache directory was deleted or this is your first time running!`);
63580
63617
  changed = true;
63581
63618
  }
@@ -64208,7 +64245,7 @@ function zipGlob(srcGlob, dstFile, options) {
64208
64245
  // but every ms counts!
64209
64246
  const files = yield gwob_1.Gwob.files(srcGlob);
64210
64247
  const start = now_1.Now.ms;
64211
- logger.log(`Zipping ${chalk_1.default.blue(srcGlob)}
64248
+ logger.log(`Zipping ${chalk_1.default.blue(srcGlob)}
64212
64249
  => ${chalk_1.default.green(dstFile)}...`);
64213
64250
  for (const file of files)
64214
64251
  archive.file(file, { name: file.substring(root.length) });
@@ -94962,7 +94999,7 @@ module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"]
94962
94999
  /***/ ((module) => {
94963
95000
 
94964
95001
  "use strict";
94965
- module.exports = JSON.parse('{"name":"@hubol/smooch","version":"1.0.0-beta.2","description":"Generate texture atlases, browser-compatible audio, and source code from directories","scripts":{"build":"npm run build:json-schema && npm run build:template-api-dts && npm run build:bundle && npm run build:distributable-package-json && npm run build:npm-pack","build:json-schema":"ts-node ./tools/generate-config-schema.ts","build:template-api-dts":"npx tsup lib/template-api.ts --dts-only --dts-resolve","build:bundle":"webpack","build:distributable-package-json":"ts-node ./tools/generate-distributable-package-json.ts","build:npm-pack":"ts-node ./tools/pack.ts ../smooch.tgz","dev:build-and-test":"npm run build && npm run test","dev:start":"node --nolazy -r ts-node/register ./lib/main/dev.ts","test":"ts-node --transpileOnly test/test.ts"},"bin":{"smooch":"index.js"},"author":"Hubol","license":"ISC","devDependencies":{"@jimp/custom":"^0.22.10","@jimp/types":"^0.22.10","@types/archiver":"^5.3.2","@types/fluent-ffmpeg":"^2.1.21","@types/js-beautify":"^1.13.3","@types/sharp":"^0.31.1","archiver":"^6.0.0","chalk":"^4.1.2","change-case":"^4.1.2","fluent-ffmpeg":"^2.1.2","glob":"^10.3.3","image-size":"^1.0.2","js-beautify":"^1.14.9","maxrects-packer":"^2.7.3","minimatch":"^9.0.3","superstruct":"^0.15.5","tree-kill":"^1.2.2","ts-loader":"^9.4.4","ts-node":"^10.9.1","tsup":"^7.2.0","typescript":"^5.0.4","typescript-json-schema":"^0.56.0","webpack":"^5.88.2","webpack-cli":"^5.1.4","webpack-shebang-plugin":"^1.1.8"}}');
95002
+ module.exports = JSON.parse('{"name":"@hubol/smooch","version":"1.0.0-beta.4","description":"Generate texture atlases, browser-compatible audio, and source code from directories","scripts":{"build":"npm run build:json-schema && npm run build:template-api-dts && npm run build:bundle && npm run build:distributable-package-json && npm run build:npm-readme && npm run build:npm-pack","build:json-schema":"ts-node ./tools/generate-config-schema.ts","build:template-api-dts":"npx tsup lib/template-api.ts --dts-only --dts-resolve","build:bundle":"webpack","build:distributable-package-json":"ts-node ./tools/generate-distributable-package-json.ts","build:npm-readme":"ts-node ./tools/generate-npm-readme.ts","build:npm-pack":"ts-node ./tools/pack.ts ../smooch.tgz","dev:build-and-test":"npm run build && npm run test","dev:start":"node --nolazy -r ts-node/register ./lib/main/dev.ts","dev:update-readme":"ts-node ./lib/main/dev.ts ../../tools/update-readme-md.ts","test":"ts-node --transpileOnly test/test.ts"},"bin":{"smooch":"index.js"},"author":"Hubol","license":"ISC","repository":{"type":"git","url":"https://github.com/hubol/smooch.git"},"devDependencies":{"@jimp/custom":"^0.22.10","@jimp/types":"^0.22.10","@types/archiver":"^5.3.2","@types/fluent-ffmpeg":"^2.1.21","@types/js-beautify":"^1.13.3","@types/sharp":"^0.31.1","archiver":"^6.0.0","chalk":"^4.1.2","change-case":"^4.1.2","fluent-ffmpeg":"^2.1.2","glob":"^10.3.3","image-size":"^1.0.2","js-beautify":"^1.14.9","maxrects-packer":"^2.7.3","minimatch":"^9.0.3","superstruct":"^0.15.5","tree-kill":"^1.2.2","ts-loader":"^9.4.4","ts-node":"^10.9.1","tsup":"^7.2.0","typescript":"^5.0.4","typescript-json-schema":"^0.56.0","webpack":"^5.88.2","webpack-cli":"^5.1.4","webpack-shebang-plugin":"^1.1.8"}}');
94966
95003
 
94967
95004
  /***/ })
94968
95005
 
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@hubol/smooch",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.4",
4
4
  "description": "Generate texture atlases, browser-compatible audio, and source code from directories",
5
5
  "bin": {
6
6
  "smooch": "index.js"
7
7
  },
8
8
  "author": "Hubol",
9
- "license": "ISC"
9
+ "license": "ISC",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/hubol/smooch.git"
13
+ }
10
14
  }
@@ -1,14 +1,14 @@
1
- /**
2
- @param {import("smooch/template-api").TemplateContext.AudioConvert} context;
3
- @param {import("smooch/template-api").Utils} utils;
4
- */
5
- module.exports = function ({ files }, { pascal, noext }) {
6
- return `
7
- // This file is generated
8
-
9
- export const Sfx = {
10
- ${files.map(file =>
11
- ` "${pascal(noext(file.path))}": { ogg: "${file.convertedPaths.ogg}", mp3: "${file.convertedPaths.mp3}", }`).join(`,
12
- `)}
13
- }`;
1
+ /**
2
+ @param {import("smooch/template-api").TemplateContext.AudioConvert} context;
3
+ @param {import("smooch/template-api").Utils} utils;
4
+ */
5
+ module.exports = function ({ files }, { pascal, noext }) {
6
+ return `
7
+ // This file is generated
8
+
9
+ export const Sfx = {
10
+ ${files.map(file =>
11
+ ` "${pascal(noext(file.path))}": { ogg: "${file.convertedPaths.ogg}", mp3: "${file.convertedPaths.mp3}", }`).join(`,
12
+ `)}
13
+ }`;
14
14
  }
@@ -1,12 +1,12 @@
1
- /**
2
- @param {import("smooch/template-api").TemplateContext.JsonAggregate} context;
3
- @param {import("smooch/template-api").Utils} utils;
4
- */
5
- module.exports = function ({ files }, { pascal, noext, oneline, json }) {
6
- return `// This file is generated.
7
-
8
- export const JsonFiles = {
9
- ${ files.map(file => ` "${ pascal(noext(file.fileName)) }": ${ oneline(json(file.json)) }`).join(`,
10
- `) }
11
- }`;
1
+ /**
2
+ @param {import("smooch/template-api").TemplateContext.JsonAggregate} context;
3
+ @param {import("smooch/template-api").Utils} utils;
4
+ */
5
+ module.exports = function ({ files }, { pascal, noext, oneline, json }) {
6
+ return `// This file is generated.
7
+
8
+ export const JsonFiles = {
9
+ ${ files.map(file => ` "${ pascal(noext(file.fileName)) }": ${ oneline(json(file.json)) }`).join(`,
10
+ `) }
11
+ }`;
12
12
  }
@@ -1,16 +1,16 @@
1
- /**
2
- @param {import("smooch/template-api").TemplateContext.TexturePack} context;
3
- @param {import("smooch/template-api").Utils} utils;
4
- */
5
- module.exports = function ({ atlases, textures }, { pascal, noext }) {
6
- return `
7
- // This file is generated
8
-
9
- export const Atlases = [ ${atlases.map(x => `"${x.fileName}"`).join(', ')} ];
10
-
11
- export const Txs = {
12
- ${textures.map(tx =>
13
- ` "${pascal(noext(tx.fileName))}": { atlas: "${tx.atlasFileName}", x: ${tx.x}, y: ${tx.y}, width: ${tx.width}, height: ${tx.height} }`).join(`,
14
- `)}
15
- }`;
1
+ /**
2
+ @param {import("smooch/template-api").TemplateContext.TexturePack} context;
3
+ @param {import("smooch/template-api").Utils} utils;
4
+ */
5
+ module.exports = function ({ atlases, textures }, { pascal, noext }) {
6
+ return `
7
+ // This file is generated
8
+
9
+ export const Atlases = [ ${atlases.map(x => `"${x.fileName}"`).join(', ')} ];
10
+
11
+ export const Txs = {
12
+ ${textures.map(tx =>
13
+ ` "${pascal(noext(tx.fileName))}": { atlas: "${tx.atlasFileName}", x: ${tx.x}, y: ${tx.y}, width: ${tx.width}, height: ${tx.height} }`).join(`,
14
+ `)}
15
+ }`;
16
16
  }