@mrdemonwolf/iconwolf 0.1.1 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA8BrE,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAqH7B"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgCrE,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgI7B"}
package/dist/generator.js CHANGED
@@ -8,19 +8,21 @@ import { generateStandardIcon } from './variants/standard.js';
8
8
  import { generateFavicon } from './variants/favicon.js';
9
9
  import { generateSplashIcon } from './variants/splash.js';
10
10
  import { generateAndroidIcons } from './variants/android.js';
11
+ import { applyBanner, shouldApplyBanner } from './utils/banner.js';
11
12
  async function resolveInput(resolvedPath, bgColor, silent) {
12
13
  if (isIconComposerFolder(resolvedPath)) {
13
14
  if (!silent)
14
15
  logger.info(`Apple Icon Composer file: ${resolvedPath}`);
15
16
  const result = await renderIconComposerFolder(resolvedPath);
16
17
  const inputPath = result.composedImagePath;
18
+ const foregroundPath = result.foregroundImagePath;
17
19
  const cleanupPath = path.dirname(result.composedImagePath);
18
20
  if (bgColor === '#FFFFFF') {
19
21
  bgColor = result.extractedBgColor;
20
22
  if (!silent)
21
23
  logger.info(`Extracted background color: ${bgColor}`);
22
24
  }
23
- return { inputPath, cleanupPath, bgColor };
25
+ return { inputPath, foregroundPath, cleanupPath, bgColor };
24
26
  }
25
27
  return { inputPath: resolvedPath, bgColor };
26
28
  }
@@ -37,6 +39,7 @@ export async function generate(options) {
37
39
  throw new Error(`Source not found: ${resolvedInput}`);
38
40
  }
39
41
  let inputPath;
42
+ let foregroundPath;
40
43
  let cleanupPath;
41
44
  let splashPath;
42
45
  let splashCleanupPath;
@@ -44,6 +47,7 @@ export async function generate(options) {
44
47
  // Resolve main input (Apple Icon Composer .icon folder or PNG)
45
48
  const mainInput = await resolveInput(resolvedInput, bgColor, silent);
46
49
  inputPath = mainInput.inputPath;
50
+ foregroundPath = mainInput.foregroundPath;
47
51
  cleanupPath = mainInput.cleanupPath;
48
52
  bgColor = mainInput.bgColor;
49
53
  // Resolve splash input if provided
@@ -53,7 +57,7 @@ export async function generate(options) {
53
57
  throw new Error(`Splash source not found: ${resolvedSplashInput}`);
54
58
  }
55
59
  const splashInput = await resolveInput(resolvedSplashInput, bgColor, silent);
56
- splashPath = splashInput.inputPath;
60
+ splashPath = splashInput.foregroundPath ?? splashInput.inputPath;
57
61
  splashCleanupPath = splashInput.cleanupPath;
58
62
  }
59
63
  // Validate source image
@@ -100,11 +104,19 @@ export async function generate(options) {
100
104
  logger.generated(result);
101
105
  }
102
106
  if (generateAll || variants.splash) {
103
- const result = await generateSplashIcon(splashPath || inputPath, outputDir);
107
+ const result = await generateSplashIcon(splashPath || foregroundPath || inputPath, outputDir);
104
108
  results.push(result);
105
109
  if (!silent)
106
110
  logger.generated(result);
107
111
  }
112
+ // Apply banner overlay if requested
113
+ if (options.banner) {
114
+ for (const result of results) {
115
+ if (shouldApplyBanner(result.filePath)) {
116
+ await applyBanner(result, options.banner);
117
+ }
118
+ }
119
+ }
108
120
  if (!silent)
109
121
  logger.summary(results);
110
122
  return results;
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { generate } from './generator.js';
4
4
  import * as logger from './utils/logger.js';
5
5
  import { resolveDefaultOutputDir } from './utils/paths.js';
6
6
  import { readCachedUpdateInfo, refreshCacheInBackground, } from './utils/update-notifier.js';
7
- const VERSION = '0.1.0';
7
+ const VERSION = '0.2.1';
8
8
  const program = new Command();
9
9
  program
10
10
  .name('iconwolf')
@@ -18,6 +18,9 @@ program
18
18
  .option('--icon', 'Generate standard icon.png only')
19
19
  .option('--splash-input <path>', 'Use a separate image for the splash screen icon')
20
20
  .option('--bg-color <hex>', 'Background color for Android adaptive icon', '#FFFFFF')
21
+ .option('--banner <text>', 'Diagonal ribbon banner text (e.g. DEV, BETA, STAGING)')
22
+ .option('--banner-color <hex>', 'Ribbon color (default: auto from text)')
23
+ .option('--banner-position <pos>', 'Banner position: top-left, top-right, bottom-left, bottom-right', 'top-left')
21
24
  .action(async (input, opts) => {
22
25
  const updateInfo = readCachedUpdateInfo(VERSION);
23
26
  refreshCacheInBackground().catch(() => { });
@@ -32,6 +35,13 @@ program
32
35
  },
33
36
  bgColor: opts.bgColor,
34
37
  splashInputPath: opts.splashInput,
38
+ banner: opts.banner
39
+ ? {
40
+ text: opts.banner,
41
+ color: opts.bannerColor,
42
+ position: opts.bannerPosition,
43
+ }
44
+ : undefined,
35
45
  };
36
46
  try {
37
47
  await generate(options);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAGpC,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CACV,+GAA+G,CAChH;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CACP,SAAS,EACT,6DAA6D,CAC9D;KACA,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC;KAC3E,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;KACnE,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC;KAChD,MAAM,CAAC,UAAU,EAAE,kCAAkC,CAAC;KACtD,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;KACnD,MAAM,CACL,uBAAuB,EACvB,iDAAiD,CAClD;KACA,MAAM,CACL,kBAAkB,EAClB,4CAA4C,EAC5C,SAAS,CACV;KACA,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAI,EAAE,EAAE;IACpC,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACjD,wBAAwB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAE3C,MAAM,OAAO,GAAqB;QAChC,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;SACzB;QACD,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,eAAe,EAAE,IAAI,CAAC,WAAW;KAClC,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QAExB,IAAI,UAAU,EAAE,eAAe,EAAE,CAAC;YAChC,MAAM,CAAC,YAAY,CACjB,UAAU,CAAC,cAAc,EACzB,UAAU,CAAC,aAAa,CACzB,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAGpC,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CACV,+GAA+G,CAChH;KACA,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CACP,SAAS,EACT,6DAA6D,CAC9D;KACA,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC;KAC3E,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;KACnE,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC;KAChD,MAAM,CAAC,UAAU,EAAE,kCAAkC,CAAC;KACtD,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;KACnD,MAAM,CACL,uBAAuB,EACvB,iDAAiD,CAClD;KACA,MAAM,CACL,kBAAkB,EAClB,4CAA4C,EAC5C,SAAS,CACV;KACA,MAAM,CACL,iBAAiB,EACjB,uDAAuD,CACxD;KACA,MAAM,CAAC,sBAAsB,EAAE,wCAAwC,CAAC;KACxE,MAAM,CACL,yBAAyB,EACzB,iEAAiE,EACjE,UAAU,CACX;KACA,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAI,EAAE,EAAE;IACpC,MAAM,UAAU,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACjD,wBAAwB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAE3C,MAAM,OAAO,GAAqB;QAChC,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI,CAAC,MAAM;QACtB,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK;SACzB;QACD,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,eAAe,EAAE,IAAI,CAAC,WAAW;QACjC,MAAM,EAAE,IAAI,CAAC,MAAM;YACjB,CAAC,CAAC;gBACE,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,KAAK,EAAE,IAAI,CAAC,WAAW;gBACvB,QAAQ,EAAE,IAAI,CAAC,cAAgC;aAChD;YACH,CAAC,CAAC,SAAS;KACd,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;QAExB,IAAI,UAAU,EAAE,eAAe,EAAE,CAAC;YAChC,MAAM,CAAC,YAAY,CACjB,UAAU,CAAC,cAAc,EACzB,UAAU,CAAC,aAAa,CACzB,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
package/dist/lib.d.ts CHANGED
@@ -4,7 +4,8 @@ export { generateFavicon } from './variants/favicon.js';
4
4
  export { generateSplashIcon } from './variants/splash.js';
5
5
  export { generateAndroidIcons } from './variants/android.js';
6
6
  export { validateSourceImage } from './utils/image.js';
7
+ export { applyBanner, createBannerSvg, shouldApplyBanner, } from './utils/banner.js';
7
8
  export { isIconComposerFolder, renderIconComposerFolder, } from './utils/icon-composer.js';
8
9
  export { OUTPUT_FILES, resolveOutputPath } from './utils/paths.js';
9
- export type { VariantFlags, GeneratorOptions, GenerationResult, } from './types.js';
10
+ export type { BannerOptions, BannerPosition, VariantFlags, GeneratorOptions, GenerationResult, } from './types.js';
10
11
  //# sourceMappingURL=lib.d.ts.map
package/dist/lib.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACnE,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,WAAW,EACX,eAAe,EACf,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACnE,YAAY,EACV,aAAa,EACb,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
package/dist/lib.js CHANGED
@@ -4,6 +4,7 @@ export { generateFavicon } from './variants/favicon.js';
4
4
  export { generateSplashIcon } from './variants/splash.js';
5
5
  export { generateAndroidIcons } from './variants/android.js';
6
6
  export { validateSourceImage } from './utils/image.js';
7
+ export { applyBanner, createBannerSvg, shouldApplyBanner, } from './utils/banner.js';
7
8
  export { isIconComposerFolder, renderIconComposerFolder, } from './utils/icon-composer.js';
8
9
  export { OUTPUT_FILES, resolveOutputPath } from './utils/paths.js';
9
10
  //# sourceMappingURL=lib.js.map
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EACL,WAAW,EACX,eAAe,EACf,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/types.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ export type BannerPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
2
+ export interface BannerOptions {
3
+ text: string;
4
+ color?: string;
5
+ position?: BannerPosition;
6
+ }
1
7
  export interface VariantFlags {
2
8
  android: boolean;
3
9
  favicon: boolean;
@@ -10,6 +16,7 @@ export interface GeneratorOptions {
10
16
  variants: VariantFlags;
11
17
  bgColor: string;
12
18
  splashInputPath?: string;
19
+ banner?: BannerOptions;
13
20
  silent?: boolean;
14
21
  }
15
22
  export interface GenerationResult {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,WAAW,GACX,aAAa,GACb,cAAc,CAAC;AAEnB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,5 @@
1
+ import type { BannerOptions, BannerPosition, GenerationResult } from '../types.js';
2
+ export declare function createBannerSvg(size: number, text: string, color: string, position: BannerPosition): string;
3
+ export declare function applyBanner(result: GenerationResult, bannerOptions: BannerOptions): Promise<void>;
4
+ export declare function shouldApplyBanner(filePath: string): boolean;
5
+ //# sourceMappingURL=banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/utils/banner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAgBrB,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,cAAc,GACvB,MAAM,CA0CR;AAUD,wBAAsB,WAAW,CAC/B,MAAM,EAAE,gBAAgB,EACxB,aAAa,EAAE,aAAa,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqBf;AASD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -0,0 +1,88 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import sharp from 'sharp';
4
+ const DEFAULT_COLORS = {
5
+ DEV: '#4CAF50',
6
+ BETA: '#FF9800',
7
+ STAGING: '#2196F3',
8
+ ALPHA: '#9C27B0',
9
+ };
10
+ const FALLBACK_COLOR = '#F44336';
11
+ function resolveColor(text, color) {
12
+ if (color)
13
+ return color;
14
+ return DEFAULT_COLORS[text.toUpperCase()] ?? FALLBACK_COLOR;
15
+ }
16
+ export function createBannerSvg(size, text, color, position) {
17
+ const ribbonWidth = Math.round(size * 0.42);
18
+ const ribbonHeight = Math.round(size * 0.08);
19
+ const fontSize = Math.round(ribbonHeight * 0.6);
20
+ const halfDiag = ribbonWidth / 2;
21
+ // Center of the ribbon in each corner
22
+ let cx;
23
+ let cy;
24
+ let angle;
25
+ switch (position) {
26
+ case 'top-left':
27
+ cx = size * 0.2;
28
+ cy = size * 0.2;
29
+ angle = -45;
30
+ break;
31
+ case 'top-right':
32
+ cx = size * 0.8;
33
+ cy = size * 0.2;
34
+ angle = 45;
35
+ break;
36
+ case 'bottom-left':
37
+ cx = size * 0.2;
38
+ cy = size * 0.8;
39
+ angle = 45;
40
+ break;
41
+ case 'bottom-right':
42
+ cx = size * 0.8;
43
+ cy = size * 0.8;
44
+ angle = -45;
45
+ break;
46
+ }
47
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
48
+ <g transform="translate(${cx}, ${cy}) rotate(${angle})">
49
+ <rect x="${-halfDiag}" y="${-ribbonHeight / 2}" width="${ribbonWidth}" height="${ribbonHeight}" fill="${color}"/>
50
+ <text x="0" y="0" text-anchor="middle" dominant-baseline="central"
51
+ font-family="Arial, Helvetica, sans-serif" font-weight="bold"
52
+ font-size="${fontSize}" fill="white">${escapeXml(text)}</text>
53
+ </g>
54
+ </svg>`;
55
+ }
56
+ function escapeXml(s) {
57
+ return s
58
+ .replace(/&/g, '&amp;')
59
+ .replace(/</g, '&lt;')
60
+ .replace(/>/g, '&gt;')
61
+ .replace(/"/g, '&quot;');
62
+ }
63
+ export async function applyBanner(result, bannerOptions) {
64
+ const color = resolveColor(bannerOptions.text, bannerOptions.color);
65
+ const position = bannerOptions.position ?? 'top-left';
66
+ const meta = await sharp(result.filePath).metadata();
67
+ const size = meta.width ?? 1024;
68
+ const svg = createBannerSvg(size, bannerOptions.text, color, position);
69
+ const svgBuffer = Buffer.from(svg);
70
+ const tmpPath = result.filePath + '.tmp';
71
+ await sharp(result.filePath)
72
+ .composite([{ input: svgBuffer, top: 0, left: 0 }])
73
+ .png()
74
+ .toFile(tmpPath);
75
+ fs.renameSync(tmpPath, result.filePath);
76
+ const stat = fs.statSync(result.filePath);
77
+ result.size = stat.size;
78
+ }
79
+ /** Files that should not receive a banner overlay. */
80
+ const SKIP_FILES = new Set([
81
+ 'favicon.png',
82
+ 'android-icon-background.png',
83
+ 'monochrome-icon.png',
84
+ ]);
85
+ export function shouldApplyBanner(filePath) {
86
+ return !SKIP_FILES.has(path.basename(filePath));
87
+ }
88
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/utils/banner.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export interface IconComposerResult {
2
2
  composedImagePath: string;
3
+ foregroundImagePath: string;
3
4
  extractedBgColor: string;
4
5
  }
5
6
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"icon-composer.d.ts","sourceRoot":"","sources":["../../src/utils/icon-composer.ts"],"names":[],"mappings":"AAsCA,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAS/D;AA6HD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAgG7B"}
1
+ {"version":3,"file":"icon-composer.d.ts","sourceRoot":"","sources":["../../src/utils/icon-composer.ts"],"names":[],"mappings":"AA4CA,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAS/D;AA6HD;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA2H7B"}
@@ -128,8 +128,13 @@ export async function renderIconComposerFolder(iconFolderPath) {
128
128
  }
129
129
  const manifestRaw = fs.readFileSync(manifestPath, 'utf-8');
130
130
  const manifest = JSON.parse(manifestRaw);
131
+ // Resolve fill: prefer top-level `fill`, fall back to first `fill-specializations` entry (light appearance)
132
+ const fill = manifest.fill ??
133
+ manifest['fill-specializations']?.find((s) => !s.appearance)?.value ??
134
+ manifest['fill-specializations']?.[0]?.value ??
135
+ {};
131
136
  // Create background
132
- const { buffer: backgroundBuffer, bgColor: extractedBgColor } = await createBackground(manifest.fill);
137
+ const { buffer: backgroundBuffer, bgColor: extractedBgColor } = await createBackground(fill);
133
138
  // Build composite operations for each layer
134
139
  const compositeOps = [];
135
140
  for (const group of manifest.groups) {
@@ -185,15 +190,32 @@ export async function renderIconComposerFolder(iconFolderPath) {
185
190
  compositeOps.push({ input: layerBuffer, left, top });
186
191
  }
187
192
  }
188
- // Compose final image
193
+ // Compose final image (with background)
189
194
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'iconwolf-compose-'));
190
195
  const composedPath = path.join(tmpDir, 'composed-icon.png');
191
196
  await sharp(backgroundBuffer)
192
197
  .composite(compositeOps)
193
198
  .png()
194
199
  .toFile(composedPath);
200
+ // Compose foreground-only image (transparent background) for splash
201
+ const foregroundPath = path.join(tmpDir, 'foreground-icon.png');
202
+ const transparentBg = await sharp({
203
+ create: {
204
+ width: ICON_SIZE,
205
+ height: ICON_SIZE,
206
+ channels: 4,
207
+ background: { r: 0, g: 0, b: 0, alpha: 0 },
208
+ },
209
+ })
210
+ .png()
211
+ .toBuffer();
212
+ await sharp(transparentBg)
213
+ .composite(compositeOps)
214
+ .png()
215
+ .toFile(foregroundPath);
195
216
  return {
196
217
  composedImagePath: composedPath,
218
+ foregroundImagePath: foregroundPath,
197
219
  extractedBgColor,
198
220
  };
199
221
  }
@@ -1 +1 @@
1
- {"version":3,"file":"icon-composer.js","sourceRoot":"","sources":["../../src/utils/icon-composer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"icon-composer.js","sourceRoot":"","sources":["../../src/utils/icon-composer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrdemonwolf/iconwolf",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "A CLI tool that takes an iOS app compositor icon and generates all necessary icon variants for cross-platform use.",
5
5
  "type": "module",
6
6
  "main": "./dist/lib.js",
package/src/generator.ts CHANGED
@@ -11,10 +11,12 @@ import { generateStandardIcon } from './variants/standard.js';
11
11
  import { generateFavicon } from './variants/favicon.js';
12
12
  import { generateSplashIcon } from './variants/splash.js';
13
13
  import { generateAndroidIcons } from './variants/android.js';
14
+ import { applyBanner, shouldApplyBanner } from './utils/banner.js';
14
15
  import type { GeneratorOptions, GenerationResult } from './types.js';
15
16
 
16
17
  interface ResolvedInput {
17
18
  inputPath: string;
19
+ foregroundPath?: string;
18
20
  cleanupPath?: string;
19
21
  bgColor: string;
20
22
  }
@@ -28,6 +30,7 @@ async function resolveInput(
28
30
  if (!silent) logger.info(`Apple Icon Composer file: ${resolvedPath}`);
29
31
  const result = await renderIconComposerFolder(resolvedPath);
30
32
  const inputPath = result.composedImagePath;
33
+ const foregroundPath = result.foregroundImagePath;
31
34
  const cleanupPath = path.dirname(result.composedImagePath);
32
35
 
33
36
  if (bgColor === '#FFFFFF') {
@@ -35,7 +38,7 @@ async function resolveInput(
35
38
  if (!silent) logger.info(`Extracted background color: ${bgColor}`);
36
39
  }
37
40
 
38
- return { inputPath, cleanupPath, bgColor };
41
+ return { inputPath, foregroundPath, cleanupPath, bgColor };
39
42
  }
40
43
 
41
44
  return { inputPath: resolvedPath, bgColor };
@@ -58,6 +61,7 @@ export async function generate(
58
61
  }
59
62
 
60
63
  let inputPath: string;
64
+ let foregroundPath: string | undefined;
61
65
  let cleanupPath: string | undefined;
62
66
  let splashPath: string | undefined;
63
67
  let splashCleanupPath: string | undefined;
@@ -66,6 +70,7 @@ export async function generate(
66
70
  // Resolve main input (Apple Icon Composer .icon folder or PNG)
67
71
  const mainInput = await resolveInput(resolvedInput, bgColor, silent);
68
72
  inputPath = mainInput.inputPath;
73
+ foregroundPath = mainInput.foregroundPath;
69
74
  cleanupPath = mainInput.cleanupPath;
70
75
  bgColor = mainInput.bgColor;
71
76
 
@@ -80,7 +85,7 @@ export async function generate(
80
85
  bgColor,
81
86
  silent,
82
87
  );
83
- splashPath = splashInput.inputPath;
88
+ splashPath = splashInput.foregroundPath ?? splashInput.inputPath;
84
89
  splashCleanupPath = splashInput.cleanupPath;
85
90
  }
86
91
 
@@ -141,13 +146,22 @@ export async function generate(
141
146
 
142
147
  if (generateAll || variants.splash) {
143
148
  const result = await generateSplashIcon(
144
- splashPath || inputPath,
149
+ splashPath || foregroundPath || inputPath,
145
150
  outputDir,
146
151
  );
147
152
  results.push(result);
148
153
  if (!silent) logger.generated(result);
149
154
  }
150
155
 
156
+ // Apply banner overlay if requested
157
+ if (options.banner) {
158
+ for (const result of results) {
159
+ if (shouldApplyBanner(result.filePath)) {
160
+ await applyBanner(result, options.banner);
161
+ }
162
+ }
163
+ }
164
+
151
165
  if (!silent) logger.summary(results);
152
166
 
153
167
  return results;
package/src/index.ts CHANGED
@@ -8,9 +8,9 @@ import {
8
8
  readCachedUpdateInfo,
9
9
  refreshCacheInBackground,
10
10
  } from './utils/update-notifier.js';
11
- import type { GeneratorOptions } from './types.js';
11
+ import type { BannerPosition, GeneratorOptions } from './types.js';
12
12
 
13
- const VERSION = '0.1.0';
13
+ const VERSION = '0.2.1';
14
14
 
15
15
  const program = new Command();
16
16
 
@@ -38,6 +38,16 @@ program
38
38
  'Background color for Android adaptive icon',
39
39
  '#FFFFFF',
40
40
  )
41
+ .option(
42
+ '--banner <text>',
43
+ 'Diagonal ribbon banner text (e.g. DEV, BETA, STAGING)',
44
+ )
45
+ .option('--banner-color <hex>', 'Ribbon color (default: auto from text)')
46
+ .option(
47
+ '--banner-position <pos>',
48
+ 'Banner position: top-left, top-right, bottom-left, bottom-right',
49
+ 'top-left',
50
+ )
41
51
  .action(async (input: string, opts) => {
42
52
  const updateInfo = readCachedUpdateInfo(VERSION);
43
53
  refreshCacheInBackground().catch(() => {});
@@ -53,6 +63,13 @@ program
53
63
  },
54
64
  bgColor: opts.bgColor,
55
65
  splashInputPath: opts.splashInput,
66
+ banner: opts.banner
67
+ ? {
68
+ text: opts.banner,
69
+ color: opts.bannerColor,
70
+ position: opts.bannerPosition as BannerPosition,
71
+ }
72
+ : undefined,
56
73
  };
57
74
 
58
75
  try {
package/src/lib.ts CHANGED
@@ -4,12 +4,19 @@ export { generateFavicon } from './variants/favicon.js';
4
4
  export { generateSplashIcon } from './variants/splash.js';
5
5
  export { generateAndroidIcons } from './variants/android.js';
6
6
  export { validateSourceImage } from './utils/image.js';
7
+ export {
8
+ applyBanner,
9
+ createBannerSvg,
10
+ shouldApplyBanner,
11
+ } from './utils/banner.js';
7
12
  export {
8
13
  isIconComposerFolder,
9
14
  renderIconComposerFolder,
10
15
  } from './utils/icon-composer.js';
11
16
  export { OUTPUT_FILES, resolveOutputPath } from './utils/paths.js';
12
17
  export type {
18
+ BannerOptions,
19
+ BannerPosition,
13
20
  VariantFlags,
14
21
  GeneratorOptions,
15
22
  GenerationResult,
package/src/types.ts CHANGED
@@ -1,3 +1,15 @@
1
+ export type BannerPosition =
2
+ | 'top-left'
3
+ | 'top-right'
4
+ | 'bottom-left'
5
+ | 'bottom-right';
6
+
7
+ export interface BannerOptions {
8
+ text: string;
9
+ color?: string;
10
+ position?: BannerPosition;
11
+ }
12
+
1
13
  export interface VariantFlags {
2
14
  android: boolean;
3
15
  favicon: boolean;
@@ -11,6 +23,7 @@ export interface GeneratorOptions {
11
23
  variants: VariantFlags;
12
24
  bgColor: string;
13
25
  splashInputPath?: string;
26
+ banner?: BannerOptions;
14
27
  silent?: boolean;
15
28
  }
16
29
 
@@ -0,0 +1,116 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import sharp from 'sharp';
4
+ import type {
5
+ BannerOptions,
6
+ BannerPosition,
7
+ GenerationResult,
8
+ } from '../types.js';
9
+
10
+ const DEFAULT_COLORS: Record<string, string> = {
11
+ DEV: '#4CAF50',
12
+ BETA: '#FF9800',
13
+ STAGING: '#2196F3',
14
+ ALPHA: '#9C27B0',
15
+ };
16
+
17
+ const FALLBACK_COLOR = '#F44336';
18
+
19
+ function resolveColor(text: string, color?: string): string {
20
+ if (color) return color;
21
+ return DEFAULT_COLORS[text.toUpperCase()] ?? FALLBACK_COLOR;
22
+ }
23
+
24
+ export function createBannerSvg(
25
+ size: number,
26
+ text: string,
27
+ color: string,
28
+ position: BannerPosition,
29
+ ): string {
30
+ const ribbonWidth = Math.round(size * 0.42);
31
+ const ribbonHeight = Math.round(size * 0.08);
32
+ const fontSize = Math.round(ribbonHeight * 0.6);
33
+ const halfDiag = ribbonWidth / 2;
34
+
35
+ // Center of the ribbon in each corner
36
+ let cx: number;
37
+ let cy: number;
38
+ let angle: number;
39
+
40
+ switch (position) {
41
+ case 'top-left':
42
+ cx = size * 0.2;
43
+ cy = size * 0.2;
44
+ angle = -45;
45
+ break;
46
+ case 'top-right':
47
+ cx = size * 0.8;
48
+ cy = size * 0.2;
49
+ angle = 45;
50
+ break;
51
+ case 'bottom-left':
52
+ cx = size * 0.2;
53
+ cy = size * 0.8;
54
+ angle = 45;
55
+ break;
56
+ case 'bottom-right':
57
+ cx = size * 0.8;
58
+ cy = size * 0.8;
59
+ angle = -45;
60
+ break;
61
+ }
62
+
63
+ return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
64
+ <g transform="translate(${cx}, ${cy}) rotate(${angle})">
65
+ <rect x="${-halfDiag}" y="${-ribbonHeight / 2}" width="${ribbonWidth}" height="${ribbonHeight}" fill="${color}"/>
66
+ <text x="0" y="0" text-anchor="middle" dominant-baseline="central"
67
+ font-family="Arial, Helvetica, sans-serif" font-weight="bold"
68
+ font-size="${fontSize}" fill="white">${escapeXml(text)}</text>
69
+ </g>
70
+ </svg>`;
71
+ }
72
+
73
+ function escapeXml(s: string): string {
74
+ return s
75
+ .replace(/&/g, '&amp;')
76
+ .replace(/</g, '&lt;')
77
+ .replace(/>/g, '&gt;')
78
+ .replace(/"/g, '&quot;');
79
+ }
80
+
81
+ export async function applyBanner(
82
+ result: GenerationResult,
83
+ bannerOptions: BannerOptions,
84
+ ): Promise<void> {
85
+ const color = resolveColor(bannerOptions.text, bannerOptions.color);
86
+ const position = bannerOptions.position ?? 'top-left';
87
+
88
+ const meta = await sharp(result.filePath).metadata();
89
+ const size = meta.width ?? 1024;
90
+
91
+ const svg = createBannerSvg(size, bannerOptions.text, color, position);
92
+ const svgBuffer = Buffer.from(svg);
93
+
94
+ const tmpPath = result.filePath + '.tmp';
95
+
96
+ await sharp(result.filePath)
97
+ .composite([{ input: svgBuffer, top: 0, left: 0 }])
98
+ .png()
99
+ .toFile(tmpPath);
100
+
101
+ fs.renameSync(tmpPath, result.filePath);
102
+
103
+ const stat = fs.statSync(result.filePath);
104
+ result.size = stat.size;
105
+ }
106
+
107
+ /** Files that should not receive a banner overlay. */
108
+ const SKIP_FILES = new Set([
109
+ 'favicon.png',
110
+ 'android-icon-background.png',
111
+ 'monochrome-icon.png',
112
+ ]);
113
+
114
+ export function shouldApplyBanner(filePath: string): boolean {
115
+ return !SKIP_FILES.has(path.basename(filePath));
116
+ }
@@ -30,14 +30,21 @@ interface IconComposerGroup {
30
30
  translucency?: { enabled: boolean; value: number };
31
31
  }
32
32
 
33
+ interface IconComposerFillSpecialization {
34
+ appearance?: string;
35
+ value: IconComposerFill;
36
+ }
37
+
33
38
  interface IconComposerManifest {
34
- fill: IconComposerFill;
39
+ fill?: IconComposerFill;
40
+ 'fill-specializations'?: IconComposerFillSpecialization[];
35
41
  groups: IconComposerGroup[];
36
42
  'supported-platforms'?: unknown;
37
43
  }
38
44
 
39
45
  export interface IconComposerResult {
40
46
  composedImagePath: string;
47
+ foregroundImagePath: string;
41
48
  extractedBgColor: string;
42
49
  }
43
50
 
@@ -195,9 +202,16 @@ export async function renderIconComposerFolder(
195
202
  const manifestRaw = fs.readFileSync(manifestPath, 'utf-8');
196
203
  const manifest: IconComposerManifest = JSON.parse(manifestRaw);
197
204
 
205
+ // Resolve fill: prefer top-level `fill`, fall back to first `fill-specializations` entry (light appearance)
206
+ const fill: IconComposerFill =
207
+ manifest.fill ??
208
+ manifest['fill-specializations']?.find((s) => !s.appearance)?.value ??
209
+ manifest['fill-specializations']?.[0]?.value ??
210
+ {};
211
+
198
212
  // Create background
199
213
  const { buffer: backgroundBuffer, bgColor: extractedBgColor } =
200
- await createBackground(manifest.fill);
214
+ await createBackground(fill);
201
215
 
202
216
  // Build composite operations for each layer
203
217
  const compositeOps: sharp.OverlayOptions[] = [];
@@ -267,7 +281,7 @@ export async function renderIconComposerFolder(
267
281
  }
268
282
  }
269
283
 
270
- // Compose final image
284
+ // Compose final image (with background)
271
285
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'iconwolf-compose-'));
272
286
  const composedPath = path.join(tmpDir, 'composed-icon.png');
273
287
 
@@ -276,8 +290,28 @@ export async function renderIconComposerFolder(
276
290
  .png()
277
291
  .toFile(composedPath);
278
292
 
293
+ // Compose foreground-only image (transparent background) for splash
294
+ const foregroundPath = path.join(tmpDir, 'foreground-icon.png');
295
+
296
+ const transparentBg = await sharp({
297
+ create: {
298
+ width: ICON_SIZE,
299
+ height: ICON_SIZE,
300
+ channels: 4,
301
+ background: { r: 0, g: 0, b: 0, alpha: 0 },
302
+ },
303
+ })
304
+ .png()
305
+ .toBuffer();
306
+
307
+ await sharp(transparentBg)
308
+ .composite(compositeOps)
309
+ .png()
310
+ .toFile(foregroundPath);
311
+
279
312
  return {
280
313
  composedImagePath: composedPath,
314
+ foregroundImagePath: foregroundPath,
281
315
  extractedBgColor,
282
316
  };
283
317
  }
package/tests/cli.test.ts CHANGED
@@ -40,6 +40,9 @@ describe('CLI end-to-end', () => {
40
40
  expect(output).toContain('--icon');
41
41
  expect(output).toContain('--splash-input');
42
42
  expect(output).toContain('--bg-color');
43
+ expect(output).toContain('--banner');
44
+ expect(output).toContain('--banner-color');
45
+ expect(output).toContain('--banner-position');
43
46
  });
44
47
 
45
48
  it('generates icon.png via CLI with --icon flag', () => {
@@ -73,6 +76,14 @@ describe('CLI end-to-end', () => {
73
76
  }).toThrow();
74
77
  });
75
78
 
79
+ it('generates icon with --banner DEV flag', () => {
80
+ const outDir = path.join(tmpDir, 'cli-banner');
81
+
82
+ runCli(`${testPng} --icon --banner DEV -o ${outDir}`);
83
+
84
+ expect(fs.existsSync(path.join(outDir, 'icon.png'))).toBe(true);
85
+ });
86
+
76
87
  it('generates favicon when --favicon flag is used', () => {
77
88
  const outDir = path.join(tmpDir, 'cli-favicon');
78
89
 
@@ -347,6 +347,54 @@ describe('generate', () => {
347
347
  expect(fs.existsSync(path.join(outDir, 'splash-icon.png'))).toBe(true);
348
348
  });
349
349
 
350
+ it('applies banner to icon, adaptive-icon, and splash but not favicon', async () => {
351
+ const outDir = path.join(tmpDir, 'banner-test');
352
+
353
+ const results = await generate({
354
+ inputPath: testPng,
355
+ outputDir: outDir,
356
+ variants: { android: false, favicon: false, splash: false, icon: false },
357
+ bgColor: '#FFFFFF',
358
+ banner: { text: 'DEV' },
359
+ });
360
+
361
+ // All 4 default files should exist
362
+ expect(fs.existsSync(path.join(outDir, OUTPUT_FILES.icon))).toBe(true);
363
+ expect(fs.existsSync(path.join(outDir, OUTPUT_FILES.favicon))).toBe(true);
364
+ expect(fs.existsSync(path.join(outDir, OUTPUT_FILES.splashIcon))).toBe(
365
+ true,
366
+ );
367
+ expect(
368
+ fs.existsSync(path.join(outDir, OUTPUT_FILES.androidForeground)),
369
+ ).toBe(true);
370
+ expect(results.length).toBe(4);
371
+ });
372
+
373
+ it('skips banner on background and monochrome android variants', async () => {
374
+ const outDir = path.join(tmpDir, 'banner-android');
375
+
376
+ const results = await generate({
377
+ inputPath: testPng,
378
+ outputDir: outDir,
379
+ variants: { android: true, favicon: false, splash: false, icon: false },
380
+ bgColor: '#FFFFFF',
381
+ banner: { text: 'STAGING', color: '#2196F3' },
382
+ });
383
+
384
+ // adaptive-icon.png should exist (banner applied)
385
+ expect(
386
+ fs.existsSync(path.join(outDir, OUTPUT_FILES.androidForeground)),
387
+ ).toBe(true);
388
+ // background and monochrome should exist (no banner)
389
+ expect(
390
+ fs.existsSync(path.join(outDir, OUTPUT_FILES.androidBackground)),
391
+ ).toBe(true);
392
+ expect(
393
+ fs.existsSync(path.join(outDir, OUTPUT_FILES.androidMonochrome)),
394
+ ).toBe(true);
395
+ expect(results.length).toBe(3);
396
+ });
397
+
350
398
  it('throws on missing splash input file', async () => {
351
399
  const outDir = path.join(tmpDir, 'splash-missing');
352
400
 
@@ -0,0 +1,142 @@
1
+ import fs from 'node:fs';
2
+ import sharp from 'sharp';
3
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
4
+ import {
5
+ createBannerSvg,
6
+ applyBanner,
7
+ shouldApplyBanner,
8
+ } from '../../src/utils/banner.js';
9
+ import { createTestPng, createTmpDir, cleanDir } from '../helpers.js';
10
+
11
+ let tmpDir: string;
12
+
13
+ beforeAll(() => {
14
+ tmpDir = createTmpDir();
15
+ });
16
+
17
+ afterAll(() => {
18
+ cleanDir(tmpDir);
19
+ });
20
+
21
+ describe('createBannerSvg', () => {
22
+ it('generates valid SVG with correct dimensions', () => {
23
+ const svg = createBannerSvg(1024, 'DEV', '#4CAF50', 'top-left');
24
+ expect(svg).toContain('width="1024"');
25
+ expect(svg).toContain('height="1024"');
26
+ expect(svg).toContain('DEV');
27
+ expect(svg).toContain('#4CAF50');
28
+ });
29
+
30
+ it('renders different positions', () => {
31
+ const positions = [
32
+ 'top-left',
33
+ 'top-right',
34
+ 'bottom-left',
35
+ 'bottom-right',
36
+ ] as const;
37
+
38
+ for (const pos of positions) {
39
+ const svg = createBannerSvg(1024, 'BETA', '#FF9800', pos);
40
+ expect(svg).toContain('BETA');
41
+ expect(svg).toContain('<svg');
42
+ }
43
+ });
44
+
45
+ it('escapes XML characters in text', () => {
46
+ const svg = createBannerSvg(1024, 'A&B<C>', '#FF0000', 'top-left');
47
+ expect(svg).toContain('A&amp;B&lt;C&gt;');
48
+ });
49
+
50
+ it('scales ribbon proportionally to icon size', () => {
51
+ const svg512 = createBannerSvg(512, 'DEV', '#4CAF50', 'top-left');
52
+ const svg1024 = createBannerSvg(1024, 'DEV', '#4CAF50', 'top-left');
53
+ expect(svg512).toContain('width="512"');
54
+ expect(svg1024).toContain('width="1024"');
55
+ });
56
+ });
57
+
58
+ describe('applyBanner', () => {
59
+ it('composites banner onto a PNG file', async () => {
60
+ const pngPath = await createTestPng(1024, 1024, tmpDir, 'banner-test.png');
61
+ const originalSize = fs.statSync(pngPath).size;
62
+
63
+ const result = {
64
+ filePath: pngPath,
65
+ width: 1024,
66
+ height: 1024,
67
+ size: originalSize,
68
+ };
69
+
70
+ await applyBanner(result, { text: 'DEV' });
71
+
72
+ expect(fs.existsSync(pngPath)).toBe(true);
73
+ // The file should still be a valid PNG
74
+ const meta = await sharp(pngPath).metadata();
75
+ expect(meta.width).toBe(1024);
76
+ expect(meta.height).toBe(1024);
77
+ expect(meta.format).toBe('png');
78
+ // Size in result should be updated
79
+ expect(result.size).toBe(fs.statSync(pngPath).size);
80
+ });
81
+
82
+ it('uses custom color when provided', async () => {
83
+ const pngPath = await createTestPng(
84
+ 1024,
85
+ 1024,
86
+ tmpDir,
87
+ 'banner-custom-color.png',
88
+ );
89
+ const result = {
90
+ filePath: pngPath,
91
+ width: 1024,
92
+ height: 1024,
93
+ size: fs.statSync(pngPath).size,
94
+ };
95
+
96
+ await applyBanner(result, { text: 'TEST', color: '#FF00FF' });
97
+
98
+ const meta = await sharp(pngPath).metadata();
99
+ expect(meta.width).toBe(1024);
100
+ });
101
+
102
+ it('uses custom position', async () => {
103
+ const pngPath = await createTestPng(1024, 1024, tmpDir, 'banner-pos.png');
104
+ const result = {
105
+ filePath: pngPath,
106
+ width: 1024,
107
+ height: 1024,
108
+ size: fs.statSync(pngPath).size,
109
+ };
110
+
111
+ await applyBanner(result, { text: 'DEV', position: 'bottom-right' });
112
+
113
+ const meta = await sharp(pngPath).metadata();
114
+ expect(meta.width).toBe(1024);
115
+ });
116
+ });
117
+
118
+ describe('shouldApplyBanner', () => {
119
+ it('returns true for icon.png', () => {
120
+ expect(shouldApplyBanner('/out/icon.png')).toBe(true);
121
+ });
122
+
123
+ it('returns true for adaptive-icon.png', () => {
124
+ expect(shouldApplyBanner('/out/adaptive-icon.png')).toBe(true);
125
+ });
126
+
127
+ it('returns true for splash-icon.png', () => {
128
+ expect(shouldApplyBanner('/out/splash-icon.png')).toBe(true);
129
+ });
130
+
131
+ it('returns false for favicon.png', () => {
132
+ expect(shouldApplyBanner('/out/favicon.png')).toBe(false);
133
+ });
134
+
135
+ it('returns false for android-icon-background.png', () => {
136
+ expect(shouldApplyBanner('/out/android-icon-background.png')).toBe(false);
137
+ });
138
+
139
+ it('returns false for monochrome-icon.png', () => {
140
+ expect(shouldApplyBanner('/out/monochrome-icon.png')).toBe(false);
141
+ });
142
+ });