@slopware/sloppy-darwin-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.
- package/LICENSE +201 -0
- package/README.md +5 -0
- package/bin/sloppy +0 -0
- package/bin/sloppyc +0 -0
- package/docs/KNOWN_LIMITATIONS.md +16 -0
- package/docs/LICENSES.md +6 -0
- package/docs/NOTICE.md +8 -0
- package/examples/README.md +140 -0
- package/examples/auth-api/README.md +20 -0
- package/examples/auth-api/app.js +61 -0
- package/examples/auth-api/appsettings.json +7 -0
- package/examples/auth-api/sloppy.json +5 -0
- package/examples/cache-basic/README.md +9 -0
- package/examples/cache-basic/app.js +32 -0
- package/examples/cache-hybrid-postgres/README.md +10 -0
- package/examples/cache-hybrid-postgres/app.js +27 -0
- package/examples/cache-output-api/README.md +10 -0
- package/examples/cache-output-api/app.js +35 -0
- package/examples/codec-base64-hex/README.md +14 -0
- package/examples/codec-base64-hex/app.js +15 -0
- package/examples/codec-checksums/README.md +15 -0
- package/examples/codec-checksums/app.js +8 -0
- package/examples/codec-compression/README.md +13 -0
- package/examples/codec-compression/app.js +9 -0
- package/examples/codec-streaming-compression/README.md +19 -0
- package/examples/codec-streaming-compression/app.js +16 -0
- package/examples/codec-text-binary/README.md +16 -0
- package/examples/codec-text-binary/app.js +17 -0
- package/examples/compiler-hello/README.md +71 -0
- package/examples/compiler-hello/app.js +7 -0
- package/examples/compiler-hello/expected/app.js +8 -0
- package/examples/compiler-hello/expected/app.js.map +53 -0
- package/examples/compiler-hello/expected/app.plan.json +229 -0
- package/examples/compiler-hello/expected/routes.slrt +0 -0
- package/examples/config-basic/README.md +13 -0
- package/examples/config-basic/app.js +13 -0
- package/examples/config-basic/appsettings.json +7 -0
- package/examples/config-secrets-redaction/README.md +9 -0
- package/examples/config-secrets-redaction/app.js +9 -0
- package/examples/config-secrets-redaction/appsettings.json +5 -0
- package/examples/config-strict-mode/README.md +7 -0
- package/examples/config-strict-mode/app.js +10 -0
- package/examples/config-strict-mode/appsettings.json +7 -0
- package/examples/configured-api/README.md +38 -0
- package/examples/configured-api/app.js +12 -0
- package/examples/configured-api/appsettings.Development.json +5 -0
- package/examples/configured-api/appsettings.json +6 -0
- package/examples/configured-api/sloppy.json +5 -0
- package/examples/core-config-secrets/README.md +10 -0
- package/examples/core-config-secrets/app.js +15 -0
- package/examples/core-fs-time-codec/README.md +9 -0
- package/examples/core-fs-time-codec/app.js +8 -0
- package/examples/core-network-time-codec/README.md +11 -0
- package/examples/core-network-time-codec/app.js +20 -0
- package/examples/core-policy-audit/README.md +7 -0
- package/examples/core-policy-audit/app.js +22 -0
- package/examples/core-process-time-codec/README.md +8 -0
- package/examples/core-process-time-codec/app.js +28 -0
- package/examples/core-worker-time/README.md +8 -0
- package/examples/core-worker-time/app.js +17 -0
- package/examples/crypto-hash-hmac/README.md +17 -0
- package/examples/crypto-hash-hmac/app.js +29 -0
- package/examples/crypto-password/README.md +21 -0
- package/examples/crypto-password/app.js +12 -0
- package/examples/crypto-random-token/README.md +16 -0
- package/examples/crypto-random-token/app.js +12 -0
- package/examples/crypto-secret-constant-time/README.md +21 -0
- package/examples/crypto-secret-constant-time/app.js +15 -0
- package/examples/data-foundation/README.md +39 -0
- package/examples/data-foundation/app.js +63 -0
- package/examples/dependency-graph/README.md +19 -0
- package/examples/dependency-graph/fixtures/graph-helper/index.js +3 -0
- package/examples/dependency-graph/fixtures/graph-helper/package.json +6 -0
- package/examples/dependency-graph/package.json +7 -0
- package/examples/dependency-graph/public/message.txt +1 -0
- package/examples/dependency-graph/sloppy.json +9 -0
- package/examples/dependency-graph/src/main.ts +8 -0
- package/examples/dogfood/README.md +23 -0
- package/examples/dogfood/dogfood.json +136 -0
- package/examples/dynamic-module-include/README.md +20 -0
- package/examples/dynamic-module-include/public/readme.txt +1 -0
- package/examples/dynamic-module-include/sloppy.json +12 -0
- package/examples/dynamic-module-include/src/main.ts +6 -0
- package/examples/dynamic-module-include/src/plugins/alpha.js +3 -0
- package/examples/dynamic-module-include/src/plugins/beta.js +3 -0
- package/examples/ergonomics/README.md +42 -0
- package/examples/ergonomics/app.js +38 -0
- package/examples/framework-controller/README.md +12 -0
- package/examples/framework-controller/app.js +31 -0
- package/examples/framework-di-services/README.md +17 -0
- package/examples/framework-di-services/app.ts +40 -0
- package/examples/framework-explicit-binding/README.md +12 -0
- package/examples/framework-explicit-binding/app.ts +34 -0
- package/examples/framework-hello/README.md +16 -0
- package/examples/framework-hello/app.ts +16 -0
- package/examples/framework-postgres-crud/README.md +73 -0
- package/examples/framework-postgres-crud/app.ts +64 -0
- package/examples/framework-sqlite-crud/README.md +52 -0
- package/examples/framework-sqlite-crud/app.ts +90 -0
- package/examples/framework-sqlite-crud/appsettings.json +11 -0
- package/examples/framework-sqlserver-crud/README.md +73 -0
- package/examples/framework-sqlserver-crud/app.ts +64 -0
- package/examples/framework-validation-errors/README.md +12 -0
- package/examples/framework-validation-errors/app.ts +16 -0
- package/examples/fs-basic/README.md +24 -0
- package/examples/fs-basic/app.js +12 -0
- package/examples/fs-roots-policy/README.md +14 -0
- package/examples/fs-roots-policy/app.js +4 -0
- package/examples/fs-streams/README.md +18 -0
- package/examples/fs-streams/app.js +11 -0
- package/examples/fs-watch/README.md +19 -0
- package/examples/fs-watch/app.js +11 -0
- package/examples/hello/README.md +63 -0
- package/examples/hello/app.js +19 -0
- package/examples/hello-minimal/README.md +51 -0
- package/examples/hello-minimal/sloppy.json +5 -0
- package/examples/hello-minimal/src/main.ts +9 -0
- package/examples/http-client-basic/README.md +11 -0
- package/examples/http-client-basic/app.js +46 -0
- package/examples/http-client-generated/README.md +22 -0
- package/examples/http-client-generated/openapi.json +45 -0
- package/examples/http-client-resilience/README.md +4 -0
- package/examples/http-client-resilience/app.js +38 -0
- package/examples/http-client-runtime-loopback/README.md +24 -0
- package/examples/http-client-testhost/README.md +4 -0
- package/examples/http-client-testhost/app.js +27 -0
- package/examples/http-client-testhost-package-mock/README.md +26 -0
- package/examples/http-client-typed/README.md +5 -0
- package/examples/http-client-typed/app.js +33 -0
- package/examples/modules-api/README.md +30 -0
- package/examples/modules-api/app.js +9 -0
- package/examples/modules-api/modules/routes.js +16 -0
- package/examples/modules-api/sloppy.json +5 -0
- package/examples/modules-basic/README.md +32 -0
- package/examples/modules-basic/app.js +41 -0
- package/examples/net-deadline-cancel/README.md +13 -0
- package/examples/net-deadline-cancel/app.js +34 -0
- package/examples/net-local-ipc/README.md +12 -0
- package/examples/net-local-ipc/app.js +46 -0
- package/examples/net-policy-strict/README.md +12 -0
- package/examples/net-policy-strict/app.js +34 -0
- package/examples/net-tcp-client/README.md +10 -0
- package/examples/net-tcp-client/app.js +23 -0
- package/examples/net-tcp-echo/README.md +11 -0
- package/examples/net-tcp-echo/app.js +45 -0
- package/examples/net-tcp-server/README.md +10 -0
- package/examples/net-tcp-server/app.js +28 -0
- package/examples/node-compat-path-events/README.md +15 -0
- package/examples/node-compat-path-events/sloppy.json +6 -0
- package/examples/node-compat-path-events/src/main.ts +15 -0
- package/examples/ops-compiler/README.md +9 -0
- package/examples/ops-compiler/app.js +26 -0
- package/examples/ops-health-metrics-management/README.md +14 -0
- package/examples/ops-health-metrics-management/app.js +24 -0
- package/examples/orm-basic/README.md +17 -0
- package/examples/orm-basic/app.js +82 -0
- package/examples/orm-cursor-export/README.md +16 -0
- package/examples/orm-cursor-export/app.js +28 -0
- package/examples/orm-migrations/README.md +14 -0
- package/examples/orm-migrations/migrations/.gitkeep +1 -0
- package/examples/orm-migrations/sloppy.json +9 -0
- package/examples/orm-migrations/src/app.ts +34 -0
- package/examples/orm-relations-includes/README.md +10 -0
- package/examples/orm-relations-includes/app.js +47 -0
- package/examples/orm-testservices/README.md +37 -0
- package/examples/orm-testservices/test.mjs +32 -0
- package/examples/os-runtime-api/README.md +11 -0
- package/examples/os-runtime-api/app.js +44 -0
- package/examples/package-zod-like/README.md +28 -0
- package/examples/package-zod-like/fixtures/zod-like/index.js +48 -0
- package/examples/package-zod-like/fixtures/zod-like/package.json +12 -0
- package/examples/package-zod-like/package.json +7 -0
- package/examples/package-zod-like/sloppy.json +6 -0
- package/examples/package-zod-like/src/main.ts +16 -0
- package/examples/postgres-basic/README.md +31 -0
- package/examples/postgres-basic/app.js +50 -0
- package/examples/prealpha-control-plane/README.md +50 -0
- package/examples/prealpha-control-plane/appsettings.Development.json +11 -0
- package/examples/prealpha-control-plane/appsettings.json +15 -0
- package/examples/prealpha-control-plane/sloppy.json +5 -0
- package/examples/prealpha-control-plane/src/db/schema.js +7 -0
- package/examples/prealpha-control-plane/src/db/seed.js +6 -0
- package/examples/prealpha-control-plane/src/main.js +21 -0
- package/examples/prealpha-control-plane/src/routes/apps.js +34 -0
- package/examples/prealpha-control-plane/src/routes/builds.js +25 -0
- package/examples/prealpha-control-plane/src/routes/deployments.js +19 -0
- package/examples/prealpha-control-plane/src/routes/diagnostics.js +11 -0
- package/examples/prealpha-control-plane/src/routes/health.js +27 -0
- package/examples/prealpha-control-plane/src/routes/projects.js +38 -0
- package/examples/prealpha-control-plane/src/services/diagnosticsSink.js +11 -0
- package/examples/prealpha-control-plane/src/services/repositories.js +9 -0
- package/examples/prealpha-control-plane/src/validation/schemas.js +6 -0
- package/examples/program-fs-process/README.md +31 -0
- package/examples/program-fs-process/sloppy.json +9 -0
- package/examples/program-fs-process/src/main.ts +27 -0
- package/examples/program-hello/README.md +32 -0
- package/examples/program-hello/main.ts +8 -0
- package/examples/program-hello/message.ts +1 -0
- package/examples/program-hello/sloppy.json +5 -0
- package/examples/rate-limit-auth/README.md +3 -0
- package/examples/rate-limit-auth/app.js +14 -0
- package/examples/rate-limit-basic/README.md +3 -0
- package/examples/rate-limit-basic/app.js +13 -0
- package/examples/rate-limit-redis/README.md +5 -0
- package/examples/rate-limit-redis/app.js +20 -0
- package/examples/rate-limit-testhost/README.md +4 -0
- package/examples/rate-limit-testhost/app.js +13 -0
- package/examples/rate-limit-websocket/README.md +3 -0
- package/examples/rate-limit-websocket/app.js +16 -0
- package/examples/realtime-auth/README.md +8 -0
- package/examples/realtime-auth/app.js +25 -0
- package/examples/realtime-auth/test.mjs +43 -0
- package/examples/realtime-chat/README.md +8 -0
- package/examples/realtime-chat/app.js +32 -0
- package/examples/realtime-chat/test.mjs +52 -0
- package/examples/realtime-dashboard/README.md +20 -0
- package/examples/realtime-dashboard/app.js +37 -0
- package/examples/realtime-presence/README.md +8 -0
- package/examples/realtime-presence/app.js +32 -0
- package/examples/realtime-presence/test.mjs +50 -0
- package/examples/realtime-testhost/README.md +8 -0
- package/examples/realtime-testhost/test.mjs +31 -0
- package/examples/redis-basic/README.md +17 -0
- package/examples/redis-basic/app.js +39 -0
- package/examples/redis-cache/README.md +14 -0
- package/examples/redis-cache/app.js +36 -0
- package/examples/redis-locks/README.md +13 -0
- package/examples/redis-locks/app.js +49 -0
- package/examples/request-context/README.md +32 -0
- package/examples/request-context/app.js +15 -0
- package/examples/sqlite-basic/README.md +52 -0
- package/examples/sqlite-basic/app.js +56 -0
- package/examples/sqlserver-basic/README.md +36 -0
- package/examples/sqlserver-basic/app.js +59 -0
- package/examples/static-files-basic/README.md +11 -0
- package/examples/static-files-basic/app.js +12 -0
- package/examples/static-files-basic/public/app.js +1 -0
- package/examples/static-files-basic/public/site.css +3 -0
- package/examples/static-files-package/README.md +12 -0
- package/examples/static-files-package/app.js +10 -0
- package/examples/static-files-package/public/index.html +2 -0
- package/examples/static-files-precompressed/README.md +12 -0
- package/examples/static-files-precompressed/app.js +11 -0
- package/examples/static-files-precompressed/public/app.js +1 -0
- package/examples/static-files-precompressed/public/app.js.br +0 -0
- package/examples/static-files-precompressed/public/app.js.gz +0 -0
- package/examples/static-files-spa/README.md +12 -0
- package/examples/static-files-spa/app.js +16 -0
- package/examples/static-files-spa/dist/assets/app.js +1 -0
- package/examples/static-files-spa/dist/index.html +4 -0
- package/examples/static-files-testhost/README.md +8 -0
- package/examples/static-files-testhost/app.js +13 -0
- package/examples/static-files-testhost/public/app.js +1 -0
- package/examples/static-files-testhost/public/app.js.gz +0 -0
- package/examples/static-files-testhost/test.mjs +38 -0
- package/examples/testhost-basic/README.md +26 -0
- package/examples/testhost-db/README.md +31 -0
- package/examples/testservices-postgres/README.md +68 -0
- package/examples/testservices-redis/README.md +71 -0
- package/examples/testservices-sqlserver/README.md +75 -0
- package/examples/time-basic/README.md +18 -0
- package/examples/time-basic/app.js +12 -0
- package/examples/time-deadline-cancellation/README.md +11 -0
- package/examples/time-deadline-cancellation/app.js +27 -0
- package/examples/time-fake-clock/README.md +14 -0
- package/examples/time-fake-clock/app.js +25 -0
- package/examples/time-interval-schedule/README.md +13 -0
- package/examples/time-interval-schedule/app.js +60 -0
- package/examples/users-api-sqlite/README.md +74 -0
- package/examples/users-api-sqlite/app.js +11 -0
- package/examples/users-api-sqlite/appsettings.Development.json +11 -0
- package/examples/users-api-sqlite/appsettings.json +11 -0
- package/examples/users-api-sqlite/modules/users.js +40 -0
- package/examples/users-api-sqlite/sloppy.json +5 -0
- package/examples/validation-errors/README.md +36 -0
- package/examples/validation-errors/app.js +14 -0
- package/examples/validation-errors/invalid-user.http +6 -0
- package/examples/validation-errors/sloppy.json +5 -0
- package/examples/web-dynamic-routes/README.md +17 -0
- package/examples/web-dynamic-routes/app.ts +27 -0
- package/examples/webhooks-basic/README.md +11 -0
- package/examples/webhooks-basic/app.js +48 -0
- package/examples/websocket-auth/README.md +8 -0
- package/examples/websocket-auth/app.js +16 -0
- package/examples/websocket-echo/README.md +9 -0
- package/examples/websocket-echo/app.js +36 -0
- package/examples/websocket-json-schema/README.md +5 -0
- package/examples/websocket-json-schema/app.js +25 -0
- package/examples/websocket-testhost/README.md +11 -0
- package/examples/websocket-testhost/test.mjs +49 -0
- package/examples/workers-background-service/README.md +7 -0
- package/examples/workers-background-service/app.js +16 -0
- package/examples/workers-js-isolate/README.md +8 -0
- package/examples/workers-js-isolate/app.js +19 -0
- package/examples/workers-js-isolate/workers/parser.ts +11 -0
- package/examples/workers-shutdown/README.md +6 -0
- package/examples/workers-shutdown/app.js +26 -0
- package/examples/workers-workerpool/README.md +6 -0
- package/examples/workers-workerpool/app.js +23 -0
- package/examples/workers-workqueue/README.md +8 -0
- package/examples/workers-workqueue/app.js +24 -0
- package/manifest.json +59 -0
- package/package.json +31 -0
- package/stdlib/sloppy/README.md +177 -0
- package/stdlib/sloppy/app.js +2142 -0
- package/stdlib/sloppy/auth.js +1813 -0
- package/stdlib/sloppy/bootstrap.manifest.json +83 -0
- package/stdlib/sloppy/cache.js +1542 -0
- package/stdlib/sloppy/codec.js +1153 -0
- package/stdlib/sloppy/config.js +61 -0
- package/stdlib/sloppy/crypto.js +312 -0
- package/stdlib/sloppy/data.js +2945 -0
- package/stdlib/sloppy/ffi.js +185 -0
- package/stdlib/sloppy/fs.js +795 -0
- package/stdlib/sloppy/health.js +603 -0
- package/stdlib/sloppy/http.js +1595 -0
- package/stdlib/sloppy/index.js +59 -0
- package/stdlib/sloppy/internal/bytes.js +31 -0
- package/stdlib/sloppy/internal/capabilities.js +155 -0
- package/stdlib/sloppy/internal/config.js +640 -0
- package/stdlib/sloppy/internal/disposable.js +31 -0
- package/stdlib/sloppy/internal/headers.js +63 -0
- package/stdlib/sloppy/internal/intrinsics.js +2 -0
- package/stdlib/sloppy/internal/json.js +20 -0
- package/stdlib/sloppy/internal/logging.js +278 -0
- package/stdlib/sloppy/internal/modules.js +405 -0
- package/stdlib/sloppy/internal/redaction.js +87 -0
- package/stdlib/sloppy/internal/routes.js +2279 -0
- package/stdlib/sloppy/internal/runtime-classic.js +19837 -0
- package/stdlib/sloppy/internal/services.js +690 -0
- package/stdlib/sloppy/internal/shared.js +32 -0
- package/stdlib/sloppy/internal/testhost-diagnostics.js +88 -0
- package/stdlib/sloppy/internal/testhost-http-server.js +238 -0
- package/stdlib/sloppy/internal/testhost-http.js +118 -0
- package/stdlib/sloppy/internal/testhost-loopback.js +50 -0
- package/stdlib/sloppy/internal/testservices-docker.js +154 -0
- package/stdlib/sloppy/internal/validation.js +117 -0
- package/stdlib/sloppy/metrics.js +427 -0
- package/stdlib/sloppy/net.js +5208 -0
- package/stdlib/sloppy/node/assert/strict.js +39 -0
- package/stdlib/sloppy/node/assert.js +228 -0
- package/stdlib/sloppy/node/buffer.js +247 -0
- package/stdlib/sloppy/node/console.js +33 -0
- package/stdlib/sloppy/node/constants.js +9 -0
- package/stdlib/sloppy/node/crypto.js +89 -0
- package/stdlib/sloppy/node/diagnostics_channel.js +41 -0
- package/stdlib/sloppy/node/events.js +113 -0
- package/stdlib/sloppy/node/fs/promises.js +27 -0
- package/stdlib/sloppy/node/fs.js +280 -0
- package/stdlib/sloppy/node/http.js +11 -0
- package/stdlib/sloppy/node/https.js +11 -0
- package/stdlib/sloppy/node/module.js +40 -0
- package/stdlib/sloppy/node/os.js +22 -0
- package/stdlib/sloppy/node/path.js +78 -0
- package/stdlib/sloppy/node/perf_hooks.js +12 -0
- package/stdlib/sloppy/node/process.js +129 -0
- package/stdlib/sloppy/node/querystring.js +21 -0
- package/stdlib/sloppy/node/stream/promises.js +3 -0
- package/stdlib/sloppy/node/stream.js +132 -0
- package/stdlib/sloppy/node/string_decoder.js +23 -0
- package/stdlib/sloppy/node/timers.js +26 -0
- package/stdlib/sloppy/node/tty.js +18 -0
- package/stdlib/sloppy/node/url.js +17 -0
- package/stdlib/sloppy/node/util.js +95 -0
- package/stdlib/sloppy/node/zlib.js +72 -0
- package/stdlib/sloppy/orm.js +2188 -0
- package/stdlib/sloppy/os.js +580 -0
- package/stdlib/sloppy/problem-details.js +29 -0
- package/stdlib/sloppy/providers/sqlite.js +26 -0
- package/stdlib/sloppy/rate-limit.js +856 -0
- package/stdlib/sloppy/realtime.js +1508 -0
- package/stdlib/sloppy/redis.js +1272 -0
- package/stdlib/sloppy/request-id.js +184 -0
- package/stdlib/sloppy/request-logging.js +101 -0
- package/stdlib/sloppy/results.js +933 -0
- package/stdlib/sloppy/schema.js +546 -0
- package/stdlib/sloppy/testing.js +4081 -0
- package/stdlib/sloppy/testservices.js +1041 -0
- package/stdlib/sloppy/time.js +894 -0
- package/stdlib/sloppy/webhooks.js +1330 -0
- package/stdlib/sloppy/workers.js +986 -0
- package/templates/api/README.md +82 -0
- package/templates/api/appsettings.Development.json +14 -0
- package/templates/api/appsettings.json +13 -0
- package/templates/api/data/.gitkeep +1 -0
- package/templates/api/gitignore +4 -0
- package/templates/api/migrations/0001_create_users.sql +1 -0
- package/templates/api/package.json +16 -0
- package/templates/api/public/hello.txt +1 -0
- package/templates/api/sloppy.json +14 -0
- package/templates/api/src/config.ts +1 -0
- package/templates/api/src/db/migrate.ts +14 -0
- package/templates/api/src/db/schema.ts +4 -0
- package/templates/api/src/db/usersRepository.ts +23 -0
- package/templates/api/src/main.ts +18 -0
- package/templates/api/src/models/user.ts +7 -0
- package/templates/api/src/routes/health.ts +20 -0
- package/templates/api/src/routes/users.ts +40 -0
- package/templates/api/src/services/usersService.ts +21 -0
- package/templates/api/tsconfig.json +15 -0
- package/templates/cli/README.md +16 -0
- package/templates/cli/gitignore +2 -0
- package/templates/cli/package.json +13 -0
- package/templates/cli/sloppy.json +6 -0
- package/templates/cli/src/commands/echo.ts +9 -0
- package/templates/cli/src/commands/inspect.ts +20 -0
- package/templates/cli/src/main.ts +50 -0
- package/templates/cli/tsconfig.json +15 -0
- package/templates/minimal-api/README.md +14 -0
- package/templates/minimal-api/gitignore +3 -0
- package/templates/minimal-api/package.json +14 -0
- package/templates/minimal-api/sloppy.json +5 -0
- package/templates/minimal-api/src/main.ts +9 -0
- package/templates/minimal-api/tsconfig.json +15 -0
- package/templates/node-compat/README.md +40 -0
- package/templates/node-compat/gitignore +2 -0
- package/templates/node-compat/package.json +11 -0
- package/templates/node-compat/sloppy.json +6 -0
- package/templates/node-compat/src/main.ts +40 -0
- package/templates/package-api/README.md +44 -0
- package/templates/package-api/fixtures/validator-lite/index.js +7 -0
- package/templates/package-api/fixtures/validator-lite/package.json +6 -0
- package/templates/package-api/gitignore +3 -0
- package/templates/package-api/package.json +17 -0
- package/templates/package-api/sloppy.json +5 -0
- package/templates/package-api/src/main.ts +10 -0
- package/templates/package-api/src/routes/health.ts +5 -0
- package/templates/package-api/src/routes/users.ts +12 -0
- package/templates/package-api/tsconfig.json +15 -0
- package/templates/program/README.md +12 -0
- package/templates/program/gitignore +1 -0
- package/templates/program/package.json +10 -0
- package/templates/program/sloppy.json +6 -0
- 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,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,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,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,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 @@
|
|
|
1
|
+
export const message = "hello from sloppy program mode";
|
|
@@ -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,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,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,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,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,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
|
+
}
|