firstly 0.10.8 → 0.12.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/CHANGELOG.md +22 -0
- package/esm/changeLog/index.d.ts +1 -0
- package/esm/changeLog/server/index.d.ts +2 -2
- package/esm/changeLog/server/index.js +2 -2
- package/esm/core/FF_Allow.d.ts +3 -3
- package/esm/core/FF_Allow.js +3 -3
- package/esm/core/FF_Filter.d.ts +3 -3
- package/esm/core/FF_Filter.js +3 -3
- package/esm/core/FF_Validators.d.ts +2 -2
- package/esm/core/FF_Validators.js +2 -2
- package/esm/core/index.d.ts +1 -0
- package/esm/core/index.js +1 -1
- package/esm/cron/server/index.d.ts +1 -1
- package/esm/cron/server/index.js +1 -1
- package/esm/mail/ui/WriteMail.svelte +1 -1
- package/esm/sqlAdmin/index.d.ts +1 -0
- package/esm/sqlAdmin/index.js +1 -0
- package/esm/sqlAdmin/presetQueries.d.ts +8 -0
- package/esm/sqlAdmin/presetQueries.js +26 -0
- package/esm/sqlAdmin/server/index.d.ts +2 -2
- package/esm/sqlAdmin/server/index.js +2 -2
- package/esm/sqlAdmin/ui/SqlAdmin.svelte +12 -41
- package/esm/sqlAdmin/ui/SqlAdmin.svelte.d.ts +5 -1
- package/esm/sqlAdmin/ui/SqlDrift.svelte +41 -41
- package/esm/svelte/FF_DialogManager.svelte +4 -4
- package/esm/svelte/FF_PromptDefault.svelte +6 -6
- package/esm/svelte/class/SP.svelte.d.ts +1 -0
- package/esm/svelte/class/SP.svelte.js +14 -15
- package/esm/svelte/dialog.svelte.d.ts +1 -1
- package/esm/svelte/grid/FF_Grid.svelte +11 -8
- package/esm/svelte/grid/buildCells.js +6 -0
- package/esm/svelte/grid/cellTypes.d.ts +4 -0
- package/esm/svelte/handleError.d.ts +8 -2
- package/esm/svelte/handleError.js +24 -2
- package/esm/svelte/index.d.ts +1 -1
- package/esm/svelte/index.js +1 -1
- package/esm/svelte/query/index.svelte.d.ts +40 -0
- package/esm/svelte/query/index.svelte.js +112 -0
- package/esm/svelte/query/read.remote.d.ts +7 -0
- package/esm/svelte/query/read.remote.js +27 -0
- package/esm/svelte/remultApiLoad.d.ts +21 -9
- package/esm/svelte/remultApiLoad.js +21 -9
- package/esm/svelte/server/handleCaching.d.ts +2 -2
- package/esm/svelte/server/handleCaching.js +1 -1
- package/esm/svelte/ui/Icon.svelte +0 -1
- package/esm/vite/index.js +11 -1
- package/package.json +8 -3
- package/bin/args.d.ts +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# firstly
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#419](https://github.com/jycouet/firstly/pull/419) [`16cfc80`](https://github.com/jycouet/firstly/commit/16cfc808e55e7cdb275020052c6207a16b12ab66) Thanks [@jycouet](https://github.com/jycouet)! - `FF_Grid`: first sort click is `desc` for Date/Number columns (`asc` otherwise), override per cell with `firstSort`. On landing, the header arrow also reflects the entity `defaultOrderBy`.
|
|
8
|
+
|
|
9
|
+
- [#405](https://github.com/jycouet/firstly/pull/405) [`5324a64`](https://github.com/jycouet/firstly/commit/5324a6471fb20fdca6a6fb16970d2235192e0431) Thanks [@jycouet](https://github.com/jycouet)! - Add experimental `queryRepo` (`firstly/svelte/query`): `$derived(await queryRepo(E).find())` with API rules on SSR, no query on hydration, and plain `repo(E)` writes refreshing it.
|
|
10
|
+
|
|
11
|
+
- [#406](https://github.com/jycouet/firstly/pull/406) [`b2f1664`](https://github.com/jycouet/firstly/commit/b2f1664429490ebb989e4dbd8c0002b0cf6e2b37) Thanks [@jycouet](https://github.com/jycouet)! - New `reloadOnStaleChunk()` for `hooks.client`: a failed lazy import in a component reloads when a new version is deployed.
|
|
12
|
+
|
|
13
|
+
- [#406](https://github.com/jycouet/firstly/pull/406) [`dac5a18`](https://github.com/jycouet/firstly/commit/dac5a18c2164bb5bedd7bd729ba74cabee57fa26) Thanks [@jycouet](https://github.com/jycouet)! - SvelteKit 3 only (Node 22.17+), stay on `0.11.x` for Kit 2. `SP` navigates with `replace: true, reset: false`: `keepFocus` and `noScroll` in `gotoOpts` now throw, use `reset`. `firstly()` sets legacy decorators and nullifies `$app/env/private` on the client. `withStaleDeployReload` reads Kit 3's `handleError` input and skips preloads.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#425](https://github.com/jycouet/firstly/pull/425) [`59d01d6`](https://github.com/jycouet/firstly/commit/59d01d6f6e862b24b50853820bdac782b2dad64d) Thanks [@jycouet](https://github.com/jycouet)! - `SP.computing` stays `true` until the navigation lands, not just until `goto` is called.
|
|
18
|
+
|
|
19
|
+
## 0.11.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- [#402](https://github.com/jycouet/firstly/pull/402) [`c19f427`](https://github.com/jycouet/firstly/commit/c19f427e24e5b9618bc1e8943ee0bc3f6b20aae1) Thanks [@jycouet](https://github.com/jycouet)! - sqlAdmin: `<SqlAdmin queries={{ ... }} />` merges app preset queries over the built-ins by title: same title overrides, new title adds a button, `false` removes one.
|
|
24
|
+
|
|
3
25
|
## 0.10.8
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
package/esm/changeLog/index.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export declare const withChangeLog: <entityType>(options?: EntityOptions<entityT
|
|
|
36
36
|
backendPreprocessFilter?: ((filter: import("remult").EntityFilter<entityType>, event: import("remult").PreprocessFilterEvent<entityType>) => import("remult").EntityFilter<entityType> | Promise<import("remult").EntityFilter<entityType>>) | undefined;
|
|
37
37
|
backendPrefilter?: import("remult").EntityFilter<entityType> | (() => import("remult").EntityFilter<entityType> | Promise<import("remult").EntityFilter<entityType>>) | undefined;
|
|
38
38
|
defaultOrderBy?: import("remult").EntityOrderBy<entityType> | undefined;
|
|
39
|
+
bulkInsert?: boolean;
|
|
39
40
|
saving?: ((entity: entityType, event: LifecycleEvent<entityType>) => Promise<any> | any) | undefined;
|
|
40
41
|
deleting?: ((entity: entityType, e: LifecycleEvent<entityType>) => Promise<any> | any) | undefined;
|
|
41
42
|
validation?: ((entity: entityType, ref: LifecycleEvent<entityType>) => Promise<any> | any) | undefined;
|
|
@@ -11,7 +11,7 @@ declare module 'remult' {
|
|
|
11
11
|
*
|
|
12
12
|
* @example
|
|
13
13
|
* ```ts
|
|
14
|
-
* import { withChangeLog } from '
|
|
14
|
+
* import { withChangeLog } from 'firstly/changeLog'
|
|
15
15
|
*
|
|
16
16
|
* \@Entity('users', withChangeLog({
|
|
17
17
|
* // ...
|
|
@@ -27,7 +27,7 @@ declare module 'remult' {
|
|
|
27
27
|
* // APP_Entity.ts example
|
|
28
28
|
* import { Entity, isBackend, type EntityOptions } from 'remult'
|
|
29
29
|
*
|
|
30
|
-
* import { withChangeLog } from '
|
|
30
|
+
* import { withChangeLog } from 'firstly/changeLog'
|
|
31
31
|
*
|
|
32
32
|
* export function APP_Entity<entityType>(
|
|
33
33
|
* key: string,
|
|
@@ -6,7 +6,7 @@ import { ChangeLog } from '../changeLogEntities';
|
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```ts
|
|
9
|
-
* import { withChangeLog } from '
|
|
9
|
+
* import { withChangeLog } from 'firstly/changeLog'
|
|
10
10
|
*
|
|
11
11
|
* \@Entity('users', withChangeLog({
|
|
12
12
|
* // ...
|
|
@@ -22,7 +22,7 @@ import { ChangeLog } from '../changeLogEntities';
|
|
|
22
22
|
* // APP_Entity.ts example
|
|
23
23
|
* import { Entity, isBackend, type EntityOptions } from 'remult'
|
|
24
24
|
*
|
|
25
|
-
* import { withChangeLog } from '
|
|
25
|
+
* import { withChangeLog } from 'firstly/changeLog'
|
|
26
26
|
*
|
|
27
27
|
* export function APP_Entity<entityType>(
|
|
28
28
|
* key: string,
|
package/esm/core/FF_Allow.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare const FF_Allow: {
|
|
|
16
16
|
* @example
|
|
17
17
|
* Owner-only update / delete (typed):
|
|
18
18
|
* ```ts
|
|
19
|
-
* import { FF_Entity, FF_Allow } from '
|
|
19
|
+
* import { FF_Entity, FF_Allow } from 'firstly'
|
|
20
20
|
*
|
|
21
21
|
* \@FF_Entity<Task>('tasks', {
|
|
22
22
|
* allowApiUpdate: FF_Allow.owner<Task>('userId'), // typed: 'userId' must be a key of Task
|
|
@@ -38,8 +38,8 @@ export declare const FF_Allow: {
|
|
|
38
38
|
* @example
|
|
39
39
|
* Admin OR owner (typed):
|
|
40
40
|
* ```ts
|
|
41
|
-
* import { FF_Entity, FF_Allow } from '
|
|
42
|
-
* import { Roles } from '../roles'
|
|
41
|
+
* import { FF_Entity, FF_Allow } from 'firstly'
|
|
42
|
+
* import { Roles } from '../roles.js'
|
|
43
43
|
*
|
|
44
44
|
* \@FF_Entity<Task>('tasks', {
|
|
45
45
|
* allowApiUpdate: FF_Allow.ownerOr<Task>({ roles: [Roles.Admin] }),
|
package/esm/core/FF_Allow.js
CHANGED
|
@@ -17,7 +17,7 @@ export const FF_Allow = {
|
|
|
17
17
|
* @example
|
|
18
18
|
* Owner-only update / delete (typed):
|
|
19
19
|
* ```ts
|
|
20
|
-
* import { FF_Entity, FF_Allow } from '
|
|
20
|
+
* import { FF_Entity, FF_Allow } from 'firstly'
|
|
21
21
|
*
|
|
22
22
|
* \@FF_Entity<Task>('tasks', {
|
|
23
23
|
* allowApiUpdate: FF_Allow.owner<Task>('userId'), // typed: 'userId' must be a key of Task
|
|
@@ -39,8 +39,8 @@ export const FF_Allow = {
|
|
|
39
39
|
* @example
|
|
40
40
|
* Admin OR owner (typed):
|
|
41
41
|
* ```ts
|
|
42
|
-
* import { FF_Entity, FF_Allow } from '
|
|
43
|
-
* import { Roles } from '../roles'
|
|
42
|
+
* import { FF_Entity, FF_Allow } from 'firstly'
|
|
43
|
+
* import { Roles } from '../roles.js'
|
|
44
44
|
*
|
|
45
45
|
* \@FF_Entity<Task>('tasks', {
|
|
46
46
|
* allowApiUpdate: FF_Allow.ownerOr<Task>({ roles: [Roles.Admin] }),
|
package/esm/core/FF_Filter.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare const FF_Filter: {
|
|
|
19
19
|
* @example
|
|
20
20
|
* Owner-only prefilter (typed):
|
|
21
21
|
* ```ts
|
|
22
|
-
* import { FF_Entity, FF_Filter } from '
|
|
22
|
+
* import { FF_Entity, FF_Filter } from 'firstly'
|
|
23
23
|
*
|
|
24
24
|
* \@FF_Entity<Task>('tasks', {
|
|
25
25
|
* apiPrefilter: () => FF_Filter.owner<Task>('userId'),
|
|
@@ -41,8 +41,8 @@ export declare const FF_Filter: {
|
|
|
41
41
|
* @example
|
|
42
42
|
* Admin sees all, others only their own (typed):
|
|
43
43
|
* ```ts
|
|
44
|
-
* import { FF_Entity, FF_Filter } from '
|
|
45
|
-
* import { Roles } from '../roles'
|
|
44
|
+
* import { FF_Entity, FF_Filter } from 'firstly'
|
|
45
|
+
* import { Roles } from '../roles.js'
|
|
46
46
|
*
|
|
47
47
|
* \@FF_Entity<Task>('tasks', {
|
|
48
48
|
* apiPrefilter: () => FF_Filter.ownerOr<Task>({ roles: [Roles.Admin] }),
|
package/esm/core/FF_Filter.js
CHANGED
|
@@ -21,7 +21,7 @@ export const FF_Filter = {
|
|
|
21
21
|
* @example
|
|
22
22
|
* Owner-only prefilter (typed):
|
|
23
23
|
* ```ts
|
|
24
|
-
* import { FF_Entity, FF_Filter } from '
|
|
24
|
+
* import { FF_Entity, FF_Filter } from 'firstly'
|
|
25
25
|
*
|
|
26
26
|
* \@FF_Entity<Task>('tasks', {
|
|
27
27
|
* apiPrefilter: () => FF_Filter.owner<Task>('userId'),
|
|
@@ -43,8 +43,8 @@ export const FF_Filter = {
|
|
|
43
43
|
* @example
|
|
44
44
|
* Admin sees all, others only their own (typed):
|
|
45
45
|
* ```ts
|
|
46
|
-
* import { FF_Entity, FF_Filter } from '
|
|
47
|
-
* import { Roles } from '../roles'
|
|
46
|
+
* import { FF_Entity, FF_Filter } from 'firstly'
|
|
47
|
+
* import { Roles } from '../roles.js'
|
|
48
48
|
*
|
|
49
49
|
* \@FF_Entity<Task>('tasks', {
|
|
50
50
|
* apiPrefilter: () => FF_Filter.ownerOr<Task>({ roles: [Roles.Admin] }),
|
|
@@ -30,8 +30,8 @@ export declare const resolveMessage: (m: LocalizedMessage) => string;
|
|
|
30
30
|
* locale resolution:
|
|
31
31
|
*
|
|
32
32
|
* ```ts
|
|
33
|
-
* import { createValidators } from '
|
|
34
|
-
* import * as m from '../paraglide/messages'
|
|
33
|
+
* import { createValidators } from 'firstly'
|
|
34
|
+
* import * as m from '../paraglide/messages.js'
|
|
35
35
|
*
|
|
36
36
|
* export const App_Validators = createValidators({
|
|
37
37
|
* email: {
|
|
@@ -36,8 +36,8 @@ export const resolveMessage = (m) => (typeof m === 'function' ? m() : m);
|
|
|
36
36
|
* locale resolution:
|
|
37
37
|
*
|
|
38
38
|
* ```ts
|
|
39
|
-
* import { createValidators } from '
|
|
40
|
-
* import * as m from '../paraglide/messages'
|
|
39
|
+
* import { createValidators } from 'firstly'
|
|
40
|
+
* import * as m from '../paraglide/messages.js'
|
|
41
41
|
*
|
|
42
42
|
* export const App_Validators = createValidators({
|
|
43
43
|
* email: {
|
package/esm/core/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/esm/core/index.js
CHANGED
package/esm/cron/server/index.js
CHANGED
package/esm/sqlAdmin/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Log } from '@kitql/helpers';
|
|
2
2
|
export { Roles_SqlAdmin } from './Roles_SqlAdmin';
|
|
3
|
+
export { builtInPresetQueries, type SqlPresetQueries } from './presetQueries';
|
|
3
4
|
export { SqlAdminController, type SqlResult, type SqlTokensOptions } from './SqlAdminController';
|
|
4
5
|
export { SqlDriftController, type SqlDriftFlag } from './SqlDriftController';
|
|
5
6
|
export { SQL_CAPABILITIES, SQL_TOKEN_TTLS, SqlToken, SqlTokenCall, type SqlCapability, type SqlTokenTtl, } from './sqlTokenEntities';
|
package/esm/sqlAdmin/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Log } from '@kitql/helpers';
|
|
2
2
|
export { Roles_SqlAdmin } from './Roles_SqlAdmin';
|
|
3
|
+
export { builtInPresetQueries } from './presetQueries';
|
|
3
4
|
export { SqlAdminController } from './SqlAdminController';
|
|
4
5
|
export { SqlDriftController } from './SqlDriftController';
|
|
5
6
|
export { SQL_CAPABILITIES, SQL_TOKEN_TTLS, SqlToken, SqlTokenCall, } from './sqlTokenEntities';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Title -> SQL. A built-in title overrides it, `false` removes it, a new title adds a button. */
|
|
2
|
+
export type SqlPresetQueries = Record<string, string | false>;
|
|
3
|
+
export declare const builtInPresetQueries: Record<string, string>;
|
|
4
|
+
/** Built-ins first (in their order), then added titles in insertion order. */
|
|
5
|
+
export declare function mergePresetQueries(queries?: SqlPresetQueries): {
|
|
6
|
+
title: string;
|
|
7
|
+
sql: string;
|
|
8
|
+
}[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export const builtInPresetQueries = {
|
|
2
|
+
Default: `SELECT *
|
|
3
|
+
FROM "public"."users"
|
|
4
|
+
LIMIT 10`,
|
|
5
|
+
'Tables & Sizes': `SELECT
|
|
6
|
+
table_schema,
|
|
7
|
+
table_name,
|
|
8
|
+
pg_size_pretty(pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as total_size,
|
|
9
|
+
pg_size_pretty(pg_table_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as data_size,
|
|
10
|
+
pg_size_pretty(pg_indexes_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as index_size
|
|
11
|
+
FROM information_schema.tables
|
|
12
|
+
WHERE table_schema IN ('public', 'ff_auth')
|
|
13
|
+
ORDER BY pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) DESC;`,
|
|
14
|
+
Indexes: `SELECT *
|
|
15
|
+
FROM pg_indexes
|
|
16
|
+
WHERE schemaname = 'public'
|
|
17
|
+
ORDER BY tablename, indexname`,
|
|
18
|
+
'Database Size': `SELECT
|
|
19
|
+
current_database() as database_name,
|
|
20
|
+
pg_size_pretty(pg_database_size(current_database())) as database_size`,
|
|
21
|
+
};
|
|
22
|
+
/** Built-ins first (in their order), then added titles in insertion order. */
|
|
23
|
+
export function mergePresetQueries(queries = {}) {
|
|
24
|
+
const merged = { ...builtInPresetQueries, ...queries };
|
|
25
|
+
return Object.entries(merged).flatMap(([title, sql]) => (sql === false ? [] : [{ title, sql }]));
|
|
26
|
+
}
|
|
@@ -65,7 +65,7 @@ export type SqlAdminOptions = {
|
|
|
65
65
|
* @example
|
|
66
66
|
* ```ts
|
|
67
67
|
* import { remultApi } from 'remult/remult-sveltekit'
|
|
68
|
-
* import { sqlAdmin } from '
|
|
68
|
+
* import { sqlAdmin } from 'firstly/sqlAdmin/server'
|
|
69
69
|
*
|
|
70
70
|
* export const api = remultApi({
|
|
71
71
|
* modules: [sqlAdmin({ tokens: { capabilities: ['read'] } })],
|
|
@@ -75,7 +75,7 @@ export type SqlAdminOptions = {
|
|
|
75
75
|
* Then on any admin route:
|
|
76
76
|
* ```svelte
|
|
77
77
|
* <script>
|
|
78
|
-
* import { SqlAdmin, SqlTokens } from '
|
|
78
|
+
* import { SqlAdmin, SqlTokens } from 'firstly/sqlAdmin'
|
|
79
79
|
* </script>
|
|
80
80
|
* <SqlAdmin />
|
|
81
81
|
* <SqlTokens />
|
|
@@ -59,7 +59,7 @@ async function resolveReadPool(opt = 'auto') {
|
|
|
59
59
|
* @example
|
|
60
60
|
* ```ts
|
|
61
61
|
* import { remultApi } from 'remult/remult-sveltekit'
|
|
62
|
-
* import { sqlAdmin } from '
|
|
62
|
+
* import { sqlAdmin } from 'firstly/sqlAdmin/server'
|
|
63
63
|
*
|
|
64
64
|
* export const api = remultApi({
|
|
65
65
|
* modules: [sqlAdmin({ tokens: { capabilities: ['read'] } })],
|
|
@@ -69,7 +69,7 @@ async function resolveReadPool(opt = 'auto') {
|
|
|
69
69
|
* Then on any admin route:
|
|
70
70
|
* ```svelte
|
|
71
71
|
* <script>
|
|
72
|
-
* import { SqlAdmin, SqlTokens } from '
|
|
72
|
+
* import { SqlAdmin, SqlTokens } from 'firstly/sqlAdmin'
|
|
73
73
|
* </script>
|
|
74
74
|
* <SqlAdmin />
|
|
75
75
|
* <SqlTokens />
|
|
@@ -11,55 +11,27 @@
|
|
|
11
11
|
* can read them with `list_console_messages`.
|
|
12
12
|
*/
|
|
13
13
|
import { log } from '../index'
|
|
14
|
+
import { mergePresetQueries, type SqlPresetQueries } from '../presetQueries'
|
|
14
15
|
import { SqlAdminController, type SqlResult } from '../SqlAdminController'
|
|
15
16
|
import { decodeSqlWire, encodeSqlWire } from '../sqlWire'
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
FROM "public"."users"
|
|
19
|
-
LIMIT 10`
|
|
18
|
+
let { queries = {} }: { queries?: SqlPresetQueries } = $props()
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
const presets = $derived(mergePresetQueries(queries))
|
|
21
|
+
|
|
22
|
+
// Seeded once: later prop changes must not clobber what the user typed.
|
|
23
|
+
const initialPresets = mergePresetQueries(queries)
|
|
24
|
+
let sqlInput = $state(
|
|
25
|
+
(initialPresets.find((q) => q.title === 'Default') ?? initialPresets[0])?.sql ?? '',
|
|
26
|
+
)
|
|
22
27
|
let result: SqlResult | undefined = $state()
|
|
23
28
|
let error = $state('')
|
|
24
29
|
let isLoading = $state(false)
|
|
25
30
|
let allowWrites = $state(false)
|
|
26
31
|
let copied = $state(false)
|
|
27
32
|
|
|
28
|
-
const queries = {
|
|
29
|
-
default: { label: 'Default', sql: defaultQuery },
|
|
30
|
-
tables: {
|
|
31
|
-
label: 'Tables & Sizes',
|
|
32
|
-
sql: `SELECT
|
|
33
|
-
table_schema,
|
|
34
|
-
table_name,
|
|
35
|
-
pg_size_pretty(pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as total_size,
|
|
36
|
-
pg_size_pretty(pg_table_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as data_size,
|
|
37
|
-
pg_size_pretty(pg_indexes_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as index_size
|
|
38
|
-
FROM information_schema.tables
|
|
39
|
-
WHERE table_schema IN ('public', 'ff_auth')
|
|
40
|
-
ORDER BY pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) DESC;`,
|
|
41
|
-
},
|
|
42
|
-
indexes: {
|
|
43
|
-
label: 'Indexes',
|
|
44
|
-
sql: `SELECT *
|
|
45
|
-
FROM pg_indexes
|
|
46
|
-
WHERE schemaname = 'public'
|
|
47
|
-
ORDER BY tablename, indexname`,
|
|
48
|
-
},
|
|
49
|
-
dbSize: {
|
|
50
|
-
label: 'Database Size',
|
|
51
|
-
sql: `SELECT
|
|
52
|
-
current_database() as database_name,
|
|
53
|
-
pg_size_pretty(pg_database_size(current_database())) as database_size`,
|
|
54
|
-
},
|
|
55
|
-
} as const
|
|
56
|
-
|
|
57
33
|
log.info('AI Hint: results are also logged as "for AI:" JSON after each query.')
|
|
58
34
|
|
|
59
|
-
function setPresetQuery(queryId: keyof typeof queries) {
|
|
60
|
-
sqlInput = queries[queryId].sql
|
|
61
|
-
}
|
|
62
|
-
|
|
63
35
|
async function handleSubmit(e: Event) {
|
|
64
36
|
e.preventDefault()
|
|
65
37
|
try {
|
|
@@ -131,11 +103,11 @@ ORDER BY tablename, indexname`,
|
|
|
131
103
|
|
|
132
104
|
<div class="flex flex-col gap-4 p-5">
|
|
133
105
|
<div class="flex flex-wrap gap-2">
|
|
134
|
-
{#each
|
|
106
|
+
{#each presets as preset (preset.title)}
|
|
135
107
|
<button
|
|
136
108
|
type="button"
|
|
137
109
|
class="border border-border bg-secondary px-3 py-1.5 text-sm font-medium text-secondary-foreground hover:bg-accent hover:text-accent-foreground disabled:opacity-50"
|
|
138
|
-
onclick={() =>
|
|
110
|
+
onclick={() => (sqlInput = preset.sql)}>{preset.title}</button
|
|
139
111
|
>
|
|
140
112
|
{/each}
|
|
141
113
|
</div>
|
|
@@ -144,8 +116,7 @@ ORDER BY tablename, indexname`,
|
|
|
144
116
|
bind:value={sqlInput}
|
|
145
117
|
class="h-52 w-full border border-input bg-background p-3 font-mono text-sm text-foreground placeholder-muted-foreground focus:border-ring focus:outline-none disabled:opacity-50"
|
|
146
118
|
placeholder="Enter SQL command..."
|
|
147
|
-
disabled={isLoading}
|
|
148
|
-
></textarea>
|
|
119
|
+
disabled={isLoading}></textarea>
|
|
149
120
|
<div class="flex flex-wrap items-center gap-4">
|
|
150
121
|
<button
|
|
151
122
|
type="submit"
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { type SqlPresetQueries } from '../presetQueries';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
queries?: SqlPresetQueries;
|
|
4
|
+
};
|
|
5
|
+
declare const SqlAdmin: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
2
6
|
type SqlAdmin = ReturnType<typeof SqlAdmin>;
|
|
3
7
|
export default SqlAdmin;
|