sonamu 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/api/sonamu.d.ts.map +1 -1
  2. package/dist/api/sonamu.js +13 -22
  3. package/dist/api/websocket-helpers.js +1 -1
  4. package/dist/auth/audit-log/builders.d.ts.map +1 -1
  5. package/dist/auth/audit-log/builders.js +3 -1
  6. package/dist/auth/audit-log/client-ip.d.ts +3 -0
  7. package/dist/auth/audit-log/client-ip.d.ts.map +1 -0
  8. package/dist/auth/audit-log/client-ip.js +27 -0
  9. package/dist/auth/audit-log/events.d.ts +1 -0
  10. package/dist/auth/audit-log/events.d.ts.map +1 -1
  11. package/dist/auth/audit-log/events.js +1 -1
  12. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  13. package/dist/auth/audit-log-ingestor.js +8 -3
  14. package/dist/auth/better-auth-request.d.ts +3 -0
  15. package/dist/auth/better-auth-request.d.ts.map +1 -0
  16. package/dist/auth/better-auth-request.js +23 -0
  17. package/dist/bin/build-config.d.ts.map +1 -1
  18. package/dist/bin/build-config.js +3 -3
  19. package/dist/bin/cli.js +1 -1
  20. package/dist/entity/entity.js +1 -1
  21. package/dist/index.js +1 -1
  22. package/dist/migration/code-generation.js +1 -1
  23. package/dist/syncer/checksum.js +6 -13
  24. package/dist/testing/index.d.ts +1 -0
  25. package/dist/testing/index.d.ts.map +1 -1
  26. package/dist/testing/index.js +4 -2
  27. package/dist/ui/api.js +1 -1
  28. package/package.json +3 -3
  29. package/src/api/sonamu.ts +14 -29
  30. package/src/auth/audit-log/builders.ts +3 -0
  31. package/src/auth/audit-log/client-ip.ts +38 -0
  32. package/src/auth/audit-log/events.ts +1 -0
  33. package/src/auth/audit-log-ingestor.ts +22 -15
  34. package/src/auth/better-auth-request.ts +20 -0
  35. package/src/bin/build-config.ts +3 -2
  36. package/src/skills/sonamu/puri.md +33 -0
  37. package/src/syncer/checksum.ts +7 -12
  38. package/src/testing/index.ts +1 -0
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { differenceWith, init_utils } from "../utils/utils.js";
2
3
  import { globAsync, init_async_utils } from "../utils/async-utils.js";
3
4
  import { exists, init_fs_utils } from "../utils/fs-utils.js";
4
- import { differenceWith, init_utils } from "../utils/utils.js";
5
5
  import { Sonamu, init_sonamu } from "../api/sonamu.js";
6
6
  import { GLOB_EXCLUDE, getChecksumPatternGroupInAbsolutePath, init_file_patterns } from "./file-patterns.js";
7
7
  import { isEqual } from "radashi";
@@ -67,17 +67,10 @@ async function saveChecksums(checksums) {
67
67
  await writeFile(checksumFilePath, JSON.stringify(serialized, null, 2), "utf-8");
68
68
  }
69
69
  async function getChecksumOfFile(filePath) {
70
- return new Promise((resolve, reject) => {
71
- const hash = crypto.createHash("sha1");
72
- const input = createReadStream(filePath);
73
- input.on("error", reject);
74
- input.on("data", (chunk) => {
75
- hash.update(chunk);
76
- });
77
- input.on("close", () => {
78
- resolve(hash.digest("hex"));
79
- });
80
- });
70
+ const hash = crypto.createHash("sha1");
71
+ const input = createReadStream(filePath);
72
+ for await (const chunk of input) hash.update(chunk);
73
+ return hash.digest("hex");
81
74
  }
82
75
  var init_checksum = __esmMin((() => {
83
76
  init_sonamu();
@@ -90,4 +83,4 @@ var init_checksum = __esmMin((() => {
90
83
  init_checksum();
91
84
  export { findChangedFilesUsingChecksums, init_checksum, renewChecksums };
92
85
 
93
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tzdW0uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNlci9jaGVja3N1bS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY3J5cHRvLCB7IHR5cGUgQmluYXJ5TGlrZSB9IGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCB7IGNyZWF0ZVJlYWRTdHJlYW0sIHR5cGUgUGF0aExpa2UgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCBlcXVhbCBmcm9tIFwiZmFzdC1kZWVwLWVxdWFsXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcInJhZGFzaGlcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IGdsb2JBc3luYyB9IGZyb20gXCIuLi91dGlscy9hc3luYy11dGlsc1wiO1xuaW1wb3J0IHsgZXhpc3RzIH0gZnJvbSBcIi4uL3V0aWxzL2ZzLXV0aWxzXCI7XG5pbXBvcnQgeyB0eXBlIEFic29sdXRlUGF0aCwgdHlwZSBBcHBSZWxhdGl2ZVBhdGggfSBmcm9tIFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiO1xuaW1wb3J0IHsgZGlmZmVyZW5jZVdpdGggfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGgsIEdMT0JfRVhDTFVERSB9IGZyb20gXCIuL2ZpbGUtcGF0dGVybnNcIjtcblxudHlwZSBQYXRoQW5kQ2hlY2tzdW0gPSB7XG4gIHBhdGg6IEFic29sdXRlUGF0aDtcbiAgY2hlY2tzdW06IHN0cmluZztcbn07XG5cbi8qKlxuICog7LK07YGs7ISsIO2MjOydvOyXkCDsoIDsnqXrkJwg64K07Jqp6rO8IO2YhOyerCDsi6TsoJwg7YyM7J287J2YIOyytO2BrOyErOydhCDruYTqtZDtlZjsl6wg67OA6rK965CcIO2MjOydvOydhCDssL7sirXri4jri6QuXG4gKiBAcmV0dXJucyDrs4Dqsr3rkJwg7YyM7J28IOqyveuhnCDrsLDsl7QuIO2UhOuhnOygne2KuCDro6jtirjrtoDthLAg7Iqs656Y7Iuc66GcIOyLnOyeke2VqeuLiOuLpC4g7JiI7IucOiBcIi9zcmMvYXBwbGljYXRpb24vdXNlci91c2VyLm1vZGVsLnRzXCJcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbmRDaGFuZ2VkRmlsZXNVc2luZ0NoZWNrc3VtcygpOiBQcm9taXNlPEFic29sdXRlUGF0aFtdPiB7XG4gIGNvbnN0IGNhbGN1bGF0ZWRDaGVja3N1bXMgPSBhd2FpdCBnZXRDdXJyZW50Q2hlY2tzdW1zKCk7XG4gIGNvbnN0IHNhdmVkQ2hlY2tzdW1zID0gYXdhaXQgZ2V0UHJldmlvdXNDaGVja3N1bXMoKTtcblxuICBjb25zdCBpc1NhbWUgPSBlcXVhbChjYWxjdWxhdGVkQ2hlY2tzdW1zLCBzYXZlZENoZWNrc3Vtcyk7XG4gIGlmIChpc1NhbWUpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gZGlmZmVyZW5jZVdpdGgoY2FsY3VsYXRlZENoZWNrc3Vtcywgc2F2ZWRDaGVja3N1bXMsIGlzRXF1YWwpLm1hcCgocikgPT4gci5wYXRoKTtcbn1cblxuLyoqXG4gKiDssrTtgazshKzsnYQg6rCx7Iug7ZWp64uI64ukLlxuICog7ZiE7J6sIO2MjOydvOuTpOydmCDssrTtgazshKzsnYQg6rOE7IKw7ZW07IScIOq1rO2VnCDri6TsnYwsIOyytO2BrOyErCDtjIzsnbzsl5Ag7KCA7J6l65CcIOuCtOyaqeqzvCDri6TrpbTrqbQg7LK07YGs7ISsIO2MjOydvOydhCDqsLHsi6Dtlanri4jri6QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW5ld0NoZWNrc3VtcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY2FsY3VsYXRlZENoZWNrc3VtcyA9IGF3YWl0IGdldEN1cnJlbnRDaGVja3N1bXMoKTtcbiAgY29uc3Qgc2F2ZWRDaGVja3N1bXMgPSBhd2FpdCBnZXRQcmV2aW91c0NoZWNrc3VtcygpO1xuXG4gIGNvbnN0IGlzU2FtZSA9IGVxdWFsKGNhbGN1bGF0ZWRDaGVja3N1bXMsIHNhdmVkQ2hlY2tzdW1zKTtcbiAgaWYgKGlzU2FtZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IHNhdmVDaGVja3N1bXMoY2FsY3VsYXRlZENoZWNrc3Vtcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEN1cnJlbnRDaGVja3N1bXMoKTogUHJvbWlzZTxQYXRoQW5kQ2hlY2tzdW1bXT4ge1xuICBjb25zdCBhbGxQYXRocyA9IChcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIE9iamVjdC5lbnRyaWVzKGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGgoKSkubWFwKChbX2ZpbGVUeXBlLCBwYXR0ZXJuXSkgPT4ge1xuICAgICAgICByZXR1cm4gZ2xvYkFzeW5jKHBhdHRlcm4sIHsgZXhjbHVkZTogR0xPQl9FWENMVURFIH0pO1xuICAgICAgfSksXG4gICAgKVxuICApLmZsYXQoKTtcblxuICAvLyDrj5nsnbwg7YyM7J287J20IOyXrOufrCDtjKjthLTsl5Ag66ek7LmY65CgIOyImCDsnojsnLzrr4DroZwo7JiIOiBzZC5nZW5lcmF0ZWQudHPripQgZ2VuZXJhdGVk7JmAIHNkR2VuZXJhdGVk7JeQIOuqqOuRkCDrp6TsuZgpXG4gIC8vIOykkeuztSDsoJzqsbAg7ZuEIOyViOyglSDsoJXroKwuXG4gIGNvbnN0IGZpbGVQYXRocyA9IEFycmF5LmZyb20obmV3IFNldChhbGxQYXRocykpLnRvU29ydGVkKCkgYXMgQWJzb2x1dGVQYXRoW107XG5cbiAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGZpbGVQYXRocy5tYXAoYXN5bmMgKGZpbGVQYXRoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYXRoOiBmaWxlUGF0aCxcbiAgICAgICAgY2hlY2tzdW06IGF3YWl0IGdldENoZWNrc3VtT2ZGaWxlKGZpbGVQYXRoKSxcbiAgICAgIH07XG4gICAgfSksXG4gICk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFByZXZpb3VzQ2hlY2tzdW1zKCk6IFByb21pc2U8UGF0aEFuZENoZWNrc3VtW10+IHtcbiAgY29uc3QgY2hlY2tzdW1GaWxlUGF0aCA9IGdldENoZWNrc3VtRmlsZVBhdGgoKTtcbiAgaWYgKCEoYXdhaXQgZXhpc3RzKGNoZWNrc3VtRmlsZVBhdGgpKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcHJldmlvdXNDaGVja3N1bXMgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGNoZWNrc3VtRmlsZVBhdGgsIFwidXRmLThcIikpLm1hcChcbiAgICAgIChyOiB7IHBhdGg6IEFwcFJlbGF0aXZlUGF0aDsgY2hlY2tzdW06IHN0cmluZyB9KSA9PiAoe1xuICAgICAgICBwYXRoOiBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCByLnBhdGgpLCAvLyDssrTtgazshKwg7YyM7J287JeQ7IScIOydveydhCDrlYw6IGFwcFJvb3Qg7IOB64yAIOqyveuhnCDihpIg7KCI64yAIOqyveuhnFxuICAgICAgICBjaGVja3N1bTogci5jaGVja3N1bSxcbiAgICAgIH0pLFxuICAgICkgYXMgUGF0aEFuZENoZWNrc3VtW107XG4gICAgcmV0dXJuIHByZXZpb3VzQ2hlY2tzdW1zO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8g7LK07YGs7ISsIO2MjOydvOydtCDshpDsg4HrkJwg6rK97JqwIOu5iCDrsLDsl7Qg67CY7ZmYICjsoITssrQg7J6s64+Z6riw7ZmUIOycoOuPhClcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBg7LK07YGs7ISsIO2MjOydvCgke2NoZWNrc3VtRmlsZVBhdGh9KeydhCDtjIzsi7HtlZjripQg642wIOyLpO2MqO2WiOyKteuLiOuLpC4g7KCE7LK0IOyerOuPmeq4sO2ZlOulvCDsp4Ttlontlanri4jri6QuYCxcbiAgICAgIGUsXG4gICAgKTtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q2hlY2tzdW1GaWxlUGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICByZXR1cm4gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzb25hbXUubG9ja1wiKSBhcyBBYnNvbHV0ZVBhdGg7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNhdmVDaGVja3N1bXMoY2hlY2tzdW1zOiBQYXRoQW5kQ2hlY2tzdW1bXSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjaGVja3N1bUZpbGVQYXRoID0gZ2V0Q2hlY2tzdW1GaWxlUGF0aCgpO1xuICAvLyBhcHBSb290IOyDgeuMgCDqsr3roZzroZwg7KeB66Cs7ZmUICsg7JWM7YyM67KzIOyViOyglSDsoJXroKwgKFBSIGRpZmYg6rmo64GX7ZWY6rKMIOycoOyngClcbiAgY29uc3Qgc2VyaWFsaXplZCA9IGNoZWNrc3Vtc1xuICAgIC5tYXAoKHIpID0+ICh7XG4gICAgICBwYXRoOiBwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcHBSb290UGF0aCwgci5wYXRoKSwgLy8g7LK07YGs7ISsIO2MjOydvOyXkCDsoIDsnqXtlaAg65WMOiDsoIjrjIAg6rK966GcIOKGkiBhcHBSb290IOyDgeuMgCDqsr3roZxcbiAgICAgIGNoZWNrc3VtOiByLmNoZWNrc3VtLFxuICAgIH0pKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLnBhdGgubG9jYWxlQ29tcGFyZShiLnBhdGgpKTtcbiAgYXdhaXQgd3JpdGVGaWxlKGNoZWNrc3VtRmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KHNlcmlhbGl6ZWQsIG51bGwsIDIpLCBcInV0Zi04XCIpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRDaGVja3N1bU9mRmlsZShmaWxlUGF0aDogUGF0aExpa2UpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgaGFzaCA9IGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMVwiKTtcbiAgICBjb25zdCBpbnB1dCA9IGNyZWF0ZVJlYWRTdHJlYW0oZmlsZVBhdGgpO1xuICAgIGlucHV0Lm9uKFwiZXJyb3JcIiwgcmVqZWN0KTtcbiAgICBpbnB1dC5vbihcImRhdGFcIiwgKGNodW5rOiBCaW5hcnlMaWtlKSA9PiB7XG4gICAgICBoYXNoLnVwZGF0ZShjaHVuayk7XG4gICAgfSk7XG4gICAgaW5wdXQub24oXCJjbG9zZVwiLCAoKSA9PiB7XG4gICAgICByZXNvbHZlKGhhc2guZGlnZXN0KFwiaGV4XCIpKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBd0JBLGVBQXNCLGlDQUEwRDtDQUM5RSxNQUFNLHNCQUFzQixNQUFNLG9CQUFvQjtDQUN0RCxNQUFNLGlCQUFpQixNQUFNLHFCQUFxQjtDQUdsRCxJQURlLE1BQU0scUJBQXFCLGNBQ3RDLEdBQ0YsT0FBTyxDQUFDO0NBR1YsT0FBTyxlQUFlLHFCQUFxQixnQkFBZ0IsT0FBTyxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsSUFBSTtBQUN2Rjs7Ozs7QUFNQSxlQUFzQixpQkFBZ0M7Q0FDcEQsTUFBTSxzQkFBc0IsTUFBTSxvQkFBb0I7Q0FJdEQsSUFEZSxNQUFNLHFCQUFxQixNQUZiLHFCQUFxQixDQUc5QyxHQUNGO0NBR0YsTUFBTSxjQUFjLG1CQUFtQjtBQUN6QztBQUVBLGVBQWUsc0JBQWtEO0NBQy9ELE1BQU0sWUFDSixNQUFNLFFBQVEsSUFDWixPQUFPLFFBQVEsc0NBQXNDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxXQUFXLGFBQWE7RUFDcEYsT0FBTyxVQUFVLFNBQVMsRUFBRSxTQUFTLGFBQWEsQ0FBQztDQUNyRCxDQUFDLENBQ0gsRUFBQSxDQUNBLEtBQUs7Q0FJUCxNQUFNLFlBQVksTUFBTSxLQUFLLElBQUksSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLFNBQVM7Q0FFekQsT0FBTyxNQUFNLFFBQVEsSUFDbkIsVUFBVSxJQUFJLE9BQU8sYUFBYTtFQUNoQyxPQUFPO0dBQ0wsTUFBTTtHQUNOLFVBQVUsTUFBTSxrQkFBa0IsUUFBUTtFQUM1QztDQUNGLENBQUMsQ0FDSDtBQUNGO0FBRUEsZUFBZSx1QkFBbUQ7Q0FDaEUsTUFBTSxtQkFBbUIsb0JBQW9CO0NBQzdDLElBQUksQ0FBRSxNQUFNLE9BQU8sZ0JBQWdCLEdBQ2pDLE9BQU8sQ0FBQztDQUdWLElBQUk7RUFPRixPQU4wQixLQUFLLE1BQU0sTUFBTSxTQUFTLGtCQUFrQixPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQzdFLE9BQW9EO0dBQ25ELE1BQU0sS0FBSyxLQUFLLE9BQU8sYUFBYSxFQUFFLElBQUk7R0FDMUMsVUFBVSxFQUFFO0VBQ2QsRUFFSztDQUNULFNBQVMsR0FBRztFQUVWLFFBQVEsS0FDTixVQUFVLGlCQUFpQixvQ0FDM0IsQ0FDRjtFQUNBLE9BQU8sQ0FBQztDQUNWO0FBQ0Y7QUFFQSxTQUFTLHNCQUFvQztDQUMzQyxPQUFPLEtBQUssS0FBSyxPQUFPLGFBQWEsYUFBYTtBQUNwRDtBQUVBLGVBQWUsY0FBYyxXQUE2QztDQUN4RSxNQUFNLG1CQUFtQixvQkFBb0I7Q0FFN0MsTUFBTSxhQUFhLFVBQ2hCLEtBQUssT0FBTztFQUNYLE1BQU0sS0FBSyxTQUFTLE9BQU8sYUFBYSxFQUFFLElBQUk7RUFDOUMsVUFBVSxFQUFFO0NBQ2QsRUFBRSxDQUFDLENBQ0YsTUFBTSxHQUFHLE1BQU0sRUFBRSxLQUFLLGNBQWMsRUFBRSxJQUFJLENBQUM7Q0FDOUMsTUFBTSxVQUFVLGtCQUFrQixLQUFLLFVBQVUsWUFBWSxNQUFNLENBQUMsR0FBRyxPQUFPO0FBQ2hGO0FBRUEsZUFBZSxrQkFBa0IsVUFBcUM7Q0FDcEUsT0FBTyxJQUFJLFNBQWlCLFNBQVMsV0FBVztFQUM5QyxNQUFNLE9BQU8sT0FBTyxXQUFXLE1BQU07RUFDckMsTUFBTSxRQUFRLGlCQUFpQixRQUFRO0VBQ3ZDLE1BQU0sR0FBRyxTQUFTLE1BQU07RUFDeEIsTUFBTSxHQUFHLFNBQVMsVUFBc0I7R0FDdEMsS0FBSyxPQUFPLEtBQUs7RUFDbkIsQ0FBQztFQUNELE1BQU0sR0FBRyxlQUFlO0dBQ3RCLFFBQVEsS0FBSyxPQUFPLEtBQUssQ0FBQztFQUM1QixDQUFDO0NBQ0gsQ0FBQztBQUNIOzthQXZIc0M7a0JBQ1U7ZUFDTjtZQUVLO29CQUNzQyJ9
86
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tzdW0uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N5bmNlci9jaGVja3N1bS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY3J5cHRvIGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCB7IGNyZWF0ZVJlYWRTdHJlYW0sIHR5cGUgUGF0aExpa2UgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCBlcXVhbCBmcm9tIFwiZmFzdC1kZWVwLWVxdWFsXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcInJhZGFzaGlcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IGdsb2JBc3luYyB9IGZyb20gXCIuLi91dGlscy9hc3luYy11dGlsc1wiO1xuaW1wb3J0IHsgZXhpc3RzIH0gZnJvbSBcIi4uL3V0aWxzL2ZzLXV0aWxzXCI7XG5pbXBvcnQgeyB0eXBlIEFic29sdXRlUGF0aCwgdHlwZSBBcHBSZWxhdGl2ZVBhdGggfSBmcm9tIFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiO1xuaW1wb3J0IHsgZGlmZmVyZW5jZVdpdGggfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGgsIEdMT0JfRVhDTFVERSB9IGZyb20gXCIuL2ZpbGUtcGF0dGVybnNcIjtcblxudHlwZSBQYXRoQW5kQ2hlY2tzdW0gPSB7XG4gIHBhdGg6IEFic29sdXRlUGF0aDtcbiAgY2hlY2tzdW06IHN0cmluZztcbn07XG5cbi8qKlxuICog7LK07YGs7ISsIO2MjOydvOyXkCDsoIDsnqXrkJwg64K07Jqp6rO8IO2YhOyerCDsi6TsoJwg7YyM7J287J2YIOyytO2BrOyErOydhCDruYTqtZDtlZjsl6wg67OA6rK965CcIO2MjOydvOydhCDssL7sirXri4jri6QuXG4gKiBAcmV0dXJucyDrs4Dqsr3rkJwg7YyM7J28IOqyveuhnCDrsLDsl7QuIO2UhOuhnOygne2KuCDro6jtirjrtoDthLAg7Iqs656Y7Iuc66GcIOyLnOyeke2VqeuLiOuLpC4g7JiI7IucOiBcIi9zcmMvYXBwbGljYXRpb24vdXNlci91c2VyLm1vZGVsLnRzXCJcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZpbmRDaGFuZ2VkRmlsZXNVc2luZ0NoZWNrc3VtcygpOiBQcm9taXNlPEFic29sdXRlUGF0aFtdPiB7XG4gIGNvbnN0IGNhbGN1bGF0ZWRDaGVja3N1bXMgPSBhd2FpdCBnZXRDdXJyZW50Q2hlY2tzdW1zKCk7XG4gIGNvbnN0IHNhdmVkQ2hlY2tzdW1zID0gYXdhaXQgZ2V0UHJldmlvdXNDaGVja3N1bXMoKTtcblxuICBjb25zdCBpc1NhbWUgPSBlcXVhbChjYWxjdWxhdGVkQ2hlY2tzdW1zLCBzYXZlZENoZWNrc3Vtcyk7XG4gIGlmIChpc1NhbWUpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gZGlmZmVyZW5jZVdpdGgoY2FsY3VsYXRlZENoZWNrc3Vtcywgc2F2ZWRDaGVja3N1bXMsIGlzRXF1YWwpLm1hcCgocikgPT4gci5wYXRoKTtcbn1cblxuLyoqXG4gKiDssrTtgazshKzsnYQg6rCx7Iug7ZWp64uI64ukLlxuICog7ZiE7J6sIO2MjOydvOuTpOydmCDssrTtgazshKzsnYQg6rOE7IKw7ZW07IScIOq1rO2VnCDri6TsnYwsIOyytO2BrOyErCDtjIzsnbzsl5Ag7KCA7J6l65CcIOuCtOyaqeqzvCDri6TrpbTrqbQg7LK07YGs7ISsIO2MjOydvOydhCDqsLHsi6Dtlanri4jri6QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW5ld0NoZWNrc3VtcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY2FsY3VsYXRlZENoZWNrc3VtcyA9IGF3YWl0IGdldEN1cnJlbnRDaGVja3N1bXMoKTtcbiAgY29uc3Qgc2F2ZWRDaGVja3N1bXMgPSBhd2FpdCBnZXRQcmV2aW91c0NoZWNrc3VtcygpO1xuXG4gIGNvbnN0IGlzU2FtZSA9IGVxdWFsKGNhbGN1bGF0ZWRDaGVja3N1bXMsIHNhdmVkQ2hlY2tzdW1zKTtcbiAgaWYgKGlzU2FtZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGF3YWl0IHNhdmVDaGVja3N1bXMoY2FsY3VsYXRlZENoZWNrc3Vtcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEN1cnJlbnRDaGVja3N1bXMoKTogUHJvbWlzZTxQYXRoQW5kQ2hlY2tzdW1bXT4ge1xuICBjb25zdCBhbGxQYXRocyA9IChcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIE9iamVjdC5lbnRyaWVzKGdldENoZWNrc3VtUGF0dGVybkdyb3VwSW5BYnNvbHV0ZVBhdGgoKSkubWFwKChbX2ZpbGVUeXBlLCBwYXR0ZXJuXSkgPT4ge1xuICAgICAgICByZXR1cm4gZ2xvYkFzeW5jKHBhdHRlcm4sIHsgZXhjbHVkZTogR0xPQl9FWENMVURFIH0pO1xuICAgICAgfSksXG4gICAgKVxuICApLmZsYXQoKTtcblxuICAvLyDrj5nsnbwg7YyM7J287J20IOyXrOufrCDtjKjthLTsl5Ag66ek7LmY65CgIOyImCDsnojsnLzrr4DroZwo7JiIOiBzZC5nZW5lcmF0ZWQudHPripQgZ2VuZXJhdGVk7JmAIHNkR2VuZXJhdGVk7JeQIOuqqOuRkCDrp6TsuZgpXG4gIC8vIOykkeuztSDsoJzqsbAg7ZuEIOyViOyglSDsoJXroKwuXG4gIGNvbnN0IGZpbGVQYXRocyA9IEFycmF5LmZyb20obmV3IFNldChhbGxQYXRocykpLnRvU29ydGVkKCkgYXMgQWJzb2x1dGVQYXRoW107XG5cbiAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKFxuICAgIGZpbGVQYXRocy5tYXAoYXN5bmMgKGZpbGVQYXRoKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYXRoOiBmaWxlUGF0aCxcbiAgICAgICAgY2hlY2tzdW06IGF3YWl0IGdldENoZWNrc3VtT2ZGaWxlKGZpbGVQYXRoKSxcbiAgICAgIH07XG4gICAgfSksXG4gICk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldFByZXZpb3VzQ2hlY2tzdW1zKCk6IFByb21pc2U8UGF0aEFuZENoZWNrc3VtW10+IHtcbiAgY29uc3QgY2hlY2tzdW1GaWxlUGF0aCA9IGdldENoZWNrc3VtRmlsZVBhdGgoKTtcbiAgaWYgKCEoYXdhaXQgZXhpc3RzKGNoZWNrc3VtRmlsZVBhdGgpKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcHJldmlvdXNDaGVja3N1bXMgPSBKU09OLnBhcnNlKGF3YWl0IHJlYWRGaWxlKGNoZWNrc3VtRmlsZVBhdGgsIFwidXRmLThcIikpLm1hcChcbiAgICAgIChyOiB7IHBhdGg6IEFwcFJlbGF0aXZlUGF0aDsgY2hlY2tzdW06IHN0cmluZyB9KSA9PiAoe1xuICAgICAgICBwYXRoOiBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCByLnBhdGgpLCAvLyDssrTtgazshKwg7YyM7J287JeQ7IScIOydveydhCDrlYw6IGFwcFJvb3Qg7IOB64yAIOqyveuhnCDihpIg7KCI64yAIOqyveuhnFxuICAgICAgICBjaGVja3N1bTogci5jaGVja3N1bSxcbiAgICAgIH0pLFxuICAgICkgYXMgUGF0aEFuZENoZWNrc3VtW107XG4gICAgcmV0dXJuIHByZXZpb3VzQ2hlY2tzdW1zO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8g7LK07YGs7ISsIO2MjOydvOydtCDshpDsg4HrkJwg6rK97JqwIOu5iCDrsLDsl7Qg67CY7ZmYICjsoITssrQg7J6s64+Z6riw7ZmUIOycoOuPhClcbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBg7LK07YGs7ISsIO2MjOydvCgke2NoZWNrc3VtRmlsZVBhdGh9KeydhCDtjIzsi7HtlZjripQg642wIOyLpO2MqO2WiOyKteuLiOuLpC4g7KCE7LK0IOyerOuPmeq4sO2ZlOulvCDsp4Ttlontlanri4jri6QuYCxcbiAgICAgIGUsXG4gICAgKTtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q2hlY2tzdW1GaWxlUGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICByZXR1cm4gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzb25hbXUubG9ja1wiKSBhcyBBYnNvbHV0ZVBhdGg7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNhdmVDaGVja3N1bXMoY2hlY2tzdW1zOiBQYXRoQW5kQ2hlY2tzdW1bXSk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjaGVja3N1bUZpbGVQYXRoID0gZ2V0Q2hlY2tzdW1GaWxlUGF0aCgpO1xuICAvLyBhcHBSb290IOyDgeuMgCDqsr3roZzroZwg7KeB66Cs7ZmUICsg7JWM7YyM67KzIOyViOyglSDsoJXroKwgKFBSIGRpZmYg6rmo64GX7ZWY6rKMIOycoOyngClcbiAgY29uc3Qgc2VyaWFsaXplZCA9IGNoZWNrc3Vtc1xuICAgIC5tYXAoKHIpID0+ICh7XG4gICAgICBwYXRoOiBwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcHBSb290UGF0aCwgci5wYXRoKSwgLy8g7LK07YGs7ISsIO2MjOydvOyXkCDsoIDsnqXtlaAg65WMOiDsoIjrjIAg6rK966GcIOKGkiBhcHBSb290IOyDgeuMgCDqsr3roZxcbiAgICAgIGNoZWNrc3VtOiByLmNoZWNrc3VtLFxuICAgIH0pKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLnBhdGgubG9jYWxlQ29tcGFyZShiLnBhdGgpKTtcbiAgYXdhaXQgd3JpdGVGaWxlKGNoZWNrc3VtRmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KHNlcmlhbGl6ZWQsIG51bGwsIDIpLCBcInV0Zi04XCIpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRDaGVja3N1bU9mRmlsZShmaWxlUGF0aDogUGF0aExpa2UpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBoYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGExXCIpO1xuICBjb25zdCBpbnB1dCA9IGNyZWF0ZVJlYWRTdHJlYW0oZmlsZVBhdGgpO1xuICBmb3IgYXdhaXQgKGNvbnN0IGNodW5rIG9mIGlucHV0KSB7XG4gICAgaGFzaC51cGRhdGUoY2h1bmspO1xuICB9XG4gIHJldHVybiBoYXNoLmRpZ2VzdChcImhleFwiKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF3QkEsZUFBc0IsaUNBQTBEO0NBQzlFLE1BQU0sc0JBQXNCLE1BQU0sb0JBQW9CO0NBQ3RELE1BQU0saUJBQWlCLE1BQU0scUJBQXFCO0NBR2xELElBRGUsTUFBTSxxQkFBcUIsY0FDdEMsR0FDRixPQUFPLENBQUM7Q0FHVixPQUFPLGVBQWUscUJBQXFCLGdCQUFnQixPQUFPLENBQUMsQ0FBQyxLQUFLLE1BQU0sRUFBRSxJQUFJO0FBQ3ZGOzs7OztBQU1BLGVBQXNCLGlCQUFnQztDQUNwRCxNQUFNLHNCQUFzQixNQUFNLG9CQUFvQjtDQUl0RCxJQURlLE1BQU0scUJBQXFCLE1BRmIscUJBQXFCLENBRzlDLEdBQ0Y7Q0FHRixNQUFNLGNBQWMsbUJBQW1CO0FBQ3pDO0FBRUEsZUFBZSxzQkFBa0Q7Q0FDL0QsTUFBTSxZQUNKLE1BQU0sUUFBUSxJQUNaLE9BQU8sUUFBUSxzQ0FBc0MsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFdBQVcsYUFBYTtFQUNwRixPQUFPLFVBQVUsU0FBUyxFQUFFLFNBQVMsYUFBYSxDQUFDO0NBQ3JELENBQUMsQ0FDSCxFQUFBLENBQ0EsS0FBSztDQUlQLE1BQU0sWUFBWSxNQUFNLEtBQUssSUFBSSxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUztDQUV6RCxPQUFPLE1BQU0sUUFBUSxJQUNuQixVQUFVLElBQUksT0FBTyxhQUFhO0VBQ2hDLE9BQU87R0FDTCxNQUFNO0dBQ04sVUFBVSxNQUFNLGtCQUFrQixRQUFRO0VBQzVDO0NBQ0YsQ0FBQyxDQUNIO0FBQ0Y7QUFFQSxlQUFlLHVCQUFtRDtDQUNoRSxNQUFNLG1CQUFtQixvQkFBb0I7Q0FDN0MsSUFBSSxDQUFFLE1BQU0sT0FBTyxnQkFBZ0IsR0FDakMsT0FBTyxDQUFDO0NBR1YsSUFBSTtFQU9GLE9BTjBCLEtBQUssTUFBTSxNQUFNLFNBQVMsa0JBQWtCLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FDN0UsT0FBb0Q7R0FDbkQsTUFBTSxLQUFLLEtBQUssT0FBTyxhQUFhLEVBQUUsSUFBSTtHQUMxQyxVQUFVLEVBQUU7RUFDZCxFQUVLO0NBQ1QsU0FBUyxHQUFHO0VBRVYsUUFBUSxLQUNOLFVBQVUsaUJBQWlCLG9DQUMzQixDQUNGO0VBQ0EsT0FBTyxDQUFDO0NBQ1Y7QUFDRjtBQUVBLFNBQVMsc0JBQW9DO0NBQzNDLE9BQU8sS0FBSyxLQUFLLE9BQU8sYUFBYSxhQUFhO0FBQ3BEO0FBRUEsZUFBZSxjQUFjLFdBQTZDO0NBQ3hFLE1BQU0sbUJBQW1CLG9CQUFvQjtDQUU3QyxNQUFNLGFBQWEsVUFDaEIsS0FBSyxPQUFPO0VBQ1gsTUFBTSxLQUFLLFNBQVMsT0FBTyxhQUFhLEVBQUUsSUFBSTtFQUM5QyxVQUFVLEVBQUU7Q0FDZCxFQUFFLENBQUMsQ0FDRixNQUFNLEdBQUcsTUFBTSxFQUFFLEtBQUssY0FBYyxFQUFFLElBQUksQ0FBQztDQUM5QyxNQUFNLFVBQVUsa0JBQWtCLEtBQUssVUFBVSxZQUFZLE1BQU0sQ0FBQyxHQUFHLE9BQU87QUFDaEY7QUFFQSxlQUFlLGtCQUFrQixVQUFxQztDQUNwRSxNQUFNLE9BQU8sT0FBTyxXQUFXLE1BQU07Q0FDckMsTUFBTSxRQUFRLGlCQUFpQixRQUFRO0NBQ3ZDLFdBQVcsTUFBTSxTQUFTLE9BQ3hCLEtBQUssT0FBTyxLQUFLO0NBRW5CLE9BQU8sS0FBSyxPQUFPLEtBQUs7QUFDMUI7O2FBbEhzQztrQkFDVTtlQUNOO1lBRUs7b0JBQ3NDIn0=
@@ -1,3 +1,4 @@
1
+ export { createBetterAuthRequest } from "../auth/better-auth-request";
1
2
  export * from "./bootstrap";
2
3
  export * from "./data-explorer";
3
4
  export * from "./dev-vitest-manager";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { createBetterAuthRequest, init_better_auth_request } from "../auth/better-auth-request.js";
1
2
  import { FixtureManager, FixtureManagerClass, init_fixture_manager } from "./fixture-manager.js";
2
3
  import { DataExplorer, init_data_explorer } from "./data-explorer.js";
3
4
  import { FixtureGenerator, init_fixture_generator } from "./fixture-generator.js";
@@ -9,11 +10,12 @@ import { createGlobalSetup, setup } from "./global-setup.js";
9
10
  import { NaiteVitestReporter } from "./naite-vitest-reporter.js";
10
11
  import { getSonamuTestConfig } from "./vitest-helpers.js";
11
12
  //#region src/testing/index.ts
13
+ init_better_auth_request();
12
14
  init_data_explorer();
13
15
  init_dev_vitest_manager();
14
16
  init_fixture_generator();
15
17
  init_fixture_manager();
16
18
  //#endregion
17
- export { DataExplorer, DevVitestManager, FixtureGenerator, FixtureManager, FixtureManagerClass, NaiteVitestReporter, ParallelDBManager, bootstrap, createFixtureLoader, createGlobalSetup, getSonamuTestConfig, runWithContext, runWithMockContext, setup, test, testAs };
19
+ export { DataExplorer, DevVitestManager, FixtureGenerator, FixtureManager, FixtureManagerClass, NaiteVitestReporter, ParallelDBManager, bootstrap, createBetterAuthRequest, createFixtureLoader, createGlobalSetup, getSonamuTestConfig, runWithContext, runWithMockContext, setup, test, testAs };
18
20
 
19
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3RpbmcvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSBcIi4vYm9vdHN0cmFwXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kYXRhLWV4cGxvcmVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9kZXYtdml0ZXN0LW1hbmFnZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpeHR1cmUtZ2VuZXJhdG9yXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maXh0dXJlLWxvYWRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZml4dHVyZS1tYW5hZ2VyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9nbG9iYWwtc2V0dXBcIjtcbmV4cG9ydCAqIGZyb20gXCIuL25haXRlLXZpdGVzdC1yZXBvcnRlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vcGFyYWxsZWwtZGItbWFuYWdlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdml0ZXN0LWhlbHBlcnNcIjtcbiJdLCJtYXBwaW5ncyI6IiJ9
21
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3RpbmcvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgY3JlYXRlQmV0dGVyQXV0aFJlcXVlc3QgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1yZXF1ZXN0XCI7XG5leHBvcnQgKiBmcm9tIFwiLi9ib290c3RyYXBcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2RhdGEtZXhwbG9yZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2Rldi12aXRlc3QtbWFuYWdlclwiO1xuZXhwb3J0ICogZnJvbSBcIi4vZml4dHVyZS1nZW5lcmF0b3JcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ZpeHR1cmUtbG9hZGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9maXh0dXJlLW1hbmFnZXJcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2dsb2JhbC1zZXR1cFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vbmFpdGUtdml0ZXN0LXJlcG9ydGVyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9wYXJhbGxlbC1kYi1tYW5hZ2VyXCI7XG5leHBvcnQgKiBmcm9tIFwiLi92aXRlc3QtaGVscGVyc1wiO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7eUJBQXFFIn0=
package/dist/ui/api.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { createKnexInstance, init_knex } from "../database/knex.js";
3
3
  import { DB, init_db } from "../database/db.js";
4
+ import { init_utils, nonNullable } from "../utils/utils.js";
4
5
  import { SD, init_sd } from "../dict/sd.js";
5
6
  import { BadRequestException, ServiceUnavailableException, init_so_exceptions, isSoException } from "../exceptions/so-exceptions.js";
6
- import { init_utils, nonNullable } from "../utils/utils.js";
7
7
  import { Sonamu, init_sonamu } from "../api/sonamu.js";
8
8
  import { BUILT_IN_TYPE_IDS, TemplateKey, init_types } from "../types/types.js";
9
9
  import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonamu",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
4
4
  "description": "Sonamu — TypeScript Fullstack API Framework",
5
5
  "keywords": [
6
6
  "framework",
@@ -129,10 +129,10 @@
129
129
  "tsicli": "^1.0.5",
130
130
  "vite": "8.0.16",
131
131
  "vitest": "^4.1.9",
132
+ "@sonamu-kit/hmr-hook": "^0.5.1",
132
133
  "@sonamu-kit/hmr-runner": "^0.2.0",
133
134
  "@sonamu-kit/tasks": "^0.3.1",
134
- "@sonamu-kit/ts-loader": "^2.2.0",
135
- "@sonamu-kit/hmr-hook": "^0.5.1"
135
+ "@sonamu-kit/ts-loader": "^2.2.0"
136
136
  },
137
137
  "devDependencies": {
138
138
  "@types/bcrypt": "^6",
package/src/api/sonamu.ts CHANGED
@@ -15,6 +15,7 @@ import { type WebSocket } from "ws";
15
15
  import { type ZodObject } from "zod";
16
16
 
17
17
  import { BASE_FIELD_MAPPINGS } from "../auth/better-auth-entities";
18
+ import { createBetterAuthRequest } from "../auth/better-auth-request";
18
19
  import { applyCacheHeaders, CachePresets } from "../cache-control/cache-control";
19
20
  import { type CacheControlConfig, type CacheControlRequest } from "../cache-control/types";
20
21
  import { type CacheConfig, type CacheManager } from "../cache/types";
@@ -1115,12 +1116,6 @@ class SonamuClass {
1115
1116
  traceContext = this.websocketRuntime.telemetryController.createConnectionContext({
1116
1117
  headers: request.headers,
1117
1118
  });
1118
- runGuards({
1119
- guards: api.options.guards,
1120
- config,
1121
- request,
1122
- api,
1123
- });
1124
1119
 
1125
1120
  preRegisterPhase = "query";
1126
1121
  const reqBody = await this.parseWebSocketRequestParams(api, request);
@@ -1139,6 +1134,16 @@ class SonamuClass {
1139
1134
 
1140
1135
  const scopedWs = this.createScopedWebSocketConnection(rawWs, () => wsContext);
1141
1136
  wsContext = await this.createWebSocketContext(config, request, scopedWs);
1137
+
1138
+ await this.asyncLocalStorage.run({ context: wsContext }, async () => {
1139
+ runGuards({
1140
+ guards: api.options.guards,
1141
+ config,
1142
+ request,
1143
+ api,
1144
+ });
1145
+ });
1146
+
1142
1147
  this.websocketRuntime.activateConnection(rawWs.id);
1143
1148
  preRegisterPhase = "handler";
1144
1149
 
@@ -1801,29 +1806,9 @@ class SonamuClass {
1801
1806
  method: ["GET", "POST"],
1802
1807
  url: `${basePath}/*`,
1803
1808
  handler: async (request, reply) => {
1804
- const url = new URL(request.url, `http://${request.headers.host}`);
1805
- const headers = convertFastifyHeadersToStandard(request.headers);
1806
-
1807
- // IP 헤더 fallback: 프록시가 표준 IP 헤더를 주입하지 않는 환경에서도
1808
- // better-auth/infra의 getClientIpFromRequest()가 IP를 인식할 수 있도록
1809
- // Fastify가 resolve한 request.ip를 x-real-ip로 주입한다.
1810
- const IP_HEADERS = [
1811
- "cf-connecting-ip",
1812
- "x-forwarded-for",
1813
- "x-real-ip",
1814
- "x-vercel-forwarded-for",
1815
- ];
1816
- if (request.ip && !IP_HEADERS.some((h) => headers.has(h))) {
1817
- headers.set("x-real-ip", request.ip);
1818
- }
1819
-
1820
- const req = new Request(url.toString(), {
1821
- method: request.method,
1822
- headers,
1823
- ...(request.body ? { body: JSON.stringify(request.body) } : {}),
1824
- });
1825
-
1826
- const response = await this.auth.handler(req);
1809
+ const response = await this.auth.handler(
1810
+ createBetterAuthRequest(request, options.advanced?.ipAddress?.ipAddressHeaders),
1811
+ );
1827
1812
 
1828
1813
  reply.status(response.status);
1829
1814
  response.headers.forEach((value: string, key: string) => {
@@ -1,3 +1,5 @@
1
+ import { randomUUID } from "node:crypto";
2
+
1
3
  import {
2
4
  type AccountSnapshot,
3
5
  type AuditLogEvent,
@@ -24,6 +26,7 @@ const createEvent = (
24
26
  location?: BuilderLocation,
25
27
  ): AuditLogEvent => ({
26
28
  ...base,
29
+ eventId: randomUUID(),
27
30
  eventData: {
28
31
  ...data,
29
32
  triggeredBy: trigger.triggeredBy,
@@ -0,0 +1,38 @@
1
+ import { isIP } from "node:net";
2
+
3
+ const CLIENT_IP_HEADERS = [
4
+ "cf-connecting-ip",
5
+ "x-forwarded-for",
6
+ "x-real-ip",
7
+ "x-vercel-forwarded-for",
8
+ ] as const;
9
+
10
+ const HEADER_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
11
+
12
+ export function replaceClientIpHeaders(
13
+ headers: Headers,
14
+ clientIp: string,
15
+ configuredHeaders: readonly string[] = [],
16
+ ): void {
17
+ const candidates = new Set(
18
+ [...CLIENT_IP_HEADERS, ...configuredHeaders]
19
+ .map((header) => header.trim().toLowerCase())
20
+ .filter((header) => HEADER_NAME_PATTERN.test(header)),
21
+ );
22
+
23
+ for (const header of candidates) {
24
+ headers.delete(header);
25
+ }
26
+
27
+ for (const header of candidates) {
28
+ headers.set(header, clientIp);
29
+ }
30
+ }
31
+
32
+ export function getValidClientIp(value: unknown): string | null {
33
+ if (typeof value !== "string" || value.length > 45 || isIP(value) === 0) {
34
+ return null;
35
+ }
36
+
37
+ return value;
38
+ }
@@ -5,6 +5,7 @@ export type AuditLogEvent = {
5
5
  eventType: string;
6
6
  eventData: Record<string, unknown>;
7
7
  eventKey: string;
8
+ eventId?: string;
8
9
  eventDisplayName?: string;
9
10
  ipAddress?: string;
10
11
  city?: string;
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
2
2
 
3
3
  import { type Knex } from "knex";
4
4
 
5
+ import { getValidClientIp } from "./audit-log/client-ip";
5
6
  import { type AuditLogEvent } from "./audit-log/events";
6
7
 
7
8
  const AUDIT_EVENT_SOURCE = "better_auth";
@@ -137,6 +138,10 @@ function computeDedupeKey(parts: {
137
138
  return createHash("sha256").update(raw).digest("hex");
138
139
  }
139
140
 
141
+ function computeEventIdDedupeKey(source: string, eventId: string): string {
142
+ return createHash("sha256").update(`${source}|${eventId}`).digest("hex");
143
+ }
144
+
140
145
  /**
141
146
  * sonamuAuditLog 플러그인이 구성한 AuditLogEvent를 audit_events 테이블에 적재합니다.
142
147
  * ON CONFLICT (dedupe_key) DO NOTHING으로 중복을 silent 무시합니다.
@@ -172,26 +177,28 @@ export async function ingestAuditEvent(db: Knex, event: AuditLogEvent): Promise<
172
177
  const trigger_context = pickString(eventData, "triggerContext");
173
178
  const user_agent = pickString(eventData, "userAgent");
174
179
 
175
- const ip_address = event.ipAddress ?? null;
180
+ const ip_address = getValidClientIp(event.ipAddress);
176
181
  const city = event.city ?? null;
177
182
  const country = event.country ?? null;
178
183
  const country_code = event.countryCode ?? null;
179
184
 
180
185
  const category = classifyCategory(event.eventType);
181
- const dedupe_key = computeDedupeKey({
182
- source: AUDIT_EVENT_SOURCE,
183
- event_type: event.eventType,
184
- event_key: event.eventKey,
185
- actor_user_id,
186
- subject_user_id,
187
- organization_id,
188
- team_id,
189
- session_id,
190
- identifier,
191
- reason,
192
- action,
193
- occurred_at,
194
- });
186
+ const dedupe_key = event.eventId
187
+ ? computeEventIdDedupeKey(AUDIT_EVENT_SOURCE, event.eventId)
188
+ : computeDedupeKey({
189
+ source: AUDIT_EVENT_SOURCE,
190
+ event_type: event.eventType,
191
+ event_key: event.eventKey,
192
+ actor_user_id,
193
+ subject_user_id,
194
+ organization_id,
195
+ team_id,
196
+ session_id,
197
+ identifier,
198
+ reason,
199
+ action,
200
+ occurred_at,
201
+ });
195
202
 
196
203
  // ON CONFLICT DO NOTHING: dedupe_key UNIQUE 위반을 silent 무시.
197
204
  // try/catch 방식은 PG 커넥션을 aborted 상태로 만드므로 사용하지 않는다.
@@ -0,0 +1,20 @@
1
+ import { type FastifyRequest } from "fastify";
2
+
3
+ import { convertFastifyHeadersToStandard } from "../utils/utils";
4
+ import { replaceClientIpHeaders } from "./audit-log/client-ip";
5
+
6
+ export function createBetterAuthRequest(
7
+ request: FastifyRequest,
8
+ ipAddressHeaders?: readonly string[],
9
+ ): Request {
10
+ const url = new URL(request.url, `http://${request.headers.host}`);
11
+ const headers = convertFastifyHeadersToStandard(request.headers);
12
+
13
+ replaceClientIpHeaders(headers, request.ip, ipAddressHeaders);
14
+
15
+ return new Request(url.toString(), {
16
+ method: request.method,
17
+ headers,
18
+ ...(request.body ? { body: JSON.stringify(request.body) } : {}),
19
+ });
20
+ }
@@ -32,7 +32,8 @@ export const WEB_ARTIFACTS: BuildArtifact[] = [
32
32
  description: "Web 프로젝트 클라이언트 빌드 산출물",
33
33
  projectPath: "web",
34
34
  preBuildCommand: () => "rm -rf dist/client",
35
- buildCommand: () => "tsc --noEmit && vite build --config vite.config.ts --outDir dist/client",
35
+ buildCommand: () =>
36
+ "tsc -b --noEmit && vite build --config vite.config.ts --outDir dist/client",
36
37
  },
37
38
  {
38
39
  name: "Web Server",
@@ -40,7 +41,7 @@ export const WEB_ARTIFACTS: BuildArtifact[] = [
40
41
  projectPath: "web",
41
42
  preBuildCommand: () => "rm -rf dist/server",
42
43
  buildCommand: () =>
43
- "tsc --noEmit && vite build --config vite.config.ts --ssr src/entry-server.generated.tsx --outDir dist/server",
44
+ "tsc -b --noEmit && vite build --config vite.config.ts --ssr src/entry-server.generated.tsx --outDir dist/server",
44
45
  postBuildCommand: () =>
45
46
  "rm -rf ../api/web-dist && mkdir -p ../api/web-dist && cp -r dist/* ../api/web-dist",
46
47
  },
@@ -18,6 +18,35 @@ await this.getPuri("w").table("users").where("id", 1).update({ is_active: false
18
18
  const users = await db.table({ u: "users" }).select({ id: "u.id" });
19
19
  ```
20
20
 
21
+ ### Where to obtain a Puri instance
22
+
23
+ Route every query — reads and writes alike — through Puri. Do NOT run queries directly on a raw `getDB()` knex handle (the only exceptions are migration files, `db.ts`, tests, and the `.knex` escape hatch below).
24
+
25
+ ```typescript
26
+ // Inside a Model
27
+ const rows = await this.getPuri("r").table("users").select({ id: "id" });
28
+
29
+ // Inside a Frame — Frame has no getPuri (only getDB / getUpsertBuilder),
30
+ // so use the associated Model's getPuri
31
+ const rows = await UserModel.getPuri("r").table("users").select({ id: "id" });
32
+
33
+ // Outside a Model (seed / batch / monitoring scripts) — wrap knex in a PuriWrapper
34
+ import { DB, PuriWrapper, UpsertBuilder } from "sonamu";
35
+ const puri = new PuriWrapper(DB.getDB("r"), new UpsertBuilder());
36
+ const rows = await puri.table("users").select({ id: "id" });
37
+ ```
38
+
39
+ > `UpsertBuilder` is a required constructor argument even for read-only wrappers; it simply stays unused for pure reads.
40
+
41
+ ### Escape hatch: `.knex` for non-entity / framework-internal tables
42
+
43
+ Puri's typed `.table()` only knows registered entity tables. For framework-internal or unregistered tables (e.g. `workflow_runs`), reach the raw knex handle via `puri.knex` instead of calling `DB.getDB()` directly:
44
+
45
+ ```typescript
46
+ const puri = new PuriWrapper(DB.getDB("r"), new UpsertBuilder());
47
+ const runs = await puri.knex.table("workflow_runs").where("status", "running").select("*");
48
+ ```
49
+
21
50
  ## SELECT
22
51
 
23
52
  > **CRITICAL: `.select()` must always be used with an object argument.**
@@ -558,6 +587,10 @@ const results = await this.getPuri("r")
558
587
 
559
588
  ## Rules
560
589
 
590
+ - Puri is the standard for BOTH reads and writes in ALL contexts (Model, Frame, scripts) — do NOT run queries on a raw `DB.getDB()` handle (exceptions: migration files, `db.ts`, tests, and the `.knex` escape hatch)
591
+ - Inside a Frame, use the associated Model's `getPuri` (Frame exposes only `getDB` / `getUpsertBuilder`, not `getPuri`)
592
+ - Outside a Model, wrap knex with `new PuriWrapper(DB.getDB(which), new UpsertBuilder())`
593
+ - Use the `puri.knex` escape hatch only for non-entity / framework-internal tables (e.g. `workflow_runs`)
561
594
  - MUST use `getPuri("r")` for read queries, `getPuri("w")` for write queries
562
595
  - MUST include WHERE condition for UPDATE/DELETE operations
563
596
  - MUST use `transaction()` for multiple write operations
@@ -1,4 +1,4 @@
1
- import crypto, { type BinaryLike } from "crypto";
1
+ import crypto from "crypto";
2
2
  import { createReadStream, type PathLike } from "fs";
3
3
  import { readFile, writeFile } from "fs/promises";
4
4
  import path from "path";
@@ -114,15 +114,10 @@ async function saveChecksums(checksums: PathAndChecksum[]): Promise<void> {
114
114
  }
115
115
 
116
116
  async function getChecksumOfFile(filePath: PathLike): Promise<string> {
117
- return new Promise<string>((resolve, reject) => {
118
- const hash = crypto.createHash("sha1");
119
- const input = createReadStream(filePath);
120
- input.on("error", reject);
121
- input.on("data", (chunk: BinaryLike) => {
122
- hash.update(chunk);
123
- });
124
- input.on("close", () => {
125
- resolve(hash.digest("hex"));
126
- });
127
- });
117
+ const hash = crypto.createHash("sha1");
118
+ const input = createReadStream(filePath);
119
+ for await (const chunk of input) {
120
+ hash.update(chunk);
121
+ }
122
+ return hash.digest("hex");
128
123
  }
@@ -1,3 +1,4 @@
1
+ export { createBetterAuthRequest } from "../auth/better-auth-request";
1
2
  export * from "./bootstrap";
2
3
  export * from "./data-explorer";
3
4
  export * from "./dev-vitest-manager";