@supabase/lite 0.8.0 → 0.8.1-next.2
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/LIMITATIONS.md +17 -4
- package/PATTERNS.md +22 -1
- package/README.md +50 -6
- package/STATUS.md +49 -23
- package/dist/{Connection-D9UUTsjg.d.ts → Connection-ZWTDByQ5.d.ts} +27 -0
- package/dist/cli/index.js +177 -139
- package/dist/cli/lib.d.ts +59 -6
- package/dist/cli/lib.js +48 -45
- package/dist/db/bun/index.d.ts +1 -0
- package/dist/db/bun/index.js +2 -2
- package/dist/db/fallback.d.ts +1 -1
- package/dist/db/node/index.d.ts +1 -0
- package/dist/db/node/index.js +2 -2
- package/dist/db/postgres/pglite/PgliteConnection.js +22 -22
- package/dist/db/workerd/index.d.ts +2 -0
- package/dist/db/workerd/index.js +2 -2
- package/dist/{index-xv_pDjEt.d.ts → index-DKO3OQpz.d.ts} +42 -0
- package/dist/index.d.ts +403 -484
- package/dist/index.js +99 -67
- package/dist/static/.vite/manifest.json +2 -2
- package/dist/static/assets/{main-DO_xnvTw.js → main-1bwWb_1q.js} +100 -17
- package/dist/static/assets/{main-BITGMylP.css → main-BDsRycsc.css} +39 -0
- package/dist/vite/index.d.ts +326 -479
- package/dist/vite/index.js +2 -2
- package/package.json +7 -5
- package/skills/supalite/SKILL.md +1 -1
|
@@ -28220,9 +28220,7 @@ function Studio({
|
|
|
28220
28220
|
),
|
|
28221
28221
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Button$1, { type: "dashed", className: "h-[28px] px-1.5", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Funnel, {}) })
|
|
28222
28222
|
] }),
|
|
28223
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col grow gap-0", children: entities?.filter(
|
|
28224
|
-
(entity) => entity.schema === selectedSchema || selectedSchema === "public" && entity.schema === ""
|
|
28225
|
-
).map((entity) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28223
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col grow gap-0", children: entities?.filter((entity) => entity.schema === selectedSchema).map((entity) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
28226
28224
|
EntityListItem,
|
|
28227
28225
|
{
|
|
28228
28226
|
id: entityActiveId,
|
|
@@ -40342,15 +40340,82 @@ function shouldShowDeprecationWarning() {
|
|
|
40342
40340
|
return parseInt(versionMatch[1], 10) <= 18;
|
|
40343
40341
|
}
|
|
40344
40342
|
if (shouldShowDeprecationWarning()) console.warn("⚠️ Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
40343
|
+
const STRIPPED_HEADERS = ["apikey", "authorization"];
|
|
40344
|
+
function studioAuth(runtime) {
|
|
40345
|
+
if (runtime.admin) {
|
|
40346
|
+
return { mode: "admin", key: "...", fetch: keylessFetch };
|
|
40347
|
+
}
|
|
40348
|
+
if (runtime.publishableKey) {
|
|
40349
|
+
return { mode: "restricted", key: runtime.publishableKey };
|
|
40350
|
+
}
|
|
40351
|
+
return {
|
|
40352
|
+
mode: "unavailable",
|
|
40353
|
+
reason: "Admin mode is off and no publishable key is configured, so studio has no credential it can use from the browser. Restart without --no-admin, or add auth.publishable_key (`lite generate-keys`)."
|
|
40354
|
+
};
|
|
40355
|
+
}
|
|
40356
|
+
const keylessFetch = (input, init) => {
|
|
40357
|
+
if (input instanceof Request) {
|
|
40358
|
+
const request = new Request(input, init);
|
|
40359
|
+
for (const name of STRIPPED_HEADERS) request.headers.delete(name);
|
|
40360
|
+
return fetch(request);
|
|
40361
|
+
}
|
|
40362
|
+
const headers = new Headers(init?.headers);
|
|
40363
|
+
for (const name of STRIPPED_HEADERS) headers.delete(name);
|
|
40364
|
+
return fetch(input, { ...init, headers });
|
|
40365
|
+
};
|
|
40345
40366
|
const StudioContext = reactExports.createContext({});
|
|
40346
40367
|
function StudioProvider({
|
|
40347
40368
|
children,
|
|
40348
40369
|
baseUrl,
|
|
40349
40370
|
anonKey
|
|
40350
40371
|
}) {
|
|
40351
|
-
const api = hc(baseUrl);
|
|
40352
|
-
const
|
|
40353
|
-
|
|
40372
|
+
const api = reactExports.useMemo(() => hc(baseUrl), [baseUrl]);
|
|
40373
|
+
const [runtime, setRuntime] = reactExports.useState(null);
|
|
40374
|
+
reactExports.useEffect(() => {
|
|
40375
|
+
let cancelled = false;
|
|
40376
|
+
void (async () => {
|
|
40377
|
+
try {
|
|
40378
|
+
const res = await fetch(`${baseUrl}/_system/info`);
|
|
40379
|
+
const info = await res.json();
|
|
40380
|
+
if (!cancelled) {
|
|
40381
|
+
setRuntime({
|
|
40382
|
+
admin: info.admin === true,
|
|
40383
|
+
publishableKey: anonKey ?? info.config?.auth?.publishable_key
|
|
40384
|
+
});
|
|
40385
|
+
}
|
|
40386
|
+
} catch {
|
|
40387
|
+
if (!cancelled) setRuntime({ admin: false, publishableKey: anonKey });
|
|
40388
|
+
}
|
|
40389
|
+
})();
|
|
40390
|
+
return () => {
|
|
40391
|
+
cancelled = true;
|
|
40392
|
+
};
|
|
40393
|
+
}, [baseUrl, anonKey]);
|
|
40394
|
+
const value = reactExports.useMemo(() => {
|
|
40395
|
+
if (!runtime) return null;
|
|
40396
|
+
const auth = studioAuth(runtime);
|
|
40397
|
+
if (auth.mode === "unavailable") return { unavailable: auth.reason };
|
|
40398
|
+
const client2 = createClient(baseUrl, auth.key, {
|
|
40399
|
+
...auth.mode === "admin" ? { global: { fetch: auth.fetch } } : {},
|
|
40400
|
+
// Studio shares an origin with the user's app under `lite dev`;
|
|
40401
|
+
// picking their session out of localStorage would attach a user JWT
|
|
40402
|
+
// and silently opt studio out of admin elevation.
|
|
40403
|
+
auth: {
|
|
40404
|
+
persistSession: false,
|
|
40405
|
+
autoRefreshToken: false,
|
|
40406
|
+
detectSessionInUrl: false
|
|
40407
|
+
}
|
|
40408
|
+
});
|
|
40409
|
+
return { api, client: client2, restricted: auth.mode === "restricted" };
|
|
40410
|
+
}, [api, baseUrl, runtime]);
|
|
40411
|
+
if (!value) return null;
|
|
40412
|
+
if ("unavailable" in value) {
|
|
40413
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mx-auto max-w-xl p-8 text-sm text-foreground-light", children: [
|
|
40414
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "pb-2 text-base text-foreground", children: "Studio is unavailable" }),
|
|
40415
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: value.unavailable })
|
|
40416
|
+
] });
|
|
40417
|
+
}
|
|
40418
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(StudioContext.Provider, { value, children });
|
|
40354
40419
|
}
|
|
40355
40420
|
function useStudioContext() {
|
|
40356
40421
|
return reactExports.useContext(StudioContext);
|
|
@@ -40358,13 +40423,24 @@ function useStudioContext() {
|
|
|
40358
40423
|
async function getDbIntrospection(api) {
|
|
40359
40424
|
return await api._system.introspect.$get().then((res) => res.json());
|
|
40360
40425
|
}
|
|
40426
|
+
const DEFAULT_SCHEMA = "public";
|
|
40427
|
+
function normalizeIntrospection(raw) {
|
|
40428
|
+
const out = { ...raw };
|
|
40429
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
40430
|
+
if (!Array.isArray(value)) continue;
|
|
40431
|
+
out[key] = value.map(
|
|
40432
|
+
(item) => item && typeof item === "object" && "schema" in item && !item.schema ? { ...item, schema: DEFAULT_SCHEMA } : item
|
|
40433
|
+
);
|
|
40434
|
+
}
|
|
40435
|
+
return out;
|
|
40436
|
+
}
|
|
40361
40437
|
function useDbInfo() {
|
|
40362
40438
|
const { api } = useStudioContext();
|
|
40363
40439
|
const [raw, setRaw] = reactExports.useState(null);
|
|
40364
40440
|
reactExports.useEffect(() => {
|
|
40365
40441
|
(async () => {
|
|
40366
40442
|
const res = await getDbIntrospection(api);
|
|
40367
|
-
setRaw(res);
|
|
40443
|
+
setRaw(normalizeIntrospection(res));
|
|
40368
40444
|
})();
|
|
40369
40445
|
}, []);
|
|
40370
40446
|
return {
|
|
@@ -40372,7 +40448,7 @@ function useDbInfo() {
|
|
|
40372
40448
|
entities: raw?.tables?.map((table, index2) => ({
|
|
40373
40449
|
id: index2,
|
|
40374
40450
|
name: table.name,
|
|
40375
|
-
schema: table.schema
|
|
40451
|
+
schema: table.schema,
|
|
40376
40452
|
type: "r"
|
|
40377
40453
|
}))
|
|
40378
40454
|
};
|
|
@@ -40710,7 +40786,7 @@ function Impl() {
|
|
|
40710
40786
|
const [selectedEntity, setSelectedEntity] = reactExports.useState(void 0);
|
|
40711
40787
|
const [rows, setRows] = reactExports.useState([]);
|
|
40712
40788
|
const [columns, setColumns] = reactExports.useState([]);
|
|
40713
|
-
const { client: client2 } = useStudioContext();
|
|
40789
|
+
const { client: client2, restricted } = useStudioContext();
|
|
40714
40790
|
const [insertPanelOpen, setInsertPanelOpen] = reactExports.useState(false);
|
|
40715
40791
|
const [insertLoading, setInsertLoading] = reactExports.useState(false);
|
|
40716
40792
|
const [insertValues, setInsertValues] = reactExports.useState({});
|
|
@@ -40776,7 +40852,7 @@ function Impl() {
|
|
|
40776
40852
|
window.alert("No entity selected, cannot insert row");
|
|
40777
40853
|
return;
|
|
40778
40854
|
}
|
|
40779
|
-
const tableSchema = selectedEntity.schema
|
|
40855
|
+
const tableSchema = selectedEntity.schema || schema;
|
|
40780
40856
|
setInsertLoading(true);
|
|
40781
40857
|
try {
|
|
40782
40858
|
const { data, error } = await client2.schema(tableSchema).from(selectedEntity.name).insert(payload).select("*");
|
|
@@ -40817,9 +40893,7 @@ function Impl() {
|
|
|
40817
40893
|
} else if (entity.includes(".")) {
|
|
40818
40894
|
const [schema2, table] = entity.split(".");
|
|
40819
40895
|
console.log("entities", entities);
|
|
40820
|
-
setSelectedEntity(
|
|
40821
|
-
entities?.find((e) => e.name === table && (e.schema === schema2 || e.schema === ""))
|
|
40822
|
-
);
|
|
40896
|
+
setSelectedEntity(entities?.find((e) => e.name === table && e.schema === schema2));
|
|
40823
40897
|
} else if (raw.tables.some((t) => t.schema === "public")) {
|
|
40824
40898
|
setSelectedEntity(entities?.find((e) => e.name === entity));
|
|
40825
40899
|
}
|
|
@@ -40850,6 +40924,18 @@ function Impl() {
|
|
|
40850
40924
|
Boolean
|
|
40851
40925
|
);
|
|
40852
40926
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
40927
|
+
restricted && // Admin mode off → studio authenticates as `anon`, so RLS applies
|
|
40928
|
+
// and rows/writes the policies hide will simply be missing. Say so,
|
|
40929
|
+
// rather than letting it look like an empty or broken table.
|
|
40930
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-b border-amber-600/40 bg-amber-500/10 px-4 py-2 text-sm text-foreground-light", children: [
|
|
40931
|
+
"Admin mode is off, so studio is connected with the publishable key and sees only what",
|
|
40932
|
+
" ",
|
|
40933
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "font-mono", children: "anon" }),
|
|
40934
|
+
" may see under RLS. Restart without",
|
|
40935
|
+
" ",
|
|
40936
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "font-mono", children: "--no-admin" }),
|
|
40937
|
+
" for full access."
|
|
40938
|
+
] }),
|
|
40853
40939
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
40854
40940
|
SidePanel,
|
|
40855
40941
|
{
|
|
@@ -40895,10 +40981,7 @@ function Impl() {
|
|
|
40895
40981
|
onOpenInsertPanel: () => setInsertPanelOpen(true),
|
|
40896
40982
|
onEntityClick: (entity2) => {
|
|
40897
40983
|
setSelectedEntity(entity2);
|
|
40898
|
-
const path = [
|
|
40899
|
-
entity2.schema && entity2.schema.length > 0 ? entity2.schema : "public",
|
|
40900
|
-
entity2.name
|
|
40901
|
-
].filter(Boolean).join(".");
|
|
40984
|
+
const path = [entity2.schema, entity2.name].filter(Boolean).join(".");
|
|
40902
40985
|
navigate2(`/${path}`);
|
|
40903
40986
|
},
|
|
40904
40987
|
schema,
|
|
@@ -132,6 +132,8 @@
|
|
|
132
132
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
133
133
|
"Courier New", monospace;
|
|
134
134
|
--color-red-500: oklch(63.7% .237 25.331);
|
|
135
|
+
--color-amber-500: oklch(76.9% .188 70.08);
|
|
136
|
+
--color-amber-600: oklch(66.6% .179 58.318);
|
|
135
137
|
--color-amber-700: oklch(55.5% .163 48.998);
|
|
136
138
|
--color-yellow-500: oklch(79.5% .184 86.047);
|
|
137
139
|
--color-yellow-900: oklch(42.1% .095 57.708);
|
|
@@ -139,6 +141,7 @@
|
|
|
139
141
|
--color-purple-500: oklch(62.7% .265 303.9);
|
|
140
142
|
--spacing: .25rem;
|
|
141
143
|
--container-md: 28rem;
|
|
144
|
+
--container-xl: 36rem;
|
|
142
145
|
--container-2xl: 42rem;
|
|
143
146
|
--container-3xl: 48rem;
|
|
144
147
|
--container-4xl: 56rem;
|
|
@@ -653,6 +656,10 @@
|
|
|
653
656
|
margin-inline: 2px;
|
|
654
657
|
}
|
|
655
658
|
|
|
659
|
+
.mx-auto {
|
|
660
|
+
margin-inline: auto;
|
|
661
|
+
}
|
|
662
|
+
|
|
656
663
|
.my-0\.5 {
|
|
657
664
|
margin-block: calc(var(--spacing) * .5);
|
|
658
665
|
}
|
|
@@ -1067,6 +1074,10 @@
|
|
|
1067
1074
|
max-width: 100vw;
|
|
1068
1075
|
}
|
|
1069
1076
|
|
|
1077
|
+
.max-w-xl {
|
|
1078
|
+
max-width: var(--container-xl);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1070
1081
|
.min-w-0 {
|
|
1071
1082
|
min-width: calc(var(--spacing) * 0);
|
|
1072
1083
|
}
|
|
@@ -1361,6 +1372,16 @@
|
|
|
1361
1372
|
border-style: dashed;
|
|
1362
1373
|
}
|
|
1363
1374
|
|
|
1375
|
+
.border-amber-600\/40 {
|
|
1376
|
+
border-color: #dd740066;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1380
|
+
.border-amber-600\/40 {
|
|
1381
|
+
border-color: color-mix(in oklab, var(--color-amber-600) 40%, transparent);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1364
1385
|
.border-border-default {
|
|
1365
1386
|
border-color: var(--color-border-default);
|
|
1366
1387
|
}
|
|
@@ -1419,6 +1440,16 @@
|
|
|
1419
1440
|
background-color: var(--color-background-alternative);
|
|
1420
1441
|
}
|
|
1421
1442
|
|
|
1443
|
+
.bg-amber-500\/10 {
|
|
1444
|
+
background-color: #f99c001a;
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1448
|
+
.bg-amber-500\/10 {
|
|
1449
|
+
background-color: color-mix(in oklab, var(--color-amber-500) 10%, transparent);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1422
1453
|
.bg-background {
|
|
1423
1454
|
background-color: var(--color-background);
|
|
1424
1455
|
}
|
|
@@ -1547,6 +1578,10 @@
|
|
|
1547
1578
|
padding: calc(var(--spacing) * 4);
|
|
1548
1579
|
}
|
|
1549
1580
|
|
|
1581
|
+
.p-8 {
|
|
1582
|
+
padding: calc(var(--spacing) * 8);
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1550
1585
|
.px-1 {
|
|
1551
1586
|
padding-inline: calc(var(--spacing) * 1);
|
|
1552
1587
|
}
|
|
@@ -1643,6 +1678,10 @@
|
|
|
1643
1678
|
padding-right: calc(var(--spacing) * 7);
|
|
1644
1679
|
}
|
|
1645
1680
|
|
|
1681
|
+
.pb-2 {
|
|
1682
|
+
padding-bottom: calc(var(--spacing) * 2);
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1646
1685
|
.pb-4 {
|
|
1647
1686
|
padding-bottom: calc(var(--spacing) * 4);
|
|
1648
1687
|
}
|