dbctx 1.0.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.
Files changed (68) hide show
  1. package/.prettierrc.cjs +7 -0
  2. package/.turbo/turbo-build.log +5 -0
  3. package/dist/App.d.ts +23 -0
  4. package/dist/App.d.ts.map +1 -0
  5. package/dist/App.js +9 -0
  6. package/dist/components/Error.d.ts +7 -0
  7. package/dist/components/Error.d.ts.map +1 -0
  8. package/dist/components/Error.js +6 -0
  9. package/dist/db/analyze.d.mts +3 -0
  10. package/dist/db/analyze.d.mts.map +1 -0
  11. package/dist/db/analyze.mjs +16 -0
  12. package/dist/db/attributes.d.mts +16 -0
  13. package/dist/db/attributes.d.mts.map +1 -0
  14. package/dist/db/attributes.mjs +37 -0
  15. package/dist/db/enums.d.mts +8 -0
  16. package/dist/db/enums.d.mts.map +1 -0
  17. package/dist/db/enums.mjs +24 -0
  18. package/dist/db/file-stats.d.mts +11 -0
  19. package/dist/db/file-stats.d.mts.map +1 -0
  20. package/dist/db/file-stats.mjs +43 -0
  21. package/dist/db/foreign-keys.d.mts +14 -0
  22. package/dist/db/foreign-keys.d.mts.map +1 -0
  23. package/dist/db/foreign-keys.mjs +44 -0
  24. package/dist/db/index.d.mts +10 -0
  25. package/dist/db/index.d.mts.map +1 -0
  26. package/dist/db/index.mjs +10 -0
  27. package/dist/db/indexes.d.mts +16 -0
  28. package/dist/db/indexes.d.mts.map +1 -0
  29. package/dist/db/indexes.mjs +38 -0
  30. package/dist/db/relations.d.mts +10 -0
  31. package/dist/db/relations.d.mts.map +1 -0
  32. package/dist/db/relations.mjs +23 -0
  33. package/dist/db/stats.d.mts +12 -0
  34. package/dist/db/stats.d.mts.map +1 -0
  35. package/dist/db/stats.mjs +34 -0
  36. package/dist/db/version.d.mts +13 -0
  37. package/dist/db/version.d.mts.map +1 -0
  38. package/dist/db/version.mjs +19 -0
  39. package/dist/index.d.mts +17 -0
  40. package/dist/index.d.mts.map +1 -0
  41. package/dist/index.mjs +75 -0
  42. package/dist/logger.d.mts +3 -0
  43. package/dist/logger.d.mts.map +1 -0
  44. package/dist/logger.mjs +7 -0
  45. package/dist/schemas/index.d.mts +2 -0
  46. package/dist/schemas/index.d.mts.map +1 -0
  47. package/dist/schemas/index.mjs +91 -0
  48. package/dist/validatePaths.d.mts +12 -0
  49. package/dist/validatePaths.d.mts.map +1 -0
  50. package/dist/validatePaths.mjs +48 -0
  51. package/package.json +43 -0
  52. package/src/App.tsx +44 -0
  53. package/src/components/Error.tsx +16 -0
  54. package/src/db/analyze.mts +22 -0
  55. package/src/db/attributes.mts +58 -0
  56. package/src/db/enums.mts +43 -0
  57. package/src/db/file-stats.mts +57 -0
  58. package/src/db/foreign-keys.mts +61 -0
  59. package/src/db/index.mts +9 -0
  60. package/src/db/indexes.mts +57 -0
  61. package/src/db/relations.mts +35 -0
  62. package/src/db/stats.mts +51 -0
  63. package/src/db/version.mts +34 -0
  64. package/src/index.mts +116 -0
  65. package/src/logger.mts +10 -0
  66. package/src/schemas/index.mts +102 -0
  67. package/src/validatePaths.mts +77 -0
  68. package/tsconfig.json +104 -0
@@ -0,0 +1,7 @@
1
+ module.exports = {
2
+ bracketSpacing: false,
3
+ jsxBracketSameLine: true,
4
+ singleQuote: true,
5
+ trailingComma: 'all',
6
+ tabWidth: 4,
7
+ };
@@ -0,0 +1,5 @@
1
+
2
+ 
3
+ > dbctx@1.0.0 build /Users/omran/Projects/airstate/dbctx/apps/client
4
+ > tsc
5
+
package/dist/App.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type { ReactNode } from "react";
2
+ import type { TSSLMode } from "./index.mjs";
3
+ export type TConnectionConfig = {
4
+ connectionString?: string;
5
+ hostname?: string;
6
+ port?: number;
7
+ database?: string;
8
+ username?: string;
9
+ sslmode?: TSSLMode;
10
+ sslcert?: string;
11
+ sslkey?: string;
12
+ sslrootcert?: string;
13
+ sshHost?: string;
14
+ sshPort?: number;
15
+ sshUsername?: string;
16
+ sshPrivateKey?: string;
17
+ };
18
+ type TAppProps = {
19
+ config: TConnectionConfig;
20
+ };
21
+ export declare function App({ config }: TAppProps): ReactNode;
22
+ export {};
23
+ //# sourceMappingURL=App.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"./src/","sources":["App.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,iBAAiB,GAAG;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,KAAK,SAAS,GAAG;IACb,MAAM,EAAE,iBAAiB,CAAC;CAC7B,CAAC;AAEF,wBAAgB,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,SAAS,GAAG,SAAS,CAmBpD"}
package/dist/App.js ADDED
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Text, Box } from "ink";
3
+ export function App({ config }) {
4
+ const connectionTarget = config.connectionString
5
+ ? config.connectionString.replace(/:[^:@]+@/, ":***@") // mask password
6
+ : `${config.hostname}:${config.port}/${config.database}`;
7
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "dbctx" }), _jsx(Text, { dimColor: true, children: " - AI generated docs from your application database" })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Connecting to: " }), _jsx(Text, { color: "yellow", children: connectionTarget })] })] }));
8
+ }
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXBwLmpzIiwic291cmNlUm9vdCI6Ii4vc3JjLyIsInNvdXJjZXMiOlsiQXBwLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxLQUFLLENBQUM7QUF3QmhDLE1BQU0sVUFBVSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQWE7SUFDckMsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCO1FBQzVDLENBQUMsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxnQkFBZ0I7UUFDdkUsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUU3RCxPQUFPLENBQ0gsTUFBQyxHQUFHLElBQUMsYUFBYSxFQUFDLFFBQVEsRUFBQyxPQUFPLEVBQUUsQ0FBQyxhQUNsQyxNQUFDLEdBQUcsSUFBQyxZQUFZLEVBQUUsQ0FBQyxhQUNoQixLQUFDLElBQUksSUFBQyxLQUFLLEVBQUMsTUFBTSxFQUFDLElBQUksNEJBRWhCLEVBQ1AsS0FBQyxJQUFJLElBQUMsUUFBUSwwRUFBMkQsSUFDdkUsRUFDTixNQUFDLEdBQUcsZUFDQSxLQUFDLElBQUksSUFBQyxRQUFRLHNDQUF1QixFQUNyQyxLQUFDLElBQUksSUFBQyxLQUFLLEVBQUMsUUFBUSxZQUFFLGdCQUFnQixHQUFRLElBQzVDLElBQ0osQ0FDVCxDQUFDO0FBQ04sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRleHQsIEJveCB9IGZyb20gXCJpbmtcIjtcbmltcG9ydCB0eXBlIHsgUmVhY3ROb2RlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgdHlwZSB7IFRTU0xNb2RlIH0gZnJvbSBcIi4vaW5kZXgubWpzXCI7XG5cbmV4cG9ydCB0eXBlIFRDb25uZWN0aW9uQ29uZmlnID0ge1xuICAgIGNvbm5lY3Rpb25TdHJpbmc/OiBzdHJpbmc7XG4gICAgaG9zdG5hbWU/OiBzdHJpbmc7XG4gICAgcG9ydD86IG51bWJlcjtcbiAgICBkYXRhYmFzZT86IHN0cmluZztcbiAgICB1c2VybmFtZT86IHN0cmluZztcbiAgICBzc2xtb2RlPzogVFNTTE1vZGU7XG4gICAgc3NsY2VydD86IHN0cmluZztcbiAgICBzc2xrZXk/OiBzdHJpbmc7XG4gICAgc3Nscm9vdGNlcnQ/OiBzdHJpbmc7XG4gICAgc3NoSG9zdD86IHN0cmluZztcbiAgICBzc2hQb3J0PzogbnVtYmVyO1xuICAgIHNzaFVzZXJuYW1lPzogc3RyaW5nO1xuICAgIHNzaFByaXZhdGVLZXk/OiBzdHJpbmc7XG59O1xuXG50eXBlIFRBcHBQcm9wcyA9IHtcbiAgICBjb25maWc6IFRDb25uZWN0aW9uQ29uZmlnO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIEFwcCh7IGNvbmZpZyB9OiBUQXBwUHJvcHMpOiBSZWFjdE5vZGUge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25UYXJnZXQgPSBjb25maWcuY29ubmVjdGlvblN0cmluZ1xuICAgICAgICA/IGNvbmZpZy5jb25uZWN0aW9uU3RyaW5nLnJlcGxhY2UoLzpbXjpAXStALywgXCI6KioqQFwiKSAvLyBtYXNrIHBhc3N3b3JkXG4gICAgICAgIDogYCR7Y29uZmlnLmhvc3RuYW1lfToke2NvbmZpZy5wb3J0fS8ke2NvbmZpZy5kYXRhYmFzZX1gO1xuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgcGFkZGluZz17MX0+XG4gICAgICAgICAgICA8Qm94IG1hcmdpbkJvdHRvbT17MX0+XG4gICAgICAgICAgICAgICAgPFRleHQgY29sb3I9XCJjeWFuXCIgYm9sZD5cbiAgICAgICAgICAgICAgICAgICAgZGJjdHhcbiAgICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+IC0gQUkgZ2VuZXJhdGVkIGRvY3MgZnJvbSB5b3VyIGFwcGxpY2F0aW9uIGRhdGFiYXNlPC9UZXh0PlxuICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgICA8Qm94PlxuICAgICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPkNvbm5lY3RpbmcgdG86IDwvVGV4dD5cbiAgICAgICAgICAgICAgICA8VGV4dCBjb2xvcj1cInllbGxvd1wiPntjb25uZWN0aW9uVGFyZ2V0fTwvVGV4dD5cbiAgICAgICAgICAgIDwvQm94PlxuICAgICAgICA8L0JveD5cbiAgICApO1xufVxuIl19
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from "react";
2
+ interface ErrorProps {
3
+ message: string;
4
+ }
5
+ export declare function Error({ message }: ErrorProps): ReactNode;
6
+ export {};
7
+ //# sourceMappingURL=Error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Error.d.ts","sourceRoot":"./src/","sources":["components/Error.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,UAAU,UAAU;IAChB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,UAAU,GAAG,SAAS,CAQxD"}
@@ -0,0 +1,6 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text, Box } from "ink";
3
+ export function Error({ message }) {
4
+ return (_jsx(Box, { children: _jsxs(Text, { color: "red", bold: true, children: ["Error: ", message] }) }));
5
+ }
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXJyb3IuanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJjb21wb25lbnRzL0Vycm9yLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFPaEMsTUFBTSxVQUFVLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBYztJQUN6QyxPQUFPLENBQ0gsS0FBQyxHQUFHLGNBQ0EsTUFBQyxJQUFJLElBQUMsS0FBSyxFQUFDLEtBQUssRUFBQyxJQUFJLDhCQUNWLE9BQU8sSUFDWixHQUNMLENBQ1QsQ0FBQztBQUNOLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZXh0LCBCb3ggfSBmcm9tIFwiaW5rXCI7XG5pbXBvcnQgdHlwZSB7IFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiO1xuXG5pbnRlcmZhY2UgRXJyb3JQcm9wcyB7XG4gICAgbWVzc2FnZTogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gRXJyb3IoeyBtZXNzYWdlIH06IEVycm9yUHJvcHMpOiBSZWFjdE5vZGUge1xuICAgIHJldHVybiAoXG4gICAgICAgIDxCb3g+XG4gICAgICAgICAgICA8VGV4dCBjb2xvcj1cInJlZFwiIGJvbGQ+XG4gICAgICAgICAgICAgICAgRXJyb3I6IHttZXNzYWdlfVxuICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICA8L0JveD5cbiAgICApO1xufVxuIl19
@@ -0,0 +1,3 @@
1
+ import type { Pool } from "pg";
2
+ export declare const analyzeRelation: (pool: Pool, relationName: string) => Promise<void>;
3
+ //# sourceMappingURL=analyze.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.mts","sourceRoot":"./src/","sources":["db/analyze.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,eAAO,MAAM,eAAe,GAAU,MAAM,IAAI,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,IAAI,CAmBpF,CAAC"}
@@ -0,0 +1,16 @@
1
+ export const analyzeRelation = async (pool, relationName) => {
2
+ // Validate relation exists and get properly quoted name to prevent SQL injection
3
+ const validation = await pool.query(`
4
+ SELECT format('%I', c.relname) AS quoted_name
5
+ FROM pg_catalog.pg_class c
6
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
7
+ WHERE n.nspname = 'public'
8
+ AND c.relname = $1
9
+ AND c.relkind IN ('r', 'p', 'm')
10
+ `, [relationName]);
11
+ if (validation.rows.length === 0) {
12
+ throw new Error(`Relation "${relationName}" not found in public schema`);
13
+ }
14
+ await pool.query(`ANALYZE public.${validation.rows[0].quoted_name}`);
15
+ };
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl6ZS5tanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJkYi9hbmFseXplLm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsS0FBSyxFQUFFLElBQVUsRUFBRSxZQUFvQixFQUFpQixFQUFFO0lBQ3JGLGlGQUFpRjtJQUNqRixNQUFNLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQy9COzs7Ozs7O1NBT0MsRUFDRCxDQUFDLFlBQVksQ0FBQyxDQUNqQixDQUFDO0lBRUYsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUMvQixNQUFNLElBQUksS0FBSyxDQUFDLGFBQWEsWUFBWSw4QkFBOEIsQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRCxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsa0JBQWtCLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUN6RSxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFBvb2wgfSBmcm9tIFwicGdcIjtcblxuZXhwb3J0IGNvbnN0IGFuYWx5emVSZWxhdGlvbiA9IGFzeW5jIChwb29sOiBQb29sLCByZWxhdGlvbk5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIC8vIFZhbGlkYXRlIHJlbGF0aW9uIGV4aXN0cyBhbmQgZ2V0IHByb3Blcmx5IHF1b3RlZCBuYW1lIHRvIHByZXZlbnQgU1FMIGluamVjdGlvblxuICAgIGNvbnN0IHZhbGlkYXRpb24gPSBhd2FpdCBwb29sLnF1ZXJ5PHsgcXVvdGVkX25hbWU6IHN0cmluZyB9PihcbiAgICAgICAgYFxuICAgICAgICBTRUxFQ1QgZm9ybWF0KCclSScsIGMucmVsbmFtZSkgQVMgcXVvdGVkX25hbWVcbiAgICAgICAgRlJPTSBwZ19jYXRhbG9nLnBnX2NsYXNzIGNcbiAgICAgICAgSk9JTiBwZ19jYXRhbG9nLnBnX25hbWVzcGFjZSBuIE9OIG4ub2lkID0gYy5yZWxuYW1lc3BhY2VcbiAgICAgICAgV0hFUkUgbi5uc3BuYW1lID0gJ3B1YmxpYydcbiAgICAgICAgICAgIEFORCBjLnJlbG5hbWUgPSAkMVxuICAgICAgICAgICAgQU5EIGMucmVsa2luZCBJTiAoJ3InLCAncCcsICdtJylcbiAgICAgICAgYCxcbiAgICAgICAgW3JlbGF0aW9uTmFtZV1cbiAgICApO1xuXG4gICAgaWYgKHZhbGlkYXRpb24ucm93cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZWxhdGlvbiBcIiR7cmVsYXRpb25OYW1lfVwiIG5vdCBmb3VuZCBpbiBwdWJsaWMgc2NoZW1hYCk7XG4gICAgfVxuXG4gICAgYXdhaXQgcG9vbC5xdWVyeShgQU5BTFlaRSBwdWJsaWMuJHt2YWxpZGF0aW9uLnJvd3NbMF0ucXVvdGVkX25hbWV9YCk7XG59O1xuIl19
@@ -0,0 +1,16 @@
1
+ import type { Pool } from "pg";
2
+ export type TAttributeKind = "regular" | "generated";
3
+ export type TGeneratedStorage = "stored" | "virtual";
4
+ export type TAttributeInfo = {
5
+ attribute_name: string;
6
+ data_type: string;
7
+ is_nullable: boolean;
8
+ has_default: boolean;
9
+ default_expression: string | null;
10
+ kind: TAttributeKind;
11
+ generated_storage: TGeneratedStorage | null;
12
+ generated_expression: string | null;
13
+ comment: string | null;
14
+ };
15
+ export declare const fetchRelationAttributes: (pool: Pool, relationName: string) => Promise<TAttributeInfo[]>;
16
+ //# sourceMappingURL=attributes.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attributes.d.mts","sourceRoot":"./src/","sources":["db/attributes.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAErD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAErD,MAAM,MAAM,cAAc,GAAG;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,IAAI,EAAE,cAAc,CAAC;IACrB,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,MAAM,IAAI,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,cAAc,EAAE,CAuCxG,CAAC"}
@@ -0,0 +1,37 @@
1
+ export const fetchRelationAttributes = async (pool, relationName) => {
2
+ const result = await pool.query(`
3
+ SELECT
4
+ a.attname AS attribute_name,
5
+ format_type(a.atttypid, a.atttypemod) AS data_type,
6
+ NOT a.attnotnull AS is_nullable,
7
+ ad.adbin IS NOT NULL AS has_default,
8
+ CASE
9
+ WHEN a.attgenerated = '' AND ad.adbin IS NOT NULL THEN pg_get_expr(ad.adbin, ad.adrelid)
10
+ ELSE NULL
11
+ END AS default_expression,
12
+ CASE a.attgenerated
13
+ WHEN '' THEN 'regular'
14
+ ELSE 'generated'
15
+ END AS kind,
16
+ CASE a.attgenerated
17
+ WHEN 's' THEN 'stored'
18
+ WHEN 'v' THEN 'virtual'
19
+ ELSE NULL
20
+ END AS generated_storage,
21
+ CASE
22
+ WHEN a.attgenerated != '' THEN pg_get_expr(ad.adbin, ad.adrelid)
23
+ ELSE NULL
24
+ END AS generated_expression,
25
+ col_description(c.oid, a.attnum) AS comment
26
+ FROM pg_catalog.pg_class c
27
+ JOIN pg_catalog.pg_attribute a ON a.attrelid = c.oid
28
+ LEFT JOIN pg_catalog.pg_attrdef ad ON ad.adrelid = a.attrelid AND ad.adnum = a.attnum
29
+ WHERE c.relname = $1
30
+ AND c.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
31
+ AND a.attnum > 0
32
+ AND NOT a.attisdropped
33
+ ORDER BY a.attnum
34
+ `, [relationName]);
35
+ return result.rows;
36
+ };
37
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0cmlidXRlcy5tanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJkYi9hdHRyaWJ1dGVzLm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFrQkEsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxFQUFFLElBQVUsRUFBRSxZQUFvQixFQUE2QixFQUFFO0lBQ3pHLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FDM0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O1NBZ0NDLEVBQ0QsQ0FBQyxZQUFZLENBQUMsQ0FDakIsQ0FBQztJQUVGLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQztBQUN2QixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFBvb2wgfSBmcm9tIFwicGdcIjtcblxuZXhwb3J0IHR5cGUgVEF0dHJpYnV0ZUtpbmQgPSBcInJlZ3VsYXJcIiB8IFwiZ2VuZXJhdGVkXCI7XG5cbmV4cG9ydCB0eXBlIFRHZW5lcmF0ZWRTdG9yYWdlID0gXCJzdG9yZWRcIiB8IFwidmlydHVhbFwiO1xuXG5leHBvcnQgdHlwZSBUQXR0cmlidXRlSW5mbyA9IHtcbiAgICBhdHRyaWJ1dGVfbmFtZTogc3RyaW5nO1xuICAgIGRhdGFfdHlwZTogc3RyaW5nO1xuICAgIGlzX251bGxhYmxlOiBib29sZWFuO1xuICAgIGhhc19kZWZhdWx0OiBib29sZWFuO1xuICAgIGRlZmF1bHRfZXhwcmVzc2lvbjogc3RyaW5nIHwgbnVsbDtcbiAgICBraW5kOiBUQXR0cmlidXRlS2luZDtcbiAgICBnZW5lcmF0ZWRfc3RvcmFnZTogVEdlbmVyYXRlZFN0b3JhZ2UgfCBudWxsO1xuICAgIGdlbmVyYXRlZF9leHByZXNzaW9uOiBzdHJpbmcgfCBudWxsO1xuICAgIGNvbW1lbnQ6IHN0cmluZyB8IG51bGw7XG59O1xuXG5leHBvcnQgY29uc3QgZmV0Y2hSZWxhdGlvbkF0dHJpYnV0ZXMgPSBhc3luYyAocG9vbDogUG9vbCwgcmVsYXRpb25OYW1lOiBzdHJpbmcpOiBQcm9taXNlPFRBdHRyaWJ1dGVJbmZvW10+ID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwb29sLnF1ZXJ5PFRBdHRyaWJ1dGVJbmZvPihcbiAgICAgICAgYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICAgIGEuYXR0bmFtZSBBUyBhdHRyaWJ1dGVfbmFtZSxcbiAgICAgICAgICAgIGZvcm1hdF90eXBlKGEuYXR0dHlwaWQsIGEuYXR0dHlwZW1vZCkgQVMgZGF0YV90eXBlLFxuICAgICAgICAgICAgTk9UIGEuYXR0bm90bnVsbCBBUyBpc19udWxsYWJsZSxcbiAgICAgICAgICAgIGFkLmFkYmluIElTIE5PVCBOVUxMIEFTIGhhc19kZWZhdWx0LFxuICAgICAgICAgICAgQ0FTRVxuICAgICAgICAgICAgICAgIFdIRU4gYS5hdHRnZW5lcmF0ZWQgPSAnJyBBTkQgYWQuYWRiaW4gSVMgTk9UIE5VTEwgVEhFTiBwZ19nZXRfZXhwcihhZC5hZGJpbiwgYWQuYWRyZWxpZClcbiAgICAgICAgICAgICAgICBFTFNFIE5VTExcbiAgICAgICAgICAgIEVORCBBUyBkZWZhdWx0X2V4cHJlc3Npb24sXG4gICAgICAgICAgICBDQVNFIGEuYXR0Z2VuZXJhdGVkXG4gICAgICAgICAgICAgICAgV0hFTiAnJyBUSEVOICdyZWd1bGFyJ1xuICAgICAgICAgICAgICAgIEVMU0UgJ2dlbmVyYXRlZCdcbiAgICAgICAgICAgIEVORCBBUyBraW5kLFxuICAgICAgICAgICAgQ0FTRSBhLmF0dGdlbmVyYXRlZFxuICAgICAgICAgICAgICAgIFdIRU4gJ3MnIFRIRU4gJ3N0b3JlZCdcbiAgICAgICAgICAgICAgICBXSEVOICd2JyBUSEVOICd2aXJ0dWFsJ1xuICAgICAgICAgICAgICAgIEVMU0UgTlVMTFxuICAgICAgICAgICAgRU5EIEFTIGdlbmVyYXRlZF9zdG9yYWdlLFxuICAgICAgICAgICAgQ0FTRVxuICAgICAgICAgICAgICAgIFdIRU4gYS5hdHRnZW5lcmF0ZWQgIT0gJycgVEhFTiBwZ19nZXRfZXhwcihhZC5hZGJpbiwgYWQuYWRyZWxpZClcbiAgICAgICAgICAgICAgICBFTFNFIE5VTExcbiAgICAgICAgICAgIEVORCBBUyBnZW5lcmF0ZWRfZXhwcmVzc2lvbixcbiAgICAgICAgICAgIGNvbF9kZXNjcmlwdGlvbihjLm9pZCwgYS5hdHRudW0pIEFTIGNvbW1lbnRcbiAgICAgICAgRlJPTSBwZ19jYXRhbG9nLnBnX2NsYXNzIGNcbiAgICAgICAgSk9JTiBwZ19jYXRhbG9nLnBnX2F0dHJpYnV0ZSBhIE9OIGEuYXR0cmVsaWQgPSBjLm9pZFxuICAgICAgICBMRUZUIEpPSU4gcGdfY2F0YWxvZy5wZ19hdHRyZGVmIGFkIE9OIGFkLmFkcmVsaWQgPSBhLmF0dHJlbGlkIEFORCBhZC5hZG51bSA9IGEuYXR0bnVtXG4gICAgICAgIFdIRVJFIGMucmVsbmFtZSA9ICQxXG4gICAgICAgICAgICBBTkQgYy5yZWxuYW1lc3BhY2UgPSAoU0VMRUNUIG9pZCBGUk9NIHBnX25hbWVzcGFjZSBXSEVSRSBuc3BuYW1lID0gJ3B1YmxpYycpXG4gICAgICAgICAgICBBTkQgYS5hdHRudW0gPiAwXG4gICAgICAgICAgICBBTkQgTk9UIGEuYXR0aXNkcm9wcGVkXG4gICAgICAgIE9SREVSIEJZIGEuYXR0bnVtXG4gICAgICAgIGAsXG4gICAgICAgIFtyZWxhdGlvbk5hbWVdXG4gICAgKTtcblxuICAgIHJldHVybiByZXN1bHQucm93cztcbn07XG4iXX0=
@@ -0,0 +1,8 @@
1
+ import type { Pool } from "pg";
2
+ export type TEnumInfo = {
3
+ values: string[];
4
+ comment: string | null;
5
+ };
6
+ export type TGroupedEnums = Record<string, TEnumInfo>;
7
+ export declare const fetchPublicEnums: (pool: Pool) => Promise<TGroupedEnums>;
8
+ //# sourceMappingURL=enums.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.d.mts","sourceRoot":"./src/","sources":["db/enums.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAU/B,MAAM,MAAM,SAAS,GAAG;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAEtD,eAAO,MAAM,gBAAgB,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,aAAa,CAyBxE,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { groupBy } from "es-toolkit";
2
+ export const fetchPublicEnums = async (pool) => {
3
+ const result = await pool.query(`
4
+ SELECT
5
+ t.typname AS enum_name,
6
+ e.enumlabel AS value,
7
+ e.enumsortorder AS sort_order,
8
+ obj_description(t.oid, 'pg_type') AS comment
9
+ FROM pg_catalog.pg_type t
10
+ JOIN pg_catalog.pg_enum e ON t.oid = e.enumtypid
11
+ JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid
12
+ WHERE n.nspname = 'public'
13
+ ORDER BY enum_name, sort_order
14
+ `);
15
+ const grouped = groupBy(result.rows, (row) => row.enum_name);
16
+ return Object.fromEntries(Object.entries(grouped).map(([name, rows]) => [
17
+ name,
18
+ {
19
+ values: rows.map((r) => r.value),
20
+ comment: rows[0]?.comment ?? null,
21
+ },
22
+ ]));
23
+ };
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW51bXMubWpzIiwic291cmNlUm9vdCI6Ii4vc3JjLyIsInNvdXJjZXMiOlsiZGIvZW51bXMubXRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFnQnJDLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLEtBQUssRUFBRSxJQUFVLEVBQTBCLEVBQUU7SUFDekUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFnQjs7Ozs7Ozs7Ozs7S0FXOUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUU3RCxPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQ3JCLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQzFDLElBQUk7UUFDSjtZQUNJLE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1lBQ2hDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxJQUFJLElBQUk7U0FDcEM7S0FDSixDQUFDLENBQ0wsQ0FBQztBQUNOLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUG9vbCB9IGZyb20gXCJwZ1wiO1xuaW1wb3J0IHsgZ3JvdXBCeSB9IGZyb20gXCJlcy10b29sa2l0XCI7XG5cbnR5cGUgVEVudW1WYWx1ZVJvdyA9IHtcbiAgICBlbnVtX25hbWU6IHN0cmluZztcbiAgICB2YWx1ZTogc3RyaW5nO1xuICAgIHNvcnRfb3JkZXI6IG51bWJlcjtcbiAgICBjb21tZW50OiBzdHJpbmcgfCBudWxsO1xufTtcblxuZXhwb3J0IHR5cGUgVEVudW1JbmZvID0ge1xuICAgIHZhbHVlczogc3RyaW5nW107XG4gICAgY29tbWVudDogc3RyaW5nIHwgbnVsbDtcbn07XG5cbmV4cG9ydCB0eXBlIFRHcm91cGVkRW51bXMgPSBSZWNvcmQ8c3RyaW5nLCBURW51bUluZm8+O1xuXG5leHBvcnQgY29uc3QgZmV0Y2hQdWJsaWNFbnVtcyA9IGFzeW5jIChwb29sOiBQb29sKTogUHJvbWlzZTxUR3JvdXBlZEVudW1zPiA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcG9vbC5xdWVyeTxURW51bVZhbHVlUm93PihgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICAgdC50eXBuYW1lIEFTIGVudW1fbmFtZSxcbiAgICAgICAgICAgIGUuZW51bWxhYmVsIEFTIHZhbHVlLFxuICAgICAgICAgICAgZS5lbnVtc29ydG9yZGVyIEFTIHNvcnRfb3JkZXIsXG4gICAgICAgICAgICBvYmpfZGVzY3JpcHRpb24odC5vaWQsICdwZ190eXBlJykgQVMgY29tbWVudFxuICAgICAgICBGUk9NIHBnX2NhdGFsb2cucGdfdHlwZSB0XG4gICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19lbnVtIGUgT04gdC5vaWQgPSBlLmVudW10eXBpZFxuICAgICAgICBKT0lOIHBnX2NhdGFsb2cucGdfbmFtZXNwYWNlIG4gT04gdC50eXBuYW1lc3BhY2UgPSBuLm9pZFxuICAgICAgICBXSEVSRSBuLm5zcG5hbWUgPSAncHVibGljJ1xuICAgICAgICBPUkRFUiBCWSBlbnVtX25hbWUsIHNvcnRfb3JkZXJcbiAgICBgKTtcblxuICAgIGNvbnN0IGdyb3VwZWQgPSBncm91cEJ5KHJlc3VsdC5yb3dzLCAocm93KSA9PiByb3cuZW51bV9uYW1lKTtcblxuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGdyb3VwZWQpLm1hcCgoW25hbWUsIHJvd3NdKSA9PiBbXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHZhbHVlczogcm93cy5tYXAoKHIpID0+IHIudmFsdWUpLFxuICAgICAgICAgICAgICAgIGNvbW1lbnQ6IHJvd3NbMF0/LmNvbW1lbnQgPz8gbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0pXG4gICAgKTtcbn07XG4iXX0=
@@ -0,0 +1,11 @@
1
+ import type { Pool } from "pg";
2
+ export type TRelationFileStats = {
3
+ relation_name: string;
4
+ file_path: string | null;
5
+ modification_time: Date;
6
+ size_bytes: number;
7
+ is_partitioned: boolean;
8
+ partition_count: number | null;
9
+ };
10
+ export declare const fetchRelationFileStats: (pool: Pool, relationName: string) => Promise<TRelationFileStats>;
11
+ //# sourceMappingURL=file-stats.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-stats.d.mts","sourceRoot":"./src/","sources":["db/file-stats.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,MAAM,kBAAkB,GAAG;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iBAAiB,EAAE,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAU,MAAM,IAAI,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,kBAAkB,CA6CzG,CAAC"}
@@ -0,0 +1,43 @@
1
+ export const fetchRelationFileStats = async (pool, relationName) => {
2
+ const result = await pool.query(`
3
+ WITH target AS (
4
+ SELECT c.oid, c.relname, c.relkind
5
+ FROM pg_catalog.pg_class c
6
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
7
+ WHERE n.nspname = 'public'
8
+ AND c.relname = $1
9
+ AND c.relkind IN ('r', 'p', 'm')
10
+ ),
11
+ partition_stats AS (
12
+ SELECT
13
+ (pg_stat_file(pg_relation_filepath(child.oid))).modification AS modification_time,
14
+ (pg_stat_file(pg_relation_filepath(child.oid))).size AS size_bytes
15
+ FROM target t
16
+ JOIN pg_catalog.pg_inherits i ON i.inhparent = t.oid
17
+ JOIN pg_catalog.pg_class child ON child.oid = i.inhrelid
18
+ WHERE t.relkind = 'p'
19
+ )
20
+ SELECT
21
+ t.relname AS relation_name,
22
+ CASE
23
+ WHEN t.relkind = 'p' THEN NULL
24
+ ELSE pg_relation_filepath(t.oid)
25
+ END AS file_path,
26
+ CASE
27
+ WHEN t.relkind = 'p' THEN (SELECT MAX(modification_time) FROM partition_stats)
28
+ ELSE (pg_stat_file(pg_relation_filepath(t.oid))).modification
29
+ END AS modification_time,
30
+ CASE
31
+ WHEN t.relkind = 'p' THEN (SELECT COALESCE(SUM(size_bytes), 0) FROM partition_stats)
32
+ ELSE (pg_stat_file(pg_relation_filepath(t.oid))).size
33
+ END AS size_bytes,
34
+ t.relkind = 'p' AS is_partitioned,
35
+ CASE
36
+ WHEN t.relkind = 'p' THEN (SELECT COUNT(*) FROM partition_stats)
37
+ ELSE NULL
38
+ END AS partition_count
39
+ FROM target t
40
+ `, [relationName]);
41
+ return result.rows[0];
42
+ };
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1zdGF0cy5tanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJkYi9maWxlLXN0YXRzLm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFXQSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxLQUFLLEVBQUUsSUFBVSxFQUFFLFlBQW9CLEVBQStCLEVBQUU7SUFDMUcsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUMzQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7U0FzQ0MsRUFDRCxDQUFDLFlBQVksQ0FBQyxDQUNqQixDQUFDO0lBRUYsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUG9vbCB9IGZyb20gXCJwZ1wiO1xuXG5leHBvcnQgdHlwZSBUUmVsYXRpb25GaWxlU3RhdHMgPSB7XG4gICAgcmVsYXRpb25fbmFtZTogc3RyaW5nO1xuICAgIGZpbGVfcGF0aDogc3RyaW5nIHwgbnVsbDtcbiAgICBtb2RpZmljYXRpb25fdGltZTogRGF0ZTtcbiAgICBzaXplX2J5dGVzOiBudW1iZXI7XG4gICAgaXNfcGFydGl0aW9uZWQ6IGJvb2xlYW47XG4gICAgcGFydGl0aW9uX2NvdW50OiBudW1iZXIgfCBudWxsO1xufTtcblxuZXhwb3J0IGNvbnN0IGZldGNoUmVsYXRpb25GaWxlU3RhdHMgPSBhc3luYyAocG9vbDogUG9vbCwgcmVsYXRpb25OYW1lOiBzdHJpbmcpOiBQcm9taXNlPFRSZWxhdGlvbkZpbGVTdGF0cz4gPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBvb2wucXVlcnk8VFJlbGF0aW9uRmlsZVN0YXRzPihcbiAgICAgICAgYFxuICAgICAgICBXSVRIIHRhcmdldCBBUyAoXG4gICAgICAgICAgICBTRUxFQ1QgYy5vaWQsIGMucmVsbmFtZSwgYy5yZWxraW5kXG4gICAgICAgICAgICBGUk9NIHBnX2NhdGFsb2cucGdfY2xhc3MgY1xuICAgICAgICAgICAgSk9JTiBwZ19jYXRhbG9nLnBnX25hbWVzcGFjZSBuIE9OIG4ub2lkID0gYy5yZWxuYW1lc3BhY2VcbiAgICAgICAgICAgIFdIRVJFIG4ubnNwbmFtZSA9ICdwdWJsaWMnXG4gICAgICAgICAgICAgICAgQU5EIGMucmVsbmFtZSA9ICQxXG4gICAgICAgICAgICAgICAgQU5EIGMucmVsa2luZCBJTiAoJ3InLCAncCcsICdtJylcbiAgICAgICAgKSxcbiAgICAgICAgcGFydGl0aW9uX3N0YXRzIEFTIChcbiAgICAgICAgICAgIFNFTEVDVFxuICAgICAgICAgICAgICAgIChwZ19zdGF0X2ZpbGUocGdfcmVsYXRpb25fZmlsZXBhdGgoY2hpbGQub2lkKSkpLm1vZGlmaWNhdGlvbiBBUyBtb2RpZmljYXRpb25fdGltZSxcbiAgICAgICAgICAgICAgICAocGdfc3RhdF9maWxlKHBnX3JlbGF0aW9uX2ZpbGVwYXRoKGNoaWxkLm9pZCkpKS5zaXplIEFTIHNpemVfYnl0ZXNcbiAgICAgICAgICAgIEZST00gdGFyZ2V0IHRcbiAgICAgICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19pbmhlcml0cyBpIE9OIGkuaW5ocGFyZW50ID0gdC5vaWRcbiAgICAgICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19jbGFzcyBjaGlsZCBPTiBjaGlsZC5vaWQgPSBpLmluaHJlbGlkXG4gICAgICAgICAgICBXSEVSRSB0LnJlbGtpbmQgPSAncCdcbiAgICAgICAgKVxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICAgIHQucmVsbmFtZSBBUyByZWxhdGlvbl9uYW1lLFxuICAgICAgICAgICAgQ0FTRVxuICAgICAgICAgICAgICAgIFdIRU4gdC5yZWxraW5kID0gJ3AnIFRIRU4gTlVMTFxuICAgICAgICAgICAgICAgIEVMU0UgcGdfcmVsYXRpb25fZmlsZXBhdGgodC5vaWQpXG4gICAgICAgICAgICBFTkQgQVMgZmlsZV9wYXRoLFxuICAgICAgICAgICAgQ0FTRVxuICAgICAgICAgICAgICAgIFdIRU4gdC5yZWxraW5kID0gJ3AnIFRIRU4gKFNFTEVDVCBNQVgobW9kaWZpY2F0aW9uX3RpbWUpIEZST00gcGFydGl0aW9uX3N0YXRzKVxuICAgICAgICAgICAgICAgIEVMU0UgKHBnX3N0YXRfZmlsZShwZ19yZWxhdGlvbl9maWxlcGF0aCh0Lm9pZCkpKS5tb2RpZmljYXRpb25cbiAgICAgICAgICAgIEVORCBBUyBtb2RpZmljYXRpb25fdGltZSxcbiAgICAgICAgICAgIENBU0VcbiAgICAgICAgICAgICAgICBXSEVOIHQucmVsa2luZCA9ICdwJyBUSEVOIChTRUxFQ1QgQ09BTEVTQ0UoU1VNKHNpemVfYnl0ZXMpLCAwKSBGUk9NIHBhcnRpdGlvbl9zdGF0cylcbiAgICAgICAgICAgICAgICBFTFNFIChwZ19zdGF0X2ZpbGUocGdfcmVsYXRpb25fZmlsZXBhdGgodC5vaWQpKSkuc2l6ZVxuICAgICAgICAgICAgRU5EIEFTIHNpemVfYnl0ZXMsXG4gICAgICAgICAgICB0LnJlbGtpbmQgPSAncCcgQVMgaXNfcGFydGl0aW9uZWQsXG4gICAgICAgICAgICBDQVNFXG4gICAgICAgICAgICAgICAgV0hFTiB0LnJlbGtpbmQgPSAncCcgVEhFTiAoU0VMRUNUIENPVU5UKCopIEZST00gcGFydGl0aW9uX3N0YXRzKVxuICAgICAgICAgICAgICAgIEVMU0UgTlVMTFxuICAgICAgICAgICAgRU5EIEFTIHBhcnRpdGlvbl9jb3VudFxuICAgICAgICBGUk9NIHRhcmdldCB0XG4gICAgICAgIGAsXG4gICAgICAgIFtyZWxhdGlvbk5hbWVdXG4gICAgKTtcblxuICAgIHJldHVybiByZXN1bHQucm93c1swXTtcbn07XG4iXX0=
@@ -0,0 +1,14 @@
1
+ import type { Pool } from "pg";
2
+ type TForeignKeyAction = "NO ACTION" | "RESTRICT" | "CASCADE" | "SET NULL" | "SET DEFAULT";
3
+ export type TForeignKeyInfo = {
4
+ constraint_name: string;
5
+ attributes: string[];
6
+ referenced_relation: string;
7
+ referenced_attributes: string[];
8
+ on_update: TForeignKeyAction;
9
+ on_delete: TForeignKeyAction;
10
+ comment: string | null;
11
+ };
12
+ export declare const fetchRelationForeignKeys: (pool: Pool, relationName: string) => Promise<TForeignKeyInfo[]>;
13
+ export {};
14
+ //# sourceMappingURL=foreign-keys.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foreign-keys.d.mts","sourceRoot":"./src/","sources":["db/foreign-keys.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;AAE3F,MAAM,MAAM,eAAe,GAAG;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,SAAS,EAAE,iBAAiB,CAAC;IAC7B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,MAAM,IAAI,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,eAAe,EAAE,CA8C1G,CAAC"}
@@ -0,0 +1,44 @@
1
+ export const fetchRelationForeignKeys = async (pool, relationName) => {
2
+ const result = await pool.query(`
3
+ SELECT
4
+ con.conname AS constraint_name,
5
+ ARRAY(
6
+ SELECT a.attname
7
+ FROM unnest(con.conkey) WITH ORDINALITY AS cols(attnum, ord)
8
+ JOIN pg_attribute a ON a.attrelid = con.conrelid AND a.attnum = cols.attnum
9
+ ORDER BY cols.ord
10
+ ) AS attributes,
11
+ ref_cl.relname AS referenced_relation,
12
+ ARRAY(
13
+ SELECT a.attname
14
+ FROM unnest(con.confkey) WITH ORDINALITY AS cols(attnum, ord)
15
+ JOIN pg_attribute a ON a.attrelid = con.confrelid AND a.attnum = cols.attnum
16
+ ORDER BY cols.ord
17
+ ) AS referenced_attributes,
18
+ CASE con.confupdtype
19
+ WHEN 'a' THEN 'NO ACTION'
20
+ WHEN 'r' THEN 'RESTRICT'
21
+ WHEN 'c' THEN 'CASCADE'
22
+ WHEN 'n' THEN 'SET NULL'
23
+ WHEN 'd' THEN 'SET DEFAULT'
24
+ END AS on_update,
25
+ CASE con.confdeltype
26
+ WHEN 'a' THEN 'NO ACTION'
27
+ WHEN 'r' THEN 'RESTRICT'
28
+ WHEN 'c' THEN 'CASCADE'
29
+ WHEN 'n' THEN 'SET NULL'
30
+ WHEN 'd' THEN 'SET DEFAULT'
31
+ END AS on_delete,
32
+ obj_description(con.oid, 'pg_constraint') AS comment
33
+ FROM pg_catalog.pg_constraint con
34
+ JOIN pg_catalog.pg_class cl ON cl.oid = con.conrelid
35
+ JOIN pg_catalog.pg_class ref_cl ON ref_cl.oid = con.confrelid
36
+ JOIN pg_catalog.pg_namespace n ON n.oid = cl.relnamespace
37
+ WHERE con.contype = 'f'
38
+ AND n.nspname = 'public'
39
+ AND cl.relname = $1
40
+ ORDER BY con.conname
41
+ `, [relationName]);
42
+ return result.rows;
43
+ };
44
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yZWlnbi1rZXlzLm1qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbImRiL2ZvcmVpZ24ta2V5cy5tdHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBY0EsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxFQUFFLElBQVUsRUFBRSxZQUFvQixFQUE4QixFQUFFO0lBQzNHLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FDM0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztTQXVDQyxFQUNELENBQUMsWUFBWSxDQUFDLENBQ2pCLENBQUM7SUFFRixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdkIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBQb29sIH0gZnJvbSBcInBnXCI7XG5cbnR5cGUgVEZvcmVpZ25LZXlBY3Rpb24gPSBcIk5PIEFDVElPTlwiIHwgXCJSRVNUUklDVFwiIHwgXCJDQVNDQURFXCIgfCBcIlNFVCBOVUxMXCIgfCBcIlNFVCBERUZBVUxUXCI7XG5cbmV4cG9ydCB0eXBlIFRGb3JlaWduS2V5SW5mbyA9IHtcbiAgICBjb25zdHJhaW50X25hbWU6IHN0cmluZztcbiAgICBhdHRyaWJ1dGVzOiBzdHJpbmdbXTtcbiAgICByZWZlcmVuY2VkX3JlbGF0aW9uOiBzdHJpbmc7XG4gICAgcmVmZXJlbmNlZF9hdHRyaWJ1dGVzOiBzdHJpbmdbXTtcbiAgICBvbl91cGRhdGU6IFRGb3JlaWduS2V5QWN0aW9uO1xuICAgIG9uX2RlbGV0ZTogVEZvcmVpZ25LZXlBY3Rpb247XG4gICAgY29tbWVudDogc3RyaW5nIHwgbnVsbDtcbn07XG5cbmV4cG9ydCBjb25zdCBmZXRjaFJlbGF0aW9uRm9yZWlnbktleXMgPSBhc3luYyAocG9vbDogUG9vbCwgcmVsYXRpb25OYW1lOiBzdHJpbmcpOiBQcm9taXNlPFRGb3JlaWduS2V5SW5mb1tdPiA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcG9vbC5xdWVyeTxURm9yZWlnbktleUluZm8+KFxuICAgICAgICBgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICAgY29uLmNvbm5hbWUgQVMgY29uc3RyYWludF9uYW1lLFxuICAgICAgICAgICAgQVJSQVkoXG4gICAgICAgICAgICAgICAgU0VMRUNUIGEuYXR0bmFtZVxuICAgICAgICAgICAgICAgIEZST00gdW5uZXN0KGNvbi5jb25rZXkpIFdJVEggT1JESU5BTElUWSBBUyBjb2xzKGF0dG51bSwgb3JkKVxuICAgICAgICAgICAgICAgIEpPSU4gcGdfYXR0cmlidXRlIGEgT04gYS5hdHRyZWxpZCA9IGNvbi5jb25yZWxpZCBBTkQgYS5hdHRudW0gPSBjb2xzLmF0dG51bVxuICAgICAgICAgICAgICAgIE9SREVSIEJZIGNvbHMub3JkXG4gICAgICAgICAgICApIEFTIGF0dHJpYnV0ZXMsXG4gICAgICAgICAgICByZWZfY2wucmVsbmFtZSBBUyByZWZlcmVuY2VkX3JlbGF0aW9uLFxuICAgICAgICAgICAgQVJSQVkoXG4gICAgICAgICAgICAgICAgU0VMRUNUIGEuYXR0bmFtZVxuICAgICAgICAgICAgICAgIEZST00gdW5uZXN0KGNvbi5jb25ma2V5KSBXSVRIIE9SRElOQUxJVFkgQVMgY29scyhhdHRudW0sIG9yZClcbiAgICAgICAgICAgICAgICBKT0lOIHBnX2F0dHJpYnV0ZSBhIE9OIGEuYXR0cmVsaWQgPSBjb24uY29uZnJlbGlkIEFORCBhLmF0dG51bSA9IGNvbHMuYXR0bnVtXG4gICAgICAgICAgICAgICAgT1JERVIgQlkgY29scy5vcmRcbiAgICAgICAgICAgICkgQVMgcmVmZXJlbmNlZF9hdHRyaWJ1dGVzLFxuICAgICAgICAgICAgQ0FTRSBjb24uY29uZnVwZHR5cGVcbiAgICAgICAgICAgICAgICBXSEVOICdhJyBUSEVOICdOTyBBQ1RJT04nXG4gICAgICAgICAgICAgICAgV0hFTiAncicgVEhFTiAnUkVTVFJJQ1QnXG4gICAgICAgICAgICAgICAgV0hFTiAnYycgVEhFTiAnQ0FTQ0FERSdcbiAgICAgICAgICAgICAgICBXSEVOICduJyBUSEVOICdTRVQgTlVMTCdcbiAgICAgICAgICAgICAgICBXSEVOICdkJyBUSEVOICdTRVQgREVGQVVMVCdcbiAgICAgICAgICAgIEVORCBBUyBvbl91cGRhdGUsXG4gICAgICAgICAgICBDQVNFIGNvbi5jb25mZGVsdHlwZVxuICAgICAgICAgICAgICAgIFdIRU4gJ2EnIFRIRU4gJ05PIEFDVElPTidcbiAgICAgICAgICAgICAgICBXSEVOICdyJyBUSEVOICdSRVNUUklDVCdcbiAgICAgICAgICAgICAgICBXSEVOICdjJyBUSEVOICdDQVNDQURFJ1xuICAgICAgICAgICAgICAgIFdIRU4gJ24nIFRIRU4gJ1NFVCBOVUxMJ1xuICAgICAgICAgICAgICAgIFdIRU4gJ2QnIFRIRU4gJ1NFVCBERUZBVUxUJ1xuICAgICAgICAgICAgRU5EIEFTIG9uX2RlbGV0ZSxcbiAgICAgICAgICAgIG9ial9kZXNjcmlwdGlvbihjb24ub2lkLCAncGdfY29uc3RyYWludCcpIEFTIGNvbW1lbnRcbiAgICAgICAgRlJPTSBwZ19jYXRhbG9nLnBnX2NvbnN0cmFpbnQgY29uXG4gICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19jbGFzcyBjbCBPTiBjbC5vaWQgPSBjb24uY29ucmVsaWRcbiAgICAgICAgSk9JTiBwZ19jYXRhbG9nLnBnX2NsYXNzIHJlZl9jbCBPTiByZWZfY2wub2lkID0gY29uLmNvbmZyZWxpZFxuICAgICAgICBKT0lOIHBnX2NhdGFsb2cucGdfbmFtZXNwYWNlIG4gT04gbi5vaWQgPSBjbC5yZWxuYW1lc3BhY2VcbiAgICAgICAgV0hFUkUgY29uLmNvbnR5cGUgPSAnZidcbiAgICAgICAgICAgIEFORCBuLm5zcG5hbWUgPSAncHVibGljJ1xuICAgICAgICAgICAgQU5EIGNsLnJlbG5hbWUgPSAkMVxuICAgICAgICBPUkRFUiBCWSBjb24uY29ubmFtZVxuICAgICAgICBgLFxuICAgICAgICBbcmVsYXRpb25OYW1lXVxuICAgICk7XG5cbiAgICByZXR1cm4gcmVzdWx0LnJvd3M7XG59O1xuIl19
@@ -0,0 +1,10 @@
1
+ export { fetchPublicRelations, type TRelationType, type TRelationInfo, type TGroupedRelations } from "./relations.mjs";
2
+ export { fetchRelationAttributes, type TAttributeKind, type TGeneratedStorage, type TAttributeInfo } from "./attributes.mjs";
3
+ export { fetchPublicEnums, type TEnumInfo, type TGroupedEnums } from "./enums.mjs";
4
+ export { fetchRelationIndexes, type TIndexInfo } from "./indexes.mjs";
5
+ export { fetchRelationForeignKeys, type TForeignKeyInfo } from "./foreign-keys.mjs";
6
+ export { fetchPostgresVersion, type TPostgresVersion, fetchDatabaseIdentifier, type TDatabaseIdentifier } from "./version.mjs";
7
+ export { fetchRelationFileStats, type TRelationFileStats } from "./file-stats.mjs";
8
+ export { analyzeRelation } from "./analyze.mjs";
9
+ export { fetchRelationStats, type TRelationStats, type TAttributeStats } from "./stats.mjs";
10
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"./src/","sources":["db/index.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvH,OAAO,EAAE,uBAAuB,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7H,OAAO,EAAE,gBAAgB,EAAE,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,uBAAuB,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC/H,OAAO,EAAE,sBAAsB,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,10 @@
1
+ export { fetchPublicRelations } from "./relations.mjs";
2
+ export { fetchRelationAttributes } from "./attributes.mjs";
3
+ export { fetchPublicEnums } from "./enums.mjs";
4
+ export { fetchRelationIndexes } from "./indexes.mjs";
5
+ export { fetchRelationForeignKeys } from "./foreign-keys.mjs";
6
+ export { fetchPostgresVersion, fetchDatabaseIdentifier } from "./version.mjs";
7
+ export { fetchRelationFileStats } from "./file-stats.mjs";
8
+ export { analyzeRelation } from "./analyze.mjs";
9
+ export { fetchRelationStats } from "./stats.mjs";
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgubWpzIiwic291cmNlUm9vdCI6Ii4vc3JjLyIsInNvdXJjZXMiOlsiZGIvaW5kZXgubXRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxvQkFBb0IsRUFBa0UsTUFBTSxpQkFBaUIsQ0FBQztBQUN2SCxPQUFPLEVBQUUsdUJBQXVCLEVBQW9FLE1BQU0sa0JBQWtCLENBQUM7QUFDN0gsT0FBTyxFQUFFLGdCQUFnQixFQUFzQyxNQUFNLGFBQWEsQ0FBQztBQUNuRixPQUFPLEVBQUUsb0JBQW9CLEVBQW1CLE1BQU0sZUFBZSxDQUFDO0FBQ3RFLE9BQU8sRUFBRSx3QkFBd0IsRUFBd0IsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRixPQUFPLEVBQUUsb0JBQW9CLEVBQXlCLHVCQUF1QixFQUE0QixNQUFNLGVBQWUsQ0FBQztBQUMvSCxPQUFPLEVBQUUsc0JBQXNCLEVBQTJCLE1BQU0sa0JBQWtCLENBQUM7QUFDbkYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRCxPQUFPLEVBQUUsa0JBQWtCLEVBQTZDLE1BQU0sYUFBYSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgZmV0Y2hQdWJsaWNSZWxhdGlvbnMsIHR5cGUgVFJlbGF0aW9uVHlwZSwgdHlwZSBUUmVsYXRpb25JbmZvLCB0eXBlIFRHcm91cGVkUmVsYXRpb25zIH0gZnJvbSBcIi4vcmVsYXRpb25zLm1qc1wiO1xuZXhwb3J0IHsgZmV0Y2hSZWxhdGlvbkF0dHJpYnV0ZXMsIHR5cGUgVEF0dHJpYnV0ZUtpbmQsIHR5cGUgVEdlbmVyYXRlZFN0b3JhZ2UsIHR5cGUgVEF0dHJpYnV0ZUluZm8gfSBmcm9tIFwiLi9hdHRyaWJ1dGVzLm1qc1wiO1xuZXhwb3J0IHsgZmV0Y2hQdWJsaWNFbnVtcywgdHlwZSBURW51bUluZm8sIHR5cGUgVEdyb3VwZWRFbnVtcyB9IGZyb20gXCIuL2VudW1zLm1qc1wiO1xuZXhwb3J0IHsgZmV0Y2hSZWxhdGlvbkluZGV4ZXMsIHR5cGUgVEluZGV4SW5mbyB9IGZyb20gXCIuL2luZGV4ZXMubWpzXCI7XG5leHBvcnQgeyBmZXRjaFJlbGF0aW9uRm9yZWlnbktleXMsIHR5cGUgVEZvcmVpZ25LZXlJbmZvIH0gZnJvbSBcIi4vZm9yZWlnbi1rZXlzLm1qc1wiO1xuZXhwb3J0IHsgZmV0Y2hQb3N0Z3Jlc1ZlcnNpb24sIHR5cGUgVFBvc3RncmVzVmVyc2lvbiwgZmV0Y2hEYXRhYmFzZUlkZW50aWZpZXIsIHR5cGUgVERhdGFiYXNlSWRlbnRpZmllciB9IGZyb20gXCIuL3ZlcnNpb24ubWpzXCI7XG5leHBvcnQgeyBmZXRjaFJlbGF0aW9uRmlsZVN0YXRzLCB0eXBlIFRSZWxhdGlvbkZpbGVTdGF0cyB9IGZyb20gXCIuL2ZpbGUtc3RhdHMubWpzXCI7XG5leHBvcnQgeyBhbmFseXplUmVsYXRpb24gfSBmcm9tIFwiLi9hbmFseXplLm1qc1wiO1xuZXhwb3J0IHsgZmV0Y2hSZWxhdGlvblN0YXRzLCB0eXBlIFRSZWxhdGlvblN0YXRzLCB0eXBlIFRBdHRyaWJ1dGVTdGF0cyB9IGZyb20gXCIuL3N0YXRzLm1qc1wiO1xuIl19
@@ -0,0 +1,16 @@
1
+ import type { Pool } from "pg";
2
+ export type TIndexInfo = {
3
+ index_name: string;
4
+ relation_name: string;
5
+ is_unique: boolean;
6
+ is_primary: boolean;
7
+ is_exclusion: boolean;
8
+ is_partial: boolean;
9
+ partial_predicate: string | null;
10
+ attributes: string[];
11
+ exclusion_operators: string[] | null;
12
+ definition: string;
13
+ comment: string | null;
14
+ };
15
+ export declare const fetchRelationIndexes: (pool: Pool, relationName: string) => Promise<TIndexInfo[]>;
16
+ //# sourceMappingURL=indexes.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexes.d.mts","sourceRoot":"./src/","sources":["db/indexes.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,MAAM,IAAI,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,UAAU,EAAE,CAwCjG,CAAC"}
@@ -0,0 +1,38 @@
1
+ export const fetchRelationIndexes = async (pool, relationName) => {
2
+ const result = await pool.query(`
3
+ SELECT
4
+ i.relname AS index_name,
5
+ t.relname AS relation_name,
6
+ ix.indisunique AS is_unique,
7
+ ix.indisprimary AS is_primary,
8
+ ix.indisexclusion AS is_exclusion,
9
+ ix.indpred IS NOT NULL AS is_partial,
10
+ pg_get_expr(ix.indpred, ix.indrelid) AS partial_predicate,
11
+ ARRAY(
12
+ SELECT pg_get_indexdef(ix.indexrelid, k + 1, true)
13
+ FROM generate_subscripts(ix.indkey, 1) AS k
14
+ ORDER BY k
15
+ ) AS attributes,
16
+ CASE
17
+ WHEN ix.indisexclusion THEN (
18
+ SELECT ARRAY_AGG(op.oprname ORDER BY ord.n)
19
+ FROM pg_constraint con
20
+ CROSS JOIN LATERAL unnest(con.conexclop) WITH ORDINALITY AS ord(opoid, n)
21
+ JOIN pg_operator op ON op.oid = ord.opoid
22
+ WHERE con.conindid = ix.indexrelid
23
+ )
24
+ ELSE NULL
25
+ END AS exclusion_operators,
26
+ pg_get_indexdef(ix.indexrelid) AS definition,
27
+ obj_description(i.oid, 'pg_class') AS comment
28
+ FROM pg_catalog.pg_index ix
29
+ JOIN pg_catalog.pg_class i ON i.oid = ix.indexrelid
30
+ JOIN pg_catalog.pg_class t ON t.oid = ix.indrelid
31
+ JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
32
+ WHERE n.nspname = 'public'
33
+ AND t.relname = $1
34
+ ORDER BY i.relname
35
+ `, [relationName]);
36
+ return result.rows;
37
+ };
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXhlcy5tanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJkYi9pbmRleGVzLm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFnQkEsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsS0FBSyxFQUFFLElBQVUsRUFBRSxZQUFvQixFQUF5QixFQUFFO0lBQ2xHLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FDM0I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztTQWlDQyxFQUNELENBQUMsWUFBWSxDQUFDLENBQ2pCLENBQUM7SUFFRixPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDdkIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBQb29sIH0gZnJvbSBcInBnXCI7XG5cbmV4cG9ydCB0eXBlIFRJbmRleEluZm8gPSB7XG4gICAgaW5kZXhfbmFtZTogc3RyaW5nO1xuICAgIHJlbGF0aW9uX25hbWU6IHN0cmluZztcbiAgICBpc191bmlxdWU6IGJvb2xlYW47XG4gICAgaXNfcHJpbWFyeTogYm9vbGVhbjtcbiAgICBpc19leGNsdXNpb246IGJvb2xlYW47XG4gICAgaXNfcGFydGlhbDogYm9vbGVhbjtcbiAgICBwYXJ0aWFsX3ByZWRpY2F0ZTogc3RyaW5nIHwgbnVsbDtcbiAgICBhdHRyaWJ1dGVzOiBzdHJpbmdbXTtcbiAgICBleGNsdXNpb25fb3BlcmF0b3JzOiBzdHJpbmdbXSB8IG51bGw7XG4gICAgZGVmaW5pdGlvbjogc3RyaW5nO1xuICAgIGNvbW1lbnQ6IHN0cmluZyB8IG51bGw7XG59O1xuXG5leHBvcnQgY29uc3QgZmV0Y2hSZWxhdGlvbkluZGV4ZXMgPSBhc3luYyAocG9vbDogUG9vbCwgcmVsYXRpb25OYW1lOiBzdHJpbmcpOiBQcm9taXNlPFRJbmRleEluZm9bXT4gPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBvb2wucXVlcnk8VEluZGV4SW5mbz4oXG4gICAgICAgIGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgICBpLnJlbG5hbWUgQVMgaW5kZXhfbmFtZSxcbiAgICAgICAgICAgIHQucmVsbmFtZSBBUyByZWxhdGlvbl9uYW1lLFxuICAgICAgICAgICAgaXguaW5kaXN1bmlxdWUgQVMgaXNfdW5pcXVlLFxuICAgICAgICAgICAgaXguaW5kaXNwcmltYXJ5IEFTIGlzX3ByaW1hcnksXG4gICAgICAgICAgICBpeC5pbmRpc2V4Y2x1c2lvbiBBUyBpc19leGNsdXNpb24sXG4gICAgICAgICAgICBpeC5pbmRwcmVkIElTIE5PVCBOVUxMIEFTIGlzX3BhcnRpYWwsXG4gICAgICAgICAgICBwZ19nZXRfZXhwcihpeC5pbmRwcmVkLCBpeC5pbmRyZWxpZCkgQVMgcGFydGlhbF9wcmVkaWNhdGUsXG4gICAgICAgICAgICBBUlJBWShcbiAgICAgICAgICAgICAgICBTRUxFQ1QgcGdfZ2V0X2luZGV4ZGVmKGl4LmluZGV4cmVsaWQsIGsgKyAxLCB0cnVlKVxuICAgICAgICAgICAgICAgIEZST00gZ2VuZXJhdGVfc3Vic2NyaXB0cyhpeC5pbmRrZXksIDEpIEFTIGtcbiAgICAgICAgICAgICAgICBPUkRFUiBCWSBrXG4gICAgICAgICAgICApIEFTIGF0dHJpYnV0ZXMsXG4gICAgICAgICAgICBDQVNFXG4gICAgICAgICAgICAgICAgV0hFTiBpeC5pbmRpc2V4Y2x1c2lvbiBUSEVOIChcbiAgICAgICAgICAgICAgICAgICAgU0VMRUNUIEFSUkFZX0FHRyhvcC5vcHJuYW1lIE9SREVSIEJZIG9yZC5uKVxuICAgICAgICAgICAgICAgICAgICBGUk9NIHBnX2NvbnN0cmFpbnQgY29uXG4gICAgICAgICAgICAgICAgICAgIENST1NTIEpPSU4gTEFURVJBTCB1bm5lc3QoY29uLmNvbmV4Y2xvcCkgV0lUSCBPUkRJTkFMSVRZIEFTIG9yZChvcG9pZCwgbilcbiAgICAgICAgICAgICAgICAgICAgSk9JTiBwZ19vcGVyYXRvciBvcCBPTiBvcC5vaWQgPSBvcmQub3BvaWRcbiAgICAgICAgICAgICAgICAgICAgV0hFUkUgY29uLmNvbmluZGlkID0gaXguaW5kZXhyZWxpZFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICBFTFNFIE5VTExcbiAgICAgICAgICAgIEVORCBBUyBleGNsdXNpb25fb3BlcmF0b3JzLFxuICAgICAgICAgICAgcGdfZ2V0X2luZGV4ZGVmKGl4LmluZGV4cmVsaWQpIEFTIGRlZmluaXRpb24sXG4gICAgICAgICAgICBvYmpfZGVzY3JpcHRpb24oaS5vaWQsICdwZ19jbGFzcycpIEFTIGNvbW1lbnRcbiAgICAgICAgRlJPTSBwZ19jYXRhbG9nLnBnX2luZGV4IGl4XG4gICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19jbGFzcyBpIE9OIGkub2lkID0gaXguaW5kZXhyZWxpZFxuICAgICAgICBKT0lOIHBnX2NhdGFsb2cucGdfY2xhc3MgdCBPTiB0Lm9pZCA9IGl4LmluZHJlbGlkXG4gICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19uYW1lc3BhY2UgbiBPTiBuLm9pZCA9IHQucmVsbmFtZXNwYWNlXG4gICAgICAgIFdIRVJFIG4ubnNwbmFtZSA9ICdwdWJsaWMnXG4gICAgICAgICAgICBBTkQgdC5yZWxuYW1lID0gJDFcbiAgICAgICAgT1JERVIgQlkgaS5yZWxuYW1lXG4gICAgICAgIGAsXG4gICAgICAgIFtyZWxhdGlvbk5hbWVdXG4gICAgKTtcblxuICAgIHJldHVybiByZXN1bHQucm93cztcbn07XG4iXX0=
@@ -0,0 +1,10 @@
1
+ import type { Pool } from "pg";
2
+ export type TRelationType = "partitioned_table" | "table" | "view" | "materialized_view";
3
+ export type TRelationInfo = {
4
+ name: string;
5
+ type: TRelationType;
6
+ comment: string | null;
7
+ };
8
+ export type TGroupedRelations = Record<TRelationType, TRelationInfo[]>;
9
+ export declare const fetchPublicRelations: (pool: Pool) => Promise<TGroupedRelations>;
10
+ //# sourceMappingURL=relations.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.d.mts","sourceRoot":"./src/","sources":["db/relations.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,OAAO,GAAG,MAAM,GAAG,mBAAmB,CAAC;AAEzF,MAAM,MAAM,aAAa,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC;AAEvE,eAAO,MAAM,oBAAoB,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,iBAAiB,CAqBhF,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { groupBy } from "es-toolkit";
2
+ export const fetchPublicRelations = async (pool) => {
3
+ const result = await pool.query(`
4
+ SELECT relname AS name,
5
+ CASE relkind
6
+ WHEN 'p' THEN 'partitioned_table'
7
+ WHEN 'r' THEN 'table'
8
+ WHEN 'v' THEN 'view'
9
+ WHEN 'm' THEN 'materialized_view'
10
+ END AS type,
11
+ obj_description(oid, 'pg_class') AS comment
12
+ FROM pg_catalog.pg_class
13
+ WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')
14
+ AND (
15
+ relkind = 'p'
16
+ OR (relkind = 'r' AND NOT relispartition)
17
+ OR relkind IN ('v', 'm')
18
+ )
19
+ ORDER BY type, name
20
+ `);
21
+ return groupBy(result.rows, (row) => row.type);
22
+ };
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVsYXRpb25zLm1qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbImRiL3JlbGF0aW9ucy5tdHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFlBQVksQ0FBQztBQVlyQyxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLEVBQUUsSUFBVSxFQUE4QixFQUFFO0lBQ2pGLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBZ0I7Ozs7Ozs7Ozs7Ozs7Ozs7O0tBaUI5QyxDQUFDLENBQUM7SUFFSCxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFzQixDQUFDO0FBQ3hFLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgUG9vbCB9IGZyb20gXCJwZ1wiO1xuaW1wb3J0IHsgZ3JvdXBCeSB9IGZyb20gXCJlcy10b29sa2l0XCI7XG5cbmV4cG9ydCB0eXBlIFRSZWxhdGlvblR5cGUgPSBcInBhcnRpdGlvbmVkX3RhYmxlXCIgfCBcInRhYmxlXCIgfCBcInZpZXdcIiB8IFwibWF0ZXJpYWxpemVkX3ZpZXdcIjtcblxuZXhwb3J0IHR5cGUgVFJlbGF0aW9uSW5mbyA9IHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdHlwZTogVFJlbGF0aW9uVHlwZTtcbiAgICBjb21tZW50OiBzdHJpbmcgfCBudWxsO1xufTtcblxuZXhwb3J0IHR5cGUgVEdyb3VwZWRSZWxhdGlvbnMgPSBSZWNvcmQ8VFJlbGF0aW9uVHlwZSwgVFJlbGF0aW9uSW5mb1tdPjtcblxuZXhwb3J0IGNvbnN0IGZldGNoUHVibGljUmVsYXRpb25zID0gYXN5bmMgKHBvb2w6IFBvb2wpOiBQcm9taXNlPFRHcm91cGVkUmVsYXRpb25zPiA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcG9vbC5xdWVyeTxUUmVsYXRpb25JbmZvPihgXG4gICAgICAgIFNFTEVDVCByZWxuYW1lIEFTIG5hbWUsXG4gICAgICAgICAgICBDQVNFIHJlbGtpbmRcbiAgICAgICAgICAgICAgICBXSEVOICdwJyBUSEVOICdwYXJ0aXRpb25lZF90YWJsZSdcbiAgICAgICAgICAgICAgICBXSEVOICdyJyBUSEVOICd0YWJsZSdcbiAgICAgICAgICAgICAgICBXSEVOICd2JyBUSEVOICd2aWV3J1xuICAgICAgICAgICAgICAgIFdIRU4gJ20nIFRIRU4gJ21hdGVyaWFsaXplZF92aWV3J1xuICAgICAgICAgICAgRU5EIEFTIHR5cGUsXG4gICAgICAgICAgICBvYmpfZGVzY3JpcHRpb24ob2lkLCAncGdfY2xhc3MnKSBBUyBjb21tZW50XG4gICAgICAgIEZST00gcGdfY2F0YWxvZy5wZ19jbGFzc1xuICAgICAgICBXSEVSRSByZWxuYW1lc3BhY2UgPSAoU0VMRUNUIG9pZCBGUk9NIHBnX25hbWVzcGFjZSBXSEVSRSBuc3BuYW1lID0gJ3B1YmxpYycpXG4gICAgICAgICAgICBBTkQgKFxuICAgICAgICAgICAgICAgIHJlbGtpbmQgPSAncCdcbiAgICAgICAgICAgICAgICBPUiAocmVsa2luZCA9ICdyJyBBTkQgTk9UIHJlbGlzcGFydGl0aW9uKVxuICAgICAgICAgICAgICAgIE9SIHJlbGtpbmQgSU4gKCd2JywgJ20nKVxuICAgICAgICAgICAgKVxuICAgICAgICBPUkRFUiBCWSB0eXBlLCBuYW1lXG4gICAgYCk7XG5cbiAgICByZXR1cm4gZ3JvdXBCeShyZXN1bHQucm93cywgKHJvdykgPT4gcm93LnR5cGUpIGFzIFRHcm91cGVkUmVsYXRpb25zO1xufTtcbiJdfQ==
@@ -0,0 +1,12 @@
1
+ import type { Pool } from "pg";
2
+ export type TAttributeStats = {
3
+ attribute_name: string;
4
+ estimated_distinct: number;
5
+ };
6
+ export type TRelationStats = {
7
+ relation_name: string;
8
+ estimated_row_count: number;
9
+ attributes: TAttributeStats[];
10
+ };
11
+ export declare const fetchRelationStats: (pool: Pool, relationName: string) => Promise<TRelationStats>;
12
+ //# sourceMappingURL=stats.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.mts","sourceRoot":"./src/","sources":["db/stats.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,MAAM,eAAe,GAAG;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,eAAe,EAAE,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,MAAM,IAAI,EAAE,cAAc,MAAM,KAAG,OAAO,CAAC,cAAc,CAqCjG,CAAC"}
@@ -0,0 +1,34 @@
1
+ export const fetchRelationStats = async (pool, relationName) => {
2
+ const result = await pool.query(`
3
+ SELECT
4
+ s.tablename AS relation_name,
5
+ c.reltuples::bigint AS estimated_row_count,
6
+ s.attname AS attribute_name,
7
+ CASE
8
+ WHEN s.n_distinct > 0 THEN s.n_distinct
9
+ ELSE abs(s.n_distinct) * c.reltuples
10
+ END::bigint AS estimated_distinct
11
+ FROM pg_catalog.pg_stats s
12
+ JOIN pg_catalog.pg_class c ON c.relname = s.tablename
13
+ JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND n.nspname = s.schemaname
14
+ WHERE s.schemaname = 'public'
15
+ AND s.tablename = $1
16
+ ORDER BY s.attnum
17
+ `, [relationName]);
18
+ if (result.rows.length === 0) {
19
+ return {
20
+ relation_name: relationName,
21
+ estimated_row_count: 0,
22
+ attributes: [],
23
+ };
24
+ }
25
+ return {
26
+ relation_name: result.rows[0].relation_name,
27
+ estimated_row_count: result.rows[0].estimated_row_count,
28
+ attributes: result.rows.map(({ attribute_name, estimated_distinct }) => ({
29
+ attribute_name,
30
+ estimated_distinct,
31
+ })),
32
+ };
33
+ };
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdHMubWpzIiwic291cmNlUm9vdCI6Ii4vc3JjLyIsInNvdXJjZXMiOlsiZGIvc3RhdHMubXRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWFBLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLEtBQUssRUFBRSxJQUFVLEVBQUUsWUFBb0IsRUFBMkIsRUFBRTtJQUNsRyxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQzNCOzs7Ozs7Ozs7Ozs7Ozs7U0FlQyxFQUNELENBQUMsWUFBWSxDQUFDLENBQ2pCLENBQUM7SUFFRixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzNCLE9BQU87WUFDSCxhQUFhLEVBQUUsWUFBWTtZQUMzQixtQkFBbUIsRUFBRSxDQUFDO1lBQ3RCLFVBQVUsRUFBRSxFQUFFO1NBQ2pCLENBQUM7SUFDTixDQUFDO0lBRUQsT0FBTztRQUNILGFBQWEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWE7UUFDM0MsbUJBQW1CLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUI7UUFDdkQsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNyRSxjQUFjO1lBQ2Qsa0JBQWtCO1NBQ3JCLENBQUMsQ0FBQztLQUNOLENBQUM7QUFDTixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFBvb2wgfSBmcm9tIFwicGdcIjtcblxuZXhwb3J0IHR5cGUgVEF0dHJpYnV0ZVN0YXRzID0ge1xuICAgIGF0dHJpYnV0ZV9uYW1lOiBzdHJpbmc7XG4gICAgZXN0aW1hdGVkX2Rpc3RpbmN0OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBUUmVsYXRpb25TdGF0cyA9IHtcbiAgICByZWxhdGlvbl9uYW1lOiBzdHJpbmc7XG4gICAgZXN0aW1hdGVkX3Jvd19jb3VudDogbnVtYmVyO1xuICAgIGF0dHJpYnV0ZXM6IFRBdHRyaWJ1dGVTdGF0c1tdO1xufTtcblxuZXhwb3J0IGNvbnN0IGZldGNoUmVsYXRpb25TdGF0cyA9IGFzeW5jIChwb29sOiBQb29sLCByZWxhdGlvbk5hbWU6IHN0cmluZyk6IFByb21pc2U8VFJlbGF0aW9uU3RhdHM+ID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwb29sLnF1ZXJ5PFRBdHRyaWJ1dGVTdGF0cyAmIHsgcmVsYXRpb25fbmFtZTogc3RyaW5nOyBlc3RpbWF0ZWRfcm93X2NvdW50OiBudW1iZXIgfT4oXG4gICAgICAgIGBcbiAgICAgICAgU0VMRUNUXG4gICAgICAgICAgICBzLnRhYmxlbmFtZSBBUyByZWxhdGlvbl9uYW1lLFxuICAgICAgICAgICAgYy5yZWx0dXBsZXM6OmJpZ2ludCBBUyBlc3RpbWF0ZWRfcm93X2NvdW50LFxuICAgICAgICAgICAgcy5hdHRuYW1lIEFTIGF0dHJpYnV0ZV9uYW1lLFxuICAgICAgICAgICAgQ0FTRVxuICAgICAgICAgICAgICAgIFdIRU4gcy5uX2Rpc3RpbmN0ID4gMCBUSEVOIHMubl9kaXN0aW5jdFxuICAgICAgICAgICAgICAgIEVMU0UgYWJzKHMubl9kaXN0aW5jdCkgKiBjLnJlbHR1cGxlc1xuICAgICAgICAgICAgRU5EOjpiaWdpbnQgQVMgZXN0aW1hdGVkX2Rpc3RpbmN0XG4gICAgICAgIEZST00gcGdfY2F0YWxvZy5wZ19zdGF0cyBzXG4gICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19jbGFzcyBjIE9OIGMucmVsbmFtZSA9IHMudGFibGVuYW1lXG4gICAgICAgIEpPSU4gcGdfY2F0YWxvZy5wZ19uYW1lc3BhY2UgbiBPTiBuLm9pZCA9IGMucmVsbmFtZXNwYWNlIEFORCBuLm5zcG5hbWUgPSBzLnNjaGVtYW5hbWVcbiAgICAgICAgV0hFUkUgcy5zY2hlbWFuYW1lID0gJ3B1YmxpYydcbiAgICAgICAgICAgIEFORCBzLnRhYmxlbmFtZSA9ICQxXG4gICAgICAgIE9SREVSIEJZIHMuYXR0bnVtXG4gICAgICAgIGAsXG4gICAgICAgIFtyZWxhdGlvbk5hbWVdXG4gICAgKTtcblxuICAgIGlmIChyZXN1bHQucm93cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlbGF0aW9uX25hbWU6IHJlbGF0aW9uTmFtZSxcbiAgICAgICAgICAgIGVzdGltYXRlZF9yb3dfY291bnQ6IDAsXG4gICAgICAgICAgICBhdHRyaWJ1dGVzOiBbXSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICByZWxhdGlvbl9uYW1lOiByZXN1bHQucm93c1swXS5yZWxhdGlvbl9uYW1lLFxuICAgICAgICBlc3RpbWF0ZWRfcm93X2NvdW50OiByZXN1bHQucm93c1swXS5lc3RpbWF0ZWRfcm93X2NvdW50LFxuICAgICAgICBhdHRyaWJ1dGVzOiByZXN1bHQucm93cy5tYXAoKHsgYXR0cmlidXRlX25hbWUsIGVzdGltYXRlZF9kaXN0aW5jdCB9KSA9PiAoe1xuICAgICAgICAgICAgYXR0cmlidXRlX25hbWUsXG4gICAgICAgICAgICBlc3RpbWF0ZWRfZGlzdGluY3QsXG4gICAgICAgIH0pKSxcbiAgICB9O1xufTtcbiJdfQ==
@@ -0,0 +1,13 @@
1
+ import type { Pool } from "pg";
2
+ export type TPostgresVersion = {
3
+ version: string;
4
+ version_num: number;
5
+ };
6
+ export declare const fetchPostgresVersion: (pool: Pool) => Promise<TPostgresVersion>;
7
+ export type TDatabaseIdentifier = {
8
+ system_identifier: string;
9
+ database_oid: number;
10
+ database_name: string;
11
+ };
12
+ export declare const fetchDatabaseIdentifier: (pool: Pool) => Promise<TDatabaseIdentifier>;
13
+ //# sourceMappingURL=version.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.mts","sourceRoot":"./src/","sources":["db/version.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,MAAM,MAAM,gBAAgB,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,gBAAgB,CAQ/E,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAU,MAAM,IAAI,KAAG,OAAO,CAAC,mBAAmB,CAUrF,CAAC"}
@@ -0,0 +1,19 @@
1
+ export const fetchPostgresVersion = async (pool) => {
2
+ const result = await pool.query(`
3
+ SELECT
4
+ current_setting('server_version') AS version,
5
+ current_setting('server_version_num')::int AS version_num
6
+ `);
7
+ return result.rows[0];
8
+ };
9
+ export const fetchDatabaseIdentifier = async (pool) => {
10
+ const result = await pool.query(`
11
+ SELECT
12
+ system_identifier::text AS system_identifier,
13
+ (SELECT oid::int FROM pg_database WHERE datname = current_database()) AS database_oid,
14
+ current_database() AS database_name
15
+ FROM pg_control_system()
16
+ `);
17
+ return result.rows[0];
18
+ };
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5tanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJkYi92ZXJzaW9uLm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFPQSxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLEVBQUUsSUFBVSxFQUE2QixFQUFFO0lBQ2hGLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBbUI7Ozs7S0FJakQsQ0FBQyxDQUFDO0lBRUgsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFCLENBQUMsQ0FBQztBQVFGLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEtBQUssRUFBRSxJQUFVLEVBQWdDLEVBQUU7SUFDdEYsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFzQjs7Ozs7O0tBTXBELENBQUMsQ0FBQztJQUVILE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFBvb2wgfSBmcm9tIFwicGdcIjtcblxuZXhwb3J0IHR5cGUgVFBvc3RncmVzVmVyc2lvbiA9IHtcbiAgICB2ZXJzaW9uOiBzdHJpbmc7XG4gICAgdmVyc2lvbl9udW06IG51bWJlcjtcbn07XG5cbmV4cG9ydCBjb25zdCBmZXRjaFBvc3RncmVzVmVyc2lvbiA9IGFzeW5jIChwb29sOiBQb29sKTogUHJvbWlzZTxUUG9zdGdyZXNWZXJzaW9uPiA9PiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcG9vbC5xdWVyeTxUUG9zdGdyZXNWZXJzaW9uPihgXG4gICAgICAgIFNFTEVDVFxuICAgICAgICAgICAgY3VycmVudF9zZXR0aW5nKCdzZXJ2ZXJfdmVyc2lvbicpIEFTIHZlcnNpb24sXG4gICAgICAgICAgICBjdXJyZW50X3NldHRpbmcoJ3NlcnZlcl92ZXJzaW9uX251bScpOjppbnQgQVMgdmVyc2lvbl9udW1cbiAgICBgKTtcblxuICAgIHJldHVybiByZXN1bHQucm93c1swXTtcbn07XG5cbmV4cG9ydCB0eXBlIFREYXRhYmFzZUlkZW50aWZpZXIgPSB7XG4gICAgc3lzdGVtX2lkZW50aWZpZXI6IHN0cmluZztcbiAgICBkYXRhYmFzZV9vaWQ6IG51bWJlcjtcbiAgICBkYXRhYmFzZV9uYW1lOiBzdHJpbmc7XG59O1xuXG5leHBvcnQgY29uc3QgZmV0Y2hEYXRhYmFzZUlkZW50aWZpZXIgPSBhc3luYyAocG9vbDogUG9vbCk6IFByb21pc2U8VERhdGFiYXNlSWRlbnRpZmllcj4gPT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHBvb2wucXVlcnk8VERhdGFiYXNlSWRlbnRpZmllcj4oYFxuICAgICAgICBTRUxFQ1RcbiAgICAgICAgICAgIHN5c3RlbV9pZGVudGlmaWVyOjp0ZXh0IEFTIHN5c3RlbV9pZGVudGlmaWVyLFxuICAgICAgICAgICAgKFNFTEVDVCBvaWQ6OmludCBGUk9NIHBnX2RhdGFiYXNlIFdIRVJFIGRhdG5hbWUgPSBjdXJyZW50X2RhdGFiYXNlKCkpIEFTIGRhdGFiYXNlX29pZCxcbiAgICAgICAgICAgIGN1cnJlbnRfZGF0YWJhc2UoKSBBUyBkYXRhYmFzZV9uYW1lXG4gICAgICAgIEZST00gcGdfY29udHJvbF9zeXN0ZW0oKVxuICAgIGApO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5yb3dzWzBdO1xufTtcbiJdfQ==