@prosopo/datasets-fs 3.0.142 → 3.0.144

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 (221) hide show
  1. package/.turbo/turbo-build$colon$cjs.log +3 -6
  2. package/.turbo/turbo-build$colon$tsc.log +11 -14
  3. package/.turbo/turbo-build.log +4 -10
  4. package/CHANGELOG.md +25 -0
  5. package/LICENSE +201 -0
  6. package/README.md +1 -1
  7. package/package.json +76 -76
  8. package/dist/tests/data/flat/data.json +0 -364
  9. package/dist/tests/data/flat_resized/captchas_v1.json +0 -5155
  10. package/dist/tests/data/flat_resized/captchas_v2.json +0 -5305
  11. package/dist/tests/data/flat_resized/data.json +0 -364
  12. package/src/cli/cli.ts +0 -82
  13. package/src/cli/cliCommand.ts +0 -68
  14. package/src/cli/cliCommandComposite.ts +0 -54
  15. package/src/cli.ts +0 -50
  16. package/src/commands/flatten.ts +0 -152
  17. package/src/commands/generate.ts +0 -218
  18. package/src/commands/generateV1.ts +0 -273
  19. package/src/commands/generateV2.ts +0 -293
  20. package/src/commands/get.ts +0 -113
  21. package/src/commands/labels.ts +0 -78
  22. package/src/commands/relocate.ts +0 -109
  23. package/src/commands/resize.ts +0 -171
  24. package/src/dummy.ts +0 -52
  25. package/src/index.ts +0 -14
  26. package/src/tests/data/flat/data.json +0 -364
  27. package/src/tests/data/flat/images/0x05091030b0194cf5a1b059e5674588fa62f8fcc95d2c37b8a00363822da00c9e.jpeg +0 -0
  28. package/src/tests/data/flat/images/0x082fb46c767ea3b1e9bfe53fa64e7a3e84847bd0d605bffadb426cdc08abef4f.png +0 -0
  29. package/src/tests/data/flat/images/0x0a35888b9b2b8647188d332ca7df5b8bbe589c1c7705939ca2fb0ee2ca3477da.png +0 -0
  30. package/src/tests/data/flat/images/0x0b0050d61e94d8ec34894f026f367e2c6ba3635f1c9bac048080ce2bf67266e7.png +0 -0
  31. package/src/tests/data/flat/images/0x10e3ae57c9add1e684fe57389333d7d6223f1fdf5822b6ea406bcffc0b351e08.png +0 -0
  32. package/src/tests/data/flat/images/0x131e0d0227ac2e907a12a25ddc6ef0604a44b77b4c588bfc4fb63794a513df83.png +0 -0
  33. package/src/tests/data/flat/images/0x1640d68939038ebab7cb0e94302b8b3d4128be793f4170aba447e78fcf40c971.png +0 -0
  34. package/src/tests/data/flat/images/0x174c3bf273178340e86f2924e9e039a7304c63976b6f7002425889d9e5d791b1.png +0 -0
  35. package/src/tests/data/flat/images/0x18ad206ff2308f7ab68309953afdd731291f041c419cad4d2325d1a5db79b8fe.png +0 -0
  36. package/src/tests/data/flat/images/0x1e52c506264d67ba391d284f5e4c658719c5fd103d127a106b19b1d0e9dc1d4f.png +0 -0
  37. package/src/tests/data/flat/images/0x3631b988baf3a904a33fb2aa90ee5037c4948298d4fa7583f6b7fc0d3bcc7dbd.png +0 -0
  38. package/src/tests/data/flat/images/0x3823a951c0f734e2853c171ccb45ffef6cbabe2db8e44373481f798e9e54bed5.png +0 -0
  39. package/src/tests/data/flat/images/0x39af118a0e9275fef6233cc8cdb99c285358b1b9af696d6248e0952c08bfa155.png +0 -0
  40. package/src/tests/data/flat/images/0x3b8135d0b0807c82d287f78efd17a83236654d1fee99b9b05880e7fff0cebd49.png +0 -0
  41. package/src/tests/data/flat/images/0x46a682c6f2dac118110e1d633caa577690e5428232f41c9ae4f7742f66349744.png +0 -0
  42. package/src/tests/data/flat/images/0x4ff56bb64db6bf8d2da9e0e41e899c0f29e4f857b55a0f3e6b0dd2b74ab2de0a.png +0 -0
  43. package/src/tests/data/flat/images/0x594b242ce43c66d60925a55781bdee393877bca20d7c1454a406060151918e3f.png +0 -0
  44. package/src/tests/data/flat/images/0x5a46e6ea9c761583e2880a30471427c34ee765c763b8cccb7aa12dc3061bdd4b.png +0 -0
  45. package/src/tests/data/flat/images/0x5e5912ce314ced9343d9b3438cf686b6fe9e7e02389291e3e062f4262c20a528.png +0 -0
  46. package/src/tests/data/flat/images/0x5e66da18ea4507243b171dbda04feb58e569b667ebf00095f8a8df133cef6837.png +0 -0
  47. package/src/tests/data/flat/images/0x6268f9fe9033f65b6f44820c016a4691f5677f982d5531350c2d272bec1d6d60.png +0 -0
  48. package/src/tests/data/flat/images/0x6393925c19adc0506341888868be75ce0c7824a6be39549ad236560440f21ba0.png +0 -0
  49. package/src/tests/data/flat/images/0x643d46be074110da9f90353c6e7b77a2e2ecc844c517efc14899bcefc2f3cbb1.png +0 -0
  50. package/src/tests/data/flat/images/0x6ded34173b4d4f29142fdd267a757cbd67d7bf658b555a9715a7799a726d92df.jpeg +0 -0
  51. package/src/tests/data/flat/images/0x7150126436c0e3e3d9c2b676c7df918aaf499897e040f2a4a2ecfa729356c656.png +0 -0
  52. package/src/tests/data/flat/images/0x74d88f9681fcf9cd0e196c5ebd7a778a5535618d23ccd261c7bd621db7b3437a.png +0 -0
  53. package/src/tests/data/flat/images/0x75df5bfc506beaa5f10cf70814d7ca2982d548dd9862b08bc8239bdacb8efb8e.png +0 -0
  54. package/src/tests/data/flat/images/0x76e8a46bb023a50ae572a0f2f0652bdbe91de396591f9b8113c591ee9167dcc6.png +0 -0
  55. package/src/tests/data/flat/images/0x7c90aa44660f9168c25b66260ecc97c6e7e59aa48b629c6849a091c10e82d718.png +0 -0
  56. package/src/tests/data/flat/images/0x7ed3f3a320b39157eaeee4b88faf436d95a80b3d9eff6582970dcd8c996976f4.png +0 -0
  57. package/src/tests/data/flat/images/0x822c948e5635f97ba2a87680afee04b034a35af7aa095c19753b591a39a3846b.png +0 -0
  58. package/src/tests/data/flat/images/0x854f011e0f856ee1c4ffa705e259da6f4edbd18366de86e68be4163777455499.png +0 -0
  59. package/src/tests/data/flat/images/0x8c67000eeb4314aaebe9673d1d0da285cad28401be302edf029a504f1fdba4b5.png +0 -0
  60. package/src/tests/data/flat/images/0x8f23eed845635dbca6eb323efaea55e5ddcd7c8fbb845b2dae7d762ccda9f437.png +0 -0
  61. package/src/tests/data/flat/images/0x96e336b3a736566736ef4a2cb2f71f31492de08010f5d4d071c7a4d16a911e55.jpeg +0 -0
  62. package/src/tests/data/flat/images/0x9b3fb6bf7cfc0ca8e6715bdc23a41fa4a6eaa1cc2e08363051ab4cb18e8326bb.jpeg +0 -0
  63. package/src/tests/data/flat/images/0xa020771c955e2ee507d55b962f1f233d2f9f1768f390a9280c28d25d8f2d567a.png +0 -0
  64. package/src/tests/data/flat/images/0xa4b7edf9324173eaede105dfa66175be48340eefad9d139595c97ff999a188b8.png +0 -0
  65. package/src/tests/data/flat/images/0xa523158bea4556c82b25dee7915f25389f6e11d79666a0f9987ff45755ba87be.png +0 -0
  66. package/src/tests/data/flat/images/0xa6e0837a126dafc677bb0e18614220fb633fc034e1fd9c6ebf5db1c2f03bf6e8.png +0 -0
  67. package/src/tests/data/flat/images/0xabaebe0601780f717be6fd6166ea1f5d5c3d14d69b72e82b2680bf8790d81d70.jpeg +0 -0
  68. package/src/tests/data/flat/images/0xaecf0481063fcb4b4bfba3dc3eee86e5686ddb763885f309551a5316f3579adb.png +0 -0
  69. package/src/tests/data/flat/images/0xbe18f40b90e0cdd9dda77b7ca3bd14a29cc85b57241b104a34db3442064fb3c0.jpeg +0 -0
  70. package/src/tests/data/flat/images/0xbe46849030260c39eef1cf2c5fd3855bef597d46049216851bdaf47efab43664.png +0 -0
  71. package/src/tests/data/flat/images/0xbfeed6b56cead71f853859b934d769767832af9344003c0685759caa79665aec.png +0 -0
  72. package/src/tests/data/flat/images/0xc1500e538df7e2fa287fe006c1b41c0b4ba4048ef58cb93926c3ff6f8e0e4f39.png +0 -0
  73. package/src/tests/data/flat/images/0xc2d03a53ff057f5a2c6f46ca830c5f8a233fb9a3ee561578b83c89cf09c1f8b1.png +0 -0
  74. package/src/tests/data/flat/images/0xcc8601fced686065c4673cc1375a1bf7b6e06ffeab3d4db9495fb55702df41c4.png +0 -0
  75. package/src/tests/data/flat/images/0xce9358701f9095fd68bbdf75c961032a18b1d5bad288d99988a3e9848359a2d0.png +0 -0
  76. package/src/tests/data/flat/images/0xd49a0f5a57584806e9f96e950039b72e762253d46d3767d442fc19e5c7c62d1f.png +0 -0
  77. package/src/tests/data/flat/images/0xd5cf2919b366879fe33306ba7bd3486a0a92b2d0ef67965c2b0c3338c1c62817.png +0 -0
  78. package/src/tests/data/flat/images/0xdec3aa6053d6699b9a6ecd5de081940f0f197ed848a42ccd828e89f941235926.jpeg +0 -0
  79. package/src/tests/data/flat/images/0xe269a4d7a2257412f3cd89a3a35c086ae23205db4559a2c91aef41a7e05b5e57.png +0 -0
  80. package/src/tests/data/flat/images/0xe2831f9d30fdfe311369a2f02bff50622b8d0fe2bd3d6b8a01baef9e6e3f6af9.png +0 -0
  81. package/src/tests/data/flat/images/0xe61857c06704ff95175ad8659abbbed617dc832b3390669754ef07fcaa98a597.png +0 -0
  82. package/src/tests/data/flat/images/0xef8fb6ba0c9849f6b462326129bd82e0d22aaf41f195492573aa0e75c7303568.png +0 -0
  83. package/src/tests/data/flat/images/0xefe80829c296bbe390dde416b6fea2d2b53410c6cffd65000efbe22cb77dde54.png +0 -0
  84. package/src/tests/data/flat/images/0xfa36fecae98675524d19650a9331bc53d55a2ea885eb2748fb9841afbf837f84.jpeg +0 -0
  85. package/src/tests/data/flat/images/0xfb3d323f655c0f322bbcd5acc8a62978b33e2f17e2593a3b9e9f690485ae70ec.png +0 -0
  86. package/src/tests/data/flat/images/0xfe059081c9d82baef2228ca0ae2d24fefff834e8e168f7b5dc8b45ec4ebcb81d.jpeg +0 -0
  87. package/src/tests/data/flat_resized/captchas_v1.json +0 -5155
  88. package/src/tests/data/flat_resized/captchas_v2.json +0 -5305
  89. package/src/tests/data/flat_resized/data.json +0 -364
  90. package/src/tests/data/flat_resized/images/0x01680c6900f9f5d1b637e9ee6a47e39bd5febfa8c05e97411bf296e08f1084123c2ddb3c811c36e5daa860390b9f90c6136a0b852a6984867e12e82357dae101.jpg +0 -0
  91. package/src/tests/data/flat_resized/images/0x04412e617469fdd30059f9f2d77b3ee8d4d47ae9b31dd835bf5c72e1f03e617fb4cd45c43b3941415ad7a0a52579721aff179fdad282692f4f8ba7a4ceac3f2b.jpg +0 -0
  92. package/src/tests/data/flat_resized/images/0x0458b3119fe75beee322385ae298e5b69935c25c7b1e5953aca86898de74beab2d724af5f9b0a88f66e6588af8a7c53124b77b4eda7274aebeaf12751c880788.jpg +0 -0
  93. package/src/tests/data/flat_resized/images/0x09880e7ecc1d66c0d0fc634717bd92f657fbe74e465d7267f053331e0ca4ed6e3f35dfe96c35d65074d614d54af274a6791a8ca1bd24e92ff4a6ddb5e3a6a30c.jpg +0 -0
  94. package/src/tests/data/flat_resized/images/0x0d7468ab4b4a4870206f9416f02fab49bd6a677cbfad72d02fefdb5a5a766b15c45d5e9bce4375eef9e0714c2085f16efd6c092bc6a6433b2bd619b59ca29823.jpg +0 -0
  95. package/src/tests/data/flat_resized/images/0x180b41b967281d56136fd1dc00866dc00e21a73045a057a0ec2e7303a95ff9f5bffae41a5a8f3fa498c435abeb90769d16db07292e42f5ec8f5557239253d867.jpg +0 -0
  96. package/src/tests/data/flat_resized/images/0x2de20d716e37f702edb17834ac8205b5b11ad43620f0dd079ed680c710f9ac0b65ecf6bb85d85aa9a82a3adf6f0795fe842e7e6a289034ed1c29027af9366da3.jpg +0 -0
  97. package/src/tests/data/flat_resized/images/0x2e000a3726d8739111832f1dbf028f8dfe74fe028c4149b1d4047c361ed3338c9ad4fff03d734daddc0748148e207c5a46b31546ad6a9853ddfa0eabde6cbd98.jpg +0 -0
  98. package/src/tests/data/flat_resized/images/0x32e77cca2c8f235bb30482e9b33bf9f00e18ba4d6356330b5c02d736688efd4e894950fc3fdd3def828284b3df9f21c62cbca81a71345068c4540ee334153b66.jpg +0 -0
  99. package/src/tests/data/flat_resized/images/0x34c24373be3774a7ce601560f74d70839365f2a72fbe9acf6400e8e72fd859df66d80111d777ec686ad742170be3865102571062710b28a6dee0b9eec5d7b16c.jpg +0 -0
  100. package/src/tests/data/flat_resized/images/0x371825e60f5132764056973240b261b6e750b8fcc2440d7651a0798c611d551939c48b51bb1c58d2bbe6cac5c76122a329b38234d1047b4e502fac8de12bcb87.jpg +0 -0
  101. package/src/tests/data/flat_resized/images/0x389e0af93f52e4b02b954d1bf86dc7731f9c39dd4ab17d30f80a3bed28c7c5638beb4de36d87346c7552f281315540beba0ca471b92790a53c0c1247acad75fc.jpg +0 -0
  102. package/src/tests/data/flat_resized/images/0x396231a7e0ac7343c672d8a1d69ca5e89a773b9e771f2261866d44197e77018667b42ac01c1343e0f89cf7ae13994b12e607a4620e41989888e438589b2906fb.jpg +0 -0
  103. package/src/tests/data/flat_resized/images/0x39c573f966efa7bd57c57835cb55dd17c781b9ef18c2e502e9c9dc663678d442e5f0e72b5ad53f4294747d8f0f4bf6567d70fa072b120e85db8fe33d3ca288b9.jpg +0 -0
  104. package/src/tests/data/flat_resized/images/0x3aa3d1167d1a59a3fd98fc625673f1eb44e40077a761deb5284db866d0971309a0f266b0c1d73ac309e0f8b630232d19d84ff2761999880477c3eaf2c9c88ac7.jpg +0 -0
  105. package/src/tests/data/flat_resized/images/0x42bdd353f77090d619e06fce1ac874811437082d3617d3e361249e4eb01c1e458f7c2f0c916e7437b8269d862acb3deac930af7895903843bded8aea2796cee4.jpg +0 -0
  106. package/src/tests/data/flat_resized/images/0x4565f4b3d28bddbecf602ec346705fc87fc119789b6302e2114b60440d85c28a5a5b28b2a9623fd1a7107e1469af738b26dcb86ab78f97b4b37c92b149097b2e.jpg +0 -0
  107. package/src/tests/data/flat_resized/images/0x470b8e46d24caad83799983764b9ad3b01899fd203571dd51d53e9043312fb8a4073a79cde621492c44e5e8767bc301edae65c7234056eaa3948332c929af4d3.jpg +0 -0
  108. package/src/tests/data/flat_resized/images/0x4b0a605692c1a6b725e118f9597f056eeef7c01879504046aede300e30d5e02ae421295a35c6d8676e9b3e0d219ab226e0dedd608946bf852d699a35e07227b3.jpg +0 -0
  109. package/src/tests/data/flat_resized/images/0x5125f70be96446963faa123a96e3b5e453e0ea3d66cc73fb075afa032ad81ead2b439b8be8837c2f7bc194aed87a62766efecbe510bfa41e2933c5f4687df123.jpg +0 -0
  110. package/src/tests/data/flat_resized/images/0x5671b364222cd5ce64a572a09bf8e726acd3ad74e5ad18f7a52751c6f9f35b506bc90d3ff2668f4b32bed6b1233827fb0443fae6f28887b0362768587171f43c.jpg +0 -0
  111. package/src/tests/data/flat_resized/images/0x5785b0476631bbf564cc032362f1ab3401f8e161056b1d7b5774a49699fb1bc60bbaf31b7e0a11456acf59df7886e2ab150d6c21f88287e66d7e15ed521e10be.jpg +0 -0
  112. package/src/tests/data/flat_resized/images/0x5ad8988769dd7d7307cf6fbb4c5c3f984e3889d9f19c472b21993144cb1be82a676f990fea505b6d2e39a0eca6755e9a7a814031afc463db1ca0eab6d9f43f55.jpg +0 -0
  113. package/src/tests/data/flat_resized/images/0x5c36f99be856c4e4cd4f66e7743763e5f8cc6598ab198fe6062fa985b5bd49e57abb5d09ace58eb032974cb76243638d6a1250faac1982d370b3c1fd54e02e06.jpg +0 -0
  114. package/src/tests/data/flat_resized/images/0x5e1ec6b5e8ef81f4235281fb9ef14168b459c7b6dc649056fc550fd3ce81d9c42d591464d1c38af59316cffb8a32d12551bc789ff76c8cdd4aa270df5d250ffb.jpg +0 -0
  115. package/src/tests/data/flat_resized/images/0x5fcba56aab516fbe641c9a025d047c0e0f1ebe5c200232cfdc865651eeca8a729a642638a8783216cf287ccc751139705c3ff23e5ca6d864c91129db3257fa5f.jpg +0 -0
  116. package/src/tests/data/flat_resized/images/0x6104fdac0b38ff92ca033296b1249a3e6aff461604a15964f12bdeb6c561b9891a700f191aabd7621f171a807206376e681fcd945be1a345c9dabb387b99d3e5.jpg +0 -0
  117. package/src/tests/data/flat_resized/images/0x6495581992b5bff4c4507ba941650ee8e9754b11c7b85856972d124c03bdf371dba86d797ffa44bf9cc8ac0bde2fb310cc2799a786484bb89b51b60aff05b647.jpg +0 -0
  118. package/src/tests/data/flat_resized/images/0x649d4b4b28245565c8f4f729674ccdde4d6985b691cb775a9367340c46d587cc733128fd82081d04e2a2321dc7c94470d1b02bad7effa6b1239086c2167d49c6.jpg +0 -0
  119. package/src/tests/data/flat_resized/images/0x681d594021ec03f34798bfd7cfdf351b2f5fce87490b7b353b265d415532c5e0b7751c04f44a5c1d92f112628068cfe185af1452046534f5adfbd75e39785927.jpg +0 -0
  120. package/src/tests/data/flat_resized/images/0x72a8e4393cf2abe8a1ded5d7b94f75bc2d87343b9893f03e67ee11a6e08c5ed112d69b71cecaf38350d8761560870c982bd0d56a4cd9c6572b20f316f4b59e4e.jpg +0 -0
  121. package/src/tests/data/flat_resized/images/0x72ce2eb8dbc60ab9f81a82e2c20867a433733e05364e4e5f0ee699a2556547ea21cd10e45e39d0f20587c6ef8fdbed1934819a06b6f64d82bb7b821b0784ac37.jpg +0 -0
  122. package/src/tests/data/flat_resized/images/0x794962f855ab553b9b269af817d22a9f3aace428b5637f27ea6fe7763ce9cbfe976f7725fa24a922401689c2df3f911f61f0d45d6a3e8e6bdd05a3aaae89200a.jpg +0 -0
  123. package/src/tests/data/flat_resized/images/0x8471a7824a8e152b12d04464fdeb73b2011337671cdc448be5dd77abe978d554de6e5f2741437fd97e25f1275ae837be8382c2c3d9a6311545c2d6e8666a6604.jpg +0 -0
  124. package/src/tests/data/flat_resized/images/0x858ae20f81f795c960a5cadd84f3dd8e1e6798fc719545f3a10001def3cc89b5c23cd00149a6eb6a2062e10b5b882030c7c0b14ec7c1ea7e1f66114b9081466e.jpg +0 -0
  125. package/src/tests/data/flat_resized/images/0x8a2fd874ef10dc79a07e8fb0a42d7d08bb9e68b4836857b7afe018e660dd1077787fff678908442f7cd31001c3d5c0c94195cac8e4eb5ce649370d40447d9ccf.jpg +0 -0
  126. package/src/tests/data/flat_resized/images/0x919e0adb11eec9a9e8aefbf91e6547c9952032539ea3cc1fb524ca7e803486082f0b673fcf2f633be2f46d3863b4af3e78bc52b0ca9fcc32d5180bf33c8da0c8.jpg +0 -0
  127. package/src/tests/data/flat_resized/images/0x9d19edc89ca1bbfebfa9f8dd54dc260e3b13e9ec150060f10e6ed3532229125b97ea7914b6079e7880eaeae6b8617428faaa4ce89f587c3394cb80472692bd70.jpg +0 -0
  128. package/src/tests/data/flat_resized/images/0x9d837a0223af31f41888daada1e773bf3c6637155ea970fc845b69a59403516b28a246f503d12aff880a895073834a930a25e3ed744a97aac39d379f3310fd17.jpg +0 -0
  129. package/src/tests/data/flat_resized/images/0xa0ccf619a2a37ef41d1db3aba88e8d85a1b0e6ae379b5dafd61e66864e33cc2f763b794cdbeb5fecfe4df980be7b64c7ee6720841530f09d4b823d7f8403192d.jpg +0 -0
  130. package/src/tests/data/flat_resized/images/0xa22be612fcc2f85ba62fe0fd5d41e4f642419fecc6c4bc3a4018292dcad0d74e1d615c8135754bbbc630c69191d3fb5a45ec923fc419fa6e5b01548102ff0e86.jpg +0 -0
  131. package/src/tests/data/flat_resized/images/0xa405b623dbacae064fcbbac84a9a810134600834e9874979d8c827a7a5571814ca1d044864b6fab738af32d791cb4fd2cb27688fd4c8d75d590135c4672e96c1.jpg +0 -0
  132. package/src/tests/data/flat_resized/images/0xa8ccce7c6e2c11463003b922c5f5a0510cd403e10f54876bbde2b742779302639bb29069005588fcff326b104c2d10f1584cad75f4cc01f4c5129f964c57f80c.jpg +0 -0
  133. package/src/tests/data/flat_resized/images/0xb1906d609690d30717b2f90e596d6a0c70e72df8d964bc81c9a657256fc4e28754908b162544810ca719f58624f392d34acc9bf5028d31512161c625957ede03.jpg +0 -0
  134. package/src/tests/data/flat_resized/images/0xb25179ff5cee6d5c86869d9dcc4622b2b4f11c78a84a55f6cfee484216cb29b1fc0e15b67edeb5e13d8715d491c1749337d8b6db904e5ca64d42a1a863064324.jpg +0 -0
  135. package/src/tests/data/flat_resized/images/0xbdb9bd3967d77c904168fa104ae1608cc49cdd203af867d8268872f8a939cb6930ab60fdad5dea105692aabe09c9b083cb98a6c33955b725096801924c85f73b.jpg +0 -0
  136. package/src/tests/data/flat_resized/images/0xcb0921ffcdcd10f17cdc682bf131ca5c30527bf54601c5d852871e2f1e1bcdff090e8f8d0cca43804ad4fe47b4e8deb9b7e1ce5958b940245caabcb4034f0e0a.jpg +0 -0
  137. package/src/tests/data/flat_resized/images/0xdccf04070efcb4476099bf280476ff43f44738561764f78eb4b7ca253249163ca347735efb767655db862797ddf4f4b7a7c93e96e5d21c0e7a60ec8bb5296f1b.jpg +0 -0
  138. package/src/tests/data/flat_resized/images/0xe07aebd1f97c948b2abbccb8dcd020add589ba84e3f6f8676c8defacdbcf70fb4e06757b0f323e988051e1528718140fd10f2182fe5e27b15b7680653525a141.jpg +0 -0
  139. package/src/tests/data/flat_resized/images/0xe09ee718f6b6677fe12a1381ca47b0bd209198070331b75ff77defdc88d066b97e0f6de1bef85ddbc857e2c5f3951fec9a450f2ae3a16f5effa62bd0f07e211c.jpg +0 -0
  140. package/src/tests/data/flat_resized/images/0xe283a7fa1c6b8de22c3cfeedf50a7a75cc4dae628e25222e2f65b9e6f2768a3db17c882c6841841ad9d9d55a02721f94fa4ad06d5797641a4992ce30ff2ac483.jpg +0 -0
  141. package/src/tests/data/flat_resized/images/0xed72d39933893c3a176e8360d38f79faef02e59b583e114f0b5a9f3043e6fb24fb6399e8550b51a5e1d9ef8cde7a02a7373739b0b488aacac74a86a8e03a34a3.jpg +0 -0
  142. package/src/tests/data/flat_resized/images/0xf086e3ee0c5f7997e724d93e02313697deacf9952c561e79365b1daf915f0291a293df2456d1894d64f6c8f191d4ef590b1374b2743f3ce695468a677d6b91a5.jpg +0 -0
  143. package/src/tests/data/flat_resized/images/0xf466148cbfd860870b834045825ae7f7b0994645b0a08ab246c0fe5d2051c2c0d9b48156d1a5bbf7621075ee98116b0514c38d7ff2886bd4882e10e1aa18b7f1.jpg +0 -0
  144. package/src/tests/data/flat_resized/images/0xf49755cdc166b3c028ed7ce9bff377f191bd3b06a10f166308b662e557e723cabc0b6f613000db5971b4205936c51c6681734100caa9475bcb75e420725f11da.jpg +0 -0
  145. package/src/tests/data/flat_resized/images/0xf74a7822da8bcca082c1c9bf9653555f6924e6a7bef0b523f7d681b34e2d3f06d0ede639a0703462b75df77c241f8ebb4673c55d619faacad749f208c8d44190.jpg +0 -0
  146. package/src/tests/data/flat_resized/images/0xf9478fa2283203a1ac62fcb044532520b9286e66f42489b5519381b4ecbfca939c9de07a4a0e4fb7315c3eb4656ab6dee6951e6f7b2a45d32b649af06ef93120.jpg +0 -0
  147. package/src/tests/data/flat_resized/images/0xfa5a7d2a32748801a8714e51595ccb6de07d7631bddea3bee543f8296cbac0acd684c29339cfbd3f578ff167bfeb2eca70cdf6a773e52797674c31a14ec293ea.jpg +0 -0
  148. package/src/tests/data/flat_resized/images/0xfb9b2be2b9fcf6294b29dc18df21714a6d23d6a78d4c574747630d21727f72a7b2b4ae5666ebae4409cb7a85308f11d8dc186aa26709b0c53e41530f4a57ba6d.jpg +0 -0
  149. package/src/tests/data/flat_resized/images/0xffeb64c20d8367f56d4ed039c11e115c85b054a53120e34e4e3b081be92741b740bc16ce334e0558eda2476c97ed6209c34c4125c93d758cbee535520364cd60.jpg +0 -0
  150. package/src/tests/data/flat_resized/labels.json +0 -13
  151. package/src/tests/data/flat_resized/relocated_data.json +0 -364
  152. package/src/tests/data/hierarchical/bird/Screenshot from 2023-10-12 16-30-52.png +0 -0
  153. package/src/tests/data/hierarchical/bird/Screenshot from 2023-10-12 16-31-26.png +0 -0
  154. package/src/tests/data/hierarchical/bird/Screenshot from 2023-10-12 16-31-40.png +0 -0
  155. package/src/tests/data/hierarchical/bird/Screenshot from 2023-10-12 16-32-07.png +0 -0
  156. package/src/tests/data/hierarchical/bird/Screenshot from 2023-10-12 16-32-25.png +0 -0
  157. package/src/tests/data/hierarchical/bird/test_image_png_15.png +0 -0
  158. package/src/tests/data/hierarchical/bus/01.02.jpeg +0 -0
  159. package/src/tests/data/hierarchical/bus/01.03.jpeg +0 -0
  160. package/src/tests/data/hierarchical/bus/01.04.jpeg +0 -0
  161. package/src/tests/data/hierarchical/bus/Screenshot from 2023-10-12 16-33-02.png +0 -0
  162. package/src/tests/data/hierarchical/bus/Screenshot from 2023-10-12 16-33-21.png +0 -0
  163. package/src/tests/data/hierarchical/bus/Screenshot from 2023-10-12 16-33-32.png +0 -0
  164. package/src/tests/data/hierarchical/car/Screenshot from 2023-10-12 16-34-03.png +0 -0
  165. package/src/tests/data/hierarchical/car/Screenshot from 2023-10-12 16-34-14.png +0 -0
  166. package/src/tests/data/hierarchical/car/Screenshot from 2023-10-12 16-34-24.png +0 -0
  167. package/src/tests/data/hierarchical/car/test_image_png_25.png +0 -0
  168. package/src/tests/data/hierarchical/car/test_image_png_71.png +0 -0
  169. package/src/tests/data/hierarchical/car/test_image_png_89.png +0 -0
  170. package/src/tests/data/hierarchical/cat/test_image_png_22.png +0 -0
  171. package/src/tests/data/hierarchical/cat/test_image_png_24.png +0 -0
  172. package/src/tests/data/hierarchical/cat/test_image_png_33.png +0 -0
  173. package/src/tests/data/hierarchical/cat/test_image_png_5.png +0 -0
  174. package/src/tests/data/hierarchical/cat/test_image_png_78.png +0 -0
  175. package/src/tests/data/hierarchical/cat/test_image_png_93.png +0 -0
  176. package/src/tests/data/hierarchical/deer/Screenshot from 2023-10-12 16-34-51.png +0 -0
  177. package/src/tests/data/hierarchical/deer/Screenshot from 2023-10-12 16-34-57.png +0 -0
  178. package/src/tests/data/hierarchical/deer/Screenshot from 2023-10-12 16-35-03.png +0 -0
  179. package/src/tests/data/hierarchical/deer/test_image_png_17.png +0 -0
  180. package/src/tests/data/hierarchical/deer/test_image_png_52.png +0 -0
  181. package/src/tests/data/hierarchical/deer/test_image_png_70.png +0 -0
  182. package/src/tests/data/hierarchical/dog/test_image_png_16.png +0 -0
  183. package/src/tests/data/hierarchical/dog/test_image_png_27.png +0 -0
  184. package/src/tests/data/hierarchical/dog/test_image_png_28.png +0 -0
  185. package/src/tests/data/hierarchical/dog/test_image_png_40.png +0 -0
  186. package/src/tests/data/hierarchical/dog/test_image_png_51.png +0 -0
  187. package/src/tests/data/hierarchical/dog/test_image_png_79.png +0 -0
  188. package/src/tests/data/hierarchical/dog/test_image_png_90.png +0 -0
  189. package/src/tests/data/hierarchical/dog/test_image_png_95.png +0 -0
  190. package/src/tests/data/hierarchical/horse/Screenshot from 2023-10-12 16-35-31.png +0 -0
  191. package/src/tests/data/hierarchical/horse/Screenshot from 2023-10-12 16-35-37.png +0 -0
  192. package/src/tests/data/hierarchical/horse/Screenshot from 2023-10-12 16-35-48.png +0 -0
  193. package/src/tests/data/hierarchical/horse/test_image_png_20.png +0 -0
  194. package/src/tests/data/hierarchical/horse/test_image_png_26.png +0 -0
  195. package/src/tests/data/hierarchical/horse/test_image_png_32.png +0 -0
  196. package/src/tests/data/hierarchical/horse/test_image_png_44.png +0 -0
  197. package/src/tests/data/hierarchical/horse/test_image_png_94.png +0 -0
  198. package/src/tests/data/hierarchical/plane/01.05.jpeg +0 -0
  199. package/src/tests/data/hierarchical/plane/01.06.jpeg +0 -0
  200. package/src/tests/data/hierarchical/plane/01.07.jpeg +0 -0
  201. package/src/tests/data/hierarchical/plane/test_image_png_4.png +0 -0
  202. package/src/tests/data/hierarchical/plane/test_image_png_61.png +0 -0
  203. package/src/tests/data/hierarchical/plane/test_image_png_69.png +0 -0
  204. package/src/tests/data/hierarchical/plane/test_image_png_82.png +0 -0
  205. package/src/tests/data/hierarchical/plane/test_image_png_85.png +0 -0
  206. package/src/tests/data/hierarchical/train/01.01.jpeg +0 -0
  207. package/src/tests/data/hierarchical/train/01.08.jpeg +0 -0
  208. package/src/tests/data/hierarchical/train/01.09.jpeg +0 -0
  209. package/src/tests/data/hierarchical/train/Screenshot from 2023-10-12 16-36-19.png +0 -0
  210. package/src/tests/data/hierarchical/train/Screenshot from 2023-10-12 16-36-27.png +0 -0
  211. package/src/tests/data/hierarchical/train/Screenshot from 2023-10-12 16-36-43.png +0 -0
  212. package/src/tests/lodash.unit.test.ts +0 -43
  213. package/src/tests/mocked.unit.test.ts +0 -378
  214. package/src/tests/utils.ts +0 -145
  215. package/src/utils/input.ts +0 -58
  216. package/src/utils/inputOutput.ts +0 -29
  217. package/src/utils/output.ts +0 -86
  218. package/tsconfig.cjs.json +0 -33
  219. package/tsconfig.json +0 -34
  220. package/tsconfig.tsbuildinfo +0 -1
  221. package/tsconfig.types.json +0 -9
@@ -1,378 +0,0 @@
1
- import fs from "node:fs";
2
- import os from "node:os";
3
- import path from "node:path";
4
- // Copyright 2021-2026 Prosopo (UK) Ltd.
5
- //
6
- // Licensed under the Apache License, Version 2.0 (the "License");
7
- // you may not use this file except in compliance with the License.
8
- // You may obtain a copy of the License at
9
- //
10
- // http://www.apache.org/licenses/LICENSE-2.0
11
- //
12
- // Unless required by applicable law or agreed to in writing, software
13
- // distributed under the License is distributed on an "AS IS" BASIS,
14
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- // See the License for the specific language governing permissions and
16
- // limitations under the License.
17
- import { CaptchasContainerSchema, DataSchema } from "@prosopo/types";
18
- import { hexHash } from "@prosopo/util-crypto";
19
- import sharp from "sharp";
20
- import { afterAll, beforeAll, describe, expect, test } from "vitest";
21
- import { Flatten } from "../commands/flatten.js";
22
- import { GenerateV1 } from "../commands/generateV1.js";
23
- import { GenerateV2 } from "../commands/generateV2.js";
24
- import { Labels } from "../commands/labels.js";
25
- import { Relocate } from "../commands/relocate.js";
26
- import { Resize } from "../commands/resize.js";
27
- import {
28
- REPO_DIR,
29
- REPO_PLACEHOLDER,
30
- captchasEqFs,
31
- fsEq,
32
- fsWalk,
33
- readJson,
34
- substituteRepoDir,
35
- } from "./utils.js";
36
-
37
- const IMAGE_PROCESSING_TIMEOUT_MS = 120_000;
38
-
39
- describe("dataset commands", () => {
40
- const fixturesDir = `${__dirname}/data`;
41
- // Where the fixtures' `${repo}` placeholder resolves to, i.e. how a
42
- // command's output paths must read to match the checked-in fixture.
43
- const fixturePathInRepo = (fixture: string): string =>
44
- path.relative(REPO_DIR, `${fixturesDir}/${fixture}`);
45
- let tmpDir: string;
46
- let testResultsDir: string;
47
- let resolvedFixturesDir: string;
48
-
49
- const resolvedFixture = (fixture: string): string =>
50
- substituteRepoDir(
51
- `${fixturesDir}/${fixture}`,
52
- `${resolvedFixturesDir}/${fixture}`,
53
- );
54
-
55
- // The command wrote absolute paths under `outputDir`; the fixture holds the
56
- // same files under `${repo}/<fixture dir>`.
57
- const expectDataJsonMatchesFixture = (
58
- outputDir: string,
59
- fixture: string,
60
- ): void => {
61
- const actual = readJson(`${outputDir}/data.json`, [
62
- fs.realpathSync(outputDir),
63
- `${REPO_PLACEHOLDER}/${fixturePathInRepo(path.dirname(fixture))}`,
64
- ]);
65
- expect(actual).toEqual(readJson(`${fixturesDir}/${fixture}`));
66
- };
67
-
68
- beforeAll(() => {
69
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "datasets-fs-test-"));
70
- testResultsDir = `${tmpDir}/results`;
71
- resolvedFixturesDir = `${tmpDir}/fixtures`;
72
- fs.mkdirSync(testResultsDir, { recursive: true });
73
- });
74
-
75
- afterAll(() => {
76
- fs.rmSync(tmpDir, { recursive: true, force: true });
77
- });
78
-
79
- test("labels", async () => {
80
- const input = resolvedFixture("flat_resized/data.json");
81
- const output = `${testResultsDir}/labels.json`;
82
- const labels = new Labels();
83
- labels.logger.setLogLevel("error");
84
- await labels.exec({
85
- input,
86
- output,
87
- });
88
- expect(readJson(output)).toEqual(
89
- readJson(`${fixturesDir}/flat_resized/labels.json`),
90
- );
91
-
92
- // make sure there's one class per hierarchical directory
93
- const content = fs.readFileSync(output).toString();
94
- const labelsJson = JSON.parse(content.toString());
95
- const foundLabels = labelsJson.labels as string[];
96
- const categories = fs.readdirSync(`${fixturesDir}/hierarchical`);
97
- if (JSON.stringify(foundLabels) !== JSON.stringify(categories)) {
98
- throw new Error(`expected ${categories} but found ${foundLabels}`);
99
- }
100
- });
101
-
102
- test(
103
- "generate v2",
104
- async () => {
105
- const input = resolvedFixture("flat_resized/data.json");
106
- const output = `${testResultsDir}/captchas_v2.json`;
107
- const minIncorrect = 1;
108
- const minCorrect = 1;
109
- const minLabelled = 2;
110
- const maxLabelled = 7;
111
- const generate = new GenerateV2();
112
- generate.logger.setLogLevel("error");
113
- await generate.exec({
114
- labelled: input,
115
- unlabelled: input,
116
- overwrite: true,
117
- output,
118
- count: 100,
119
- seed: 0,
120
- minIncorrect,
121
- minCorrect,
122
- minLabelled,
123
- maxLabelled,
124
- allowDuplicates: true,
125
- });
126
- // make sure the results are the same as the expected results
127
- if (
128
- !captchasEqFs(output, resolvedFixture("flat_resized/captchas_v2.json"))
129
- ) {
130
- throw new Error("captchas not equal");
131
- }
132
-
133
- // test that the solutions array and unlabelled array per captcha never conflict
134
- const content = fs.readFileSync(output).toString();
135
- const captchasJson = JSON.parse(content.toString());
136
- const captchas = CaptchasContainerSchema.parse(captchasJson);
137
- for (const captcha of captchas.captchas) {
138
- const solutions = captcha.solution;
139
- const unlabelled = captcha.unlabelled;
140
- // both should not be undefined
141
- if (solutions === undefined || unlabelled === undefined) {
142
- console.log(captcha);
143
- throw new Error("solutions or unlabelled array is undefined");
144
- }
145
- for (const solution of solutions) {
146
- // solution should not be in unlabelled
147
- if (unlabelled.includes(solution)) {
148
- throw new Error(`solution ${solution} is also in unlabelled array`);
149
- }
150
- }
151
- // check the correct, incorrect, labelled and unlabelled distribution
152
- const nCorrect = solutions.length;
153
- const nUnlabelled = unlabelled.length;
154
- const nIncorrect = 9 - nCorrect - nUnlabelled;
155
- const nLabelled = nCorrect + nIncorrect;
156
- if (nCorrect < minCorrect) {
157
- throw new Error(
158
- `expected at least ${minCorrect} correct but found ${nCorrect}`,
159
- );
160
- }
161
- if (nIncorrect < minIncorrect) {
162
- throw new Error(
163
- `expected at least ${minIncorrect} incorrect but found ${nIncorrect}`,
164
- );
165
- }
166
- if (nLabelled < minLabelled) {
167
- throw new Error(
168
- `expected at least ${minLabelled} labelled but found ${nLabelled}`,
169
- );
170
- }
171
- if (nLabelled > maxLabelled) {
172
- throw new Error(
173
- `expected at most ${maxLabelled} labelled but found ${nLabelled}`,
174
- );
175
- }
176
- if (nUnlabelled !== 9 - nLabelled) {
177
- throw new Error(
178
- `expected ${9 - nLabelled} unlabelled but found ${nUnlabelled}`,
179
- );
180
- }
181
- }
182
- },
183
- IMAGE_PROCESSING_TIMEOUT_MS,
184
- );
185
-
186
- test("generate v1", async () => {
187
- const input = resolvedFixture("flat_resized/data.json");
188
- const output = `${testResultsDir}/captchas_v1.json`;
189
- const generate = new GenerateV1();
190
- generate.logger.setLogLevel("error");
191
- await generate.exec({
192
- labelled: input,
193
- unlabelled: input,
194
- overwrite: true,
195
- output,
196
- solved: 50,
197
- unsolved: 50,
198
- seed: 0,
199
- minCorrect: 1,
200
- maxCorrect: 6,
201
- allowDuplicates: true,
202
- });
203
- // make sure the results are the same as the expected results
204
- if (
205
- !captchasEqFs(output, resolvedFixture("flat_resized/captchas_v1.json"))
206
- ) {
207
- throw new Error("captchas not equal");
208
- }
209
- });
210
-
211
- test(
212
- "resizes data",
213
- async () => {
214
- const input = resolvedFixture("flat/data.json");
215
- const output = `${testResultsDir}/flat_resized`;
216
- const resize = new Resize();
217
- resize.logger.setLogLevel("error");
218
- await resize.exec({
219
- input,
220
- output,
221
- overwrite: true,
222
- square: true,
223
- size: 128,
224
- });
225
-
226
- expect(
227
- fsEq(`${output}/images`, `${fixturesDir}/flat_resized/images`),
228
- ).toBe(true);
229
- expectDataJsonMatchesFixture(output, "flat_resized/data.json");
230
-
231
- // check data in resized dir is all 128x128
232
- for (const pth of fsWalk(output)) {
233
- // if pth is not img, ignore
234
- if (
235
- !pth.endsWith(".jpg") &&
236
- !pth.endsWith(".jpeg") &&
237
- !pth.endsWith(".png")
238
- ) {
239
- continue;
240
- }
241
- const image = sharp(pth);
242
- const metadata = await image.metadata();
243
- if (metadata.width !== 128 || metadata.height !== 128) {
244
- throw new Error(`image ${pth} is not 128x128`);
245
- }
246
- }
247
- },
248
- IMAGE_PROCESSING_TIMEOUT_MS,
249
- );
250
-
251
- test("relocates data", async () => {
252
- const input = `${fixturesDir}/flat_resized/data.json`;
253
- const output = `${testResultsDir}/relocated_data.json`;
254
- const relocate = new Relocate();
255
- relocate.logger.setLogLevel("error");
256
- await relocate.exec({
257
- input,
258
- output,
259
- overwrite: true,
260
- to: "newwebsite.com",
261
- from: REPO_PLACEHOLDER,
262
- });
263
-
264
- expect(readJson(output)).toEqual(
265
- readJson(`${fixturesDir}/flat_resized/relocated_data.json`),
266
- );
267
- });
268
-
269
- test(
270
- "flattens hierarchical data",
271
- async () => {
272
- const input = `${fixturesDir}/hierarchical`;
273
- const output = `${testResultsDir}/flat`;
274
- const flatten = new Flatten();
275
- flatten.logger.setLogLevel("error");
276
- await flatten.exec({
277
- input,
278
- output,
279
- overwrite: true,
280
- });
281
-
282
- expect(fsEq(`${output}/images`, `${fixturesDir}/flat/images`)).toBe(true);
283
- expectDataJsonMatchesFixture(output, "flat/data.json");
284
-
285
- // read data json
286
- const content = fs.readFileSync(`${output}/data.json`).toString();
287
- const dataJson = JSON.parse(content.toString());
288
- const data = DataSchema.parse(dataJson);
289
-
290
- // check each image from the hierarchical data is in the flat data
291
- let hierCount = 0;
292
- for (const pth of fsWalk(input)) {
293
- // if pth is not img, ignore
294
- if (
295
- !pth.endsWith(".jpg") &&
296
- !pth.endsWith(".jpeg") &&
297
- !pth.endsWith(".png")
298
- ) {
299
- continue;
300
- }
301
- hierCount++;
302
- // get the category
303
- const category = pth.split("/").slice(-2)[0];
304
- const content = fs.readFileSync(pth);
305
- // check the image is in the flat data
306
- let name = "";
307
- for (const pth2 of fsWalk(output)) {
308
- // if pth2 is not file, ignore
309
- if (!fs.statSync(pth2).isFile()) {
310
- continue;
311
- }
312
- const content2 = fs.readFileSync(pth2);
313
- if (content.equals(content2)) {
314
- const str = pth2.split("/").slice(-1)[0];
315
- if (str === undefined) {
316
- throw new Error(`unable to parse ${pth2}`);
317
- }
318
- name = str;
319
- break;
320
- }
321
- }
322
-
323
- if (!name) {
324
- throw new Error(`unable to find image ${pth} in output`);
325
- }
326
- // check the image is in the data json
327
- const item = data.items.find((item) => {
328
- const name2 = item.data.split("/").slice(-1)[0];
329
- if (name2 !== name) {
330
- return false;
331
- }
332
- return true;
333
- });
334
- if (item === undefined) {
335
- throw new Error(`unable to find image ${pth} in data.json`);
336
- }
337
- // correct name, so check category
338
- if (item.label !== category) {
339
- throw new Error(`expected ${category} but found ${item.label}`);
340
- }
341
- // type should be image
342
- if (item.type !== "image") {
343
- throw new Error(`expected image type but found ${item.type}`);
344
- }
345
- // file name should be the hash
346
- if (item.hash !== name.split(".")[0]) {
347
- throw new Error(
348
- `expected ${name.split(".")[0]} hash but found ${item.hash}`,
349
- );
350
- }
351
- // hash should be the hash of the image content
352
- const hash = hexHash(content);
353
- if (item.hash !== hash) {
354
- throw new Error(`expected ${hash} hash but found ${item.hash}`);
355
- }
356
- }
357
-
358
- // count the number of images in the flat data
359
- let flatCount = 0;
360
- for (const pth of fsWalk(output)) {
361
- if (
362
- !pth.endsWith(".jpg") &&
363
- !pth.endsWith(".jpeg") &&
364
- !pth.endsWith(".png")
365
- ) {
366
- continue;
367
- }
368
- flatCount++;
369
- }
370
-
371
- // check same number of images in flat data
372
- if (hierCount !== flatCount) {
373
- throw new Error(`expected ${hierCount} images but found ${flatCount}`);
374
- }
375
- },
376
- IMAGE_PROCESSING_TIMEOUT_MS,
377
- );
378
- });
@@ -1,145 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- // Copyright 2021-2026 Prosopo (UK) Ltd.
4
- //
5
- // Licensed under the Apache License, Version 2.0 (the "License");
6
- // you may not use this file except in compliance with the License.
7
- // You may obtain a copy of the License at
8
- //
9
- // http://www.apache.org/licenses/LICENSE-2.0
10
- //
11
- // Unless required by applicable law or agreed to in writing, software
12
- // distributed under the License is distributed on an "AS IS" BASIS,
13
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- // See the License for the specific language governing permissions and
15
- // limitations under the License.
16
- import {
17
- type CaptchasContainer,
18
- CaptchasContainerSchema,
19
- DataSchema,
20
- } from "@prosopo/types";
21
- import { at } from "@prosopo/util";
22
-
23
- // recursively list files in a directory
24
- export function* fsWalk(
25
- pth: string,
26
- options?: {
27
- filesFirst?: boolean; // if true, depth first (i.e. yield files inside a dir before the dir itself, recursively), else yield in encounter order (i.e. dir first, then files inside, recursively)
28
- },
29
- ): Generator<string> {
30
- // if path is a directory, recurse
31
- const isDir = fs.existsSync(pth) && fs.statSync(pth).isDirectory();
32
- let subpaths = isDir ? fs.readdirSync(pth) : [];
33
- subpaths = subpaths.map((f) => `${pth}/${f}`);
34
- if (!options?.filesFirst) {
35
- yield pth;
36
- }
37
- for (const subpath of subpaths) {
38
- yield* fsWalk(subpath, options);
39
- }
40
- if (options?.filesFirst) {
41
- yield pth;
42
- }
43
- }
44
-
45
- // test whether two files/dirs are equal, recursively comparing contents as required
46
- export const fsEq = (pth1: string, pth2: string) => {
47
- const it1 = fsWalk(pth1);
48
- const it2 = fsWalk(pth2);
49
- // drop the root path
50
- const files1 = [...it1].map((f) => f.slice(pth1.length));
51
- const files2 = [...it2].map((f) => f.slice(pth2.length));
52
- if (files1.length !== files2.length) {
53
- return false;
54
- }
55
- // sort files so in same order
56
- files1.sort();
57
- files2.sort();
58
- if (!files1.every((f, i) => f === files2[i])) {
59
- // the two lists of files are not the same
60
- return false;
61
- }
62
- // compare contents of each file
63
- for (let i = 0; i < files1.length; i++) {
64
- const file1 = pth1 + at(files1, i);
65
- const file2 = pth2 + at(files2, i);
66
- const stat1 = fs.statSync(file1);
67
- if (stat1.isDirectory()) {
68
- // already checked above
69
- continue;
70
- }
71
- // files, so compare contents
72
- const content1 = fs.readFileSync(file1);
73
- const content2 = fs.readFileSync(file2);
74
- if (!content1.equals(content2)) {
75
- return false;
76
- }
77
- }
78
- return true;
79
- };
80
-
81
- export const readDataJson = (pth: string) => {
82
- let content = fs.readFileSync(pth).toString();
83
- content = content.replaceAll(REPO_PLACEHOLDER, REPO_DIR);
84
- const dataJson = JSON.parse(content.toString());
85
- const data = DataSchema.parse(dataJson);
86
- return data;
87
- };
88
-
89
- export const readCaptchasJson = (pth: string) => {
90
- const content = fs.readFileSync(pth).toString();
91
- const dataJson = JSON.parse(content);
92
- const captchas = CaptchasContainerSchema.parse(dataJson);
93
- return captchas;
94
- };
95
-
96
- export const captchasEqFs = (pth1: string, pth2: string) => {
97
- const data1 = readCaptchasJson(pth1);
98
- const data2 = readCaptchasJson(pth2);
99
- return captchasEq(data1, data2);
100
- };
101
-
102
- export const captchasEq = (
103
- first: CaptchasContainer,
104
- second: CaptchasContainer,
105
- ) => {
106
- if (first.captchas.length !== second.captchas.length) {
107
- return false;
108
- }
109
- for (let i = 0; i < first.captchas.length; i++) {
110
- const captcha1 = at(first.captchas, i);
111
- const captcha2 = at(second.captchas, i);
112
- // salts should not be the same as generated on the fly and not stored!
113
- if (captcha1.salt === captcha2.salt) {
114
- return false;
115
- }
116
- // everything else should be the same
117
- const { salt: salt1, ...rest1 } = captcha1;
118
- const { salt: salt2, ...rest2 } = captcha2;
119
- if (JSON.stringify(rest1) !== JSON.stringify(rest2)) {
120
- return false;
121
- }
122
- }
123
- return true;
124
- };
125
-
126
- export const REPO_PLACEHOLDER = "${repo}";
127
- // TODO use getPaths() here to find the repo dir
128
- export const REPO_DIR = path.resolve(__dirname, "../../../..");
129
-
130
- // Fixture JSON refers to images as `${repo}/...`. Writes a copy of the fixture
131
- // with the placeholder resolved, leaving the checked-in file untouched.
132
- export const substituteRepoDir = (fixture: string, dest: string): string => {
133
- const content = fs.readFileSync(fixture).toString();
134
- fs.mkdirSync(path.dirname(dest), { recursive: true });
135
- fs.writeFileSync(dest, content.replaceAll(REPO_PLACEHOLDER, REPO_DIR));
136
- return dest;
137
- };
138
-
139
- export const readJson = (pth: string, replace?: [string, string]): unknown => {
140
- let content = fs.readFileSync(pth).toString();
141
- if (replace) {
142
- content = content.replaceAll(replace[0], replace[1]);
143
- }
144
- return JSON.parse(content);
145
- };
@@ -1,58 +0,0 @@
1
- import fs from "node:fs";
2
- import { ProsopoDatasetError, ProsopoError } from "@prosopo/common";
3
- // Copyright 2021-2026 Prosopo (UK) Ltd.
4
- //
5
- // Licensed under the Apache License, Version 2.0 (the "License");
6
- // you may not use this file except in compliance with the License.
7
- // You may obtain a copy of the License at
8
- //
9
- // http://www.apache.org/licenses/LICENSE-2.0
10
- //
11
- // Unless required by applicable law or agreed to in writing, software
12
- // distributed under the License is distributed on an "AS IS" BASIS,
13
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- // See the License for the specific language governing permissions and
15
- // limitations under the License.
16
- import * as z from "zod";
17
- import { CliCommand } from "../cli/cliCommand.js";
18
-
19
- export const InputArgsSchema = z.object({
20
- input: z.string(),
21
- });
22
-
23
- export type InputArgs = z.infer<typeof InputArgsSchema>;
24
-
25
- export class InputCliCommand<
26
- T extends typeof InputArgsSchema,
27
- > extends CliCommand<T> {
28
- public override getArgSchema(): T {
29
- throw new ProsopoError("DEVELOPER.METHOD_NOT_IMPLEMENTED");
30
- }
31
- public override getDescription(): string {
32
- throw new ProsopoError("DEVELOPER.METHOD_NOT_IMPLEMENTED");
33
- }
34
- public override getOptions() {
35
- return {
36
- input: {
37
- string: true,
38
- alias: "in",
39
- demand: true,
40
- description: "The input path",
41
- },
42
- };
43
- }
44
-
45
- public override async _check(args: InputArgs) {
46
- this.logger.debug(() => ({ msg: "input _check" }));
47
- await super._check(args);
48
- // input must exist
49
- if (!fs.existsSync(args.input)) {
50
- throw new ProsopoDatasetError(
51
- new Error(`input path does not exist: ${args.input}`),
52
- {
53
- translationKey: "FS.FILE_NOT_FOUND",
54
- },
55
- );
56
- }
57
- }
58
- }
@@ -1,29 +0,0 @@
1
- // Copyright 2021-2026 Prosopo (UK) Ltd.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
- import type * as z from "zod";
15
- import { CliCommandComposite } from "../cli/cliCommandComposite.js";
16
- import { InputArgsSchema, InputCliCommand } from "./input.js";
17
- import { OutputArgsSchema, OutputCliCommand } from "./output.js";
18
-
19
- export const InputOutputArgsSchema = InputArgsSchema.merge(OutputArgsSchema);
20
-
21
- export type InputOutputArgs = z.infer<typeof InputOutputArgsSchema>;
22
-
23
- export abstract class InputOutputCliCommand<
24
- T extends typeof InputOutputArgsSchema,
25
- > extends CliCommandComposite<T> {
26
- constructor() {
27
- super([new InputCliCommand<T>(), new OutputCliCommand<T>()]);
28
- }
29
- }
@@ -1,86 +0,0 @@
1
- import fs from "node:fs";
2
- import { ProsopoEnvError, ProsopoError } from "@prosopo/common";
3
- import { lodash } from "@prosopo/util/lodash";
4
- import { boolean, object, string, type infer as zInfer } from "zod";
5
- // Copyright 2021-2026 Prosopo (UK) Ltd.
6
- //
7
- // Licensed under the Apache License, Version 2.0 (the "License");
8
- // you may not use this file except in compliance with the License.
9
- // You may obtain a copy of the License at
10
- //
11
- // http://www.apache.org/licenses/LICENSE-2.0
12
- //
13
- // Unless required by applicable law or agreed to in writing, software
14
- // distributed under the License is distributed on an "AS IS" BASIS,
15
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- // See the License for the specific language governing permissions and
17
- // limitations under the License.
18
- import { CliCommand } from "../cli/cliCommand.js";
19
-
20
- export const OutputArgsSchema = object({
21
- output: string(),
22
- overwrite: boolean().optional(),
23
- });
24
-
25
- export type OutputArgs = zInfer<typeof OutputArgsSchema>;
26
-
27
- export class OutputCliCommand<
28
- T extends typeof OutputArgsSchema,
29
- > extends CliCommand<T> {
30
- #outputExists = false;
31
-
32
- public outputExists() {
33
- return this.#outputExists;
34
- }
35
-
36
- public override getArgSchema(): T {
37
- throw new ProsopoError("DEVELOPER.METHOD_NOT_IMPLEMENTED");
38
- }
39
- public override getDescription(): string {
40
- throw new ProsopoError("DEVELOPER.METHOD_NOT_IMPLEMENTED");
41
- }
42
- public override getOptions() {
43
- return lodash().merge(super.getOptions(), {
44
- output: {
45
- alias: "out",
46
- string: true,
47
- demand: true,
48
- description: "The output path",
49
- },
50
- overwrite: {
51
- boolean: true,
52
- description: "Overwrite files in the output path if they already exist",
53
- },
54
- });
55
- }
56
-
57
- public override async _check(args: OutputArgs) {
58
- this.logger.debug(() => ({ msg: "Output _check" }));
59
- await super._check(args);
60
-
61
- // record whether output already exists
62
- this.#outputExists = fs.existsSync(args.output);
63
-
64
- // output must not exist, unless overwrite is true
65
- if (this.outputExists()) {
66
- if (!args.overwrite) {
67
- throw new ProsopoEnvError(
68
- new Error(`output path already exists: ${args.output}`),
69
- {
70
- translationKey: "FS.FILE_ALREADY_EXISTS",
71
- },
72
- );
73
- }
74
- }
75
- }
76
-
77
- public override async _run(args: OutputArgs) {
78
- this.logger.debug(() => ({ msg: "Output run" }));
79
- await super._run(args);
80
- if (args.overwrite && this.outputExists()) {
81
- // if overwrite is true, delete the output directory
82
- this.logger.info(() => ({ msg: "cleaning output directory..." }));
83
- fs.rmSync(args.output, { recursive: true });
84
- }
85
- }
86
- }