@slopware/sloppy-linux-x64 0.1.0-alpha.0

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 (434) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +5 -0
  3. package/bin/sloppy +0 -0
  4. package/bin/sloppyc +0 -0
  5. package/docs/KNOWN_LIMITATIONS.md +16 -0
  6. package/docs/LICENSES.md +6 -0
  7. package/docs/NOTICE.md +8 -0
  8. package/examples/README.md +140 -0
  9. package/examples/auth-api/README.md +20 -0
  10. package/examples/auth-api/app.js +61 -0
  11. package/examples/auth-api/appsettings.json +7 -0
  12. package/examples/auth-api/sloppy.json +5 -0
  13. package/examples/cache-basic/README.md +9 -0
  14. package/examples/cache-basic/app.js +32 -0
  15. package/examples/cache-hybrid-postgres/README.md +10 -0
  16. package/examples/cache-hybrid-postgres/app.js +27 -0
  17. package/examples/cache-output-api/README.md +10 -0
  18. package/examples/cache-output-api/app.js +35 -0
  19. package/examples/codec-base64-hex/README.md +14 -0
  20. package/examples/codec-base64-hex/app.js +15 -0
  21. package/examples/codec-checksums/README.md +15 -0
  22. package/examples/codec-checksums/app.js +8 -0
  23. package/examples/codec-compression/README.md +13 -0
  24. package/examples/codec-compression/app.js +9 -0
  25. package/examples/codec-streaming-compression/README.md +19 -0
  26. package/examples/codec-streaming-compression/app.js +16 -0
  27. package/examples/codec-text-binary/README.md +16 -0
  28. package/examples/codec-text-binary/app.js +17 -0
  29. package/examples/compiler-hello/README.md +71 -0
  30. package/examples/compiler-hello/app.js +7 -0
  31. package/examples/compiler-hello/expected/app.js +8 -0
  32. package/examples/compiler-hello/expected/app.js.map +53 -0
  33. package/examples/compiler-hello/expected/app.plan.json +229 -0
  34. package/examples/compiler-hello/expected/routes.slrt +0 -0
  35. package/examples/config-basic/README.md +13 -0
  36. package/examples/config-basic/app.js +13 -0
  37. package/examples/config-basic/appsettings.json +7 -0
  38. package/examples/config-secrets-redaction/README.md +9 -0
  39. package/examples/config-secrets-redaction/app.js +9 -0
  40. package/examples/config-secrets-redaction/appsettings.json +5 -0
  41. package/examples/config-strict-mode/README.md +7 -0
  42. package/examples/config-strict-mode/app.js +10 -0
  43. package/examples/config-strict-mode/appsettings.json +7 -0
  44. package/examples/configured-api/README.md +38 -0
  45. package/examples/configured-api/app.js +12 -0
  46. package/examples/configured-api/appsettings.Development.json +5 -0
  47. package/examples/configured-api/appsettings.json +6 -0
  48. package/examples/configured-api/sloppy.json +5 -0
  49. package/examples/core-config-secrets/README.md +10 -0
  50. package/examples/core-config-secrets/app.js +15 -0
  51. package/examples/core-fs-time-codec/README.md +9 -0
  52. package/examples/core-fs-time-codec/app.js +8 -0
  53. package/examples/core-network-time-codec/README.md +11 -0
  54. package/examples/core-network-time-codec/app.js +20 -0
  55. package/examples/core-policy-audit/README.md +7 -0
  56. package/examples/core-policy-audit/app.js +22 -0
  57. package/examples/core-process-time-codec/README.md +8 -0
  58. package/examples/core-process-time-codec/app.js +28 -0
  59. package/examples/core-worker-time/README.md +8 -0
  60. package/examples/core-worker-time/app.js +17 -0
  61. package/examples/crypto-hash-hmac/README.md +17 -0
  62. package/examples/crypto-hash-hmac/app.js +29 -0
  63. package/examples/crypto-password/README.md +21 -0
  64. package/examples/crypto-password/app.js +12 -0
  65. package/examples/crypto-random-token/README.md +16 -0
  66. package/examples/crypto-random-token/app.js +12 -0
  67. package/examples/crypto-secret-constant-time/README.md +21 -0
  68. package/examples/crypto-secret-constant-time/app.js +15 -0
  69. package/examples/data-foundation/README.md +39 -0
  70. package/examples/data-foundation/app.js +63 -0
  71. package/examples/dependency-graph/README.md +19 -0
  72. package/examples/dependency-graph/fixtures/graph-helper/index.js +3 -0
  73. package/examples/dependency-graph/fixtures/graph-helper/package.json +6 -0
  74. package/examples/dependency-graph/package.json +7 -0
  75. package/examples/dependency-graph/public/message.txt +1 -0
  76. package/examples/dependency-graph/sloppy.json +9 -0
  77. package/examples/dependency-graph/src/main.ts +8 -0
  78. package/examples/dogfood/README.md +23 -0
  79. package/examples/dogfood/dogfood.json +136 -0
  80. package/examples/dynamic-module-include/README.md +20 -0
  81. package/examples/dynamic-module-include/public/readme.txt +1 -0
  82. package/examples/dynamic-module-include/sloppy.json +12 -0
  83. package/examples/dynamic-module-include/src/main.ts +6 -0
  84. package/examples/dynamic-module-include/src/plugins/alpha.js +3 -0
  85. package/examples/dynamic-module-include/src/plugins/beta.js +3 -0
  86. package/examples/ergonomics/README.md +42 -0
  87. package/examples/ergonomics/app.js +38 -0
  88. package/examples/framework-controller/README.md +12 -0
  89. package/examples/framework-controller/app.js +31 -0
  90. package/examples/framework-di-services/README.md +17 -0
  91. package/examples/framework-di-services/app.ts +40 -0
  92. package/examples/framework-explicit-binding/README.md +12 -0
  93. package/examples/framework-explicit-binding/app.ts +34 -0
  94. package/examples/framework-hello/README.md +16 -0
  95. package/examples/framework-hello/app.ts +16 -0
  96. package/examples/framework-postgres-crud/README.md +73 -0
  97. package/examples/framework-postgres-crud/app.ts +64 -0
  98. package/examples/framework-sqlite-crud/README.md +52 -0
  99. package/examples/framework-sqlite-crud/app.ts +90 -0
  100. package/examples/framework-sqlite-crud/appsettings.json +11 -0
  101. package/examples/framework-sqlserver-crud/README.md +73 -0
  102. package/examples/framework-sqlserver-crud/app.ts +64 -0
  103. package/examples/framework-validation-errors/README.md +12 -0
  104. package/examples/framework-validation-errors/app.ts +16 -0
  105. package/examples/fs-basic/README.md +24 -0
  106. package/examples/fs-basic/app.js +12 -0
  107. package/examples/fs-roots-policy/README.md +14 -0
  108. package/examples/fs-roots-policy/app.js +4 -0
  109. package/examples/fs-streams/README.md +18 -0
  110. package/examples/fs-streams/app.js +11 -0
  111. package/examples/fs-watch/README.md +19 -0
  112. package/examples/fs-watch/app.js +11 -0
  113. package/examples/hello/README.md +63 -0
  114. package/examples/hello/app.js +19 -0
  115. package/examples/hello-minimal/README.md +51 -0
  116. package/examples/hello-minimal/sloppy.json +5 -0
  117. package/examples/hello-minimal/src/main.ts +9 -0
  118. package/examples/http-client-basic/README.md +11 -0
  119. package/examples/http-client-basic/app.js +46 -0
  120. package/examples/http-client-generated/README.md +22 -0
  121. package/examples/http-client-generated/openapi.json +45 -0
  122. package/examples/http-client-resilience/README.md +4 -0
  123. package/examples/http-client-resilience/app.js +38 -0
  124. package/examples/http-client-runtime-loopback/README.md +24 -0
  125. package/examples/http-client-testhost/README.md +4 -0
  126. package/examples/http-client-testhost/app.js +27 -0
  127. package/examples/http-client-testhost-package-mock/README.md +26 -0
  128. package/examples/http-client-typed/README.md +5 -0
  129. package/examples/http-client-typed/app.js +33 -0
  130. package/examples/modules-api/README.md +30 -0
  131. package/examples/modules-api/app.js +9 -0
  132. package/examples/modules-api/modules/routes.js +16 -0
  133. package/examples/modules-api/sloppy.json +5 -0
  134. package/examples/modules-basic/README.md +32 -0
  135. package/examples/modules-basic/app.js +41 -0
  136. package/examples/net-deadline-cancel/README.md +13 -0
  137. package/examples/net-deadline-cancel/app.js +34 -0
  138. package/examples/net-local-ipc/README.md +12 -0
  139. package/examples/net-local-ipc/app.js +46 -0
  140. package/examples/net-policy-strict/README.md +12 -0
  141. package/examples/net-policy-strict/app.js +34 -0
  142. package/examples/net-tcp-client/README.md +10 -0
  143. package/examples/net-tcp-client/app.js +23 -0
  144. package/examples/net-tcp-echo/README.md +11 -0
  145. package/examples/net-tcp-echo/app.js +45 -0
  146. package/examples/net-tcp-server/README.md +10 -0
  147. package/examples/net-tcp-server/app.js +28 -0
  148. package/examples/node-compat-path-events/README.md +15 -0
  149. package/examples/node-compat-path-events/sloppy.json +6 -0
  150. package/examples/node-compat-path-events/src/main.ts +15 -0
  151. package/examples/ops-compiler/README.md +9 -0
  152. package/examples/ops-compiler/app.js +26 -0
  153. package/examples/ops-health-metrics-management/README.md +14 -0
  154. package/examples/ops-health-metrics-management/app.js +24 -0
  155. package/examples/orm-basic/README.md +17 -0
  156. package/examples/orm-basic/app.js +82 -0
  157. package/examples/orm-cursor-export/README.md +16 -0
  158. package/examples/orm-cursor-export/app.js +28 -0
  159. package/examples/orm-migrations/README.md +14 -0
  160. package/examples/orm-migrations/migrations/.gitkeep +1 -0
  161. package/examples/orm-migrations/sloppy.json +9 -0
  162. package/examples/orm-migrations/src/app.ts +34 -0
  163. package/examples/orm-relations-includes/README.md +10 -0
  164. package/examples/orm-relations-includes/app.js +47 -0
  165. package/examples/orm-testservices/README.md +37 -0
  166. package/examples/orm-testservices/test.mjs +32 -0
  167. package/examples/os-runtime-api/README.md +11 -0
  168. package/examples/os-runtime-api/app.js +44 -0
  169. package/examples/package-zod-like/README.md +28 -0
  170. package/examples/package-zod-like/fixtures/zod-like/index.js +48 -0
  171. package/examples/package-zod-like/fixtures/zod-like/package.json +12 -0
  172. package/examples/package-zod-like/package.json +7 -0
  173. package/examples/package-zod-like/sloppy.json +6 -0
  174. package/examples/package-zod-like/src/main.ts +16 -0
  175. package/examples/postgres-basic/README.md +31 -0
  176. package/examples/postgres-basic/app.js +50 -0
  177. package/examples/prealpha-control-plane/README.md +50 -0
  178. package/examples/prealpha-control-plane/appsettings.Development.json +11 -0
  179. package/examples/prealpha-control-plane/appsettings.json +15 -0
  180. package/examples/prealpha-control-plane/sloppy.json +5 -0
  181. package/examples/prealpha-control-plane/src/db/schema.js +7 -0
  182. package/examples/prealpha-control-plane/src/db/seed.js +6 -0
  183. package/examples/prealpha-control-plane/src/main.js +21 -0
  184. package/examples/prealpha-control-plane/src/routes/apps.js +34 -0
  185. package/examples/prealpha-control-plane/src/routes/builds.js +25 -0
  186. package/examples/prealpha-control-plane/src/routes/deployments.js +19 -0
  187. package/examples/prealpha-control-plane/src/routes/diagnostics.js +11 -0
  188. package/examples/prealpha-control-plane/src/routes/health.js +27 -0
  189. package/examples/prealpha-control-plane/src/routes/projects.js +38 -0
  190. package/examples/prealpha-control-plane/src/services/diagnosticsSink.js +11 -0
  191. package/examples/prealpha-control-plane/src/services/repositories.js +9 -0
  192. package/examples/prealpha-control-plane/src/validation/schemas.js +6 -0
  193. package/examples/program-fs-process/README.md +31 -0
  194. package/examples/program-fs-process/sloppy.json +9 -0
  195. package/examples/program-fs-process/src/main.ts +27 -0
  196. package/examples/program-hello/README.md +32 -0
  197. package/examples/program-hello/main.ts +8 -0
  198. package/examples/program-hello/message.ts +1 -0
  199. package/examples/program-hello/sloppy.json +5 -0
  200. package/examples/rate-limit-auth/README.md +3 -0
  201. package/examples/rate-limit-auth/app.js +14 -0
  202. package/examples/rate-limit-basic/README.md +3 -0
  203. package/examples/rate-limit-basic/app.js +13 -0
  204. package/examples/rate-limit-redis/README.md +5 -0
  205. package/examples/rate-limit-redis/app.js +20 -0
  206. package/examples/rate-limit-testhost/README.md +4 -0
  207. package/examples/rate-limit-testhost/app.js +13 -0
  208. package/examples/rate-limit-websocket/README.md +3 -0
  209. package/examples/rate-limit-websocket/app.js +16 -0
  210. package/examples/realtime-auth/README.md +8 -0
  211. package/examples/realtime-auth/app.js +25 -0
  212. package/examples/realtime-auth/test.mjs +43 -0
  213. package/examples/realtime-chat/README.md +8 -0
  214. package/examples/realtime-chat/app.js +32 -0
  215. package/examples/realtime-chat/test.mjs +52 -0
  216. package/examples/realtime-dashboard/README.md +20 -0
  217. package/examples/realtime-dashboard/app.js +37 -0
  218. package/examples/realtime-presence/README.md +8 -0
  219. package/examples/realtime-presence/app.js +32 -0
  220. package/examples/realtime-presence/test.mjs +50 -0
  221. package/examples/realtime-testhost/README.md +8 -0
  222. package/examples/realtime-testhost/test.mjs +31 -0
  223. package/examples/redis-basic/README.md +17 -0
  224. package/examples/redis-basic/app.js +39 -0
  225. package/examples/redis-cache/README.md +14 -0
  226. package/examples/redis-cache/app.js +36 -0
  227. package/examples/redis-locks/README.md +13 -0
  228. package/examples/redis-locks/app.js +49 -0
  229. package/examples/request-context/README.md +32 -0
  230. package/examples/request-context/app.js +15 -0
  231. package/examples/sqlite-basic/README.md +52 -0
  232. package/examples/sqlite-basic/app.js +56 -0
  233. package/examples/sqlserver-basic/README.md +36 -0
  234. package/examples/sqlserver-basic/app.js +59 -0
  235. package/examples/static-files-basic/README.md +11 -0
  236. package/examples/static-files-basic/app.js +12 -0
  237. package/examples/static-files-basic/public/app.js +1 -0
  238. package/examples/static-files-basic/public/site.css +3 -0
  239. package/examples/static-files-package/README.md +12 -0
  240. package/examples/static-files-package/app.js +10 -0
  241. package/examples/static-files-package/public/index.html +2 -0
  242. package/examples/static-files-precompressed/README.md +12 -0
  243. package/examples/static-files-precompressed/app.js +11 -0
  244. package/examples/static-files-precompressed/public/app.js +1 -0
  245. package/examples/static-files-precompressed/public/app.js.br +0 -0
  246. package/examples/static-files-precompressed/public/app.js.gz +0 -0
  247. package/examples/static-files-spa/README.md +12 -0
  248. package/examples/static-files-spa/app.js +16 -0
  249. package/examples/static-files-spa/dist/assets/app.js +1 -0
  250. package/examples/static-files-spa/dist/index.html +4 -0
  251. package/examples/static-files-testhost/README.md +8 -0
  252. package/examples/static-files-testhost/app.js +13 -0
  253. package/examples/static-files-testhost/public/app.js +1 -0
  254. package/examples/static-files-testhost/public/app.js.gz +0 -0
  255. package/examples/static-files-testhost/test.mjs +38 -0
  256. package/examples/testhost-basic/README.md +26 -0
  257. package/examples/testhost-db/README.md +31 -0
  258. package/examples/testservices-postgres/README.md +68 -0
  259. package/examples/testservices-redis/README.md +71 -0
  260. package/examples/testservices-sqlserver/README.md +75 -0
  261. package/examples/time-basic/README.md +18 -0
  262. package/examples/time-basic/app.js +12 -0
  263. package/examples/time-deadline-cancellation/README.md +11 -0
  264. package/examples/time-deadline-cancellation/app.js +27 -0
  265. package/examples/time-fake-clock/README.md +14 -0
  266. package/examples/time-fake-clock/app.js +25 -0
  267. package/examples/time-interval-schedule/README.md +13 -0
  268. package/examples/time-interval-schedule/app.js +60 -0
  269. package/examples/users-api-sqlite/README.md +74 -0
  270. package/examples/users-api-sqlite/app.js +11 -0
  271. package/examples/users-api-sqlite/appsettings.Development.json +11 -0
  272. package/examples/users-api-sqlite/appsettings.json +11 -0
  273. package/examples/users-api-sqlite/modules/users.js +40 -0
  274. package/examples/users-api-sqlite/sloppy.json +5 -0
  275. package/examples/validation-errors/README.md +36 -0
  276. package/examples/validation-errors/app.js +14 -0
  277. package/examples/validation-errors/invalid-user.http +6 -0
  278. package/examples/validation-errors/sloppy.json +5 -0
  279. package/examples/web-dynamic-routes/README.md +17 -0
  280. package/examples/web-dynamic-routes/app.ts +27 -0
  281. package/examples/webhooks-basic/README.md +11 -0
  282. package/examples/webhooks-basic/app.js +48 -0
  283. package/examples/websocket-auth/README.md +8 -0
  284. package/examples/websocket-auth/app.js +16 -0
  285. package/examples/websocket-echo/README.md +9 -0
  286. package/examples/websocket-echo/app.js +36 -0
  287. package/examples/websocket-json-schema/README.md +5 -0
  288. package/examples/websocket-json-schema/app.js +25 -0
  289. package/examples/websocket-testhost/README.md +11 -0
  290. package/examples/websocket-testhost/test.mjs +49 -0
  291. package/examples/workers-background-service/README.md +7 -0
  292. package/examples/workers-background-service/app.js +16 -0
  293. package/examples/workers-js-isolate/README.md +8 -0
  294. package/examples/workers-js-isolate/app.js +19 -0
  295. package/examples/workers-js-isolate/workers/parser.ts +11 -0
  296. package/examples/workers-shutdown/README.md +6 -0
  297. package/examples/workers-shutdown/app.js +26 -0
  298. package/examples/workers-workerpool/README.md +6 -0
  299. package/examples/workers-workerpool/app.js +23 -0
  300. package/examples/workers-workqueue/README.md +8 -0
  301. package/examples/workers-workqueue/app.js +24 -0
  302. package/manifest.json +59 -0
  303. package/package.json +34 -0
  304. package/stdlib/sloppy/README.md +177 -0
  305. package/stdlib/sloppy/app.js +2142 -0
  306. package/stdlib/sloppy/auth.js +1813 -0
  307. package/stdlib/sloppy/bootstrap.manifest.json +83 -0
  308. package/stdlib/sloppy/cache.js +1542 -0
  309. package/stdlib/sloppy/codec.js +1153 -0
  310. package/stdlib/sloppy/config.js +61 -0
  311. package/stdlib/sloppy/crypto.js +312 -0
  312. package/stdlib/sloppy/data.js +2945 -0
  313. package/stdlib/sloppy/ffi.js +185 -0
  314. package/stdlib/sloppy/fs.js +795 -0
  315. package/stdlib/sloppy/health.js +603 -0
  316. package/stdlib/sloppy/http.js +1595 -0
  317. package/stdlib/sloppy/index.js +59 -0
  318. package/stdlib/sloppy/internal/bytes.js +31 -0
  319. package/stdlib/sloppy/internal/capabilities.js +155 -0
  320. package/stdlib/sloppy/internal/config.js +640 -0
  321. package/stdlib/sloppy/internal/disposable.js +31 -0
  322. package/stdlib/sloppy/internal/headers.js +63 -0
  323. package/stdlib/sloppy/internal/intrinsics.js +2 -0
  324. package/stdlib/sloppy/internal/json.js +20 -0
  325. package/stdlib/sloppy/internal/logging.js +278 -0
  326. package/stdlib/sloppy/internal/modules.js +405 -0
  327. package/stdlib/sloppy/internal/redaction.js +87 -0
  328. package/stdlib/sloppy/internal/routes.js +2279 -0
  329. package/stdlib/sloppy/internal/runtime-classic.js +19837 -0
  330. package/stdlib/sloppy/internal/services.js +690 -0
  331. package/stdlib/sloppy/internal/shared.js +32 -0
  332. package/stdlib/sloppy/internal/testhost-diagnostics.js +88 -0
  333. package/stdlib/sloppy/internal/testhost-http-server.js +238 -0
  334. package/stdlib/sloppy/internal/testhost-http.js +118 -0
  335. package/stdlib/sloppy/internal/testhost-loopback.js +50 -0
  336. package/stdlib/sloppy/internal/testservices-docker.js +154 -0
  337. package/stdlib/sloppy/internal/validation.js +117 -0
  338. package/stdlib/sloppy/metrics.js +427 -0
  339. package/stdlib/sloppy/net.js +5208 -0
  340. package/stdlib/sloppy/node/assert/strict.js +39 -0
  341. package/stdlib/sloppy/node/assert.js +228 -0
  342. package/stdlib/sloppy/node/buffer.js +247 -0
  343. package/stdlib/sloppy/node/console.js +33 -0
  344. package/stdlib/sloppy/node/constants.js +9 -0
  345. package/stdlib/sloppy/node/crypto.js +89 -0
  346. package/stdlib/sloppy/node/diagnostics_channel.js +41 -0
  347. package/stdlib/sloppy/node/events.js +113 -0
  348. package/stdlib/sloppy/node/fs/promises.js +27 -0
  349. package/stdlib/sloppy/node/fs.js +280 -0
  350. package/stdlib/sloppy/node/http.js +11 -0
  351. package/stdlib/sloppy/node/https.js +11 -0
  352. package/stdlib/sloppy/node/module.js +40 -0
  353. package/stdlib/sloppy/node/os.js +22 -0
  354. package/stdlib/sloppy/node/path.js +78 -0
  355. package/stdlib/sloppy/node/perf_hooks.js +12 -0
  356. package/stdlib/sloppy/node/process.js +129 -0
  357. package/stdlib/sloppy/node/querystring.js +21 -0
  358. package/stdlib/sloppy/node/stream/promises.js +3 -0
  359. package/stdlib/sloppy/node/stream.js +132 -0
  360. package/stdlib/sloppy/node/string_decoder.js +23 -0
  361. package/stdlib/sloppy/node/timers.js +26 -0
  362. package/stdlib/sloppy/node/tty.js +18 -0
  363. package/stdlib/sloppy/node/url.js +17 -0
  364. package/stdlib/sloppy/node/util.js +95 -0
  365. package/stdlib/sloppy/node/zlib.js +72 -0
  366. package/stdlib/sloppy/orm.js +2188 -0
  367. package/stdlib/sloppy/os.js +580 -0
  368. package/stdlib/sloppy/problem-details.js +29 -0
  369. package/stdlib/sloppy/providers/sqlite.js +26 -0
  370. package/stdlib/sloppy/rate-limit.js +856 -0
  371. package/stdlib/sloppy/realtime.js +1508 -0
  372. package/stdlib/sloppy/redis.js +1272 -0
  373. package/stdlib/sloppy/request-id.js +184 -0
  374. package/stdlib/sloppy/request-logging.js +101 -0
  375. package/stdlib/sloppy/results.js +933 -0
  376. package/stdlib/sloppy/schema.js +546 -0
  377. package/stdlib/sloppy/testing.js +4081 -0
  378. package/stdlib/sloppy/testservices.js +1041 -0
  379. package/stdlib/sloppy/time.js +894 -0
  380. package/stdlib/sloppy/webhooks.js +1330 -0
  381. package/stdlib/sloppy/workers.js +986 -0
  382. package/templates/api/README.md +82 -0
  383. package/templates/api/appsettings.Development.json +14 -0
  384. package/templates/api/appsettings.json +13 -0
  385. package/templates/api/data/.gitkeep +1 -0
  386. package/templates/api/gitignore +4 -0
  387. package/templates/api/migrations/0001_create_users.sql +1 -0
  388. package/templates/api/package.json +16 -0
  389. package/templates/api/public/hello.txt +1 -0
  390. package/templates/api/sloppy.json +14 -0
  391. package/templates/api/src/config.ts +1 -0
  392. package/templates/api/src/db/migrate.ts +14 -0
  393. package/templates/api/src/db/schema.ts +4 -0
  394. package/templates/api/src/db/usersRepository.ts +23 -0
  395. package/templates/api/src/main.ts +18 -0
  396. package/templates/api/src/models/user.ts +7 -0
  397. package/templates/api/src/routes/health.ts +20 -0
  398. package/templates/api/src/routes/users.ts +40 -0
  399. package/templates/api/src/services/usersService.ts +21 -0
  400. package/templates/api/tsconfig.json +15 -0
  401. package/templates/cli/README.md +16 -0
  402. package/templates/cli/gitignore +2 -0
  403. package/templates/cli/package.json +13 -0
  404. package/templates/cli/sloppy.json +6 -0
  405. package/templates/cli/src/commands/echo.ts +9 -0
  406. package/templates/cli/src/commands/inspect.ts +20 -0
  407. package/templates/cli/src/main.ts +50 -0
  408. package/templates/cli/tsconfig.json +15 -0
  409. package/templates/minimal-api/README.md +14 -0
  410. package/templates/minimal-api/gitignore +3 -0
  411. package/templates/minimal-api/package.json +14 -0
  412. package/templates/minimal-api/sloppy.json +5 -0
  413. package/templates/minimal-api/src/main.ts +9 -0
  414. package/templates/minimal-api/tsconfig.json +15 -0
  415. package/templates/node-compat/README.md +40 -0
  416. package/templates/node-compat/gitignore +2 -0
  417. package/templates/node-compat/package.json +11 -0
  418. package/templates/node-compat/sloppy.json +6 -0
  419. package/templates/node-compat/src/main.ts +40 -0
  420. package/templates/package-api/README.md +44 -0
  421. package/templates/package-api/fixtures/validator-lite/index.js +7 -0
  422. package/templates/package-api/fixtures/validator-lite/package.json +6 -0
  423. package/templates/package-api/gitignore +3 -0
  424. package/templates/package-api/package.json +17 -0
  425. package/templates/package-api/sloppy.json +5 -0
  426. package/templates/package-api/src/main.ts +10 -0
  427. package/templates/package-api/src/routes/health.ts +5 -0
  428. package/templates/package-api/src/routes/users.ts +12 -0
  429. package/templates/package-api/tsconfig.json +15 -0
  430. package/templates/program/README.md +12 -0
  431. package/templates/program/gitignore +1 -0
  432. package/templates/program/package.json +10 -0
  433. package/templates/program/sloppy.json +6 -0
  434. package/templates/program/src/main.ts +9 -0
@@ -0,0 +1,50 @@
1
+ # Pre-alpha control plane
2
+
3
+ This is a multi-file contributor/internal example for the current Sloppy
4
+ app-host and source-input path. It models a small deployment control plane with
5
+ projects, apps, builds, deployments, diagnostics, health routes, and a SQLite
6
+ provider.
7
+
8
+ The example is intentionally plain JavaScript source with no `package.json`.
9
+ No npm package scope is required. The compiler resolves `"sloppy"` and relative
10
+ imports from the project root.
11
+
12
+ ## What it covers
13
+
14
+ - `sloppy build` and `sloppy run` project-mode dogfood through `sloppy.json`.
15
+ - Function modules registered through `app.useModule(...)`.
16
+ - Route groups, named routes, path params, query params, JSON request bodies,
17
+ `Results.created`, `Results.badRequest`, and `Results.notFound`.
18
+ - SQLite provider metadata and the `data.main` capability in emitted plans.
19
+ - App test host dispatch against the same route modules in
20
+ `tests/bootstrap/test_prealpha_control_plane_dogfood.mjs`.
21
+
22
+ ## Current coverage
23
+
24
+ Default non-V8 lanes compile the project and verify that `sloppy run` emits
25
+ artifacts before reporting the required V8 diagnostic. The V8-gated lane runs:
26
+
27
+ ```powershell
28
+ sloppy run --once GET /projects?owner=runtime
29
+ ```
30
+
31
+ from this directory and expects the seeded `Compiler Platform` project in the
32
+ response.
33
+
34
+ The app test host lane also verifies CORS preflight, request IDs, request
35
+ logging redaction, ProblemDetails redaction, request service-scope disposal,
36
+ health routes, method mismatch, not-found behavior, and host lifecycle cleanup.
37
+
38
+ ## Current limits
39
+
40
+ This example stays inside the syntax that `sloppyc` can extract today. Source
41
+ root imports therefore use `Sloppy`, `ProblemDetails`, and
42
+ `sloppy/providers/sqlite`; route modules import `Results` in the files that
43
+ call `Results.*`. Request-id middleware, request logging middleware, and
44
+ `app.mapHealthChecks()` are covered by the app test host rather than by the
45
+ compiled source project.
46
+
47
+ The source route modules keep SQL near the handlers because current function
48
+ module extraction does not support arbitrary helper calls inside module files.
49
+ The `src/services`, `src/db`, and `src/validation` folders document the intended
50
+ bounded-context layout without being imported by the compiled app yet.
@@ -0,0 +1,11 @@
1
+ {
2
+ "Sloppy": {
3
+ "Providers": {
4
+ "sqlite": {
5
+ "main": {
6
+ "database": "prealpha-control-plane-dev.db"
7
+ }
8
+ }
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "Sloppy": {
3
+ "Providers": {
4
+ "sqlite": {
5
+ "main": {
6
+ "database": "prealpha-control-plane.db"
7
+ }
8
+ }
9
+ }
10
+ },
11
+ "ControlPlane": {
12
+ "corsOrigin": "https://console.example",
13
+ "environment": "dogfood"
14
+ }
15
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "entry": "src/main.js",
3
+ "outDir": ".sloppy",
4
+ "environment": "Development"
5
+ }
@@ -0,0 +1,7 @@
1
+ export const schemaStatements = Object.freeze([
2
+ "create table if not exists projects (id integer primary key, slug text not null unique, name text not null, owner text not null)",
3
+ "create table if not exists apps (id integer primary key, project_id integer not null, name text not null, environment text not null)",
4
+ "create table if not exists builds (id integer primary key, app_id integer not null, commit_sha text not null, status text not null)",
5
+ "create table if not exists deployments (id integer primary key, app_id integer not null, build_id integer not null, status text not null)",
6
+ "create table if not exists diagnostics (id integer primary key, level text not null, message text not null)",
7
+ ]);
@@ -0,0 +1,6 @@
1
+ export const seedSummary = Object.freeze({
2
+ projects: 2,
3
+ apps: 2,
4
+ builds: 1,
5
+ diagnostics: 1,
6
+ });
@@ -0,0 +1,21 @@
1
+ import { ProblemDetails, Sloppy } from "sloppy";
2
+ import { sqlite } from "sloppy/providers/sqlite";
3
+ import { appsModule } from "./routes/apps.js";
4
+ import { buildsModule } from "./routes/builds.js";
5
+ import { deploymentsModule } from "./routes/deployments.js";
6
+ import { diagnosticsModule } from "./routes/diagnostics.js";
7
+ import { healthModule } from "./routes/health.js";
8
+ import { projectsModule } from "./routes/projects.js";
9
+
10
+ const app = Sloppy.create();
11
+
12
+ app.use(ProblemDetails.defaults());
13
+ app.use(sqlite("main", { database: "prealpha-control-plane.db" }));
14
+ app.useModule(healthModule);
15
+ app.useModule(projectsModule);
16
+ app.useModule(appsModule);
17
+ app.useModule(buildsModule);
18
+ app.useModule(deploymentsModule);
19
+ app.useModule(diagnosticsModule);
20
+
21
+ export default app;
@@ -0,0 +1,34 @@
1
+ import { Results } from "sloppy";
2
+
3
+ export function appsModule(app) {
4
+ const db = app.provider("sqlite:main");
5
+ const apps = app.group("/apps");
6
+
7
+ apps.get("/", async () => {
8
+ await db.exec("create table if not exists apps (id integer primary key, project_id integer not null, name text not null, environment text not null)", []);
9
+ await db.exec("insert into apps (id, project_id, name, environment) select ?, ?, ?, ? where not exists (select 1 from apps where id = ?)", [1, 1, "compiler-api", "Development", 1]);
10
+ await db.exec("insert into apps (id, project_id, name, environment) select ?, ?, ?, ? where not exists (select 1 from apps where id = ?)", [2, 2, "control-plane", "Development", 2]);
11
+ return Results.ok(await db.query("select id, project_id, name, environment from apps order by id", []));
12
+ }).withName("Apps.List");
13
+
14
+ apps.post("/", async (ctx) => {
15
+ const body = ctx.request.json();
16
+ if (body === null || Array.isArray(body) || typeof body !== "object" ||
17
+ typeof body.name !== "string" || body.name.length === 0 ||
18
+ !Number.isInteger(body.projectId) || body.projectId <= 0) {
19
+ return Results.badRequest({ code: "APP_INVALID", message: "projectId and name are required" });
20
+ }
21
+
22
+ await db.exec("create table if not exists apps (id integer primary key, project_id integer not null, name text not null, environment text not null)", []);
23
+ await db.exec("insert into apps (project_id, name, environment) values (?, ?, ?)", [body.projectId, body.name, body.environment ?? "Development"]);
24
+ const created = await db.queryOne("select id, project_id, name, environment from apps where id = last_insert_rowid()", []);
25
+ return Results.created(`/apps/${created.id}`, created);
26
+ }).withName("Apps.Create");
27
+
28
+ apps.get("/{id:int}", async (ctx) => {
29
+ await db.exec("create table if not exists apps (id integer primary key, project_id integer not null, name text not null, environment text not null)", []);
30
+ await db.exec("insert into apps (id, project_id, name, environment) select ?, ?, ?, ? where not exists (select 1 from apps where id = ?)", [1, 1, "compiler-api", "Development", 1]);
31
+ const current = await db.queryOne("select id, project_id, name, environment from apps where id = ?", [ctx.route.id]);
32
+ return current === null ? Results.notFound({ code: "APP_NOT_FOUND" }) : Results.ok(current);
33
+ }).withName("Apps.Get");
34
+ }
@@ -0,0 +1,25 @@
1
+ import { Results } from "sloppy";
2
+
3
+ export function buildsModule(app) {
4
+ const db = app.provider("sqlite:main");
5
+ const apps = app.group("/apps");
6
+
7
+ apps.post("/{id:int}/builds", async (ctx) => {
8
+ const body = ctx.request.json();
9
+ if (body === null || Array.isArray(body) || typeof body !== "object" ||
10
+ typeof body.commit !== "string" || body.commit.length === 0) {
11
+ return Results.badRequest({ code: "BUILD_INVALID", message: "commit is required" });
12
+ }
13
+
14
+ await db.exec("create table if not exists builds (id integer primary key, app_id integer not null, commit_sha text not null, status text not null)", []);
15
+ await db.exec("insert into builds (app_id, commit_sha, status) values (?, ?, ?)", [ctx.route.id, body.commit, "queued"]);
16
+ const build = await db.queryOne("select id, app_id, commit_sha, status from builds where id = last_insert_rowid()", []);
17
+ return Results.created(`/apps/${ctx.route.id}/builds/${build.id}`, build);
18
+ }).withName("Builds.Create");
19
+
20
+ apps.get("/{id:int}/builds", async (ctx) => {
21
+ await db.exec("create table if not exists builds (id integer primary key, app_id integer not null, commit_sha text not null, status text not null)", []);
22
+ await db.exec("insert into builds (id, app_id, commit_sha, status) select ?, ?, ?, ? where not exists (select 1 from builds where id = ?)", [1, ctx.route.id, "abc123", "succeeded", 1]);
23
+ return Results.ok(await db.query("select id, app_id, commit_sha, status from builds where app_id = ? order by id", [ctx.route.id]));
24
+ }).withName("Builds.List");
25
+ }
@@ -0,0 +1,19 @@
1
+ import { Results } from "sloppy";
2
+
3
+ export function deploymentsModule(app) {
4
+ const db = app.provider("sqlite:main");
5
+ const apps = app.group("/apps");
6
+
7
+ apps.post("/{id:int}/deployments", async (ctx) => {
8
+ const body = ctx.request.json();
9
+ if (body === null || Array.isArray(body) || typeof body !== "object" ||
10
+ !Number.isInteger(body.buildId) || body.buildId <= 0) {
11
+ return Results.badRequest({ code: "DEPLOYMENT_INVALID", message: "buildId is required" });
12
+ }
13
+
14
+ await db.exec("create table if not exists deployments (id integer primary key, app_id integer not null, build_id integer not null, status text not null)", []);
15
+ await db.exec("insert into deployments (app_id, build_id, status) values (?, ?, ?)", [ctx.route.id, body.buildId, "started"]);
16
+ const deployment = await db.queryOne("select id, app_id, build_id, status from deployments where id = last_insert_rowid()", []);
17
+ return Results.created(`/apps/${ctx.route.id}/deployments/${deployment.id}`, deployment);
18
+ }).withName("Deployments.Create");
19
+ }
@@ -0,0 +1,11 @@
1
+ import { Results } from "sloppy";
2
+
3
+ export function diagnosticsModule(app) {
4
+ const db = app.provider("sqlite:main");
5
+
6
+ app.get("/diagnostics/recent", async () => {
7
+ await db.exec("create table if not exists diagnostics (id integer primary key, level text not null, message text not null)", []);
8
+ await db.exec("insert into diagnostics (id, level, message) select ?, ?, ? where not exists (select 1 from diagnostics where id = ?)", [1, "info", "dogfood app bootstrapped", 1]);
9
+ return Results.ok(await db.query("select id, level, message from diagnostics order by id desc", []));
10
+ }).withName("Diagnostics.Recent");
11
+ }
@@ -0,0 +1,27 @@
1
+ import { Results } from "sloppy";
2
+
3
+ export function healthModule(app) {
4
+ const health = app.group("/health");
5
+
6
+ health.get("/", () => Results.ok({
7
+ status: "healthy",
8
+ checks: [
9
+ { name: "sqlite", status: "healthy" },
10
+ { name: "app-host", status: "healthy" },
11
+ ],
12
+ })).withName("Health");
13
+
14
+ health.get("/live", () => Results.ok({
15
+ status: "healthy",
16
+ checks: [
17
+ { name: "process", status: "healthy" },
18
+ ],
19
+ })).withName("Health.Liveness");
20
+
21
+ health.get("/ready", () => Results.ok({
22
+ status: "healthy",
23
+ checks: [
24
+ { name: "sqlite", status: "healthy" },
25
+ ],
26
+ })).withName("Health.Readiness");
27
+ }
@@ -0,0 +1,38 @@
1
+ import { Results } from "sloppy";
2
+
3
+ export function projectsModule(app) {
4
+ const db = app.provider("sqlite:main");
5
+ const projects = app.group("/projects");
6
+
7
+ projects.get("/", async (ctx) => {
8
+ await db.exec("create table if not exists projects (id integer primary key, slug text not null unique, name text not null, owner text not null)", []);
9
+ await db.exec("insert into projects (id, slug, name, owner) select ?, ?, ?, ? where not exists (select 1 from projects where id = ?)", [1, "compiler", "Compiler Platform", "runtime", 1]);
10
+ await db.exec("insert into projects (id, slug, name, owner) select ?, ?, ?, ? where not exists (select 1 from projects where id = ?)", [2, "web", "Web Framework", "framework", 2]);
11
+ const owner = ctx.query.owner;
12
+ if (owner !== undefined) {
13
+ return Results.ok(await db.query("select id, slug, name, owner from projects where owner = ? order by id", [owner]));
14
+ }
15
+ return Results.ok(await db.query("select id, slug, name, owner from projects order by id", []));
16
+ }).withName("Projects.List");
17
+
18
+ projects.post("/", async (ctx) => {
19
+ const body = ctx.request.json();
20
+ if (body === null || Array.isArray(body) || typeof body !== "object" ||
21
+ typeof body.slug !== "string" || body.slug.length === 0 ||
22
+ typeof body.name !== "string" || body.name.length === 0) {
23
+ return Results.badRequest({ code: "PROJECT_INVALID", message: "slug and name are required" });
24
+ }
25
+
26
+ await db.exec("create table if not exists projects (id integer primary key, slug text not null unique, name text not null, owner text not null)", []);
27
+ await db.exec("insert into projects (slug, name, owner) values (?, ?, ?)", [body.slug, body.name, body.owner ?? "platform"]);
28
+ const project = await db.queryOne("select id, slug, name, owner from projects where slug = ?", [body.slug]);
29
+ return Results.created(`/projects/${project.id}`, project);
30
+ }).withName("Projects.Create");
31
+
32
+ projects.get("/{id:int}", async (ctx) => {
33
+ await db.exec("create table if not exists projects (id integer primary key, slug text not null unique, name text not null, owner text not null)", []);
34
+ await db.exec("insert into projects (id, slug, name, owner) select ?, ?, ?, ? where not exists (select 1 from projects where id = ?)", [1, "compiler", "Compiler Platform", "runtime", 1]);
35
+ const project = await db.queryOne("select id, slug, name, owner from projects where id = ?", [ctx.route.id]);
36
+ return project === null ? Results.notFound({ code: "PROJECT_NOT_FOUND" }) : Results.ok(project);
37
+ }).withName("Projects.Get");
38
+ }
@@ -0,0 +1,11 @@
1
+ export function createDiagnosticsSink() {
2
+ const entries = [];
3
+ return Object.freeze({
4
+ push(entry) {
5
+ entries.push(Object.freeze({ ...entry }));
6
+ },
7
+ recent() {
8
+ return Object.freeze(entries.slice().reverse());
9
+ },
10
+ });
11
+ }
@@ -0,0 +1,9 @@
1
+ export function repositoryTokens() {
2
+ return Object.freeze([
3
+ "projects",
4
+ "apps",
5
+ "builds",
6
+ "deployments",
7
+ "diagnostics",
8
+ ]);
9
+ }
@@ -0,0 +1,6 @@
1
+ export const validationShapes = Object.freeze({
2
+ projectCreate: ["slug", "name"],
3
+ appCreate: ["projectId", "name"],
4
+ buildCreate: ["commit"],
5
+ deploymentCreate: ["buildId"],
6
+ });
@@ -0,0 +1,31 @@
1
+ # Program Filesystem And Process
2
+
3
+ Program Mode can use the Sloppy stdlib without declaring a web app. This
4
+ example writes a small file, reads it back, and runs `git --version` through
5
+ `Process.run`.
6
+
7
+ Prerequisite: `git` must be installed and available on `PATH` for the
8
+ `Process.run("git", ["--version"])` call.
9
+
10
+ Run from this directory with a V8-enabled build:
11
+
12
+ ```powershell
13
+ sloppy run -- report
14
+ ```
15
+
16
+ Build and run the artifacts:
17
+
18
+ ```powershell
19
+ sloppy build
20
+ sloppy run .sloppy -- report
21
+ ```
22
+
23
+ Package and run from the package directory:
24
+
25
+ ```powershell
26
+ sloppy package
27
+ sloppy run .sloppy/package -- report
28
+ ```
29
+
30
+ The example writes under `./tmp`. It uses `sloppy/fs` and `sloppy/os`; it does
31
+ not use Node `fs`, `process`, or `child_process` globals.
@@ -0,0 +1,9 @@
1
+ {
2
+ "kind": "program",
3
+ "entry": "src/main.ts",
4
+ "outDir": ".sloppy",
5
+ "capabilities": {
6
+ "fs": true,
7
+ "os": true
8
+ }
9
+ }
@@ -0,0 +1,27 @@
1
+ import { Directory, File } from "sloppy/fs";
2
+ import { Process, System } from "sloppy/os";
3
+
4
+ function sanitizeFilename(value) {
5
+ const text = String(value || "report")
6
+ .replace(/[^A-Za-z0-9_-]/g, "_")
7
+ .slice(0, 64);
8
+ return text.length > 0 ? text : "report";
9
+ }
10
+
11
+ export async function main(args, ctx) {
12
+ const name = sanitizeFilename(args[0]);
13
+ const path = `./tmp/${name}.txt`;
14
+
15
+ await Directory.create("./tmp", { recursive: true });
16
+ await File.writeText(path, `kind=${ctx.kind}\nplatform=${System.platform}\n`);
17
+
18
+ const text = await File.readText(path);
19
+ const git = await Process.run("git", ["--version"], {
20
+ capture: "text",
21
+ timeoutMs: 5000,
22
+ });
23
+
24
+ console.log(text.trim());
25
+ console.log(git.stdout.trim());
26
+ return git.exitCode;
27
+ }
@@ -0,0 +1,32 @@
1
+ # Program Hello
2
+
3
+ Minimal Program Mode source. It does not declare a web app or routes; the
4
+ compiler emits a Program Plan with an opaque metadata status and a
5
+ `__sloppy_program_main` entrypoint.
6
+
7
+ Run the source directly when using a V8-enabled build:
8
+
9
+ ```powershell
10
+ sloppy run main.ts -- Ada
11
+ ```
12
+
13
+ Build and inspect the generated artifacts:
14
+
15
+ ```powershell
16
+ sloppy build main.ts
17
+ sloppy run .sloppy -- Ada
18
+ sloppy routes .sloppy --format json
19
+ sloppy capabilities .sloppy
20
+ ```
21
+
22
+ `sloppy.json` is optional project pinning for this example. From this directory,
23
+ the same project can be built with:
24
+
25
+ ```powershell
26
+ sloppy build
27
+ sloppy run .sloppy -- Ada
28
+ ```
29
+
30
+ Program execution requires a V8-enabled build. In a default non-V8 developer
31
+ build, `sloppy run main.ts -- Ada` and `sloppy run .sloppy -- Ada` fail before V8
32
+ initialization with a required-feature diagnostic.
@@ -0,0 +1,8 @@
1
+ import { message } from "./message";
2
+
3
+ export function main(args, ctx) {
4
+ const suffix = args.length > 0 ? ` ${args.join(" ")}` : "";
5
+ console.log(`${message}${suffix}`);
6
+ console.log(`cwd=${ctx.cwd}`);
7
+ return 0;
8
+ }
@@ -0,0 +1 @@
1
+ export const message = "hello from sloppy program mode";
@@ -0,0 +1,5 @@
1
+ {
2
+ "kind": "program",
3
+ "entry": "main.ts",
4
+ "outDir": ".sloppy"
5
+ }
@@ -0,0 +1,3 @@
1
+ # Rate Limit Auth
2
+
3
+ Shows a token-bucket limiter partitioned by authenticated user.
@@ -0,0 +1,14 @@
1
+ import { RateLimit, Results, Sloppy } from "sloppy";
2
+
3
+ const app = Sloppy.create();
4
+
5
+ app.get("/me", (ctx) => Results.ok({ sub: ctx.user.sub }))
6
+ .requiresAuth()
7
+ .rateLimit(RateLimit.tokenBucket({
8
+ name: "me",
9
+ capacity: 100,
10
+ refillPerSecond: 10,
11
+ partitionBy: RateLimit.partition.user(),
12
+ }));
13
+
14
+ export default app;
@@ -0,0 +1,3 @@
1
+ # Rate Limit Basic
2
+
3
+ Protects a public login route with a sliding-window IP limiter.
@@ -0,0 +1,13 @@
1
+ import { RateLimit, Results, Sloppy } from "sloppy";
2
+
3
+ const app = Sloppy.create();
4
+
5
+ app.post("/login", () => Results.ok({ ok: true }))
6
+ .rateLimit(RateLimit.slidingWindow({
7
+ name: "login",
8
+ limit: 5,
9
+ windowMs: 60_000,
10
+ partitionBy: RateLimit.partition.ip(),
11
+ }));
12
+
13
+ export default app;
@@ -0,0 +1,5 @@
1
+ # Rate Limit Redis
2
+
3
+ Demonstrates the distributed-store registration shape. This build does not
4
+ include a first-party Redis provider, so the adapter fails closed instead of
5
+ falling back to memory.
@@ -0,0 +1,20 @@
1
+ import { RateLimit, Results, Sloppy } from "sloppy";
2
+
3
+ const app = Sloppy.create();
4
+
5
+ const redisStore = RateLimit.redis(undefined, {
6
+ prefix: "sloppy:rl:",
7
+ });
8
+
9
+ app.services.addRateLimitStore("redis", redisStore);
10
+
11
+ app.post("/login", () => Results.ok({ ok: true }))
12
+ .rateLimit(RateLimit.slidingWindow({
13
+ name: "login",
14
+ limit: 5,
15
+ windowMs: 60_000,
16
+ store: "redis",
17
+ partitionBy: RateLimit.partition.ip(),
18
+ }));
19
+
20
+ export default app;
@@ -0,0 +1,4 @@
1
+ # Rate Limit TestHost
2
+
3
+ Use `TestHost.create(app, { clock, rateLimit: { stores } })` to isolate stores
4
+ and drive windows with a fake clock.
@@ -0,0 +1,13 @@
1
+ import { RateLimit, Results, Sloppy } from "sloppy";
2
+
3
+ const app = Sloppy.create();
4
+
5
+ app.get("/limited", () => Results.ok({ ok: true }))
6
+ .rateLimit(RateLimit.fixedWindow({
7
+ name: "test",
8
+ limit: 1,
9
+ windowMs: 1000,
10
+ partitionBy: RateLimit.partition.ip(),
11
+ }));
12
+
13
+ export default app;
@@ -0,0 +1,3 @@
1
+ # Rate Limit WebSocket
2
+
3
+ Applies a fixed-window limiter to WebSocket upgrade attempts.
@@ -0,0 +1,16 @@
1
+ import { RateLimit, Sloppy } from "sloppy";
2
+
3
+ const app = Sloppy.create();
4
+
5
+ app.websocket("/ws", async (socket) => {
6
+ await socket.accept();
7
+ await socket.sendText("connected");
8
+ })
9
+ .rateLimit(RateLimit.fixedWindow({
10
+ name: "ws-connect",
11
+ limit: 10,
12
+ windowMs: 60_000,
13
+ partitionBy: RateLimit.partition.ip(),
14
+ }));
15
+
16
+ export default app;
@@ -0,0 +1,8 @@
1
+ # Realtime Auth
2
+
3
+ Realtime auth example covering route-level auth, origin policy, and
4
+ per-message role checks.
5
+
6
+ ```powershell
7
+ node examples/realtime-auth/test.mjs
8
+ ```
@@ -0,0 +1,25 @@
1
+ import { Realtime, Sloppy, schema } from "sloppy";
2
+
3
+ export const SecureChannel = Realtime.channel("secureChat", {
4
+ client: {
5
+ adminMessage: Realtime.event(schema.object({
6
+ text: schema.string(),
7
+ })).requiresRole("admin"),
8
+ },
9
+ server: {
10
+ accepted: schema.object({
11
+ text: schema.string(),
12
+ }),
13
+ },
14
+ });
15
+
16
+ const app = Sloppy.create();
17
+
18
+ app.realtime("/secure/chat", SecureChannel, async (ctx) => {
19
+ await ctx.accept();
20
+ ctx.on("adminMessage", async (input) => {
21
+ await ctx.send("accepted", { text: input.text });
22
+ });
23
+ }).requiresAuth().requiresScope("chat").allowedOrigins(["https://app.example.com"]);
24
+
25
+ export default app;
@@ -0,0 +1,43 @@
1
+ import { Realtime, Sloppy, TestHost, schema } from "sloppy";
2
+
3
+ const SecureChannel = Realtime.channel("secureChat", {
4
+ client: {
5
+ adminMessage: Realtime.event(schema.object({
6
+ text: schema.string(),
7
+ })).requiresRole("admin"),
8
+ },
9
+ server: {
10
+ accepted: schema.object({
11
+ text: schema.string(),
12
+ }),
13
+ },
14
+ });
15
+
16
+ const app = Sloppy.create();
17
+
18
+ app.realtime("/secure/chat", SecureChannel, async (ctx) => {
19
+ await ctx.accept();
20
+ ctx.on("adminMessage", async (input) => {
21
+ await ctx.send("accepted", { text: input.text });
22
+ });
23
+ }).requiresAuth().requiresScope("chat").allowedOrigins(["https://app.example.com"]);
24
+
25
+ const host = await TestHost.create(app);
26
+
27
+ try {
28
+ await host.realtime("/secure/chat", SecureChannel)
29
+ .origin("https://app.example.com")
30
+ .connect()
31
+ .expectRejected(401);
32
+
33
+ const writer = await host.realtime("/secure/chat", SecureChannel)
34
+ .origin("https://app.example.com")
35
+ .asUser({ sub: "writer", scopes: ["chat"], roles: ["admin"] })
36
+ .connect();
37
+
38
+ await writer.send("adminMessage", { text: "approved" });
39
+ await writer.expect("accepted", { text: "approved" });
40
+ await writer.close();
41
+ } finally {
42
+ await host.close();
43
+ }
@@ -0,0 +1,8 @@
1
+ # Realtime Chat
2
+
3
+ Typed chat room example using `app.realtime(...)`, a `Realtime.channel(...)`,
4
+ single-process groups, route auth, and TestHost clients.
5
+
6
+ ```powershell
7
+ node examples/realtime-chat/test.mjs
8
+ ```