studiograph 1.0.9 → 1.1.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/dist/cli/commands/r2.js +48 -28
- package/dist/cli/commands/r2.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/commands/r2.js
CHANGED
|
@@ -10,7 +10,7 @@ import { intro, outro, text, spinner, log } from '@clack/prompts';
|
|
|
10
10
|
import { readdirSync, statSync, readFileSync } from 'fs';
|
|
11
11
|
import { join, relative, extname } from 'path';
|
|
12
12
|
import { spawnSync } from 'child_process';
|
|
13
|
-
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
|
|
13
|
+
import { S3Client, CreateBucketCommand, PutObjectCommand } from '@aws-sdk/client-s3';
|
|
14
14
|
import { Workspace } from '../../core/workspace.js';
|
|
15
15
|
import { loadUserConfig, saveUserConfig } from '../../core/user-config.js';
|
|
16
16
|
// ── Open a URL in the default browser (macOS + Linux) ────────────────────
|
|
@@ -67,52 +67,72 @@ r2Command
|
|
|
67
67
|
process.exit(1);
|
|
68
68
|
}
|
|
69
69
|
const config = workspace.loadConfig();
|
|
70
|
-
intro('Set up Cloudflare R2 —
|
|
71
|
-
// ── Step 1: Account ID
|
|
72
|
-
log.step('Step 1 of
|
|
73
|
-
log.message('Opening your
|
|
70
|
+
intro('Set up Cloudflare R2 — 2 steps');
|
|
71
|
+
// ── Step 1: Account ID + credentials ───────────────────────────────
|
|
72
|
+
log.step('Step 1 of 2 — Connect your Cloudflare account');
|
|
73
|
+
log.message('Opening your R2 dashboard...\n' +
|
|
74
|
+
' 1. Copy your Account ID from the right sidebar\n' +
|
|
75
|
+
' 2. Click API Tokens → Manage → Create API Token\n' +
|
|
76
|
+
' Permissions: Admin Read & Write\n' +
|
|
77
|
+
' 3. Copy the Access Key ID and Secret Access Key\n\n' +
|
|
78
|
+
'Note: Admin access lets Studiograph create your bucket automatically.\n' +
|
|
79
|
+
'You can replace this with a bucket-scoped token later for tighter security.');
|
|
74
80
|
openBrowser('https://dash.cloudflare.com/?to=/:account/r2/overview');
|
|
75
81
|
const accountId = await text({
|
|
76
|
-
message: '
|
|
82
|
+
message: 'Account ID',
|
|
77
83
|
placeholder: 'e.g. 730badcf851d93c77bf83157749f0280',
|
|
78
84
|
validate: (v) => v.trim() ? undefined : 'Required',
|
|
79
85
|
});
|
|
80
|
-
|
|
86
|
+
const accessKeyId = await text({
|
|
87
|
+
message: 'Access Key ID',
|
|
88
|
+
placeholder: 'Paste the Access Key ID',
|
|
89
|
+
validate: (v) => v.trim() ? undefined : 'Required',
|
|
90
|
+
});
|
|
91
|
+
const secretAccessKey = await text({
|
|
92
|
+
message: 'Secret Access Key',
|
|
93
|
+
placeholder: 'Paste the Secret Access Key',
|
|
94
|
+
validate: (v) => v.trim() ? undefined : 'Required',
|
|
95
|
+
});
|
|
96
|
+
// ── Create bucket automatically ─────────────────────────────────────
|
|
81
97
|
const defaultBucket = config.team_name
|
|
82
98
|
.toLowerCase()
|
|
83
99
|
.replace(/\s+/g, '-')
|
|
84
100
|
.replace(/[^a-z0-9-]/g, '')
|
|
85
101
|
+ '-assets';
|
|
86
|
-
log.step('Step 2 of 4 — Create a bucket');
|
|
87
|
-
log.message('Opening bucket creation...\nEnter a name and click Create bucket.');
|
|
88
|
-
openBrowser(`https://dash.cloudflare.com/${accountId}/r2/new`);
|
|
89
102
|
const bucketInput = await text({
|
|
90
103
|
message: 'Bucket name',
|
|
91
104
|
placeholder: defaultBucket,
|
|
92
105
|
});
|
|
93
106
|
const bucket = bucketInput.trim() || defaultBucket;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
const client = new S3Client({
|
|
108
|
+
region: 'auto',
|
|
109
|
+
endpoint: `https://${accountId}.r2.cloudflarestorage.com`,
|
|
110
|
+
credentials: { accessKeyId, secretAccessKey },
|
|
111
|
+
});
|
|
112
|
+
const s = spinner();
|
|
113
|
+
s.start(`Creating bucket "${bucket}"...`);
|
|
114
|
+
try {
|
|
115
|
+
await client.send(new CreateBucketCommand({ Bucket: bucket }));
|
|
116
|
+
s.stop(`Bucket "${bucket}" created`);
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
if (e?.name === 'BucketAlreadyExists' || e?.name === 'BucketAlreadyOwnedByYou' || e?.$metadata?.httpStatusCode === 409) {
|
|
120
|
+
s.stop(`Bucket "${bucket}" already exists — continuing`);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
s.stop(`Failed to create bucket: ${e?.message ?? 'unknown error'}`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ── Step 2: Enable public access ────────────────────────────────────
|
|
128
|
+
log.step('Step 2 of 2 — Enable public access');
|
|
129
|
+
log.message(`In your browser: click "${bucket}" → Settings tab → Public Development URL → Enable.\n` +
|
|
130
|
+
'Then paste the URL that appears below (looks like https://pub-xxxx.r2.dev).');
|
|
97
131
|
const publicUrl = await text({
|
|
98
|
-
message: '
|
|
132
|
+
message: 'Public URL',
|
|
99
133
|
placeholder: 'https://pub-xxxx.r2.dev',
|
|
100
134
|
validate: (v) => v.trim() ? undefined : 'Required',
|
|
101
135
|
});
|
|
102
|
-
// ── Step 4: Upload credentials ──────────────────────────────────────
|
|
103
|
-
log.step('Step 4 of 4 — Create upload credentials');
|
|
104
|
-
log.message('Opening R2 overview...\nIn the right sidebar → API Tokens → Manage → Create API Token.\nSet permissions to "Object Read & Write" → Create API Token.\nCopy both the Access Key ID and Secret Access Key — you\'ll need both.');
|
|
105
|
-
openBrowser(`https://dash.cloudflare.com/${accountId}/r2/overview`);
|
|
106
|
-
const accessKeyId = await text({
|
|
107
|
-
message: 'Access Key ID',
|
|
108
|
-
placeholder: 'Paste the Access Key ID',
|
|
109
|
-
validate: (v) => v.trim() ? undefined : 'Required',
|
|
110
|
-
});
|
|
111
|
-
const secretAccessKey = await text({
|
|
112
|
-
message: 'Secret Access Key',
|
|
113
|
-
placeholder: 'Paste the Secret Access Key',
|
|
114
|
-
validate: (v) => v.trim() ? undefined : 'Required',
|
|
115
|
-
});
|
|
116
136
|
// ── Save config ─────────────────────────────────────────────────────
|
|
117
137
|
config.r2_config = { account_id: accountId, bucket, public_url: publicUrl };
|
|
118
138
|
workspace.writeConfig(config);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../../../src/cli/commands/r2.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"r2.js","sourceRoot":"","sources":["../../../src/cli/commands/r2.ts"],"names":[],"mappings":"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"}
|