Commit b24eac2f authored by nanahira's avatar nanahira

add template rendering

parent 7d4b331d
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
"@types/koa": "^2.13.4", "@types/koa": "^2.13.4",
"@types/koa__router": "^8.0.11", "@types/koa__router": "^8.0.11",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mustache": "^4.2.0",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"typed-reflector": "^1.0.10" "typed-reflector": "^1.0.10"
}, },
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
"@koishijs/plugin-adapter-onebot": "^4.1.5", "@koishijs/plugin-adapter-onebot": "^4.1.5",
"@types/jest": "^27.4.0", "@types/jest": "^27.4.0",
"@types/lodash": "^4.14.178", "@types/lodash": "^4.14.178",
"@types/mustache": "^4.1.2",
"@types/node": "^17.0.10", "@types/node": "^17.0.10",
"@types/supertest": "^2.0.11", "@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/eslint-plugin": "^4.33.0",
...@@ -34,7 +36,7 @@ ...@@ -34,7 +36,7 @@
"typescript": "^4.5.5" "typescript": "^4.5.5"
}, },
"peerDependencies": { "peerDependencies": {
"koishi": "^4.6.0" "koishi": "^4.7.0"
} }
}, },
"node_modules/@babel/code-frame": { "node_modules/@babel/code-frame": {
...@@ -997,15 +999,15 @@ ...@@ -997,15 +999,15 @@
} }
}, },
"node_modules/@koishijs/core": { "node_modules/@koishijs/core": {
"version": "4.6.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@koishijs/core/-/core-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@koishijs/core/-/core-4.7.0.tgz",
"integrity": "sha512-m+K2h/Oqmpcw39dQhJ/D9MBmwnWNUf9uFqymJ94+nP4CR7rcM1DTWNiaMGshGUqNu+s4q0ildoEDlQrE4hVuWA==", "integrity": "sha512-MCF8eJaDV8Bw74N3GesFMaxBmRfrUCvez4SwAPkODjRk2uuQpmnxKCAOJu/AFxyyLLg/vQNTGUMG4mPW8RDIyA==",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@koishijs/utils": "^5.4.0", "@koishijs/utils": "^5.4.3",
"cosmotype": "^1.0.3",
"fastest-levenshtein": "^1.0.12", "fastest-levenshtein": "^1.0.12",
"ns-require": "^1.1.0" "minato": "^1.0.10",
"ns-require": "^1.1.2"
}, },
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
...@@ -1052,15 +1054,15 @@ ...@@ -1052,15 +1054,15 @@
"peer": true "peer": true
}, },
"node_modules/@koishijs/utils": { "node_modules/@koishijs/utils": {
"version": "5.4.0", "version": "5.4.4",
"resolved": "https://registry.npmjs.org/@koishijs/utils/-/utils-5.4.0.tgz", "resolved": "https://registry.npmjs.org/@koishijs/utils/-/utils-5.4.4.tgz",
"integrity": "sha512-w5SHArw032cXVtxp5nXkc5jzP6Fn3LrF7FQTanPnOgmjGv/AIOAKfJ6bqaOUsSg+ttcK3iO8xs65W6XsNz3g7g==", "integrity": "sha512-afPJs9aiwOjcSXZgGaOqmuEqlhIASxhUKdSBoB0msrw9RVz2HmegmyqHm0reRmftFWoeOvGh8Tv/3BKettzklw==",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@koishijs/segment": "^1.1.1", "@koishijs/segment": "^1.1.1",
"cosmokit": "^1.1.1", "cosmokit": "^1.1.2",
"reggol": "^1.0.1", "reggol": "^1.0.3",
"schemastery": "^3.3.2", "schemastery": "^3.4.0",
"supports-color": "^8.1.1" "supports-color": "^8.1.1"
} }
}, },
...@@ -1361,6 +1363,12 @@ ...@@ -1361,6 +1363,12 @@
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
}, },
"node_modules/@types/mustache": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.2.tgz",
"integrity": "sha512-c4OVMMcyodKQ9dpwBwh3ofK9P6U9ZktKU9S+p33UqwMNN1vlv2P0zJZUScTshnx7OEoIIRcCFNQ904sYxZz8kg==",
"dev": true
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "17.0.10", "version": "17.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
...@@ -2268,21 +2276,11 @@ ...@@ -2268,21 +2276,11 @@
"peer": true "peer": true
}, },
"node_modules/cosmokit": { "node_modules/cosmokit": {
"version": "1.1.1", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/cosmokit/-/cosmokit-1.1.1.tgz", "resolved": "https://registry.npmjs.org/cosmokit/-/cosmokit-1.1.2.tgz",
"integrity": "sha512-+f8x9pFGIc7I6HTObS90dq2K5YsI4U3Me4l9OminU9woVtF9Sv3CAHb5vKbFZ93XpTFctAQ6qAVSGjkGvGI9iw==", "integrity": "sha512-cSNrcyxZ3GT+tjSlUzWIzMiK7Wndq1Nm/2tlRhT65RXltSIcH5zaHdmnz1TnIhLuOViaO9qfSdnRPzxNkxMv0g==",
"peer": true "peer": true
}, },
"node_modules/cosmotype": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cosmotype/-/cosmotype-1.0.3.tgz",
"integrity": "sha512-JykvyDjyjaDjycm8CcK8GD4Xt6/Glu4pJU9uJ5lsDuE5B5bdmAykiTPMHfs+Is8QUsNaDKpsHfxtxCUBDPYgdw==",
"peer": true,
"dependencies": {
"cosmokit": "^1.1.1",
"ns-require": "^1.1.0"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
...@@ -4747,14 +4745,14 @@ ...@@ -4747,14 +4745,14 @@
} }
}, },
"node_modules/koishi": { "node_modules/koishi": {
"version": "4.6.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/koishi/-/koishi-4.6.0.tgz", "resolved": "https://registry.npmjs.org/koishi/-/koishi-4.7.0.tgz",
"integrity": "sha512-QhjFWTGhrFnYfpVg4dNNxgHER38zSij3nyM/RB3YrLTM4VwImVk5unpgg0QryViwWxSYM4zJ0YUoys4A9jgG6A==", "integrity": "sha512-aCtfE+QydqbcpoOspOp/QCY1CAXieqnPIR101eKtODgrPBHUVc8XbXbkqGAzx6c2kr6wC7mE4ZLBgECqGBn7tw==",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@koa/router": "^10.1.1", "@koa/router": "^10.1.1",
"@koishijs/core": "^4.6.0", "@koishijs/core": "^4.7.0",
"@koishijs/utils": "^5.4.0", "@koishijs/utils": "^5.4.3",
"@types/koa": "*", "@types/koa": "*",
"@types/koa__router": "*", "@types/koa__router": "*",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
...@@ -4765,16 +4763,16 @@ ...@@ -4765,16 +4763,16 @@
"parseurl": "^1.3.3", "parseurl": "^1.3.3",
"path-to-regexp": "^6.2.0", "path-to-regexp": "^6.2.0",
"proxy-agent": "^5.0.0", "proxy-agent": "^5.0.0",
"ws": "^8.5.0" "ws": "^8.6.0"
}, },
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
} }
}, },
"node_modules/koishi/node_modules/ws": { "node_modules/koishi/node_modules/ws": {
"version": "8.5.0", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
"peer": true, "peer": true,
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
...@@ -4985,6 +4983,16 @@ ...@@ -4985,6 +4983,16 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/minato": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/minato/-/minato-1.1.0.tgz",
"integrity": "sha512-by1KMWxWlzq0iDV7tMkqS3thDRzYNQoS2ECfX5HRpMGaPQJqSgm5aY9IAky7knwAMoW3cMxQ/IhpvEShQqyj6A==",
"peer": true,
"dependencies": {
"cosmokit": "^1.1.2",
"ns-require": "^1.1.2"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
...@@ -5008,6 +5016,14 @@ ...@@ -5008,6 +5016,14 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
"bin": {
"mustache": "bin/mustache"
}
},
"node_modules/natural-compare": { "node_modules/natural-compare": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
...@@ -5066,9 +5082,9 @@ ...@@ -5066,9 +5082,9 @@
} }
}, },
"node_modules/ns-require": { "node_modules/ns-require": {
"version": "1.1.0", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/ns-require/-/ns-require-1.1.0.tgz", "resolved": "https://registry.npmjs.org/ns-require/-/ns-require-1.1.2.tgz",
"integrity": "sha512-Iw349zwWNgkGZjYJtruf+BXUe8YHOiMZE0iUNffvpt/A1yTSabTnpBMQ0zNl65G1LhpzwCo1KMCqjmJF0z8O6g==", "integrity": "sha512-GUF6I1hWDsGx1cA9FW27KIRAlkMel2UZagR39dVNPAPBgwWK1Ez0XB96WEz2OFcwHsCORI9h75dEZueHqZ/1pA==",
"peer": true "peer": true
}, },
"node_modules/nwsapi": { "node_modules/nwsapi": {
...@@ -5627,12 +5643,12 @@ ...@@ -5627,12 +5643,12 @@
} }
}, },
"node_modules/reggol": { "node_modules/reggol": {
"version": "1.0.1", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/reggol/-/reggol-1.0.1.tgz", "resolved": "https://registry.npmjs.org/reggol/-/reggol-1.0.3.tgz",
"integrity": "sha512-ZMOp3rZG6YQFVp/DC+BgFZaXSQcxHDayCmo7cL/kGujsSEoUzee0VJq1KCe9sgNt0qsM6JzkuSlj/+5SmmoO7Q==", "integrity": "sha512-91bFsIEaw3IKoMt7JQz703yuEgdcbbKBTJbeVyFMrZwA93wCU/ByDvhwDfvVWXjvLqwRuFOfhV1pkxvAgdkVZQ==",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"cosmokit": "^1.1.0", "cosmokit": "^1.1.2",
"supports-color": "^8.1.1" "supports-color": "^8.1.1"
} }
}, },
...@@ -5797,12 +5813,12 @@ ...@@ -5797,12 +5813,12 @@
} }
}, },
"node_modules/schemastery": { "node_modules/schemastery": {
"version": "3.3.2", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/schemastery/-/schemastery-3.3.2.tgz", "resolved": "https://registry.npmjs.org/schemastery/-/schemastery-3.4.0.tgz",
"integrity": "sha512-Z1C850OPtNEBs+D4QBPdC+Wu1t6Fn1BrOJILRHs2b+I/u61hUKP2vIPMAXFLvmmONnwqAW8ksPdCD6Zz9n8zhg==", "integrity": "sha512-VGPk/BL/Qs+p3ldNXpqyqxMek9Oi3+2uWMeYhgVJvzQ4V4nOIPFuvEeyixZH+Uq1iGNEUjdBMeLOAV2HeWfaeg==",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"cosmokit": "^1.1.0" "cosmokit": "^1.1.2"
} }
}, },
"node_modules/semver": { "node_modules/semver": {
...@@ -7578,15 +7594,15 @@ ...@@ -7578,15 +7594,15 @@
} }
}, },
"@koishijs/core": { "@koishijs/core": {
"version": "4.6.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/@koishijs/core/-/core-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@koishijs/core/-/core-4.7.0.tgz",
"integrity": "sha512-m+K2h/Oqmpcw39dQhJ/D9MBmwnWNUf9uFqymJ94+nP4CR7rcM1DTWNiaMGshGUqNu+s4q0ildoEDlQrE4hVuWA==", "integrity": "sha512-MCF8eJaDV8Bw74N3GesFMaxBmRfrUCvez4SwAPkODjRk2uuQpmnxKCAOJu/AFxyyLLg/vQNTGUMG4mPW8RDIyA==",
"peer": true, "peer": true,
"requires": { "requires": {
"@koishijs/utils": "^5.4.0", "@koishijs/utils": "^5.4.3",
"cosmotype": "^1.0.3",
"fastest-levenshtein": "^1.0.12", "fastest-levenshtein": "^1.0.12",
"ns-require": "^1.1.0" "minato": "^1.0.10",
"ns-require": "^1.1.2"
} }
}, },
"@koishijs/plugin-adapter-onebot": { "@koishijs/plugin-adapter-onebot": {
...@@ -7615,15 +7631,15 @@ ...@@ -7615,15 +7631,15 @@
"peer": true "peer": true
}, },
"@koishijs/utils": { "@koishijs/utils": {
"version": "5.4.0", "version": "5.4.4",
"resolved": "https://registry.npmjs.org/@koishijs/utils/-/utils-5.4.0.tgz", "resolved": "https://registry.npmjs.org/@koishijs/utils/-/utils-5.4.4.tgz",
"integrity": "sha512-w5SHArw032cXVtxp5nXkc5jzP6Fn3LrF7FQTanPnOgmjGv/AIOAKfJ6bqaOUsSg+ttcK3iO8xs65W6XsNz3g7g==", "integrity": "sha512-afPJs9aiwOjcSXZgGaOqmuEqlhIASxhUKdSBoB0msrw9RVz2HmegmyqHm0reRmftFWoeOvGh8Tv/3BKettzklw==",
"peer": true, "peer": true,
"requires": { "requires": {
"@koishijs/segment": "^1.1.1", "@koishijs/segment": "^1.1.1",
"cosmokit": "^1.1.1", "cosmokit": "^1.1.2",
"reggol": "^1.0.1", "reggol": "^1.0.3",
"schemastery": "^3.3.2", "schemastery": "^3.4.0",
"supports-color": "^8.1.1" "supports-color": "^8.1.1"
}, },
"dependencies": { "dependencies": {
...@@ -7908,6 +7924,12 @@ ...@@ -7908,6 +7924,12 @@
"resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz",
"integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw=="
}, },
"@types/mustache": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.1.2.tgz",
"integrity": "sha512-c4OVMMcyodKQ9dpwBwh3ofK9P6U9ZktKU9S+p33UqwMNN1vlv2P0zJZUScTshnx7OEoIIRcCFNQ904sYxZz8kg==",
"dev": true
},
"@types/node": { "@types/node": {
"version": "17.0.10", "version": "17.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
...@@ -8591,21 +8613,11 @@ ...@@ -8591,21 +8613,11 @@
"peer": true "peer": true
}, },
"cosmokit": { "cosmokit": {
"version": "1.1.1", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/cosmokit/-/cosmokit-1.1.1.tgz", "resolved": "https://registry.npmjs.org/cosmokit/-/cosmokit-1.1.2.tgz",
"integrity": "sha512-+f8x9pFGIc7I6HTObS90dq2K5YsI4U3Me4l9OminU9woVtF9Sv3CAHb5vKbFZ93XpTFctAQ6qAVSGjkGvGI9iw==", "integrity": "sha512-cSNrcyxZ3GT+tjSlUzWIzMiK7Wndq1Nm/2tlRhT65RXltSIcH5zaHdmnz1TnIhLuOViaO9qfSdnRPzxNkxMv0g==",
"peer": true "peer": true
}, },
"cosmotype": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cosmotype/-/cosmotype-1.0.3.tgz",
"integrity": "sha512-JykvyDjyjaDjycm8CcK8GD4Xt6/Glu4pJU9uJ5lsDuE5B5bdmAykiTPMHfs+Is8QUsNaDKpsHfxtxCUBDPYgdw==",
"peer": true,
"requires": {
"cosmokit": "^1.1.1",
"ns-require": "^1.1.0"
}
},
"cross-spawn": { "cross-spawn": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
...@@ -10463,14 +10475,14 @@ ...@@ -10463,14 +10475,14 @@
} }
}, },
"koishi": { "koishi": {
"version": "4.6.0", "version": "4.7.0",
"resolved": "https://registry.npmjs.org/koishi/-/koishi-4.6.0.tgz", "resolved": "https://registry.npmjs.org/koishi/-/koishi-4.7.0.tgz",
"integrity": "sha512-QhjFWTGhrFnYfpVg4dNNxgHER38zSij3nyM/RB3YrLTM4VwImVk5unpgg0QryViwWxSYM4zJ0YUoys4A9jgG6A==", "integrity": "sha512-aCtfE+QydqbcpoOspOp/QCY1CAXieqnPIR101eKtODgrPBHUVc8XbXbkqGAzx6c2kr6wC7mE4ZLBgECqGBn7tw==",
"peer": true, "peer": true,
"requires": { "requires": {
"@koa/router": "^10.1.1", "@koa/router": "^10.1.1",
"@koishijs/core": "^4.6.0", "@koishijs/core": "^4.7.0",
"@koishijs/utils": "^5.4.0", "@koishijs/utils": "^5.4.3",
"@types/koa": "*", "@types/koa": "*",
"@types/koa__router": "*", "@types/koa__router": "*",
"@types/ws": "^8.5.3", "@types/ws": "^8.5.3",
...@@ -10481,13 +10493,13 @@ ...@@ -10481,13 +10493,13 @@
"parseurl": "^1.3.3", "parseurl": "^1.3.3",
"path-to-regexp": "^6.2.0", "path-to-regexp": "^6.2.0",
"proxy-agent": "^5.0.0", "proxy-agent": "^5.0.0",
"ws": "^8.5.0" "ws": "^8.6.0"
}, },
"dependencies": { "dependencies": {
"ws": { "ws": {
"version": "8.5.0", "version": "8.6.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.6.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", "integrity": "sha512-AzmM3aH3gk0aX7/rZLYvjdvZooofDu3fFOzGqcSnQ1tOcTWwhM/o+q++E8mAyVVIyUdajrkzWUGftaVSDLn1bw==",
"peer": true, "peer": true,
"requires": {} "requires": {}
} }
...@@ -10640,6 +10652,16 @@ ...@@ -10640,6 +10652,16 @@
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true "dev": true
}, },
"minato": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/minato/-/minato-1.1.0.tgz",
"integrity": "sha512-by1KMWxWlzq0iDV7tMkqS3thDRzYNQoS2ECfX5HRpMGaPQJqSgm5aY9IAky7knwAMoW3cMxQ/IhpvEShQqyj6A==",
"peer": true,
"requires": {
"cosmokit": "^1.1.2",
"ns-require": "^1.1.2"
}
},
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
...@@ -10660,6 +10682,11 @@ ...@@ -10660,6 +10682,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="
},
"natural-compare": { "natural-compare": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
...@@ -10706,9 +10733,9 @@ ...@@ -10706,9 +10733,9 @@
} }
}, },
"ns-require": { "ns-require": {
"version": "1.1.0", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/ns-require/-/ns-require-1.1.0.tgz", "resolved": "https://registry.npmjs.org/ns-require/-/ns-require-1.1.2.tgz",
"integrity": "sha512-Iw349zwWNgkGZjYJtruf+BXUe8YHOiMZE0iUNffvpt/A1yTSabTnpBMQ0zNl65G1LhpzwCo1KMCqjmJF0z8O6g==", "integrity": "sha512-GUF6I1hWDsGx1cA9FW27KIRAlkMel2UZagR39dVNPAPBgwWK1Ez0XB96WEz2OFcwHsCORI9h75dEZueHqZ/1pA==",
"peer": true "peer": true
}, },
"nwsapi": { "nwsapi": {
...@@ -11117,12 +11144,12 @@ ...@@ -11117,12 +11144,12 @@
"dev": true "dev": true
}, },
"reggol": { "reggol": {
"version": "1.0.1", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/reggol/-/reggol-1.0.1.tgz", "resolved": "https://registry.npmjs.org/reggol/-/reggol-1.0.3.tgz",
"integrity": "sha512-ZMOp3rZG6YQFVp/DC+BgFZaXSQcxHDayCmo7cL/kGujsSEoUzee0VJq1KCe9sgNt0qsM6JzkuSlj/+5SmmoO7Q==", "integrity": "sha512-91bFsIEaw3IKoMt7JQz703yuEgdcbbKBTJbeVyFMrZwA93wCU/ByDvhwDfvVWXjvLqwRuFOfhV1pkxvAgdkVZQ==",
"peer": true, "peer": true,
"requires": { "requires": {
"cosmokit": "^1.1.0", "cosmokit": "^1.1.2",
"supports-color": "^8.1.1" "supports-color": "^8.1.1"
}, },
"dependencies": { "dependencies": {
...@@ -11234,12 +11261,12 @@ ...@@ -11234,12 +11261,12 @@
} }
}, },
"schemastery": { "schemastery": {
"version": "3.3.2", "version": "3.4.0",
"resolved": "https://registry.npmjs.org/schemastery/-/schemastery-3.3.2.tgz", "resolved": "https://registry.npmjs.org/schemastery/-/schemastery-3.4.0.tgz",
"integrity": "sha512-Z1C850OPtNEBs+D4QBPdC+Wu1t6Fn1BrOJILRHs2b+I/u61hUKP2vIPMAXFLvmmONnwqAW8ksPdCD6Zz9n8zhg==", "integrity": "sha512-VGPk/BL/Qs+p3ldNXpqyqxMek9Oi3+2uWMeYhgVJvzQ4V4nOIPFuvEeyixZH+Uq1iGNEUjdBMeLOAV2HeWfaeg==",
"peer": true, "peer": true,
"requires": { "requires": {
"cosmokit": "^1.1.0" "cosmokit": "^1.1.2"
} }
}, },
"semver": { "semver": {
......
...@@ -123,17 +123,17 @@ export const CommandDef = ( ...@@ -123,17 +123,17 @@ export const CommandDef = (
export const CommandUse = <T extends Command, R extends any[]>( export const CommandUse = <T extends Command, R extends any[]>(
callback: (command: Command, ...args: R) => T, callback: (command: Command, ...args: R) => T,
...args: R ...args: R
) => CommandDef((cmd) => callback(cmd, ...args)); ) => CommandDef((cmd, ctx, r) => callback(cmd, ...args));
export const CommandLocale = (locale: string, def: CommandLocaleDef) => export const CommandLocale = (locale: string, def: CommandLocaleDef) =>
CommandDef((cmd, ctx) => { CommandDef((cmd, ctx, r) => {
ctx.i18n.define(locale, `commands.${cmd.name}`, def); ctx.i18n.define(r(locale), `commands.${cmd.name}`, r(def));
return cmd; return cmd;
}); });
export const CommandDescription = (desc: string | Dict<string>) => { export const CommandDescription = (desc: string | Dict<string>) => {
return CommandDef((cmd, ctx) => { return CommandDef((cmd, ctx, r) => {
for (const localData of Object.entries(adaptLocaleDict(desc))) { for (const localData of Object.entries(adaptLocaleDict(r(desc)))) {
const [locale, text] = localData; const [locale, text] = localData;
ctx.i18n.define(locale, `commands.${cmd.name}.description`, text); ctx.i18n.define(locale, `commands.${cmd.name}.description`, text);
} }
...@@ -142,48 +142,53 @@ export const CommandDescription = (desc: string | Dict<string>) => { ...@@ -142,48 +142,53 @@ export const CommandDescription = (desc: string | Dict<string>) => {
}; };
export const CommandAlias = (...names: string[]) => export const CommandAlias = (...names: string[]) =>
CommandDef((cmd) => cmd.alias(...names)); CommandDef((cmd, ctx, r) => cmd.alias(...r(names)));
export const CommandShortcut = ( export const CommandShortcut = (
name: string | RegExp, name: string | RegExp,
config: Command.Shortcut = {}, config: Command.Shortcut = {},
) => CommandDef((cmd) => cmd.shortcut(name, config)); ) => CommandDef((cmd, ctx, r) => cmd.shortcut(r(name), r(config)));
export const CommandUsage = (text: Command.Usage) => export const CommandUsage = (text: Command.Usage) =>
CommandDef((cmd) => cmd.usage(text)); CommandDef((cmd, ctx, r) => cmd.usage(r(text)));
export const CommandExample = (text: string) => export const CommandExample = (text: string) =>
CommandDef((cmd) => cmd.example(text)); CommandDef((cmd, ctx, r) => cmd.example(r(text)));
export const CommandOption = ( export const CommandOption = (
name: string, name: string,
desc: string, desc: string,
config: CommandOptionConfigWithDescription = {}, config: CommandOptionConfigWithDescription = {},
) => ) =>
CommandDef((cmd, ctx) => CommandDef((cmd, ctx, r) =>
applyOptionToCommand(ctx, cmd, { name, desc, config }), applyOptionToCommand(ctx, cmd, r({ name, desc, config })),
); );
export const CommandUserFields = (fields: FieldCollector<'user'>) => export const CommandUserFields = (fields: FieldCollector<'user'>) =>
CommandDef((cmd) => cmd.userFields(fields)); CommandDef((cmd, ctx, r) => cmd.userFields(r(fields)));
export const CommandChannelFields = (fields: FieldCollector<'channel'>) => export const CommandChannelFields = (fields: FieldCollector<'channel'>) =>
CommandDef((cmd) => cmd.channelFields(fields)); CommandDef((cmd, ctx, r) => cmd.channelFields(r(fields)));
export const CommandBefore = (callback: Command.Action, append = false) => export const CommandBefore = (callback: Command.Action, append = false) =>
CommandDef((cmd) => cmd.before(callback, append)); CommandDef((cmd, ctx, r) => cmd.before(callback, append));
export const CommandAction = (callback: Command.Action, prepend = false) => export const CommandAction = (callback: Command.Action, prepend = false) =>
CommandDef((cmd) => cmd.action(callback, prepend)); CommandDef((cmd, ctx, r) => cmd.action(callback, prepend));
export const CommandTemplate = (name: string, text: string | Dict<string>) => export const CommandTemplate = (name: string, text: string | Dict<string>) =>
CommandDef((cmd, ctx) => { CommandDef((cmd, ctx, r) => {
registerTemplate({ name, text: adaptLocaleDict(text) }, ctx, cmd); registerTemplate(
{ name: r(name), text: adaptLocaleDict(r(text)) },
ctx,
cmd,
);
return cmd; return cmd;
}); });
// Command put config // Command put config
export const PutValue = (value: string) => CommandPut.decorate('value', value);
export const PutArgv = (field?: keyof Argv) => export const PutArgv = (field?: keyof Argv) =>
field ? CommandPut.decorate('argvField', field) : CommandPut.decorate('argv'); field ? CommandPut.decorate('argvField', field) : CommandPut.decorate('argv');
export const PutSession = (field?: keyof Session) => export const PutSession = (field?: keyof Session) =>
...@@ -231,8 +236,8 @@ export const TopLevelAction = (action: TopLevelActionDef): ClassDecorator => ...@@ -231,8 +236,8 @@ export const TopLevelAction = (action: TopLevelActionDef): ClassDecorator =>
Metadata.append('KoishiTopLevelAction', action); Metadata.append('KoishiTopLevelAction', action);
export const DefineTemplate = (name: string, text: string | Dict<string>) => export const DefineTemplate = (name: string, text: string | Dict<string>) =>
TopLevelAction((ctx) => TopLevelAction((ctx, obj, r) =>
registerTemplate({ name, text: adaptLocaleDict(text) }, ctx), registerTemplate({ name, text: adaptLocaleDict(r(text)) }, ctx),
); );
export function DefineLocale(locale: string, dict: I18n.Store): ClassDecorator; export function DefineLocale(locale: string, dict: I18n.Store): ClassDecorator;
...@@ -245,9 +250,9 @@ export function DefineLocale( ...@@ -245,9 +250,9 @@ export function DefineLocale(
locale: string, locale: string,
...args: [I18n.Store] | [string, I18n.Node] ...args: [I18n.Store] | [string, I18n.Node]
): ClassDecorator { ): ClassDecorator {
return TopLevelAction((ctx) => return TopLevelAction((ctx, obj, r) =>
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
ctx.i18n.define(locale, ...args), ctx.i18n.define(r(locale), ...r(args)),
); );
} }
...@@ -117,7 +117,11 @@ export interface CommandOptionConfig { ...@@ -117,7 +117,11 @@ export interface CommandOptionConfig {
config?: CommandOptionConfigWithDescription; config?: CommandOptionConfigWithDescription;
} }
export type CommandDefinitionFun = (cmd: Command, ctx: Context) => Command; export type CommandDefinitionFun = (
cmd: Command,
ctx: Context,
renderer: ParamRenderer,
) => Command;
export interface KoishiRouteDef { export interface KoishiRouteDef {
path: string; path: string;
...@@ -148,7 +152,11 @@ export interface TemplateConfig { ...@@ -148,7 +152,11 @@ export interface TemplateConfig {
text: Dict<string>; text: Dict<string>;
} }
export type TopLevelActionDef = (ctx: Context, obj: any) => void; export type TopLevelActionDef = (
ctx: Context,
obj: any,
renderer: ParamRenderer,
) => void;
export interface CommandOptionConfigWithDescription extends Argv.OptionConfig { export interface CommandOptionConfigWithDescription extends Argv.OptionConfig {
description?: string | Dict<string>; description?: string | Dict<string>;
...@@ -166,3 +174,5 @@ export interface CommandArgDef { ...@@ -166,3 +174,5 @@ export interface CommandArgDef {
index: number; index: number;
decl?: Argv.Declaration; decl?: Argv.Declaration;
} }
export type ParamRenderer = <T>(v: T) => T;
...@@ -5,7 +5,11 @@ import { ...@@ -5,7 +5,11 @@ import {
} from './def'; } from './def';
import { reflector } from './meta/meta-fetch'; import { reflector } from './meta/meta-fetch';
import { Context } from 'koishi'; import { Context } from 'koishi';
import { getContextFromFilters } from './utility'; import {
generateRenderer,
getContextFromFilters,
renderObject,
} from './utility';
import { DoRegister } from './registry'; import { DoRegister } from './registry';
import _ from 'lodash'; import _ from 'lodash';
...@@ -15,7 +19,11 @@ export interface DoRegisterResult<T> extends DoRegister.Config { ...@@ -15,7 +19,11 @@ export interface DoRegisterResult<T> extends DoRegister.Config {
} }
export class Registrar<T = any> { export class Registrar<T = any> {
constructor(private obj: T, private alternativeObject?: any) {} constructor(
private obj: T,
private alternativeObject?: any,
private view: Record<any, any> = {},
) {}
getAllFieldsToRegister(): (keyof T)[] { getAllFieldsToRegister(): (keyof T)[] {
const arr = reflector.getArray(KoishiDoRegisterKeys, this.obj); const arr = reflector.getArray(KoishiDoRegisterKeys, this.obj);
...@@ -43,34 +51,49 @@ export class Registrar<T = any> { ...@@ -43,34 +51,49 @@ export class Registrar<T = any> {
return getContextFromFilters(ctx, contextFilters); return getContextFromFilters(ctx, contextFilters);
} }
register(ctx: Context, key: keyof T, autoScope = true): DoRegisterResult<T> { register(
ctx: Context,
key: keyof T,
autoScope = true,
extraView: Record<any, any> = {},
): DoRegisterResult<T> {
if (autoScope) { if (autoScope) {
ctx = this.getScopeContext(ctx, key, true); ctx = this.getScopeContext(ctx, key, true);
} }
const _key = key as string; const _key = key as string;
const data = reflector.get(KoishiDoRegister, this.obj, _key); let data = reflector.get(KoishiDoRegister, this.obj, _key);
if (!data) return; if (!data) return;
data = renderObject(data, { ...this.view, ...extraView });
const result = DoRegister.registry.execute( const result = DoRegister.registry.execute(
data, data,
ctx, ctx,
this.obj, this.obj,
_key, _key,
this.alternativeObject, this.alternativeObject,
this.view,
); );
return { ...data, key: key as keyof T & string, result }; return { ...data, key: key as keyof T & string, result };
} }
registerAll(ctx: Context, autoScope = false) { registerAll(
ctx: Context,
autoScope = false,
extraView: Record<any, any> = {},
) {
if (autoScope) { if (autoScope) {
ctx = this.getScopeContext(ctx); ctx = this.getScopeContext(ctx);
} }
this.performTopActions(ctx, false); this.performTopActions(ctx, false);
return this.getAllFieldsToRegister().map((key) => return this.getAllFieldsToRegister().map((key) =>
this.register(ctx, key, true), this.register(ctx, key, true, extraView),
); );
} }
performTopActions(ctx: Context, autoScope = false) { performTopActions(
ctx: Context,
autoScope = false,
extraView: Record<any, any> = {},
) {
if (autoScope) { if (autoScope) {
ctx = this.getScopeContext(ctx); ctx = this.getScopeContext(ctx);
} }
...@@ -81,6 +104,7 @@ export class Registrar<T = any> { ...@@ -81,6 +104,7 @@ export class Registrar<T = any> {
); );
} }
actions = _.uniq(actions); actions = _.uniq(actions);
actions.forEach((action) => action(ctx, this.obj)); const renderer = generateRenderer({ ...this.view, ...extraView });
actions.forEach((action) => action(ctx, this.obj, renderer));
} }
} }
import { MappingStruct } from '../def'; import { MappingStruct } from '../def';
import { renderObject } from '../utility';
export class AbstractRegistry<M extends Record<string | number | symbol, any>> { export class AbstractRegistry<M extends Record<string | number | symbol, any>> {
private map = new Map<keyof M, any>(); private map = new Map<keyof M, any>();
......
...@@ -12,6 +12,7 @@ import { ...@@ -12,6 +12,7 @@ import {
applyNativeTypeToArg, applyNativeTypeToArg,
applyOptionToCommand, applyOptionToCommand,
registerTemplate, registerTemplate,
renderObject,
} from '../../utility'; } from '../../utility';
import { Metadata } from '../../meta/metadata.decorators'; import { Metadata } from '../../meta/metadata.decorators';
import { reflector } from '../../meta/meta-fetch'; import { reflector } from '../../meta/meta-fetch';
...@@ -32,6 +33,7 @@ export namespace CommandPut { ...@@ -32,6 +33,7 @@ export namespace CommandPut {
renderer: string | undefined; renderer: string | undefined;
template: TemplateConfig; template: TemplateConfig;
typeClass: void; typeClass: void;
value: string;
} }
export type Config<K extends keyof ConfigMap = keyof ConfigMap> = export type Config<K extends keyof ConfigMap = keyof ConfigMap> =
...@@ -41,7 +43,7 @@ export namespace CommandPut { ...@@ -41,7 +43,7 @@ export namespace CommandPut {
ConfigMap, ConfigMap,
void, void,
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
[Command, Context, Function] [Command, Context, Function, any]
>(); >();
preRegistry.extend('option', (data, cmd, ctx, nativeType) => preRegistry.extend('option', (data, cmd, ctx, nativeType) =>
...@@ -82,7 +84,7 @@ export namespace CommandPut { ...@@ -82,7 +84,7 @@ export namespace CommandPut {
registerTemplate(data, ctx, cmd), registerTemplate(data, ctx, cmd),
); );
preRegistry.extend('typeClass', (data, cmd, ctx, nativeType) => { preRegistry.extend('typeClass', (data, cmd, ctx, nativeType, view) => {
const keys = reflector.getArray('KoishiPutClassFieldKeys', nativeType); const keys = reflector.getArray('KoishiPutClassFieldKeys', nativeType);
for (const key of keys) { for (const key of keys) {
const meta = reflector.get('KoishiPutClassField', nativeType, key); const meta = reflector.get('KoishiPutClassField', nativeType, key);
...@@ -92,7 +94,13 @@ export namespace CommandPut { ...@@ -92,7 +94,13 @@ export namespace CommandPut {
nativeType.prototype, nativeType.prototype,
key, key,
); );
preRegistry.execute(meta, cmd, ctx, propertyNativeType); preRegistry.execute(
renderObject(meta, view),
cmd,
ctx,
propertyNativeType,
view,
);
} }
}); });
...@@ -100,9 +108,10 @@ export namespace CommandPut { ...@@ -100,9 +108,10 @@ export namespace CommandPut {
ConfigMap, ConfigMap,
any, any,
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/ban-types
[Argv, any[], Function] [Argv, any[], Function, any]
>(); >();
registry.extend('value', (data) => data);
registry.extend('args', (data, argv, args) => args); registry.extend('args', (data, argv, args) => args);
registry.extend('arg', (data, argv, args) => args[data.index]); registry.extend('arg', (data, argv, args) => args[data.index]);
registry.extend('argv', (data, argv, args) => argv); registry.extend('argv', (data, argv, args) => argv);
...@@ -141,7 +150,7 @@ export namespace CommandPut { ...@@ -141,7 +150,7 @@ export namespace CommandPut {
); );
registry.extend( registry.extend(
'typeClass', 'typeClass',
(data, argv, args, nativeType: { new (): any }) => { (data, argv, args, nativeType: { new (): any }, view) => {
const keys = reflector.getArray('KoishiPutClassFieldKeys', nativeType); const keys = reflector.getArray('KoishiPutClassFieldKeys', nativeType);
const obj = new nativeType(); const obj = new nativeType();
for (const key of keys) { for (const key of keys) {
...@@ -152,7 +161,13 @@ export namespace CommandPut { ...@@ -152,7 +161,13 @@ export namespace CommandPut {
nativeType.prototype, nativeType.prototype,
key, key,
); );
obj[key] = registry.execute(meta, argv, args, propertyNativeType); obj[key] = registry.execute(
renderObject(meta, view),
argv,
args,
propertyNativeType,
view,
);
} }
return obj; return obj;
}, },
......
...@@ -14,7 +14,7 @@ import { ...@@ -14,7 +14,7 @@ import {
import { Metadata } from '../../meta/metadata.decorators'; import { Metadata } from '../../meta/metadata.decorators';
import { reflector } from '../../meta/meta-fetch'; import { reflector } from '../../meta/meta-fetch';
import { CommandPut } from './command-put'; import { CommandPut } from './command-put';
import { applySelector } from '../../utility'; import { applySelector, generateRenderer, renderObject } from '../../utility';
// eslint-disable-next-line @typescript-eslint/no-namespace // eslint-disable-next-line @typescript-eslint/no-namespace
export namespace DoRegister { export namespace DoRegister {
...@@ -27,7 +27,17 @@ export namespace DoRegister { ...@@ -27,7 +27,17 @@ export namespace DoRegister {
class SpecificRegistry extends MethodRegistry< class SpecificRegistry extends MethodRegistry<
ConfigMap, ConfigMap,
any, any,
[Context, any, string, any | undefined] [
Context,
// obj
any,
// key
string,
// extra obj
any | undefined,
// view
any | undefined,
]
> { > {
define<K extends keyof ConfigMap>( define<K extends keyof ConfigMap>(
name: K, name: K,
...@@ -120,7 +130,7 @@ export namespace DoRegister { ...@@ -120,7 +130,7 @@ export namespace DoRegister {
export const command = registry.define( export const command = registry.define(
'command', 'command',
(data, ctx, obj, key, extraObj) => { (data, ctx, obj, key, extraObj, view) => {
let command = ctx.command(data.def, data.desc, data.config); let command = ctx.command(data.def, data.desc, data.config);
const commandDefs = reflector.getProperty( const commandDefs = reflector.getProperty(
KoishiCommandDefinition, KoishiCommandDefinition,
...@@ -128,8 +138,9 @@ export namespace DoRegister { ...@@ -128,8 +138,9 @@ export namespace DoRegister {
key, key,
extraObj, extraObj,
); );
const renderer = generateRenderer(view);
for (const commandDef of commandDefs) { for (const commandDef of commandDefs) {
command = commandDef(command, ctx) || command; command = commandDef(command, ctx, renderer) || command;
} }
if (!data.config?.empty) { if (!data.config?.empty) {
if (!data.putOptions) { if (!data.putOptions) {
...@@ -143,11 +154,23 @@ export namespace DoRegister { ...@@ -143,11 +154,23 @@ export namespace DoRegister {
continue; continue;
} }
const nativeType = data.paramTypes[i]; const nativeType = data.paramTypes[i];
CommandPut.preRegistry.execute(putOption, command, ctx, nativeType); CommandPut.preRegistry.execute(
putOption,
command,
ctx,
nativeType,
view,
);
} }
command.action((argv: Argv, ...args: any[]) => { command.action((argv: Argv, ...args: any[]) => {
const params = data.putOptions.map((o, i) => const params = data.putOptions.map((o, i) =>
CommandPut.registry.execute(o, argv, args, data.paramTypes[i]), CommandPut.registry.execute(
o,
argv,
args,
data.paramTypes[i],
view,
),
); );
return obj[key](...params); return obj[key](...params);
}); });
......
...@@ -3,9 +3,12 @@ import { ...@@ -3,9 +3,12 @@ import {
CommandOptionConfig, CommandOptionConfig,
ContextSelector, ContextSelector,
OnContextFunction, OnContextFunction,
ParamRenderer,
TemplateConfig, TemplateConfig,
} from '../def'; } from '../def';
import { applyNativeTypeToArg } from './native-type-mapping'; import { applyNativeTypeToArg } from './native-type-mapping';
import Mustache from 'mustache';
import _ from 'lodash';
export function applySelector( export function applySelector(
ctx: Context, ctx: Context,
...@@ -78,3 +81,34 @@ export function applyOptionToCommand( ...@@ -78,3 +81,34 @@ export function applyOptionToCommand(
applyNativeTypeToArg(option, nativeType); applyNativeTypeToArg(option, nativeType);
return cmd; return cmd;
} }
export function renderObject<T = any>(
object: T,
view: any,
visited?: Set<any>,
): T;
export function renderObject(object: any, view: any, visited: Set<any>): any {
if (!view || !object) {
return object;
}
visited ??= new Set();
if (typeof object === 'string') {
return Mustache.render(object, view, undefined, { escape: (v) => v });
}
if (visited.has(object)) {
return object;
}
if (Array.isArray(object)) {
visited.add(object);
return (object as any[]).map((item) => renderObject(item, view, visited));
}
if (typeof object === 'object') {
visited.add(object);
return _.mapValues(object, (value) => renderObject(value, view, visited));
}
return object;
}
export function generateRenderer(view: any): ParamRenderer {
return (v) => renderObject(v, view);
}
...@@ -3,6 +3,7 @@ import { ...@@ -3,6 +3,7 @@ import {
PutArg, PutArg,
PutObject, PutObject,
PutOption, PutOption,
PutValue,
UseCommand, UseCommand,
UseEvent, UseEvent,
UseMiddleware, UseMiddleware,
...@@ -50,6 +51,15 @@ class MyClass { ...@@ -50,6 +51,15 @@ class MyClass {
async onSkirt(@PutObject() arg: SkirtArg) { async onSkirt(@PutObject() arg: SkirtArg) {
return `I have ${arg.count} ${arg.color} skirts.`; return `I have ${arg.count} ${arg.color} skirts.`;
} }
@UseCommand('{{name}}')
@CommandUsage('{{usage}}')
async onGeneric(
@PutOption('{{option}}', '-c <count>') count: number,
@PutValue('{{name}}') name: string,
) {
return `I have ${count} ${name}.`;
}
} }
const registrar = new Registrar(new MyClass()); const registrar = new Registrar(new MyClass());
...@@ -105,4 +115,21 @@ describe('Register', () => { ...@@ -105,4 +115,21 @@ describe('Register', () => {
command.execute({ args: ['4'], options: { color: 'red' } }), command.execute({ args: ['4'], options: { color: 'red' } }),
).resolves.toBe('I have 4 red skirts.'); ).resolves.toBe('I have 4 red skirts.');
}); });
it('should work on template', () => {
const registrar = new Registrar(new MyClass(), undefined, {
name: 'socks',
usage: 'Socks count',
option: 'count',
});
const result = registrar.register(app, 'onGeneric');
expect(result.type).toBe('command');
const command: Command = result.result;
expect(command._usage).toBe('Socks count');
expect(command.name).toBe('socks');
expect(command._options.count.name).toBe('count');
expect(command.execute({ options: { count: 7 } })).resolves.toBe(
'I have 7 socks.',
);
});
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment