@kozou/svelte-ui 1.2.0 → 1.3.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/build/client/_app/immutable/chunks/{M-rQODG_.js → BLwQsTD2.js} +1 -1
- package/build/client/_app/immutable/chunks/BLwQsTD2.js.br +0 -0
- package/build/client/_app/immutable/chunks/BLwQsTD2.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{CrTaJnzY.js → DY0oakY5.js} +1 -1
- package/build/client/_app/immutable/chunks/DY0oakY5.js.br +0 -0
- package/build/client/_app/immutable/chunks/DY0oakY5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/rPPoD7Sp.js +4 -0
- package/build/client/_app/immutable/chunks/rPPoD7Sp.js.br +0 -0
- package/build/client/_app/immutable/chunks/rPPoD7Sp.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.ByhtJ88k.js → app.G2Y8IfhN.js} +2 -2
- package/build/client/_app/immutable/entry/app.G2Y8IfhN.js.br +0 -0
- package/build/client/_app/immutable/entry/app.G2Y8IfhN.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.sPBaDl_M.js +1 -0
- package/build/client/_app/immutable/entry/start.sPBaDl_M.js.br +1 -0
- package/build/client/_app/immutable/entry/start.sPBaDl_M.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.BI5dO6h8.js → 1.D09foNRb.js} +1 -1
- package/build/client/_app/immutable/nodes/1.D09foNRb.js.br +2 -0
- package/build/client/_app/immutable/nodes/1.D09foNRb.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.5H5WIc-o.js +1 -0
- package/build/client/_app/immutable/nodes/4.5H5WIc-o.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.5H5WIc-o.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{5.CEXAqzYO.js → 5.BR2iBXwV.js} +1 -1
- package/build/client/_app/immutable/nodes/5.BR2iBXwV.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.BR2iBXwV.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.4fTWRTA8.js → 6.ChubZePh.js} +1 -1
- package/build/client/_app/immutable/nodes/6.ChubZePh.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.ChubZePh.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{1-CVLmaMi2.js → 1-BvxsIwwy.js} +3 -3
- package/build/server/chunks/{1-CVLmaMi2.js.map → 1-BvxsIwwy.js.map} +1 -1
- package/build/server/chunks/{4-Dc-NPvAO.js → 4-1chJCfPL.js} +5 -3
- package/build/server/chunks/4-1chJCfPL.js.map +1 -0
- package/build/server/chunks/{5-DvwPrYwd.js → 5-DUCxshKE.js} +13 -11
- package/build/server/chunks/5-DUCxshKE.js.map +1 -0
- package/build/server/chunks/{6-DxT9TB6A.js → 6-Dh7Tg-XB.js} +13 -11
- package/build/server/chunks/6-Dh7Tg-XB.js.map +1 -0
- package/build/server/chunks/{_page.svelte-DvcE6zrM.js → _page.svelte-CBUJNhG1.js} +6 -6
- package/build/server/chunks/{_page.svelte-DvcE6zrM.js.map → _page.svelte-CBUJNhG1.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-BGxCzjmZ.js → _page.svelte-DI_FY3zW.js} +6 -6
- package/build/server/chunks/{_page.svelte-BGxCzjmZ.js.map → _page.svelte-DI_FY3zW.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-FkcquIeL.js → _page.svelte-DaJwoT9F.js} +9 -4
- package/build/server/chunks/_page.svelte-DaJwoT9F.js.map +1 -0
- package/build/server/chunks/{app-DST8OmzT.js → app-MIcRQ3KA.js} +2 -2
- package/build/server/chunks/{app-DST8OmzT.js.map → app-MIcRQ3KA.js.map} +1 -1
- package/build/server/chunks/{client-BfR0iysy.js → client-C004jkBy.js} +3 -3
- package/build/server/chunks/{client-BfR0iysy.js.map → client-C004jkBy.js.map} +1 -1
- package/build/server/chunks/{composite-form-DeAbT97s.js → composite-form-_tg7iknp.js} +40 -27
- package/build/server/chunks/{composite-form-DeAbT97s.js.map → composite-form-_tg7iknp.js.map} +1 -1
- package/build/server/chunks/{error.svelte-CgmjtCM8.js → error.svelte-u8Vsq8vF.js} +6 -6
- package/build/server/chunks/{error.svelte-CgmjtCM8.js.map → error.svelte-u8Vsq8vF.js.map} +1 -1
- package/build/server/chunks/{hooks.server-BCX7tjO4.js → hooks.server-DtCXcOVD.js} +113 -7
- package/build/server/chunks/hooks.server-DtCXcOVD.js.map +1 -0
- package/build/server/chunks/index-5kYmxIr9.js.map +1 -1
- package/build/server/chunks/index-DBqjc0Yf.js.map +1 -1
- package/build/server/chunks/{internal-D3PcExp3.js → internal-fxcuSPWe.js} +13 -13
- package/build/server/chunks/{internal-D3PcExp3.js.map → internal-fxcuSPWe.js.map} +1 -1
- package/build/server/chunks/{widget-registry-COKz4xxc.js → widget-registry-BcgMXjkA.js} +2 -2
- package/build/server/chunks/{widget-registry-COKz4xxc.js.map → widget-registry-BcgMXjkA.js.map} +1 -1
- package/build/server/index.js +31 -31
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +5 -5
- package/build/server/manifest.js.map +1 -1
- package/package.json +4 -4
- package/build/client/_app/immutable/chunks/0-MunKvN.js +0 -4
- package/build/client/_app/immutable/chunks/0-MunKvN.js.br +0 -0
- package/build/client/_app/immutable/chunks/0-MunKvN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/CrTaJnzY.js.br +0 -0
- package/build/client/_app/immutable/chunks/CrTaJnzY.js.gz +0 -0
- package/build/client/_app/immutable/chunks/M-rQODG_.js.br +0 -0
- package/build/client/_app/immutable/chunks/M-rQODG_.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.ByhtJ88k.js.br +0 -0
- package/build/client/_app/immutable/entry/app.ByhtJ88k.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.C_VgULzk.js +0 -1
- package/build/client/_app/immutable/entry/start.C_VgULzk.js.br +0 -0
- package/build/client/_app/immutable/entry/start.C_VgULzk.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.BI5dO6h8.js.br +0 -3
- package/build/client/_app/immutable/nodes/1.BI5dO6h8.js.gz +0 -0
- package/build/client/_app/immutable/nodes/4.PUtoqAEs.js +0 -1
- package/build/client/_app/immutable/nodes/4.PUtoqAEs.js.br +0 -0
- package/build/client/_app/immutable/nodes/4.PUtoqAEs.js.gz +0 -0
- package/build/client/_app/immutable/nodes/5.CEXAqzYO.js.br +0 -0
- package/build/client/_app/immutable/nodes/5.CEXAqzYO.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.4fTWRTA8.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.4fTWRTA8.js.gz +0 -0
- package/build/server/chunks/4-Dc-NPvAO.js.map +0 -1
- package/build/server/chunks/5-DvwPrYwd.js.map +0 -1
- package/build/server/chunks/6-DxT9TB6A.js.map +0 -1
- package/build/server/chunks/_page.svelte-FkcquIeL.js.map +0 -1
- package/build/server/chunks/hooks.server-BCX7tjO4.js.map +0 -1
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import 'node:module';
|
|
2
2
|
import { q as escape_html, x as getContext } from './dev-yFiAtg5l.js';
|
|
3
|
-
import './client-
|
|
3
|
+
import './client-C004jkBy.js';
|
|
4
4
|
import 'clsx';
|
|
5
|
-
import './internal-
|
|
5
|
+
import './internal-fxcuSPWe.js';
|
|
6
6
|
import './index-DBqjc0Yf.js';
|
|
7
7
|
|
|
8
8
|
//#endregion
|
|
9
|
-
//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-
|
|
9
|
+
//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-eslin_31b35890553a27fb0d8f940d66156f76/node_modules/@sveltejs/kit/src/runtime/app/state/server.js
|
|
10
10
|
function context() {
|
|
11
11
|
return getContext("__request__");
|
|
12
12
|
}
|
|
13
13
|
//#endregion
|
|
14
|
-
//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-
|
|
14
|
+
//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-eslin_31b35890553a27fb0d8f940d66156f76/node_modules/@sveltejs/kit/src/runtime/app/state/index.js
|
|
15
15
|
/**
|
|
16
16
|
* A read-only reactive object with information about the current page, serving several use cases:
|
|
17
17
|
* - retrieving the combined `data` of all pages/layouts anywhere in your component tree (also see [loading data](https://svelte.dev/docs/kit/load))
|
|
@@ -57,7 +57,7 @@ var page = {
|
|
|
57
57
|
return context().page.status;
|
|
58
58
|
}};
|
|
59
59
|
//#endregion
|
|
60
|
-
//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-
|
|
60
|
+
//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-eslin_31b35890553a27fb0d8f940d66156f76/node_modules/@sveltejs/kit/src/runtime/components/svelte-5/error.svelte
|
|
61
61
|
function Error$1($$renderer, $$props) {
|
|
62
62
|
$$renderer.component(($$renderer) => {
|
|
63
63
|
$$renderer.push(`<h1>${escape_html(page.status)}</h1> <p>${escape_html(page.error?.message)}</p>`);
|
|
@@ -65,4 +65,4 @@ function Error$1($$renderer, $$props) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
export { Error$1 as default };
|
|
68
|
-
//# sourceMappingURL=error.svelte-
|
|
68
|
+
//# sourceMappingURL=error.svelte-u8Vsq8vF.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.svelte-
|
|
1
|
+
{"version":3,"file":"error.svelte-u8Vsq8vF.js","sources":["../../../.svelte-kit/adapter-node/entries/fallbacks/error.svelte.js"],"sourcesContent":["import \"../../chunks/environment.js\";\nimport { H as escape_html, tt as getContext } from \"../../chunks/dev.js\";\nimport { c as navigating$1, s as stores } from \"../../chunks/client.js\";\nObject.defineProperty({\n\tget from() {\n\t\treturn navigating$1.current ? navigating$1.current.from : null;\n\t},\n\tget to() {\n\t\treturn navigating$1.current ? navigating$1.current.to : null;\n\t},\n\tget type() {\n\t\treturn navigating$1.current ? navigating$1.current.type : null;\n\t},\n\tget willUnload() {\n\t\treturn navigating$1.current ? navigating$1.current.willUnload : null;\n\t},\n\tget delta() {\n\t\treturn navigating$1.current ? navigating$1.current.delta : null;\n\t},\n\tget complete() {\n\t\treturn navigating$1.current ? navigating$1.current.complete : null;\n\t}\n}, \"current\", { get() {\n\tthrow new Error(\"Replace navigating.current.<prop> with navigating.<prop>\");\n} });\nstores.updated.check;\n//#endregion\n//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-eslin_31b35890553a27fb0d8f940d66156f76/node_modules/@sveltejs/kit/src/runtime/app/state/server.js\nfunction context() {\n\treturn getContext(\"__request__\");\n}\n//#endregion\n//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-eslin_31b35890553a27fb0d8f940d66156f76/node_modules/@sveltejs/kit/src/runtime/app/state/index.js\n/**\n* A read-only reactive object with information about the current page, serving several use cases:\n* - retrieving the combined `data` of all pages/layouts anywhere in your component tree (also see [loading data](https://svelte.dev/docs/kit/load))\n* - retrieving the current value of the `form` prop anywhere in your component tree (also see [form actions](https://svelte.dev/docs/kit/form-actions))\n* - retrieving the page state that was set through `goto`, `pushState` or `replaceState` (also see [goto](https://svelte.dev/docs/kit/$app-navigation#goto) and [shallow routing](https://svelte.dev/docs/kit/shallow-routing))\n* - retrieving metadata such as the URL you're on, the current route and its parameters, and whether or not there was an error\n*\n* ```svelte\n* <!--- file: +layout.svelte --->\n* <script>\n* \timport { page } from '$app/state';\n* <\\/script>\n*\n* <p>Currently at {page.url.pathname}</p>\n*\n* {#if page.error}\n* \t<span class=\"red\">Problem detected</span>\n* {:else}\n* \t<span class=\"small\">All systems operational</span>\n* {/if}\n* ```\n*\n* Changes to `page` are available exclusively with runes. (The legacy reactivity syntax will not reflect any changes)\n*\n* ```svelte\n* <!--- file: +page.svelte --->\n* <script>\n* \timport { page } from '$app/state';\n* \tconst id = $derived(page.params.id); // This will correctly update id for usage on this page\n* \t$: badId = page.params.id; // Do not use; will never update after initial load\n* <\\/script>\n* ```\n*\n* On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time.\n*\n* @type {import('@sveltejs/kit').Page}\n*/\nvar page = {\n\tget data() {\n\t\treturn context().page.data;\n\t},\n\tget error() {\n\t\treturn context().page.error;\n\t},\n\tget form() {\n\t\treturn context().page.form;\n\t},\n\tget params() {\n\t\treturn context().page.params;\n\t},\n\tget route() {\n\t\treturn context().page.route;\n\t},\n\tget state() {\n\t\treturn context().page.state;\n\t},\n\tget status() {\n\t\treturn context().page.status;\n\t},\n\tget url() {\n\t\treturn context().page.url;\n\t}\n};\n//#endregion\n//#region ../../node_modules/.pnpm/@sveltejs+kit@2.61.1_@sveltejs+vite-plugin-svelte@7.1.2_svelte@5.55.9_@typescript-eslin_31b35890553a27fb0d8f940d66156f76/node_modules/@sveltejs/kit/src/runtime/components/svelte-5/error.svelte\nfunction Error$1($$renderer, $$props) {\n\t$$renderer.component(($$renderer) => {\n\t\t$$renderer.push(`<h1>${escape_html(page.status)}</h1> <p>${escape_html(page.error?.message)}</p>`);\n\t});\n}\n//#endregion\nexport { Error$1 as default };\n"],"names":[],"mappings":";;;;;;;AA0BA;AACA;AACA,SAAS,OAAO,GAAG;AACnB,CAAC,OAAO,UAAU,CAAC,aAAa,CAAC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,IAAI,GAAG;AACX,CAGC,IAAI,KAAK,GAAG;AACb,EAAE,OAAO,OAAO,EAAE,CAAC,IAAI,CAAC,KAAK;AAC7B,CAAC,CAAC;AACF,CAYC,IAAI,MAAM,GAAG;AACd,EAAE,OAAO,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM;AAC9B,CAAC,CAID,CAAC;AACD;AACA;AACA,SAAS,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE;AACtC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,UAAU,KAAK;AACtC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC;AACpG,CAAC,CAAC,CAAC;AACH;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as __commonJSMin, b as __require } from './internal-
|
|
1
|
+
import { _ as __commonJSMin, b as __require } from './internal-fxcuSPWe.js';
|
|
2
2
|
import { e as encodeResourceId } from './resource-id-PDcQeAnc.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import require$$0$3 from 'events';
|
|
@@ -6743,6 +6743,9 @@ function buildColumn(input) {
|
|
|
6743
6743
|
commentBody: parsed.body
|
|
6744
6744
|
});
|
|
6745
6745
|
const label = hints?.label ?? deriveLabel(column.name);
|
|
6746
|
+
const priv = column.privileges;
|
|
6747
|
+
const insertable = priv === void 0 ? void 0 : priv.insert;
|
|
6748
|
+
const updatable = priv === void 0 ? void 0 : priv.update;
|
|
6746
6749
|
return {
|
|
6747
6750
|
name: column.name,
|
|
6748
6751
|
dataType: column.dataType,
|
|
@@ -6756,7 +6759,9 @@ function buildColumn(input) {
|
|
|
6756
6759
|
policy: parsed.policy,
|
|
6757
6760
|
widget,
|
|
6758
6761
|
enumValues,
|
|
6759
|
-
readonly: hints?.readonly ?? false
|
|
6762
|
+
readonly: hints?.readonly ?? false,
|
|
6763
|
+
...insertable === void 0 ? {} : { insertable },
|
|
6764
|
+
...updatable === void 0 ? {} : { updatable }
|
|
6760
6765
|
};
|
|
6761
6766
|
}
|
|
6762
6767
|
function buildRelations(table, issues) {
|
|
@@ -6939,13 +6944,32 @@ async function buildSchemaContext(opts) {
|
|
|
6939
6944
|
message: `UIHints view "${viewName}" does not exist in raw.views`
|
|
6940
6945
|
});
|
|
6941
6946
|
}
|
|
6942
|
-
const
|
|
6947
|
+
const hiddenNames = [];
|
|
6948
|
+
const visibleRawTables = raw.tables.filter((t) => {
|
|
6949
|
+
if (t.privileges?.select === false) {
|
|
6950
|
+
hiddenNames.push(t.name);
|
|
6951
|
+
return false;
|
|
6952
|
+
}
|
|
6953
|
+
return true;
|
|
6954
|
+
});
|
|
6955
|
+
const visibleRawViews = raw.views.filter((v) => {
|
|
6956
|
+
if (v.privileges?.select === false) {
|
|
6957
|
+
hiddenNames.push(v.name);
|
|
6958
|
+
return false;
|
|
6959
|
+
}
|
|
6960
|
+
return true;
|
|
6961
|
+
});
|
|
6962
|
+
if (hiddenNames.length > 0) {
|
|
6963
|
+
const role = raw.tables.find((t) => t.privileges !== void 0)?.privileges?.role ?? raw.views.find((v) => v.privileges !== void 0)?.privileges?.role ?? "the role";
|
|
6964
|
+
console.warn(`[@kozou/core] privilege-aware introspection: hid ${hiddenNames.length} relation(s) that "${role}" cannot SELECT: ${hiddenNames.join(", ")}`);
|
|
6965
|
+
}
|
|
6966
|
+
const tables = visibleRawTables.map((t) => buildTableContext({
|
|
6943
6967
|
table: t,
|
|
6944
6968
|
hints: uiHints?.tables?.[t.name],
|
|
6945
6969
|
issues,
|
|
6946
6970
|
knownTables
|
|
6947
6971
|
}));
|
|
6948
|
-
const views =
|
|
6972
|
+
const views = visibleRawViews.map((v) => buildViewContext({
|
|
6949
6973
|
view: v,
|
|
6950
6974
|
hints: uiHints?.views?.[v.name],
|
|
6951
6975
|
issues
|
|
@@ -6956,7 +6980,7 @@ async function buildSchemaContext(opts) {
|
|
|
6956
6980
|
values: e.values,
|
|
6957
6981
|
description: null
|
|
6958
6982
|
}));
|
|
6959
|
-
const concepts =
|
|
6983
|
+
const concepts = visibleRawViews.map(buildConcept);
|
|
6960
6984
|
if (issues.length > 0) {
|
|
6961
6985
|
if (strict) throw new KozouBuildError(`buildSchemaContext: ${issues.length} validation issue(s) (strict=true)`, issues);
|
|
6962
6986
|
for (const issue of issues) console.warn(`[@kozou/core] ${issue.path}: ${issue.message}`);
|
|
@@ -13935,6 +13959,83 @@ async function fetchEnums(client, schemas) {
|
|
|
13935
13959
|
}));
|
|
13936
13960
|
}
|
|
13937
13961
|
//#endregion
|
|
13962
|
+
//#region ../introspect/dist/privileges.js
|
|
13963
|
+
var tableKey = (schema, name) => `${schema}.${name}`;
|
|
13964
|
+
/** Throw a clear error if the configured privilege role does not exist, rather
|
|
13965
|
+
* than letting `has_table_privilege` fail mid-query with a terse pg message. */
|
|
13966
|
+
async function assertRoleExists(client, role) {
|
|
13967
|
+
if ((await runQuery(client, "SELECT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = $1) AS exists", [role], "fetchPrivileges (role check)"))[0]?.exists !== true) throw new KozouIntrospectError(`introspection.respectPrivileges is on but the role "${role}" does not exist. Set it to the role the Admin UI assumes (auth.ui.role / auth.defaultRole), or turn privilege-aware introspection off.`);
|
|
13968
|
+
}
|
|
13969
|
+
/**
|
|
13970
|
+
* Evaluate the privileges of `role` on every base table / view (and base-table
|
|
13971
|
+
* columns) in `schemas`, and attach them to the matching `RawTable` /
|
|
13972
|
+
* `RawColumn` / `RawView`. Mutates the inputs in place (mirrors
|
|
13973
|
+
* `mergeTableMetadata`). Call only when privilege-aware mode is on; otherwise
|
|
13974
|
+
* the privilege fields stay `undefined`.
|
|
13975
|
+
*/
|
|
13976
|
+
async function fetchAndAttachPrivileges(client, schemas, role, tables, views) {
|
|
13977
|
+
if (schemas.length === 0 || tables.length === 0 && views.length === 0) return;
|
|
13978
|
+
await assertRoleExists(client, role);
|
|
13979
|
+
const tableRows = await runQuery(client, `SELECT
|
|
13980
|
+
n.nspname AS schema,
|
|
13981
|
+
c.relname AS name,
|
|
13982
|
+
has_schema_privilege($2, n.nspname, 'USAGE') AS usage,
|
|
13983
|
+
has_table_privilege($2, c.oid, 'SELECT') AS sel,
|
|
13984
|
+
has_table_privilege($2, c.oid, 'INSERT') AS ins,
|
|
13985
|
+
has_table_privilege($2, c.oid, 'UPDATE') AS upd,
|
|
13986
|
+
has_table_privilege($2, c.oid, 'DELETE') AS del
|
|
13987
|
+
FROM pg_class c
|
|
13988
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
13989
|
+
WHERE c.relkind IN ('r', 'v', 'm')
|
|
13990
|
+
AND n.nspname = ANY($1)`, [schemas, role], "fetchPrivileges (relations)");
|
|
13991
|
+
const columnRows = await runQuery(client, `SELECT
|
|
13992
|
+
n.nspname AS schema,
|
|
13993
|
+
c.relname AS table,
|
|
13994
|
+
a.attname AS name,
|
|
13995
|
+
has_schema_privilege($2, n.nspname, 'USAGE') AS usage,
|
|
13996
|
+
has_column_privilege($2, c.oid, a.attname, 'INSERT') AS ins,
|
|
13997
|
+
has_column_privilege($2, c.oid, a.attname, 'UPDATE') AS upd
|
|
13998
|
+
FROM pg_attribute a
|
|
13999
|
+
JOIN pg_class c ON c.oid = a.attrelid
|
|
14000
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
14001
|
+
WHERE c.relkind = 'r'
|
|
14002
|
+
AND n.nspname = ANY($1)
|
|
14003
|
+
AND a.attnum > 0
|
|
14004
|
+
AND NOT a.attisdropped`, [schemas, role], "fetchPrivileges (columns)");
|
|
14005
|
+
const tablePrivByKey = /* @__PURE__ */ new Map();
|
|
14006
|
+
for (const row of tableRows) tablePrivByKey.set(tableKey(row.schema, row.name), row);
|
|
14007
|
+
const columnPrivByKey = /* @__PURE__ */ new Map();
|
|
14008
|
+
for (const row of columnRows) {
|
|
14009
|
+
const key = tableKey(row.schema, row.table);
|
|
14010
|
+
if (!columnPrivByKey.has(key)) columnPrivByKey.set(key, /* @__PURE__ */ new Map());
|
|
14011
|
+
columnPrivByKey.get(key).set(row.name, row);
|
|
14012
|
+
}
|
|
14013
|
+
const gate = (tp) => ({
|
|
14014
|
+
role,
|
|
14015
|
+
select: tp.usage && tp.sel,
|
|
14016
|
+
insert: tp.usage && tp.ins,
|
|
14017
|
+
update: tp.usage && tp.upd,
|
|
14018
|
+
delete: tp.usage && tp.del
|
|
14019
|
+
});
|
|
14020
|
+
for (const table of tables) {
|
|
14021
|
+
const key = tableKey(table.schema, table.name);
|
|
14022
|
+
const tp = tablePrivByKey.get(key);
|
|
14023
|
+
if (tp !== void 0) table.privileges = gate(tp);
|
|
14024
|
+
const cols = columnPrivByKey.get(key);
|
|
14025
|
+
if (cols !== void 0) for (const column of table.columns) {
|
|
14026
|
+
const cp = cols.get(column.name);
|
|
14027
|
+
if (cp !== void 0) column.privileges = {
|
|
14028
|
+
insert: cp.usage && cp.ins,
|
|
14029
|
+
update: cp.usage && cp.upd
|
|
14030
|
+
};
|
|
14031
|
+
}
|
|
14032
|
+
}
|
|
14033
|
+
for (const view of views) {
|
|
14034
|
+
const vp = tablePrivByKey.get(tableKey(view.schema, view.name));
|
|
14035
|
+
if (vp !== void 0) view.privileges = gate(vp);
|
|
14036
|
+
}
|
|
14037
|
+
}
|
|
14038
|
+
//#endregion
|
|
13938
14039
|
//#region ../introspect/dist/filter.js
|
|
13939
14040
|
function compilePattern(pattern) {
|
|
13940
14041
|
const qualified = pattern.includes(".") ? pattern : `*.${pattern}`;
|
|
@@ -14018,6 +14119,7 @@ async function introspect(opts) {
|
|
|
14018
14119
|
mergeTableMetadata(allTables, await fetchForeignKeys(client, validSchemas), await fetchChecks(client, validSchemas));
|
|
14019
14120
|
const allViews = await fetchViews(client, validSchemas);
|
|
14020
14121
|
const enums = await fetchEnums(client, validSchemas);
|
|
14122
|
+
if (opts.privilegeRole !== void 0) await fetchAndAttachPrivileges(client, validSchemas, opts.privilegeRole, allTables, allViews);
|
|
14021
14123
|
const filterOpts = {
|
|
14022
14124
|
include: opts.include,
|
|
14023
14125
|
exclude: opts.exclude
|
|
@@ -14127,7 +14229,11 @@ var SchemaCache = class {
|
|
|
14127
14229
|
var cache = new SchemaCache({ loader: async () => {
|
|
14128
14230
|
const connection = process.env.DATABASE_URL;
|
|
14129
14231
|
if (typeof connection !== "string" || connection.length === 0) throw new Error("hooks.server: DATABASE_URL is required to introspect the schema.");
|
|
14130
|
-
|
|
14232
|
+
const privilegeRole = process.env.KOZOU_INTROSPECTION_ROLE;
|
|
14233
|
+
return buildSchemaContext({ raw: await introspect({
|
|
14234
|
+
connection,
|
|
14235
|
+
...typeof privilegeRole === "string" && privilegeRole.length > 0 ? { privilegeRole } : {}
|
|
14236
|
+
}) });
|
|
14131
14237
|
} });
|
|
14132
14238
|
var fkRowCache = new FkRowCache();
|
|
14133
14239
|
var handle = async ({ event, resolve }) => {
|
|
@@ -14137,4 +14243,4 @@ var handle = async ({ event, resolve }) => {
|
|
|
14137
14243
|
};
|
|
14138
14244
|
|
|
14139
14245
|
export { handle };
|
|
14140
|
-
//# sourceMappingURL=hooks.server-
|
|
14246
|
+
//# sourceMappingURL=hooks.server-DtCXcOVD.js.map
|