@supacloud/lite 0.5.7 → 0.5.8
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/CHANGELOG.md +7 -0
- package/dist/cli.js +37 -2
- package/dist/index.js +37 -2
- package/dist/runtime/storage/handler.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.8](https://github.com/zuohuadong/supacloud/compare/supacloud-lite-v0.5.7...supacloud-lite-v0.5.8) (2026-08-05)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **lite:** actionable hint when storage upload is denied by RLS ([2de9601](https://github.com/zuohuadong/supacloud/commit/2de96016c802f43a588e22e4dacc91d4efdaa1f3))
|
|
9
|
+
|
|
3
10
|
## [0.5.7](https://github.com/zuohuadong/supacloud/compare/supacloud-lite-v0.5.6...supacloud-lite-v0.5.7) (2026-08-05)
|
|
4
11
|
|
|
5
12
|
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { dirname as dirname5, join as join9, resolve as resolve4 } from "path";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@supacloud/lite",
|
|
11
|
-
version: "0.5.
|
|
11
|
+
version: "0.5.8",
|
|
12
12
|
description: "Bun-native, single-project Supabase-compatible backend powered by PGlite",
|
|
13
13
|
type: "module",
|
|
14
14
|
license: "Apache-2.0",
|
|
@@ -6002,6 +6002,29 @@ function invalidObjectKey(key) {
|
|
|
6002
6002
|
function storageError(status, error, message) {
|
|
6003
6003
|
return json3(status, { statusCode: String(status), error, message });
|
|
6004
6004
|
}
|
|
6005
|
+
var RLS_POLICY_HINT = "Upload denied by storage.objects RLS. Create a policy in supabase/migrations, e.g. " + "`create policy \"objects insert\" on storage.objects for insert to authenticated with check (bucket_id = '<bucket>');`. " + "Without a policy, RLS blocks every write by default.";
|
|
6006
|
+
|
|
6007
|
+
class RlsPolicyError extends Error {
|
|
6008
|
+
cause;
|
|
6009
|
+
constructor(cause) {
|
|
6010
|
+
super("storage.objects row-level security policy denied the write");
|
|
6011
|
+
this.cause = cause;
|
|
6012
|
+
this.name = "RlsPolicyError";
|
|
6013
|
+
}
|
|
6014
|
+
}
|
|
6015
|
+
function rlsDeniedResponse() {
|
|
6016
|
+
return storageError(403, "Unauthorized", RLS_POLICY_HINT);
|
|
6017
|
+
}
|
|
6018
|
+
function isRlsDenied(error) {
|
|
6019
|
+
if (!error)
|
|
6020
|
+
return false;
|
|
6021
|
+
const pg = error;
|
|
6022
|
+
if (pg.code === "42501")
|
|
6023
|
+
return true;
|
|
6024
|
+
if (error instanceof Error && /row-level security|permission denied/i.test(error.message))
|
|
6025
|
+
return true;
|
|
6026
|
+
return false;
|
|
6027
|
+
}
|
|
6005
6028
|
function json3(status, body) {
|
|
6006
6029
|
return new Response(JSON.stringify(body), {
|
|
6007
6030
|
status,
|
|
@@ -6287,6 +6310,8 @@ class StorageHandler {
|
|
|
6287
6310
|
const id = await this.persistObject(ctx, bucketId, key, bytes, contentType, cacheControl, upsert);
|
|
6288
6311
|
return json3(200, { Key: `${bucketId}/${key}`, Id: id });
|
|
6289
6312
|
} catch (e) {
|
|
6313
|
+
if (e instanceof RlsPolicyError)
|
|
6314
|
+
return rlsDeniedResponse();
|
|
6290
6315
|
const pg = e;
|
|
6291
6316
|
if (pg.code === "23505") {
|
|
6292
6317
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
@@ -6324,6 +6349,12 @@ class StorageHandler {
|
|
|
6324
6349
|
values ($1, $2, $3, $4, $5::jsonb, $6) ${conflictClause} returning *`, [objectId, bucketId, key, ctx.claims?.sub ?? null, JSON.stringify(metadata), version]));
|
|
6325
6350
|
inserted = result.rows[0];
|
|
6326
6351
|
} catch (error) {
|
|
6352
|
+
if (isRlsDenied(error)) {
|
|
6353
|
+
try {
|
|
6354
|
+
await this.driver.delete(stagedKey);
|
|
6355
|
+
} catch {}
|
|
6356
|
+
throw new RlsPolicyError(error);
|
|
6357
|
+
}
|
|
6327
6358
|
await this.discardStagedBytes(stagedKey, error);
|
|
6328
6359
|
}
|
|
6329
6360
|
if (!inserted)
|
|
@@ -6381,6 +6412,8 @@ class StorageHandler {
|
|
|
6381
6412
|
try {
|
|
6382
6413
|
await this.persistObject(ctx, bucketId, key, new Uint8Array, contentType, meta.cacheControl ?? "no-cache", upsert);
|
|
6383
6414
|
} catch (error) {
|
|
6415
|
+
if (error instanceof RlsPolicyError)
|
|
6416
|
+
return rlsDeniedResponse();
|
|
6384
6417
|
const pg = error;
|
|
6385
6418
|
if (pg.code === "23505")
|
|
6386
6419
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
@@ -6511,6 +6544,8 @@ class StorageHandler {
|
|
|
6511
6544
|
await this.persistObject(upload.ctx, upload.bucketId, upload.key, data, upload.contentType, upload.cacheControl, upload.upsert);
|
|
6512
6545
|
} catch (e) {
|
|
6513
6546
|
this.tusUploads.delete(id);
|
|
6547
|
+
if (e instanceof RlsPolicyError)
|
|
6548
|
+
return rlsDeniedResponse();
|
|
6514
6549
|
const pg = e;
|
|
6515
6550
|
if (pg.code === "23505")
|
|
6516
6551
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
@@ -6556,7 +6591,7 @@ class StorageHandler {
|
|
|
6556
6591
|
if (pg.code === "23505")
|
|
6557
6592
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
6558
6593
|
if (pg.code === "42501" || error instanceof Error && /row-level security|permission denied/i.test(error.message)) {
|
|
6559
|
-
return
|
|
6594
|
+
return rlsDeniedResponse();
|
|
6560
6595
|
}
|
|
6561
6596
|
throw error;
|
|
6562
6597
|
}
|
package/dist/index.js
CHANGED
|
@@ -71,7 +71,7 @@ function randomToken(bytes = 32) {
|
|
|
71
71
|
// package.json
|
|
72
72
|
var package_default = {
|
|
73
73
|
name: "@supacloud/lite",
|
|
74
|
-
version: "0.5.
|
|
74
|
+
version: "0.5.8",
|
|
75
75
|
description: "Bun-native, single-project Supabase-compatible backend powered by PGlite",
|
|
76
76
|
type: "module",
|
|
77
77
|
license: "Apache-2.0",
|
|
@@ -6007,6 +6007,29 @@ function invalidObjectKey(key) {
|
|
|
6007
6007
|
function storageError(status, error, message) {
|
|
6008
6008
|
return json3(status, { statusCode: String(status), error, message });
|
|
6009
6009
|
}
|
|
6010
|
+
var RLS_POLICY_HINT = "Upload denied by storage.objects RLS. Create a policy in supabase/migrations, e.g. " + "`create policy \"objects insert\" on storage.objects for insert to authenticated with check (bucket_id = '<bucket>');`. " + "Without a policy, RLS blocks every write by default.";
|
|
6011
|
+
|
|
6012
|
+
class RlsPolicyError extends Error {
|
|
6013
|
+
cause;
|
|
6014
|
+
constructor(cause) {
|
|
6015
|
+
super("storage.objects row-level security policy denied the write");
|
|
6016
|
+
this.cause = cause;
|
|
6017
|
+
this.name = "RlsPolicyError";
|
|
6018
|
+
}
|
|
6019
|
+
}
|
|
6020
|
+
function rlsDeniedResponse() {
|
|
6021
|
+
return storageError(403, "Unauthorized", RLS_POLICY_HINT);
|
|
6022
|
+
}
|
|
6023
|
+
function isRlsDenied(error) {
|
|
6024
|
+
if (!error)
|
|
6025
|
+
return false;
|
|
6026
|
+
const pg = error;
|
|
6027
|
+
if (pg.code === "42501")
|
|
6028
|
+
return true;
|
|
6029
|
+
if (error instanceof Error && /row-level security|permission denied/i.test(error.message))
|
|
6030
|
+
return true;
|
|
6031
|
+
return false;
|
|
6032
|
+
}
|
|
6010
6033
|
function json3(status, body) {
|
|
6011
6034
|
return new Response(JSON.stringify(body), {
|
|
6012
6035
|
status,
|
|
@@ -6292,6 +6315,8 @@ class StorageHandler {
|
|
|
6292
6315
|
const id = await this.persistObject(ctx, bucketId, key, bytes, contentType, cacheControl, upsert);
|
|
6293
6316
|
return json3(200, { Key: `${bucketId}/${key}`, Id: id });
|
|
6294
6317
|
} catch (e) {
|
|
6318
|
+
if (e instanceof RlsPolicyError)
|
|
6319
|
+
return rlsDeniedResponse();
|
|
6295
6320
|
const pg = e;
|
|
6296
6321
|
if (pg.code === "23505") {
|
|
6297
6322
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
@@ -6329,6 +6354,12 @@ class StorageHandler {
|
|
|
6329
6354
|
values ($1, $2, $3, $4, $5::jsonb, $6) ${conflictClause} returning *`, [objectId, bucketId, key, ctx.claims?.sub ?? null, JSON.stringify(metadata), version]));
|
|
6330
6355
|
inserted = result.rows[0];
|
|
6331
6356
|
} catch (error) {
|
|
6357
|
+
if (isRlsDenied(error)) {
|
|
6358
|
+
try {
|
|
6359
|
+
await this.driver.delete(stagedKey);
|
|
6360
|
+
} catch {}
|
|
6361
|
+
throw new RlsPolicyError(error);
|
|
6362
|
+
}
|
|
6332
6363
|
await this.discardStagedBytes(stagedKey, error);
|
|
6333
6364
|
}
|
|
6334
6365
|
if (!inserted)
|
|
@@ -6386,6 +6417,8 @@ class StorageHandler {
|
|
|
6386
6417
|
try {
|
|
6387
6418
|
await this.persistObject(ctx, bucketId, key, new Uint8Array, contentType, meta.cacheControl ?? "no-cache", upsert);
|
|
6388
6419
|
} catch (error) {
|
|
6420
|
+
if (error instanceof RlsPolicyError)
|
|
6421
|
+
return rlsDeniedResponse();
|
|
6389
6422
|
const pg = error;
|
|
6390
6423
|
if (pg.code === "23505")
|
|
6391
6424
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
@@ -6516,6 +6549,8 @@ class StorageHandler {
|
|
|
6516
6549
|
await this.persistObject(upload.ctx, upload.bucketId, upload.key, data, upload.contentType, upload.cacheControl, upload.upsert);
|
|
6517
6550
|
} catch (e) {
|
|
6518
6551
|
this.tusUploads.delete(id);
|
|
6552
|
+
if (e instanceof RlsPolicyError)
|
|
6553
|
+
return rlsDeniedResponse();
|
|
6519
6554
|
const pg = e;
|
|
6520
6555
|
if (pg.code === "23505")
|
|
6521
6556
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
@@ -6561,7 +6596,7 @@ class StorageHandler {
|
|
|
6561
6596
|
if (pg.code === "23505")
|
|
6562
6597
|
return storageError(409, "Duplicate", "The resource already exists");
|
|
6563
6598
|
if (pg.code === "42501" || error instanceof Error && /row-level security|permission denied/i.test(error.message)) {
|
|
6564
|
-
return
|
|
6599
|
+
return rlsDeniedResponse();
|
|
6565
6600
|
}
|
|
6566
6601
|
throw error;
|
|
6567
6602
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/runtime/storage/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAQjD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE5E,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB,0GAA0G;IAC1G,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uFAAuF;IACvF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/runtime/storage/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAQjD,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE5E,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAA;IACjB,0GAA0G;IAC1G,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uFAAuF;IACvF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AAmID,qEAAqE;AACrE,qBAAa,cAAc;IAKvB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,YAAY,CAAoB;gBAG9B,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,aAAa;IAG/B,4FAA4F;IACtF,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAazD,8GAA8G;IACxG,MAAM,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;YA6G9D,YAAY;IAgB1B,OAAO,CAAC,cAAc;YAOR,YAAY;YA2BZ,WAAW;YAKX,SAAS;YAMT,YAAY;YAqBZ,YAAY;YAYZ,WAAW;YAUX,UAAU;YAKV,MAAM;YA0DN,sBAAsB;IAgBpC,gFAAgF;YAClE,aAAa;YAiDb,SAAS;IA8KvB,2EAA2E;YAC7D,SAAS;IA2CvB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,sBAAsB;YAMhB,oBAAoB;YA2CpB,QAAQ;YASR,cAAc;YAYd,WAAW;YAoBX,aAAa;YAeb,SAAS;YAUT,UAAU;YAuEV,gBAAgB;YAUhB,kBAAkB;YASlB,eAAe;YAKf,iBAAiB;YAcjB,WAAW;YAsDX,UAAU;YAyBV,OAAO;YAmBP,QAAQ;YAiBR,eAAe;YAef,aAAa;YAab,kBAAkB;IAehC,OAAO,CAAC,aAAa;CAUtB;AAsHD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,UAAU,CAAA;CACjB;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE,CAqCnF"}
|