firstly 0.3.0 → 0.4.1
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 +60 -0
- package/esm/SqlDatabase/FF_LogToConsole.js +9 -14
- package/esm/carbone/CarboneController.js +2 -1
- package/esm/changeLog/index.d.ts +0 -5
- package/esm/core/FF_Allow.d.ts +55 -0
- package/esm/core/FF_Allow.js +54 -0
- package/esm/core/FF_Filter.d.ts +55 -0
- package/esm/core/FF_Filter.js +57 -0
- package/esm/core/helper.d.ts +2 -0
- package/esm/core/helper.js +3 -0
- package/esm/core/index.d.ts +0 -0
- package/esm/core/index.js +5 -0
- package/esm/core/tailwind.d.ts +21 -0
- package/esm/core/tailwind.js +22 -0
- package/esm/core/tryCatch.d.ts +44 -0
- package/esm/core/tryCatch.js +34 -0
- package/esm/cron/server/index.js +1 -1
- package/esm/feedback/FeedbackController.js +3 -2
- package/esm/feedback/index.d.ts +7 -2
- package/esm/feedback/index.js +1 -2
- package/esm/feedback/server/index.d.ts +0 -5
- package/esm/feedback/server/index.js +1 -1
- package/esm/formats/strings.js +2 -2
- package/esm/index.d.ts +18 -0
- package/esm/index.js +15 -0
- package/esm/sqlAdmin/Roles_SqlAdmin.d.ts +3 -0
- package/esm/sqlAdmin/Roles_SqlAdmin.js +3 -0
- package/esm/sqlAdmin/SqlAdminController.d.ts +9 -0
- package/esm/sqlAdmin/SqlAdminController.js +23 -0
- package/esm/sqlAdmin/index.d.ts +6 -0
- package/esm/sqlAdmin/index.js +6 -0
- package/esm/sqlAdmin/server/index.d.ts +40 -0
- package/esm/sqlAdmin/server/index.js +40 -0
- package/esm/sqlAdmin/ui/SqlAdmin.svelte +146 -0
- package/esm/sqlAdmin/ui/SqlAdmin.svelte.d.ts +3 -0
- package/esm/svelte/FF_Repo.svelte.d.ts +0 -2
- package/esm/svelte/FF_Repo.svelte.js +1 -17
- package/esm/svelte/helpers/debounce.js +1 -1
- package/esm/svelte/index.d.ts +2 -24
- package/esm/svelte/index.js +2 -22
- package/esm/{ui → svelte/ui}/Icon.svelte +1 -1
- package/esm/virtual/StateDemoEnum.d.ts +3 -3
- package/esm/virtual/StateDemoEnum.js +3 -3
- package/esm/virtual/UIEntity.js +1 -2
- package/package.json +15 -24
- package/esm/bin/cmd.d.ts +0 -1
- package/esm/bin/cmd.js +0 -638
- package/esm/feedback/ui/DialogIssue.svelte +0 -149
- package/esm/feedback/ui/DialogIssue.svelte.d.ts +0 -22
- package/esm/feedback/ui/DialogIssues.svelte +0 -114
- package/esm/feedback/ui/DialogIssues.svelte.d.ts +0 -22
- package/esm/feedback/ui/DialogMilestones.svelte +0 -43
- package/esm/feedback/ui/DialogMilestones.svelte.d.ts +0 -20
- package/esm/feedback/ui/Feedback.svelte +0 -16
- package/esm/feedback/ui/Feedback.svelte.d.ts +0 -18
- package/esm/internals/FF_Entity.d.ts +0 -2
- package/esm/internals/FF_Fields.d.ts +0 -11
- package/esm/internals/FF_Fields.js +0 -144
- package/esm/internals/cellsBuildor.d.ts +0 -47
- package/esm/internals/cellsBuildor.js +0 -141
- package/esm/internals/helper.d.ts +0 -49
- package/esm/internals/helper.js +0 -162
- package/esm/internals/index.d.ts +0 -78
- package/esm/internals/index.js +0 -45
- package/esm/internals/storeItem.d.ts +0 -19
- package/esm/internals/storeItem.js +0 -190
- package/esm/internals/storeList.d.ts +0 -34
- package/esm/internals/storeList.js +0 -108
- package/esm/internals/theme.d.ts +0 -4
- package/esm/internals/theme.js +0 -4
- package/esm/server/index.d.ts +0 -52
- package/esm/server/index.js +0 -87
- package/esm/svelte/FF_Cell.svelte +0 -103
- package/esm/svelte/FF_Cell.svelte.d.ts +0 -33
- package/esm/svelte/FF_Cell_Caption.svelte +0 -20
- package/esm/svelte/FF_Cell_Caption.svelte.d.ts +0 -31
- package/esm/svelte/FF_Cell_Display.svelte +0 -61
- package/esm/svelte/FF_Cell_Display.svelte.d.ts +0 -29
- package/esm/svelte/FF_Cell_Edit.svelte +0 -104
- package/esm/svelte/FF_Cell_Edit.svelte.d.ts +0 -32
- package/esm/svelte/FF_Cell_Error.svelte +0 -20
- package/esm/svelte/FF_Cell_Error.svelte.d.ts +0 -31
- package/esm/svelte/FF_Cell_Hint.svelte +0 -20
- package/esm/svelte/FF_Cell_Hint.svelte.d.ts +0 -31
- package/esm/svelte/FF_Config.svelte +0 -29
- package/esm/svelte/FF_Config.svelte.d.ts +0 -9
- package/esm/svelte/FF_Form.svelte +0 -155
- package/esm/svelte/FF_Form.svelte.d.ts +0 -37
- package/esm/svelte/FF_Grid.svelte +0 -257
- package/esm/svelte/FF_Grid.svelte.d.ts +0 -37
- package/esm/svelte/FF_Layout.svelte +0 -62
- package/esm/svelte/FF_Layout.svelte.d.ts +0 -31
- package/esm/svelte/actions/intersection.d.ts +0 -6
- package/esm/svelte/actions/intersection.js +0 -17
- package/esm/svelte/customField.d.ts +0 -69
- package/esm/svelte/customField.js +0 -4
- package/esm/svelte/dialog/DialogManagement.svelte +0 -98
- package/esm/svelte/dialog/DialogManagement.svelte.d.ts +0 -18
- package/esm/svelte/dialog/DialogPrimitive.svelte +0 -156
- package/esm/svelte/dialog/DialogPrimitive.svelte.d.ts +0 -38
- package/esm/svelte/dialog/dialog.d.ts +0 -58
- package/esm/svelte/dialog/dialog.js +0 -130
- package/esm/svelte/ff_Config.svelte.d.ts +0 -91
- package/esm/svelte/ff_Config.svelte.js +0 -111
- package/esm/svelte/firstly.css +0 -14
- package/esm/svelte/helpers.d.ts +0 -30
- package/esm/svelte/helpers.js +0 -38
- package/esm/svelte/tryCatch.d.ts +0 -12
- package/esm/svelte/tryCatch.js +0 -18
- package/esm/sveltekit/server/index.d.ts +0 -5
- package/esm/sveltekit/server/index.js +0 -24
- package/esm/ui/Button.svelte +0 -90
- package/esm/ui/Button.svelte.d.ts +0 -11
- package/esm/ui/Clipboardable.svelte +0 -25
- package/esm/ui/Clipboardable.svelte.d.ts +0 -12
- package/esm/ui/Field.svelte +0 -391
- package/esm/ui/Field.svelte.d.ts +0 -40
- package/esm/ui/FieldGroup.svelte +0 -117
- package/esm/ui/FieldGroup.svelte.d.ts +0 -44
- package/esm/ui/Grid.svelte +0 -262
- package/esm/ui/Grid.svelte.d.ts +0 -57
- package/esm/ui/Grid2.svelte +0 -290
- package/esm/ui/Grid2.svelte.d.ts +0 -57
- package/esm/ui/GridLoading.svelte +0 -58
- package/esm/ui/GridLoading.svelte.d.ts +0 -23
- package/esm/ui/GridPaginate.svelte +0 -69
- package/esm/ui/GridPaginate.svelte.d.ts +0 -23
- package/esm/ui/GridPaginate2.svelte +0 -25
- package/esm/ui/GridPaginate2.svelte.d.ts +0 -7
- package/esm/ui/Loading.svelte +0 -16
- package/esm/ui/Loading.svelte.d.ts +0 -31
- package/esm/ui/Tooltip.svelte +0 -45
- package/esm/ui/Tooltip.svelte.d.ts +0 -32
- package/esm/ui/dialog/DialogForm.svelte +0 -76
- package/esm/ui/dialog/DialogForm.svelte.d.ts +0 -21
- package/esm/ui/dialog/DialogManagement.svelte +0 -96
- package/esm/ui/dialog/DialogManagement.svelte.d.ts +0 -26
- package/esm/ui/dialog/DialogPrimitive.svelte +0 -90
- package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +0 -38
- package/esm/ui/dialog/FormEditAction.svelte +0 -62
- package/esm/ui/dialog/FormEditAction.svelte.d.ts +0 -31
- package/esm/ui/dialog/dialog.d.ts +0 -60
- package/esm/ui/dialog/dialog.js +0 -100
- package/esm/ui/index.d.ts +0 -6
- package/esm/ui/index.js +0 -20
- package/esm/ui/internals/FieldContainer.svelte +0 -39
- package/esm/ui/internals/FieldContainer.svelte.d.ts +0 -18
- package/esm/ui/internals/Input.svelte +0 -143
- package/esm/ui/internals/Input.svelte.d.ts +0 -37
- package/esm/ui/internals/Textarea.svelte +0 -66
- package/esm/ui/internals/Textarea.svelte.d.ts +0 -33
- package/esm/ui/internals/select/MultiSelectMelt.svelte +0 -260
- package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +0 -32
- package/esm/ui/internals/select/Select2.svelte +0 -88
- package/esm/ui/internals/select/Select2.svelte.d.ts +0 -12
- package/esm/ui/internals/select/SelectMelt.svelte +0 -289
- package/esm/ui/internals/select/SelectMelt.svelte.d.ts +0 -40
- package/esm/ui/internals/select/SelectRadio.svelte +0 -43
- package/esm/ui/internals/select/SelectRadio.svelte.d.ts +0 -27
- package/esm/ui/link/Link.svelte +0 -33
- package/esm/ui/link/Link.svelte.d.ts +0 -33
- package/esm/ui/link/LinkPlus.svelte +0 -63
- package/esm/ui/link/LinkPlus.svelte.d.ts +0 -9
- package/esm/utils/tailwind.d.ts +0 -2
- package/esm/utils/tailwind.js +0 -3
- package/esm/utils/transition.d.ts +0 -9
- package/esm/utils/transition.js +0 -33
- /package/esm/{internals → core}/BaseEnum.d.ts +0 -0
- /package/esm/{internals → core}/BaseEnum.js +0 -0
- /package/esm/{internals → core}/FF_Entity.js +0 -0
- /package/esm/{internals → core}/common.d.ts +0 -0
- /package/esm/{internals → core}/common.js +0 -0
- /package/esm/{utils → core}/types.d.ts +0 -0
- /package/esm/{utils → core}/types.js +0 -0
- /package/esm/{ui → svelte/ui}/Icon.svelte.d.ts +0 -0
- /package/esm/{ui → svelte/ui}/LibIcon.d.ts +0 -0
- /package/esm/{ui → svelte/ui}/LibIcon.js +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BackendMethod, SqlDatabase } from 'remult';
|
|
8
|
+
import { FF_Role } from '../core/common';
|
|
9
|
+
import { Roles_SqlAdmin } from './Roles_SqlAdmin';
|
|
10
|
+
export class SqlAdminController {
|
|
11
|
+
/** Optional override set by the `sqlAdmin()` module's `initApi`. Falls back to `SqlDatabase.getDb()`. */
|
|
12
|
+
static dp;
|
|
13
|
+
static async exec(cmd) {
|
|
14
|
+
const db = SqlAdminController.dp ?? SqlDatabase.getDb();
|
|
15
|
+
const start = performance.now();
|
|
16
|
+
const r = await db.execute(cmd);
|
|
17
|
+
const took = performance.now() - start;
|
|
18
|
+
return { r, took };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
__decorate([
|
|
22
|
+
BackendMethod({ allowed: [Roles_SqlAdmin.SqlAdmin_Admin, FF_Role.FF_Role_Admin] })
|
|
23
|
+
], SqlAdminController, "exec", null);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Log } from '@kitql/helpers';
|
|
2
|
+
export { Roles_SqlAdmin } from './Roles_SqlAdmin';
|
|
3
|
+
export { SqlAdminController } from './SqlAdminController';
|
|
4
|
+
export { default as SqlAdmin } from './ui/SqlAdmin.svelte';
|
|
5
|
+
export declare const key = "sqlAdmin";
|
|
6
|
+
export declare const log: Log;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Log } from '@kitql/helpers';
|
|
2
|
+
export { Roles_SqlAdmin } from './Roles_SqlAdmin';
|
|
3
|
+
export { SqlAdminController } from './SqlAdminController';
|
|
4
|
+
export { default as SqlAdmin } from './ui/SqlAdmin.svelte';
|
|
5
|
+
export const key = 'sqlAdmin';
|
|
6
|
+
export const log = new Log(key);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { SqlDatabase } from 'remult';
|
|
2
|
+
import { Module } from 'remult/server';
|
|
3
|
+
export type SqlAdminOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* Override the SqlDatabase used to execute queries.
|
|
6
|
+
* Defaults to `SqlDatabase.getDb()` (the active Remult data provider).
|
|
7
|
+
*/
|
|
8
|
+
dp?: () => SqlDatabase | Promise<SqlDatabase>;
|
|
9
|
+
/**
|
|
10
|
+
* The route where you mounted the `<SqlAdmin />` component.
|
|
11
|
+
* Used only for the AI hint logged on server start.
|
|
12
|
+
*
|
|
13
|
+
* @default '/sql/admin'
|
|
14
|
+
*/
|
|
15
|
+
path?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Drop-in SQL admin endpoint + companion `<SqlAdmin />` component (`firstly/sqlAdmin`).
|
|
19
|
+
*
|
|
20
|
+
* Gated by `Roles_SqlAdmin.SqlAdmin_Admin` (or the global `FF_Role.FF_Role_Admin`).
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { remultApi } from 'remult/remult-sveltekit'
|
|
25
|
+
* import { sqlAdmin } from './'
|
|
26
|
+
*
|
|
27
|
+
* export const api = remultApi({
|
|
28
|
+
* modules: [sqlAdmin()],
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* Then on any admin route:
|
|
33
|
+
* ```svelte
|
|
34
|
+
* <script>
|
|
35
|
+
* import { SqlAdmin } from '..'
|
|
36
|
+
* </script>
|
|
37
|
+
* <SqlAdmin />
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare const sqlAdmin: (opts?: SqlAdminOptions) => Module<unknown>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Module } from 'remult/server';
|
|
2
|
+
import { yellow } from '@kitql/helpers';
|
|
3
|
+
import { log } from '..';
|
|
4
|
+
import { SqlAdminController } from '../SqlAdminController';
|
|
5
|
+
/**
|
|
6
|
+
* Drop-in SQL admin endpoint + companion `<SqlAdmin />` component (`firstly/sqlAdmin`).
|
|
7
|
+
*
|
|
8
|
+
* Gated by `Roles_SqlAdmin.SqlAdmin_Admin` (or the global `FF_Role.FF_Role_Admin`).
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { remultApi } from 'remult/remult-sveltekit'
|
|
13
|
+
* import { sqlAdmin } from './'
|
|
14
|
+
*
|
|
15
|
+
* export const api = remultApi({
|
|
16
|
+
* modules: [sqlAdmin()],
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Then on any admin route:
|
|
21
|
+
* ```svelte
|
|
22
|
+
* <script>
|
|
23
|
+
* import { SqlAdmin } from '..'
|
|
24
|
+
* </script>
|
|
25
|
+
* <SqlAdmin />
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export const sqlAdmin = (opts) => {
|
|
29
|
+
const path = opts?.path ?? '/sql/admin';
|
|
30
|
+
return new Module({
|
|
31
|
+
key: 'sqlAdmin',
|
|
32
|
+
controllers: [SqlAdminController],
|
|
33
|
+
initApi: async () => {
|
|
34
|
+
if (opts?.dp) {
|
|
35
|
+
SqlAdminController.dp = await opts.dp();
|
|
36
|
+
}
|
|
37
|
+
log.info(`AI Hint: visit ${yellow(path)} to query raw SQL.`);
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SQL Admin UI.
|
|
4
|
+
*
|
|
5
|
+
* Results are logged to the browser console as `for AI: <json rows>` after
|
|
6
|
+
* each successful query - chrome-devtools / AI agents inspecting the page
|
|
7
|
+
* can read them with `list_console_messages`.
|
|
8
|
+
*/
|
|
9
|
+
import { SqlAdminController } from '../SqlAdminController'
|
|
10
|
+
|
|
11
|
+
const defaultQuery = `SELECT *
|
|
12
|
+
FROM "public"."users"
|
|
13
|
+
LIMIT 10`
|
|
14
|
+
|
|
15
|
+
let sqlInput = $state(defaultQuery)
|
|
16
|
+
let result: any = $state()
|
|
17
|
+
let error = $state('')
|
|
18
|
+
let isLoading = $state(false)
|
|
19
|
+
|
|
20
|
+
const queries = {
|
|
21
|
+
default: { label: 'Default', sql: defaultQuery },
|
|
22
|
+
tables: {
|
|
23
|
+
label: 'Tables & Sizes',
|
|
24
|
+
sql: `SELECT
|
|
25
|
+
table_schema,
|
|
26
|
+
table_name,
|
|
27
|
+
pg_size_pretty(pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as total_size,
|
|
28
|
+
pg_size_pretty(pg_table_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as data_size,
|
|
29
|
+
pg_size_pretty(pg_indexes_size(quote_ident(table_schema) || '.' || quote_ident(table_name))) as index_size
|
|
30
|
+
FROM information_schema.tables
|
|
31
|
+
WHERE table_schema IN ('public', 'ff_auth')
|
|
32
|
+
ORDER BY pg_total_relation_size(quote_ident(table_schema) || '.' || quote_ident(table_name)) DESC;`,
|
|
33
|
+
},
|
|
34
|
+
indexes: {
|
|
35
|
+
label: 'Indexes',
|
|
36
|
+
sql: `SELECT *
|
|
37
|
+
FROM pg_indexes
|
|
38
|
+
WHERE schemaname = 'public'
|
|
39
|
+
ORDER BY tablename, indexname`,
|
|
40
|
+
},
|
|
41
|
+
dbSize: {
|
|
42
|
+
label: 'Database Size',
|
|
43
|
+
sql: `SELECT
|
|
44
|
+
current_database() as database_name,
|
|
45
|
+
pg_size_pretty(pg_database_size(current_database())) as database_size`,
|
|
46
|
+
},
|
|
47
|
+
} as const
|
|
48
|
+
|
|
49
|
+
console.info(
|
|
50
|
+
'[firstly/SqlAdmin] AI Hint: results are also logged as "for AI:" JSON after each query.',
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
function setPresetQuery(queryId: keyof typeof queries) {
|
|
54
|
+
sqlInput = queries[queryId].sql
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async function handleSubmit(e: Event) {
|
|
58
|
+
e.preventDefault()
|
|
59
|
+
try {
|
|
60
|
+
error = ''
|
|
61
|
+
isLoading = true
|
|
62
|
+
result = { ...(await SqlAdminController.exec(sqlInput)) }
|
|
63
|
+
console.info('for AI:', JSON.stringify(result.r.rows))
|
|
64
|
+
console.info('for humans:', result)
|
|
65
|
+
} catch (e) {
|
|
66
|
+
error = JSON.stringify(e, null, 2)
|
|
67
|
+
} finally {
|
|
68
|
+
isLoading = false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getHeaders(rows: any[]): string[] {
|
|
73
|
+
if (!rows || rows.length === 0) return []
|
|
74
|
+
return Object.keys(rows[0])
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<div class="flex flex-col gap-4">
|
|
79
|
+
<div class="flex flex-col gap-2">
|
|
80
|
+
<h2 class="text-2xl font-bold">SQL Admin</h2>
|
|
81
|
+
<p class="text-sm text-base-content/70">
|
|
82
|
+
Execute SQL queries directly on the database. Results are displayed below and also logged to the
|
|
83
|
+
browser console.
|
|
84
|
+
</p>
|
|
85
|
+
</div>
|
|
86
|
+
<div class="flex flex-wrap gap-2">
|
|
87
|
+
{#each Object.entries(queries) as [id, query] (id)}
|
|
88
|
+
<button class="btn btn-outline btn-sm" onclick={() => setPresetQuery(id as keyof typeof queries)}
|
|
89
|
+
>{query.label}</button
|
|
90
|
+
>
|
|
91
|
+
{/each}
|
|
92
|
+
</div>
|
|
93
|
+
<form onsubmit={handleSubmit} class="flex flex-col gap-4">
|
|
94
|
+
<fieldset class="fieldset">
|
|
95
|
+
<textarea
|
|
96
|
+
bind:value={sqlInput}
|
|
97
|
+
class="textarea h-52 w-full font-mono"
|
|
98
|
+
placeholder="Enter SQL command..."
|
|
99
|
+
disabled={isLoading}
|
|
100
|
+
></textarea>
|
|
101
|
+
</fieldset>
|
|
102
|
+
<div class="flex items-center gap-4">
|
|
103
|
+
<button type="submit" class="btn btn-primary" disabled={isLoading}>
|
|
104
|
+
{#if isLoading}<span class="loading loading-spinner"></span>{/if}
|
|
105
|
+
Execute SQL
|
|
106
|
+
</button>
|
|
107
|
+
{#if error}<pre class="alert flex-1 text-sm alert-error">{error.replaceAll(
|
|
108
|
+
'\\n',
|
|
109
|
+
'\n',
|
|
110
|
+
)}</pre>{/if}
|
|
111
|
+
{#if result}
|
|
112
|
+
<div class="alert flex flex-1 justify-between alert-success">
|
|
113
|
+
<span class="text-success-content">{result.took.toFixed(0)} ms</span>
|
|
114
|
+
<span class="text-success-content">{result.r.rowCount} rows</span>
|
|
115
|
+
</div>
|
|
116
|
+
{/if}
|
|
117
|
+
</div>
|
|
118
|
+
</form>
|
|
119
|
+
{#if result}
|
|
120
|
+
<div class="max-h-[600px] overflow-auto rounded-lg border border-base-300">
|
|
121
|
+
{#if result.r.rows && result.r.rows.length > 0}
|
|
122
|
+
<table class="table w-full table-zebra bg-base-200">
|
|
123
|
+
<thead class="sticky top-0 z-10 bg-base-300">
|
|
124
|
+
<tr
|
|
125
|
+
>{#each getHeaders(result.r.rows) as header, i (i)}<th>{header}</th>{/each}</tr
|
|
126
|
+
>
|
|
127
|
+
</thead>
|
|
128
|
+
<tbody>
|
|
129
|
+
{#each result.r.rows as row, r (r)}
|
|
130
|
+
<tr>
|
|
131
|
+
{#each Object.values(row) as cell, c (c)}
|
|
132
|
+
<td class="align-top">
|
|
133
|
+
{#if typeof cell === 'object'}<pre class="text-xs">{JSON.stringify(cell, null, 2)}</pre>
|
|
134
|
+
{:else}{cell === null ? 'null' : cell}{/if}
|
|
135
|
+
</td>
|
|
136
|
+
{/each}
|
|
137
|
+
</tr>
|
|
138
|
+
{/each}
|
|
139
|
+
</tbody>
|
|
140
|
+
</table>
|
|
141
|
+
{:else}
|
|
142
|
+
<div class="alert alert-info">No rows returned</div>
|
|
143
|
+
{/if}
|
|
144
|
+
</div>
|
|
145
|
+
{/if}
|
|
146
|
+
</div>
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type ClassType, type FindOptions, type GroupByOptions, type GroupByResult, type MembersOnly, type NumericKeys, type QueryOptions, type Repository } from 'remult';
|
|
2
|
-
import type { getLayoutStrict } from './customField';
|
|
3
2
|
type EmptyAggregateResult = {
|
|
4
3
|
$count: number;
|
|
5
4
|
};
|
|
@@ -73,6 +72,5 @@ export declare class FF_Repo<Entity, QueryOptions extends QueryOptionsHelper<Ent
|
|
|
73
72
|
} | undefined>;
|
|
74
73
|
create(...args: Parameters<Repository<Entity>['create']>): Entity;
|
|
75
74
|
delete(...args: Parameters<Repository<Entity>['delete']>): Promise<undefined>;
|
|
76
|
-
getLayout: getLayoutStrict<Entity>;
|
|
77
75
|
}
|
|
78
76
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { repo as remultRepo, } from 'remult';
|
|
2
2
|
import { Log } from '@kitql/helpers';
|
|
3
|
-
import { tryCatch, tryCatchSync } from '
|
|
3
|
+
import { tryCatch, tryCatchSync } from '../core/tryCatch.js';
|
|
4
4
|
export class FF_Repo {
|
|
5
5
|
ent;
|
|
6
6
|
#repo;
|
|
@@ -190,20 +190,4 @@ export class FF_Repo {
|
|
|
190
190
|
}
|
|
191
191
|
return this.loadingEnd();
|
|
192
192
|
}
|
|
193
|
-
getLayout = (o) => {
|
|
194
|
-
const layout = this.metadata.options.ui?.getLayout?.(o);
|
|
195
|
-
if (layout) {
|
|
196
|
-
return layout;
|
|
197
|
-
}
|
|
198
|
-
return {
|
|
199
|
-
key: o?.key ?? 'default',
|
|
200
|
-
type: o?.type ?? 'grid',
|
|
201
|
-
groups: [
|
|
202
|
-
{
|
|
203
|
-
key: o?.key ?? 'default',
|
|
204
|
-
fields: this.#repo.fields.toArray().filter((c) => c.apiUpdateAllowed()),
|
|
205
|
-
},
|
|
206
|
-
],
|
|
207
|
-
};
|
|
208
|
-
};
|
|
209
193
|
}
|
package/esm/svelte/index.d.ts
CHANGED
|
@@ -1,28 +1,6 @@
|
|
|
1
|
-
import type { CellMetadata, getLayout } from './customField';
|
|
2
|
-
import { default as FF_Cell_Display } from './FF_Cell_Display.svelte';
|
|
3
|
-
import { default as FF_Cell } from './FF_Cell.svelte';
|
|
4
|
-
import { default as FF_Config } from './FF_Config.svelte';
|
|
5
|
-
import { default as FF_Form } from './FF_Form.svelte';
|
|
6
|
-
import { default as FF_Grid } from './FF_Grid.svelte';
|
|
7
|
-
import { default as FF_Layout } from './FF_Layout.svelte';
|
|
8
|
-
export type { FieldTheme, FormTheme, GridTheme, Theme, EditTheme, DisplayTheme, } from './ff_Config.svelte.js';
|
|
9
|
-
export { getDynamicCustomField, getTheme, setDynamicCustomField, setTheme, getClasses, daisyTheme, defaultTheme, emptyTheme, FF_Theme, } from './ff_Config.svelte.js';
|
|
10
|
-
export { FF_Grid, FF_Form, FF_Config, FF_Layout, FF_Cell, FF_Cell_Display };
|
|
11
|
-
export type { DynamicCustomField, FieldGroup } from './customField';
|
|
12
1
|
export { FF_Repo } from './FF_Repo.svelte.js';
|
|
13
|
-
export { tryCatch, tryCatchSync } from './tryCatch';
|
|
14
|
-
export { overwriteOptions, deepMerge, isOfType } from './helpers';
|
|
15
|
-
export { dialog } from './dialog/dialog';
|
|
16
2
|
export { SP } from './class/SP.svelte';
|
|
17
3
|
export type { ParamDefinition } from './class/SP.svelte';
|
|
18
4
|
export { initRemultSvelteReactivity } from './initRemultSvelteReactivity';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
ui?: CellMetadata<valueType, entityType>['ui'];
|
|
22
|
-
}
|
|
23
|
-
interface EntityOptions<entityType> {
|
|
24
|
-
ui?: {
|
|
25
|
-
getLayout?: getLayout<entityType>;
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
}
|
|
5
|
+
export { default as Icon } from './ui/Icon.svelte';
|
|
6
|
+
export { LibIcon_Empty, LibIcon_Forbidden, LibIcon_ChevronDown, LibIcon_ChevronUp, LibIcon_ChevronLeft, LibIcon_ChevronRight, LibIcon_Search, LibIcon_Check, LibIcon_MultiCheck, LibIcon_Add, LibIcon_MultiAdd, LibIcon_Edit, LibIcon_Eye, LibIcon_EyeOff, LibIcon_Delete, LibIcon_Cross, LibIcon_Save, LibIcon_Man, LibIcon_Woman, LibIcon_Send, LibIcon_Load, LibIcon_Settings, LibIcon_Sort, LibIcon_SortAsc, LibIcon_SortDesc, } from './ui/LibIcon.js';
|
package/esm/svelte/index.js
CHANGED
|
@@ -1,25 +1,5 @@
|
|
|
1
|
-
import { default as FF_Cell_Display } from './FF_Cell_Display.svelte';
|
|
2
|
-
import { default as FF_Cell } from './FF_Cell.svelte';
|
|
3
|
-
import { default as FF_Config } from './FF_Config.svelte';
|
|
4
|
-
import { default as FF_Form } from './FF_Form.svelte';
|
|
5
|
-
import { default as FF_Grid } from './FF_Grid.svelte';
|
|
6
|
-
import { default as FF_Layout } from './FF_Layout.svelte';
|
|
7
|
-
export { getDynamicCustomField, getTheme, setDynamicCustomField, setTheme, getClasses, daisyTheme, defaultTheme, emptyTheme, FF_Theme, } from './ff_Config.svelte.js';
|
|
8
|
-
export { FF_Grid, FF_Form, FF_Config, FF_Layout, FF_Cell, FF_Cell_Display };
|
|
9
1
|
export { FF_Repo } from './FF_Repo.svelte.js';
|
|
10
|
-
export { tryCatch, tryCatchSync } from './tryCatch';
|
|
11
|
-
export { overwriteOptions, deepMerge, isOfType } from './helpers';
|
|
12
|
-
export { dialog } from './dialog/dialog';
|
|
13
2
|
export { SP } from './class/SP.svelte';
|
|
14
3
|
export { initRemultSvelteReactivity } from './initRemultSvelteReactivity';
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// - [ ] how lib defaults should be configured ?
|
|
18
|
-
// - [ ] What deault css should be provided to the user ?
|
|
19
|
-
// - [ ] Add fform in readonly mode (readonly / edit / insert ?)
|
|
20
|
-
// - [ ] Add Filter Fields
|
|
21
|
-
// - [ ] Add actions form (cancel button to form, global error, ...)
|
|
22
|
-
// - [x] Create a dedicated FF_Dialog
|
|
23
|
-
// - [ ] switch to data-ff-dialog (https://www.melt-ui.com/docs/builders/dialog example with non tailwind)
|
|
24
|
-
// - [ ] Create a [crud] demo ? a [crud]/[detail] demo ?
|
|
25
|
-
// - [ ] Add Toast ?
|
|
4
|
+
export { default as Icon } from './ui/Icon.svelte';
|
|
5
|
+
export { LibIcon_Empty, LibIcon_Forbidden, LibIcon_ChevronDown, LibIcon_ChevronUp, LibIcon_ChevronLeft, LibIcon_ChevronRight, LibIcon_Search, LibIcon_Check, LibIcon_MultiCheck, LibIcon_Add, LibIcon_MultiAdd, LibIcon_Edit, LibIcon_Eye, LibIcon_EyeOff, LibIcon_Delete, LibIcon_Cross, LibIcon_Save, LibIcon_Man, LibIcon_Woman, LibIcon_Send, LibIcon_Load, LibIcon_Settings, LibIcon_Sort, LibIcon_SortAsc, LibIcon_SortDesc, } from './ui/LibIcon.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BaseEnum } from '../
|
|
2
|
-
import type { BaseEnumOptions } from '../
|
|
3
|
-
import '../ui/LibIcon';
|
|
1
|
+
import { BaseEnum } from '../core/BaseEnum';
|
|
2
|
+
import type { BaseEnumOptions } from '../core/BaseEnum';
|
|
3
|
+
import '../svelte/ui/LibIcon';
|
|
4
4
|
export declare class StateDemoEnum extends BaseEnum {
|
|
5
5
|
static CHECK: StateDemoEnum;
|
|
6
6
|
static EDIT: StateDemoEnum;
|
|
@@ -6,9 +6,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
var StateDemoEnum_1;
|
|
8
8
|
import { ValueListFieldType } from 'remult';
|
|
9
|
-
import { BaseEnum } from '../
|
|
10
|
-
import '../ui/LibIcon';
|
|
11
|
-
import { LibIcon_Add, LibIcon_Delete, LibIcon_Edit } from '../ui/LibIcon';
|
|
9
|
+
import { BaseEnum } from '../core/BaseEnum';
|
|
10
|
+
import '../svelte/ui/LibIcon';
|
|
11
|
+
import { LibIcon_Add, LibIcon_Delete, LibIcon_Edit } from '../svelte/ui/LibIcon';
|
|
12
12
|
let StateDemoEnum = class StateDemoEnum extends BaseEnum {
|
|
13
13
|
static { StateDemoEnum_1 = this; }
|
|
14
14
|
static CHECK = new StateDemoEnum_1('CHECK', {
|
package/esm/virtual/UIEntity.js
CHANGED
|
@@ -42,7 +42,6 @@ __decorate([
|
|
|
42
42
|
required: true,
|
|
43
43
|
caption: "Nom de l'utilisateur",
|
|
44
44
|
placeholder: 'Jean-Yves',
|
|
45
|
-
suffix: 'SUF!',
|
|
46
45
|
})
|
|
47
46
|
], UIEntity.prototype, "username", void 0);
|
|
48
47
|
__decorate([
|
|
@@ -71,7 +70,7 @@ __decorate([
|
|
|
71
70
|
Fields.boolean({ allowNull: true })
|
|
72
71
|
], UIEntity.prototype, "isSubContractor", void 0);
|
|
73
72
|
__decorate([
|
|
74
|
-
Fields.number({ allowNull: true
|
|
73
|
+
Fields.number({ allowNull: true })
|
|
75
74
|
], UIEntity.prototype, "rate", void 0);
|
|
76
75
|
__decorate([
|
|
77
76
|
Fields.date({ allowNull: true, allowApiUpdate: false })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firstly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Firstly, an opinionated Remult setup!",
|
|
6
6
|
"funding": "https://github.com/sponsors/jycouet",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
18
|
"@sveltejs/kit": ">=1.0.0 <3.0.0",
|
|
19
|
-
"remult": ">=3.3.
|
|
19
|
+
"remult": ">=3.3.7",
|
|
20
20
|
"svelte": ">=5"
|
|
21
21
|
},
|
|
22
22
|
"peerDependenciesMeta": {
|
|
@@ -31,40 +31,25 @@
|
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@clack/prompts": "0.11.0",
|
|
35
|
-
"@kitql/internals": "0.11.0",
|
|
36
|
-
"@layerstack/svelte-actions": "1.0.0",
|
|
37
34
|
"@layerstack/utils": "1.0.0",
|
|
38
35
|
"@mdi/js": "7.4.47",
|
|
39
|
-
"@types/nodemailer": "
|
|
40
|
-
"@melt-ui/svelte": "0.86.6",
|
|
36
|
+
"@types/nodemailer": "8.0.0",
|
|
41
37
|
"clsx": "2.1.1",
|
|
42
38
|
"cron": "4.4.0",
|
|
43
|
-
"daisyui": "5.5.3",
|
|
44
39
|
"esm-env": "1.2.2",
|
|
45
|
-
"nodemailer": "
|
|
46
|
-
"svelecte": "5.3.0",
|
|
40
|
+
"nodemailer": "8.0.5",
|
|
47
41
|
"tailwind-merge": "3.5.0",
|
|
48
|
-
"tailwindcss": "4.
|
|
42
|
+
"tailwindcss": "4.2.2",
|
|
49
43
|
"vite-plugin-kit-routes": "1.0.3",
|
|
50
|
-
"vite-plugin-stripper": "0.10.
|
|
44
|
+
"vite-plugin-stripper": "0.10.1"
|
|
51
45
|
},
|
|
52
46
|
"sideEffects": false,
|
|
53
|
-
"bin": "./esm/bin/cmd.js",
|
|
54
47
|
"exports": {
|
|
55
48
|
".": {
|
|
56
49
|
"types": "./esm/index.d.ts",
|
|
57
50
|
"svelte": "./esm/index.js",
|
|
58
51
|
"default": "./esm/index.js"
|
|
59
52
|
},
|
|
60
|
-
"./internals": {
|
|
61
|
-
"types": "./esm/internals/index.d.ts",
|
|
62
|
-
"default": "./esm/internals/index.js"
|
|
63
|
-
},
|
|
64
|
-
"./server": {
|
|
65
|
-
"types": "./esm/server/index.d.ts",
|
|
66
|
-
"default": "./esm/server/index.js"
|
|
67
|
-
},
|
|
68
53
|
"./svelte": {
|
|
69
54
|
"types": "./esm/svelte/index.d.ts",
|
|
70
55
|
"svelte": "./esm/svelte/index.js",
|
|
@@ -74,9 +59,6 @@
|
|
|
74
59
|
"types": "./esm/vite/index.d.ts",
|
|
75
60
|
"default": "./esm/vite/index.js"
|
|
76
61
|
},
|
|
77
|
-
"./bin": {
|
|
78
|
-
"default": "./esm/bin/cmd.js"
|
|
79
|
-
},
|
|
80
62
|
"./formats": {
|
|
81
63
|
"types": "./esm/formats/index.d.ts",
|
|
82
64
|
"default": "./esm/formats/index.js"
|
|
@@ -116,6 +98,15 @@
|
|
|
116
98
|
"./carbone/server": {
|
|
117
99
|
"types": "./esm/carbone/server/index.d.ts",
|
|
118
100
|
"default": "./esm/carbone/server/index.js"
|
|
101
|
+
},
|
|
102
|
+
"./sqlAdmin": {
|
|
103
|
+
"types": "./esm/sqlAdmin/index.d.ts",
|
|
104
|
+
"svelte": "./esm/sqlAdmin/index.js",
|
|
105
|
+
"default": "./esm/sqlAdmin/index.js"
|
|
106
|
+
},
|
|
107
|
+
"./sqlAdmin/server": {
|
|
108
|
+
"types": "./esm/sqlAdmin/server/index.d.ts",
|
|
109
|
+
"default": "./esm/sqlAdmin/server/index.js"
|
|
119
110
|
}
|
|
120
111
|
},
|
|
121
112
|
"keywords": [
|
package/esm/bin/cmd.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|