@vibes.diy/api-svc 4.0.14 → 4.0.16
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/create-handler.js.map +1 -1
- package/intern/backend-db-callback.js +1 -2
- package/intern/backend-db-callback.js.map +1 -1
- package/intern/emit-backend-onchange.d.ts +1 -0
- package/intern/emit-backend-onchange.js +28 -0
- package/intern/emit-backend-onchange.js.map +1 -1
- package/intern/load-vibe-env.d.ts +2 -0
- package/intern/load-vibe-env.js +17 -0
- package/intern/load-vibe-env.js.map +1 -0
- package/intern/render-vibe.d.ts +2 -1
- package/intern/render-vibe.js +5 -4
- package/intern/render-vibe.js.map +1 -1
- package/package.json +15 -14
- package/public/app-documents-write-eventos.js +5 -5
- package/public/app-documents-write-eventos.js.map +1 -1
- package/public/ensure-handle-avatar.d.ts +1 -0
- package/public/ensure-handle-avatar.js +10 -1
- package/public/ensure-handle-avatar.js.map +1 -1
- package/public/prompt-chat-section.js +14 -0
- package/public/prompt-chat-section.js.map +1 -1
- package/public/serv-entry-point.d.ts +1 -0
- package/public/serv-entry-point.js +13 -5
- package/public/serv-entry-point.js.map +1 -1
- package/public/who-am-i.js +7 -7
- package/public/who-am-i.js.map +1 -1
- package/usage-report/backfill-avatars.d.ts +1 -0
- package/usage-report/backfill-avatars.js +207 -0
- package/usage-report/backfill-avatars.js.map +1 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { Pool } from "@neondatabase/serverless";
|
|
6
|
+
import { Result, exception2Result } from "@adviser/cement";
|
|
7
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
8
|
+
import { base58btc } from "multiformats/bases/base58";
|
|
9
|
+
import sharp from "sharp";
|
|
10
|
+
import { AVATAR_MAX_BYTES } from "../public/ensure-handle-avatar.js";
|
|
11
|
+
import { formatError, loadDevVars } from "./usage-report-util.js";
|
|
12
|
+
const MAX_DIM = 512;
|
|
13
|
+
const WEBP_QUALITY = 85;
|
|
14
|
+
const R2_BUCKET = "vibes-diy-fs-ids";
|
|
15
|
+
function printUsage() {
|
|
16
|
+
console.log(`
|
|
17
|
+
Usage:
|
|
18
|
+
pnpm --dir vibes.diy/api/svc run admin:backfill-avatars # dry run (read-only)
|
|
19
|
+
pnpm --dir vibes.diy/api/svc run admin:backfill-avatars -- --apply # write pass
|
|
20
|
+
|
|
21
|
+
Environment:
|
|
22
|
+
NEON_DATABASE_URL read connection (dry run + row discovery)
|
|
23
|
+
NEON_DATABASE_ADMIN_URL write connection (required for --apply)
|
|
24
|
+
ASSET_FETCH_BASE public host serving /assets/cid/ (default https://vibes.diy)
|
|
25
|
+
--apply additionally shells out to \`wrangler r2 object put\` — wrangler must be
|
|
26
|
+
authenticated (CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID, or wrangler login).
|
|
27
|
+
`.trim());
|
|
28
|
+
}
|
|
29
|
+
function assetFetchURL(base, getURL, mime) {
|
|
30
|
+
return `${base}/assets/cid/?url=${encodeURIComponent(getURL)}&mime=${encodeURIComponent(mime)}`;
|
|
31
|
+
}
|
|
32
|
+
async function fetchAvatarBytes(base, row) {
|
|
33
|
+
return exception2Result(async () => {
|
|
34
|
+
const res = await fetch(assetFetchURL(base, row.getURL, row.mimeType ?? "application/octet-stream"));
|
|
35
|
+
if (!res.ok)
|
|
36
|
+
throw new Error(`fetch ${row.getURL} returned ${res.status}`);
|
|
37
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
38
|
+
if (buf.byteLength !== row.size) {
|
|
39
|
+
throw new Error(`fetched ${buf.byteLength} bytes but AssetUploads says ${row.size} — refusing to transform`);
|
|
40
|
+
}
|
|
41
|
+
return buf;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async function transform(bytes) {
|
|
45
|
+
return exception2Result(() => sharp(bytes)
|
|
46
|
+
.rotate()
|
|
47
|
+
.resize(MAX_DIM, MAX_DIM, { fit: "inside", withoutEnlargement: true })
|
|
48
|
+
.webp({ quality: WEBP_QUALITY })
|
|
49
|
+
.toBuffer());
|
|
50
|
+
}
|
|
51
|
+
function contentCid(bytes) {
|
|
52
|
+
return base58btc.encode(sha256(bytes));
|
|
53
|
+
}
|
|
54
|
+
async function discover(pool) {
|
|
55
|
+
const q = await pool.query(`
|
|
56
|
+
WITH avatars AS (
|
|
57
|
+
SELECT hs.handle, hs."userId", e->>'currentCid' AS geturl
|
|
58
|
+
FROM "HandleSettings" hs, jsonb_array_elements(hs.settings) e
|
|
59
|
+
WHERE e->>'type' = 'active.avatar'
|
|
60
|
+
)
|
|
61
|
+
SELECT DISTINCT ON (a.handle) a.handle, a."userId", a.geturl, au."mimeType", au.size
|
|
62
|
+
FROM avatars a
|
|
63
|
+
JOIN "AssetUploads" au ON au."assetURI" = a.geturl
|
|
64
|
+
ORDER BY a.handle, au.created DESC
|
|
65
|
+
`);
|
|
66
|
+
return q.rows.map((r) => ({
|
|
67
|
+
handle: r.handle,
|
|
68
|
+
userId: r.userId,
|
|
69
|
+
getURL: r.geturl,
|
|
70
|
+
mimeType: r.mimeType,
|
|
71
|
+
size: Number(r.size),
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
function putR2Object(cid, bytes) {
|
|
75
|
+
const tmp = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "avatar-backfill-")), cid);
|
|
76
|
+
fs.writeFileSync(tmp, bytes);
|
|
77
|
+
try {
|
|
78
|
+
const res = spawnSync("pnpm", ["exec", "wrangler", "r2", "object", "put", `${R2_BUCKET}/${cid}`, "--file", tmp, "--content-type", "image/webp", "--remote"], { stdio: "inherit" });
|
|
79
|
+
if (res.status !== 0)
|
|
80
|
+
return Result.Err(`wrangler r2 object put exited ${res.status}`);
|
|
81
|
+
return Result.Ok(undefined);
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
fs.rmSync(path.dirname(tmp), { recursive: true, force: true });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function verifyServed(base, work) {
|
|
88
|
+
return exception2Result(async () => {
|
|
89
|
+
const res = await fetch(assetFetchURL(base, work.newGetURL, "image/webp"));
|
|
90
|
+
if (!res.ok)
|
|
91
|
+
throw new Error(`verify fetch of ${work.newGetURL} returned ${res.status}`);
|
|
92
|
+
const buf = Buffer.from(await res.arrayBuffer());
|
|
93
|
+
if (buf.byteLength !== work.newBytes.byteLength) {
|
|
94
|
+
throw new Error(`verify size mismatch: served ${buf.byteLength}, expected ${work.newBytes.byteLength}`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async function applyOne(pool, base, work, stamp) {
|
|
99
|
+
const { row, newBytes, newCid, newGetURL } = work;
|
|
100
|
+
const rPut = putR2Object(newCid, newBytes);
|
|
101
|
+
if (rPut.isErr())
|
|
102
|
+
return Result.Err(rPut);
|
|
103
|
+
const rVerify = await verifyServed(base, work);
|
|
104
|
+
if (rVerify.isErr())
|
|
105
|
+
return Result.Err(rVerify);
|
|
106
|
+
return exception2Result(async () => {
|
|
107
|
+
const now = new Date().toISOString();
|
|
108
|
+
await pool.query(`INSERT INTO "AssetUploads" ("uploadId", "userId", "userSlug", "appSlug", cid, "assetURI", size, "mimeType", created)
|
|
109
|
+
VALUES ($1, $2, $3, '_profile', $4, $5, $6, 'image/webp', $7)
|
|
110
|
+
ON CONFLICT ("uploadId") DO NOTHING`, [`backfill-${stamp}-${row.handle}`, row.userId, row.handle, newCid, newGetURL, newBytes.byteLength, now]);
|
|
111
|
+
const cur = await pool.query(`SELECT settings FROM "HandleSettings" WHERE handle = $1`, [row.handle]);
|
|
112
|
+
if (cur.rowCount !== 1)
|
|
113
|
+
throw new Error(`HandleSettings row for ${row.handle} disappeared`);
|
|
114
|
+
const entries = cur.rows[0].settings;
|
|
115
|
+
const idx = entries.findIndex((e) => e.type === "active.avatar");
|
|
116
|
+
if (idx < 0)
|
|
117
|
+
throw new Error(`no active.avatar entry for ${row.handle}`);
|
|
118
|
+
if (entries[idx].currentCid !== row.getURL) {
|
|
119
|
+
throw new Error(`currentCid for ${row.handle} changed since discovery (user re-uploaded?) — skipping`);
|
|
120
|
+
}
|
|
121
|
+
entries[idx] = {
|
|
122
|
+
type: "active.avatar",
|
|
123
|
+
versions: [...(entries[idx].versions ?? []), { cid: newGetURL, mime: "image/webp", created: now }],
|
|
124
|
+
currentCid: newGetURL,
|
|
125
|
+
};
|
|
126
|
+
await pool.query(`UPDATE "HandleSettings" SET settings = $1, updated = $2 WHERE handle = $3`, [
|
|
127
|
+
JSON.stringify(entries),
|
|
128
|
+
now,
|
|
129
|
+
row.handle,
|
|
130
|
+
]);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const kb = (n) => `${(n / 1024).toFixed(1)}KB`;
|
|
134
|
+
async function run() {
|
|
135
|
+
loadDevVars();
|
|
136
|
+
const args = process.argv.slice(2);
|
|
137
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
138
|
+
printUsage();
|
|
139
|
+
return Result.Ok(undefined);
|
|
140
|
+
}
|
|
141
|
+
const apply = args.includes("--apply");
|
|
142
|
+
const base = process.env["ASSET_FETCH_BASE"] ?? "https://vibes.diy";
|
|
143
|
+
const connectionString = apply ? process.env["NEON_DATABASE_ADMIN_URL"] : process.env["NEON_DATABASE_URL"];
|
|
144
|
+
if (connectionString === undefined) {
|
|
145
|
+
printUsage();
|
|
146
|
+
return Result.Err(`${apply ? "NEON_DATABASE_ADMIN_URL" : "NEON_DATABASE_URL"} is required (set in .dev.vars or env)`);
|
|
147
|
+
}
|
|
148
|
+
const pool = new Pool({ connectionString });
|
|
149
|
+
const result = await exception2Result(async () => {
|
|
150
|
+
const rows = await discover(pool);
|
|
151
|
+
console.log(`${rows.length} live handle avatar(s)\n`);
|
|
152
|
+
const planned = [];
|
|
153
|
+
let skipped = 0;
|
|
154
|
+
for (const row of rows) {
|
|
155
|
+
if (row.mimeType === "image/webp" && row.size <= AVATAR_MAX_BYTES) {
|
|
156
|
+
skipped += 1;
|
|
157
|
+
console.log(`SKIP @${row.handle} already normalized webp (${kb(row.size)})`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const rBytes = await fetchAvatarBytes(base, row);
|
|
161
|
+
if (rBytes.isErr()) {
|
|
162
|
+
console.log(`ERROR @${row.handle} ${formatError(rBytes.Err())}`);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
const rNew = await transform(rBytes.Ok());
|
|
166
|
+
if (rNew.isErr()) {
|
|
167
|
+
console.log(`ERROR @${row.handle} transform failed: ${formatError(rNew.Err())}`);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const newBytes = rNew.Ok();
|
|
171
|
+
const newCid = contentCid(newBytes);
|
|
172
|
+
planned.push({ row, newBytes, newCid, newGetURL: `s3://r2/${newCid}` });
|
|
173
|
+
const pct = ((1 - newBytes.byteLength / row.size) * 100).toFixed(1);
|
|
174
|
+
console.log(`PLAN @${row.handle} ${row.mimeType} ${kb(row.size)} -> webp ${kb(newBytes.byteLength)} (-${pct}%) cid ${newCid}`);
|
|
175
|
+
}
|
|
176
|
+
const oldTotal = planned.reduce((a, w) => a + w.row.size, 0);
|
|
177
|
+
const newTotal = planned.reduce((a, w) => a + w.newBytes.byteLength, 0);
|
|
178
|
+
console.log(`\n${planned.length} to transform, ${skipped} already normalized. ${kb(oldTotal)} -> ${kb(newTotal)}`);
|
|
179
|
+
if (!apply) {
|
|
180
|
+
console.log("\nDry run — nothing written. Re-run with --apply for the write pass.");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const stamp = new Date().toISOString().slice(0, 10);
|
|
184
|
+
let ok = 0;
|
|
185
|
+
for (const work of planned) {
|
|
186
|
+
const r = await applyOne(pool, base, work, stamp);
|
|
187
|
+
if (r.isErr()) {
|
|
188
|
+
console.log(`FAIL @${work.row.handle} ${formatError(r.Err())}`);
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
ok += 1;
|
|
192
|
+
console.log(`DONE @${work.row.handle} now ${work.newGetURL}`);
|
|
193
|
+
}
|
|
194
|
+
console.log(`\nApplied ${ok}/${planned.length}.`);
|
|
195
|
+
});
|
|
196
|
+
await pool.end();
|
|
197
|
+
if (result.isErr())
|
|
198
|
+
return Result.Err(result.Err());
|
|
199
|
+
return Result.Ok(undefined);
|
|
200
|
+
}
|
|
201
|
+
run().then((r) => {
|
|
202
|
+
if (r.isErr()) {
|
|
203
|
+
console.error(formatError(r.Err()));
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
//# sourceMappingURL=backfill-avatars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backfill-avatars.js","sourceRoot":"","sources":["../../jsr/usage-report/backfill-avatars.ts"],"names":[],"mappings":"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"}
|