wao 0.41.3 → 0.41.5
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/.babelrc-cjs +5 -0
- package/.babelrc-esm +5 -0
- package/.gitmodules +4 -0
- package/.prettierrc +6 -0
- package/README.md +90 -0
- package/app/.eslintrc.json +3 -0
- package/app/.mocharc.cjs +6 -0
- package/app/arweave.mjs +87 -0
- package/app/components/Footer.js +76 -0
- package/app/components/Global.js +1128 -0
- package/app/components/Header.js +306 -0
- package/app/components/Left.js +28 -0
- package/app/components/Logo.js +34 -0
- package/app/components/Middle.js +37 -0
- package/app/components/Sidebar.js +93 -0
- package/app/components/Tags.js +42 -0
- package/app/components/editor/Editor.js +322 -0
- package/app/components/editor/FilePath.js +42 -0
- package/app/components/editor/MonacoEditor.js +44 -0
- package/app/components/left/LeftMessages.js +85 -0
- package/app/components/left/LeftModules.js +86 -0
- package/app/components/left/LeftNetworks.js +438 -0
- package/app/components/left/LeftProcesses.js +98 -0
- package/app/components/left/LeftProjects.js +397 -0
- package/app/components/left/LeftTests.js +189 -0
- package/app/components/middle/MiddleBlocks.js +79 -0
- package/app/components/middle/MiddleEntity.js +16 -0
- package/app/components/middle/MiddleEntityAccount.js +264 -0
- package/app/components/middle/MiddleEntityAssignment.js +104 -0
- package/app/components/middle/MiddleEntityBlock.js +148 -0
- package/app/components/middle/MiddleEntityMessage.js +430 -0
- package/app/components/middle/MiddleEntityModule.js +183 -0
- package/app/components/middle/MiddleEntityProcess.js +323 -0
- package/app/components/middle/MiddleEntityTx.js +211 -0
- package/app/components/middle/MiddleMessages.js +87 -0
- package/app/components/middle/MiddleModules.js +89 -0
- package/app/components/middle/MiddleNetworks.js +516 -0
- package/app/components/middle/MiddleProcesses.js +87 -0
- package/app/components/middle/MiddleTests.js +134 -0
- package/app/components/modals/CreateFileModal.js +115 -0
- package/app/components/modals/CreateFolderModal.js +83 -0
- package/app/components/modals/CreateProjectModal.js +63 -0
- package/app/components/modals/FSModal.js +141 -0
- package/app/components/modals/ImportModal.js +105 -0
- package/app/components/modals/LaunchNetworkModal.js +95 -0
- package/app/components/modals/Modal.js +38 -0
- package/app/components/modals/ProxyModal.js +122 -0
- package/app/components/modals/RenameFileModal.js +95 -0
- package/app/components/styles/EditorScrollbarStyle.js +29 -0
- package/app/components/styles/EntityScrollbarStyle.js +29 -0
- package/app/components/styles/GlobalStyle.js +102 -0
- package/app/components/styles/XtermStyle.js +37 -0
- package/app/components/terminal/Terminal.js +132 -0
- package/app/components/terminal/Xterm.js +160 -0
- package/app/components/ui/avatar.jsx +49 -0
- package/app/components/ui/checkbox.jsx +17 -0
- package/app/components/ui/close-button.jsx +20 -0
- package/app/components/ui/color-mode.jsx +61 -0
- package/app/components/ui/dialog.jsx +54 -0
- package/app/components/ui/drawer.jsx +44 -0
- package/app/components/ui/field.jsx +22 -0
- package/app/components/ui/input-group.jsx +39 -0
- package/app/components/ui/popover.jsx +49 -0
- package/app/components/ui/provider.jsx +12 -0
- package/app/components/ui/radio.jsx +17 -0
- package/app/components/ui/slider.jsx +107 -0
- package/app/components/ui/toaster.jsx +69 -0
- package/app/components/ui/tooltip.jsx +35 -0
- package/app/index.js +10 -0
- package/app/jsconfig.json +7 -0
- package/app/lib/GithubCSS.js +1218 -0
- package/app/lib/addon-fit.js +72 -0
- package/app/lib/data.js +31 -0
- package/app/lib/github-markdown.css +1169 -0
- package/app/lib/global.js +1 -0
- package/app/lib/guide.js +82 -0
- package/app/lib/hub.js +109 -0
- package/app/lib/scripts.js +47 -0
- package/app/lib/store.js +34 -0
- package/app/lib/use.js +64 -0
- package/app/lib/utils.js +387 -0
- package/app/lib/webrtc.js +217 -0
- package/app/next.config.js +25 -0
- package/app/package.json +62 -0
- package/app/pages/404.js +9 -0
- package/app/pages/_app.js +10 -0
- package/app/pages/_document.js +14 -0
- package/app/pages/index.js +121 -0
- package/app/playwright.config.mjs +41 -0
- package/app/proxy.mjs +21 -0
- package/app/public/assets/cover.png +0 -0
- package/app/public/blueprints/apm.lua +91 -0
- package/app/public/blueprints/arena.lua +345 -0
- package/app/public/blueprints/arns.lua +318 -0
- package/app/public/blueprints/chat.lua +210 -0
- package/app/public/blueprints/chatroom.lua +56 -0
- package/app/public/blueprints/patch-legacy-reply.lua +13 -0
- package/app/public/blueprints/staking.lua +93 -0
- package/app/public/blueprints/token.lua +298 -0
- package/app/public/blueprints/voting.lua +45 -0
- package/app/public/favicon.ico +0 -0
- package/app/public/logo.png +0 -0
- package/cli-esm.js +55 -0
- package/cli.js +54 -0
- package/devnet/app/api.js +129 -0
- package/devnet/app/components/layout.js +89 -0
- package/devnet/app/components/pagination.js +144 -0
- package/devnet/app/components/search.js +159 -0
- package/devnet/app/components/table.js +124 -0
- package/devnet/app/components/tags.js +89 -0
- package/devnet/app/index.html +14 -0
- package/devnet/app/main.js +215 -0
- package/devnet/app/router.js +59 -0
- package/devnet/app/state.js +19 -0
- package/devnet/app/style.css +1606 -0
- package/devnet/app/utils.js +77 -0
- package/devnet/app/views/blocks.js +75 -0
- package/devnet/app/views/dashboard.js +127 -0
- package/devnet/app/views/entity.js +1473 -0
- package/devnet/app/views/messages.js +90 -0
- package/devnet/app/views/modules.js +165 -0
- package/devnet/app/views/processes.js +90 -0
- package/devnet/app/views/schedulers.js +90 -0
- package/devnet/app/views/transactions.js +88 -0
- package/devnet/migrations/0001_initial.sql +51 -0
- package/devnet/package.json +26 -0
- package/devnet/playwright.config.js +7 -0
- package/devnet/src/cu-worker.js +166 -0
- package/devnet/src/index.js +309 -0
- package/devnet/vite.config.js +17 -0
- package/devnet/vitest.config.js +10 -0
- package/devnet/wrangler-cu.toml +32 -0
- package/devnet/wrangler.toml +38 -0
- package/dhfs-tutorial-app/package.json +15 -0
- package/dist/esm/workspace/dashboard/public/favicon.png +0 -0
- package/dist/esm/workspace/src/counter.lua +14 -0
- package/dist/package.json +82 -0
- package/hb.sh +18 -0
- package/hbsig/.babelrc-cjs +5 -0
- package/hbsig/.babelrc-esm +5 -0
- package/hbsig/README.md +1 -0
- package/hbsig/dist/cjs/bin_to_str.js +44 -0
- package/hbsig/dist/cjs/collect-body-keys.js +470 -0
- package/hbsig/dist/cjs/commit.js +330 -0
- package/hbsig/dist/cjs/encode-array-item.js +110 -0
- package/hbsig/dist/cjs/encode-utils.js +242 -0
- package/hbsig/dist/cjs/encode.js +1365 -0
- package/hbsig/dist/cjs/erl_json.js +326 -0
- package/hbsig/dist/cjs/erl_str.js +1042 -0
- package/hbsig/dist/cjs/flat.js +279 -0
- package/hbsig/dist/cjs/http-message-signatures/httpbis.js +489 -0
- package/hbsig/dist/cjs/http-message-signatures/index.js +25 -0
- package/hbsig/dist/cjs/http-message-signatures/structured-header.js +129 -0
- package/hbsig/dist/cjs/httpsig.js +861 -0
- package/hbsig/dist/cjs/id.js +470 -0
- package/hbsig/dist/cjs/index.js +174 -0
- package/hbsig/dist/cjs/nocrypto.js +51 -0
- package/hbsig/dist/cjs/parser.js +201 -0
- package/hbsig/dist/cjs/send-utils.js +1231 -0
- package/hbsig/dist/cjs/send.js +211 -0
- package/hbsig/dist/cjs/signer-utils.js +494 -0
- package/hbsig/dist/cjs/signer.js +436 -0
- package/hbsig/dist/cjs/structured.js +515 -0
- package/hbsig/dist/cjs/test.js +12 -0
- package/hbsig/dist/cjs/utils.js +44 -0
- package/hbsig/dist/esm/bin_to_str.js +46 -0
- package/hbsig/dist/esm/collect-body-keys.js +436 -0
- package/hbsig/dist/esm/commit.js +219 -0
- package/hbsig/dist/esm/encode-array-item.js +112 -0
- package/hbsig/dist/esm/encode-utils.js +191 -0
- package/hbsig/dist/esm/encode.js +1256 -0
- package/hbsig/dist/esm/erl_json.js +292 -0
- package/hbsig/dist/esm/erl_str.js +1144 -0
- package/hbsig/dist/esm/flat.js +250 -0
- package/hbsig/dist/esm/http-message-signatures/httpbis.js +438 -0
- package/hbsig/dist/esm/http-message-signatures/index.js +4 -0
- package/hbsig/dist/esm/http-message-signatures/structured-header.js +105 -0
- package/hbsig/dist/esm/httpsig.js +866 -0
- package/hbsig/dist/esm/id.js +459 -0
- package/hbsig/dist/esm/index.js +13 -0
- package/hbsig/dist/esm/nocrypto.js +4 -0
- package/hbsig/dist/esm/package.json +3 -0
- package/hbsig/dist/esm/parser.js +171 -0
- package/hbsig/dist/esm/send-utils.js +1132 -0
- package/hbsig/dist/esm/send.js +142 -0
- package/hbsig/dist/esm/signer-utils.js +375 -0
- package/hbsig/dist/esm/signer.js +312 -0
- package/hbsig/dist/esm/structured.js +496 -0
- package/hbsig/dist/esm/test.js +2 -0
- package/hbsig/dist/esm/utils.js +29 -0
- package/hbsig/dist/package.json +39 -0
- package/hbsig/make.js +36 -0
- package/hbsig/package.json +39 -0
- package/hbsig/src/bin_to_str.js +46 -0
- package/hbsig/src/collect-body-keys.js +436 -0
- package/hbsig/src/commit.js +219 -0
- package/hbsig/src/encode-array-item.js +112 -0
- package/hbsig/src/encode-utils.js +191 -0
- package/hbsig/src/encode.js +1256 -0
- package/hbsig/src/erl_json.js +292 -0
- package/hbsig/src/erl_str.js +1144 -0
- package/hbsig/src/flat.js +250 -0
- package/hbsig/src/http-message-signatures/httpbis.js +438 -0
- package/hbsig/src/http-message-signatures/index.js +4 -0
- package/hbsig/src/http-message-signatures/structured-header.js +105 -0
- package/hbsig/src/httpsig.js +866 -0
- package/hbsig/src/id.js +459 -0
- package/hbsig/src/index.js +13 -0
- package/hbsig/src/nocrypto.js +4 -0
- package/hbsig/src/parser.js +171 -0
- package/hbsig/src/send-utils.js +1132 -0
- package/hbsig/src/send.js +142 -0
- package/hbsig/src/signer-utils.js +375 -0
- package/hbsig/src/signer.js +312 -0
- package/hbsig/src/structured.js +496 -0
- package/hbsig/src/test.js +2 -0
- package/hbsig/src/utils.js +29 -0
- package/lp/index.html +25 -0
- package/lp/package.json +19 -0
- package/lp/public/cover.png +0 -0
- package/lp/public/favicon.ico +0 -0
- package/lp/public/favicon.png +0 -0
- package/lp/public/images/book.jpg +0 -0
- package/lp/public/images/dashboard.png +0 -0
- package/lp/public/images/devnet.png +0 -0
- package/lp/public/images/hero-bg.png +0 -0
- package/lp/public/images/hyperadd.png +0 -0
- package/lp/public/images/message-flow.png +0 -0
- package/lp/public/images/mobile.png +0 -0
- package/lp/public/images/og-cover.png +0 -0
- package/lp/public/images/scan.png +0 -0
- package/lp/public/images/wao-hub.png +0 -0
- package/lp/public/images/wao-web.png +0 -0
- package/lp/public/logo.png +0 -0
- package/lp/src/App.jsx +29 -0
- package/lp/src/components/CodeBlock.jsx +37 -0
- package/lp/src/components/CodeBlock.module.css +89 -0
- package/lp/src/components/Footer.jsx +22 -0
- package/lp/src/components/Footer.module.css +60 -0
- package/lp/src/components/Nav.jsx +80 -0
- package/lp/src/components/Nav.module.css +177 -0
- package/lp/src/components/SectionWrapper.jsx +15 -0
- package/lp/src/hooks/useReveal.js +25 -0
- package/lp/src/hooks/useScrolled.js +14 -0
- package/lp/src/main.jsx +10 -0
- package/lp/src/sections/Book.jsx +60 -0
- package/lp/src/sections/Book.module.css +204 -0
- package/lp/src/sections/Browser.jsx +46 -0
- package/lp/src/sections/Browser.module.css +67 -0
- package/lp/src/sections/Devnet.jsx +55 -0
- package/lp/src/sections/Devnet.module.css +136 -0
- package/lp/src/sections/GetStarted.jsx +51 -0
- package/lp/src/sections/GetStarted.module.css +128 -0
- package/lp/src/sections/Hero.jsx +67 -0
- package/lp/src/sections/Hero.module.css +202 -0
- package/lp/src/sections/HyperADD.jsx +46 -0
- package/lp/src/sections/HyperADD.module.css +113 -0
- package/lp/src/sections/SDK.jsx +90 -0
- package/lp/src/sections/SDK.module.css +122 -0
- package/lp/src/sections/Testing.jsx +47 -0
- package/lp/src/sections/Testing.module.css +124 -0
- package/lp/src/sections/Vision.jsx +93 -0
- package/lp/src/sections/Vision.module.css +147 -0
- package/lp/src/styles/globals.css +285 -0
- package/lp/src/utils/scrollTo.js +4 -0
- package/lp/vite.config.js +7 -0
- package/make.js +39 -0
- package/package.json +17 -12
- package/patches/@permaweb+ao-loader+0.0.44.patch +64 -0
- package/plan.md +435 -0
- package/rebar.lock +1 -0
- package/src/accounts-web.js +128 -0
- package/src/accounts.js +124 -0
- package/src/adaptor-base.js +622 -0
- package/src/adaptor-cf.js +11 -0
- package/src/adaptor-web.js +11 -0
- package/src/adaptor.js +10 -0
- package/src/ao-loader.js +30660 -0
- package/src/ao.js +1173 -0
- package/src/aoconnect-base.js +1098 -0
- package/src/aoconnect-cf.js +9 -0
- package/src/aoconnect-web.js +8 -0
- package/src/aoconnect.js +8 -0
- package/src/aos_wamr.js +1 -0
- package/src/ar-remote.js +87 -0
- package/src/ar.js +276 -0
- package/src/armem-base.js +529 -0
- package/src/armem-cf.js +67 -0
- package/src/armem-web.js +19 -0
- package/src/armem.js +26 -0
- package/src/bao.js +141 -0
- package/src/bar.js +366 -0
- package/src/build.js +7 -0
- package/src/bundler.js +119 -0
- package/src/car.js +10 -0
- package/src/cf-env.js +29 -0
- package/src/cf.js +11 -0
- package/src/cli.js +561 -0
- package/src/compress.js +112 -0
- package/src/create.js +415 -0
- package/src/devs.js +86 -0
- package/src/dirname.js +1 -0
- package/src/dodb.js +26 -0
- package/src/erl_json.js +289 -0
- package/src/erl_str.js +1139 -0
- package/src/gql.js +229 -0
- package/src/hb.js +967 -0
- package/src/helpers.js +203 -0
- package/src/http.js +619 -0
- package/src/hub/bundler.js +123 -0
- package/src/hub/cu.js +74 -0
- package/src/hub/fs.js +157 -0
- package/src/hub/index.js +85 -0
- package/src/hub/utils.js +64 -0
- package/src/hub/ws-proxy.js +67 -0
- package/src/hyper-aos.js +1 -0
- package/src/hyperbeam-server.js +21 -0
- package/src/hyperbeam.js +585 -0
- package/src/index.js +5 -0
- package/src/keygen.js +47 -0
- package/src/lfdb.js +67 -0
- package/src/lua/aos.wasm +0 -0
- package/src/lua/aos2_0_1.js +1 -0
- package/src/lua/aos2_0_1.wasm +0 -0
- package/src/lua/aos2_0_3.js +1 -0
- package/src/lua/aos2_0_3.wasm +0 -0
- package/src/lua/aos2_0_4_32.js +1 -0
- package/src/lua/aos2_0_4_32.wasm +0 -0
- package/src/lua/aos2_0_6.wasm +0 -0
- package/src/lua/apm.lua +61 -0
- package/src/lua/llama.wasm +0 -0
- package/src/lua/process.wasm +0 -0
- package/src/lua/sqlite.js +1 -0
- package/src/lua/sqlite.wasm +0 -0
- package/src/lua/weavedb_mock.lua +44 -0
- package/src/lua/weavedrive.lua +53 -0
- package/src/run.js +25 -0
- package/src/server.js +173 -0
- package/src/storage-multi.js +183 -0
- package/src/tao.js +12 -0
- package/src/tar.js +10 -0
- package/src/test.js +42 -0
- package/src/tgql-d1.js +407 -0
- package/src/tgql.js +310 -0
- package/src/toerl.js +162 -0
- package/src/utils.js +777 -0
- package/src/wao.js +29 -0
- package/src/waosm/README.md +81 -0
- package/src/waosm/waosm.d.ts +40 -0
- package/src/waosm/waosm.js +240 -0
- package/src/waosm/waosm_bg.wasm +0 -0
- package/src/waosm/waosm_bg.wasm.d.ts +8 -0
- package/src/waosm-node/README.md +81 -0
- package/src/waosm-node/waosm.d.ts +8 -0
- package/src/waosm-node/waosm.js +4 -0
- package/src/waosm-node/waosm_bg.js +147 -0
- package/src/waosm-node/waosm_bg.wasm +0 -0
- package/src/waosm-node/waosm_bg.wasm.d.ts +8 -0
- package/src/waosm-node/waosm_bg.wasm.js +14 -0
- package/src/waosm-node.js +9 -0
- package/src/war.js +10 -0
- package/src/weavedrive.js +376 -0
- package/src/web.js +11 -0
- package/src/workspace/.mcp.json +8 -0
- package/src/workspace/CLAUDE.md +258 -0
- package/src/workspace/README.md +85 -0
- package/src/workspace/dashboard/index.html +163 -0
- package/src/workspace/dashboard/package.json +18 -0
- package/src/workspace/dashboard/public/favicon.ico +0 -0
- package/src/workspace/dashboard/public/favicon.png +0 -0
- package/src/workspace/dashboard/server.js +224 -0
- package/src/workspace/dashboard/src/App.jsx +2350 -0
- package/{cjs/workspace/frontend → src/workspace/dashboard}/vite.config.js +6 -0
- package/src/workspace/package.json +18 -0
- package/src/workspace/src/counter.lua +14 -0
- package/tsconfig.json +18 -0
- package/types/index.d.ts +329 -0
- package/waollama/.eslintrc.json +3 -0
- package/waollama/README.md +19 -0
- package/waollama/arweave.mjs +87 -0
- package/waollama/components/ui/avatar.jsx +49 -0
- package/waollama/components/ui/checkbox.jsx +17 -0
- package/waollama/components/ui/close-button.jsx +20 -0
- package/waollama/components/ui/color-mode.jsx +61 -0
- package/waollama/components/ui/dialog.jsx +54 -0
- package/waollama/components/ui/drawer.jsx +44 -0
- package/waollama/components/ui/field.jsx +22 -0
- package/waollama/components/ui/input-group.jsx +39 -0
- package/waollama/components/ui/popover.jsx +49 -0
- package/waollama/components/ui/provider.jsx +12 -0
- package/waollama/components/ui/radio.jsx +17 -0
- package/waollama/components/ui/slider.jsx +107 -0
- package/waollama/components/ui/tooltip.jsx +35 -0
- package/waollama/index.js +10 -0
- package/waollama/jsconfig.json +7 -0
- package/waollama/lib/ao-loader.js +30654 -0
- package/waollama/lib/client.js +1 -0
- package/waollama/lib/wasm.js +1 -0
- package/waollama/next.config.js +25 -0
- package/waollama/package.json +43 -0
- package/waollama/pages/404.js +9 -0
- package/waollama/pages/_app.js +9 -0
- package/waollama/pages/_document.js +14 -0
- package/waollama/pages/index.js +212 -0
- package/waollama/playwright.config.js +31 -0
- package/waollama/proxy.mjs +21 -0
- package/waollama/public/favicon.ico +0 -0
- package/waollama/public/human.png +0 -0
- package/waollama/public/llama.png +0 -0
- package/waosm/Cargo.toml +11 -0
- package/waosm/README.md +81 -0
- package/waosm/compress.js +112 -0
- package/waosm/make.js +33 -0
- package/waosm/package.json +10 -0
- package/waosm/src/lib.rs +180 -0
- package/waosm/test.js +16 -0
- package/cjs/workspace/.claude/agents/builder.md +0 -99
- package/cjs/workspace/.claude/agents/device-builder.md +0 -86
- package/cjs/workspace/.claude/agents/tester.md +0 -90
- package/cjs/workspace/.claude/mcp/dashboard/server.js +0 -128
- package/cjs/workspace/.claude/rules/deploy.md +0 -45
- package/cjs/workspace/.claude/rules/frontend.md +0 -69
- package/cjs/workspace/.claude/rules/hyperbeam.md +0 -104
- package/cjs/workspace/.claude/rules/lua.md +0 -108
- package/cjs/workspace/.claude/rules/testing.md +0 -257
- package/cjs/workspace/.claude/settings.json +0 -109
- package/cjs/workspace/.claude/skills/build/SKILL.md +0 -214
- package/cjs/workspace/.claude/skills/build-aos/SKILL.md +0 -129
- package/cjs/workspace/.claude/skills/build-device/SKILL.md +0 -192
- package/cjs/workspace/.claude/skills/build-frontend/SKILL.md +0 -134
- package/cjs/workspace/.claude/skills/build-module/SKILL.md +0 -281
- package/cjs/workspace/.claude/skills/create-aos/SKILL.md +0 -63
- package/cjs/workspace/.claude/skills/create-device/SKILL.md +0 -87
- package/cjs/workspace/.claude/skills/create-module/SKILL.md +0 -162
- package/cjs/workspace/.claude/skills/debug/SKILL.md +0 -57
- package/cjs/workspace/.claude/skills/deploy/SKILL.md +0 -85
- package/cjs/workspace/.claude/skills/dev/SKILL.md +0 -32
- package/cjs/workspace/.claude/skills/plan/SKILL.md +0 -176
- package/cjs/workspace/.claude/skills/readme/SKILL.md +0 -186
- package/cjs/workspace/.claude/skills/report/SKILL.md +0 -49
- package/cjs/workspace/.claude/skills/team/SKILL.md +0 -101
- package/cjs/workspace/.claude/skills/test/SKILL.md +0 -56
- package/cjs/workspace/.claude/skills/test-device/SKILL.md +0 -114
- package/cjs/workspace/.claude/skills/test-e2e/SKILL.md +0 -103
- package/cjs/workspace/.claude/skills/test-hb/SKILL.md +0 -76
- package/cjs/workspace/.claude/skills/validate/SKILL.md +0 -96
- package/cjs/workspace/.claude/skills/validate/scripts/check-lua.sh +0 -41
- package/cjs/workspace/docs/aos-lua.md +0 -428
- package/cjs/workspace/docs/debug.md +0 -230
- package/cjs/workspace/docs/hyperbeam-dev.md +0 -606
- package/cjs/workspace/docs/hyperbeam-devices.md +0 -618
- package/cjs/workspace/docs/wao-sdk.md +0 -807
- package/cjs/workspace/frontend/e2e/.gitkeep +0 -0
- package/cjs/workspace/frontend/index.html +0 -12
- package/cjs/workspace/frontend/package.json +0 -24
- package/cjs/workspace/frontend/playwright.config.js +0 -10
- package/cjs/workspace/frontend/src/App.jsx +0 -24
- package/cjs/workspace/frontend/test/.gitkeep +0 -0
- package/cjs/workspace/frontend/vitest.config.js +0 -10
- package/cjs/workspace/scripts/deploy.js +0 -140
- package/cjs/workspace/scripts/keygen.js +0 -52
- package/cjs/workspace/test/aos.test.js +0 -98
- package/cjs/workspace/test/hyperbeam.test.js +0 -80
- package/esm/compiler/native +0 -0
- package/esm/workspace/.claude/agents/builder.md +0 -99
- package/esm/workspace/.claude/agents/device-builder.md +0 -86
- package/esm/workspace/.claude/agents/tester.md +0 -90
- package/esm/workspace/.claude/mcp/dashboard/server.js +0 -128
- package/esm/workspace/.claude/rules/deploy.md +0 -45
- package/esm/workspace/.claude/rules/frontend.md +0 -69
- package/esm/workspace/.claude/rules/hyperbeam.md +0 -104
- package/esm/workspace/.claude/rules/lua.md +0 -108
- package/esm/workspace/.claude/rules/testing.md +0 -257
- package/esm/workspace/.claude/settings.json +0 -109
- package/esm/workspace/.claude/skills/build/SKILL.md +0 -214
- package/esm/workspace/.claude/skills/build-aos/SKILL.md +0 -129
- package/esm/workspace/.claude/skills/build-device/SKILL.md +0 -192
- package/esm/workspace/.claude/skills/build-frontend/SKILL.md +0 -134
- package/esm/workspace/.claude/skills/build-module/SKILL.md +0 -281
- package/esm/workspace/.claude/skills/create-aos/SKILL.md +0 -63
- package/esm/workspace/.claude/skills/create-device/SKILL.md +0 -87
- package/esm/workspace/.claude/skills/create-module/SKILL.md +0 -162
- package/esm/workspace/.claude/skills/debug/SKILL.md +0 -57
- package/esm/workspace/.claude/skills/deploy/SKILL.md +0 -85
- package/esm/workspace/.claude/skills/dev/SKILL.md +0 -32
- package/esm/workspace/.claude/skills/plan/SKILL.md +0 -176
- package/esm/workspace/.claude/skills/readme/SKILL.md +0 -186
- package/esm/workspace/.claude/skills/report/SKILL.md +0 -49
- package/esm/workspace/.claude/skills/team/SKILL.md +0 -101
- package/esm/workspace/.claude/skills/test/SKILL.md +0 -56
- package/esm/workspace/.claude/skills/test-device/SKILL.md +0 -114
- package/esm/workspace/.claude/skills/test-e2e/SKILL.md +0 -103
- package/esm/workspace/.claude/skills/test-hb/SKILL.md +0 -76
- package/esm/workspace/.claude/skills/validate/SKILL.md +0 -96
- package/esm/workspace/.claude/skills/validate/scripts/check-lua.sh +0 -41
- package/esm/workspace/docs/aos-lua.md +0 -428
- package/esm/workspace/docs/debug.md +0 -230
- package/esm/workspace/docs/hyperbeam-dev.md +0 -606
- package/esm/workspace/docs/hyperbeam-devices.md +0 -618
- package/esm/workspace/docs/wao-sdk.md +0 -807
- package/esm/workspace/frontend/e2e/.gitkeep +0 -0
- package/esm/workspace/frontend/index.html +0 -12
- package/esm/workspace/frontend/package.json +0 -24
- package/esm/workspace/frontend/playwright.config.js +0 -10
- package/esm/workspace/frontend/src/App.jsx +0 -24
- package/esm/workspace/frontend/src/main.jsx +0 -9
- package/esm/workspace/frontend/test/.gitkeep +0 -0
- package/esm/workspace/frontend/vite.config.js +0 -6
- package/esm/workspace/frontend/vitest.config.js +0 -10
- package/esm/workspace/scripts/deploy.js +0 -140
- package/esm/workspace/scripts/keygen.js +0 -52
- package/esm/workspace/test/aos.test.js +0 -98
- package/esm/workspace/test/hyperbeam.test.js +0 -80
- /package/{cjs/workspace/dashboard/public → devnet/app}/favicon.ico +0 -0
- /package/{cjs/workspace → dhfs-tutorial-app}/src/counter.lua +0 -0
- /package/{cjs → dist/cjs}/accounts-web.js +0 -0
- /package/{cjs → dist/cjs}/accounts.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-base.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-cf.js +0 -0
- /package/{cjs → dist/cjs}/adaptor-web.js +0 -0
- /package/{cjs → dist/cjs}/adaptor.js +0 -0
- /package/{cjs → dist/cjs}/ao-loader.js +0 -0
- /package/{cjs → dist/cjs}/ao.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-base.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-cf.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect-web.js +0 -0
- /package/{cjs → dist/cjs}/aoconnect.js +0 -0
- /package/{cjs → dist/cjs}/aos_wamr.js +0 -0
- /package/{cjs → dist/cjs}/ar-remote.js +0 -0
- /package/{cjs → dist/cjs}/ar.js +0 -0
- /package/{cjs → dist/cjs}/armem-base.js +0 -0
- /package/{cjs → dist/cjs}/armem-cf.js +0 -0
- /package/{cjs → dist/cjs}/armem-web.js +0 -0
- /package/{cjs → dist/cjs}/armem.js +0 -0
- /package/{cjs → dist/cjs}/bao.js +0 -0
- /package/{cjs → dist/cjs}/bar.js +0 -0
- /package/{cjs → dist/cjs}/build.js +0 -0
- /package/{cjs → dist/cjs}/bundler.js +0 -0
- /package/{cjs → dist/cjs}/car.js +0 -0
- /package/{cjs → dist/cjs}/cf-env.js +0 -0
- /package/{cjs → dist/cjs}/cf.js +0 -0
- /package/{cjs → dist/cjs}/cli.js +0 -0
- /package/{cjs → dist/cjs}/compress.js +0 -0
- /package/{cjs → dist/cjs}/create.js +0 -0
- /package/{cjs → dist/cjs}/devs.js +0 -0
- /package/{cjs → dist/cjs}/dirname.js +0 -0
- /package/{cjs → dist/cjs}/dodb.js +0 -0
- /package/{cjs → dist/cjs}/erl_json.js +0 -0
- /package/{cjs → dist/cjs}/erl_str.js +0 -0
- /package/{cjs → dist/cjs}/gql.js +0 -0
- /package/{cjs → dist/cjs}/hb.js +0 -0
- /package/{cjs → dist/cjs}/helpers.js +0 -0
- /package/{cjs → dist/cjs}/http.js +0 -0
- /package/{cjs → dist/cjs}/hub/bundler.js +0 -0
- /package/{cjs → dist/cjs}/hub/cu.js +0 -0
- /package/{cjs → dist/cjs}/hub/fs.js +0 -0
- /package/{cjs → dist/cjs}/hub/index.js +0 -0
- /package/{cjs → dist/cjs}/hub/utils.js +0 -0
- /package/{cjs → dist/cjs}/hub/ws-proxy.js +0 -0
- /package/{cjs → dist/cjs}/hyper-aos.js +0 -0
- /package/{cjs → dist/cjs}/hyperbeam-server.js +0 -0
- /package/{cjs → dist/cjs}/hyperbeam.js +0 -0
- /package/{cjs → dist/cjs}/index.js +0 -0
- /package/{cjs → dist/cjs}/keygen.js +0 -0
- /package/{cjs → dist/cjs}/lfdb.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_1.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_1.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_3.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_3.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_4_32.js +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_4_32.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/aos2_0_6.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/apm.lua +0 -0
- /package/{cjs → dist/cjs}/lua/llama.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/process.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/sqlite.js +0 -0
- /package/{cjs → dist/cjs}/lua/sqlite.wasm +0 -0
- /package/{cjs → dist/cjs}/lua/weavedb_mock.lua +0 -0
- /package/{cjs → dist/cjs}/lua/weavedrive.lua +0 -0
- /package/{cjs → dist/cjs}/run.js +0 -0
- /package/{cjs → dist/cjs}/server.js +0 -0
- /package/{cjs → dist/cjs}/storage-multi.js +0 -0
- /package/{cjs → dist/cjs}/tao.js +0 -0
- /package/{cjs → dist/cjs}/tar.js +0 -0
- /package/{cjs → dist/cjs}/test.js +0 -0
- /package/{cjs → dist/cjs}/tgql-d1.js +0 -0
- /package/{cjs → dist/cjs}/tgql.js +0 -0
- /package/{cjs → dist/cjs}/toerl.js +0 -0
- /package/{cjs → dist/cjs}/utils.js +0 -0
- /package/{cjs → dist/cjs}/wao.js +0 -0
- /package/{cjs → dist/cjs}/waosm/waosm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.wasm +0 -0
- /package/{cjs → dist/cjs}/waosm-node/waosm_bg.wasm.js +0 -0
- /package/{cjs → dist/cjs}/waosm-node.js +0 -0
- /package/{cjs → dist/cjs}/war.js +0 -0
- /package/{cjs → dist/cjs}/weavedrive.js +0 -0
- /package/{cjs → dist/cjs}/web.js +0 -0
- /package/{cjs → dist/cjs}/workspace/.mcp.json +0 -0
- /package/{cjs → dist/cjs}/workspace/CLAUDE.md +0 -0
- /package/{cjs → dist/cjs}/workspace/README.md +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/index.html +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/package.json +0 -0
- /package/{esm → dist/cjs}/workspace/dashboard/public/favicon.ico +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/public/favicon.png +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/server.js +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/src/App.jsx +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/src/main.jsx +0 -0
- /package/{cjs → dist/cjs}/workspace/dashboard/vite.config.js +0 -0
- /package/{cjs → dist/cjs}/workspace/package.json +0 -0
- /package/{esm → dist/cjs}/workspace/src/counter.lua +0 -0
- /package/{esm → dist/esm}/accounts-web.js +0 -0
- /package/{esm → dist/esm}/accounts.js +0 -0
- /package/{esm → dist/esm}/adaptor-base.js +0 -0
- /package/{esm → dist/esm}/adaptor-cf.js +0 -0
- /package/{esm → dist/esm}/adaptor-web.js +0 -0
- /package/{esm → dist/esm}/adaptor.js +0 -0
- /package/{esm → dist/esm}/ao-loader.js +0 -0
- /package/{esm → dist/esm}/ao.js +0 -0
- /package/{esm → dist/esm}/aoconnect-base.js +0 -0
- /package/{esm → dist/esm}/aoconnect-cf.js +0 -0
- /package/{esm → dist/esm}/aoconnect-web.js +0 -0
- /package/{esm → dist/esm}/aoconnect.js +0 -0
- /package/{esm → dist/esm}/aos_wamr.js +0 -0
- /package/{esm → dist/esm}/ar-remote.js +0 -0
- /package/{esm → dist/esm}/ar.js +0 -0
- /package/{esm → dist/esm}/armem-base.js +0 -0
- /package/{esm → dist/esm}/armem-cf.js +0 -0
- /package/{esm → dist/esm}/armem-web.js +0 -0
- /package/{esm → dist/esm}/armem.js +0 -0
- /package/{esm → dist/esm}/bao.js +0 -0
- /package/{esm → dist/esm}/bar.js +0 -0
- /package/{esm → dist/esm}/build.js +0 -0
- /package/{esm → dist/esm}/bundler.js +0 -0
- /package/{esm → dist/esm}/car.js +0 -0
- /package/{esm → dist/esm}/cf-env.js +0 -0
- /package/{esm → dist/esm}/cf.js +0 -0
- /package/{esm → dist/esm}/cli.js +0 -0
- /package/{esm → dist/esm}/compress.js +0 -0
- /package/{esm → dist/esm}/create.js +0 -0
- /package/{esm → dist/esm}/devs.js +0 -0
- /package/{esm → dist/esm}/dirname.js +0 -0
- /package/{esm → dist/esm}/dodb.js +0 -0
- /package/{esm → dist/esm}/erl_json.js +0 -0
- /package/{esm → dist/esm}/erl_str.js +0 -0
- /package/{esm → dist/esm}/gql.js +0 -0
- /package/{esm → dist/esm}/hb.js +0 -0
- /package/{esm → dist/esm}/helpers.js +0 -0
- /package/{esm → dist/esm}/http.js +0 -0
- /package/{esm → dist/esm}/hub/bundler.js +0 -0
- /package/{esm → dist/esm}/hub/cu.js +0 -0
- /package/{esm → dist/esm}/hub/fs.js +0 -0
- /package/{esm → dist/esm}/hub/index.js +0 -0
- /package/{esm → dist/esm}/hub/utils.js +0 -0
- /package/{esm → dist/esm}/hub/ws-proxy.js +0 -0
- /package/{esm → dist/esm}/hyper-aos.js +0 -0
- /package/{esm → dist/esm}/hyperbeam-server.js +0 -0
- /package/{esm → dist/esm}/hyperbeam.js +0 -0
- /package/{esm → dist/esm}/index.js +0 -0
- /package/{esm → dist/esm}/keygen.js +0 -0
- /package/{esm → dist/esm}/lfdb.js +0 -0
- /package/{esm → dist/esm}/lua/aos.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_1.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_1.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_3.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_3.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_4_32.js +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_4_32.wasm +0 -0
- /package/{esm → dist/esm}/lua/aos2_0_6.wasm +0 -0
- /package/{esm → dist/esm}/lua/apm.lua +0 -0
- /package/{esm → dist/esm}/lua/llama.wasm +0 -0
- /package/{esm → dist/esm}/lua/process.wasm +0 -0
- /package/{esm → dist/esm}/lua/sqlite.js +0 -0
- /package/{esm → dist/esm}/lua/sqlite.wasm +0 -0
- /package/{esm → dist/esm}/lua/weavedb_mock.lua +0 -0
- /package/{esm → dist/esm}/lua/weavedrive.lua +0 -0
- /package/{esm → dist/esm}/package.json +0 -0
- /package/{esm → dist/esm}/run.js +0 -0
- /package/{esm → dist/esm}/server.js +0 -0
- /package/{esm → dist/esm}/storage-multi.js +0 -0
- /package/{esm → dist/esm}/tao.js +0 -0
- /package/{esm → dist/esm}/tar.js +0 -0
- /package/{esm → dist/esm}/test.js +0 -0
- /package/{esm → dist/esm}/tgql-d1.js +0 -0
- /package/{esm → dist/esm}/tgql.js +0 -0
- /package/{esm → dist/esm}/toerl.js +0 -0
- /package/{esm → dist/esm}/utils.js +0 -0
- /package/{esm → dist/esm}/wao.js +0 -0
- /package/{esm → dist/esm}/waosm/README.md +0 -0
- /package/{esm → dist/esm}/waosm/waosm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm/waosm.js +0 -0
- /package/{esm → dist/esm}/waosm/waosm_bg.wasm +0 -0
- /package/{esm → dist/esm}/waosm/waosm_bg.wasm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/README.md +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm.js +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.js +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm.d.ts +0 -0
- /package/{esm → dist/esm}/waosm-node/waosm_bg.wasm.js +0 -0
- /package/{esm → dist/esm}/waosm-node.js +0 -0
- /package/{esm → dist/esm}/war.js +0 -0
- /package/{esm → dist/esm}/weavedrive.js +0 -0
- /package/{esm → dist/esm}/web.js +0 -0
- /package/{esm → dist/esm}/workspace/.mcp.json +0 -0
- /package/{esm → dist/esm}/workspace/CLAUDE.md +0 -0
- /package/{esm → dist/esm}/workspace/README.md +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/index.html +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/package.json +0 -0
- /package/{esm/workspace/dashboard/public/favicon.png → dist/esm/workspace/dashboard/public/favicon.ico} +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/server.js +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/src/App.jsx +0 -0
- /package/{cjs/workspace/frontend → dist/esm/workspace/dashboard}/src/main.jsx +0 -0
- /package/{esm → dist/esm}/workspace/dashboard/vite.config.js +0 -0
- /package/{esm → dist/esm}/workspace/package.json +0 -0
- /package/{postinstall.cjs → dist/postinstall.cjs} +0 -0
- /package/{esm → src}/workspace/dashboard/src/main.jsx +0 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasNonAscii,
|
|
3
|
+
sha256,
|
|
4
|
+
hasNewline,
|
|
5
|
+
isBytes,
|
|
6
|
+
isPojo,
|
|
7
|
+
} from "./encode-utils.js"
|
|
8
|
+
|
|
9
|
+
// Helper functions
|
|
10
|
+
const isEmpty = value => {
|
|
11
|
+
if (typeof value === "string") return value === ""
|
|
12
|
+
if (Array.isArray(value)) return value.length === 0
|
|
13
|
+
if (isPojo(value)) return Object.keys(value).length === 0
|
|
14
|
+
if (isBytes(value)) return value.length === 0 || value.byteLength === 0
|
|
15
|
+
return false
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const hasOnlyEmptyValues = obj => {
|
|
19
|
+
if (!isPojo(obj)) return false
|
|
20
|
+
return Object.values(obj).every(
|
|
21
|
+
v =>
|
|
22
|
+
(typeof v === "string" && v === "") ||
|
|
23
|
+
(Array.isArray(v) && v.length === 0) ||
|
|
24
|
+
(isPojo(v) && Object.keys(v).length === 0)
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const isSimpleValue = value => {
|
|
29
|
+
return (
|
|
30
|
+
typeof value === "string" ||
|
|
31
|
+
typeof value === "number" ||
|
|
32
|
+
typeof value === "boolean" ||
|
|
33
|
+
value === null ||
|
|
34
|
+
value === undefined ||
|
|
35
|
+
typeof value === "symbol"
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const getValueByPath = (obj, path) => {
|
|
40
|
+
const parts = path.split("/")
|
|
41
|
+
let value = obj
|
|
42
|
+
for (const part of parts) {
|
|
43
|
+
if (/^\d+$/.test(part)) {
|
|
44
|
+
value = value[parseInt(part) - 1]
|
|
45
|
+
} else {
|
|
46
|
+
value = value[part]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return value
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const canArrayBeInHeader = array => {
|
|
53
|
+
// Empty arrays can be in headers
|
|
54
|
+
if (array.length === 0) return true
|
|
55
|
+
|
|
56
|
+
// Arrays with objects must go to body
|
|
57
|
+
if (array.some(item => isPojo(item))) return false
|
|
58
|
+
|
|
59
|
+
// Arrays with binary data must go to body
|
|
60
|
+
if (array.some(item => isBytes(item) && item.length > 0)) return false
|
|
61
|
+
|
|
62
|
+
// Arrays with non-ASCII strings must go to body
|
|
63
|
+
if (array.some(item => typeof item === "string" && hasNonAscii(item)))
|
|
64
|
+
return false
|
|
65
|
+
|
|
66
|
+
// Arrays with nested arrays must go to body (to match original behavior)
|
|
67
|
+
if (array.some(item => Array.isArray(item))) return false
|
|
68
|
+
|
|
69
|
+
// Arrays with nested arrays that have objects must go to body
|
|
70
|
+
if (
|
|
71
|
+
array.some(
|
|
72
|
+
item => Array.isArray(item) && item.some(subItem => isPojo(subItem))
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
return false
|
|
76
|
+
|
|
77
|
+
// Simple arrays of primitives can stay in headers
|
|
78
|
+
return true
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Array analysis helper
|
|
82
|
+
const analyzeArray = array => {
|
|
83
|
+
const analysis = {
|
|
84
|
+
hasObjects: false,
|
|
85
|
+
hasArrays: false,
|
|
86
|
+
hasNonObjects: false,
|
|
87
|
+
hasArraysOfObjects: false,
|
|
88
|
+
hasEmptyStrings: false,
|
|
89
|
+
hasEmptyObjects: false,
|
|
90
|
+
hasNonEmptyObjects: false,
|
|
91
|
+
hasObjectsWithOnlyEmptyValues: false,
|
|
92
|
+
hasOnlyEmptyElements: true,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
for (const item of array) {
|
|
96
|
+
if (isPojo(item)) {
|
|
97
|
+
analysis.hasObjects = true
|
|
98
|
+
if (Object.keys(item).length === 0) {
|
|
99
|
+
analysis.hasEmptyObjects = true
|
|
100
|
+
} else {
|
|
101
|
+
analysis.hasNonEmptyObjects = true
|
|
102
|
+
if (hasOnlyEmptyValues(item)) {
|
|
103
|
+
analysis.hasObjectsWithOnlyEmptyValues = true
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} else if (Array.isArray(item)) {
|
|
107
|
+
analysis.hasArrays = true
|
|
108
|
+
if (item.some(subItem => isPojo(subItem))) {
|
|
109
|
+
analysis.hasArraysOfObjects = true
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
analysis.hasNonObjects = true
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (typeof item === "string" && item === "") {
|
|
116
|
+
analysis.hasEmptyStrings = true
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!isEmpty(item)) {
|
|
120
|
+
analysis.hasOnlyEmptyElements = false
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return analysis
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Body key collector class
|
|
128
|
+
class BodyKeyCollector {
|
|
129
|
+
constructor(obj) {
|
|
130
|
+
this.obj = obj
|
|
131
|
+
this.keys = []
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
collect() {
|
|
135
|
+
this.processRootObject()
|
|
136
|
+
return this.deduplicateAndFilter()
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Process top-level object
|
|
140
|
+
processRootObject() {
|
|
141
|
+
const objKeys = Object.keys(this.obj)
|
|
142
|
+
|
|
143
|
+
for (const [key, value] of Object.entries(this.obj)) {
|
|
144
|
+
if (this.isSpecialDataBodyField(key, value, objKeys)) {
|
|
145
|
+
this.keys.push(key)
|
|
146
|
+
} else if (Array.isArray(value) && value.length > 0) {
|
|
147
|
+
// Check if array can stay in header
|
|
148
|
+
if (!canArrayBeInHeader(value)) {
|
|
149
|
+
this.processRootArray(key, value)
|
|
150
|
+
}
|
|
151
|
+
} else if (isPojo(value)) {
|
|
152
|
+
this.processRootNestedObject(key, value)
|
|
153
|
+
} else if (this.needsBodyKey(key, value)) {
|
|
154
|
+
this.keys.push(key)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Check if field is special data/body field
|
|
160
|
+
isSpecialDataBodyField(key, value, objKeys) {
|
|
161
|
+
if (
|
|
162
|
+
(key === "data" || key === "body") &&
|
|
163
|
+
isSimpleValue(value) &&
|
|
164
|
+
objKeys.length > 1
|
|
165
|
+
) {
|
|
166
|
+
const otherKey = key === "data" ? "body" : "data"
|
|
167
|
+
const otherValue = this.obj[otherKey]
|
|
168
|
+
|
|
169
|
+
if (
|
|
170
|
+
otherValue &&
|
|
171
|
+
isPojo(otherValue) &&
|
|
172
|
+
Object.keys(otherValue).length > 0
|
|
173
|
+
) {
|
|
174
|
+
return false
|
|
175
|
+
}
|
|
176
|
+
return true
|
|
177
|
+
}
|
|
178
|
+
return false
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Check if value needs a body key
|
|
182
|
+
needsBodyKey(key, value) {
|
|
183
|
+
return (
|
|
184
|
+
(isBytes(value) && value.length > 0) ||
|
|
185
|
+
(typeof value === "string" && value.includes("\n")) ||
|
|
186
|
+
(typeof value === "string" && hasNonAscii(value))
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Process root-level arrays
|
|
191
|
+
processRootArray(key, array) {
|
|
192
|
+
const analysis = analyzeArray(array)
|
|
193
|
+
let bodyPartCounter = 1
|
|
194
|
+
|
|
195
|
+
if (analysis.hasArraysOfObjects) {
|
|
196
|
+
// Handle arrays of arrays containing objects
|
|
197
|
+
array.forEach((item, index) => {
|
|
198
|
+
if (Array.isArray(item)) {
|
|
199
|
+
item.forEach((subItem, subIndex) => {
|
|
200
|
+
if (isPojo(subItem)) {
|
|
201
|
+
this.keys.push(`${key}/${index + 1}/${subIndex + 1}`)
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
this.keys.push(key)
|
|
207
|
+
} else if (
|
|
208
|
+
analysis.hasObjects &&
|
|
209
|
+
(analysis.hasEmptyStrings || analysis.hasEmptyObjects) &&
|
|
210
|
+
!analysis.hasObjectsWithOnlyEmptyValues
|
|
211
|
+
) {
|
|
212
|
+
// Mixed array: only non-empty objects get parts
|
|
213
|
+
array.forEach(item => {
|
|
214
|
+
if (isPojo(item) && Object.keys(item).length > 0) {
|
|
215
|
+
const path = `${key}/${bodyPartCounter}`
|
|
216
|
+
this.keys.push(path)
|
|
217
|
+
this.addNestedObjectPaths(item, path)
|
|
218
|
+
}
|
|
219
|
+
bodyPartCounter++
|
|
220
|
+
})
|
|
221
|
+
this.keys.push(key)
|
|
222
|
+
} else if (analysis.hasObjects) {
|
|
223
|
+
// Regular array with objects
|
|
224
|
+
const skipEmptyObjects = analysis.hasOnlyEmptyElements
|
|
225
|
+
|
|
226
|
+
array.forEach(item => {
|
|
227
|
+
if (isPojo(item)) {
|
|
228
|
+
if (!(skipEmptyObjects && Object.keys(item).length === 0)) {
|
|
229
|
+
const path = `${key}/${bodyPartCounter}`
|
|
230
|
+
this.keys.push(path)
|
|
231
|
+
if (Object.keys(item).length > 0) {
|
|
232
|
+
this.addNestedObjectPaths(item, path)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
} else if (typeof item === "string" && item === "") {
|
|
236
|
+
this.keys.push(`${key}/${bodyPartCounter}`)
|
|
237
|
+
}
|
|
238
|
+
bodyPartCounter++
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
// Add main array key conditionally
|
|
242
|
+
if (!analysis.hasObjectsWithOnlyEmptyValues || analysis.hasNonObjects) {
|
|
243
|
+
if (!analysis.hasOnlyEmptyElements) {
|
|
244
|
+
this.keys.push(key)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
} else {
|
|
248
|
+
// Simple array without objects
|
|
249
|
+
const hasOnlyEmptyArraysOrObjects = array.every(
|
|
250
|
+
item =>
|
|
251
|
+
isEmpty(item) &&
|
|
252
|
+
(Array.isArray(item) || isPojo(item) || typeof item === "string")
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
if (hasOnlyEmptyArraysOrObjects || !array.every(isEmpty)) {
|
|
256
|
+
this.keys.push(key)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Add paths for nested objects within an object
|
|
262
|
+
addNestedObjectPaths(obj, basePath) {
|
|
263
|
+
for (const [nestedKey, nestedValue] of Object.entries(obj)) {
|
|
264
|
+
if (isPojo(nestedValue) && Object.keys(nestedValue).length > 0) {
|
|
265
|
+
this.keys.push(`${basePath}/${nestedKey}`)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Process root-level nested object
|
|
271
|
+
processRootNestedObject(key, obj) {
|
|
272
|
+
// Check for arrays with only empty elements
|
|
273
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
274
|
+
if (Array.isArray(v) && v.length > 0 && v.every(isEmpty)) {
|
|
275
|
+
this.keys.push(`${key}/${k}`)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Traverse the object
|
|
280
|
+
this.traverse(obj, key)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Traverse nested structures
|
|
284
|
+
traverse(current, path) {
|
|
285
|
+
let hasSimpleFields = false
|
|
286
|
+
const nestedPaths = []
|
|
287
|
+
let hasArraysWithObjects = false
|
|
288
|
+
|
|
289
|
+
// First pass: analyze structure
|
|
290
|
+
for (const [key, value] of Object.entries(current)) {
|
|
291
|
+
const fullPath = path ? `${path}/${key}` : key
|
|
292
|
+
const result = this.analyzeFieldInTraversal(value, fullPath, nestedPaths)
|
|
293
|
+
|
|
294
|
+
hasSimpleFields = hasSimpleFields || result.hasSimpleFields
|
|
295
|
+
hasArraysWithObjects = hasArraysWithObjects || result.hasArraysWithObjects
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Add current path if needed
|
|
299
|
+
if (hasSimpleFields || (hasArraysWithObjects && path)) {
|
|
300
|
+
this.keys.push(path)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Second pass: check for arrays with only empty elements
|
|
304
|
+
for (const [key, value] of Object.entries(current)) {
|
|
305
|
+
const fullPath = path ? `${path}/${key}` : key
|
|
306
|
+
if (Array.isArray(value) && value.length > 0 && value.every(isEmpty)) {
|
|
307
|
+
this.keys.push(fullPath)
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Traverse nested objects
|
|
312
|
+
for (const nestedPath of nestedPaths) {
|
|
313
|
+
const nestedObj = getValueByPath(this.obj, nestedPath)
|
|
314
|
+
if (isPojo(nestedObj)) {
|
|
315
|
+
this.traverse(nestedObj, nestedPath)
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Analyze a field during traversal
|
|
321
|
+
analyzeFieldInTraversal(value, fullPath, nestedPaths) {
|
|
322
|
+
let hasSimpleFields = false
|
|
323
|
+
let hasArraysWithObjects = false
|
|
324
|
+
|
|
325
|
+
if (Array.isArray(value)) {
|
|
326
|
+
if (value.length === 0) {
|
|
327
|
+
hasSimpleFields = true
|
|
328
|
+
} else {
|
|
329
|
+
const analysis = analyzeArray(value)
|
|
330
|
+
|
|
331
|
+
if (analysis.hasObjects) {
|
|
332
|
+
hasArraysWithObjects = true
|
|
333
|
+
this.processArrayInTraversal(value, fullPath, nestedPaths, analysis)
|
|
334
|
+
|
|
335
|
+
if (analysis.hasNonObjects) {
|
|
336
|
+
hasSimpleFields = true
|
|
337
|
+
// Only add to keys if array can't be in header
|
|
338
|
+
if (!canArrayBeInHeader(value)) {
|
|
339
|
+
this.keys.push(fullPath)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
} else {
|
|
343
|
+
hasSimpleFields = true
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
} else if (isPojo(value)) {
|
|
347
|
+
if (Object.keys(value).length === 0) {
|
|
348
|
+
hasSimpleFields = true
|
|
349
|
+
} else if (hasOnlyEmptyValues(value)) {
|
|
350
|
+
this.keys.push(fullPath)
|
|
351
|
+
} else {
|
|
352
|
+
const hasArraysWithOnlyEmptyElements = Object.entries(value).some(
|
|
353
|
+
([k, v]) => Array.isArray(v) && v.length > 0 && v.every(isEmpty)
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
if (hasArraysWithOnlyEmptyElements) {
|
|
357
|
+
this.keys.push(fullPath)
|
|
358
|
+
}
|
|
359
|
+
nestedPaths.push(fullPath)
|
|
360
|
+
}
|
|
361
|
+
} else if ((isBytes(value) && value.length > 0) || isSimpleValue(value)) {
|
|
362
|
+
hasSimpleFields = true
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return { hasSimpleFields, hasArraysWithObjects }
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Process arrays found during traversal
|
|
369
|
+
processArrayInTraversal(array, fullPath, nestedPaths, analysis) {
|
|
370
|
+
if (
|
|
371
|
+
(analysis.hasEmptyStrings || analysis.hasEmptyObjects) &&
|
|
372
|
+
analysis.hasNonEmptyObjects
|
|
373
|
+
) {
|
|
374
|
+
// Special case: only non-empty objects get parts
|
|
375
|
+
array.forEach((item, index) => {
|
|
376
|
+
if (isPojo(item) && Object.keys(item).length > 0) {
|
|
377
|
+
const itemPath = `${fullPath}/${index + 1}`
|
|
378
|
+
this.keys.push(itemPath)
|
|
379
|
+
nestedPaths.push(itemPath)
|
|
380
|
+
}
|
|
381
|
+
})
|
|
382
|
+
} else if (
|
|
383
|
+
analysis.hasObjectsWithOnlyEmptyValues &&
|
|
384
|
+
!analysis.hasNonObjects
|
|
385
|
+
) {
|
|
386
|
+
// Objects with only empty values
|
|
387
|
+
array.forEach((item, index) => {
|
|
388
|
+
if (isPojo(item)) {
|
|
389
|
+
const itemPath = `${fullPath}/${index + 1}`
|
|
390
|
+
this.keys.push(itemPath)
|
|
391
|
+
if (Object.keys(item).length > 0) {
|
|
392
|
+
nestedPaths.push(itemPath)
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
})
|
|
396
|
+
} else {
|
|
397
|
+
// Normal case
|
|
398
|
+
array.forEach((item, index) => {
|
|
399
|
+
if (isPojo(item)) {
|
|
400
|
+
const itemPath = `${fullPath}/${index + 1}`
|
|
401
|
+
this.keys.push(itemPath)
|
|
402
|
+
if (Object.keys(item).length > 0) {
|
|
403
|
+
nestedPaths.push(itemPath)
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
})
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// Deduplicate and filter results
|
|
411
|
+
deduplicateAndFilter() {
|
|
412
|
+
const uniqueKeys = [...new Set(this.keys)]
|
|
413
|
+
|
|
414
|
+
return uniqueKeys.filter(k => {
|
|
415
|
+
if (!k) return false
|
|
416
|
+
|
|
417
|
+
// Check if this is a path to an element inside an array with only empty elements
|
|
418
|
+
const parts = k.split("/")
|
|
419
|
+
if (parts.length >= 2 && /^\d+$/.test(parts[parts.length - 1])) {
|
|
420
|
+
const arrayPath = parts.slice(0, -1).join("/")
|
|
421
|
+
const arrayValue = getValueByPath(this.obj, arrayPath)
|
|
422
|
+
|
|
423
|
+
if (Array.isArray(arrayValue) && arrayValue.every(isEmpty)) {
|
|
424
|
+
return false
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return true
|
|
429
|
+
})
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export default function collectBodyKeys(obj, prefix = "") {
|
|
434
|
+
const collector = new BodyKeyCollector(obj)
|
|
435
|
+
return collector.collect()
|
|
436
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { id, base, hashpath, rsaid } from "./id.js"
|
|
2
|
+
import { toAddr } from "./utils.js"
|
|
3
|
+
import { extractPubKey } from "./signer-utils.js"
|
|
4
|
+
import { verify } from "./signer-utils.js"
|
|
5
|
+
import crypto from "crypto"
|
|
6
|
+
|
|
7
|
+
// Helper to compute SHA-256 content-digest in RFC 9530 format
|
|
8
|
+
const computeContentDigest = (body) => {
|
|
9
|
+
let bodyBuffer
|
|
10
|
+
if (Buffer.isBuffer(body)) {
|
|
11
|
+
bodyBuffer = body
|
|
12
|
+
} else if (body instanceof Blob) {
|
|
13
|
+
return null // Can't compute synchronously for Blob
|
|
14
|
+
} else if (typeof body === "string") {
|
|
15
|
+
bodyBuffer = Buffer.from(body, "binary")
|
|
16
|
+
} else {
|
|
17
|
+
bodyBuffer = Buffer.from(String(body), "binary")
|
|
18
|
+
}
|
|
19
|
+
const hash = crypto.createHash("sha256").update(bodyBuffer).digest("base64")
|
|
20
|
+
return `sha-256=:${hash}:`
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Helper to build ao-types string from an object
|
|
24
|
+
const buildAoTypes = (obj) => {
|
|
25
|
+
const types = []
|
|
26
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
27
|
+
if (typeof value === "number") {
|
|
28
|
+
types.push(`${key}="${Number.isInteger(value) ? "integer" : "float"}"`)
|
|
29
|
+
} else if (typeof value === "boolean") {
|
|
30
|
+
types.push(`${key}="atom"`)
|
|
31
|
+
} else if (value === null) {
|
|
32
|
+
types.push(`${key}="atom"`)
|
|
33
|
+
} else if (typeof value === "symbol") {
|
|
34
|
+
// Symbols are Erlang atoms
|
|
35
|
+
types.push(`${key}="atom"`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return types.length > 0 ? types.join(", ") : null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// todo: handle @
|
|
42
|
+
export const commit = async (obj, opts) => {
|
|
43
|
+
const msg = await opts.signer(obj, opts)
|
|
44
|
+
const {
|
|
45
|
+
decodedSignatureInput: { components },
|
|
46
|
+
} = await verify(msg)
|
|
47
|
+
|
|
48
|
+
let body = {}
|
|
49
|
+
|
|
50
|
+
// Check for inline-body-key (indicates a field was moved to HTTP body during encoding)
|
|
51
|
+
const inlineBodyKey = msg.headers["inline-body-key"] || msg.headers["ao-body-key"]
|
|
52
|
+
|
|
53
|
+
// Body field names that HyperBEAM's inline_key() recognizes natively.
|
|
54
|
+
// For these, normalize_for_encoding() re-derives ao-body-key automatically.
|
|
55
|
+
// For custom names (e.g., "json"), we must keep ao-body-key in committed list
|
|
56
|
+
// so HyperBEAM knows which field to inline during verification.
|
|
57
|
+
const NATIVE_BODY_KEYS = new Set(["body", "data"])
|
|
58
|
+
const isNativeBodyKey = !inlineBodyKey || NATIVE_BODY_KEYS.has(inlineBodyKey)
|
|
59
|
+
|
|
60
|
+
// Build body from committed components.
|
|
61
|
+
// IMPORTANT: Use original typed values from obj (preserves integers, booleans, etc.)
|
|
62
|
+
// instead of string values from headers. This is critical because:
|
|
63
|
+
// 1. HTTP headers are always strings (e.g., quantity: 100 → "100")
|
|
64
|
+
// 2. We include ao-types to tell HyperBEAM the original types
|
|
65
|
+
// 3. HyperBEAM applies ao-types BEFORE signature verification
|
|
66
|
+
// 4. If we send strings, HyperBEAM converts to integers, breaking signature
|
|
67
|
+
// 5. If we send original integers, HyperBEAM re-encodes them as strings for verification
|
|
68
|
+
//
|
|
69
|
+
// Always skip content-digest and inline-body-key (transport artifacts re-derived by HyperBEAM).
|
|
70
|
+
// Skip ao-body-key only for native body keys (HyperBEAM re-derives it).
|
|
71
|
+
// Keep ao-body-key for custom body keys (HyperBEAM needs it to find the body field).
|
|
72
|
+
|
|
73
|
+
// Create case-insensitive lookup maps
|
|
74
|
+
const headerLookup = new Map()
|
|
75
|
+
for (const [k, v] of Object.entries(msg.headers)) {
|
|
76
|
+
headerLookup.set(k.toLowerCase(), v)
|
|
77
|
+
}
|
|
78
|
+
// Case-insensitive lookup for original object values (preserves types)
|
|
79
|
+
const objLookup = new Map()
|
|
80
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
81
|
+
objLookup.set(k.toLowerCase(), v)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (const v of components) {
|
|
85
|
+
const key = v === "@path" ? "path" : v
|
|
86
|
+
if (key === "content-length") continue
|
|
87
|
+
if (key === "content-digest") continue
|
|
88
|
+
if (key === "inline-body-key") continue
|
|
89
|
+
if (isNativeBodyKey && key === "ao-body-key") continue
|
|
90
|
+
|
|
91
|
+
// Prefer original value from input object (preserves integer/boolean/etc. types)
|
|
92
|
+
// Fall back to header string value if not found in original object
|
|
93
|
+
const originalValue = objLookup.get(key.toLowerCase())
|
|
94
|
+
if (originalValue !== undefined) {
|
|
95
|
+
body[key] = originalValue
|
|
96
|
+
} else {
|
|
97
|
+
const headerValue = headerLookup.get(key)
|
|
98
|
+
if (headerValue !== undefined) {
|
|
99
|
+
body[key] = headerValue
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Handle body resolution - restore the inlined field to its AO-Core name
|
|
105
|
+
let bodyContent = null
|
|
106
|
+
if (msg.body) {
|
|
107
|
+
if (msg.body instanceof Blob) {
|
|
108
|
+
const arrayBuffer = await msg.body.arrayBuffer()
|
|
109
|
+
bodyContent = Buffer.from(arrayBuffer)
|
|
110
|
+
} else {
|
|
111
|
+
bodyContent = msg.body
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Put body content under the original field name (e.g., "data", "json")
|
|
115
|
+
if (inlineBodyKey) {
|
|
116
|
+
body[inlineBodyKey] = bodyContent
|
|
117
|
+
} else {
|
|
118
|
+
body.body = bodyContent
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Include non-committed fields from the original object as JSON values.
|
|
123
|
+
// This covers: (1) body-key fields (arrays/objects encoded as multipart,
|
|
124
|
+
// which can't be included as raw multipart in JSON), and (2) any other
|
|
125
|
+
// fields excluded from signing. These fields are unsigned but present
|
|
126
|
+
// so HyperBEAM can parse them directly as JSON types.
|
|
127
|
+
// Use case-insensitive matching: signing normalizes keys to lowercase,
|
|
128
|
+
// but the original object may use mixed case (e.g., "To" vs "to").
|
|
129
|
+
const committedSetLower = new Set(components.map(v => (v === "@path" ? "path" : v).toLowerCase()))
|
|
130
|
+
// Also track lowercase keys already in body to prevent duplicates
|
|
131
|
+
const bodyKeysLower = new Set(Object.keys(body).map(k => k.toLowerCase()))
|
|
132
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
133
|
+
// Skip HTTP method (not a data field)
|
|
134
|
+
if (key === "method") continue
|
|
135
|
+
// Skip if already in committed set (was signed)
|
|
136
|
+
if (committedSetLower.has(key.toLowerCase())) continue
|
|
137
|
+
// Skip if already in body (duplicate prevention)
|
|
138
|
+
if (bodyKeysLower.has(key.toLowerCase())) continue
|
|
139
|
+
if (value === undefined) continue
|
|
140
|
+
body[key] = value
|
|
141
|
+
bodyKeysLower.add(key.toLowerCase())
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Include ao-types so HyperBEAM knows how to convert string values to proper types.
|
|
145
|
+
// First check if it was set by the signer, otherwise compute it from the original object
|
|
146
|
+
let aoTypes = msg.headers["ao-types"]
|
|
147
|
+
if (!aoTypes) {
|
|
148
|
+
// Compute ao-types from the original typed values in obj
|
|
149
|
+
aoTypes = buildAoTypes(obj)
|
|
150
|
+
}
|
|
151
|
+
if (aoTypes) {
|
|
152
|
+
body["ao-types"] = aoTypes
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const rsaId = rsaid(msg.headers)
|
|
156
|
+
const pub = extractPubKey(msg.headers)
|
|
157
|
+
const pubKeyBase64 = pub.toString("base64")
|
|
158
|
+
const committer = toAddr(pubKeyBase64)
|
|
159
|
+
|
|
160
|
+
// Extract keyid from signature-input to ensure it matches what was signed
|
|
161
|
+
// Format: sig-xxx=("field1"...);alg="...";keyid="..."
|
|
162
|
+
// The keyid may already have a scheme prefix (e.g., "publickey:base64data")
|
|
163
|
+
const extractKeyidFromSigInput = (sigInput) => {
|
|
164
|
+
if (!sigInput) return null
|
|
165
|
+
const match = sigInput.match(/keyid="([^"]+)"/)
|
|
166
|
+
if (!match) return null
|
|
167
|
+
// Return as-is - the keyid already includes the prefix from signing
|
|
168
|
+
return match[1]
|
|
169
|
+
}
|
|
170
|
+
const keyid = extractKeyidFromSigInput(msg.headers["signature-input"]) || `publickey:${pubKeyBase64}`
|
|
171
|
+
|
|
172
|
+
// Build the list of committed fields.
|
|
173
|
+
// Always transform HTTPSig transport keys to AO-Core keys:
|
|
174
|
+
// - Replace content-digest with the body field name (HyperBEAM re-derives content-digest)
|
|
175
|
+
// - For native body keys ("body", "data"): also remove ao-body-key (HyperBEAM re-derives it)
|
|
176
|
+
// - For custom body keys (e.g., "json"): keep ao-body-key (HyperBEAM needs it to find the field)
|
|
177
|
+
let committedFields = components.map(v => v === "@path" ? "path" : v)
|
|
178
|
+
if (committedFields.includes("content-digest") && (inlineBodyKey || msg.body)) {
|
|
179
|
+
const bodyFieldName = inlineBodyKey || "body"
|
|
180
|
+
committedFields = committedFields.filter(k => k !== "content-digest")
|
|
181
|
+
if (!committedFields.includes(bodyFieldName)) {
|
|
182
|
+
committedFields.push(bodyFieldName)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (isNativeBodyKey) {
|
|
186
|
+
// For native body keys, ao-body-key is a transport artifact - remove it
|
|
187
|
+
committedFields = committedFields.filter(k => k !== "ao-body-key")
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Extract just the base64 signature data from the header format "sig-xxx=:base64data:"
|
|
191
|
+
// HyperBEAM expects raw base64 without colons (uses b64fast:encode/decode)
|
|
192
|
+
const extractSignature = (sigHeader) => {
|
|
193
|
+
if (!sigHeader) return sigHeader
|
|
194
|
+
// Match the base64 data between colons after the label
|
|
195
|
+
const match = sigHeader.match(/=:([^:]+):/)
|
|
196
|
+
return match ? match[1] : sigHeader
|
|
197
|
+
}
|
|
198
|
+
const rawSignature = extractSignature(msg.headers.signature)
|
|
199
|
+
const meta = {
|
|
200
|
+
type: "rsa-pss-sha512",
|
|
201
|
+
alg: "rsa-pss-sha512",
|
|
202
|
+
"commitment-device": "httpsig@1.0",
|
|
203
|
+
keyid: keyid,
|
|
204
|
+
committed: committedFields
|
|
205
|
+
}
|
|
206
|
+
const sigs = {
|
|
207
|
+
signature: rawSignature,
|
|
208
|
+
"signature-input": msg.headers["signature-input"],
|
|
209
|
+
}
|
|
210
|
+
// Only include the RSA commitment - HMAC commitments are created by HyperBEAM
|
|
211
|
+
// when needed and require the server's HMAC key which we don't have
|
|
212
|
+
const committed = {
|
|
213
|
+
commitments: {
|
|
214
|
+
[rsaId]: { ...meta, committer, ...sigs },
|
|
215
|
+
},
|
|
216
|
+
...body,
|
|
217
|
+
}
|
|
218
|
+
return committed
|
|
219
|
+
}
|