@invarn/cibuild 2.9.5 → 2.9.7

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.
Files changed (553) hide show
  1. package/dist/chunk-35SI42CD.mjs +1 -0
  2. package/dist/chunk-IC45KVLJ.mjs +1 -0
  3. package/dist/chunk-XDY4V23V.mjs +1 -0
  4. package/dist/cli.cjs +14 -14
  5. package/dist/commands.mjs +1 -0
  6. package/dist/lib.mjs +3934 -0
  7. package/package.json +6 -10
  8. package/dist/src/cli.d.ts +0 -3
  9. package/dist/src/cli.d.ts.map +0 -1
  10. package/dist/src/cli.js +0 -399
  11. package/dist/src/commands/a-credential-target-follows-the-flavor-source-set.test.d.ts +0 -38
  12. package/dist/src/commands/a-credential-target-follows-the-flavor-source-set.test.d.ts.map +0 -1
  13. package/dist/src/commands/a-credential-target-follows-the-flavor-source-set.test.js +0 -222
  14. package/dist/src/commands/a-credential-two-workflows-cannot-share-is-declared-per-workflow.test.d.ts +0 -41
  15. package/dist/src/commands/a-credential-two-workflows-cannot-share-is-declared-per-workflow.test.d.ts.map +0 -1
  16. package/dist/src/commands/a-credential-two-workflows-cannot-share-is-declared-per-workflow.test.js +0 -324
  17. package/dist/src/commands/a-properties-stand-in-declares-the-keys-the-build-reads.test.d.ts +0 -2
  18. package/dist/src/commands/a-properties-stand-in-declares-the-keys-the-build-reads.test.d.ts.map +0 -1
  19. package/dist/src/commands/a-properties-stand-in-declares-the-keys-the-build-reads.test.js +0 -382
  20. package/dist/src/commands/an-already-stored-value-does-not-answer-the-target-question.test.d.ts +0 -29
  21. package/dist/src/commands/an-already-stored-value-does-not-answer-the-target-question.test.d.ts.map +0 -1
  22. package/dist/src/commands/an-already-stored-value-does-not-answer-the-target-question.test.js +0 -160
  23. package/dist/src/commands/android-gms-guard.test.d.ts +0 -9
  24. package/dist/src/commands/android-gms-guard.test.d.ts.map +0 -1
  25. package/dist/src/commands/android-gms-guard.test.js +0 -78
  26. package/dist/src/commands/android-java-version.test.d.ts +0 -12
  27. package/dist/src/commands/android-java-version.test.d.ts.map +0 -1
  28. package/dist/src/commands/android-java-version.test.js +0 -209
  29. package/dist/src/commands/android-scanner-java.test.d.ts +0 -2
  30. package/dist/src/commands/android-scanner-java.test.d.ts.map +0 -1
  31. package/dist/src/commands/android-scanner-java.test.js +0 -130
  32. package/dist/src/commands/android-scanner.d.ts +0 -250
  33. package/dist/src/commands/android-scanner.d.ts.map +0 -1
  34. package/dist/src/commands/android-scanner.js +0 -1639
  35. package/dist/src/commands/build.d.ts +0 -215
  36. package/dist/src/commands/build.d.ts.map +0 -1
  37. package/dist/src/commands/build.js +0 -1433
  38. package/dist/src/commands/build.test.d.ts +0 -13
  39. package/dist/src/commands/build.test.d.ts.map +0 -1
  40. package/dist/src/commands/build.test.js +0 -121
  41. package/dist/src/commands/detect-platform.d.ts +0 -13
  42. package/dist/src/commands/detect-platform.d.ts.map +0 -1
  43. package/dist/src/commands/detect-platform.js +0 -51
  44. package/dist/src/commands/detect-project.d.ts +0 -7
  45. package/dist/src/commands/detect-project.d.ts.map +0 -1
  46. package/dist/src/commands/detect-project.js +0 -12
  47. package/dist/src/commands/each-flavor-is-asked-for-its-own-properties-file.test.d.ts +0 -26
  48. package/dist/src/commands/each-flavor-is-asked-for-its-own-properties-file.test.d.ts.map +0 -1
  49. package/dist/src/commands/each-flavor-is-asked-for-its-own-properties-file.test.js +0 -196
  50. package/dist/src/commands/edit.d.ts +0 -12
  51. package/dist/src/commands/edit.d.ts.map +0 -1
  52. package/dist/src/commands/edit.js +0 -652
  53. package/dist/src/commands/edit.test.d.ts +0 -6
  54. package/dist/src/commands/edit.test.d.ts.map +0 -1
  55. package/dist/src/commands/edit.test.js +0 -45
  56. package/dist/src/commands/fidelity-trim.d.ts +0 -13
  57. package/dist/src/commands/fidelity-trim.d.ts.map +0 -1
  58. package/dist/src/commands/fidelity-trim.js +0 -21
  59. package/dist/src/commands/fidelity-trim.test.d.ts +0 -8
  60. package/dist/src/commands/fidelity-trim.test.d.ts.map +0 -1
  61. package/dist/src/commands/fidelity-trim.test.js +0 -79
  62. package/dist/src/commands/file-secret-collector.d.ts +0 -50
  63. package/dist/src/commands/file-secret-collector.d.ts.map +0 -1
  64. package/dist/src/commands/file-secret-collector.js +0 -217
  65. package/dist/src/commands/flavors-a-convention-plugin-creates-are-still-found.test.d.ts +0 -38
  66. package/dist/src/commands/flavors-a-convention-plugin-creates-are-still-found.test.d.ts.map +0 -1
  67. package/dist/src/commands/flavors-a-convention-plugin-creates-are-still-found.test.js +0 -300
  68. package/dist/src/commands/github-workflow.d.ts +0 -5
  69. package/dist/src/commands/github-workflow.d.ts.map +0 -1
  70. package/dist/src/commands/github-workflow.js +0 -45
  71. package/dist/src/commands/index.d.ts +0 -33
  72. package/dist/src/commands/index.d.ts.map +0 -1
  73. package/dist/src/commands/index.js +0 -33
  74. package/dist/src/commands/init.d.ts +0 -20
  75. package/dist/src/commands/init.d.ts.map +0 -1
  76. package/dist/src/commands/init.js +0 -264
  77. package/dist/src/commands/ios-scanner.d.ts +0 -104
  78. package/dist/src/commands/ios-scanner.d.ts.map +0 -1
  79. package/dist/src/commands/ios-scanner.js +0 -492
  80. package/dist/src/commands/ios-scheme-ranking.test.d.ts +0 -2
  81. package/dist/src/commands/ios-scheme-ranking.test.d.ts.map +0 -1
  82. package/dist/src/commands/ios-scheme-ranking.test.js +0 -264
  83. package/dist/src/commands/local-properties-reaches-every-workflow.test.d.ts +0 -30
  84. package/dist/src/commands/local-properties-reaches-every-workflow.test.d.ts.map +0 -1
  85. package/dist/src/commands/local-properties-reaches-every-workflow.test.js +0 -146
  86. package/dist/src/commands/reset.d.ts +0 -7
  87. package/dist/src/commands/reset.d.ts.map +0 -1
  88. package/dist/src/commands/reset.js +0 -81
  89. package/dist/src/commands/run.d.ts +0 -22
  90. package/dist/src/commands/run.d.ts.map +0 -1
  91. package/dist/src/commands/run.js +0 -141
  92. package/dist/src/commands/secrets-sync-workflow.d.ts +0 -15
  93. package/dist/src/commands/secrets-sync-workflow.d.ts.map +0 -1
  94. package/dist/src/commands/secrets-sync-workflow.js +0 -255
  95. package/dist/src/commands/secrets-upload.d.ts +0 -21
  96. package/dist/src/commands/secrets-upload.d.ts.map +0 -1
  97. package/dist/src/commands/secrets-upload.js +0 -177
  98. package/dist/src/commands/secrets-upload.test.d.ts +0 -5
  99. package/dist/src/commands/secrets-upload.test.d.ts.map +0 -1
  100. package/dist/src/commands/secrets-upload.test.js +0 -60
  101. package/dist/src/commands/validate.d.ts +0 -10
  102. package/dist/src/commands/validate.d.ts.map +0 -1
  103. package/dist/src/commands/validate.js +0 -46
  104. package/dist/src/config.d.ts +0 -3
  105. package/dist/src/config.d.ts.map +0 -1
  106. package/dist/src/config.js +0 -47
  107. package/dist/src/envman/cli.d.ts +0 -21
  108. package/dist/src/envman/cli.d.ts.map +0 -1
  109. package/dist/src/envman/cli.js +0 -240
  110. package/dist/src/envman/envman.d.ts +0 -83
  111. package/dist/src/envman/envman.d.ts.map +0 -1
  112. package/dist/src/envman/envman.js +0 -361
  113. package/dist/src/envman/envman.test.d.ts +0 -5
  114. package/dist/src/envman/envman.test.d.ts.map +0 -1
  115. package/dist/src/envman/envman.test.js +0 -236
  116. package/dist/src/envman/envstore-round-trip.test.d.ts +0 -27
  117. package/dist/src/envman/envstore-round-trip.test.d.ts.map +0 -1
  118. package/dist/src/envman/envstore-round-trip.test.js +0 -130
  119. package/dist/src/envman/index.d.ts +0 -23
  120. package/dist/src/envman/index.d.ts.map +0 -1
  121. package/dist/src/envman/index.js +0 -23
  122. package/dist/src/envman/shim.d.ts +0 -16
  123. package/dist/src/envman/shim.d.ts.map +0 -1
  124. package/dist/src/envman/shim.js +0 -66
  125. package/dist/src/envman/types.d.ts +0 -55
  126. package/dist/src/envman/types.d.ts.map +0 -1
  127. package/dist/src/envman/types.js +0 -12
  128. package/dist/src/lib.d.ts +0 -33
  129. package/dist/src/lib.d.ts.map +0 -1
  130. package/dist/src/lib.js +0 -37
  131. package/dist/src/pipeline.d.ts +0 -3
  132. package/dist/src/pipeline.d.ts.map +0 -1
  133. package/dist/src/pipeline.js +0 -57
  134. package/dist/src/runner-node-step.test.d.ts +0 -12
  135. package/dist/src/runner-node-step.test.d.ts.map +0 -1
  136. package/dist/src/runner-node-step.test.js +0 -61
  137. package/dist/src/runner.d.ts +0 -31
  138. package/dist/src/runner.d.ts.map +0 -1
  139. package/dist/src/runner.js +0 -240
  140. package/dist/src/shared/detect-project.d.ts +0 -57
  141. package/dist/src/shared/detect-project.d.ts.map +0 -1
  142. package/dist/src/shared/detect-project.js +0 -219
  143. package/dist/src/shared/detect-project.test.d.ts +0 -2
  144. package/dist/src/shared/detect-project.test.d.ts.map +0 -1
  145. package/dist/src/shared/detect-project.test.js +0 -161
  146. package/dist/src/shared/git.d.ts +0 -25
  147. package/dist/src/shared/git.d.ts.map +0 -1
  148. package/dist/src/shared/git.js +0 -53
  149. package/dist/src/shared/git.test.d.ts +0 -9
  150. package/dist/src/shared/git.test.d.ts.map +0 -1
  151. package/dist/src/shared/git.test.js +0 -66
  152. package/dist/src/shared/gitignore.d.ts +0 -6
  153. package/dist/src/shared/gitignore.d.ts.map +0 -1
  154. package/dist/src/shared/gitignore.js +0 -26
  155. package/dist/src/shared/gradle-settings.d.ts +0 -49
  156. package/dist/src/shared/gradle-settings.d.ts.map +0 -1
  157. package/dist/src/shared/gradle-settings.js +0 -138
  158. package/dist/src/shared/gradle-settings.test.d.ts +0 -2
  159. package/dist/src/shared/gradle-settings.test.d.ts.map +0 -1
  160. package/dist/src/shared/gradle-settings.test.js +0 -65
  161. package/dist/src/shared/prompts.d.ts +0 -30
  162. package/dist/src/shared/prompts.d.ts.map +0 -1
  163. package/dist/src/shared/prompts.js +0 -121
  164. package/dist/src/shared/xcode-container.test.d.ts +0 -2
  165. package/dist/src/shared/xcode-container.test.d.ts.map +0 -1
  166. package/dist/src/shared/xcode-container.test.js +0 -123
  167. package/dist/src/step-marker.d.ts +0 -12
  168. package/dist/src/step-marker.d.ts.map +0 -1
  169. package/dist/src/step-marker.js +0 -29
  170. package/dist/src/step-marker.test.d.ts +0 -11
  171. package/dist/src/step-marker.test.d.ts.map +0 -1
  172. package/dist/src/step-marker.test.js +0 -45
  173. package/dist/src/types.d.ts +0 -58
  174. package/dist/src/types.d.ts.map +0 -1
  175. package/dist/src/types.js +0 -2
  176. package/dist/src/yaml/a-cache-path-must-not-swallow-a-credential.test.d.ts +0 -28
  177. package/dist/src/yaml/a-cache-path-must-not-swallow-a-credential.test.d.ts.map +0 -1
  178. package/dist/src/yaml/a-cache-path-must-not-swallow-a-credential.test.js +0 -223
  179. package/dist/src/yaml/a-declared-secret-reaches-the-file-step.test.d.ts +0 -20
  180. package/dist/src/yaml/a-declared-secret-reaches-the-file-step.test.d.ts.map +0 -1
  181. package/dist/src/yaml/a-declared-secret-reaches-the-file-step.test.js +0 -201
  182. package/dist/src/yaml/a-declared-slot-may-name-the-workflow-it-belongs-to.test.d.ts +0 -37
  183. package/dist/src/yaml/a-declared-slot-may-name-the-workflow-it-belongs-to.test.d.ts.map +0 -1
  184. package/dist/src/yaml/a-declared-slot-may-name-the-workflow-it-belongs-to.test.js +0 -255
  185. package/dist/src/yaml/a-missing-credential-is-loud.test.d.ts +0 -32
  186. package/dist/src/yaml/a-missing-credential-is-loud.test.d.ts.map +0 -1
  187. package/dist/src/yaml/a-missing-credential-is-loud.test.js +0 -301
  188. package/dist/src/yaml/a-runtime-requirement-names-a-real-provider.test.d.ts +0 -18
  189. package/dist/src/yaml/a-runtime-requirement-names-a-real-provider.test.d.ts.map +0 -1
  190. package/dist/src/yaml/a-runtime-requirement-names-a-real-provider.test.js +0 -66
  191. package/dist/src/yaml/a-scoped-slot-must-name-a-workflow-the-pipeline-has.test.d.ts +0 -34
  192. package/dist/src/yaml/a-scoped-slot-must-name-a-workflow-the-pipeline-has.test.d.ts.map +0 -1
  193. package/dist/src/yaml/a-scoped-slot-must-name-a-workflow-the-pipeline-has.test.js +0 -218
  194. package/dist/src/yaml/a-value-this-instance-stored-is-a-value-it-has.test.d.ts +0 -27
  195. package/dist/src/yaml/a-value-this-instance-stored-is-a-value-it-has.test.d.ts.map +0 -1
  196. package/dist/src/yaml/a-value-this-instance-stored-is-a-value-it-has.test.js +0 -126
  197. package/dist/src/yaml/bitrise-compat.d.ts +0 -65
  198. package/dist/src/yaml/bitrise-compat.d.ts.map +0 -1
  199. package/dist/src/yaml/bitrise-compat.js +0 -206
  200. package/dist/src/yaml/bitrise-compat.test.d.ts +0 -5
  201. package/dist/src/yaml/bitrise-compat.test.d.ts.map +0 -1
  202. package/dist/src/yaml/bitrise-compat.test.js +0 -347
  203. package/dist/src/yaml/cache-key-missing-file.test.d.ts +0 -12
  204. package/dist/src/yaml/cache-key-missing-file.test.d.ts.map +0 -1
  205. package/dist/src/yaml/cache-key-missing-file.test.js +0 -116
  206. package/dist/src/yaml/converter.d.ts +0 -103
  207. package/dist/src/yaml/converter.d.ts.map +0 -1
  208. package/dist/src/yaml/converter.js +0 -420
  209. package/dist/src/yaml/converter.test.d.ts +0 -5
  210. package/dist/src/yaml/converter.test.d.ts.map +0 -1
  211. package/dist/src/yaml/converter.test.js +0 -548
  212. package/dist/src/yaml/e2e.test.d.ts +0 -6
  213. package/dist/src/yaml/e2e.test.d.ts.map +0 -1
  214. package/dist/src/yaml/e2e.test.js +0 -446
  215. package/dist/src/yaml/env-resolver.d.ts +0 -218
  216. package/dist/src/yaml/env-resolver.d.ts.map +0 -1
  217. package/dist/src/yaml/env-resolver.js +0 -591
  218. package/dist/src/yaml/env-resolver.test.d.ts +0 -5
  219. package/dist/src/yaml/env-resolver.test.d.ts.map +0 -1
  220. package/dist/src/yaml/env-resolver.test.js +0 -502
  221. package/dist/src/yaml/every-build-log-witnesses-the-commit-on-disk.test.d.ts +0 -16
  222. package/dist/src/yaml/every-build-log-witnesses-the-commit-on-disk.test.d.ts.map +0 -1
  223. package/dist/src/yaml/every-build-log-witnesses-the-commit-on-disk.test.js +0 -126
  224. package/dist/src/yaml/fidelity-input-digest.d.ts +0 -37
  225. package/dist/src/yaml/fidelity-input-digest.d.ts.map +0 -1
  226. package/dist/src/yaml/fidelity-input-digest.js +0 -208
  227. package/dist/src/yaml/fidelity-input-digest.test.d.ts +0 -2
  228. package/dist/src/yaml/fidelity-input-digest.test.d.ts.map +0 -1
  229. package/dist/src/yaml/fidelity-input-digest.test.js +0 -167
  230. package/dist/src/yaml/fidelity-manifest.d.ts +0 -126
  231. package/dist/src/yaml/fidelity-manifest.d.ts.map +0 -1
  232. package/dist/src/yaml/fidelity-manifest.js +0 -134
  233. package/dist/src/yaml/fidelity-manifest.test.d.ts +0 -12
  234. package/dist/src/yaml/fidelity-manifest.test.d.ts.map +0 -1
  235. package/dist/src/yaml/fidelity-manifest.test.js +0 -251
  236. package/dist/src/yaml/interactive-prompts.d.ts +0 -71
  237. package/dist/src/yaml/interactive-prompts.d.ts.map +0 -1
  238. package/dist/src/yaml/interactive-prompts.js +0 -260
  239. package/dist/src/yaml/meta-helpers.d.ts +0 -28
  240. package/dist/src/yaml/meta-helpers.d.ts.map +0 -1
  241. package/dist/src/yaml/meta-helpers.js +0 -46
  242. package/dist/src/yaml/missing-env-handler.d.ts +0 -45
  243. package/dist/src/yaml/missing-env-handler.d.ts.map +0 -1
  244. package/dist/src/yaml/missing-env-handler.js +0 -64
  245. package/dist/src/yaml/parser.d.ts +0 -33
  246. package/dist/src/yaml/parser.d.ts.map +0 -1
  247. package/dist/src/yaml/parser.js +0 -148
  248. package/dist/src/yaml/parser.test.d.ts +0 -5
  249. package/dist/src/yaml/parser.test.d.ts.map +0 -1
  250. package/dist/src/yaml/parser.test.js +0 -83
  251. package/dist/src/yaml/pipeline-with-secrets.d.ts +0 -25
  252. package/dist/src/yaml/pipeline-with-secrets.d.ts.map +0 -1
  253. package/dist/src/yaml/pipeline-with-secrets.js +0 -76
  254. package/dist/src/yaml/platform-detector.d.ts +0 -83
  255. package/dist/src/yaml/platform-detector.d.ts.map +0 -1
  256. package/dist/src/yaml/platform-detector.js +0 -189
  257. package/dist/src/yaml/platform-detector.test.d.ts +0 -5
  258. package/dist/src/yaml/platform-detector.test.d.ts.map +0 -1
  259. package/dist/src/yaml/platform-detector.test.js +0 -525
  260. package/dist/src/yaml/preflight-validation.d.ts +0 -29
  261. package/dist/src/yaml/preflight-validation.d.ts.map +0 -1
  262. package/dist/src/yaml/preflight-validation.js +0 -21
  263. package/dist/src/yaml/secrets-manager.d.ts +0 -87
  264. package/dist/src/yaml/secrets-manager.d.ts.map +0 -1
  265. package/dist/src/yaml/secrets-manager.js +0 -230
  266. package/dist/src/yaml/shell-assignments.d.ts +0 -40
  267. package/dist/src/yaml/shell-assignments.d.ts.map +0 -1
  268. package/dist/src/yaml/shell-assignments.js +0 -77
  269. package/dist/src/yaml/step-validator-check-failure.test.d.ts +0 -24
  270. package/dist/src/yaml/step-validator-check-failure.test.d.ts.map +0 -1
  271. package/dist/src/yaml/step-validator-check-failure.test.js +0 -130
  272. package/dist/src/yaml/step-validator-self-assigned.test.d.ts +0 -23
  273. package/dist/src/yaml/step-validator-self-assigned.test.d.ts.map +0 -1
  274. package/dist/src/yaml/step-validator-self-assigned.test.js +0 -191
  275. package/dist/src/yaml/step-validator.d.ts +0 -67
  276. package/dist/src/yaml/step-validator.d.ts.map +0 -1
  277. package/dist/src/yaml/step-validator.js +0 -466
  278. package/dist/src/yaml/step-validator.test.d.ts +0 -18
  279. package/dist/src/yaml/step-validator.test.d.ts.map +0 -1
  280. package/dist/src/yaml/step-validator.test.js +0 -140
  281. package/dist/src/yaml/steps/android-sign.d.ts +0 -35
  282. package/dist/src/yaml/steps/android-sign.d.ts.map +0 -1
  283. package/dist/src/yaml/steps/android-sign.js +0 -147
  284. package/dist/src/yaml/steps/android-variant-resolution.test.d.ts +0 -2
  285. package/dist/src/yaml/steps/android-variant-resolution.test.d.ts.map +0 -1
  286. package/dist/src/yaml/steps/android-variant-resolution.test.js +0 -260
  287. package/dist/src/yaml/steps/android-version.d.ts +0 -26
  288. package/dist/src/yaml/steps/android-version.d.ts.map +0 -1
  289. package/dist/src/yaml/steps/android-version.js +0 -128
  290. package/dist/src/yaml/steps/android-version.test.d.ts +0 -5
  291. package/dist/src/yaml/steps/android-version.test.d.ts.map +0 -1
  292. package/dist/src/yaml/steps/android-version.test.js +0 -196
  293. package/dist/src/yaml/steps/android.d.ts +0 -156
  294. package/dist/src/yaml/steps/android.d.ts.map +0 -1
  295. package/dist/src/yaml/steps/android.js +0 -1092
  296. package/dist/src/yaml/steps/app-store-deploy.d.ts +0 -48
  297. package/dist/src/yaml/steps/app-store-deploy.d.ts.map +0 -1
  298. package/dist/src/yaml/steps/app-store-deploy.js +0 -167
  299. package/dist/src/yaml/steps/base.d.ts +0 -263
  300. package/dist/src/yaml/steps/base.d.ts.map +0 -1
  301. package/dist/src/yaml/steps/base.js +0 -380
  302. package/dist/src/yaml/steps/bitrise-android-tools.d.ts +0 -26
  303. package/dist/src/yaml/steps/bitrise-android-tools.d.ts.map +0 -1
  304. package/dist/src/yaml/steps/bitrise-android-tools.js +0 -200
  305. package/dist/src/yaml/steps/bitrise-android-tools.test.d.ts +0 -5
  306. package/dist/src/yaml/steps/bitrise-android-tools.test.d.ts.map +0 -1
  307. package/dist/src/yaml/steps/bitrise-android-tools.test.js +0 -280
  308. package/dist/src/yaml/steps/bitrise-apk-info.d.ts +0 -22
  309. package/dist/src/yaml/steps/bitrise-apk-info.d.ts.map +0 -1
  310. package/dist/src/yaml/steps/bitrise-apk-info.js +0 -144
  311. package/dist/src/yaml/steps/bitrise-apk-info.test.d.ts +0 -5
  312. package/dist/src/yaml/steps/bitrise-apk-info.test.d.ts.map +0 -1
  313. package/dist/src/yaml/steps/bitrise-apk-info.test.js +0 -331
  314. package/dist/src/yaml/steps/bitrise-slack.d.ts +0 -49
  315. package/dist/src/yaml/steps/bitrise-slack.d.ts.map +0 -1
  316. package/dist/src/yaml/steps/bitrise-slack.js +0 -280
  317. package/dist/src/yaml/steps/bitrise-slack.test.d.ts +0 -5
  318. package/dist/src/yaml/steps/bitrise-slack.test.d.ts.map +0 -1
  319. package/dist/src/yaml/steps/bitrise-slack.test.js +0 -484
  320. package/dist/src/yaml/steps/bitrise-ssh.d.ts +0 -27
  321. package/dist/src/yaml/steps/bitrise-ssh.d.ts.map +0 -1
  322. package/dist/src/yaml/steps/bitrise-ssh.js +0 -134
  323. package/dist/src/yaml/steps/bitrise-ssh.test.d.ts +0 -5
  324. package/dist/src/yaml/steps/bitrise-ssh.test.d.ts.map +0 -1
  325. package/dist/src/yaml/steps/bitrise-ssh.test.js +0 -205
  326. package/dist/src/yaml/steps/cache-pull-daemon.test.d.ts +0 -27
  327. package/dist/src/yaml/steps/cache-pull-daemon.test.d.ts.map +0 -1
  328. package/dist/src/yaml/steps/cache-pull-daemon.test.js +0 -212
  329. package/dist/src/yaml/steps/cache-pull-restore-roots.test.d.ts +0 -42
  330. package/dist/src/yaml/steps/cache-pull-restore-roots.test.d.ts.map +0 -1
  331. package/dist/src/yaml/steps/cache-pull-restore-roots.test.js +0 -209
  332. package/dist/src/yaml/steps/cache-push-daemon.test.d.ts +0 -27
  333. package/dist/src/yaml/steps/cache-push-daemon.test.d.ts.map +0 -1
  334. package/dist/src/yaml/steps/cache-push-daemon.test.js +0 -171
  335. package/dist/src/yaml/steps/cache.d.ts +0 -59
  336. package/dist/src/yaml/steps/cache.d.ts.map +0 -1
  337. package/dist/src/yaml/steps/cache.js +0 -1027
  338. package/dist/src/yaml/steps/capture-injection.d.ts +0 -30
  339. package/dist/src/yaml/steps/capture-injection.d.ts.map +0 -1
  340. package/dist/src/yaml/steps/capture-injection.js +0 -88
  341. package/dist/src/yaml/steps/capture-injection.test.d.ts +0 -2
  342. package/dist/src/yaml/steps/capture-injection.test.d.ts.map +0 -1
  343. package/dist/src/yaml/steps/capture-injection.test.js +0 -163
  344. package/dist/src/yaml/steps/cocoapods-deployment-floor.d.ts +0 -42
  345. package/dist/src/yaml/steps/cocoapods-deployment-floor.d.ts.map +0 -1
  346. package/dist/src/yaml/steps/cocoapods-deployment-floor.js +0 -140
  347. package/dist/src/yaml/steps/cocoapods-deployment-floor.test.d.ts +0 -11
  348. package/dist/src/yaml/steps/cocoapods-deployment-floor.test.d.ts.map +0 -1
  349. package/dist/src/yaml/steps/cocoapods-deployment-floor.test.js +0 -176
  350. package/dist/src/yaml/steps/cocoapods-install-emits-valid-bash.test.d.ts +0 -22
  351. package/dist/src/yaml/steps/cocoapods-install-emits-valid-bash.test.d.ts.map +0 -1
  352. package/dist/src/yaml/steps/cocoapods-install-emits-valid-bash.test.js +0 -97
  353. package/dist/src/yaml/steps/cocoapods-locked-bundler.test.d.ts +0 -17
  354. package/dist/src/yaml/steps/cocoapods-locked-bundler.test.d.ts.map +0 -1
  355. package/dist/src/yaml/steps/cocoapods-locked-bundler.test.js +0 -282
  356. package/dist/src/yaml/steps/cocoapods-skip-if-absent.test.d.ts +0 -17
  357. package/dist/src/yaml/steps/cocoapods-skip-if-absent.test.d.ts.map +0 -1
  358. package/dist/src/yaml/steps/cocoapods-skip-if-absent.test.js +0 -132
  359. package/dist/src/yaml/steps/envstore-loader.test.d.ts +0 -15
  360. package/dist/src/yaml/steps/envstore-loader.test.d.ts.map +0 -1
  361. package/dist/src/yaml/steps/envstore-loader.test.js +0 -143
  362. package/dist/src/yaml/steps/fastlane.d.ts +0 -27
  363. package/dist/src/yaml/steps/fastlane.d.ts.map +0 -1
  364. package/dist/src/yaml/steps/fastlane.js +0 -79
  365. package/dist/src/yaml/steps/fidelity-aspect-guard.d.ts +0 -53
  366. package/dist/src/yaml/steps/fidelity-aspect-guard.d.ts.map +0 -1
  367. package/dist/src/yaml/steps/fidelity-aspect-guard.js +0 -72
  368. package/dist/src/yaml/steps/fidelity-aspect-guard.test.d.ts +0 -11
  369. package/dist/src/yaml/steps/fidelity-aspect-guard.test.d.ts.map +0 -1
  370. package/dist/src/yaml/steps/fidelity-aspect-guard.test.js +0 -50
  371. package/dist/src/yaml/steps/fidelity-reference-provenance.d.ts +0 -87
  372. package/dist/src/yaml/steps/fidelity-reference-provenance.d.ts.map +0 -1
  373. package/dist/src/yaml/steps/fidelity-reference-provenance.js +0 -111
  374. package/dist/src/yaml/steps/fidelity-reference-provenance.test.d.ts +0 -22
  375. package/dist/src/yaml/steps/fidelity-reference-provenance.test.d.ts.map +0 -1
  376. package/dist/src/yaml/steps/fidelity-reference-provenance.test.js +0 -118
  377. package/dist/src/yaml/steps/file.d.ts +0 -52
  378. package/dist/src/yaml/steps/file.d.ts.map +0 -1
  379. package/dist/src/yaml/steps/file.js +0 -108
  380. package/dist/src/yaml/steps/flutter.d.ts +0 -63
  381. package/dist/src/yaml/steps/flutter.d.ts.map +0 -1
  382. package/dist/src/yaml/steps/flutter.js +0 -215
  383. package/dist/src/yaml/steps/git-clone-names-the-inputs-it-ignores.test.d.ts +0 -16
  384. package/dist/src/yaml/steps/git-clone-names-the-inputs-it-ignores.test.d.ts.map +0 -1
  385. package/dist/src/yaml/steps/git-clone-names-the-inputs-it-ignores.test.js +0 -127
  386. package/dist/src/yaml/steps/git-clone.d.ts +0 -32
  387. package/dist/src/yaml/steps/git-clone.d.ts.map +0 -1
  388. package/dist/src/yaml/steps/git-clone.js +0 -171
  389. package/dist/src/yaml/steps/git-fetch-retry-exec.test.d.ts +0 -10
  390. package/dist/src/yaml/steps/git-fetch-retry-exec.test.d.ts.map +0 -1
  391. package/dist/src/yaml/steps/git-fetch-retry-exec.test.js +0 -162
  392. package/dist/src/yaml/steps/git-fetch-retry.d.ts +0 -62
  393. package/dist/src/yaml/steps/git-fetch-retry.d.ts.map +0 -1
  394. package/dist/src/yaml/steps/git-fetch-retry.js +0 -155
  395. package/dist/src/yaml/steps/git-fetch-retry.test.d.ts +0 -5
  396. package/dist/src/yaml/steps/git-fetch-retry.test.d.ts.map +0 -1
  397. package/dist/src/yaml/steps/git-fetch-retry.test.js +0 -86
  398. package/dist/src/yaml/steps/google-play-deploy.d.ts +0 -37
  399. package/dist/src/yaml/steps/google-play-deploy.d.ts.map +0 -1
  400. package/dist/src/yaml/steps/google-play-deploy.js +0 -193
  401. package/dist/src/yaml/steps/google-play-deploy.test.d.ts +0 -5
  402. package/dist/src/yaml/steps/google-play-deploy.test.d.ts.map +0 -1
  403. package/dist/src/yaml/steps/google-play-deploy.test.js +0 -310
  404. package/dist/src/yaml/steps/gradle-memory.d.ts +0 -61
  405. package/dist/src/yaml/steps/gradle-memory.d.ts.map +0 -1
  406. package/dist/src/yaml/steps/gradle-memory.js +0 -386
  407. package/dist/src/yaml/steps/gradle-memory.test.d.ts +0 -2
  408. package/dist/src/yaml/steps/gradle-memory.test.d.ts.map +0 -1
  409. package/dist/src/yaml/steps/gradle-memory.test.js +0 -344
  410. package/dist/src/yaml/steps/gradle-sdk-cmake.d.ts +0 -28
  411. package/dist/src/yaml/steps/gradle-sdk-cmake.d.ts.map +0 -1
  412. package/dist/src/yaml/steps/gradle-sdk-cmake.js +0 -107
  413. package/dist/src/yaml/steps/gradle-sdk-cmake.test.d.ts +0 -2
  414. package/dist/src/yaml/steps/gradle-sdk-cmake.test.d.ts.map +0 -1
  415. package/dist/src/yaml/steps/gradle-sdk-cmake.test.js +0 -183
  416. package/dist/src/yaml/steps/index.d.ts +0 -10
  417. package/dist/src/yaml/steps/index.d.ts.map +0 -1
  418. package/dist/src/yaml/steps/index.js +0 -1461
  419. package/dist/src/yaml/steps/ios-deps.d.ts +0 -78
  420. package/dist/src/yaml/steps/ios-deps.d.ts.map +0 -1
  421. package/dist/src/yaml/steps/ios-deps.js +0 -279
  422. package/dist/src/yaml/steps/ios-deps.test.d.ts +0 -5
  423. package/dist/src/yaml/steps/ios-deps.test.d.ts.map +0 -1
  424. package/dist/src/yaml/steps/ios-deps.test.js +0 -90
  425. package/dist/src/yaml/steps/ios-signing.d.ts +0 -31
  426. package/dist/src/yaml/steps/ios-signing.d.ts.map +0 -1
  427. package/dist/src/yaml/steps/ios-signing.js +0 -144
  428. package/dist/src/yaml/steps/ios-version.d.ts +0 -47
  429. package/dist/src/yaml/steps/ios-version.d.ts.map +0 -1
  430. package/dist/src/yaml/steps/ios-version.js +0 -151
  431. package/dist/src/yaml/steps/java-home-version-spec.test.d.ts +0 -10
  432. package/dist/src/yaml/steps/java-home-version-spec.test.d.ts.map +0 -1
  433. package/dist/src/yaml/steps/java-home-version-spec.test.js +0 -58
  434. package/dist/src/yaml/steps/linting.d.ts +0 -47
  435. package/dist/src/yaml/steps/linting.d.ts.map +0 -1
  436. package/dist/src/yaml/steps/linting.js +0 -148
  437. package/dist/src/yaml/steps/phase2.test.d.ts +0 -6
  438. package/dist/src/yaml/steps/phase2.test.d.ts.map +0 -1
  439. package/dist/src/yaml/steps/phase2.test.js +0 -197
  440. package/dist/src/yaml/steps/phase3.test.d.ts +0 -5
  441. package/dist/src/yaml/steps/phase3.test.d.ts.map +0 -1
  442. package/dist/src/yaml/steps/phase3.test.js +0 -144
  443. package/dist/src/yaml/steps/phase4.test.d.ts +0 -5
  444. package/dist/src/yaml/steps/phase4.test.d.ts.map +0 -1
  445. package/dist/src/yaml/steps/phase4.test.js +0 -166
  446. package/dist/src/yaml/steps/phase5.test.d.ts +0 -6
  447. package/dist/src/yaml/steps/phase5.test.d.ts.map +0 -1
  448. package/dist/src/yaml/steps/phase5.test.js +0 -263
  449. package/dist/src/yaml/steps/registry.d.ts +0 -88
  450. package/dist/src/yaml/steps/registry.d.ts.map +0 -1
  451. package/dist/src/yaml/steps/registry.js +0 -125
  452. package/dist/src/yaml/steps/registry.test.d.ts +0 -5
  453. package/dist/src/yaml/steps/registry.test.d.ts.map +0 -1
  454. package/dist/src/yaml/steps/registry.test.js +0 -235
  455. package/dist/src/yaml/steps/release.d.ts +0 -50
  456. package/dist/src/yaml/steps/release.d.ts.map +0 -1
  457. package/dist/src/yaml/steps/release.js +0 -154
  458. package/dist/src/yaml/steps/render-post-processor.d.ts +0 -100
  459. package/dist/src/yaml/steps/render-post-processor.d.ts.map +0 -1
  460. package/dist/src/yaml/steps/render-post-processor.js +0 -270
  461. package/dist/src/yaml/steps/render-post-processor.test.d.ts +0 -13
  462. package/dist/src/yaml/steps/render-post-processor.test.d.ts.map +0 -1
  463. package/dist/src/yaml/steps/render-post-processor.test.js +0 -220
  464. package/dist/src/yaml/steps/script.d.ts +0 -23
  465. package/dist/src/yaml/steps/script.d.ts.map +0 -1
  466. package/dist/src/yaml/steps/script.js +0 -63
  467. package/dist/src/yaml/steps/spec-validation.test.d.ts +0 -6
  468. package/dist/src/yaml/steps/spec-validation.test.d.ts.map +0 -1
  469. package/dist/src/yaml/steps/spec-validation.test.js +0 -130
  470. package/dist/src/yaml/steps/steps.test.d.ts +0 -6
  471. package/dist/src/yaml/steps/steps.test.d.ts.map +0 -1
  472. package/dist/src/yaml/steps/steps.test.js +0 -881
  473. package/dist/src/yaml/steps/structural-facts.d.ts +0 -992
  474. package/dist/src/yaml/steps/structural-facts.d.ts.map +0 -1
  475. package/dist/src/yaml/steps/structural-facts.js +0 -3276
  476. package/dist/src/yaml/steps/structural-facts.test.d.ts +0 -12
  477. package/dist/src/yaml/steps/structural-facts.test.d.ts.map +0 -1
  478. package/dist/src/yaml/steps/structural-facts.test.js +0 -3039
  479. package/dist/src/yaml/steps/test-config.d.ts +0 -5
  480. package/dist/src/yaml/steps/test-config.d.ts.map +0 -1
  481. package/dist/src/yaml/steps/test-config.js +0 -25
  482. package/dist/src/yaml/steps/trim-align-corpus.test.d.ts +0 -28
  483. package/dist/src/yaml/steps/trim-align-corpus.test.d.ts.map +0 -1
  484. package/dist/src/yaml/steps/trim-align-corpus.test.js +0 -383
  485. package/dist/src/yaml/steps/trim-align.d.ts +0 -87
  486. package/dist/src/yaml/steps/trim-align.d.ts.map +0 -1
  487. package/dist/src/yaml/steps/trim-align.js +0 -367
  488. package/dist/src/yaml/steps/trim-align.test.d.ts +0 -11
  489. package/dist/src/yaml/steps/trim-align.test.d.ts.map +0 -1
  490. package/dist/src/yaml/steps/trim-align.test.js +0 -261
  491. package/dist/src/yaml/steps/ui-fidelity-preview-android.d.ts +0 -66
  492. package/dist/src/yaml/steps/ui-fidelity-preview-android.d.ts.map +0 -1
  493. package/dist/src/yaml/steps/ui-fidelity-preview-android.js +0 -251
  494. package/dist/src/yaml/steps/ui-fidelity-preview-android.test.d.ts +0 -13
  495. package/dist/src/yaml/steps/ui-fidelity-preview-android.test.d.ts.map +0 -1
  496. package/dist/src/yaml/steps/ui-fidelity-preview-android.test.js +0 -302
  497. package/dist/src/yaml/steps/ui-fidelity-preview.d.ts +0 -134
  498. package/dist/src/yaml/steps/ui-fidelity-preview.d.ts.map +0 -1
  499. package/dist/src/yaml/steps/ui-fidelity-preview.js +0 -173
  500. package/dist/src/yaml/steps/ui-fidelity-preview.test.d.ts +0 -11
  501. package/dist/src/yaml/steps/ui-fidelity-preview.test.d.ts.map +0 -1
  502. package/dist/src/yaml/steps/ui-fidelity-preview.test.js +0 -210
  503. package/dist/src/yaml/steps/ui-fidelity-render-android.d.ts +0 -155
  504. package/dist/src/yaml/steps/ui-fidelity-render-android.d.ts.map +0 -1
  505. package/dist/src/yaml/steps/ui-fidelity-render-android.js +0 -1389
  506. package/dist/src/yaml/steps/ui-fidelity-render-android.test.d.ts +0 -2
  507. package/dist/src/yaml/steps/ui-fidelity-render-android.test.d.ts.map +0 -1
  508. package/dist/src/yaml/steps/ui-fidelity-render-android.test.js +0 -1106
  509. package/dist/src/yaml/steps/ui-fidelity-render.d.ts +0 -230
  510. package/dist/src/yaml/steps/ui-fidelity-render.d.ts.map +0 -1
  511. package/dist/src/yaml/steps/ui-fidelity-render.js +0 -1597
  512. package/dist/src/yaml/steps/ui-fidelity-render.test.d.ts +0 -18
  513. package/dist/src/yaml/steps/ui-fidelity-render.test.d.ts.map +0 -1
  514. package/dist/src/yaml/steps/ui-fidelity-render.test.js +0 -1871
  515. package/dist/src/yaml/steps/xcode-app-product.d.ts +0 -90
  516. package/dist/src/yaml/steps/xcode-app-product.d.ts.map +0 -1
  517. package/dist/src/yaml/steps/xcode-app-product.js +0 -247
  518. package/dist/src/yaml/steps/xcode-app-product.test.d.ts +0 -2
  519. package/dist/src/yaml/steps/xcode-app-product.test.d.ts.map +0 -1
  520. package/dist/src/yaml/steps/xcode-app-product.test.js +0 -202
  521. package/dist/src/yaml/steps/xcode-derived-data.test.d.ts +0 -30
  522. package/dist/src/yaml/steps/xcode-derived-data.test.d.ts.map +0 -1
  523. package/dist/src/yaml/steps/xcode-derived-data.test.js +0 -279
  524. package/dist/src/yaml/steps/xcode-destination.d.ts +0 -47
  525. package/dist/src/yaml/steps/xcode-destination.d.ts.map +0 -1
  526. package/dist/src/yaml/steps/xcode-destination.js +0 -202
  527. package/dist/src/yaml/steps/xcode-destination.test.d.ts +0 -9
  528. package/dist/src/yaml/steps/xcode-destination.test.d.ts.map +0 -1
  529. package/dist/src/yaml/steps/xcode-destination.test.js +0 -227
  530. package/dist/src/yaml/steps/xcode-new.test.d.ts +0 -5
  531. package/dist/src/yaml/steps/xcode-new.test.d.ts.map +0 -1
  532. package/dist/src/yaml/steps/xcode-new.test.js +0 -211
  533. package/dist/src/yaml/steps/xcode-resolve-retry.test.d.ts +0 -9
  534. package/dist/src/yaml/steps/xcode-resolve-retry.test.d.ts.map +0 -1
  535. package/dist/src/yaml/steps/xcode-resolve-retry.test.js +0 -146
  536. package/dist/src/yaml/steps/xcode-simulator-archs.d.ts +0 -53
  537. package/dist/src/yaml/steps/xcode-simulator-archs.d.ts.map +0 -1
  538. package/dist/src/yaml/steps/xcode-simulator-archs.js +0 -98
  539. package/dist/src/yaml/steps/xcode-simulator-archs.test.d.ts +0 -21
  540. package/dist/src/yaml/steps/xcode-simulator-archs.test.d.ts.map +0 -1
  541. package/dist/src/yaml/steps/xcode-simulator-archs.test.js +0 -155
  542. package/dist/src/yaml/steps/xcode.d.ts +0 -230
  543. package/dist/src/yaml/steps/xcode.d.ts.map +0 -1
  544. package/dist/src/yaml/steps/xcode.js +0 -1350
  545. package/dist/src/yaml/types.d.ts +0 -76
  546. package/dist/src/yaml/types.d.ts.map +0 -1
  547. package/dist/src/yaml/types.js +0 -5
  548. package/dist/src/yaml/validation-types.d.ts +0 -102
  549. package/dist/src/yaml/validation-types.d.ts.map +0 -1
  550. package/dist/src/yaml/validation-types.js +0 -8
  551. package/dist/src/yaml/yaml-updater.d.ts +0 -24
  552. package/dist/src/yaml/yaml-updater.d.ts.map +0 -1
  553. package/dist/src/yaml/yaml-updater.js +0 -128
@@ -1,367 +0,0 @@
1
- /**
2
- * Pure-JS trim/align helper — the CoreGraphics port (fidelity-linux 06).
3
- *
4
- * This is a PORT of the embedded Swift helper that used to live in
5
- * render-post-processor.ts (`TRIM_HELPER_SWIFT_SOURCE`), not a redesign: the
6
- * bounding-box semantics (alpha pass, corner-derived uniform background,
7
- * tolerance 4, never-crop-to-nothing fallback), the fit-pad geometry
8
- * (aspect-preserving scale, centered, transparent letterbox) and the TRIMDIMS
9
- * contract are byte-for-byte the Swift behavior. CoreGraphics/ImageIO do not
10
- * exist on Linux, so the pixel work moved into the ci binary itself (pngjs is
11
- * pure JS and bundles via bundle.mjs) — iOS and Android now run the SAME bytes,
12
- * and output pixels can only change with our lockfile, never with a runner OS
13
- * upgrade.
14
- *
15
- * Port-fidelity notes, load-bearing for the corpus gate:
16
- * - The Swift helper ANALYZED pixels through a premultiplied-alpha CGContext
17
- * but CROPPED the original (straight-alpha) image. We mirror both: the
18
- * bounding box is computed over premultiplied values, the trimmed output is
19
- * a raw copy of the source pixels.
20
- * - The Swift aligned output was drawn through a premultiplied context and
21
- * unpremultiplied on PNG encode, which is lossy on semi-transparent pixels;
22
- * we reproduce that roundtrip. Where CoreGraphics RESAMPLED (trimmed size ≠
23
- * reference size), its proprietary `.high` interpolation is not bit-exactly
24
- * reproducible — we use bilinear filtering in premultiplied space. The
25
- * trimmed image and TRIMDIMS never depend on resampling and are the
26
- * pixel-identical surface the corpus gate enforces.
27
- */
28
- import { readFileSync, writeFileSync } from 'node:fs';
29
- import { PNG } from 'pngjs';
30
- /** Mirror of the Swift helper's exit codes. */
31
- export const TRIM_EXIT_USAGE = 64;
32
- export const TRIM_EXIT_UNREADABLE = 65;
33
- export const TRIM_EXIT_NO_CONTENT = 66;
34
- export const TRIM_EXIT_WRITE_FAILED = 68;
35
- // Tight tolerance: exact solid fills match, near-colored content does not.
36
- // (Same constant, same meaning as the Swift helper.)
37
- const TOLERANCE = 4;
38
- /**
39
- * Premultiply one straight-alpha channel value, matching the rounding
40
- * CoreGraphics/vImage applies when drawing into a premultiplied context:
41
- * (v * a + 127) / 255, truncated.
42
- */
43
- function premultiply(value, alpha) {
44
- return ((value * alpha + 127) / 255) | 0;
45
- }
46
- /**
47
- * Un-premultiply one channel value, matching ImageIO's PNG encode of a
48
- * premultiplied bitmap. Transparent pixels collapse to zero (which is also
49
- * why the Swift aligned output zeroes the RGB of fully-transparent pixels).
50
- */
51
- function unpremultiply(value, alpha) {
52
- if (alpha === 0)
53
- return 0;
54
- const v = Math.round((value * 255) / alpha);
55
- return v > 255 ? 255 : v;
56
- }
57
- /**
58
- * Bounding box of content: pixels that are neither transparent nor part of a
59
- * uniform solid background. Two passes, because the renderer forces the view
60
- * into a fixed device frame whose margins are transparent: (1) bound the
61
- * non-transparent pixels, then (2) detect a uniform opaque background from the
62
- * CORNERS OF THAT OPAQUE BOX — not the raw frame, whose corners are the
63
- * transparent device margin — and bound everything that is not that
64
- * background. A wrapper that fills the canvas with .background(.white) is thus
65
- * trimmed to its real content. When the opaque corners disagree, only
66
- * transparency is trimmed. Top-left image coordinates.
67
- *
68
- * `data` is straight-alpha RGBA8 (as pngjs decodes); the color comparisons run
69
- * on premultiplied values to mirror the Swift helper's analysis context.
70
- */
71
- export function contentBoundingBox(data, width, height) {
72
- if (width === 0 || height === 0)
73
- return null;
74
- const bytesPerRow = width * 4;
75
- // Pass 1: bounding box of all non-transparent pixels.
76
- let aMinX = width;
77
- let aMinY = height;
78
- let aMaxX = -1;
79
- let aMaxY = -1;
80
- for (let y = 0; y < height; y++) {
81
- const rowBase = y * bytesPerRow;
82
- for (let x = 0; x < width; x++) {
83
- if (data[rowBase + x * 4 + 3] > 0) {
84
- if (x < aMinX)
85
- aMinX = x;
86
- if (x > aMaxX)
87
- aMaxX = x;
88
- if (y < aMinY)
89
- aMinY = y;
90
- if (y > aMaxY)
91
- aMaxY = y;
92
- }
93
- }
94
- }
95
- if (aMaxX < 0)
96
- return null;
97
- const opaqueBox = {
98
- x: aMinX,
99
- y: aMinY,
100
- width: aMaxX - aMinX + 1,
101
- height: aMaxY - aMinY + 1,
102
- };
103
- // Premultiplied RGBA of one pixel — the analysis view of the image.
104
- function sample(x, y) {
105
- const i = y * bytesPerRow + x * 4;
106
- const a = data[i + 3];
107
- return [
108
- premultiply(data[i], a),
109
- premultiply(data[i + 1], a),
110
- premultiply(data[i + 2], a),
111
- a,
112
- ];
113
- }
114
- // Detect a uniform opaque background from the corners of the opaque box.
115
- // As in the Swift helper, every corner is compared against the FIRST corner
116
- // (background only ever holds corners[0] or null).
117
- const corners = [
118
- sample(aMinX, aMinY),
119
- sample(aMaxX, aMinY),
120
- sample(aMinX, aMaxY),
121
- sample(aMaxX, aMaxY),
122
- ];
123
- let background = corners[0];
124
- for (const c of corners) {
125
- if (background !== null) {
126
- if (c[3] === 0 ||
127
- Math.abs(c[0] - background[0]) > TOLERANCE ||
128
- Math.abs(c[1] - background[1]) > TOLERANCE ||
129
- Math.abs(c[2] - background[2]) > TOLERANCE ||
130
- Math.abs(c[3] - background[3]) > TOLERANCE) {
131
- background = null;
132
- }
133
- }
134
- }
135
- // No uniform background: the opaque box is the content.
136
- if (background === null)
137
- return opaqueBox;
138
- const bg = background;
139
- // Pass 2: within the opaque box, bound everything that is not the background.
140
- let minX = aMaxX + 1;
141
- let minY = aMaxY + 1;
142
- let maxX = aMinX - 1;
143
- let maxY = aMinY - 1;
144
- for (let y = aMinY; y <= aMaxY; y++) {
145
- const rowBase = y * bytesPerRow;
146
- for (let x = aMinX; x <= aMaxX; x++) {
147
- const idx = rowBase + x * 4;
148
- const a = data[idx + 3];
149
- if (a === 0)
150
- continue;
151
- const r = premultiply(data[idx], a);
152
- const g = premultiply(data[idx + 1], a);
153
- const b = premultiply(data[idx + 2], a);
154
- if (Math.abs(r - bg[0]) <= TOLERANCE &&
155
- Math.abs(g - bg[1]) <= TOLERANCE &&
156
- Math.abs(b - bg[2]) <= TOLERANCE &&
157
- Math.abs(a - bg[3]) <= TOLERANCE) {
158
- continue;
159
- }
160
- if (x < minX)
161
- minX = x;
162
- if (x > maxX)
163
- maxX = x;
164
- if (y < minY)
165
- minY = y;
166
- if (y > maxY)
167
- maxY = y;
168
- }
169
- }
170
- // All background, no distinct content: keep the opaque box, never crop to nothing.
171
- if (maxX < minX)
172
- return opaqueBox;
173
- return { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 };
174
- }
175
- /** Raw pixel copy of a region — the Swift `image.cropping(to:)` equivalent. */
176
- export function cropImage(src, box) {
177
- const out = new PNG({ width: box.width, height: box.height });
178
- for (let y = 0; y < box.height; y++) {
179
- const srcStart = ((box.y + y) * src.width + box.x) * 4;
180
- src.data.copy(out.data, y * box.width * 4, srcStart, srcStart + box.width * 4);
181
- }
182
- return out;
183
- }
184
- /**
185
- * Draw `src` centered on a transparent reference-sized canvas, scaled to fit
186
- * while PRESERVING its aspect ratio. Unlike a stretch-to-fit (which distorts
187
- * proportions when the aspect ratios differ), this keeps the rendered shape
188
- * honest: an aspect mismatch shows as transparent letterbox/pillarbox padding
189
- * rather than a squished image, while the canvas stays exactly reference-sized
190
- * so the pair still overlays 1:1.
191
- *
192
- * Compositing happens in premultiplied space with an unpremultiply on the way
193
- * out, mirroring the Swift context roundtrip. Resampling is bilinear (see the
194
- * module docblock for why CG's `.high` filter is not reproducible).
195
- */
196
- export function fitPad(src, width, height) {
197
- if (width <= 0 || height <= 0)
198
- return null;
199
- const out = new PNG({ width, height }); // zero-initialized: transparent canvas
200
- const scale = Math.min(width / src.width, height / src.height);
201
- const drawW = src.width * scale;
202
- const drawH = src.height * scale;
203
- const originX = (width - drawW) / 2;
204
- const originY = (height - drawH) / 2;
205
- // Premultiplied source, sampled by the filter below.
206
- const pre = Buffer.alloc(src.width * src.height * 4);
207
- for (let i = 0; i < src.width * src.height * 4; i += 4) {
208
- const a = src.data[i + 3];
209
- pre[i] = premultiply(src.data[i], a);
210
- pre[i + 1] = premultiply(src.data[i + 1], a);
211
- pre[i + 2] = premultiply(src.data[i + 2], a);
212
- pre[i + 3] = a;
213
- }
214
- const identity = scale === 1 && Number.isInteger(originX) && Number.isInteger(originY);
215
- for (let dy = 0; dy < height; dy++) {
216
- for (let dx = 0; dx < width; dx++) {
217
- const cx = dx + 0.5;
218
- const cy = dy + 0.5;
219
- if (cx < originX || cx > originX + drawW || cy < originY || cy > originY + drawH) {
220
- continue; // transparent padding
221
- }
222
- const di = (dy * width + dx) * 4;
223
- if (identity) {
224
- // 1:1 placement — no filtering, but still the premultiply roundtrip
225
- // the Swift context applied.
226
- const si = ((dy - originY) * src.width + (dx - originX)) * 4;
227
- const a = pre[si + 3];
228
- out.data[di] = unpremultiply(pre[si], a);
229
- out.data[di + 1] = unpremultiply(pre[si + 1], a);
230
- out.data[di + 2] = unpremultiply(pre[si + 2], a);
231
- out.data[di + 3] = a;
232
- continue;
233
- }
234
- // Bilinear sample at the source-space position of this dest pixel center,
235
- // clamped to the source edges.
236
- const sx = (cx - originX) / scale - 0.5;
237
- const sy = (cy - originY) / scale - 0.5;
238
- const x0 = Math.floor(sx);
239
- const y0 = Math.floor(sy);
240
- const fx = sx - x0;
241
- const fy = sy - y0;
242
- const clampX = (v) => (v < 0 ? 0 : v >= src.width ? src.width - 1 : v);
243
- const clampY = (v) => (v < 0 ? 0 : v >= src.height ? src.height - 1 : v);
244
- const i00 = (clampY(y0) * src.width + clampX(x0)) * 4;
245
- const i10 = (clampY(y0) * src.width + clampX(x0 + 1)) * 4;
246
- const i01 = (clampY(y0 + 1) * src.width + clampX(x0)) * 4;
247
- const i11 = (clampY(y0 + 1) * src.width + clampX(x0 + 1)) * 4;
248
- const w00 = (1 - fx) * (1 - fy);
249
- const w10 = fx * (1 - fy);
250
- const w01 = (1 - fx) * fy;
251
- const w11 = fx * fy;
252
- const blend = (offset) => pre[i00 + offset] * w00 +
253
- pre[i10 + offset] * w10 +
254
- pre[i01 + offset] * w01 +
255
- pre[i11 + offset] * w11;
256
- const a = Math.round(blend(3));
257
- out.data[di] = unpremultiply(Math.round(blend(0)), a);
258
- out.data[di + 1] = unpremultiply(Math.round(blend(1)), a);
259
- out.data[di + 2] = unpremultiply(Math.round(blend(2)), a);
260
- out.data[di + 3] = a;
261
- }
262
- }
263
- return out;
264
- }
265
- /**
266
- * The helper entry point, argv-compatible with the retired Swift helper:
267
- * `[in.png, out.png]` or `[in.png, out.png, aligned.png, reference.png]`.
268
- * Crops the input to its content bounding box, optionally writes a
269
- * reference-sized aligned copy (best-effort), and reports a TRIMDIMS line
270
- * (`TRIMDIMS <rW> <rH> <refW> <refH> <srcW> <srcH> <offX> <offY>` — the crop
271
- * origin appended 2026-08-01, older consumers ignore it). Same exit codes,
272
- * same stdout/stderr shape as the Swift helper.
273
- */
274
- export function runTrimAlign(argv) {
275
- if (argv.length < 2) {
276
- return {
277
- status: TRIM_EXIT_USAGE,
278
- stdout: '',
279
- stderr: 'usage: fidelity-trim <in.png> <out.png> [<aligned.png> <reference.png>]',
280
- };
281
- }
282
- const [inputPath, outputPath] = argv;
283
- let image;
284
- try {
285
- image = PNG.sync.read(readFileSync(inputPath));
286
- }
287
- catch {
288
- return {
289
- status: TRIM_EXIT_UNREADABLE,
290
- stdout: '',
291
- stderr: 'could not read image at ' + inputPath,
292
- };
293
- }
294
- const box = contentBoundingBox(image.data, image.width, image.height);
295
- if (box === null) {
296
- return {
297
- status: TRIM_EXIT_NO_CONTENT,
298
- stdout: '',
299
- stderr: 'no content to trim (image is uniform)',
300
- };
301
- }
302
- const cropped = cropImage(image, box);
303
- try {
304
- writeFileSync(outputPath, PNG.sync.write(cropped));
305
- }
306
- catch {
307
- return {
308
- status: TRIM_EXIT_WRITE_FAILED,
309
- stdout: '',
310
- stderr: 'could not write trimmed PNG to ' + outputPath,
311
- };
312
- }
313
- // Optional aligned output: the trimmed image fit onto a reference-sized
314
- // canvas, preserving aspect ratio (transparent letterbox/pillarbox padding
315
- // when aspect ratios differ). A reference-sized, undistorted overlay pair.
316
- // Best-effort; dimensions are reported either way.
317
- let referenceWidth = 0;
318
- let referenceHeight = 0;
319
- if (argv.length >= 4) {
320
- const alignedPath = argv[2];
321
- const referencePath = argv[3];
322
- let reference = null;
323
- try {
324
- reference = PNG.sync.read(readFileSync(referencePath));
325
- }
326
- catch {
327
- reference = null;
328
- }
329
- if (reference !== null) {
330
- referenceWidth = reference.width;
331
- referenceHeight = reference.height;
332
- const aligned = fitPad(cropped, referenceWidth, referenceHeight);
333
- if (aligned !== null) {
334
- try {
335
- writeFileSync(alignedPath, PNG.sync.write(aligned));
336
- }
337
- catch {
338
- // best effort, as in the Swift helper
339
- }
340
- }
341
- }
342
- }
343
- // Report: rendered (trimmed) px, reference px (0 0 when unavailable), the
344
- // pre-trim source px (how much margin was removed), then the CROP ORIGIN —
345
- // where the trimmed image's top-left sits inside the source. The origin is
346
- // what lets a consumer place source-coordinate geometry (the layout dump's
347
- // window-space bounds) onto the trimmed bytes; without it every finding
348
- // spotlight drew shifted by exactly this offset on the first padded
349
- // wrappers (the 2026-08-01 diagnosis). Appended, never inserted: TRIMDIMS
350
- // parsers require >= 7 fields and ignore extras, so an old parser reading a
351
- // new line (and a new parser reading an old 6-number line) both degrade
352
- // safely to "origin unknown".
353
- const stdout = 'TRIMDIMS ' +
354
- [
355
- box.width,
356
- box.height,
357
- referenceWidth,
358
- referenceHeight,
359
- image.width,
360
- image.height,
361
- box.x,
362
- box.y,
363
- ].join(' ') +
364
- '\n';
365
- return { status: 0, stdout, stderr: '' };
366
- }
367
- //# sourceMappingURL=trim-align.js.map
@@ -1,11 +0,0 @@
1
- /**
2
- * Unit tests for the pure-JS trim/align helper (the CoreGraphics port).
3
- *
4
- * These exercise the pixel logic directly with pngjs-crafted images — no
5
- * `swift`, no real toolchain — so the bounding-box/crop/pad semantics that
6
- * previously needed CIBUILD_UI_FIDELITY_REAL_SWIFT=1 now run in every CI pass.
7
- * The Swift-vs-JS equivalence itself is guarded by the corpus gate in
8
- * trim-align-corpus.test.ts (real toolchain, gated).
9
- */
10
- export {};
11
- //# sourceMappingURL=trim-align.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"trim-align.test.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/trim-align.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -1,261 +0,0 @@
1
- /**
2
- * Unit tests for the pure-JS trim/align helper (the CoreGraphics port).
3
- *
4
- * These exercise the pixel logic directly with pngjs-crafted images — no
5
- * `swift`, no real toolchain — so the bounding-box/crop/pad semantics that
6
- * previously needed CIBUILD_UI_FIDELITY_REAL_SWIFT=1 now run in every CI pass.
7
- * The Swift-vs-JS equivalence itself is guarded by the corpus gate in
8
- * trim-align-corpus.test.ts (real toolchain, gated).
9
- */
10
- import { mkdtempSync, rmSync, writeFileSync, readFileSync, existsSync } from 'node:fs';
11
- import { tmpdir } from 'node:os';
12
- import { join } from 'node:path';
13
- import { PNG } from 'pngjs';
14
- import { describe, test, expect, afterAll } from '@jest/globals';
15
- import { runTrimAlign } from './trim-align.js';
16
- const RED = { r: 255, g: 0, b: 0, a: 255 };
17
- const BLUE = { r: 0, g: 0, b: 255, a: 255 };
18
- const WHITE = { r: 255, g: 255, b: 255, a: 255 };
19
- const PINK = { r: 255, g: 240, b: 238, a: 255 };
20
- /** Paint opaque rects onto a transparent canvas, top-left coordinates. */
21
- function craftPng(w, h, rects) {
22
- const png = new PNG({ width: w, height: h });
23
- for (const rect of rects) {
24
- for (let y = rect.y; y < rect.y + rect.h; y++) {
25
- for (let x = rect.x; x < rect.x + rect.w; x++) {
26
- const i = (y * w + x) * 4;
27
- png.data[i] = rect.r;
28
- png.data[i + 1] = rect.g;
29
- png.data[i + 2] = rect.b;
30
- png.data[i + 3] = rect.a;
31
- }
32
- }
33
- }
34
- return PNG.sync.write(png);
35
- }
36
- function pngSize(filePath) {
37
- const buf = readFileSync(filePath);
38
- return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) };
39
- }
40
- function pixelAt(filePath, x, y) {
41
- const png = PNG.sync.read(readFileSync(filePath));
42
- const i = (y * png.width + x) * 4;
43
- return [png.data[i], png.data[i + 1], png.data[i + 2], png.data[i + 3]];
44
- }
45
- const dirs = [];
46
- function scene() {
47
- const dir = mkdtempSync(join(tmpdir(), 'trim-align-js-'));
48
- dirs.push(dir);
49
- return dir;
50
- }
51
- afterAll(() => {
52
- for (const dir of dirs) {
53
- try {
54
- rmSync(dir, { recursive: true, force: true });
55
- }
56
- catch {
57
- // best effort
58
- }
59
- }
60
- });
61
- // ---- trim ----------------------------------------------------------------------
62
- describe('runTrimAlign — trim', () => {
63
- test('trims a transparent frame down to its single content rectangle', () => {
64
- const dir = scene();
65
- const input = join(dir, 'in.png');
66
- writeFileSync(input, craftPng(200, 200, [{ x: 30, y: 50, w: 60, h: 40, ...RED }]));
67
- const out = join(dir, 'out.png');
68
- const result = runTrimAlign([input, out]);
69
- expect(result.stderr).toBe('');
70
- expect(result.status).toBe(0);
71
- expect(pngSize(out)).toEqual({ width: 60, height: 40 });
72
- // The crop is a raw pixel copy of the content region.
73
- expect(pixelAt(out, 0, 0)).toEqual([255, 0, 0, 255]);
74
- expect(pixelAt(out, 59, 39)).toEqual([255, 0, 0, 255]);
75
- // TRIMDIMS: rendered (trimmed) px, reference px (0 0 without one), source
76
- // px, then the crop origin — where the trimmed image sits in the source.
77
- // The origin is what lets a consumer place source-coordinate geometry on
78
- // the trimmed bytes (the 2026-08-01 spotlight diagnosis).
79
- expect(result.stdout.trim()).toBe('TRIMDIMS 60 40 0 0 200 200 30 50');
80
- });
81
- test('crops an opaque uniform-background wrapper to its content card', () => {
82
- const dir = scene();
83
- // 420x320 transparent canvas, 375x200 white wrapper, 343x168 pink card.
84
- const input = join(dir, 'in.png');
85
- writeFileSync(input, craftPng(420, 320, [
86
- { x: 20, y: 40, w: 375, h: 200, ...WHITE },
87
- { x: 36, y: 56, w: 343, h: 168, ...PINK },
88
- ]));
89
- const out = join(dir, 'out.png');
90
- const result = runTrimAlign([input, out]);
91
- expect(result.status).toBe(0);
92
- // Lands on the content card, NOT the white wrapper (375x200) or the raw
93
- // canvas (420x320).
94
- expect(pngSize(out)).toEqual({ width: 343, height: 168 });
95
- });
96
- test('trims only transparency when the opaque corners disagree (fallback)', () => {
97
- const dir = scene();
98
- // Two differently-colored halves: the opaque bounding box is 80x80 but its
99
- // corners are not one uniform color, so no background is detected and only
100
- // the transparent margin is removed.
101
- const input = join(dir, 'in.png');
102
- writeFileSync(input, craftPng(120, 120, [
103
- { x: 20, y: 20, w: 40, h: 80, ...RED },
104
- { x: 60, y: 20, w: 40, h: 80, ...BLUE },
105
- ]));
106
- const out = join(dir, 'out.png');
107
- const result = runTrimAlign([input, out]);
108
- expect(result.status).toBe(0);
109
- expect(pngSize(out)).toEqual({ width: 80, height: 80 });
110
- });
111
- test('keeps a fully-opaque uniform image whole (never crops to nothing)', () => {
112
- const dir = scene();
113
- const input = join(dir, 'in.png');
114
- writeFileSync(input, craftPng(64, 48, [{ x: 0, y: 0, w: 64, h: 48, ...WHITE }]));
115
- const out = join(dir, 'out.png');
116
- const result = runTrimAlign([input, out]);
117
- // All four corners agree (uniform background) and pass 2 finds no distinct
118
- // content — the opaque box (the whole image) is kept, exit 0.
119
- expect(result.status).toBe(0);
120
- expect(pngSize(out)).toEqual({ width: 64, height: 48 });
121
- expect(result.stdout.trim()).toBe('TRIMDIMS 64 48 0 0 64 48 0 0');
122
- });
123
- test('is a no-op crop when content touches every edge', () => {
124
- const dir = scene();
125
- // Content fills the canvas with differing corner colors: nothing to trim.
126
- const input = join(dir, 'in.png');
127
- writeFileSync(input, craftPng(50, 30, [
128
- { x: 0, y: 0, w: 25, h: 30, ...RED },
129
- { x: 25, y: 0, w: 25, h: 30, ...BLUE },
130
- ]));
131
- const out = join(dir, 'out.png');
132
- const result = runTrimAlign([input, out]);
133
- expect(result.status).toBe(0);
134
- expect(pngSize(out)).toEqual({ width: 50, height: 30 });
135
- // Raw copy: pixels survive untouched.
136
- expect(pixelAt(out, 0, 0)).toEqual([255, 0, 0, 255]);
137
- expect(pixelAt(out, 49, 29)).toEqual([0, 0, 255, 255]);
138
- });
139
- });
140
- // ---- align ---------------------------------------------------------------------
141
- describe('runTrimAlign — aligned output', () => {
142
- test('writes a reference-sized aligned image and reports all three dimensions', () => {
143
- const dir = scene();
144
- const input = join(dir, 'in.png');
145
- writeFileSync(input, craftPng(200, 200, [{ x: 30, y: 50, w: 60, h: 40, ...RED }]));
146
- const reference = join(dir, 'ref.png');
147
- writeFileSync(reference, craftPng(100, 50, [{ x: 0, y: 0, w: 100, h: 50, ...BLUE }]));
148
- const out = join(dir, 'out.png');
149
- const aligned = join(dir, 'aligned.png');
150
- const result = runTrimAlign([input, out, aligned, reference]);
151
- expect(result.status).toBe(0);
152
- // The trimmed render is the content; the aligned copy is fit onto a
153
- // reference-sized canvas (preserving aspect) for a 1:1 overlay.
154
- expect(pngSize(out)).toEqual({ width: 60, height: 40 });
155
- expect(pngSize(aligned)).toEqual({ width: 100, height: 50 });
156
- expect(result.stdout.trim()).toBe('TRIMDIMS 60 40 100 50 200 200 30 50');
157
- });
158
- test('fits a wide render into a square reference without distortion (transparent letterbox)', () => {
159
- const dir = scene();
160
- // Content fills its canvas: a 2:1 render (80x40), all opaque red.
161
- const input = join(dir, 'in.png');
162
- writeFileSync(input, craftPng(80, 40, [{ x: 0, y: 0, w: 80, h: 40, ...RED }]));
163
- // Square 1:1 reference (50x50) — a deliberately different aspect ratio.
164
- const reference = join(dir, 'ref.png');
165
- writeFileSync(reference, craftPng(50, 50, [{ x: 0, y: 0, w: 50, h: 50, ...BLUE }]));
166
- const out = join(dir, 'out.png');
167
- const aligned = join(dir, 'aligned.png');
168
- runTrimAlign([input, out, aligned, reference]);
169
- // Aligned stays exactly reference-sized (overlay pair holds).
170
- expect(pngSize(aligned)).toEqual({ width: 50, height: 50 });
171
- // Aspect preserved: the 2:1 content fits by width (50x25) and is centered,
172
- // so both letterbox bands are transparent while the center is opaque
173
- // content. A stretch-to-fit would make every one of these opaque.
174
- expect(pixelAt(aligned, 25, 3)[3]).toBe(0); // top band
175
- expect(pixelAt(aligned, 25, 46)[3]).toBe(0); // bottom band
176
- expect(pixelAt(aligned, 25, 25)[3]).toBe(255); // content (center)
177
- });
178
- test('upscales into a larger reference and downscales into a smaller one', () => {
179
- const dir = scene();
180
- const input = join(dir, 'in.png');
181
- writeFileSync(input, craftPng(40, 40, [{ x: 0, y: 0, w: 40, h: 40, ...RED }]));
182
- const out = join(dir, 'out.png');
183
- // Reference smaller than the render: content is downscaled to fit.
184
- const smallRef = join(dir, 'ref-small.png');
185
- writeFileSync(smallRef, craftPng(20, 20, [{ x: 0, y: 0, w: 20, h: 20, ...BLUE }]));
186
- const alignedSmall = join(dir, 'aligned-small.png');
187
- let result = runTrimAlign([input, out, alignedSmall, smallRef]);
188
- expect(result.status).toBe(0);
189
- expect(pngSize(alignedSmall)).toEqual({ width: 20, height: 20 });
190
- expect(pixelAt(alignedSmall, 10, 10)).toEqual([255, 0, 0, 255]);
191
- // Reference larger than the render: content is upscaled to fit.
192
- const bigRef = join(dir, 'ref-big.png');
193
- writeFileSync(bigRef, craftPng(80, 80, [{ x: 0, y: 0, w: 80, h: 80, ...BLUE }]));
194
- const alignedBig = join(dir, 'aligned-big.png');
195
- result = runTrimAlign([input, out, alignedBig, bigRef]);
196
- expect(result.status).toBe(0);
197
- expect(pngSize(alignedBig)).toEqual({ width: 80, height: 80 });
198
- expect(pixelAt(alignedBig, 40, 40)).toEqual([255, 0, 0, 255]);
199
- });
200
- test('an identity-size reference yields a pixel-identical aligned copy for opaque content', () => {
201
- const dir = scene();
202
- const input = join(dir, 'in.png');
203
- writeFileSync(input, craftPng(30, 20, [
204
- { x: 0, y: 0, w: 15, h: 20, ...RED },
205
- { x: 15, y: 0, w: 15, h: 20, ...BLUE },
206
- ]));
207
- const reference = join(dir, 'ref.png');
208
- writeFileSync(reference, craftPng(30, 20, [{ x: 0, y: 0, w: 30, h: 20, ...WHITE }]));
209
- const out = join(dir, 'out.png');
210
- const aligned = join(dir, 'aligned.png');
211
- const result = runTrimAlign([input, out, aligned, reference]);
212
- expect(result.status).toBe(0);
213
- const outPng = PNG.sync.read(readFileSync(out));
214
- const alignedPng = PNG.sync.read(readFileSync(aligned));
215
- expect(alignedPng.width).toBe(outPng.width);
216
- expect(alignedPng.height).toBe(outPng.height);
217
- expect(Buffer.compare(alignedPng.data, outPng.data)).toBe(0);
218
- });
219
- test('a missing reference is best-effort: no aligned image, zero reference dims', () => {
220
- const dir = scene();
221
- const input = join(dir, 'in.png');
222
- writeFileSync(input, craftPng(100, 100, [{ x: 10, y: 10, w: 50, h: 30, ...RED }]));
223
- const out = join(dir, 'out.png');
224
- const aligned = join(dir, 'aligned.png');
225
- const result = runTrimAlign([input, out, aligned, join(dir, 'nope.png')]);
226
- expect(result.status).toBe(0);
227
- expect(existsSync(aligned)).toBe(false);
228
- expect(result.stdout.trim()).toBe('TRIMDIMS 50 30 0 0 100 100 10 10');
229
- });
230
- });
231
- // ---- failure contract ------------------------------------------------------------
232
- describe('runTrimAlign — failure contract (Swift helper exit codes)', () => {
233
- test('usage error without two paths', () => {
234
- const result = runTrimAlign(['only-one.png']);
235
- expect(result.status).toBe(64);
236
- expect(result.stderr).toContain('usage:');
237
- });
238
- test('unreadable input exits 65', () => {
239
- const dir = scene();
240
- const result = runTrimAlign([join(dir, 'missing.png'), join(dir, 'out.png')]);
241
- expect(result.status).toBe(65);
242
- expect(result.stderr).toContain('could not read image at');
243
- });
244
- test('a fully-transparent image has no content and exits 66', () => {
245
- const dir = scene();
246
- const input = join(dir, 'in.png');
247
- writeFileSync(input, craftPng(40, 40, []));
248
- const result = runTrimAlign([input, join(dir, 'out.png')]);
249
- expect(result.status).toBe(66);
250
- expect(result.stderr).toContain('no content to trim');
251
- });
252
- test('an unwritable output path exits 68', () => {
253
- const dir = scene();
254
- const input = join(dir, 'in.png');
255
- writeFileSync(input, craftPng(40, 40, [{ x: 0, y: 0, w: 10, h: 10, ...RED }]));
256
- const result = runTrimAlign([input, join(dir, 'no-such-dir', 'out.png')]);
257
- expect(result.status).toBe(68);
258
- expect(result.stderr).toContain('could not write trimmed PNG');
259
- });
260
- });
261
- //# sourceMappingURL=trim-align.test.js.map