@struktoai/mirage-browser 0.0.5 → 0.0.7-alpha.1
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/README.md +138 -80
- package/dist/accessor/opfs.d.ts +10 -0
- package/dist/accessor/opfs.d.ts.map +1 -0
- package/dist/accessor/opfs.js +25 -0
- package/dist/accessor/opfs.js.map +1 -0
- package/dist/commands/builtin/opfs/index.d.ts +3 -0
- package/dist/commands/builtin/opfs/index.d.ts.map +1 -0
- package/dist/commands/builtin/opfs/index.js +20 -0
- package/dist/commands/builtin/opfs/index.js.map +1 -0
- package/dist/commands/builtin/opfs/io.d.ts +4 -0
- package/dist/commands/builtin/opfs/io.d.ts.map +1 -0
- package/dist/commands/builtin/opfs/io.js +56 -0
- package/dist/commands/builtin/opfs/io.js.map +1 -0
- package/dist/core/opfs/append.d.ts +4 -0
- package/dist/core/opfs/append.d.ts.map +1 -0
- package/dist/core/opfs/append.js +38 -0
- package/dist/core/opfs/append.js.map +1 -0
- package/dist/core/opfs/constants.d.ts +3 -0
- package/dist/core/opfs/constants.d.ts.map +1 -0
- package/dist/core/opfs/constants.js +16 -0
- package/dist/core/opfs/constants.js.map +1 -0
- package/dist/core/opfs/copy.d.ts +4 -0
- package/dist/core/opfs/copy.d.ts.map +1 -0
- package/dist/core/opfs/copy.js +40 -0
- package/dist/core/opfs/copy.js.map +1 -0
- package/dist/core/opfs/create.d.ts +4 -0
- package/dist/core/opfs/create.d.ts.map +1 -0
- package/dist/core/opfs/create.js +18 -0
- package/dist/core/opfs/create.js.map +1 -0
- package/dist/core/opfs/du/entries.d.ts +4 -0
- package/dist/core/opfs/du/entries.d.ts.map +1 -0
- package/dist/core/opfs/du/entries.js +56 -0
- package/dist/core/opfs/du/entries.js.map +1 -0
- package/dist/core/opfs/du/index.d.ts +3 -0
- package/dist/core/opfs/du/index.d.ts.map +1 -0
- package/dist/core/opfs/du/index.js +16 -0
- package/dist/core/opfs/du/index.js.map +1 -0
- package/dist/core/opfs/du/size.d.ts +4 -0
- package/dist/core/opfs/du/size.d.ts.map +1 -0
- package/dist/core/opfs/du/size.js +18 -0
- package/dist/core/opfs/du/size.js.map +1 -0
- package/dist/core/opfs/du/walk.d.ts +3 -0
- package/dist/core/opfs/du/walk.d.ts.map +1 -0
- package/dist/core/opfs/du/walk.js +98 -0
- package/dist/core/opfs/du/walk.js.map +1 -0
- package/dist/core/opfs/entry.d.ts +11 -0
- package/dist/core/opfs/entry.d.ts.map +1 -0
- package/dist/core/opfs/entry.js +42 -0
- package/dist/core/opfs/entry.js.map +1 -0
- package/dist/core/opfs/exists.d.ts +4 -0
- package/dist/core/opfs/exists.d.ts.map +1 -0
- package/dist/core/opfs/exists.js +64 -0
- package/dist/core/opfs/exists.js.map +1 -0
- package/dist/core/opfs/find.d.ts +21 -0
- package/dist/core/opfs/find.d.ts.map +1 -0
- package/dist/core/opfs/find.js +154 -0
- package/dist/core/opfs/find.js.map +1 -0
- package/dist/core/opfs/mkdir.d.ts +4 -0
- package/dist/core/opfs/mkdir.d.ts.map +1 -0
- package/dist/core/opfs/mkdir.js +64 -0
- package/dist/core/opfs/mkdir.js.map +1 -0
- package/dist/core/opfs/read.d.ts +22 -0
- package/dist/core/opfs/read.d.ts.map +1 -0
- package/dist/core/opfs/read.js +57 -0
- package/dist/core/opfs/read.js.map +1 -0
- package/dist/core/opfs/readdir.d.ts +4 -0
- package/dist/core/opfs/readdir.d.ts.map +1 -0
- package/dist/core/opfs/readdir.js +50 -0
- package/dist/core/opfs/readdir.js.map +1 -0
- package/dist/core/opfs/rename.d.ts +4 -0
- package/dist/core/opfs/rename.d.ts.map +1 -0
- package/dist/core/opfs/rename.js +97 -0
- package/dist/core/opfs/rename.js.map +1 -0
- package/dist/core/opfs/rm.d.ts +4 -0
- package/dist/core/opfs/rm.d.ts.map +1 -0
- package/dist/core/opfs/rm.js +40 -0
- package/dist/core/opfs/rm.js.map +1 -0
- package/dist/core/opfs/rmdir.d.ts +4 -0
- package/dist/core/opfs/rmdir.d.ts.map +1 -0
- package/dist/core/opfs/rmdir.js +48 -0
- package/dist/core/opfs/rmdir.js.map +1 -0
- package/dist/core/opfs/stat.d.ts +5 -0
- package/dist/core/opfs/stat.d.ts.map +1 -0
- package/dist/core/opfs/stat.js +88 -0
- package/dist/core/opfs/stat.js.map +1 -0
- package/dist/core/opfs/stream.d.ts +4 -0
- package/dist/core/opfs/stream.d.ts.map +1 -0
- package/dist/core/opfs/stream.js +44 -0
- package/dist/core/opfs/stream.js.map +1 -0
- package/dist/core/opfs/truncate.d.ts +4 -0
- package/dist/core/opfs/truncate.d.ts.map +1 -0
- package/dist/core/opfs/truncate.js +49 -0
- package/dist/core/opfs/truncate.js.map +1 -0
- package/dist/core/opfs/unlink.d.ts +4 -0
- package/dist/core/opfs/unlink.d.ts.map +1 -0
- package/dist/core/opfs/unlink.js +40 -0
- package/dist/core/opfs/unlink.js.map +1 -0
- package/dist/core/opfs/utils.d.ts +20 -0
- package/dist/core/opfs/utils.d.ts.map +1 -0
- package/dist/core/opfs/utils.js +149 -0
- package/dist/core/opfs/utils.js.map +1 -0
- package/dist/core/opfs/write.d.ts +4 -0
- package/dist/core/opfs/write.d.ts.map +1 -0
- package/dist/core/opfs/write.js +33 -0
- package/dist/core/opfs/write.js.map +1 -0
- package/dist/generated/wasm.d.ts +3 -0
- package/dist/generated/wasm.d.ts.map +1 -0
- package/dist/generated/wasm.js +4 -0
- package/dist/generated/wasm.js.map +1 -0
- package/dist/index.d.ts +121 -1246
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +132 -698
- package/dist/index.js.map +1 -1
- package/dist/ops/opfs/index.d.ts +3 -0
- package/dist/ops/opfs/index.d.ts.map +1 -0
- package/dist/ops/opfs/index.js +23 -0
- package/dist/ops/opfs/index.js.map +1 -0
- package/dist/resource/aliyun/aliyun.d.ts +8 -0
- package/dist/resource/aliyun/aliyun.d.ts.map +1 -0
- package/dist/resource/aliyun/aliyun.js +24 -0
- package/dist/resource/aliyun/aliyun.js.map +1 -0
- package/dist/resource/aliyun/config.d.ts +17 -0
- package/dist/resource/aliyun/config.d.ts.map +1 -0
- package/dist/resource/aliyun/config.js +24 -0
- package/dist/resource/aliyun/config.js.map +1 -0
- package/dist/resource/aliyun/prompt.d.ts +2 -0
- package/dist/resource/aliyun/prompt.d.ts.map +1 -0
- package/dist/resource/aliyun/prompt.js +19 -0
- package/dist/resource/aliyun/prompt.js.map +1 -0
- package/dist/resource/backblaze/backblaze.d.ts +8 -0
- package/dist/resource/backblaze/backblaze.d.ts.map +1 -0
- package/dist/resource/backblaze/backblaze.js +24 -0
- package/dist/resource/backblaze/backblaze.js.map +1 -0
- package/dist/resource/backblaze/config.d.ts +17 -0
- package/dist/resource/backblaze/config.d.ts.map +1 -0
- package/dist/resource/backblaze/config.js +24 -0
- package/dist/resource/backblaze/config.js.map +1 -0
- package/dist/resource/backblaze/prompt.d.ts +2 -0
- package/dist/resource/backblaze/prompt.d.ts.map +1 -0
- package/dist/resource/backblaze/prompt.js +19 -0
- package/dist/resource/backblaze/prompt.js.map +1 -0
- package/dist/resource/box/box.d.ts +34 -0
- package/dist/resource/box/box.d.ts.map +1 -0
- package/dist/resource/box/box.js +99 -0
- package/dist/resource/box/box.js.map +1 -0
- package/dist/resource/box/config.d.ts +41 -0
- package/dist/resource/box/config.d.ts.map +1 -0
- package/dist/resource/box/config.js +38 -0
- package/dist/resource/box/config.js.map +1 -0
- package/dist/resource/ceph/ceph.d.ts +8 -0
- package/dist/resource/ceph/ceph.d.ts.map +1 -0
- package/dist/resource/ceph/ceph.js +24 -0
- package/dist/resource/ceph/ceph.js.map +1 -0
- package/dist/resource/ceph/config.d.ts +16 -0
- package/dist/resource/ceph/config.d.ts.map +1 -0
- package/dist/resource/ceph/config.js +22 -0
- package/dist/resource/ceph/config.js.map +1 -0
- package/dist/resource/ceph/prompt.d.ts +2 -0
- package/dist/resource/ceph/prompt.d.ts.map +1 -0
- package/dist/resource/ceph/prompt.js +19 -0
- package/dist/resource/ceph/prompt.js.map +1 -0
- package/dist/resource/digitalocean/config.d.ts +17 -0
- package/dist/resource/digitalocean/config.d.ts.map +1 -0
- package/dist/resource/digitalocean/config.js +24 -0
- package/dist/resource/digitalocean/config.js.map +1 -0
- package/dist/resource/digitalocean/digitalocean.d.ts +8 -0
- package/dist/resource/digitalocean/digitalocean.d.ts.map +1 -0
- package/dist/resource/digitalocean/digitalocean.js +24 -0
- package/dist/resource/digitalocean/digitalocean.js.map +1 -0
- package/dist/resource/digitalocean/prompt.d.ts +2 -0
- package/dist/resource/digitalocean/prompt.d.ts.map +1 -0
- package/dist/resource/digitalocean/prompt.js +19 -0
- package/dist/resource/digitalocean/prompt.js.map +1 -0
- package/dist/resource/discord/config.d.ts +20 -0
- package/dist/resource/discord/config.d.ts.map +1 -0
- package/dist/resource/discord/config.js +32 -0
- package/dist/resource/discord/config.js.map +1 -0
- package/dist/resource/discord/discord.d.ts +33 -0
- package/dist/resource/discord/discord.d.ts.map +1 -0
- package/dist/resource/discord/discord.js +90 -0
- package/dist/resource/discord/discord.js.map +1 -0
- package/dist/resource/dropbox/config.d.ts +34 -0
- package/dist/resource/dropbox/config.d.ts.map +1 -0
- package/dist/resource/dropbox/config.js +31 -0
- package/dist/resource/dropbox/config.js.map +1 -0
- package/dist/resource/dropbox/dropbox.d.ts +34 -0
- package/dist/resource/dropbox/dropbox.d.ts.map +1 -0
- package/dist/resource/dropbox/dropbox.js +95 -0
- package/dist/resource/dropbox/dropbox.js.map +1 -0
- package/dist/resource/gcal/gcal.d.ts +32 -0
- package/dist/resource/gcal/gcal.d.ts.map +1 -0
- package/dist/resource/gcal/gcal.js +87 -0
- package/dist/resource/gcal/gcal.js.map +1 -0
- package/dist/resource/gcs/config.d.ts +16 -0
- package/dist/resource/gcs/config.d.ts.map +1 -0
- package/dist/resource/gcs/config.js +24 -0
- package/dist/resource/gcs/config.js.map +1 -0
- package/dist/resource/gcs/gcs.d.ts +8 -0
- package/dist/resource/gcs/gcs.d.ts.map +1 -0
- package/dist/resource/gcs/gcs.js +24 -0
- package/dist/resource/gcs/gcs.js.map +1 -0
- package/dist/resource/gcs/prompt.d.ts +2 -0
- package/dist/resource/gcs/prompt.d.ts.map +1 -0
- package/dist/resource/gcs/prompt.js +19 -0
- package/dist/resource/gcs/prompt.js.map +1 -0
- package/dist/resource/gdocs/gdocs.d.ts +32 -0
- package/dist/resource/gdocs/gdocs.d.ts.map +1 -0
- package/dist/resource/gdocs/gdocs.js +84 -0
- package/dist/resource/gdocs/gdocs.js.map +1 -0
- package/dist/resource/gdrive/gdrive.d.ts +34 -0
- package/dist/resource/gdrive/gdrive.d.ts.map +1 -0
- package/dist/resource/gdrive/gdrive.js +89 -0
- package/dist/resource/gdrive/gdrive.js.map +1 -0
- package/dist/resource/github/github.d.ts +38 -0
- package/dist/resource/github/github.d.ts.map +1 -0
- package/dist/resource/github/github.js +121 -0
- package/dist/resource/github/github.js.map +1 -0
- package/dist/resource/gmail/gmail.d.ts +33 -0
- package/dist/resource/gmail/gmail.d.ts.map +1 -0
- package/dist/resource/gmail/gmail.js +88 -0
- package/dist/resource/gmail/gmail.js.map +1 -0
- package/dist/resource/gsheets/gsheets.d.ts +32 -0
- package/dist/resource/gsheets/gsheets.d.ts.map +1 -0
- package/dist/resource/gsheets/gsheets.js +84 -0
- package/dist/resource/gsheets/gsheets.js.map +1 -0
- package/dist/resource/gslides/gslides.d.ts +32 -0
- package/dist/resource/gslides/gslides.d.ts.map +1 -0
- package/dist/resource/gslides/gslides.js +84 -0
- package/dist/resource/gslides/gslides.js.map +1 -0
- package/dist/resource/langfuse/config.d.ts +23 -0
- package/dist/resource/langfuse/config.d.ts.map +1 -0
- package/dist/resource/langfuse/config.js +36 -0
- package/dist/resource/langfuse/config.js.map +1 -0
- package/dist/resource/langfuse/langfuse.d.ts +31 -0
- package/dist/resource/langfuse/langfuse.d.ts.map +1 -0
- package/dist/resource/langfuse/langfuse.js +98 -0
- package/dist/resource/langfuse/langfuse.js.map +1 -0
- package/dist/resource/linear/linear.d.ts +33 -0
- package/dist/resource/linear/linear.d.ts.map +1 -0
- package/dist/resource/linear/linear.js +93 -0
- package/dist/resource/linear/linear.js.map +1 -0
- package/dist/resource/minio/config.d.ts +16 -0
- package/dist/resource/minio/config.d.ts.map +1 -0
- package/dist/resource/minio/config.js +22 -0
- package/dist/resource/minio/config.js.map +1 -0
- package/dist/resource/minio/minio.d.ts +8 -0
- package/dist/resource/minio/minio.d.ts.map +1 -0
- package/dist/resource/minio/minio.js +24 -0
- package/dist/resource/minio/minio.js.map +1 -0
- package/dist/resource/minio/prompt.d.ts +2 -0
- package/dist/resource/minio/prompt.d.ts.map +1 -0
- package/dist/resource/minio/prompt.js +19 -0
- package/dist/resource/minio/prompt.js.map +1 -0
- package/dist/resource/mongodb/http_driver.d.ts +27 -0
- package/dist/resource/mongodb/http_driver.d.ts.map +1 -0
- package/dist/resource/mongodb/http_driver.js +96 -0
- package/dist/resource/mongodb/http_driver.js.map +1 -0
- package/dist/resource/mongodb/mongodb.d.ts +41 -0
- package/dist/resource/mongodb/mongodb.d.ts.map +1 -0
- package/dist/resource/mongodb/mongodb.js +100 -0
- package/dist/resource/mongodb/mongodb.js.map +1 -0
- package/dist/resource/notion/config.d.ts +20 -0
- package/dist/resource/notion/config.d.ts.map +1 -0
- package/dist/resource/notion/config.js +32 -0
- package/dist/resource/notion/config.js.map +1 -0
- package/dist/resource/notion/notion.d.ts +32 -0
- package/dist/resource/notion/notion.d.ts.map +1 -0
- package/dist/resource/notion/notion.js +86 -0
- package/dist/resource/notion/notion.js.map +1 -0
- package/dist/resource/oci/config.d.ts +20 -0
- package/dist/resource/oci/config.d.ts.map +1 -0
- package/dist/resource/oci/config.js +30 -0
- package/dist/resource/oci/config.js.map +1 -0
- package/dist/resource/oci/oci.d.ts +8 -0
- package/dist/resource/oci/oci.d.ts.map +1 -0
- package/dist/resource/oci/oci.js +24 -0
- package/dist/resource/oci/oci.js.map +1 -0
- package/dist/resource/oci/prompt.d.ts +2 -0
- package/dist/resource/oci/prompt.d.ts.map +1 -0
- package/dist/resource/oci/prompt.js +19 -0
- package/dist/resource/oci/prompt.js.map +1 -0
- package/dist/resource/opfs/opfs.d.ts +57 -0
- package/dist/resource/opfs/opfs.d.ts.map +1 -0
- package/dist/resource/opfs/opfs.js +236 -0
- package/dist/resource/opfs/opfs.js.map +1 -0
- package/dist/resource/opfs/prompt.d.ts +2 -0
- package/dist/resource/opfs/prompt.d.ts.map +1 -0
- package/dist/resource/opfs/prompt.js +17 -0
- package/dist/resource/opfs/prompt.js.map +1 -0
- package/dist/resource/postgres/neon_driver.d.ts +8 -0
- package/dist/resource/postgres/neon_driver.d.ts.map +1 -0
- package/dist/resource/postgres/neon_driver.js +28 -0
- package/dist/resource/postgres/neon_driver.js.map +1 -0
- package/dist/resource/postgres/postgres.d.ts +40 -0
- package/dist/resource/postgres/postgres.d.ts.map +1 -0
- package/dist/resource/postgres/postgres.js +98 -0
- package/dist/resource/postgres/postgres.js.map +1 -0
- package/dist/resource/qingstor/config.d.ts +17 -0
- package/dist/resource/qingstor/config.d.ts.map +1 -0
- package/dist/resource/qingstor/config.js +24 -0
- package/dist/resource/qingstor/config.js.map +1 -0
- package/dist/resource/qingstor/prompt.d.ts +2 -0
- package/dist/resource/qingstor/prompt.d.ts.map +1 -0
- package/dist/resource/qingstor/prompt.js +19 -0
- package/dist/resource/qingstor/prompt.js.map +1 -0
- package/dist/resource/qingstor/qingstor.d.ts +8 -0
- package/dist/resource/qingstor/qingstor.d.ts.map +1 -0
- package/dist/resource/qingstor/qingstor.js +24 -0
- package/dist/resource/qingstor/qingstor.js.map +1 -0
- package/dist/resource/r2/config.d.ts +20 -0
- package/dist/resource/r2/config.d.ts.map +1 -0
- package/dist/resource/r2/config.js +26 -0
- package/dist/resource/r2/config.js.map +1 -0
- package/dist/resource/r2/prompt.d.ts +2 -0
- package/dist/resource/r2/prompt.d.ts.map +1 -0
- package/dist/resource/r2/prompt.js +19 -0
- package/dist/resource/r2/prompt.js.map +1 -0
- package/dist/resource/r2/r2.d.ts +8 -0
- package/dist/resource/r2/r2.d.ts.map +1 -0
- package/dist/resource/r2/r2.js +24 -0
- package/dist/resource/r2/r2.js.map +1 -0
- package/dist/resource/redis/redis.d.ts +17 -0
- package/dist/resource/redis/redis.d.ts.map +1 -0
- package/dist/resource/redis/redis.js +29 -0
- package/dist/resource/redis/redis.js.map +1 -0
- package/dist/resource/redis/store.d.ts +75 -0
- package/dist/resource/redis/store.d.ts.map +1 -0
- package/dist/resource/redis/store.js +381 -0
- package/dist/resource/redis/store.js.map +1 -0
- package/dist/resource/registry.d.ts +25 -0
- package/dist/resource/registry.d.ts.map +1 -0
- package/dist/resource/registry.js +279 -0
- package/dist/resource/registry.js.map +1 -0
- package/dist/resource/s3/config.d.ts +7 -0
- package/dist/resource/s3/config.d.ts.map +1 -0
- package/dist/resource/s3/config.js +26 -0
- package/dist/resource/s3/config.js.map +1 -0
- package/dist/resource/s3/s3.d.ts +53 -0
- package/dist/resource/s3/s3.d.ts.map +1 -0
- package/dist/resource/s3/s3.js +182 -0
- package/dist/resource/s3/s3.js.map +1 -0
- package/dist/resource/s3_alias.d.ts +113 -0
- package/dist/resource/s3_alias.d.ts.map +1 -0
- package/dist/resource/s3_alias.js +133 -0
- package/dist/resource/s3_alias.js.map +1 -0
- package/dist/resource/scaleway/config.d.ts +17 -0
- package/dist/resource/scaleway/config.d.ts.map +1 -0
- package/dist/resource/scaleway/config.js +24 -0
- package/dist/resource/scaleway/config.js.map +1 -0
- package/dist/resource/scaleway/prompt.d.ts +2 -0
- package/dist/resource/scaleway/prompt.d.ts.map +1 -0
- package/dist/resource/scaleway/prompt.js +19 -0
- package/dist/resource/scaleway/prompt.js.map +1 -0
- package/dist/resource/scaleway/scaleway.d.ts +8 -0
- package/dist/resource/scaleway/scaleway.d.ts.map +1 -0
- package/dist/resource/scaleway/scaleway.js +24 -0
- package/dist/resource/scaleway/scaleway.js.map +1 -0
- package/dist/resource/seaweedfs/config.d.ts +16 -0
- package/dist/resource/seaweedfs/config.d.ts.map +1 -0
- package/dist/resource/seaweedfs/config.js +22 -0
- package/dist/resource/seaweedfs/config.js.map +1 -0
- package/dist/resource/seaweedfs/prompt.d.ts +2 -0
- package/dist/resource/seaweedfs/prompt.d.ts.map +1 -0
- package/dist/resource/seaweedfs/prompt.js +19 -0
- package/dist/resource/seaweedfs/prompt.js.map +1 -0
- package/dist/resource/seaweedfs/seaweedfs.d.ts +8 -0
- package/dist/resource/seaweedfs/seaweedfs.d.ts.map +1 -0
- package/dist/resource/seaweedfs/seaweedfs.js +24 -0
- package/dist/resource/seaweedfs/seaweedfs.js.map +1 -0
- package/dist/resource/slack/config.d.ts +20 -0
- package/dist/resource/slack/config.d.ts.map +1 -0
- package/dist/resource/slack/config.js +32 -0
- package/dist/resource/slack/config.js.map +1 -0
- package/dist/resource/slack/slack.d.ts +33 -0
- package/dist/resource/slack/slack.d.ts.map +1 -0
- package/dist/resource/slack/slack.js +91 -0
- package/dist/resource/slack/slack.js.map +1 -0
- package/dist/resource/supabase/config.d.ts +20 -0
- package/dist/resource/supabase/config.d.ts.map +1 -0
- package/dist/resource/supabase/config.js +26 -0
- package/dist/resource/supabase/config.js.map +1 -0
- package/dist/resource/supabase/prompt.d.ts +2 -0
- package/dist/resource/supabase/prompt.d.ts.map +1 -0
- package/dist/resource/supabase/prompt.js +19 -0
- package/dist/resource/supabase/prompt.js.map +1 -0
- package/dist/resource/supabase/supabase.d.ts +8 -0
- package/dist/resource/supabase/supabase.d.ts.map +1 -0
- package/dist/resource/supabase/supabase.js +24 -0
- package/dist/resource/supabase/supabase.js.map +1 -0
- package/dist/resource/tencent/config.d.ts +17 -0
- package/dist/resource/tencent/config.d.ts.map +1 -0
- package/dist/resource/tencent/config.js +24 -0
- package/dist/resource/tencent/config.js.map +1 -0
- package/dist/resource/tencent/prompt.d.ts +2 -0
- package/dist/resource/tencent/prompt.d.ts.map +1 -0
- package/dist/resource/tencent/prompt.js +19 -0
- package/dist/resource/tencent/prompt.js.map +1 -0
- package/dist/resource/tencent/tencent.d.ts +8 -0
- package/dist/resource/tencent/tencent.d.ts.map +1 -0
- package/dist/resource/tencent/tencent.js +24 -0
- package/dist/resource/tencent/tencent.js.map +1 -0
- package/dist/resource/trello/config.d.ts +22 -0
- package/dist/resource/trello/config.d.ts.map +1 -0
- package/dist/resource/trello/config.js +35 -0
- package/dist/resource/trello/config.js.map +1 -0
- package/dist/resource/trello/trello.d.ts +32 -0
- package/dist/resource/trello/trello.d.ts.map +1 -0
- package/dist/resource/trello/trello.js +94 -0
- package/dist/resource/trello/trello.js.map +1 -0
- package/dist/resource/wasabi/config.d.ts +17 -0
- package/dist/resource/wasabi/config.d.ts.map +1 -0
- package/dist/resource/wasabi/config.js +29 -0
- package/dist/resource/wasabi/config.js.map +1 -0
- package/dist/resource/wasabi/prompt.d.ts +2 -0
- package/dist/resource/wasabi/prompt.d.ts.map +1 -0
- package/dist/resource/wasabi/prompt.js +19 -0
- package/dist/resource/wasabi/prompt.js.map +1 -0
- package/dist/resource/wasabi/wasabi.d.ts +8 -0
- package/dist/resource/wasabi/wasabi.d.ts.map +1 -0
- package/dist/resource/wasabi/wasabi.js +24 -0
- package/dist/resource/wasabi/wasabi.js.map +1 -0
- package/dist/runtime/sandbox/e2b/config.d.ts +2 -0
- package/dist/runtime/sandbox/e2b/config.d.ts.map +1 -0
- package/dist/runtime/sandbox/e2b/config.js +15 -0
- package/dist/runtime/sandbox/e2b/config.js.map +1 -0
- package/dist/runtime/sandbox/e2b/runtime.d.ts +2 -0
- package/dist/runtime/sandbox/e2b/runtime.d.ts.map +1 -0
- package/dist/runtime/sandbox/e2b/runtime.js +15 -0
- package/dist/runtime/sandbox/e2b/runtime.js.map +1 -0
- package/dist/test-utils.d.ts +37 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +518 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/workspace.d.ts +10 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +62 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +22 -6
- package/dist/aliyun-DR6KT3H6.js +0 -8
- package/dist/aliyun-DR6KT3H6.js.map +0 -1
- package/dist/backblaze-XCLZXTES.js +0 -8
- package/dist/backblaze-XCLZXTES.js.map +0 -1
- package/dist/box-XBCSU3AA.js +0 -8
- package/dist/box-XBCSU3AA.js.map +0 -1
- package/dist/ceph-F5S2NMTO.js +0 -8
- package/dist/ceph-F5S2NMTO.js.map +0 -1
- package/dist/chunk-2J35WXX5.js +0 -28
- package/dist/chunk-2J35WXX5.js.map +0 -1
- package/dist/chunk-2WNXK742.js +0 -89
- package/dist/chunk-2WNXK742.js.map +0 -1
- package/dist/chunk-2WSKXBSV.js +0 -139
- package/dist/chunk-2WSKXBSV.js.map +0 -1
- package/dist/chunk-37WKCB2E.js +0 -95
- package/dist/chunk-37WKCB2E.js.map +0 -1
- package/dist/chunk-3IYCVC7W.js +0 -96
- package/dist/chunk-3IYCVC7W.js.map +0 -1
- package/dist/chunk-46HNNKFR.js +0 -95
- package/dist/chunk-46HNNKFR.js.map +0 -1
- package/dist/chunk-4IF4TGAI.js +0 -11
- package/dist/chunk-4IF4TGAI.js.map +0 -1
- package/dist/chunk-5OZJMTYW.js +0 -113
- package/dist/chunk-5OZJMTYW.js.map +0 -1
- package/dist/chunk-5UM6EBVW.js +0 -108
- package/dist/chunk-5UM6EBVW.js.map +0 -1
- package/dist/chunk-6HRSCX2U.js +0 -98
- package/dist/chunk-6HRSCX2U.js.map +0 -1
- package/dist/chunk-7HWQAYXR.js +0 -85
- package/dist/chunk-7HWQAYXR.js.map +0 -1
- package/dist/chunk-AUZNQ7EI.js +0 -85
- package/dist/chunk-AUZNQ7EI.js.map +0 -1
- package/dist/chunk-BGA2F226.js +0 -182
- package/dist/chunk-BGA2F226.js.map +0 -1
- package/dist/chunk-BV372CUO.js +0 -90
- package/dist/chunk-BV372CUO.js.map +0 -1
- package/dist/chunk-C4THTILY.js +0 -95
- package/dist/chunk-C4THTILY.js.map +0 -1
- package/dist/chunk-D4MEOKNQ.js +0 -95
- package/dist/chunk-D4MEOKNQ.js.map +0 -1
- package/dist/chunk-D4RAMWYH.js +0 -88
- package/dist/chunk-D4RAMWYH.js.map +0 -1
- package/dist/chunk-EHIT6WCY.js +0 -95
- package/dist/chunk-EHIT6WCY.js.map +0 -1
- package/dist/chunk-EN6TZYT2.js +0 -95
- package/dist/chunk-EN6TZYT2.js.map +0 -1
- package/dist/chunk-FTDVV7EQ.js +0 -85
- package/dist/chunk-FTDVV7EQ.js.map +0 -1
- package/dist/chunk-G67Q2Z6I.js +0 -95
- package/dist/chunk-G67Q2Z6I.js.map +0 -1
- package/dist/chunk-GM2QMJAY.js +0 -85
- package/dist/chunk-GM2QMJAY.js.map +0 -1
- package/dist/chunk-HRWLHJX2.js +0 -84
- package/dist/chunk-HRWLHJX2.js.map +0 -1
- package/dist/chunk-INEXV2PN.js +0 -91
- package/dist/chunk-INEXV2PN.js.map +0 -1
- package/dist/chunk-IZMKMD3O.js +0 -11
- package/dist/chunk-IZMKMD3O.js.map +0 -1
- package/dist/chunk-JUVMJ5GI.js +0 -85
- package/dist/chunk-JUVMJ5GI.js.map +0 -1
- package/dist/chunk-KL2VFYUV.js +0 -159
- package/dist/chunk-KL2VFYUV.js.map +0 -1
- package/dist/chunk-L64GRKOD.js +0 -38
- package/dist/chunk-L64GRKOD.js.map +0 -1
- package/dist/chunk-LPDLPRPS.js +0 -11
- package/dist/chunk-LPDLPRPS.js.map +0 -1
- package/dist/chunk-M2UF2JHJ.js +0 -11
- package/dist/chunk-M2UF2JHJ.js.map +0 -1
- package/dist/chunk-NVHPJ5CV.js +0 -109
- package/dist/chunk-NVHPJ5CV.js.map +0 -1
- package/dist/chunk-OSTDTTWI.js +0 -35
- package/dist/chunk-OSTDTTWI.js.map +0 -1
- package/dist/chunk-PQCRGTSA.js +0 -85
- package/dist/chunk-PQCRGTSA.js.map +0 -1
- package/dist/chunk-QE7QNA45.js +0 -114
- package/dist/chunk-QE7QNA45.js.map +0 -1
- package/dist/chunk-QG2NUNCY.js +0 -95
- package/dist/chunk-QG2NUNCY.js.map +0 -1
- package/dist/chunk-UFHBDBZD.js +0 -1212
- package/dist/chunk-UFHBDBZD.js.map +0 -1
- package/dist/chunk-UY22T4AC.js +0 -112
- package/dist/chunk-UY22T4AC.js.map +0 -1
- package/dist/chunk-XJBC3OYX.js +0 -11
- package/dist/chunk-XJBC3OYX.js.map +0 -1
- package/dist/chunk-Y6DYUK6J.js +0 -85
- package/dist/chunk-Y6DYUK6J.js.map +0 -1
- package/dist/chunk-YOCTIHQZ.js +0 -89
- package/dist/chunk-YOCTIHQZ.js.map +0 -1
- package/dist/chunk-ZDJPUXYH.js +0 -101
- package/dist/chunk-ZDJPUXYH.js.map +0 -1
- package/dist/chunk-ZKCOSE3R.js +0 -90
- package/dist/chunk-ZKCOSE3R.js.map +0 -1
- package/dist/chunk-ZTHVEXIV.js +0 -11
- package/dist/chunk-ZTHVEXIV.js.map +0 -1
- package/dist/config-2Y6LZKLV.js +0 -9
- package/dist/config-2Y6LZKLV.js.map +0 -1
- package/dist/config-4GSOMUMF.js +0 -9
- package/dist/config-4GSOMUMF.js.map +0 -1
- package/dist/config-5YBUWFUP.js +0 -9
- package/dist/config-5YBUWFUP.js.map +0 -1
- package/dist/config-DE5OZ4I7.js +0 -9
- package/dist/config-DE5OZ4I7.js.map +0 -1
- package/dist/config-ELDOFRJW.js +0 -9
- package/dist/config-ELDOFRJW.js.map +0 -1
- package/dist/config-FPM3LAW7.js +0 -9
- package/dist/config-FPM3LAW7.js.map +0 -1
- package/dist/config-JY557MA6.js +0 -9
- package/dist/config-JY557MA6.js.map +0 -1
- package/dist/config-UU27ALAA.js +0 -9
- package/dist/config-UU27ALAA.js.map +0 -1
- package/dist/config-WRACCRPN.js +0 -9
- package/dist/config-WRACCRPN.js.map +0 -1
- package/dist/digitalocean-QDHTRS2W.js +0 -8
- package/dist/digitalocean-QDHTRS2W.js.map +0 -1
- package/dist/discord-ERUI7OAQ.js +0 -7
- package/dist/discord-ERUI7OAQ.js.map +0 -1
- package/dist/dropbox-3U6D4HLE.js +0 -8
- package/dist/dropbox-3U6D4HLE.js.map +0 -1
- package/dist/gcal-MTBSDG34.js +0 -8
- package/dist/gcal-MTBSDG34.js.map +0 -1
- package/dist/gcs-KNGRBBET.js +0 -8
- package/dist/gcs-KNGRBBET.js.map +0 -1
- package/dist/gdocs-RUIOIRKP.js +0 -8
- package/dist/gdocs-RUIOIRKP.js.map +0 -1
- package/dist/gdrive-5JB7ZKEP.js +0 -8
- package/dist/gdrive-5JB7ZKEP.js.map +0 -1
- package/dist/github-CIXBFBVO.js +0 -7
- package/dist/github-CIXBFBVO.js.map +0 -1
- package/dist/github_ci-HR6YOYAO.js +0 -8
- package/dist/github_ci-HR6YOYAO.js.map +0 -1
- package/dist/gmail-JHGWTQU5.js +0 -8
- package/dist/gmail-JHGWTQU5.js.map +0 -1
- package/dist/gsheets-N54JO2RS.js +0 -8
- package/dist/gsheets-N54JO2RS.js.map +0 -1
- package/dist/gslides-B4VMNLMB.js +0 -8
- package/dist/gslides-B4VMNLMB.js.map +0 -1
- package/dist/langfuse-HEUJGDOC.js +0 -7
- package/dist/langfuse-HEUJGDOC.js.map +0 -1
- package/dist/linear-J4QQ3CA6.js +0 -7
- package/dist/linear-J4QQ3CA6.js.map +0 -1
- package/dist/minio-BXWHJ6K5.js +0 -8
- package/dist/minio-BXWHJ6K5.js.map +0 -1
- package/dist/mongodb-YZP643ZU.js +0 -7
- package/dist/mongodb-YZP643ZU.js.map +0 -1
- package/dist/notion-I5S5SRLO.js +0 -7
- package/dist/notion-I5S5SRLO.js.map +0 -1
- package/dist/oci-XOPKH4AE.js +0 -8
- package/dist/oci-XOPKH4AE.js.map +0 -1
- package/dist/opfs-36QO72Y5.js +0 -7
- package/dist/opfs-36QO72Y5.js.map +0 -1
- package/dist/postgres-HPOMN2AR.js +0 -7
- package/dist/postgres-HPOMN2AR.js.map +0 -1
- package/dist/qingstor-JKAHLK62.js +0 -8
- package/dist/qingstor-JKAHLK62.js.map +0 -1
- package/dist/r2-L3QXQ76M.js +0 -8
- package/dist/r2-L3QXQ76M.js.map +0 -1
- package/dist/s3-LRZJPGHK.js +0 -9
- package/dist/s3-LRZJPGHK.js.map +0 -1
- package/dist/scaleway-CGNDYNKS.js +0 -8
- package/dist/scaleway-CGNDYNKS.js.map +0 -1
- package/dist/seaweedfs-BSQWCBIR.js +0 -8
- package/dist/seaweedfs-BSQWCBIR.js.map +0 -1
- package/dist/slack-62ECSENR.js +0 -7
- package/dist/slack-62ECSENR.js.map +0 -1
- package/dist/supabase-J66NXWAF.js +0 -8
- package/dist/supabase-J66NXWAF.js.map +0 -1
- package/dist/tencent-AC667LV3.js +0 -8
- package/dist/tencent-AC667LV3.js.map +0 -1
- package/dist/trello-SUPG6VDF.js +0 -7
- package/dist/trello-SUPG6VDF.js.map +0 -1
- package/dist/wasabi-5KKPW6LH.js +0 -8
- package/dist/wasabi-5KKPW6LH.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/resource/r2/config.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,CAAC,EAAE,MAAM,yCAAyC,CAAA;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAA;AAGvF,QAAA,MAAM,cAAc;;;;;;;;;iBAA2D,CAAA;AAE/E,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,cAAc,CAAC,CAAA;AAEtD,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAA;AAW/E,eAAO,MAAM,kBAAkB,0CAAyB,CAAA;AACxD,eAAO,MAAM,YAAY,oFAAmB,CAAA;AAC5C,eAAO,MAAM,cAAc,wCAAe,CAAA;AAC1C,eAAO,MAAM,iBAAiB,8CAAkB,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
14
|
+
import { z } from '@struktoai/mirage-core/resource/secrets';
|
|
15
|
+
import { browserAliasSchema, derivedEndpoint, makeBrowserS3Alias } from "../s3_alias.js";
|
|
16
|
+
const R2ConfigSchema = browserAliasSchema({ accountId: z.string().optional() });
|
|
17
|
+
const alias = makeBrowserS3Alias({
|
|
18
|
+
schema: R2ConfigSchema,
|
|
19
|
+
endpointFor: derivedEndpoint('accountId', (accountId) => `https://${accountId}.r2.cloudflarestorage.com`),
|
|
20
|
+
regionDefault: 'auto',
|
|
21
|
+
});
|
|
22
|
+
export const resolvedR2Endpoint = alias.resolvedEndpoint;
|
|
23
|
+
export const r2ToS3Config = alias.toS3Config;
|
|
24
|
+
export const redactR2Config = alias.redact;
|
|
25
|
+
export const normalizeR2Config = alias.normalize;
|
|
26
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/resource/r2/config.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAEvE,OAAO,EAAE,CAAC,EAAE,MAAM,yCAAyC,CAAA;AAE3D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExF,MAAM,cAAc,GAAG,kBAAkB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;AAM/E,MAAM,KAAK,GAAG,kBAAkB,CAA6B;IAC3D,MAAM,EAAE,cAAc;IACtB,WAAW,EAAE,eAAe,CAC1B,WAAW,EACX,CAAC,SAAS,EAAE,EAAE,CAAC,WAAW,SAAS,2BAA2B,CAC/D;IACD,aAAa,EAAE,MAAM;CACtB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,gBAAgB,CAAA;AACxD,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,CAAA;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAA;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,SAAS,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const R2_BROWSER_PROMPT = "{prefix}\n Remote Cloudflare R2 bucket accessed via presigned URLs (browser runtime).\n Supports the full filesystem command set: ls/tree/cat/grep/find/du/cp/mv/rm/etc.\n Listing operations require the presigner to sign LIST/COPY operations in\n addition to GET/PUT/HEAD/DELETE \u2014 see S3BrowserPresignedUrlProvider docs.";
|
|
2
|
+
//# sourceMappingURL=prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/resource/r2/prompt.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB,6UAI8C,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
14
|
+
export const R2_BROWSER_PROMPT = `{prefix}
|
|
15
|
+
Remote Cloudflare R2 bucket accessed via presigned URLs (browser runtime).
|
|
16
|
+
Supports the full filesystem command set: ls/tree/cat/grep/find/du/cp/mv/rm/etc.
|
|
17
|
+
Listing operations require the presigner to sign LIST/COPY operations in
|
|
18
|
+
addition to GET/PUT/HEAD/DELETE — see S3BrowserPresignedUrlProvider docs.`;
|
|
19
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/resource/r2/prompt.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAEvE,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;4EAI2C,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { S3AliasResource, type S3AliasResourceState } from '../s3_alias.ts';
|
|
2
|
+
import { type R2Config, type R2ConfigRedacted } from './config.ts';
|
|
3
|
+
export type R2ResourceState = S3AliasResourceState<R2ConfigRedacted>;
|
|
4
|
+
export declare class R2Resource extends S3AliasResource<R2Config, R2ConfigRedacted> {
|
|
5
|
+
readonly prompt: string;
|
|
6
|
+
constructor(config: R2Config);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=r2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../../../src/resource/r2/r2.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC3E,OAAO,EAAgC,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGhG,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC,gBAAgB,CAAC,CAAA;AAEpE,qBAAa,UAAW,SAAQ,eAAe,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACzE,SAAkB,MAAM,EAAE,MAAM,CAAoB;gBAExC,MAAM,EAAE,QAAQ;CAG7B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
14
|
+
import { ResourceName } from '@struktoai/mirage-core/types';
|
|
15
|
+
import { S3AliasResource } from "../s3_alias.js";
|
|
16
|
+
import { r2ToS3Config, redactR2Config } from "./config.js";
|
|
17
|
+
import { R2_BROWSER_PROMPT } from "./prompt.js";
|
|
18
|
+
export class R2Resource extends S3AliasResource {
|
|
19
|
+
prompt = R2_BROWSER_PROMPT;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
super(ResourceName.R2, config, r2ToS3Config(config), redactR2Config);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=r2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../../../src/resource/r2/r2.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAC3D,OAAO,EAAE,eAAe,EAA6B,MAAM,gBAAgB,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,cAAc,EAAwC,MAAM,aAAa,CAAA;AAChG,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAI/C,MAAM,OAAO,UAAW,SAAQ,eAA2C;IACvD,MAAM,GAAW,iBAAiB,CAAA;IAEpD,YAAY,MAAgB;QAC1B,KAAK,CAAC,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC,CAAA;IACtE,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RedisResourceBase } from '@struktoai/mirage-core/resource/redis/redis';
|
|
2
|
+
import { UpstashRedisStore, type UpstashRedisStoreOptions } from './store.ts';
|
|
3
|
+
export type { RedisResourceState } from '@struktoai/mirage-core/resource/redis/redis';
|
|
4
|
+
export type RedisResourceOptions = UpstashRedisStoreOptions;
|
|
5
|
+
/**
|
|
6
|
+
* The browser redis mount: the shared resource over Upstash's REST api.
|
|
7
|
+
*
|
|
8
|
+
* A page cannot open a socket, so the store speaks HTTP to Upstash, or to
|
|
9
|
+
* serverless-redis-http in front of any redis. It takes the redis url the
|
|
10
|
+
* node and python mounts take, and the keyspace is the one they use, so one
|
|
11
|
+
* configuration and one database serve all three.
|
|
12
|
+
*/
|
|
13
|
+
export declare class RedisResource extends RedisResourceBase {
|
|
14
|
+
readonly store: UpstashRedisStore;
|
|
15
|
+
constructor(options: RedisResourceOptions);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=redis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../src/resource/redis/redis.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AAC/E,OAAO,EAAE,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAE7E,YAAY,EAAE,kBAAkB,EAAE,MAAM,6CAA6C,CAAA;AAErF,MAAM,MAAM,oBAAoB,GAAG,wBAAwB,CAAA;AAE3D;;;;;;;GAOG;AACH,qBAAa,aAAc,SAAQ,iBAAiB;IAClD,SAAiB,KAAK,EAAE,iBAAiB,CAAA;gBAE7B,OAAO,EAAE,oBAAoB;CAG1C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
14
|
+
import { RedisResourceBase } from '@struktoai/mirage-core/resource/redis/redis';
|
|
15
|
+
import { UpstashRedisStore } from "./store.js";
|
|
16
|
+
/**
|
|
17
|
+
* The browser redis mount: the shared resource over Upstash's REST api.
|
|
18
|
+
*
|
|
19
|
+
* A page cannot open a socket, so the store speaks HTTP to Upstash, or to
|
|
20
|
+
* serverless-redis-http in front of any redis. It takes the redis url the
|
|
21
|
+
* node and python mounts take, and the keyspace is the one they use, so one
|
|
22
|
+
* configuration and one database serve all three.
|
|
23
|
+
*/
|
|
24
|
+
export class RedisResource extends RedisResourceBase {
|
|
25
|
+
constructor(options) {
|
|
26
|
+
super(new UpstashRedisStore(options));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/resource/redis/redis.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,uEAAuE;AAEvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6CAA6C,CAAA;AAC/E,OAAO,EAAE,iBAAiB,EAAiC,MAAM,YAAY,CAAA;AAM7E;;;;;;;GAOG;AACH,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAGlD,YAAY,OAA6B;QACvC,KAAK,CAAC,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAA;IACvC,CAAC;CACF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { RedisRestore, RedisStoreLike } from '@struktoai/mirage-core/resource/redis/store';
|
|
2
|
+
export interface UpstashRedisStoreOptions {
|
|
3
|
+
/**
|
|
4
|
+
* The redis url the Upstash console prints,
|
|
5
|
+
* `rediss://default:<token>@<name>.upstash.io:6379`, which is the url the
|
|
6
|
+
* node and python mounts take; or the REST url, `https://<name>.upstash.io`,
|
|
7
|
+
* with `token` beside it.
|
|
8
|
+
*/
|
|
9
|
+
url: string;
|
|
10
|
+
/**
|
|
11
|
+
* The REST token. Required with a REST url; a redis url carries it as its
|
|
12
|
+
* password. Read-only tokens cannot SCAN, which readdir needs.
|
|
13
|
+
*/
|
|
14
|
+
token?: string;
|
|
15
|
+
keyPrefix?: string;
|
|
16
|
+
fetchImpl?: typeof fetch;
|
|
17
|
+
maxRequestBytes?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The redis keyspace over Upstash's REST API, so a browser page can mount
|
|
21
|
+
* redis with no socket. Anything that answers that API serves: Upstash
|
|
22
|
+
* itself, or serverless-redis-http in front of any redis. It is configured
|
|
23
|
+
* with the same redis url as the node and python mounts (see `restTarget`).
|
|
24
|
+
*
|
|
25
|
+
* Bytes need care, because a JSON command array carries UTF-8 strings and
|
|
26
|
+
* nothing else. Writes therefore use the path form, `POST /set/<key>` with
|
|
27
|
+
* the raw body as the last argument, and reads ask for `Upstash-Encoding:
|
|
28
|
+
* base64`, which encodes every bulk string in the reply. Both keep the stored
|
|
29
|
+
* value byte-identical to what the node and python stores write, so one
|
|
30
|
+
* database serves all three runtimes. The one thing the path form cannot
|
|
31
|
+
* carry is an empty body, which the server reads as a missing argument, so an
|
|
32
|
+
* empty file is written through the JSON form instead.
|
|
33
|
+
*/
|
|
34
|
+
export declare class UpstashRedisStore implements RedisStoreLike {
|
|
35
|
+
readonly url: string;
|
|
36
|
+
readonly keyPrefix: string;
|
|
37
|
+
private readonly token;
|
|
38
|
+
private readonly fetchImpl;
|
|
39
|
+
private readonly maxRequestBytes;
|
|
40
|
+
constructor(options: UpstashRedisStoreOptions);
|
|
41
|
+
fk(path: string): string;
|
|
42
|
+
dk(): string;
|
|
43
|
+
mk(path: string): string;
|
|
44
|
+
ak(path: string): string;
|
|
45
|
+
private request;
|
|
46
|
+
private command;
|
|
47
|
+
private pipeline;
|
|
48
|
+
private raw;
|
|
49
|
+
private integer;
|
|
50
|
+
private scan;
|
|
51
|
+
open(): Promise<void>;
|
|
52
|
+
getFile(path: string): Promise<Uint8Array | null>;
|
|
53
|
+
getFileRange(path: string, offset: number, size: number | null): Promise<Uint8Array | null>;
|
|
54
|
+
setFile(path: string, data: Uint8Array): Promise<void>;
|
|
55
|
+
delFile(path: string): Promise<void>;
|
|
56
|
+
hasFile(path: string): Promise<boolean>;
|
|
57
|
+
listFiles(prefix?: string): Promise<string[]>;
|
|
58
|
+
fileLen(path: string): Promise<number>;
|
|
59
|
+
hasDir(path: string): Promise<boolean>;
|
|
60
|
+
addDir(path: string): Promise<void>;
|
|
61
|
+
removeDir(path: string): Promise<void>;
|
|
62
|
+
listDirs(): Promise<Set<string>>;
|
|
63
|
+
getModified(path: string): Promise<string | null>;
|
|
64
|
+
setModified(path: string, ts: string): Promise<void>;
|
|
65
|
+
delModified(path: string): Promise<void>;
|
|
66
|
+
getAttrs(path: string): Promise<Record<string, string>>;
|
|
67
|
+
setAttrs(path: string, fields: Record<string, string>): Promise<void>;
|
|
68
|
+
delAttrs(path: string): Promise<void>;
|
|
69
|
+
listAttrs(): Promise<Record<string, Record<string, string>>>;
|
|
70
|
+
listModified(): Promise<Record<string, string>>;
|
|
71
|
+
restore(state: RedisRestore): Promise<void>;
|
|
72
|
+
clear(): Promise<void>;
|
|
73
|
+
close(): Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/resource/redis/store.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAA;AAgB/F,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAA;IACX;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAoGD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IACtD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;gBAE5B,OAAO,EAAE,wBAAwB;IAa7C,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIxB,EAAE,IAAI,MAAM;IAIZ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIxB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;YAIV,OAAO;YAyCP,OAAO;YAIP,QAAQ;YAkBR,GAAG;YAWH,OAAO;YAQP,IAAI;IAcZ,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAMjD,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GAAG,IAAI,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAgBvB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BtD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvC,SAAS,CAAC,MAAM,SAAK,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAM/C,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIhC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInC,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAIhC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKjD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAIvD,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAW5D,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAY/C,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvB"}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
2
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
// you may not use this file except in compliance with the License.
|
|
4
|
+
// You may obtain a copy of the License at
|
|
5
|
+
//
|
|
6
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
//
|
|
8
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
// See the License for the specific language governing permissions and
|
|
12
|
+
// limitations under the License.
|
|
13
|
+
// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========
|
|
14
|
+
import { decodeBase64 } from '@struktoai/mirage-core/utils/base64';
|
|
15
|
+
import { escapeGlob } from '@struktoai/mirage-core/core/redis/utils';
|
|
16
|
+
import { rstripSlash } from '@struktoai/mirage-core/utils/slash';
|
|
17
|
+
import { compareCodePoints } from '@struktoai/mirage-core/utils/sort';
|
|
18
|
+
// Upstash caps one REST request at 10 MB on every plan, so a file above this
|
|
19
|
+
// goes out as one SET followed by APPENDs, each under the cap with headroom,
|
|
20
|
+
// and a DEL or a pipeline is packed to the same budget by serialized size,
|
|
21
|
+
// with KEY_BATCH keys as a ceiling on top for a reply that has to fit too.
|
|
22
|
+
const DEFAULT_MAX_REQUEST_BYTES = 8 * 1024 * 1024;
|
|
23
|
+
const SCAN_COUNT = 1000;
|
|
24
|
+
const KEY_BATCH = 500;
|
|
25
|
+
const UTF8 = new TextEncoder();
|
|
26
|
+
/**
|
|
27
|
+
* Where the requests go and what they carry. Upstash hands out one secret
|
|
28
|
+
* that is both the database password and the REST token, so the redis url
|
|
29
|
+
* the node and python mounts take names the REST listener too: `https://`
|
|
30
|
+
* on the same host, with the password as the bearer token. A REST url needs
|
|
31
|
+
* `token` beside it, which is the form a serverless-redis-http front takes,
|
|
32
|
+
* since its token is its own setting and not a redis password. No message
|
|
33
|
+
* echoes the url, because a redis url carries the secret.
|
|
34
|
+
*/
|
|
35
|
+
function restTarget(options) {
|
|
36
|
+
if (typeof options.url !== 'string' || options.url === '') {
|
|
37
|
+
throw new Error('redis: url is required, the redis url or the REST url from the Upstash console');
|
|
38
|
+
}
|
|
39
|
+
let parsed;
|
|
40
|
+
try {
|
|
41
|
+
parsed = new URL(options.url);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new Error('redis: url must be a redis:// or rediss:// url, or an https:// REST url');
|
|
45
|
+
}
|
|
46
|
+
if (parsed.protocol === 'redis:' || parsed.protocol === 'rediss:') {
|
|
47
|
+
const token = parsed.password === '' ? (options.token ?? '') : decodeURIComponent(parsed.password);
|
|
48
|
+
if (token === '') {
|
|
49
|
+
throw new Error('redis: a redis url needs its password, which the Upstash console prints as the token; ' +
|
|
50
|
+
'put it in the url or pass it as token');
|
|
51
|
+
}
|
|
52
|
+
return { base: `https://${parsed.hostname}`, token };
|
|
53
|
+
}
|
|
54
|
+
if (parsed.protocol === 'https:' || parsed.protocol === 'http:') {
|
|
55
|
+
if (typeof options.token !== 'string' || options.token === '') {
|
|
56
|
+
throw new Error('redis: token is required, the database REST token from the Upstash console');
|
|
57
|
+
}
|
|
58
|
+
return { base: rstripSlash(options.url), token: options.token };
|
|
59
|
+
}
|
|
60
|
+
throw new Error('redis: url must be a redis:// or rediss:// url, or an https:// REST url');
|
|
61
|
+
}
|
|
62
|
+
function unwrap(payload) {
|
|
63
|
+
if (payload === null || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
64
|
+
throw new Error('upstash: reply is not an object');
|
|
65
|
+
}
|
|
66
|
+
const error = payload.error;
|
|
67
|
+
if (typeof error === 'string')
|
|
68
|
+
throw new Error(`upstash: ${error}`);
|
|
69
|
+
return payload.result ?? null;
|
|
70
|
+
}
|
|
71
|
+
function expectString(value, command) {
|
|
72
|
+
if (typeof value !== 'string')
|
|
73
|
+
throw new Error(`upstash: ${command} did not answer a string`);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
function expectStrings(value, command) {
|
|
77
|
+
if (!Array.isArray(value))
|
|
78
|
+
throw new Error(`upstash: ${command} did not answer an array`);
|
|
79
|
+
return value.map((item) => expectString(item, command));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Splits `items` into runs whose JSON array stays within `limit` UTF-8 bytes
|
|
83
|
+
* and KEY_BATCH entries. An item that alone outgrows the limit still goes out,
|
|
84
|
+
* on its own, so the server is the one to refuse it rather than a silent drop.
|
|
85
|
+
*/
|
|
86
|
+
function packJson(items, limit) {
|
|
87
|
+
const runs = [];
|
|
88
|
+
let run = [];
|
|
89
|
+
let bytes = 2;
|
|
90
|
+
for (const item of items) {
|
|
91
|
+
const size = UTF8.encode(JSON.stringify(item)).byteLength + 1;
|
|
92
|
+
if (run.length > 0 && (run.length >= KEY_BATCH || bytes + size > limit)) {
|
|
93
|
+
runs.push(run);
|
|
94
|
+
run = [];
|
|
95
|
+
bytes = 2;
|
|
96
|
+
}
|
|
97
|
+
run.push(item);
|
|
98
|
+
bytes += size;
|
|
99
|
+
}
|
|
100
|
+
if (run.length > 0)
|
|
101
|
+
runs.push(run);
|
|
102
|
+
return runs;
|
|
103
|
+
}
|
|
104
|
+
function pairsToRecord(flat) {
|
|
105
|
+
const out = {};
|
|
106
|
+
for (let i = 0; i + 1 < flat.length; i += 2) {
|
|
107
|
+
out[flat[i] ?? ''] = flat[i + 1] ?? '';
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The redis keyspace over Upstash's REST API, so a browser page can mount
|
|
113
|
+
* redis with no socket. Anything that answers that API serves: Upstash
|
|
114
|
+
* itself, or serverless-redis-http in front of any redis. It is configured
|
|
115
|
+
* with the same redis url as the node and python mounts (see `restTarget`).
|
|
116
|
+
*
|
|
117
|
+
* Bytes need care, because a JSON command array carries UTF-8 strings and
|
|
118
|
+
* nothing else. Writes therefore use the path form, `POST /set/<key>` with
|
|
119
|
+
* the raw body as the last argument, and reads ask for `Upstash-Encoding:
|
|
120
|
+
* base64`, which encodes every bulk string in the reply. Both keep the stored
|
|
121
|
+
* value byte-identical to what the node and python stores write, so one
|
|
122
|
+
* database serves all three runtimes. The one thing the path form cannot
|
|
123
|
+
* carry is an empty body, which the server reads as a missing argument, so an
|
|
124
|
+
* empty file is written through the JSON form instead.
|
|
125
|
+
*/
|
|
126
|
+
export class UpstashRedisStore {
|
|
127
|
+
url;
|
|
128
|
+
keyPrefix;
|
|
129
|
+
token;
|
|
130
|
+
fetchImpl;
|
|
131
|
+
maxRequestBytes;
|
|
132
|
+
constructor(options) {
|
|
133
|
+
const target = restTarget(options);
|
|
134
|
+
this.url = target.base;
|
|
135
|
+
this.token = target.token;
|
|
136
|
+
this.keyPrefix = options.keyPrefix ?? 'mirage:fs:';
|
|
137
|
+
this.fetchImpl = options.fetchImpl ?? fetch.bind(globalThis);
|
|
138
|
+
const limit = options.maxRequestBytes ?? DEFAULT_MAX_REQUEST_BYTES;
|
|
139
|
+
if (!Number.isInteger(limit) || limit <= 0) {
|
|
140
|
+
throw new Error('redis: maxRequestBytes must be a positive integer');
|
|
141
|
+
}
|
|
142
|
+
this.maxRequestBytes = limit;
|
|
143
|
+
}
|
|
144
|
+
fk(path) {
|
|
145
|
+
return `${this.keyPrefix}file:${path}`;
|
|
146
|
+
}
|
|
147
|
+
dk() {
|
|
148
|
+
return `${this.keyPrefix}dir`;
|
|
149
|
+
}
|
|
150
|
+
mk(path) {
|
|
151
|
+
return `${this.keyPrefix}modified:${path}`;
|
|
152
|
+
}
|
|
153
|
+
ak(path) {
|
|
154
|
+
return `${this.keyPrefix}attrs:${path}`;
|
|
155
|
+
}
|
|
156
|
+
async request(path, body, contentType, base64) {
|
|
157
|
+
const headers = {
|
|
158
|
+
Authorization: `Bearer ${this.token}`,
|
|
159
|
+
'Content-Type': contentType,
|
|
160
|
+
};
|
|
161
|
+
if (base64)
|
|
162
|
+
headers['Upstash-Encoding'] = 'base64';
|
|
163
|
+
let response;
|
|
164
|
+
try {
|
|
165
|
+
response = await this.fetchImpl(`${this.url}${path}`, { method: 'POST', headers, body });
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
169
|
+
throw new Error(`upstash: cannot reach ${this.url} (${reason}); a page needs a REST listener at this ` +
|
|
170
|
+
'host, Upstash itself or serverless-redis-http in front of the redis');
|
|
171
|
+
}
|
|
172
|
+
const text = await response.text();
|
|
173
|
+
let payload;
|
|
174
|
+
try {
|
|
175
|
+
payload = JSON.parse(text);
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
throw new Error(`upstash: HTTP ${String(response.status)} with a non-JSON body`);
|
|
179
|
+
}
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
const message = payload !== null &&
|
|
182
|
+
typeof payload === 'object' &&
|
|
183
|
+
!Array.isArray(payload) &&
|
|
184
|
+
typeof payload.error === 'string'
|
|
185
|
+
? payload.error
|
|
186
|
+
: text;
|
|
187
|
+
throw new Error(`upstash: HTTP ${String(response.status)}: ${message}`);
|
|
188
|
+
}
|
|
189
|
+
return payload;
|
|
190
|
+
}
|
|
191
|
+
async command(args, base64 = false) {
|
|
192
|
+
return unwrap(await this.request('', JSON.stringify(args), 'application/json', base64));
|
|
193
|
+
}
|
|
194
|
+
async pipeline(commands, base64 = false) {
|
|
195
|
+
const replies = [];
|
|
196
|
+
for (const run of packJson(commands, this.maxRequestBytes)) {
|
|
197
|
+
const payload = await this.request('/pipeline', JSON.stringify(run), 'application/json', base64);
|
|
198
|
+
if (!Array.isArray(payload))
|
|
199
|
+
throw new Error('upstash: pipeline did not answer an array');
|
|
200
|
+
for (const item of payload)
|
|
201
|
+
replies.push(unwrap(item));
|
|
202
|
+
}
|
|
203
|
+
return replies;
|
|
204
|
+
}
|
|
205
|
+
async raw(command, key, data) {
|
|
206
|
+
unwrap(await this.request(`/${command}/${encodeURIComponent(key)}`, data, 'application/octet-stream', false));
|
|
207
|
+
}
|
|
208
|
+
async integer(args) {
|
|
209
|
+
const reply = await this.command(args);
|
|
210
|
+
if (typeof reply !== 'number') {
|
|
211
|
+
throw new Error(`upstash: ${String(args[0])} did not answer an integer`);
|
|
212
|
+
}
|
|
213
|
+
return reply;
|
|
214
|
+
}
|
|
215
|
+
async scan(pattern) {
|
|
216
|
+
const keys = [];
|
|
217
|
+
let cursor = '0';
|
|
218
|
+
do {
|
|
219
|
+
const reply = await this.command(['SCAN', cursor, 'MATCH', pattern, 'COUNT', SCAN_COUNT]);
|
|
220
|
+
if (!Array.isArray(reply) || reply.length !== 2) {
|
|
221
|
+
throw new Error('upstash: SCAN did not answer a cursor and a page');
|
|
222
|
+
}
|
|
223
|
+
cursor = expectString(reply[0] ?? null, 'SCAN');
|
|
224
|
+
for (const key of expectStrings(reply[1] ?? null, 'SCAN'))
|
|
225
|
+
keys.push(key);
|
|
226
|
+
} while (cursor !== '0');
|
|
227
|
+
return keys;
|
|
228
|
+
}
|
|
229
|
+
async open() {
|
|
230
|
+
await this.command(['SADD', this.dk(), '/']);
|
|
231
|
+
}
|
|
232
|
+
async getFile(path) {
|
|
233
|
+
const reply = await this.command(['GET', this.fk(path)], true);
|
|
234
|
+
if (reply === null)
|
|
235
|
+
return null;
|
|
236
|
+
return decodeBase64(expectString(reply, 'GET'));
|
|
237
|
+
}
|
|
238
|
+
async getFileRange(path, offset, size) {
|
|
239
|
+
const key = this.fk(path);
|
|
240
|
+
// GETRANGE 0 -1 means the whole value, not an empty window.
|
|
241
|
+
if (size === 0)
|
|
242
|
+
return (await this.integer(['EXISTS', key])) === 0 ? null : new Uint8Array(0);
|
|
243
|
+
const end = size === null ? -1 : offset + size - 1;
|
|
244
|
+
const [exists, raw] = await this.pipeline([
|
|
245
|
+
['EXISTS', key],
|
|
246
|
+
['GETRANGE', key, offset, end],
|
|
247
|
+
], true);
|
|
248
|
+
if (exists === 0)
|
|
249
|
+
return null;
|
|
250
|
+
return decodeBase64(expectString(raw ?? null, 'GETRANGE'));
|
|
251
|
+
}
|
|
252
|
+
async setFile(path, data) {
|
|
253
|
+
const key = this.fk(path);
|
|
254
|
+
if (data.byteLength === 0) {
|
|
255
|
+
await this.command(['SET', key, '']);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const limit = this.maxRequestBytes;
|
|
259
|
+
if (data.byteLength <= limit) {
|
|
260
|
+
await this.raw('set', key, data);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
// A chunked write lands on a staging key and is renamed in only once every
|
|
264
|
+
// chunk arrived, so a failed chunk never leaves a truncated file behind and
|
|
265
|
+
// two writers of one path never interleave: the mount keeps the single-SET
|
|
266
|
+
// semantics of the node and python stores.
|
|
267
|
+
const staging = `${this.keyPrefix}tmp:${path}:${crypto.randomUUID()}`;
|
|
268
|
+
try {
|
|
269
|
+
await this.raw('set', staging, data.subarray(0, limit));
|
|
270
|
+
for (let offset = limit; offset < data.byteLength; offset += limit) {
|
|
271
|
+
await this.raw('append', staging, data.subarray(offset, offset + limit));
|
|
272
|
+
}
|
|
273
|
+
await this.command(['RENAME', staging, key]);
|
|
274
|
+
}
|
|
275
|
+
catch (err) {
|
|
276
|
+
await this.command(['DEL', staging]);
|
|
277
|
+
throw err;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async delFile(path) {
|
|
281
|
+
await this.command(['DEL', this.fk(path)]);
|
|
282
|
+
}
|
|
283
|
+
async hasFile(path) {
|
|
284
|
+
return (await this.integer(['EXISTS', this.fk(path)])) > 0;
|
|
285
|
+
}
|
|
286
|
+
async listFiles(prefix = '') {
|
|
287
|
+
const head = `${this.keyPrefix}file:`;
|
|
288
|
+
const keys = await this.scan(`${escapeGlob(`${head}${prefix}`)}*`);
|
|
289
|
+
return keys.map((key) => key.slice(head.length)).sort(compareCodePoints);
|
|
290
|
+
}
|
|
291
|
+
fileLen(path) {
|
|
292
|
+
return this.integer(['STRLEN', this.fk(path)]);
|
|
293
|
+
}
|
|
294
|
+
async hasDir(path) {
|
|
295
|
+
return (await this.integer(['SISMEMBER', this.dk(), path])) === 1;
|
|
296
|
+
}
|
|
297
|
+
async addDir(path) {
|
|
298
|
+
await this.command(['SADD', this.dk(), path]);
|
|
299
|
+
}
|
|
300
|
+
async removeDir(path) {
|
|
301
|
+
await this.command(['SREM', this.dk(), path]);
|
|
302
|
+
}
|
|
303
|
+
async listDirs() {
|
|
304
|
+
return new Set(expectStrings(await this.command(['SMEMBERS', this.dk()]), 'SMEMBERS'));
|
|
305
|
+
}
|
|
306
|
+
async getModified(path) {
|
|
307
|
+
const reply = await this.command(['GET', this.mk(path)]);
|
|
308
|
+
return reply === null ? null : expectString(reply, 'GET');
|
|
309
|
+
}
|
|
310
|
+
async setModified(path, ts) {
|
|
311
|
+
await this.command(['SET', this.mk(path), ts]);
|
|
312
|
+
}
|
|
313
|
+
async delModified(path) {
|
|
314
|
+
await this.command(['DEL', this.mk(path)]);
|
|
315
|
+
}
|
|
316
|
+
async getAttrs(path) {
|
|
317
|
+
return pairsToRecord(expectStrings(await this.command(['HGETALL', this.ak(path)]), 'HGETALL'));
|
|
318
|
+
}
|
|
319
|
+
async setAttrs(path, fields) {
|
|
320
|
+
const flat = Object.entries(fields).flat();
|
|
321
|
+
if (flat.length === 0)
|
|
322
|
+
return;
|
|
323
|
+
await this.command(['HSET', this.ak(path), ...flat]);
|
|
324
|
+
}
|
|
325
|
+
async delAttrs(path) {
|
|
326
|
+
await this.command(['DEL', this.ak(path)]);
|
|
327
|
+
}
|
|
328
|
+
async listAttrs() {
|
|
329
|
+
const head = `${this.keyPrefix}attrs:`;
|
|
330
|
+
const keys = await this.scan(`${escapeGlob(head)}*`);
|
|
331
|
+
const replies = await this.pipeline(keys.map((key) => ['HGETALL', key]));
|
|
332
|
+
const out = {};
|
|
333
|
+
keys.forEach((key, i) => {
|
|
334
|
+
out[key.slice(head.length)] = pairsToRecord(expectStrings(replies[i] ?? null, 'HGETALL'));
|
|
335
|
+
});
|
|
336
|
+
return out;
|
|
337
|
+
}
|
|
338
|
+
async listModified() {
|
|
339
|
+
const head = `${this.keyPrefix}modified:`;
|
|
340
|
+
const keys = await this.scan(`${escapeGlob(head)}*`);
|
|
341
|
+
const replies = await this.pipeline(keys.map((key) => ['GET', key]));
|
|
342
|
+
const out = {};
|
|
343
|
+
keys.forEach((key, i) => {
|
|
344
|
+
const reply = replies[i] ?? null;
|
|
345
|
+
if (reply !== null)
|
|
346
|
+
out[key.slice(head.length)] = expectString(reply, 'GET');
|
|
347
|
+
});
|
|
348
|
+
return out;
|
|
349
|
+
}
|
|
350
|
+
async restore(state) {
|
|
351
|
+
for (const [path, data] of Object.entries(state.files)) {
|
|
352
|
+
await this.setFile(path, data);
|
|
353
|
+
}
|
|
354
|
+
const commands = [];
|
|
355
|
+
for (const dir of state.dirs)
|
|
356
|
+
commands.push(['SADD', this.dk(), dir]);
|
|
357
|
+
for (const [path, fields] of Object.entries(state.attrs)) {
|
|
358
|
+
const flat = Object.entries(fields).flat();
|
|
359
|
+
if (flat.length > 0)
|
|
360
|
+
commands.push(['HSET', this.ak(path), ...flat]);
|
|
361
|
+
}
|
|
362
|
+
for (const [path, ts] of Object.entries(state.modified)) {
|
|
363
|
+
commands.push(['SET', this.mk(path), ts]);
|
|
364
|
+
}
|
|
365
|
+
await this.pipeline(commands);
|
|
366
|
+
}
|
|
367
|
+
async clear() {
|
|
368
|
+
const p = escapeGlob(this.keyPrefix);
|
|
369
|
+
for (const pattern of [`${p}file:*`, `${p}tmp:*`, `${p}modified:*`, `${p}attrs:*`]) {
|
|
370
|
+
const keys = await this.scan(pattern);
|
|
371
|
+
for (const run of packJson(keys, this.maxRequestBytes - '"DEL",'.length)) {
|
|
372
|
+
await this.command(['DEL', ...run]);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
await this.command(['DEL', this.dk()]);
|
|
376
|
+
}
|
|
377
|
+
close() {
|
|
378
|
+
return Promise.resolve();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=store.js.map
|