commit abb2b74468568941450b78d7fc67e61d01902f39 Author: database-mysql Date: Sun Oct 4 04:30:57 2026 +0800 first commit 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);