@questpie/admin 3.2.7 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/client/components/blocks/block-editor-provider.mjs +13 -0
  2. package/dist/client/components/fields/array-field.mjs +105 -122
  3. package/dist/client/components/fields/asset-preview-field.mjs +1 -1
  4. package/dist/client/components/fields/blocks-field/blocks-field.mjs +1 -1
  5. package/dist/client/components/fields/boolean-field.mjs +1 -1
  6. package/dist/client/components/fields/date-field.mjs +1 -1
  7. package/dist/client/components/fields/datetime-field.mjs +1 -1
  8. package/dist/client/components/fields/email-field.mjs +1 -1
  9. package/dist/client/components/fields/field-wrapper.mjs +44 -15
  10. package/dist/client/components/fields/number-field.mjs +1 -1
  11. package/dist/client/components/fields/object-array-field.mjs +179 -149
  12. package/dist/client/components/fields/object-field.mjs +96 -87
  13. package/dist/client/components/fields/relation-picker.mjs +1 -1
  14. package/dist/client/components/fields/relation-select.mjs +1 -1
  15. package/dist/client/components/fields/rich-text-editor/index.mjs +1 -1
  16. package/dist/client/components/fields/select-field.mjs +1 -1
  17. package/dist/client/components/fields/text-field.mjs +1 -1
  18. package/dist/client/components/fields/textarea-field.mjs +1 -1
  19. package/dist/client/components/fields/time-field.mjs +1 -1
  20. package/dist/client/components/fields/upload-field.mjs +1 -1
  21. package/dist/client/components/history-sidebar.mjs +10 -4
  22. package/dist/client/components/structured-diff.mjs +367 -0
  23. package/dist/client/components/ui/sidebar.mjs +1 -1
  24. package/dist/client/hooks/use-field-options.mjs +34 -15
  25. package/dist/client/hooks/use-transition-stage.mjs +2 -2
  26. package/dist/client/utils/auto-expand-fields.mjs +1 -1
  27. package/dist/client/views/collection/auto-form-fields.mjs +23 -19
  28. package/dist/client/views/collection/cells/complex-cells.mjs +1 -1
  29. package/dist/client/views/collection/columns/build-columns.mjs +1 -1
  30. package/dist/client/views/collection/columns/column-defaults.mjs +17 -4
  31. package/dist/client/views/collection/field-renderer.mjs +19 -7
  32. package/dist/client/views/collection/form-view.mjs +10 -6
  33. package/dist/client/views/collection/table-view.mjs +19 -13
  34. package/dist/client/views/globals/global-form-view.mjs +47 -27
  35. package/dist/client/views/layout/admin-sidebar.mjs +2 -2
  36. package/dist/client.mjs +1 -1
  37. package/dist/index.mjs +1 -1
  38. package/dist/server/i18n/messages/cs.mjs +8 -0
  39. package/dist/server/i18n/messages/de.mjs +8 -0
  40. package/dist/server/i18n/messages/en.mjs +8 -0
  41. package/dist/server/i18n/messages/es.mjs +8 -0
  42. package/dist/server/i18n/messages/fr.mjs +8 -0
  43. package/dist/server/i18n/messages/pl.mjs +8 -0
  44. package/dist/server/i18n/messages/pt.mjs +8 -0
  45. package/dist/server/i18n/messages/sk.mjs +8 -0
  46. package/dist/server/modules/admin/collections/account.d.mts +50 -50
  47. package/dist/server/modules/admin/collections/admin-locks.d.mts +54 -54
  48. package/dist/server/modules/admin/collections/admin-preferences.d.mts +39 -39
  49. package/dist/server/modules/admin/collections/admin-saved-views.d.mts +47 -47
  50. package/dist/server/modules/admin/collections/apikey.d.mts +68 -68
  51. package/dist/server/modules/admin/collections/assets.d.mts +39 -39
  52. package/dist/server/modules/admin/collections/session.d.mts +42 -42
  53. package/dist/server/modules/admin/collections/user.d.mts +63 -63
  54. package/dist/server/modules/admin/collections/verification.d.mts +36 -36
  55. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  56. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  57. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  58. package/dist/server/modules/admin/routes/preview.d.mts +24 -19
  59. package/dist/server/modules/admin/routes/preview.mjs +83 -62
  60. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  61. package/dist/server/modules/admin/routes/setup.d.mts +7 -7
  62. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  63. package/dist/server/modules/admin/routes/widget-data.d.mts +5 -5
  64. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +41 -41
  65. package/dist/server/modules/audit/.generated/module.d.mts +6 -6
  66. package/dist/server/modules/audit/collections/audit-log.d.mts +80 -78
  67. package/dist/server/modules/audit/collections/audit-log.mjs +7 -2
  68. package/dist/server/modules/audit/config/localize-title.mjs +67 -0
  69. package/dist/server/modules/audit/index.d.mts +2 -1
  70. package/dist/server/modules/audit/jobs/audit-cleanup.d.mts +2 -2
  71. package/dist/server/modules/audit/log-audit-entry.d.mts +85 -0
  72. package/dist/server/modules/audit/log-audit-entry.mjs +125 -0
  73. package/dist/server/plugin.mjs +4 -4
  74. package/dist/server.d.mts +2 -1
  75. package/dist/server.mjs +2 -1
  76. package/dist/shared/preview-utils.d.mts +4 -4
  77. package/dist/shared/preview-utils.mjs +5 -7
  78. package/package.json +3 -3
  79. package/dist/client/hooks/use-audit-history.mjs +0 -38
@@ -1,10 +1,10 @@
1
1
  import { FilterOperator, FilterRule, SortConfig, ViewConfiguration } from "../../../../shared/types/saved-views.types.mjs";
2
- import * as questpie_shared0 from "questpie/shared";
3
- import * as questpie36 from "questpie";
2
+ import * as questpie_shared16 from "questpie/shared";
3
+ import * as questpie69 from "questpie";
4
4
  import * as questpie_src_server_modules_core_fields_email_js1 from "questpie/src/server/modules/core/fields/email.js";
5
5
  import * as questpie_src_server_modules_core_fields_json_js1 from "questpie/src/server/modules/core/fields/json.js";
6
- import * as drizzle_orm_pg_core0 from "drizzle-orm/pg-core";
7
- import * as drizzle_orm0 from "drizzle-orm";
6
+ import * as drizzle_orm_pg_core22 from "drizzle-orm/pg-core";
7
+ import * as drizzle_orm5 from "drizzle-orm";
8
8
 
9
9
  //#region src/server/modules/admin-preferences/collections/saved-views.d.ts
10
10
 
@@ -31,61 +31,61 @@ import * as drizzle_orm0 from "drizzle-orm";
31
31
  * });
32
32
  * ```
33
33
  */
34
- declare const savedViewsCollection: questpie36.CollectionBuilder<questpie_shared0.Override<questpie_shared0.Override<questpie36.EmptyCollectionState<"admin_saved_views", undefined, {
35
- readonly text: typeof questpie36.text;
36
- readonly textarea: typeof questpie36.textarea;
34
+ declare const savedViewsCollection: questpie69.CollectionBuilder<questpie_shared16.Override<questpie_shared16.Override<questpie69.EmptyCollectionState<"admin_saved_views", undefined, {
35
+ readonly text: typeof questpie69.text;
36
+ readonly textarea: typeof questpie69.textarea;
37
37
  readonly email: typeof questpie_src_server_modules_core_fields_email_js1.email;
38
- readonly url: typeof questpie36.url;
39
- readonly number: typeof questpie36.number;
40
- readonly boolean: typeof questpie36.boolean;
41
- readonly date: typeof questpie36.date;
42
- readonly datetime: typeof questpie36.datetime;
43
- readonly time: typeof questpie36.time;
44
- readonly select: typeof questpie36.select;
45
- readonly upload: typeof questpie36.upload;
46
- readonly relation: typeof questpie36.relation;
47
- readonly object: typeof questpie36.object;
38
+ readonly url: typeof questpie69.url;
39
+ readonly number: typeof questpie69.number;
40
+ readonly boolean: typeof questpie69.boolean;
41
+ readonly date: typeof questpie69.date;
42
+ readonly datetime: typeof questpie69.datetime;
43
+ readonly time: typeof questpie69.time;
44
+ readonly select: typeof questpie69.select;
45
+ readonly upload: typeof questpie69.upload;
46
+ readonly relation: typeof questpie69.relation;
47
+ readonly object: typeof questpie69.object;
48
48
  readonly json: typeof questpie_src_server_modules_core_fields_json_js1.json;
49
- readonly from: typeof questpie36.from;
49
+ readonly from: typeof questpie69.from;
50
50
  }>, {
51
51
  fields: {
52
- readonly userId: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
53
- readonly collectionName: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
54
- readonly name: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
55
- readonly configuration: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgJsonbBuilder>;
56
- readonly isDefault: drizzle_orm0.HasDefault<drizzle_orm_pg_core0.PgBooleanBuilder>;
52
+ readonly userId: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
53
+ readonly collectionName: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
54
+ readonly name: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
55
+ readonly configuration: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgJsonbBuilder>;
56
+ readonly isDefault: drizzle_orm5.HasDefault<drizzle_orm_pg_core22.PgBooleanBuilder>;
57
57
  };
58
58
  localized: readonly string[];
59
59
  fieldDefinitions: {
60
- readonly userId: questpie36.FieldWithMethods<Omit<questpie36.TextFieldState, "notNull" | "column"> & {
60
+ readonly userId: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
61
61
  notNull: true;
62
- column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
62
+ column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
63
63
  } & {
64
- label: questpie_shared0.I18nText;
65
- }, questpie36.TextFieldMethods>;
66
- readonly collectionName: questpie36.FieldWithMethods<Omit<questpie36.TextFieldState, "notNull" | "column"> & {
64
+ label: questpie_shared16.I18nText;
65
+ }, questpie69.TextFieldMethods>;
66
+ readonly collectionName: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
67
67
  notNull: true;
68
- column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
68
+ column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
69
69
  } & {
70
- label: questpie_shared0.I18nText;
71
- }, questpie36.TextFieldMethods>;
72
- readonly name: questpie36.FieldWithMethods<Omit<questpie36.TextFieldState, "notNull" | "column"> & {
70
+ label: questpie_shared16.I18nText;
71
+ }, questpie69.TextFieldMethods>;
72
+ readonly name: questpie69.FieldWithMethods<Omit<questpie69.TextFieldState, "notNull" | "column"> & {
73
73
  notNull: true;
74
- column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
74
+ column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgVarcharBuilder<[string, ...string[]]>>;
75
75
  } & {
76
- label: questpie_shared0.I18nText;
77
- }, questpie36.TextFieldMethods>;
78
- readonly configuration: questpie36.Field<Omit<questpie36.JsonFieldState, "notNull" | "column"> & {
76
+ label: questpie_shared16.I18nText;
77
+ }, questpie69.TextFieldMethods>;
78
+ readonly configuration: questpie69.Field<Omit<questpie69.JsonFieldState, "notNull" | "column"> & {
79
79
  notNull: true;
80
- column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgJsonbBuilder>;
80
+ column: drizzle_orm5.NotNull<drizzle_orm_pg_core22.PgJsonbBuilder>;
81
81
  } & {
82
- label: questpie_shared0.I18nText;
82
+ label: questpie_shared16.I18nText;
83
83
  }>;
84
- readonly isDefault: questpie36.Field<Omit<questpie36.BooleanFieldState, "column" | "hasDefault"> & {
84
+ readonly isDefault: questpie69.Field<Omit<questpie69.BooleanFieldState, "column" | "hasDefault"> & {
85
85
  hasDefault: true;
86
- column: drizzle_orm0.HasDefault<drizzle_orm_pg_core0.PgBooleanBuilder>;
86
+ column: drizzle_orm5.HasDefault<drizzle_orm_pg_core22.PgBooleanBuilder>;
87
87
  } & {
88
- label: questpie_shared0.I18nText;
88
+ label: questpie_shared16.I18nText;
89
89
  }>;
90
90
  };
91
91
  }>, {
@@ -1,6 +1,6 @@
1
1
  import { auditLogCollection } from "../collections/audit-log.mjs";
2
2
  import { auditCleanupJob } from "../jobs/audit-cleanup.mjs";
3
- import * as questpie146 from "questpie";
3
+ import * as questpie16 from "questpie";
4
4
 
5
5
  //#region src/server/modules/audit/.generated/module.d.ts
6
6
  interface AuditCollections {
@@ -43,13 +43,13 @@ declare const _module: {
43
43
  app: {
44
44
  hooks: {
45
45
  collections: {
46
- afterChange: (ctx: questpie146.GlobalCollectionHookContext) => Promise<void>;
47
- afterDelete: (ctx: questpie146.GlobalCollectionHookContext) => Promise<void>;
48
- afterTransition: (ctx: questpie146.GlobalCollectionTransitionHookContext) => Promise<void>;
46
+ afterChange: (ctx: questpie16.GlobalCollectionHookContext) => Promise<void>;
47
+ afterDelete: (ctx: questpie16.GlobalCollectionHookContext) => Promise<void>;
48
+ afterTransition: (ctx: questpie16.GlobalCollectionTransitionHookContext) => Promise<void>;
49
49
  };
50
50
  globals: {
51
- afterChange: (ctx: questpie146.GlobalGlobalHookContext) => Promise<void>;
52
- afterTransition: (ctx: questpie146.GlobalGlobalTransitionHookContext) => Promise<void>;
51
+ afterChange: (ctx: questpie16.GlobalGlobalHookContext) => Promise<void>;
52
+ afterTransition: (ctx: questpie16.GlobalGlobalTransitionHookContext) => Promise<void>;
53
53
  };
54
54
  };
55
55
  };
@@ -1,9 +1,9 @@
1
- import * as questpie_shared6 from "questpie/shared";
2
- import * as questpie98 from "questpie";
3
- import * as questpie_src_server_modules_core_fields_email_js2 from "questpie/src/server/modules/core/fields/email.js";
4
- import * as questpie_src_server_modules_core_fields_json_js2 from "questpie/src/server/modules/core/fields/json.js";
5
- import * as drizzle_orm_pg_core9 from "drizzle-orm/pg-core";
6
- import * as drizzle_orm9 from "drizzle-orm";
1
+ import * as questpie_shared0 from "questpie/shared";
2
+ import * as questpie21 from "questpie";
3
+ import * as questpie_src_server_modules_core_fields_email_js0 from "questpie/src/server/modules/core/fields/email.js";
4
+ import * as questpie_src_server_modules_core_fields_json_js0 from "questpie/src/server/modules/core/fields/json.js";
5
+ import * as drizzle_orm_pg_core0 from "drizzle-orm/pg-core";
6
+ import * as drizzle_orm0 from "drizzle-orm";
7
7
  import * as questpie_src_server_fields_operators_builtin_js0 from "questpie/src/server/fields/operators/builtin.js";
8
8
 
9
9
  //#region src/server/modules/audit/collections/audit-log.d.ts
@@ -19,140 +19,142 @@ import * as questpie_src_server_fields_operators_builtin_js0 from "questpie/src/
19
19
  * - update: disallowed
20
20
  * - read: allowed (for admin UI display)
21
21
  */
22
- declare const auditLogCollection: questpie98.CollectionBuilder<questpie_shared6.Override<questpie_shared6.Override<questpie_shared6.Override<questpie_shared6.Override<questpie_shared6.Override<questpie98.EmptyCollectionState<"admin_audit_log", undefined, {
23
- readonly text: typeof questpie98.text;
24
- readonly textarea: typeof questpie98.textarea;
25
- readonly email: typeof questpie_src_server_modules_core_fields_email_js2.email;
26
- readonly url: typeof questpie98.url;
27
- readonly number: typeof questpie98.number;
28
- readonly boolean: typeof questpie98.boolean;
29
- readonly date: typeof questpie98.date;
30
- readonly datetime: typeof questpie98.datetime;
31
- readonly time: typeof questpie98.time;
32
- readonly select: typeof questpie98.select;
33
- readonly upload: typeof questpie98.upload;
34
- readonly relation: typeof questpie98.relation;
35
- readonly object: typeof questpie98.object;
36
- readonly json: typeof questpie_src_server_modules_core_fields_json_js2.json;
37
- readonly from: typeof questpie98.from;
22
+ declare const auditLogCollection: questpie21.CollectionBuilder<questpie_shared0.Override<questpie_shared0.Override<questpie_shared0.Override<questpie_shared0.Override<questpie_shared0.Override<questpie_shared0.Override<questpie21.EmptyCollectionState<"admin_audit_log", undefined, {
23
+ readonly text: typeof questpie21.text;
24
+ readonly textarea: typeof questpie21.textarea;
25
+ readonly email: typeof questpie_src_server_modules_core_fields_email_js0.email;
26
+ readonly url: typeof questpie21.url;
27
+ readonly number: typeof questpie21.number;
28
+ readonly boolean: typeof questpie21.boolean;
29
+ readonly date: typeof questpie21.date;
30
+ readonly datetime: typeof questpie21.datetime;
31
+ readonly time: typeof questpie21.time;
32
+ readonly select: typeof questpie21.select;
33
+ readonly upload: typeof questpie21.upload;
34
+ readonly relation: typeof questpie21.relation;
35
+ readonly object: typeof questpie21.object;
36
+ readonly json: typeof questpie_src_server_modules_core_fields_json_js0.json;
37
+ readonly from: typeof questpie21.from;
38
38
  }>, {
39
39
  fields: {
40
- readonly action: drizzle_orm9.NotNull<drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>>;
41
- readonly resourceType: drizzle_orm9.NotNull<drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>>;
42
- readonly resource: drizzle_orm9.NotNull<drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>>;
43
- readonly resourceId: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
44
- readonly resourceLabel: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
45
- readonly userId: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
46
- readonly userName: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
47
- readonly locale: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
48
- readonly changes: drizzle_orm_pg_core9.PgJsonbBuilder;
49
- readonly metadata: drizzle_orm_pg_core9.PgJsonbBuilder;
50
- readonly title: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
40
+ readonly action: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
41
+ readonly resourceType: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
42
+ readonly resource: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
43
+ readonly resourceId: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
44
+ readonly resourceLabel: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
45
+ readonly userId: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
46
+ readonly userName: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
47
+ readonly locale: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
48
+ readonly changes: drizzle_orm_pg_core0.PgJsonbBuilder;
49
+ readonly metadata: drizzle_orm_pg_core0.PgJsonbBuilder;
50
+ readonly title: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
51
51
  };
52
52
  localized: readonly string[];
53
53
  fieldDefinitions: {
54
54
  /** Action performed: create, update, delete, transition, custom */
55
- readonly action: questpie98.FieldWithMethods<Omit<questpie98.TextFieldState, "notNull" | "column"> & {
55
+ readonly action: questpie21.FieldWithMethods<Omit<questpie21.TextFieldState, "notNull" | "column"> & {
56
56
  notNull: true;
57
- column: drizzle_orm9.NotNull<drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>>;
57
+ column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
58
58
  } & {
59
- label: questpie_shared6.I18nText;
60
- }, questpie98.TextFieldMethods>;
59
+ label: questpie_shared0.I18nText;
60
+ }, questpie21.TextFieldMethods>;
61
61
  /** Resource type: collection, global, auth, system, custom */
62
- readonly resourceType: questpie98.FieldWithMethods<Omit<questpie98.TextFieldState, "notNull" | "column"> & {
62
+ readonly resourceType: questpie21.FieldWithMethods<Omit<questpie21.TextFieldState, "notNull" | "column"> & {
63
63
  notNull: true;
64
- column: drizzle_orm9.NotNull<drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>>;
64
+ column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
65
65
  } & {
66
- label: questpie_shared6.I18nText;
67
- }, questpie98.TextFieldMethods>;
66
+ label: questpie_shared0.I18nText;
67
+ }, questpie21.TextFieldMethods>;
68
68
  /** Resource slug (collection/global name) */
69
- readonly resource: questpie98.FieldWithMethods<Omit<questpie98.TextFieldState, "notNull" | "column"> & {
69
+ readonly resource: questpie21.FieldWithMethods<Omit<questpie21.TextFieldState, "notNull" | "column"> & {
70
70
  notNull: true;
71
- column: drizzle_orm9.NotNull<drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>>;
71
+ column: drizzle_orm0.NotNull<drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>>;
72
72
  } & {
73
- label: questpie_shared6.I18nText;
74
- }, questpie98.TextFieldMethods>;
73
+ label: questpie_shared0.I18nText;
74
+ }, questpie21.TextFieldMethods>;
75
75
  /** ID of the specific record (null for globals) */
76
- readonly resourceId: questpie98.FieldWithMethods<questpie98.DefaultFieldState & {
76
+ readonly resourceId: questpie21.FieldWithMethods<questpie21.DefaultFieldState & {
77
77
  type: "text";
78
78
  data: string;
79
- column: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
79
+ column: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
80
80
  operators: typeof questpie_src_server_fields_operators_builtin_js0.stringOps;
81
81
  } & {
82
- label: questpie_shared6.I18nText;
83
- }, questpie98.TextFieldMethods>;
82
+ label: questpie_shared0.I18nText;
83
+ }, questpie21.TextFieldMethods>;
84
84
  /** Denormalized display label for the affected record */
85
- readonly resourceLabel: questpie98.FieldWithMethods<questpie98.DefaultFieldState & {
85
+ readonly resourceLabel: questpie21.FieldWithMethods<questpie21.DefaultFieldState & {
86
86
  type: "text";
87
87
  data: string;
88
- column: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
88
+ column: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
89
89
  operators: typeof questpie_src_server_fields_operators_builtin_js0.stringOps;
90
90
  } & {
91
- label: questpie_shared6.I18nText;
92
- }, questpie98.TextFieldMethods>;
91
+ label: questpie_shared0.I18nText;
92
+ }, questpie21.TextFieldMethods>;
93
93
  /** User who performed the action */
94
- readonly userId: questpie98.FieldWithMethods<questpie98.DefaultFieldState & {
94
+ readonly userId: questpie21.FieldWithMethods<questpie21.DefaultFieldState & {
95
95
  type: "text";
96
96
  data: string;
97
- column: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
97
+ column: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
98
98
  operators: typeof questpie_src_server_fields_operators_builtin_js0.stringOps;
99
99
  } & {
100
- label: questpie_shared6.I18nText;
101
- }, questpie98.TextFieldMethods>;
100
+ label: questpie_shared0.I18nText;
101
+ }, questpie21.TextFieldMethods>;
102
102
  /** Denormalized user display name */
103
- readonly userName: questpie98.FieldWithMethods<questpie98.DefaultFieldState & {
103
+ readonly userName: questpie21.FieldWithMethods<questpie21.DefaultFieldState & {
104
104
  type: "text";
105
105
  data: string;
106
- column: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
106
+ column: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
107
107
  operators: typeof questpie_src_server_fields_operators_builtin_js0.stringOps;
108
108
  } & {
109
- label: questpie_shared6.I18nText;
110
- }, questpie98.TextFieldMethods>;
109
+ label: questpie_shared0.I18nText;
110
+ }, questpie21.TextFieldMethods>;
111
111
  /** Locale context of the operation */
112
- readonly locale: questpie98.FieldWithMethods<questpie98.DefaultFieldState & {
112
+ readonly locale: questpie21.FieldWithMethods<questpie21.DefaultFieldState & {
113
113
  type: "text";
114
114
  data: string;
115
- column: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
115
+ column: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
116
116
  operators: typeof questpie_src_server_fields_operators_builtin_js0.stringOps;
117
117
  } & {
118
- label: questpie_shared6.I18nText;
119
- }, questpie98.TextFieldMethods>;
118
+ label: questpie_shared0.I18nText;
119
+ }, questpie21.TextFieldMethods>;
120
120
  /** Field-level diffs: { field: { from, to } } or null */
121
- readonly changes: questpie98.Field<questpie98.DefaultFieldState & {
121
+ readonly changes: questpie21.Field<questpie21.DefaultFieldState & {
122
122
  type: "json";
123
- data: questpie98.JsonValue;
124
- column: drizzle_orm_pg_core9.PgJsonbBuilder;
123
+ data: questpie21.JsonValue;
124
+ column: drizzle_orm_pg_core0.PgJsonbBuilder;
125
125
  operators: typeof questpie_src_server_fields_operators_builtin_js0.basicOps;
126
126
  } & {
127
- label: questpie_shared6.I18nText;
127
+ label: questpie_shared0.I18nText;
128
128
  }>;
129
129
  /** Extra context metadata */
130
- readonly metadata: questpie98.Field<questpie98.DefaultFieldState & {
130
+ readonly metadata: questpie21.Field<questpie21.DefaultFieldState & {
131
131
  type: "json";
132
- data: questpie98.JsonValue;
133
- column: drizzle_orm_pg_core9.PgJsonbBuilder;
132
+ data: questpie21.JsonValue;
133
+ column: drizzle_orm_pg_core0.PgJsonbBuilder;
134
134
  operators: typeof questpie_src_server_fields_operators_builtin_js0.basicOps;
135
135
  } & {
136
- label: questpie_shared6.I18nText;
136
+ label: questpie_shared0.I18nText;
137
137
  }>;
138
138
  /** Human-readable title: "User Action ResourceType 'ResourceLabel'" */
139
- readonly title: questpie98.FieldWithMethods<questpie98.DefaultFieldState & {
139
+ readonly title: questpie21.FieldWithMethods<questpie21.DefaultFieldState & {
140
140
  type: "text";
141
141
  data: string;
142
- column: drizzle_orm_pg_core9.PgVarcharBuilder<[string, ...string[]]>;
142
+ column: drizzle_orm_pg_core0.PgVarcharBuilder<[string, ...string[]]>;
143
143
  operators: typeof questpie_src_server_fields_operators_builtin_js0.stringOps;
144
144
  } & {
145
- label: questpie_shared6.I18nText;
146
- }, questpie98.TextFieldMethods>;
145
+ label: questpie_shared0.I18nText;
146
+ }, questpie21.TextFieldMethods>;
147
147
  };
148
148
  }>, {
149
149
  options: {
150
150
  timestamps: true;
151
151
  };
152
152
  }>, {
153
- indexes: drizzle_orm_pg_core9.IndexBuilder[];
153
+ indexes: drizzle_orm_pg_core0.IndexBuilder[];
154
154
  }>, {
155
155
  access: Record<string, any>;
156
+ }>, {
157
+ hooks: Record<string, any>;
156
158
  }> & Record<"admin", {
157
159
  label: {
158
160
  key: string;
@@ -1,4 +1,5 @@
1
- import { collection } from "questpie";
1
+ import { localizeAuditTitle } from "../config/localize-title.mjs";
2
+ import { collection, tryGetContext } from "questpie";
2
3
  import { index } from "questpie/drizzle-pg-core";
3
4
 
4
5
  //#region src/server/modules/audit/collections/audit-log.ts
@@ -41,7 +42,11 @@ const auditLogCollection = collection(AUDIT_LOG_COLLECTION).fields(({ f }) => ({
41
42
  update: false,
42
43
  delete: false,
43
44
  read: true
44
- }).set("admin", {
45
+ }).hooks({ afterRead: ({ data, locale }) => {
46
+ if (!data) return;
47
+ const localized = localizeAuditTitle(data, locale, tryGetContext()?.app);
48
+ if (localized) data.title = localized;
49
+ } }).set("admin", {
45
50
  label: { key: "audit.collection.label" },
46
51
  icon: {
47
52
  type: "icon",
@@ -0,0 +1,67 @@
1
+ import { getAdminMessagesForLocale } from "../../../i18n/index.mjs";
2
+ import { isI18nTranslationKey, resolveI18nText } from "questpie/shared";
3
+
4
+ //#region src/server/modules/audit/config/localize-title.ts
5
+ function lookupMessage(messages, key) {
6
+ const value = messages[key];
7
+ if (typeof value === "string") return value;
8
+ if (value && typeof value === "object") {
9
+ const plural = value.other;
10
+ if (typeof plural === "string") return plural;
11
+ }
12
+ return null;
13
+ }
14
+ function makeTranslator(messages) {
15
+ return (key) => lookupMessage(messages, key) ?? key;
16
+ }
17
+ function getResourceLabel(app, resourceType, resource) {
18
+ if (!app) return null;
19
+ if (resourceType === "collection") {
20
+ const config = app.getCollectionConfig?.(resource);
21
+ return config?.state?.admin?.label ?? config?.state?.label ?? null;
22
+ }
23
+ if (resourceType === "global") {
24
+ const config = app.getGlobals?.()?.[resource];
25
+ return config?.state?.admin?.label ?? config?.state?.label ?? null;
26
+ }
27
+ return null;
28
+ }
29
+ function resolveLabel(label, locale, t) {
30
+ if (label == null) return null;
31
+ if (isI18nTranslationKey(label)) {
32
+ const resolved = t(label.key);
33
+ return resolved === label.key ? label.fallback ?? null : resolved;
34
+ }
35
+ return resolveI18nText(label, locale, t);
36
+ }
37
+ function interpolate(template, values) {
38
+ return template.replace(/\{\{\s*(\w+)\s*\}\}/g, (_m, k) => values[k] ?? `{{${k}}}`);
39
+ }
40
+ /**
41
+ * Recompute the audit log title in the viewer's locale.
42
+ * Returns null when no locale is provided so the caller can keep the stored value.
43
+ */
44
+ function localizeAuditTitle(data, locale, app) {
45
+ if (!locale) return null;
46
+ const messages = getAdminMessagesForLocale(locale);
47
+ const t = makeTranslator(messages);
48
+ const action = String(data.action ?? "");
49
+ const resourceType = String(data.resourceType ?? "");
50
+ const resource = String(data.resource ?? "");
51
+ const userName = String(data.userName ?? "");
52
+ const actionText = lookupMessage(messages, `audit.action.${action}`) ?? action;
53
+ const resourceTypeText = lookupMessage(messages, `audit.resourceType.${resourceType}`) ?? resourceType;
54
+ const resourceName = resolveLabel(getResourceLabel(app, resourceType, resource), locale, t) ?? resource;
55
+ const rawLabel = typeof data.resourceLabel === "string" && data.resourceLabel.length > 0 ? data.resourceLabel : null;
56
+ const unnamed = lookupMessage(messages, "audit.unnamed") ?? "(unnamed)";
57
+ const resourceLabel = rawLabel ? `'${rawLabel}'` : unnamed;
58
+ return interpolate(lookupMessage(messages, "audit.title.template") ?? "{{userName}} {{action}} {{resourceType}} {{resourceLabel}}", {
59
+ userName,
60
+ action: actionText,
61
+ resourceType: `${resourceTypeText} ${resourceName}`,
62
+ resourceLabel
63
+ });
64
+ }
65
+
66
+ //#endregion
67
+ export { localizeAuditTitle };
@@ -1,2 +1,3 @@
1
1
  import { auditLogCollection } from "./collections/audit-log.mjs";
2
- import { AuditModule, _module } from "./.generated/module.mjs";
2
+ import { AuditModule, _module } from "./.generated/module.mjs";
3
+ import { AuditActorType, AuditContext, LogAuditEntryOptions, logAuditEntry } from "./log-audit-entry.mjs";
@@ -1,4 +1,4 @@
1
- import * as questpie461 from "questpie";
1
+ import * as questpie151 from "questpie";
2
2
 
3
3
  //#region src/server/modules/audit/jobs/audit-cleanup.d.ts
4
4
 
@@ -6,7 +6,7 @@ import * as questpie461 from "questpie";
6
6
  * Audit log cleanup job.
7
7
  * Runs daily (via cron) to delete entries older than the configured retention period.
8
8
  */
9
- declare const auditCleanupJob: questpie461.JobDefinition<{
9
+ declare const auditCleanupJob: questpie151.JobDefinition<{
10
10
  retentionDays: number;
11
11
  }, void, "audit-cleanup">;
12
12
  //#endregion
@@ -0,0 +1,85 @@
1
+ //#region src/server/modules/audit/log-audit-entry.d.ts
2
+ /**
3
+ * Options for a custom audit log entry.
4
+ */
5
+ type AuditActorType = "anonymous" | "system" | "user" | (string & {});
6
+ interface LogAuditEntryOptions {
7
+ /** Action performed (e.g., "create", "bulk-email", "archive", "migrate"). */
8
+ action: string;
9
+ /**
10
+ * Category of the affected resource.
11
+ * Built-in: "collection" | "global"
12
+ * Custom: "system" | "job" | "webhook" | any string
13
+ */
14
+ resourceType: string;
15
+ /** Resource identifier (e.g., collection slug, job name). */
16
+ resource: string;
17
+ /** Optional ID of a specific record. */
18
+ resourceId?: string | null;
19
+ /** Display label for the affected resource (e.g., record title, job description). */
20
+ resourceLabel?: string | null;
21
+ /** Override actor user name (auto-resolved from session when omitted). */
22
+ userName?: string;
23
+ /** Override actor user ID (auto-resolved from session when omitted). */
24
+ userId?: string | null;
25
+ /** Override actor category stored in metadata. */
26
+ actorType?: AuditActorType;
27
+ /** Locale context of the operation. */
28
+ locale?: string | null;
29
+ /** Field-level changes, or arbitrary structured data. */
30
+ changes?: Record<string, unknown> | null;
31
+ /** Extra metadata (e.g., job payload, webhook source). */
32
+ metadata?: Record<string, unknown> | null;
33
+ }
34
+ /**
35
+ * Audit context — pass the hook/job context directly.
36
+ * Needs `collections` (or `app.collections`) and optionally `session`, `db`.
37
+ */
38
+ interface AuditContext {
39
+ collections?: Record<string, any>;
40
+ app?: {
41
+ collections?: Record<string, any>;
42
+ getCollectionConfig?: (slug: string) => any;
43
+ getGlobals?: () => Record<string, any>;
44
+ };
45
+ session?: {
46
+ user?: Record<string, unknown> | null;
47
+ } | null;
48
+ accessMode?: string;
49
+ db?: unknown;
50
+ logger?: {
51
+ error?: (...args: any[]) => void;
52
+ };
53
+ }
54
+ /**
55
+ * Write a custom audit log entry.
56
+ *
57
+ * Use this in jobs, custom actions, webhooks, or anywhere you want
58
+ * to record a meaningful event in the audit trail.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * import { logAuditEntry } from "@questpie/admin/server";
63
+ *
64
+ * // Inside a job handler:
65
+ * await logAuditEntry(ctx, {
66
+ * action: "bulk-email",
67
+ * resourceType: "system",
68
+ * resource: "newsletter",
69
+ * resourceLabel: "Q1 Campaign",
70
+ * metadata: { sentCount: 1234, jobId: ctx.id },
71
+ * });
72
+ *
73
+ * // Inside a collection hook with session:
74
+ * await logAuditEntry(ctx, {
75
+ * action: "export",
76
+ * resourceType: "collection",
77
+ * resource: "orders",
78
+ * resourceLabel: "Monthly export",
79
+ * changes: { format: { from: null, to: "csv" } },
80
+ * });
81
+ * ```
82
+ */
83
+ declare function logAuditEntry(ctx: AuditContext, options: LogAuditEntryOptions): Promise<void>;
84
+ //#endregion
85
+ export { AuditActorType, AuditContext, LogAuditEntryOptions, logAuditEntry };