From abb2b74468568941450b78d7fc67e61d01902f39 Mon Sep 17 00:00:00 2001 From: database-mysql Date: Sun, 4 Oct 2026 04:30:57 +0800 Subject: [PATCH] first commit --- .gitignore | 2 + .idea/.gitignore | 10 ++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/misc.xml | 6 +++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 +++ TurboWarp_S3.iml | 8 +++ src/main.js | 77 ++++++++++++++++++++++++++++ 8 files changed, 122 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 TurboWarp_S3.iml create mode 100644 src/main.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46edf1c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea/ +./.gitignore diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b6b1ecf --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 已忽略包含查询文件的默认文件夹 +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4b151ab --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..cd170de --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TurboWarp_S3.iml b/TurboWarp_S3.iml new file mode 100644 index 0000000..9a5cfce --- /dev/null +++ b/TurboWarp_S3.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..37a5d0e --- /dev/null +++ b/src/main.js @@ -0,0 +1,77 @@ +(function (Scratch) { + 'use strict'; + + // 非沙箱守卫:确保扩展有权限发起网络请求 + if (!Scratch.extensions.unsandboxed) { + throw new Error('S3 扩展必须运行在非沙箱模式下'); + } + + class S3Extension { + constructor() { + // 在内存中保存凭据(仅用于演示,生产环境需注意安全) + this.credentials = {}; + } + + getInfo() { + return { + id: 's3client', + name: 'S3 客户端', + blocks: [ + { + opcode: 'setCredentials', + blockType: Scratch.BlockType.COMMAND, + text: '设置 S3 凭据 Key [AK] Secret [SK] 区域 [REGION]', + arguments: { + AK: { type: Scratch.ArgumentType.STRING, defaultValue: 'AKIA...' }, + SK: { type: Scratch.ArgumentType.STRING, defaultValue: 'secret...' }, + REGION: { type: Scratch.ArgumentType.STRING, defaultValue: 'us-east-1' } + } + }, + { + opcode: 'putObject', + blockType: Scratch.BlockType.COMMAND, + text: '上传桶 [BUCKET] 键 [KEY] 内容 [BODY]', + arguments: { + BUCKET: { type: Scratch.ArgumentType.STRING, defaultValue: 'my-bucket' }, + KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'hello.txt' }, + BODY: { type: Scratch.ArgumentType.STRING, defaultValue: 'Hello S3!' } + } + }, + { + opcode: 'getObject', + blockType: Scratch.BlockType.REPORTER, + text: '下载桶 [BUCKET] 键 [KEY]', + arguments: { + BUCKET: { type: Scratch.ArgumentType.STRING, defaultValue: 'my-bucket' }, + KEY: { type: Scratch.ArgumentType.STRING, defaultValue: 'hello.txt' } + } + } + ] + }; + } + + setCredentials(args) { + this.credentials = { + accessKey: args.AK, + secretKey: args.SK, + region: args.REGION + }; + } + + // 这里接入上一轮实现的 SigV4 签名与 fetch 调用 + async putObject(args) { + const { accessKey, secretKey, region } = this.credentials; + // 1. 计算 payload hash(对 BODY 做 SHA256) + // 2. 构造 CanonicalRequest -> StringToSign -> Signature + // 3. fetch(`https://${args.BUCKET}.s3.${region}.amazonaws.com/${args.KEY}`, { method: 'PUT', ... }) + // 返回成功或抛出错误 + } + + async getObject(args) { + // 签名时 payload hash 为空字符串的 SHA256 + // fetch GET,返回 res.text() 或 arrayBuffer + } + } + + Scratch.extensions.register(new S3Extension()); +})(Scratch);