firstly 0.10.7 → 0.11.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 +12 -0
- 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/ui/SqlAdmin.svelte +11 -39
- package/esm/sqlAdmin/ui/SqlAdmin.svelte.d.ts +5 -1
- package/package.json +13 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# firstly
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#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.
|
|
8
|
+
|
|
9
|
+
## 0.10.8
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#393](https://github.com/jycouet/firstly/pull/393) [`37feeb8`](https://github.com/jycouet/firstly/commit/37feeb820a2a7867a449d14181e3be9f72df3ec5) Thanks [@jycouet](https://github.com/jycouet)! - Dependencies are `^` ranges instead of exact pins, so apps share one copy of each with their own deps. `tailwindcss` is no longer a dependency (firstly never imports it). `vite-plugin-kit-routes` 1.1.1 and `vite-plugin-stripper` 0.10.6 publish ranges too, so `@kitql/*` and `esrap` dedupe as well.
|
|
14
|
+
|
|
3
15
|
## 0.10.7
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
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
|
+
}
|
|
@@ -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>
|
|
@@ -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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firstly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Firstly, an opinionated Remult setup!",
|
|
6
6
|
"bin": {
|
|
@@ -34,19 +34,18 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@kitql/helpers": "0.8.15",
|
|
38
|
-
"@layerstack/utils": "1.0.0",
|
|
39
|
-
"@mdi/js": "7.4.47",
|
|
40
|
-
"@types/nodemailer": "8.0.0",
|
|
41
|
-
"clsx": "2.1.1",
|
|
42
|
-
"cron": "4.4.0",
|
|
43
|
-
"esm-env": "1.2.2",
|
|
44
|
-
"nodemailer": "10.0.10",
|
|
45
|
-
"svelte-sonner": "1.2.1",
|
|
46
|
-
"tailwind-merge": "3.7.0",
|
|
47
|
-
"
|
|
48
|
-
"vite-plugin-
|
|
49
|
-
"vite-plugin-stripper": "0.10.4"
|
|
37
|
+
"@kitql/helpers": "^0.8.15",
|
|
38
|
+
"@layerstack/utils": "^1.0.0",
|
|
39
|
+
"@mdi/js": "^7.4.47",
|
|
40
|
+
"@types/nodemailer": "^8.0.0",
|
|
41
|
+
"clsx": "^2.1.1",
|
|
42
|
+
"cron": "^4.4.0",
|
|
43
|
+
"esm-env": "^1.2.2",
|
|
44
|
+
"nodemailer": "^10.0.10",
|
|
45
|
+
"svelte-sonner": "^1.2.1",
|
|
46
|
+
"tailwind-merge": "^3.7.0",
|
|
47
|
+
"vite-plugin-kit-routes": "^1.1.1",
|
|
48
|
+
"vite-plugin-stripper": "^0.10.6"
|
|
50
49
|
},
|
|
51
50
|
"sideEffects": false,
|
|
52
51
|
"exports": {
|