@xylabs/aries 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +693 -0
- package/dist/actions/audit/auditPaths.mjs +22 -0
- package/dist/actions/audit/auditPaths.mjs.map +1 -0
- package/dist/actions/audit/index.mjs +739 -0
- package/dist/actions/audit/index.mjs.map +1 -0
- package/dist/actions/audit/installPlugin.mjs +298 -0
- package/dist/actions/audit/installPlugin.mjs.map +1 -0
- package/dist/actions/audit/listSessions.mjs +93 -0
- package/dist/actions/audit/listSessions.mjs.map +1 -0
- package/dist/actions/audit/openAuditDir.mjs +44 -0
- package/dist/actions/audit/openAuditDir.mjs.map +1 -0
- package/dist/actions/audit/searchAudit.mjs +77 -0
- package/dist/actions/audit/searchAudit.mjs.map +1 -0
- package/dist/actions/audit/showAiMeta.mjs +105 -0
- package/dist/actions/audit/showAiMeta.mjs.map +1 -0
- package/dist/actions/audit/showSession.mjs +105 -0
- package/dist/actions/audit/showSession.mjs.map +1 -0
- package/dist/actions/audit/statusAudit.mjs +98 -0
- package/dist/actions/audit/statusAudit.mjs.map +1 -0
- package/dist/actions/clamp/clampAudit.mjs +53 -0
- package/dist/actions/clamp/clampAudit.mjs.map +1 -0
- package/dist/actions/clamp/index.mjs +2258 -0
- package/dist/actions/clamp/index.mjs.map +1 -0
- package/dist/actions/clamp/ipcServer.mjs +55 -0
- package/dist/actions/clamp/ipcServer.mjs.map +1 -0
- package/dist/actions/clamp/policyManagement.mjs +144 -0
- package/dist/actions/clamp/policyManagement.mjs.map +1 -0
- package/dist/actions/clamp/promptUser.mjs +91 -0
- package/dist/actions/clamp/promptUser.mjs.map +1 -0
- package/dist/actions/clamp/runClamped.mjs +2107 -0
- package/dist/actions/clamp/runClamped.mjs.map +1 -0
- package/dist/actions/clamp/sandboxExec.mjs +1612 -0
- package/dist/actions/clamp/sandboxExec.mjs.map +1 -0
- package/dist/actions/clamp/shellEnvSetup.mjs +59 -0
- package/dist/actions/clamp/shellEnvSetup.mjs.map +1 -0
- package/dist/actions/clamp/shimGenerator.mjs +68 -0
- package/dist/actions/clamp/shimGenerator.mjs.map +1 -0
- package/dist/actions/clamp/terminalRenderer.mjs +145 -0
- package/dist/actions/clamp/terminalRenderer.mjs.map +1 -0
- package/dist/actions/datalake/audit/auditLog.mjs +191 -0
- package/dist/actions/datalake/audit/auditLog.mjs.map +1 -0
- package/dist/actions/datalake/createDatalake.mjs +127 -0
- package/dist/actions/datalake/createDatalake.mjs.map +1 -0
- package/dist/actions/datalake/describeDatalake.mjs +159 -0
- package/dist/actions/datalake/describeDatalake.mjs.map +1 -0
- package/dist/actions/datalake/destroyDatalake.mjs +34 -0
- package/dist/actions/datalake/destroyDatalake.mjs.map +1 -0
- package/dist/actions/datalake/dev/downDevServer.mjs +102 -0
- package/dist/actions/datalake/dev/downDevServer.mjs.map +1 -0
- package/dist/actions/datalake/dev/index.mjs +369 -0
- package/dist/actions/datalake/dev/index.mjs.map +1 -0
- package/dist/actions/datalake/dev/logsDevServer.mjs +44 -0
- package/dist/actions/datalake/dev/logsDevServer.mjs.map +1 -0
- package/dist/actions/datalake/dev/paths.mjs +25 -0
- package/dist/actions/datalake/dev/paths.mjs.map +1 -0
- package/dist/actions/datalake/dev/resetDevServer.mjs +118 -0
- package/dist/actions/datalake/dev/resetDevServer.mjs.map +1 -0
- package/dist/actions/datalake/dev/resolveServerBin.mjs +26 -0
- package/dist/actions/datalake/dev/resolveServerBin.mjs.map +1 -0
- package/dist/actions/datalake/dev/state.mjs +62 -0
- package/dist/actions/datalake/dev/state.mjs.map +1 -0
- package/dist/actions/datalake/dev/statusDevServer.mjs +101 -0
- package/dist/actions/datalake/dev/statusDevServer.mjs.map +1 -0
- package/dist/actions/datalake/dev/upDevServer.mjs +221 -0
- package/dist/actions/datalake/dev/upDevServer.mjs.map +1 -0
- package/dist/actions/datalake/dev/waitForHealth.mjs +22 -0
- package/dist/actions/datalake/dev/waitForHealth.mjs.map +1 -0
- package/dist/actions/datalake/formatters.mjs +90 -0
- package/dist/actions/datalake/formatters.mjs.map +1 -0
- package/dist/actions/datalake/grantAccess.mjs +116 -0
- package/dist/actions/datalake/grantAccess.mjs.map +1 -0
- package/dist/actions/datalake/index.mjs +361 -0
- package/dist/actions/datalake/index.mjs.map +1 -0
- package/dist/actions/datalake/listDatalakes.mjs +54 -0
- package/dist/actions/datalake/listDatalakes.mjs.map +1 -0
- package/dist/actions/datalake/login.mjs +20 -0
- package/dist/actions/datalake/login.mjs.map +1 -0
- package/dist/actions/datalake/logout.mjs +11 -0
- package/dist/actions/datalake/logout.mjs.map +1 -0
- package/dist/actions/datalake/mintToken.mjs +37 -0
- package/dist/actions/datalake/mintToken.mjs.map +1 -0
- package/dist/actions/datalake/parseSize.mjs +21 -0
- package/dist/actions/datalake/parseSize.mjs.map +1 -0
- package/dist/actions/datalake/payloads/fetchPayload.mjs +76 -0
- package/dist/actions/datalake/payloads/fetchPayload.mjs.map +1 -0
- package/dist/actions/datalake/payloads/index.mjs +271 -0
- package/dist/actions/datalake/payloads/index.mjs.map +1 -0
- package/dist/actions/datalake/payloads/mintAndConnect.mjs +46 -0
- package/dist/actions/datalake/payloads/mintAndConnect.mjs.map +1 -0
- package/dist/actions/datalake/payloads/parsePayloadsFile.mjs +71 -0
- package/dist/actions/datalake/payloads/parsePayloadsFile.mjs.map +1 -0
- package/dist/actions/datalake/payloads/pushPayloads.mjs +181 -0
- package/dist/actions/datalake/payloads/pushPayloads.mjs.map +1 -0
- package/dist/actions/datalake/payloads/tailPayloads.mjs +106 -0
- package/dist/actions/datalake/payloads/tailPayloads.mjs.map +1 -0
- package/dist/actions/datalake/resolveTarget.mjs +15 -0
- package/dist/actions/datalake/resolveTarget.mjs.map +1 -0
- package/dist/actions/datalake/revokeAccess.mjs +108 -0
- package/dist/actions/datalake/revokeAccess.mjs.map +1 -0
- package/dist/actions/datalake/useDatalake.mjs +22 -0
- package/dist/actions/datalake/useDatalake.mjs.map +1 -0
- package/dist/actions/detect/detectAiClients.mjs +405 -0
- package/dist/actions/detect/detectAiClients.mjs.map +1 -0
- package/dist/actions/detect/index.mjs +405 -0
- package/dist/actions/detect/index.mjs.map +1 -0
- package/dist/actions/hash/algorithms/blockhash.mjs +61 -0
- package/dist/actions/hash/algorithms/blockhash.mjs.map +1 -0
- package/dist/actions/hash/algorithms/chromaprint.mjs +205 -0
- package/dist/actions/hash/algorithms/chromaprint.mjs.map +1 -0
- package/dist/actions/hash/algorithms/dhash.mjs +75 -0
- package/dist/actions/hash/algorithms/dhash.mjs.map +1 -0
- package/dist/actions/hash/algorithms/index.mjs +818 -0
- package/dist/actions/hash/algorithms/index.mjs.map +1 -0
- package/dist/actions/hash/algorithms/nilsimsa.mjs +27 -0
- package/dist/actions/hash/algorithms/nilsimsa.mjs.map +1 -0
- package/dist/actions/hash/algorithms/pdq.mjs +83 -0
- package/dist/actions/hash/algorithms/pdq.mjs.map +1 -0
- package/dist/actions/hash/algorithms/phash.mjs +71 -0
- package/dist/actions/hash/algorithms/phash.mjs.map +1 -0
- package/dist/actions/hash/algorithms/sha256.mjs +24 -0
- package/dist/actions/hash/algorithms/sha256.mjs.map +1 -0
- package/dist/actions/hash/algorithms/ssdeep.mjs +203 -0
- package/dist/actions/hash/algorithms/ssdeep.mjs.map +1 -0
- package/dist/actions/hash/algorithms/tlsh.mjs +66 -0
- package/dist/actions/hash/algorithms/tlsh.mjs.map +1 -0
- package/dist/actions/hash/algorithms/types.mjs +1 -0
- package/dist/actions/hash/algorithms/types.mjs.map +1 -0
- package/dist/actions/hash/algorithms/videoFrames.mjs +404 -0
- package/dist/actions/hash/algorithms/videoFrames.mjs.map +1 -0
- package/dist/actions/hash/algorithms/xyo.mjs +30 -0
- package/dist/actions/hash/algorithms/xyo.mjs.map +1 -0
- package/dist/actions/hash/compareHashes.mjs +823 -0
- package/dist/actions/hash/compareHashes.mjs.map +1 -0
- package/dist/actions/hash/hashInput.mjs +868 -0
- package/dist/actions/hash/hashInput.mjs.map +1 -0
- package/dist/actions/hash/index.mjs +881 -0
- package/dist/actions/hash/index.mjs.map +1 -0
- package/dist/actions/hash/lib/hamming.mjs +44 -0
- package/dist/actions/hash/lib/hamming.mjs.map +1 -0
- package/dist/actions/hash/lib/levenshtein.mjs +36 -0
- package/dist/actions/hash/lib/levenshtein.mjs.map +1 -0
- package/dist/actions/hash/lib/runBinary.mjs +54 -0
- package/dist/actions/hash/lib/runBinary.mjs.map +1 -0
- package/dist/actions/hash/lib/which.mjs +36 -0
- package/dist/actions/hash/lib/which.mjs.map +1 -0
- package/dist/actions/hash/lib/withTempfile.mjs +19 -0
- package/dist/actions/hash/lib/withTempfile.mjs.map +1 -0
- package/dist/actions/index.mjs +4615 -0
- package/dist/actions/index.mjs.map +1 -0
- package/dist/actions/printVersion.mjs +12 -0
- package/dist/actions/printVersion.mjs.map +1 -0
- package/dist/actions/sync/index.mjs +51 -0
- package/dist/actions/sync/index.mjs.map +1 -0
- package/dist/actions/sync/syncAiConfig.mjs +51 -0
- package/dist/actions/sync/syncAiConfig.mjs.map +1 -0
- package/dist/actions/wallet/account/deriveAndAdd.mjs +394 -0
- package/dist/actions/wallet/account/deriveAndAdd.mjs.map +1 -0
- package/dist/actions/wallet/account/getActiveWallet.mjs +338 -0
- package/dist/actions/wallet/account/getActiveWallet.mjs.map +1 -0
- package/dist/actions/wallet/account/labelAccount.mjs +389 -0
- package/dist/actions/wallet/account/labelAccount.mjs.map +1 -0
- package/dist/actions/wallet/account/listAccounts.mjs +374 -0
- package/dist/actions/wallet/account/listAccounts.mjs.map +1 -0
- package/dist/actions/wallet/account/removeAccount.mjs +384 -0
- package/dist/actions/wallet/account/removeAccount.mjs.map +1 -0
- package/dist/actions/wallet/account/showAccount.mjs +368 -0
- package/dist/actions/wallet/account/showAccount.mjs.map +1 -0
- package/dist/actions/wallet/addressBook/storage.mjs +110 -0
- package/dist/actions/wallet/addressBook/storage.mjs.map +1 -0
- package/dist/actions/wallet/backup/exportBackup.mjs +93 -0
- package/dist/actions/wallet/backup/exportBackup.mjs.map +1 -0
- package/dist/actions/wallet/backup/importBackup.mjs +142 -0
- package/dist/actions/wallet/backup/importBackup.mjs.map +1 -0
- package/dist/actions/wallet/balance/getBalance.mjs +434 -0
- package/dist/actions/wallet/balance/getBalance.mjs.map +1 -0
- package/dist/actions/wallet/client/walletClient.mjs +64 -0
- package/dist/actions/wallet/client/walletClient.mjs.map +1 -0
- package/dist/actions/wallet/contact/contactActions.mjs +120 -0
- package/dist/actions/wallet/contact/contactActions.mjs.map +1 -0
- package/dist/actions/wallet/contact/storage.mjs +69 -0
- package/dist/actions/wallet/contact/storage.mjs.map +1 -0
- package/dist/actions/wallet/index.mjs +1439 -0
- package/dist/actions/wallet/index.mjs.map +1 -0
- package/dist/actions/wallet/network/networkActions.mjs +137 -0
- package/dist/actions/wallet/network/networkActions.mjs.map +1 -0
- package/dist/actions/wallet/network/storage.mjs +93 -0
- package/dist/actions/wallet/network/storage.mjs.map +1 -0
- package/dist/actions/wallet/password/changePassword.mjs +282 -0
- package/dist/actions/wallet/password/changePassword.mjs.map +1 -0
- package/dist/actions/wallet/password/getActiveKey.mjs +297 -0
- package/dist/actions/wallet/password/getActiveKey.mjs.map +1 -0
- package/dist/actions/wallet/password/initOrUnlock.mjs +337 -0
- package/dist/actions/wallet/password/initOrUnlock.mjs.map +1 -0
- package/dist/actions/wallet/password/passwordStorage.mjs +69 -0
- package/dist/actions/wallet/password/passwordStorage.mjs.map +1 -0
- package/dist/actions/wallet/password/setPassword.mjs +138 -0
- package/dist/actions/wallet/password/setPassword.mjs.map +1 -0
- package/dist/actions/wallet/password/validatePassword.mjs +123 -0
- package/dist/actions/wallet/password/validatePassword.mjs.map +1 -0
- package/dist/actions/wallet/passwordKey.mjs +87 -0
- package/dist/actions/wallet/passwordKey.mjs.map +1 -0
- package/dist/actions/wallet/paths.mjs +26 -0
- package/dist/actions/wallet/paths.mjs.map +1 -0
- package/dist/actions/wallet/prompt.mjs +93 -0
- package/dist/actions/wallet/prompt.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/createPhrase.mjs +392 -0
- package/dist/actions/wallet/seedPhrase/createPhrase.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/exportPhrase.mjs +334 -0
- package/dist/actions/wallet/seedPhrase/exportPhrase.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/idGen.mjs +11 -0
- package/dist/actions/wallet/seedPhrase/idGen.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/importPhrase.mjs +393 -0
- package/dist/actions/wallet/seedPhrase/importPhrase.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/listPhrases.mjs +62 -0
- package/dist/actions/wallet/seedPhrase/listPhrases.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/phraseStorage.mjs +89 -0
- package/dist/actions/wallet/seedPhrase/phraseStorage.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/removePhrase.mjs +366 -0
- package/dist/actions/wallet/seedPhrase/removePhrase.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/renamePhrase.mjs +78 -0
- package/dist/actions/wallet/seedPhrase/renamePhrase.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/types.mjs +1 -0
- package/dist/actions/wallet/seedPhrase/types.mjs.map +1 -0
- package/dist/actions/wallet/seedPhrase/usePhrase.mjs +83 -0
- package/dist/actions/wallet/seedPhrase/usePhrase.mjs.map +1 -0
- package/dist/actions/wallet/session/machineId.mjs +145 -0
- package/dist/actions/wallet/session/machineId.mjs.map +1 -0
- package/dist/actions/wallet/session/sessionCache.mjs +221 -0
- package/dist/actions/wallet/session/sessionCache.mjs.map +1 -0
- package/dist/actions/wallet/session/unlock.mjs +307 -0
- package/dist/actions/wallet/session/unlock.mjs.map +1 -0
- package/dist/actions/wallet/sign/signPayload.mjs +637 -0
- package/dist/actions/wallet/sign/signPayload.mjs.map +1 -0
- package/dist/actions/wallet/storage.mjs +51 -0
- package/dist/actions/wallet/storage.mjs.map +1 -0
- package/dist/actions/wallet/transaction/broadcastTransaction.mjs +453 -0
- package/dist/actions/wallet/transaction/broadcastTransaction.mjs.map +1 -0
- package/dist/actions/wallet/transaction/sendTransaction.mjs +457 -0
- package/dist/actions/wallet/transaction/sendTransaction.mjs.map +1 -0
- package/dist/actions/wallet/transaction/signTransactionFile.mjs +378 -0
- package/dist/actions/wallet/transaction/signTransactionFile.mjs.map +1 -0
- package/dist/actions/xyo/index.mjs +138 -0
- package/dist/actions/xyo/index.mjs.map +1 -0
- package/dist/actions/xyo/transaction/index.mjs +138 -0
- package/dist/actions/xyo/transaction/index.mjs.map +1 -0
- package/dist/actions/xyo/transaction/validateTransactions.mjs +138 -0
- package/dist/actions/xyo/transaction/validateTransactions.mjs.map +1 -0
- package/dist/aries.mjs +8466 -0
- package/dist/aries.mjs.map +1 -0
- package/dist/bin/aries.mjs +8472 -0
- package/dist/bin/aries.mjs.map +1 -0
- package/dist/commands/aiCommand.mjs +492 -0
- package/dist/commands/aiCommand.mjs.map +1 -0
- package/dist/commands/auditAiCommand.mjs +119 -0
- package/dist/commands/auditAiCommand.mjs.map +1 -0
- package/dist/commands/auditCommand.mjs +857 -0
- package/dist/commands/auditCommand.mjs.map +1 -0
- package/dist/commands/auditInstallCommand.mjs +324 -0
- package/dist/commands/auditInstallCommand.mjs.map +1 -0
- package/dist/commands/auditListCommand.mjs +107 -0
- package/dist/commands/auditListCommand.mjs.map +1 -0
- package/dist/commands/auditOpenCommand.mjs +51 -0
- package/dist/commands/auditOpenCommand.mjs.map +1 -0
- package/dist/commands/auditSearchCommand.mjs +98 -0
- package/dist/commands/auditSearchCommand.mjs.map +1 -0
- package/dist/commands/auditShowCommand.mjs +123 -0
- package/dist/commands/auditShowCommand.mjs.map +1 -0
- package/dist/commands/auditStatusCommand.mjs +105 -0
- package/dist/commands/auditStatusCommand.mjs.map +1 -0
- package/dist/commands/clampCommand.mjs +2328 -0
- package/dist/commands/clampCommand.mjs.map +1 -0
- package/dist/commands/clampPolicyCommand.mjs +184 -0
- package/dist/commands/clampPolicyCommand.mjs.map +1 -0
- package/dist/commands/clampPolicyInitCommand.mjs +63 -0
- package/dist/commands/clampPolicyInitCommand.mjs.map +1 -0
- package/dist/commands/clampPolicyListCommand.mjs +56 -0
- package/dist/commands/clampPolicyListCommand.mjs.map +1 -0
- package/dist/commands/clampPolicyShowCommand.mjs +83 -0
- package/dist/commands/clampPolicyShowCommand.mjs.map +1 -0
- package/dist/commands/clampRunCommand.mjs +2137 -0
- package/dist/commands/clampRunCommand.mjs.map +1 -0
- package/dist/commands/datalakeAuditCommand.mjs +273 -0
- package/dist/commands/datalakeAuditCommand.mjs.map +1 -0
- package/dist/commands/datalakeCommand.mjs +1637 -0
- package/dist/commands/datalakeCommand.mjs.map +1 -0
- package/dist/commands/datalakeCreateCommand.mjs +189 -0
- package/dist/commands/datalakeCreateCommand.mjs.map +1 -0
- package/dist/commands/datalakeDescribeCommand.mjs +172 -0
- package/dist/commands/datalakeDescribeCommand.mjs.map +1 -0
- package/dist/commands/datalakeDestroyCommand.mjs +53 -0
- package/dist/commands/datalakeDestroyCommand.mjs.map +1 -0
- package/dist/commands/datalakeDevCommand.mjs +470 -0
- package/dist/commands/datalakeDevCommand.mjs.map +1 -0
- package/dist/commands/datalakeDevDownCommand.mjs +111 -0
- package/dist/commands/datalakeDevDownCommand.mjs.map +1 -0
- package/dist/commands/datalakeDevLogsCommand.mjs +65 -0
- package/dist/commands/datalakeDevLogsCommand.mjs.map +1 -0
- package/dist/commands/datalakeDevResetCommand.mjs +125 -0
- package/dist/commands/datalakeDevResetCommand.mjs.map +1 -0
- package/dist/commands/datalakeDevStatusCommand.mjs +110 -0
- package/dist/commands/datalakeDevStatusCommand.mjs.map +1 -0
- package/dist/commands/datalakeDevUpCommand.mjs +268 -0
- package/dist/commands/datalakeDevUpCommand.mjs.map +1 -0
- package/dist/commands/datalakeFetchCommand.mjs +106 -0
- package/dist/commands/datalakeFetchCommand.mjs.map +1 -0
- package/dist/commands/datalakeGrantCommand.mjs +147 -0
- package/dist/commands/datalakeGrantCommand.mjs.map +1 -0
- package/dist/commands/datalakeListCommand.mjs +61 -0
- package/dist/commands/datalakeListCommand.mjs.map +1 -0
- package/dist/commands/datalakeLoginCommand.mjs +39 -0
- package/dist/commands/datalakeLoginCommand.mjs.map +1 -0
- package/dist/commands/datalakeLogoutCommand.mjs +20 -0
- package/dist/commands/datalakeLogoutCommand.mjs.map +1 -0
- package/dist/commands/datalakePushCommand.mjs +214 -0
- package/dist/commands/datalakePushCommand.mjs.map +1 -0
- package/dist/commands/datalakeRevokeCommand.mjs +127 -0
- package/dist/commands/datalakeRevokeCommand.mjs.map +1 -0
- package/dist/commands/datalakeTailCommand.mjs +144 -0
- package/dist/commands/datalakeTailCommand.mjs.map +1 -0
- package/dist/commands/datalakeTokenCommand.mjs +61 -0
- package/dist/commands/datalakeTokenCommand.mjs.map +1 -0
- package/dist/commands/datalakeUseCommand.mjs +35 -0
- package/dist/commands/datalakeUseCommand.mjs.map +1 -0
- package/dist/commands/detectCommand.mjs +419 -0
- package/dist/commands/detectCommand.mjs.map +1 -0
- package/dist/commands/hashCommand.mjs +976 -0
- package/dist/commands/hashCommand.mjs.map +1 -0
- package/dist/commands/hashCompareCommand.mjs +865 -0
- package/dist/commands/hashCompareCommand.mjs.map +1 -0
- package/dist/commands/index.mjs +8461 -0
- package/dist/commands/index.mjs.map +1 -0
- package/dist/commands/syncCommand.mjs +66 -0
- package/dist/commands/syncCommand.mjs.map +1 -0
- package/dist/commands/versionCommand.mjs +24 -0
- package/dist/commands/versionCommand.mjs.map +1 -0
- package/dist/commands/walletAccountCommand.mjs +536 -0
- package/dist/commands/walletAccountCommand.mjs.map +1 -0
- package/dist/commands/walletAccountDeriveCommand.mjs +415 -0
- package/dist/commands/walletAccountDeriveCommand.mjs.map +1 -0
- package/dist/commands/walletAccountLabelCommand.mjs +405 -0
- package/dist/commands/walletAccountLabelCommand.mjs.map +1 -0
- package/dist/commands/walletAccountListCommand.mjs +381 -0
- package/dist/commands/walletAccountListCommand.mjs.map +1 -0
- package/dist/commands/walletAccountRemoveCommand.mjs +396 -0
- package/dist/commands/walletAccountRemoveCommand.mjs.map +1 -0
- package/dist/commands/walletAccountShowCommand.mjs +380 -0
- package/dist/commands/walletAccountShowCommand.mjs.map +1 -0
- package/dist/commands/walletBackupCommand.mjs +222 -0
- package/dist/commands/walletBackupCommand.mjs.map +1 -0
- package/dist/commands/walletBackupExportCommand.mjs +107 -0
- package/dist/commands/walletBackupExportCommand.mjs.map +1 -0
- package/dist/commands/walletBackupImportCommand.mjs +154 -0
- package/dist/commands/walletBackupImportCommand.mjs.map +1 -0
- package/dist/commands/walletBalanceCommand.mjs +448 -0
- package/dist/commands/walletBalanceCommand.mjs.map +1 -0
- package/dist/commands/walletCommand.mjs +1968 -0
- package/dist/commands/walletCommand.mjs.map +1 -0
- package/dist/commands/walletContactAddCommand.mjs +111 -0
- package/dist/commands/walletContactAddCommand.mjs.map +1 -0
- package/dist/commands/walletContactCommand.mjs +184 -0
- package/dist/commands/walletContactCommand.mjs.map +1 -0
- package/dist/commands/walletContactListCommand.mjs +66 -0
- package/dist/commands/walletContactListCommand.mjs.map +1 -0
- package/dist/commands/walletContactRemoveCommand.mjs +97 -0
- package/dist/commands/walletContactRemoveCommand.mjs.map +1 -0
- package/dist/commands/walletContactRenameCommand.mjs +114 -0
- package/dist/commands/walletContactRenameCommand.mjs.map +1 -0
- package/dist/commands/walletCreateCommand.mjs +407 -0
- package/dist/commands/walletCreateCommand.mjs.map +1 -0
- package/dist/commands/walletExportCommand.mjs +345 -0
- package/dist/commands/walletExportCommand.mjs.map +1 -0
- package/dist/commands/walletImportCommand.mjs +413 -0
- package/dist/commands/walletImportCommand.mjs.map +1 -0
- package/dist/commands/walletListCommand.mjs +69 -0
- package/dist/commands/walletListCommand.mjs.map +1 -0
- package/dist/commands/walletLockCommand.mjs +56 -0
- package/dist/commands/walletLockCommand.mjs.map +1 -0
- package/dist/commands/walletNetworkAddCommand.mjs +131 -0
- package/dist/commands/walletNetworkAddCommand.mjs.map +1 -0
- package/dist/commands/walletNetworkCommand.mjs +206 -0
- package/dist/commands/walletNetworkCommand.mjs.map +1 -0
- package/dist/commands/walletNetworkListCommand.mjs +104 -0
- package/dist/commands/walletNetworkListCommand.mjs.map +1 -0
- package/dist/commands/walletNetworkRemoveCommand.mjs +112 -0
- package/dist/commands/walletNetworkRemoveCommand.mjs.map +1 -0
- package/dist/commands/walletNetworkUseCommand.mjs +110 -0
- package/dist/commands/walletNetworkUseCommand.mjs.map +1 -0
- package/dist/commands/walletPasswordChangeCommand.mjs +291 -0
- package/dist/commands/walletPasswordChangeCommand.mjs.map +1 -0
- package/dist/commands/walletPasswordCommand.mjs +301 -0
- package/dist/commands/walletPasswordCommand.mjs.map +1 -0
- package/dist/commands/walletRemoveCommand.mjs +378 -0
- package/dist/commands/walletRemoveCommand.mjs.map +1 -0
- package/dist/commands/walletRenameCommand.mjs +94 -0
- package/dist/commands/walletRenameCommand.mjs.map +1 -0
- package/dist/commands/walletSignCommand.mjs +662 -0
- package/dist/commands/walletSignCommand.mjs.map +1 -0
- package/dist/commands/walletTxBroadcastCommand.mjs +473 -0
- package/dist/commands/walletTxBroadcastCommand.mjs.map +1 -0
- package/dist/commands/walletTxCommand.mjs +612 -0
- package/dist/commands/walletTxCommand.mjs.map +1 -0
- package/dist/commands/walletTxSendCommand.mjs +492 -0
- package/dist/commands/walletTxSendCommand.mjs.map +1 -0
- package/dist/commands/walletTxSignCommand.mjs +403 -0
- package/dist/commands/walletTxSignCommand.mjs.map +1 -0
- package/dist/commands/walletUnlockCommand.mjs +308 -0
- package/dist/commands/walletUnlockCommand.mjs.map +1 -0
- package/dist/commands/walletUseCommand.mjs +95 -0
- package/dist/commands/walletUseCommand.mjs.map +1 -0
- package/dist/commands/xyoCommand.mjs +188 -0
- package/dist/commands/xyoCommand.mjs.map +1 -0
- package/dist/commands/xyoTxCommand.mjs +178 -0
- package/dist/commands/xyoTxCommand.mjs.map +1 -0
- package/dist/commands/xyoTxValidateCommand.mjs +168 -0
- package/dist/commands/xyoTxValidateCommand.mjs.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +8466 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types/modules.d.mjs +1 -0
- package/dist/types/modules.d.mjs.map +1 -0
- package/package.json +197 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// src/actions/hash/algorithms/tlsh.ts
|
|
2
|
+
import tlsh from "tlsh";
|
|
3
|
+
|
|
4
|
+
// src/actions/hash/lib/hamming.ts
|
|
5
|
+
function popcount8(byte) {
|
|
6
|
+
let count = 0;
|
|
7
|
+
let value = byte & 255;
|
|
8
|
+
while (value !== 0) {
|
|
9
|
+
count += value & 1;
|
|
10
|
+
value >>>= 1;
|
|
11
|
+
}
|
|
12
|
+
return count;
|
|
13
|
+
}
|
|
14
|
+
function hammingHex(a, b) {
|
|
15
|
+
if (a.length !== b.length) {
|
|
16
|
+
throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`);
|
|
17
|
+
}
|
|
18
|
+
if (a.length % 2 !== 0) {
|
|
19
|
+
throw new Error(`Hash hex length must be even, got ${a.length}`);
|
|
20
|
+
}
|
|
21
|
+
let dist = 0;
|
|
22
|
+
for (let i = 0; i < a.length; i += 2) {
|
|
23
|
+
const xa = Number.parseInt(a.slice(i, i + 2), 16);
|
|
24
|
+
const xb = Number.parseInt(b.slice(i, i + 2), 16);
|
|
25
|
+
if (Number.isNaN(xa) || Number.isNaN(xb)) {
|
|
26
|
+
throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`);
|
|
27
|
+
}
|
|
28
|
+
dist += popcount8(xa ^ xb);
|
|
29
|
+
}
|
|
30
|
+
return dist;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/actions/hash/algorithms/tlsh.ts
|
|
34
|
+
var tlshAlgorithm = {
|
|
35
|
+
name: "tlsh",
|
|
36
|
+
family: "fuzzy-byte",
|
|
37
|
+
inputType: "bytes",
|
|
38
|
+
async hash(input) {
|
|
39
|
+
if (input.bytes === void 0) {
|
|
40
|
+
throw new Error("tlsh requires loaded bytes.");
|
|
41
|
+
}
|
|
42
|
+
if (input.bytes.length < 50) {
|
|
43
|
+
throw new Error(`tlsh requires at least 50 bytes of input (got ${input.bytes.length}).`);
|
|
44
|
+
}
|
|
45
|
+
return tlsh(input.bytes.toString("binary"));
|
|
46
|
+
},
|
|
47
|
+
async compare(a, b) {
|
|
48
|
+
if (a.length !== b.length) {
|
|
49
|
+
throw new Error(`tlsh hash length mismatch: ${a.length} vs ${b.length}`);
|
|
50
|
+
}
|
|
51
|
+
const skip = a.length >= 8 ? 4 : 0;
|
|
52
|
+
const aBody = a.slice(skip);
|
|
53
|
+
const bBody = b.slice(skip);
|
|
54
|
+
const distance = hammingHex(aBody, bBody);
|
|
55
|
+
const bits = aBody.length / 2 * 8;
|
|
56
|
+
return {
|
|
57
|
+
distance,
|
|
58
|
+
similarity: 1 - distance / bits,
|
|
59
|
+
metric: "tlsh-bit-hamming"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
export {
|
|
64
|
+
tlshAlgorithm
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=tlsh.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/hash/algorithms/tlsh.ts","../../../../src/actions/hash/lib/hamming.ts"],"sourcesContent":["import tlsh from 'tlsh'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\n/**\n * The `tlsh` npm package exports a single function: `tlsh(data: string): string`.\n * It does NOT expose the canonical diff algorithm publicly. We use a Hamming-distance\n * proxy over the hash bytes for `compare`. This is a reasonable approximation, not the\n * canonical TLSH-diff score — the metric label `tlsh-bit-hamming` makes that explicit.\n */\n\nexport const tlshAlgorithm: Algorithm = {\n name: 'tlsh',\n family: 'fuzzy-byte',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('tlsh requires loaded bytes.')\n }\n if (input.bytes.length < 50) {\n throw new Error(`tlsh requires at least 50 bytes of input (got ${input.bytes.length}).`)\n }\n return tlsh(input.bytes.toString('binary'))\n },\n async compare(a, b) {\n if (a.length !== b.length) {\n throw new Error(`tlsh hash length mismatch: ${a.length} vs ${b.length}`)\n }\n // TLSH hashes carry a leading version/type byte that's identical for hashes\n // produced by the same library — skip 4 hex chars (version+checksum bytes)\n // before measuring distance for slightly more meaningful comparison.\n const skip = a.length >= 8 ? 4 : 0\n const aBody = a.slice(skip)\n const bBody = b.slice(skip)\n const distance = hammingHex(aBody, bBody)\n const bits = (aBody.length / 2) * 8\n return {\n distance,\n similarity: 1 - distance / bits,\n metric: 'tlsh-bit-hamming',\n }\n },\n}\n","/**\n * Population count for an 8-bit value (number of set bits).\n */\nfunction popcount8(byte: number): number {\n let count = 0\n let value = byte & 0xff\n while (value !== 0) {\n count += value & 1\n value >>>= 1\n }\n return count\n}\n\n/**\n * Hamming distance between two equal-length lowercase-hex strings.\n * Throws when the lengths differ.\n */\nexport function hammingHex(a: string, b: string): number {\n if (a.length !== b.length) {\n throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`)\n }\n if (a.length % 2 !== 0) {\n throw new Error(`Hash hex length must be even, got ${a.length}`)\n }\n let dist = 0\n for (let i = 0; i < a.length; i += 2) {\n const xa = Number.parseInt(a.slice(i, i + 2), 16)\n const xb = Number.parseInt(b.slice(i, i + 2), 16)\n if (Number.isNaN(xa) || Number.isNaN(xb)) {\n throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`)\n }\n dist += popcount8(xa ^ xb)\n }\n return dist\n}\n\n/**\n * Bit-length of an even-length hex string.\n */\nexport function bitLengthHex(hex: string): number {\n return (hex.length / 2) * 8\n}\n\n/**\n * Population count for a 32-bit unsigned value (number of set bits).\n * Uses the parallel-prefix bit trick.\n */\nexport function popcount32(value: number): number {\n let v = Math.trunc(value)\n v = v - ((v >>> 1) & 0x55_55_55_55)\n v = (v & 0x33_33_33_33) + ((v >>> 2) & 0x33_33_33_33)\n v = (v + (v >>> 4)) & 0x0f_0f_0f_0f\n return ((v * 0x01_01_01_01) >>> 24) & 0xff\n}\n"],"mappings":";AAAA,OAAO,UAAU;;;ACGjB,SAAS,UAAU,MAAsB;AACvC,MAAI,QAAQ;AACZ,MAAI,QAAQ,OAAO;AACnB,SAAO,UAAU,GAAG;AAClB,aAAS,QAAQ;AACjB,eAAW;AAAA,EACb;AACA,SAAO;AACT;AAMO,SAAS,WAAW,GAAW,GAAmB;AACvD,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,UAAM,IAAI,MAAM,yBAAyB,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE;AAAA,EACpE;AACA,MAAI,EAAE,SAAS,MAAM,GAAG;AACtB,UAAM,IAAI,MAAM,qCAAqC,EAAE,MAAM,EAAE;AAAA,EACjE;AACA,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,GAAG;AACpC,UAAM,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AAChD,UAAM,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AAChD,QAAI,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,EAAE,GAAG;AACxC,YAAM,IAAI,UAAU,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG;AAAA,IACrG;AACA,YAAQ,UAAU,KAAK,EAAE;AAAA,EAC3B;AACA,SAAO;AACT;;;ADtBO,IAAM,gBAA2B;AAAA,EACtC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM,KAAK,OAAO;AAChB,QAAI,MAAM,UAAU,QAAW;AAC7B,YAAM,IAAI,MAAM,6BAA6B;AAAA,IAC/C;AACA,QAAI,MAAM,MAAM,SAAS,IAAI;AAC3B,YAAM,IAAI,MAAM,iDAAiD,MAAM,MAAM,MAAM,IAAI;AAAA,IACzF;AACA,WAAO,KAAK,MAAM,MAAM,SAAS,QAAQ,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,GAAG,GAAG;AAClB,QAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,YAAM,IAAI,MAAM,8BAA8B,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE;AAAA,IACzE;AAIA,UAAM,OAAO,EAAE,UAAU,IAAI,IAAI;AACjC,UAAM,QAAQ,EAAE,MAAM,IAAI;AAC1B,UAAM,QAAQ,EAAE,MAAM,IAAI;AAC1B,UAAM,WAAW,WAAW,OAAO,KAAK;AACxC,UAAM,OAAQ,MAAM,SAAS,IAAK;AAClC,WAAO;AAAA,MACL;AAAA,MACA,YAAY,IAAI,WAAW;AAAA,MAC3B,QAAQ;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
// src/actions/hash/algorithms/videoFrames.ts
|
|
2
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
3
|
+
import {
|
|
4
|
+
mkdtemp,
|
|
5
|
+
readdir,
|
|
6
|
+
readFile,
|
|
7
|
+
rm as rm2
|
|
8
|
+
} from "fs/promises";
|
|
9
|
+
import OS2 from "os";
|
|
10
|
+
import PATH2 from "path";
|
|
11
|
+
|
|
12
|
+
// src/actions/hash/lib/hamming.ts
|
|
13
|
+
function popcount8(byte) {
|
|
14
|
+
let count = 0;
|
|
15
|
+
let value = byte & 255;
|
|
16
|
+
while (value !== 0) {
|
|
17
|
+
count += value & 1;
|
|
18
|
+
value >>>= 1;
|
|
19
|
+
}
|
|
20
|
+
return count;
|
|
21
|
+
}
|
|
22
|
+
function hammingHex(a, b) {
|
|
23
|
+
if (a.length !== b.length) {
|
|
24
|
+
throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`);
|
|
25
|
+
}
|
|
26
|
+
if (a.length % 2 !== 0) {
|
|
27
|
+
throw new Error(`Hash hex length must be even, got ${a.length}`);
|
|
28
|
+
}
|
|
29
|
+
let dist = 0;
|
|
30
|
+
for (let i = 0; i < a.length; i += 2) {
|
|
31
|
+
const xa = Number.parseInt(a.slice(i, i + 2), 16);
|
|
32
|
+
const xb = Number.parseInt(b.slice(i, i + 2), 16);
|
|
33
|
+
if (Number.isNaN(xa) || Number.isNaN(xb)) {
|
|
34
|
+
throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`);
|
|
35
|
+
}
|
|
36
|
+
dist += popcount8(xa ^ xb);
|
|
37
|
+
}
|
|
38
|
+
return dist;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/actions/hash/lib/runBinary.ts
|
|
42
|
+
import { spawn } from "child_process";
|
|
43
|
+
async function runBinary(options) {
|
|
44
|
+
const maxBytes = options.maxBytes ?? 64 * 1024 * 1024;
|
|
45
|
+
return await new Promise((resolve, reject) => {
|
|
46
|
+
const child = spawn(options.binary, [...options.args ?? []], { stdio: ["pipe", "pipe", "pipe"] });
|
|
47
|
+
const stdoutChunks = [];
|
|
48
|
+
let stdoutBytes = 0;
|
|
49
|
+
let stderr = "";
|
|
50
|
+
let killedForOverflow = false;
|
|
51
|
+
child.stdout.on("data", (chunk) => {
|
|
52
|
+
stdoutBytes += chunk.length;
|
|
53
|
+
if (stdoutBytes > maxBytes) {
|
|
54
|
+
if (!killedForOverflow) {
|
|
55
|
+
killedForOverflow = true;
|
|
56
|
+
child.kill("SIGKILL");
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
stdoutChunks.push(chunk);
|
|
61
|
+
});
|
|
62
|
+
child.stderr.on("data", (chunk) => {
|
|
63
|
+
stderr += chunk.toString("utf8");
|
|
64
|
+
});
|
|
65
|
+
child.on("error", (err) => reject(err));
|
|
66
|
+
child.on("close", (code) => {
|
|
67
|
+
if (killedForOverflow) {
|
|
68
|
+
reject(new Error(`${options.binary} stdout exceeded ${maxBytes} bytes`));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const exitCode = code ?? -1;
|
|
72
|
+
const stdout = Buffer.concat(stdoutChunks);
|
|
73
|
+
if (exitCode !== 0) {
|
|
74
|
+
const tail = stderr.trim().split(/\r?\n/).slice(-3).join("\n");
|
|
75
|
+
reject(new Error(`${options.binary} exited ${exitCode}${tail.length > 0 ? `: ${tail}` : ""}`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
resolve({
|
|
79
|
+
stdout,
|
|
80
|
+
stderr,
|
|
81
|
+
exitCode
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
if (options.stdin === void 0) {
|
|
85
|
+
child.stdin.end();
|
|
86
|
+
} else {
|
|
87
|
+
child.stdin.end(options.stdin);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/actions/hash/lib/which.ts
|
|
93
|
+
import { spawn as spawn2 } from "child_process";
|
|
94
|
+
async function which(binary) {
|
|
95
|
+
return await new Promise((resolve) => {
|
|
96
|
+
const cmd = process.platform === "win32" ? "where" : "command";
|
|
97
|
+
const args = process.platform === "win32" ? [binary] : ["-v", binary];
|
|
98
|
+
const child = spawn2(cmd, args, { shell: process.platform !== "win32" });
|
|
99
|
+
let stdout = "";
|
|
100
|
+
child.stdout.on("data", (chunk) => {
|
|
101
|
+
stdout += chunk.toString("utf8");
|
|
102
|
+
});
|
|
103
|
+
child.on("error", () => resolve(null));
|
|
104
|
+
child.on("close", (code) => {
|
|
105
|
+
if (code === 0) {
|
|
106
|
+
const path = stdout.split(/\r?\n/).find((line) => line.trim().length > 0)?.trim() ?? null;
|
|
107
|
+
resolve(path);
|
|
108
|
+
} else {
|
|
109
|
+
resolve(null);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async function requireBinary(req) {
|
|
115
|
+
const path = await which(req.binary);
|
|
116
|
+
if (path !== null) return path;
|
|
117
|
+
const lines = [`${req.binary} binary not found on PATH. Install with:`];
|
|
118
|
+
if (req.install.brew !== void 0) lines.push(` macOS: brew install ${req.install.brew}`);
|
|
119
|
+
if (req.install.apt !== void 0) lines.push(` Debian: apt install ${req.install.apt}`);
|
|
120
|
+
if (req.install.choco !== void 0) lines.push(` Windows: choco install ${req.install.choco}`);
|
|
121
|
+
throw new Error(lines.join("\n"));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/actions/hash/lib/withTempfile.ts
|
|
125
|
+
import { randomBytes } from "crypto";
|
|
126
|
+
import { rm, writeFile } from "fs/promises";
|
|
127
|
+
import OS from "os";
|
|
128
|
+
import PATH from "path";
|
|
129
|
+
async function withTempfile(bytes, extension, fn) {
|
|
130
|
+
const ext = extension !== void 0 && extension.length > 0 ? `.${extension}` : "";
|
|
131
|
+
const path = PATH.join(OS.tmpdir(), `aries-hash-${randomBytes(8).toString("hex")}${ext}`);
|
|
132
|
+
await writeFile(path, bytes);
|
|
133
|
+
try {
|
|
134
|
+
return await fn(path);
|
|
135
|
+
} finally {
|
|
136
|
+
await rm(path, { force: true });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/actions/hash/algorithms/pdq.ts
|
|
141
|
+
import { createRequire } from "module";
|
|
142
|
+
import sharp from "sharp";
|
|
143
|
+
var require2 = createRequire(import.meta.url);
|
|
144
|
+
var { PDQ } = require2("pdq-wasm");
|
|
145
|
+
var initialized = false;
|
|
146
|
+
async function ensureInit() {
|
|
147
|
+
if (initialized) return;
|
|
148
|
+
await PDQ.init();
|
|
149
|
+
initialized = true;
|
|
150
|
+
}
|
|
151
|
+
async function toRgbRaw(source) {
|
|
152
|
+
const { data, info } = await sharp(source).removeAlpha().raw().toBuffer({ resolveWithObject: true });
|
|
153
|
+
return {
|
|
154
|
+
data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
|
|
155
|
+
width: info.width,
|
|
156
|
+
height: info.height
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
var pdqAlgorithm = {
|
|
160
|
+
name: "pdq",
|
|
161
|
+
family: "perceptual-image",
|
|
162
|
+
inputType: "image",
|
|
163
|
+
async hash(input) {
|
|
164
|
+
const source = input.path ?? input.bytes;
|
|
165
|
+
if (source === void 0) {
|
|
166
|
+
throw new Error("pdq requires bytes or a path.");
|
|
167
|
+
}
|
|
168
|
+
await ensureInit();
|
|
169
|
+
const rgb = await toRgbRaw(source);
|
|
170
|
+
const result = PDQ.hash({
|
|
171
|
+
data: rgb.data,
|
|
172
|
+
width: rgb.width,
|
|
173
|
+
height: rgb.height,
|
|
174
|
+
channels: 3
|
|
175
|
+
});
|
|
176
|
+
return PDQ.toHex(result.hash);
|
|
177
|
+
},
|
|
178
|
+
async compare(a, b) {
|
|
179
|
+
const dist = hammingHex(a, b);
|
|
180
|
+
const bits = a.length / 2 * 8;
|
|
181
|
+
return {
|
|
182
|
+
distance: dist,
|
|
183
|
+
similarity: 1 - dist / bits,
|
|
184
|
+
metric: `hamming-${bits}`
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// src/actions/hash/algorithms/phash.ts
|
|
190
|
+
import phashLib from "sharp-phash";
|
|
191
|
+
var phash = phashLib;
|
|
192
|
+
function binaryToHex(bin) {
|
|
193
|
+
if (!/^[01]+$/.test(bin)) {
|
|
194
|
+
throw new TypeError(`phash returned unexpected output: ${bin.slice(0, 20)}\u2026`);
|
|
195
|
+
}
|
|
196
|
+
const padded = bin.padStart(Math.ceil(bin.length / 4) * 4, "0");
|
|
197
|
+
let hex = "";
|
|
198
|
+
for (let i = 0; i < padded.length; i += 4) {
|
|
199
|
+
hex += Number.parseInt(padded.slice(i, i + 4), 2).toString(16);
|
|
200
|
+
}
|
|
201
|
+
return hex;
|
|
202
|
+
}
|
|
203
|
+
var phashAlgorithm = {
|
|
204
|
+
name: "phash",
|
|
205
|
+
family: "perceptual-image",
|
|
206
|
+
inputType: "image",
|
|
207
|
+
async hash(input) {
|
|
208
|
+
const source = input.path ?? input.bytes;
|
|
209
|
+
if (source === void 0) {
|
|
210
|
+
throw new Error("phash requires bytes or a path.");
|
|
211
|
+
}
|
|
212
|
+
const bin = await phash(source);
|
|
213
|
+
return binaryToHex(bin);
|
|
214
|
+
},
|
|
215
|
+
async compare(a, b) {
|
|
216
|
+
const dist = hammingHex(a, b);
|
|
217
|
+
const bits = a.length / 2 * 8;
|
|
218
|
+
return {
|
|
219
|
+
distance: dist,
|
|
220
|
+
similarity: 1 - dist / bits,
|
|
221
|
+
metric: `hamming-${bits}`
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// src/actions/hash/algorithms/videoFrames.ts
|
|
227
|
+
var FFMPEG_BIN = {
|
|
228
|
+
binary: "ffmpeg",
|
|
229
|
+
install: {
|
|
230
|
+
brew: "ffmpeg",
|
|
231
|
+
apt: "ffmpeg",
|
|
232
|
+
choco: "ffmpeg"
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
var SUPPORTED_FRAME_ALGORITHMS = ["phash", "pdq"];
|
|
236
|
+
var DEFAULT_FPS = 1;
|
|
237
|
+
var DEFAULT_FRAME_ALGORITHM = "phash";
|
|
238
|
+
async function extractFrames(videoPath, fps) {
|
|
239
|
+
await requireBinary(FFMPEG_BIN);
|
|
240
|
+
const dir = await mkdtemp(PATH2.join(OS2.tmpdir(), `aries-vframes-${randomBytes2(6).toString("hex")}-`));
|
|
241
|
+
try {
|
|
242
|
+
await runBinary({
|
|
243
|
+
binary: "ffmpeg",
|
|
244
|
+
args: [
|
|
245
|
+
"-hide_banner",
|
|
246
|
+
"-loglevel",
|
|
247
|
+
"error",
|
|
248
|
+
"-i",
|
|
249
|
+
videoPath,
|
|
250
|
+
"-vf",
|
|
251
|
+
`fps=${fps},scale=128:128:force_original_aspect_ratio=disable`,
|
|
252
|
+
"-q:v",
|
|
253
|
+
"5",
|
|
254
|
+
PATH2.join(dir, "frame-%05d.jpg")
|
|
255
|
+
]
|
|
256
|
+
});
|
|
257
|
+
const entries = (await readdir(dir)).filter((name) => name.endsWith(".jpg")).toSorted();
|
|
258
|
+
const frames = await Promise.all(entries.map(async (name) => await readFile(PATH2.join(dir, name))));
|
|
259
|
+
return { frames };
|
|
260
|
+
} finally {
|
|
261
|
+
await rm2(dir, { recursive: true, force: true });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function frameHasher(name) {
|
|
265
|
+
switch (name) {
|
|
266
|
+
case "phash": {
|
|
267
|
+
return async (bytes) => await phashAlgorithm.hash({ bytes });
|
|
268
|
+
}
|
|
269
|
+
case "pdq": {
|
|
270
|
+
return async (bytes) => await pdqAlgorithm.hash({ bytes });
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
async function fingerprintVideo(videoPath, fps, frameAlgorithm) {
|
|
275
|
+
const { frames } = await extractFrames(videoPath, fps);
|
|
276
|
+
const hashFrame = frameHasher(frameAlgorithm);
|
|
277
|
+
const hashes = await Promise.all(frames.map(async (frame, idx) => ({
|
|
278
|
+
t: idx / fps,
|
|
279
|
+
hash: await hashFrame(frame)
|
|
280
|
+
})));
|
|
281
|
+
return {
|
|
282
|
+
algorithm: "video-frames",
|
|
283
|
+
fps,
|
|
284
|
+
frameAlgorithm,
|
|
285
|
+
duration: frames.length / fps,
|
|
286
|
+
frames: hashes
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function parseVideoFramesHash(raw) {
|
|
290
|
+
let parsed;
|
|
291
|
+
try {
|
|
292
|
+
parsed = JSON.parse(raw);
|
|
293
|
+
} catch {
|
|
294
|
+
throw new Error("video-frames hash must be JSON produced by `aries hash --algorithm video-frames`.");
|
|
295
|
+
}
|
|
296
|
+
const obj = parsed;
|
|
297
|
+
if (obj.algorithm !== "video-frames" || typeof obj.fps !== "number" || typeof obj.duration !== "number" || !Array.isArray(obj.frames)) {
|
|
298
|
+
throw new Error("video-frames hash JSON missing required fields.");
|
|
299
|
+
}
|
|
300
|
+
if (obj.frameAlgorithm === void 0) {
|
|
301
|
+
return { ...obj, frameAlgorithm: "phash" };
|
|
302
|
+
}
|
|
303
|
+
return obj;
|
|
304
|
+
}
|
|
305
|
+
function compareFrameSequences(a, b) {
|
|
306
|
+
const fps = Math.min(a.fps, b.fps);
|
|
307
|
+
if (a.frames.length === 0 || b.frames.length === 0) {
|
|
308
|
+
return {
|
|
309
|
+
similarity: 0,
|
|
310
|
+
distance: Number.NaN,
|
|
311
|
+
bestOffsetSeconds: 0,
|
|
312
|
+
overlapSeconds: 0
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
const minLen = Math.min(a.frames.length, b.frames.length);
|
|
316
|
+
const maxOffset = Math.max(a.frames.length, b.frames.length) - 1;
|
|
317
|
+
let best = {
|
|
318
|
+
similarity: 0,
|
|
319
|
+
distance: Number.NaN,
|
|
320
|
+
bestOffsetSeconds: 0,
|
|
321
|
+
overlapSeconds: 0
|
|
322
|
+
};
|
|
323
|
+
const minOverlap = Math.max(2, Math.floor(minLen / 4));
|
|
324
|
+
for (let offset = -maxOffset; offset <= maxOffset; offset++) {
|
|
325
|
+
const aStart = Math.max(0, -offset);
|
|
326
|
+
const bStart = Math.max(0, offset);
|
|
327
|
+
const overlap = Math.min(a.frames.length - aStart, b.frames.length - bStart);
|
|
328
|
+
if (overlap < minOverlap) continue;
|
|
329
|
+
let totalBits = 0;
|
|
330
|
+
let bitWidth = 0;
|
|
331
|
+
for (let i = 0; i < overlap; i++) {
|
|
332
|
+
const ah = a.frames[aStart + i].hash;
|
|
333
|
+
const bh = b.frames[bStart + i].hash;
|
|
334
|
+
if (ah.length !== bh.length) continue;
|
|
335
|
+
totalBits += hammingHex(ah, bh);
|
|
336
|
+
bitWidth += ah.length / 2 * 8;
|
|
337
|
+
}
|
|
338
|
+
if (bitWidth === 0) continue;
|
|
339
|
+
const similarity = 1 - totalBits / bitWidth;
|
|
340
|
+
if (similarity > best.similarity) {
|
|
341
|
+
best = {
|
|
342
|
+
similarity,
|
|
343
|
+
distance: totalBits,
|
|
344
|
+
bestOffsetSeconds: offset / fps,
|
|
345
|
+
overlapSeconds: overlap / fps
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return best;
|
|
350
|
+
}
|
|
351
|
+
function parseFps(options) {
|
|
352
|
+
const raw = options?.fps;
|
|
353
|
+
if (raw === void 0) return DEFAULT_FPS;
|
|
354
|
+
const value = typeof raw === "string" ? Number.parseFloat(raw) : Number(raw);
|
|
355
|
+
if (!Number.isFinite(value) || value <= 0 || value > 60) {
|
|
356
|
+
const display = typeof raw === "string" || typeof raw === "number" ? String(raw) : "<non-scalar>";
|
|
357
|
+
throw new RangeError(`Invalid --fps ${display}: expected a number in (0, 60].`);
|
|
358
|
+
}
|
|
359
|
+
return value;
|
|
360
|
+
}
|
|
361
|
+
function parseFrameAlgorithm(options) {
|
|
362
|
+
const raw = options?.frameAlgorithm;
|
|
363
|
+
if (raw === void 0) return DEFAULT_FRAME_ALGORITHM;
|
|
364
|
+
if (typeof raw !== "string" || !SUPPORTED_FRAME_ALGORITHMS.includes(raw)) {
|
|
365
|
+
const display = typeof raw === "string" ? raw : `<${typeof raw}>`;
|
|
366
|
+
throw new RangeError(`Invalid --frame-algorithm ${display}: expected one of ${SUPPORTED_FRAME_ALGORITHMS.join(", ")}.`);
|
|
367
|
+
}
|
|
368
|
+
return raw;
|
|
369
|
+
}
|
|
370
|
+
var videoFramesAlgorithm = {
|
|
371
|
+
name: "video-frames",
|
|
372
|
+
family: "video",
|
|
373
|
+
inputType: "video",
|
|
374
|
+
requires: [FFMPEG_BIN],
|
|
375
|
+
async hash(input) {
|
|
376
|
+
const fps = parseFps(input.options);
|
|
377
|
+
const frameAlgorithm = parseFrameAlgorithm(input.options);
|
|
378
|
+
const fp = input.path === void 0 ? input.bytes === void 0 ? null : await withTempfile(input.bytes, "video.bin", async (path) => await fingerprintVideo(path, fps, frameAlgorithm)) : await fingerprintVideo(input.path, fps, frameAlgorithm);
|
|
379
|
+
if (fp === null) {
|
|
380
|
+
throw new Error("video-frames requires bytes or a path.");
|
|
381
|
+
}
|
|
382
|
+
return JSON.stringify(fp);
|
|
383
|
+
},
|
|
384
|
+
async compare(a, b) {
|
|
385
|
+
const fpA = parseVideoFramesHash(a);
|
|
386
|
+
const fpB = parseVideoFramesHash(b);
|
|
387
|
+
if (fpA.frameAlgorithm !== fpB.frameAlgorithm) {
|
|
388
|
+
throw new Error(`Cannot compare video-frames hashes with different frame algorithms (${fpA.frameAlgorithm} vs ${fpB.frameAlgorithm}).`);
|
|
389
|
+
}
|
|
390
|
+
const result = compareFrameSequences(fpA, fpB);
|
|
391
|
+
return {
|
|
392
|
+
similarity: result.similarity,
|
|
393
|
+
distance: Number.isFinite(result.distance) ? result.distance : void 0,
|
|
394
|
+
metric: `frame-sequence-${fpA.frameAlgorithm}@${fpA.fps}fps`
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
export {
|
|
399
|
+
DEFAULT_FPS,
|
|
400
|
+
DEFAULT_FRAME_ALGORITHM,
|
|
401
|
+
SUPPORTED_FRAME_ALGORITHMS,
|
|
402
|
+
videoFramesAlgorithm
|
|
403
|
+
};
|
|
404
|
+
//# sourceMappingURL=videoFrames.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/hash/algorithms/videoFrames.ts","../../../../src/actions/hash/lib/hamming.ts","../../../../src/actions/hash/lib/runBinary.ts","../../../../src/actions/hash/lib/which.ts","../../../../src/actions/hash/lib/withTempfile.ts","../../../../src/actions/hash/algorithms/pdq.ts","../../../../src/actions/hash/algorithms/phash.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto'\nimport {\n mkdtemp, readdir, readFile, rm,\n} from 'node:fs/promises'\nimport OS from 'node:os'\nimport PATH from 'node:path'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport { runBinary } from '../lib/runBinary.ts'\nimport { requireBinary } from '../lib/which.ts'\nimport { withTempfile } from '../lib/withTempfile.ts'\nimport { pdqAlgorithm } from './pdq.ts'\nimport { phashAlgorithm } from './phash.ts'\nimport type { Algorithm, RequiredBinary } from './types.ts'\n\nconst FFMPEG_BIN: RequiredBinary = {\n binary: 'ffmpeg',\n install: {\n brew: 'ffmpeg',\n apt: 'ffmpeg',\n choco: 'ffmpeg',\n },\n}\n\nexport type FrameAlgorithmName = 'phash' | 'pdq'\nexport const SUPPORTED_FRAME_ALGORITHMS = ['phash', 'pdq'] as const\n\ninterface VideoFramesFingerprint {\n algorithm: 'video-frames'\n fps: number\n frameAlgorithm: FrameAlgorithmName\n duration: number\n frames: { t: number; hash: string }[]\n}\n\nexport const DEFAULT_FPS = 1\nexport const DEFAULT_FRAME_ALGORITHM: FrameAlgorithmName = 'phash'\n\nasync function extractFrames(videoPath: string, fps: number): Promise<{ frames: Buffer[] }> {\n await requireBinary(FFMPEG_BIN)\n const dir = await mkdtemp(PATH.join(OS.tmpdir(), `aries-vframes-${randomBytes(6).toString('hex')}-`))\n try {\n await runBinary({\n binary: 'ffmpeg',\n args: [\n '-hide_banner',\n '-loglevel',\n 'error',\n '-i',\n videoPath,\n '-vf',\n `fps=${fps},scale=128:128:force_original_aspect_ratio=disable`,\n '-q:v',\n '5',\n PATH.join(dir, 'frame-%05d.jpg'),\n ],\n })\n const entries = (await readdir(dir)).filter(name => name.endsWith('.jpg')).toSorted()\n const frames = await Promise.all(entries.map(async name => await readFile(PATH.join(dir, name))))\n return { frames }\n } finally {\n await rm(dir, { recursive: true, force: true })\n }\n}\n\nfunction frameHasher(name: FrameAlgorithmName): (bytes: Buffer) => Promise<string> {\n switch (name) {\n case 'phash': { return async bytes => await phashAlgorithm.hash({ bytes })\n }\n case 'pdq': { return async bytes => await pdqAlgorithm.hash({ bytes })\n }\n }\n}\n\nasync function fingerprintVideo(\n videoPath: string,\n fps: number,\n frameAlgorithm: FrameAlgorithmName,\n): Promise<VideoFramesFingerprint> {\n const { frames } = await extractFrames(videoPath, fps)\n const hashFrame = frameHasher(frameAlgorithm)\n const hashes = await Promise.all(frames.map(async (frame, idx) => ({\n t: idx / fps,\n hash: await hashFrame(frame),\n })))\n return {\n algorithm: 'video-frames',\n fps,\n frameAlgorithm,\n duration: frames.length / fps,\n frames: hashes,\n }\n}\n\nfunction parseVideoFramesHash(raw: string): VideoFramesFingerprint {\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n throw new Error('video-frames hash must be JSON produced by `aries hash --algorithm video-frames`.')\n }\n const obj = parsed as Partial<VideoFramesFingerprint>\n if (\n obj.algorithm !== 'video-frames'\n || typeof obj.fps !== 'number'\n || typeof obj.duration !== 'number'\n || !Array.isArray(obj.frames)\n ) {\n throw new Error('video-frames hash JSON missing required fields.')\n }\n // frameAlgorithm was added in a later revision; default to phash when older hashes lack it.\n if (obj.frameAlgorithm === undefined) {\n return { ...obj, frameAlgorithm: 'phash' } as VideoFramesFingerprint\n }\n return obj as VideoFramesFingerprint\n}\n\ninterface VideoFramesCompareDetails {\n similarity: number\n distance: number\n bestOffsetSeconds: number\n overlapSeconds: number\n}\n\n/** Sliding-window Hamming distance over the two frame sequences. */\nfunction compareFrameSequences(\n a: VideoFramesFingerprint,\n b: VideoFramesFingerprint,\n): VideoFramesCompareDetails {\n const fps = Math.min(a.fps, b.fps)\n if (a.frames.length === 0 || b.frames.length === 0) {\n return {\n similarity: 0, distance: Number.NaN, bestOffsetSeconds: 0, overlapSeconds: 0,\n }\n }\n const minLen = Math.min(a.frames.length, b.frames.length)\n const maxOffset = Math.max(a.frames.length, b.frames.length) - 1\n let best: VideoFramesCompareDetails = {\n similarity: 0,\n distance: Number.NaN,\n bestOffsetSeconds: 0,\n overlapSeconds: 0,\n }\n const minOverlap = Math.max(2, Math.floor(minLen / 4))\n for (let offset = -maxOffset; offset <= maxOffset; offset++) {\n const aStart = Math.max(0, -offset)\n const bStart = Math.max(0, offset)\n const overlap = Math.min(a.frames.length - aStart, b.frames.length - bStart)\n if (overlap < minOverlap) continue\n let totalBits = 0\n let bitWidth = 0\n for (let i = 0; i < overlap; i++) {\n const ah = a.frames[aStart + i].hash\n const bh = b.frames[bStart + i].hash\n if (ah.length !== bh.length) continue\n totalBits += hammingHex(ah, bh)\n bitWidth += (ah.length / 2) * 8\n }\n if (bitWidth === 0) continue\n const similarity = 1 - totalBits / bitWidth\n if (similarity > best.similarity) {\n best = {\n similarity,\n distance: totalBits,\n bestOffsetSeconds: offset / fps,\n overlapSeconds: overlap / fps,\n }\n }\n }\n return best\n}\n\nfunction parseFps(options: Record<string, unknown> | undefined): number {\n const raw = options?.fps\n if (raw === undefined) return DEFAULT_FPS\n const value = typeof raw === 'string' ? Number.parseFloat(raw) : Number(raw)\n if (!Number.isFinite(value) || value <= 0 || value > 60) {\n const display = typeof raw === 'string' || typeof raw === 'number' ? String(raw) : '<non-scalar>'\n throw new RangeError(`Invalid --fps ${display}: expected a number in (0, 60].`)\n }\n return value\n}\n\nfunction parseFrameAlgorithm(options: Record<string, unknown> | undefined): FrameAlgorithmName {\n const raw = options?.frameAlgorithm\n if (raw === undefined) return DEFAULT_FRAME_ALGORITHM\n if (typeof raw !== 'string' || !(SUPPORTED_FRAME_ALGORITHMS as readonly string[]).includes(raw)) {\n const display = typeof raw === 'string' ? raw : `<${typeof raw}>`\n throw new RangeError(`Invalid --frame-algorithm ${display}: expected one of ${SUPPORTED_FRAME_ALGORITHMS.join(', ')}.`)\n }\n return raw as FrameAlgorithmName\n}\n\nexport const videoFramesAlgorithm: Algorithm = {\n name: 'video-frames',\n family: 'video',\n inputType: 'video',\n requires: [FFMPEG_BIN],\n async hash(input) {\n const fps = parseFps(input.options)\n const frameAlgorithm = parseFrameAlgorithm(input.options)\n const fp = input.path === undefined\n ? input.bytes === undefined\n ? null\n : await withTempfile(input.bytes, 'video.bin', async path => await fingerprintVideo(path, fps, frameAlgorithm))\n : await fingerprintVideo(input.path, fps, frameAlgorithm)\n if (fp === null) {\n throw new Error('video-frames requires bytes or a path.')\n }\n return JSON.stringify(fp)\n },\n async compare(a, b) {\n const fpA = parseVideoFramesHash(a)\n const fpB = parseVideoFramesHash(b)\n if (fpA.frameAlgorithm !== fpB.frameAlgorithm) {\n throw new Error(`Cannot compare video-frames hashes with different frame algorithms (${fpA.frameAlgorithm} vs ${fpB.frameAlgorithm}).`)\n }\n const result = compareFrameSequences(fpA, fpB)\n return {\n similarity: result.similarity,\n distance: Number.isFinite(result.distance) ? result.distance : undefined,\n metric: `frame-sequence-${fpA.frameAlgorithm}@${fpA.fps}fps`,\n }\n },\n}\n","/**\n * Population count for an 8-bit value (number of set bits).\n */\nfunction popcount8(byte: number): number {\n let count = 0\n let value = byte & 0xff\n while (value !== 0) {\n count += value & 1\n value >>>= 1\n }\n return count\n}\n\n/**\n * Hamming distance between two equal-length lowercase-hex strings.\n * Throws when the lengths differ.\n */\nexport function hammingHex(a: string, b: string): number {\n if (a.length !== b.length) {\n throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`)\n }\n if (a.length % 2 !== 0) {\n throw new Error(`Hash hex length must be even, got ${a.length}`)\n }\n let dist = 0\n for (let i = 0; i < a.length; i += 2) {\n const xa = Number.parseInt(a.slice(i, i + 2), 16)\n const xb = Number.parseInt(b.slice(i, i + 2), 16)\n if (Number.isNaN(xa) || Number.isNaN(xb)) {\n throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`)\n }\n dist += popcount8(xa ^ xb)\n }\n return dist\n}\n\n/**\n * Bit-length of an even-length hex string.\n */\nexport function bitLengthHex(hex: string): number {\n return (hex.length / 2) * 8\n}\n\n/**\n * Population count for a 32-bit unsigned value (number of set bits).\n * Uses the parallel-prefix bit trick.\n */\nexport function popcount32(value: number): number {\n let v = Math.trunc(value)\n v = v - ((v >>> 1) & 0x55_55_55_55)\n v = (v & 0x33_33_33_33) + ((v >>> 2) & 0x33_33_33_33)\n v = (v + (v >>> 4)) & 0x0f_0f_0f_0f\n return ((v * 0x01_01_01_01) >>> 24) & 0xff\n}\n","import { spawn } from 'node:child_process'\n\nexport interface RunBinaryOptions {\n binary: string\n args?: readonly string[]\n /** When provided, written to the child's stdin and stdin is closed. */\n stdin?: Buffer\n /** When true, the child's stdout is captured as a Buffer. Otherwise as utf8. */\n binaryOutput?: boolean\n /** Cap stdout capture at this many bytes. Default 64 MiB. */\n maxBytes?: number\n}\n\nexport interface RunBinaryResult {\n stdout: Buffer\n stderr: string\n exitCode: number\n}\n\n/**\n * Spawn a binary, optionally write to its stdin, and capture stdout/stderr.\n * Throws if the child exits non-zero.\n */\nexport async function runBinary(options: RunBinaryOptions): Promise<RunBinaryResult> {\n const maxBytes = options.maxBytes ?? 64 * 1024 * 1024\n return await new Promise((resolve, reject) => {\n const child = spawn(options.binary, [...(options.args ?? [])], { stdio: ['pipe', 'pipe', 'pipe'] })\n\n const stdoutChunks: Buffer[] = []\n let stdoutBytes = 0\n let stderr = ''\n let killedForOverflow = false\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutBytes += chunk.length\n if (stdoutBytes > maxBytes) {\n if (!killedForOverflow) {\n killedForOverflow = true\n child.kill('SIGKILL')\n }\n return\n }\n stdoutChunks.push(chunk)\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8')\n })\n\n child.on('error', err => reject(err))\n child.on('close', (code) => {\n if (killedForOverflow) {\n reject(new Error(`${options.binary} stdout exceeded ${maxBytes} bytes`))\n return\n }\n const exitCode = code ?? -1\n const stdout = Buffer.concat(stdoutChunks)\n if (exitCode !== 0) {\n const tail = stderr.trim().split(/\\r?\\n/).slice(-3).join('\\n')\n reject(new Error(`${options.binary} exited ${exitCode}${tail.length > 0 ? `: ${tail}` : ''}`))\n return\n }\n resolve({\n stdout, stderr, exitCode,\n })\n })\n\n if (options.stdin === undefined) {\n child.stdin.end()\n } else {\n child.stdin.end(options.stdin)\n }\n })\n}\n","import { spawn } from 'node:child_process'\n\nimport type { RequiredBinary } from '../algorithms/types.ts'\n\n/**\n * Resolve a binary name to its absolute path on the user's PATH.\n * Returns null if not found.\n */\nexport async function which(binary: string): Promise<string | null> {\n return await new Promise((resolve) => {\n const cmd = process.platform === 'win32' ? 'where' : 'command'\n const args = process.platform === 'win32' ? [binary] : ['-v', binary]\n const child = spawn(cmd, args, { shell: process.platform !== 'win32' })\n\n let stdout = ''\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8')\n })\n child.on('error', () => resolve(null))\n child.on('close', (code) => {\n if (code === 0) {\n const path = stdout.split(/\\r?\\n/).find(line => line.trim().length > 0)?.trim() ?? null\n resolve(path)\n } else {\n resolve(null)\n }\n })\n })\n}\n\n/**\n * Throw a clearly-actionable error when a required binary is missing.\n */\nexport async function requireBinary(req: RequiredBinary): Promise<string> {\n const path = await which(req.binary)\n if (path !== null) return path\n const lines = [`${req.binary} binary not found on PATH. Install with:`]\n if (req.install.brew !== undefined) lines.push(` macOS: brew install ${req.install.brew}`)\n if (req.install.apt !== undefined) lines.push(` Debian: apt install ${req.install.apt}`)\n if (req.install.choco !== undefined) lines.push(` Windows: choco install ${req.install.choco}`)\n throw new Error(lines.join('\\n'))\n}\n","import { randomBytes } from 'node:crypto'\nimport { rm, writeFile } from 'node:fs/promises'\nimport OS from 'node:os'\nimport PATH from 'node:path'\n\n/**\n * Write a buffer to a tempfile, run `fn` with its path, and unlink afterwards.\n * `extension` is included in the filename when provided (no leading dot).\n */\nexport async function withTempfile<T>(\n bytes: Buffer,\n extension: string | undefined,\n fn: (path: string) => Promise<T>,\n): Promise<T> {\n const ext = extension !== undefined && extension.length > 0 ? `.${extension}` : ''\n const path = PATH.join(OS.tmpdir(), `aries-hash-${randomBytes(8).toString('hex')}${ext}`)\n await writeFile(path, bytes)\n try {\n return await fn(path)\n } finally {\n await rm(path, { force: true })\n }\n}\n","import { createRequire } from 'node:module'\n\nimport sharp from 'sharp'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\n/**\n * pdq-wasm ships a CommonJS entry that uses `require` to load its bundled WASM file.\n * Aries is ESM, so we use `createRequire` to bridge — this picks the CJS dist via the\n * package's `exports.require` condition, which can resolve the relative WASM path.\n */\nconst require = createRequire(import.meta.url)\ninterface PDQHashResult { hash: Uint8Array; quality: number }\ninterface PDQModule {\n init(): Promise<void>\n hash(input: { data: Uint8Array; width: number; height: number; channels: 1 | 3 }): PDQHashResult\n toHex(hash: Uint8Array): string\n}\nconst { PDQ } = require('pdq-wasm') as { PDQ: PDQModule }\n\nlet initialized = false\nasync function ensureInit(): Promise<void> {\n if (initialized) return\n await PDQ.init()\n initialized = true\n}\n\n/**\n * Decode the input image to RGB raw bytes that pdq-wasm can consume directly.\n * sharp handles JPEG/PNG/WebP/AVIF/etc. transparently.\n */\nasync function toRgbRaw(source: Buffer | string): Promise<{ data: Uint8Array; width: number; height: number }> {\n const { data, info } = await sharp(source).removeAlpha().raw().toBuffer({ resolveWithObject: true })\n return {\n data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),\n width: info.width,\n height: info.height,\n }\n}\n\nexport const pdqAlgorithm: Algorithm = {\n name: 'pdq',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.path ?? input.bytes\n if (source === undefined) {\n throw new Error('pdq requires bytes or a path.')\n }\n await ensureInit()\n const rgb = await toRgbRaw(source)\n const result = PDQ.hash({\n data: rgb.data, width: rgb.width, height: rgb.height, channels: 3,\n })\n return PDQ.toHex(result.hash)\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","import phashLib from 'sharp-phash'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\nconst phash = phashLib as unknown as (image: Buffer | string) => Promise<string>\n\n/**\n * sharp-phash returns a 64-character '01' binary string. We pack it into 16-char hex\n * for parity with the other perceptual image algorithms.\n */\nfunction binaryToHex(bin: string): string {\n if (!/^[01]+$/.test(bin)) {\n throw new TypeError(`phash returned unexpected output: ${bin.slice(0, 20)}…`)\n }\n const padded = bin.padStart(Math.ceil(bin.length / 4) * 4, '0')\n let hex = ''\n for (let i = 0; i < padded.length; i += 4) {\n hex += Number.parseInt(padded.slice(i, i + 4), 2).toString(16)\n }\n return hex\n}\n\nexport const phashAlgorithm: Algorithm = {\n name: 'phash',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.path ?? input.bytes\n if (source === undefined) {\n throw new Error('phash requires bytes or a path.')\n }\n const bin = await phash(source)\n return binaryToHex(bin)\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n"],"mappings":"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","names":["randomBytes","rm","OS","PATH","spawn","require","PATH","OS","randomBytes","rm"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/actions/hash/algorithms/xyo.ts
|
|
2
|
+
import { ObjectHasher } from "@xyo-network/hash";
|
|
3
|
+
var xyoAlgorithm = {
|
|
4
|
+
name: "xyo",
|
|
5
|
+
family: "strict",
|
|
6
|
+
inputType: "bytes",
|
|
7
|
+
async hash(input) {
|
|
8
|
+
if (input.bytes === void 0) {
|
|
9
|
+
throw new Error("xyo requires loaded bytes.");
|
|
10
|
+
}
|
|
11
|
+
let parsed;
|
|
12
|
+
try {
|
|
13
|
+
parsed = JSON.parse(input.bytes.toString("utf8"));
|
|
14
|
+
} catch {
|
|
15
|
+
throw new Error("xyo requires valid JSON input.");
|
|
16
|
+
}
|
|
17
|
+
return await ObjectHasher.hash(parsed);
|
|
18
|
+
},
|
|
19
|
+
async compare(a, b) {
|
|
20
|
+
return {
|
|
21
|
+
similarity: a === b ? 1 : 0,
|
|
22
|
+
distance: a === b ? 0 : 1,
|
|
23
|
+
metric: "exact-match"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
xyoAlgorithm
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=xyo.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/hash/algorithms/xyo.ts"],"sourcesContent":["import { ObjectHasher } from '@xyo-network/hash'\n\nimport type { Algorithm } from './types.ts'\n\nexport const xyoAlgorithm: Algorithm = {\n name: 'xyo',\n family: 'strict',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('xyo requires loaded bytes.')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(input.bytes.toString('utf8'))\n } catch {\n throw new Error('xyo requires valid JSON input.')\n }\n return await ObjectHasher.hash(parsed as Record<string, unknown>)\n },\n async compare(a, b) {\n return {\n similarity: a === b ? 1 : 0,\n distance: a === b ? 0 : 1,\n metric: 'exact-match',\n }\n },\n}\n"],"mappings":";AAAA,SAAS,oBAAoB;AAItB,IAAM,eAA0B;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM,KAAK,OAAO;AAChB,QAAI,MAAM,UAAU,QAAW;AAC7B,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AACA,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,MAAM,MAAM,SAAS,MAAM,CAAC;AAAA,IAClD,QAAQ;AACN,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO,MAAM,aAAa,KAAK,MAAiC;AAAA,EAClE;AAAA,EACA,MAAM,QAAQ,GAAG,GAAG;AAClB,WAAO;AAAA,MACL,YAAY,MAAM,IAAI,IAAI;AAAA,MAC1B,UAAU,MAAM,IAAI,IAAI;AAAA,MACxB,QAAQ;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
|