adminforth 2.4.0-next.7 → 2.4.0-next.71

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 (114) hide show
  1. package/commands/callTsProxy.js +14 -4
  2. package/commands/cli.js +12 -4
  3. package/commands/createApp/templates/custom/tsconfig.json.hbs +2 -3
  4. package/commands/createApp/templates/index.ts.hbs +1 -1
  5. package/commands/createApp/templates/package.json.hbs +1 -1
  6. package/commands/createApp/utils.js +39 -13
  7. package/commands/createCustomComponent/configUpdater.js +25 -21
  8. package/commands/createCustomComponent/fileGenerator.js +1 -1
  9. package/commands/createCustomComponent/main.js +2 -1
  10. package/commands/createCustomComponent/templates/login/beforeLogin.vue.hbs +18 -0
  11. package/dist/dataConnectors/baseConnector.d.ts.map +1 -1
  12. package/dist/dataConnectors/baseConnector.js +16 -3
  13. package/dist/dataConnectors/baseConnector.js.map +1 -1
  14. package/dist/dataConnectors/mongo.d.ts.map +1 -1
  15. package/dist/dataConnectors/mongo.js +14 -14
  16. package/dist/dataConnectors/mongo.js.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +20 -9
  20. package/dist/index.js.map +1 -1
  21. package/dist/modules/codeInjector.d.ts.map +1 -1
  22. package/dist/modules/codeInjector.js +25 -9
  23. package/dist/modules/codeInjector.js.map +1 -1
  24. package/dist/modules/configValidator.d.ts.map +1 -1
  25. package/dist/modules/configValidator.js +50 -1
  26. package/dist/modules/configValidator.js.map +1 -1
  27. package/dist/modules/restApi.d.ts.map +1 -1
  28. package/dist/modules/restApi.js +45 -2
  29. package/dist/modules/restApi.js.map +1 -1
  30. package/dist/modules/styles.d.ts +42 -0
  31. package/dist/modules/styles.d.ts.map +1 -1
  32. package/dist/modules/styles.js +44 -2
  33. package/dist/modules/styles.js.map +1 -1
  34. package/dist/spa/index.html +1 -1
  35. package/dist/spa/src/App.vue +14 -5
  36. package/dist/spa/src/afcl/Button.vue +4 -4
  37. package/dist/spa/src/afcl/Checkbox.vue +21 -13
  38. package/dist/spa/src/afcl/CountryFlag.vue +3 -1
  39. package/dist/spa/src/afcl/Dropzone.vue +4 -2
  40. package/dist/spa/src/afcl/Input.vue +5 -3
  41. package/dist/spa/src/afcl/JsonViewer.vue +25 -0
  42. package/dist/spa/src/afcl/Link.vue +1 -1
  43. package/dist/spa/src/afcl/LinkButton.vue +1 -1
  44. package/dist/spa/src/afcl/Select.vue +44 -15
  45. package/dist/spa/src/afcl/Table.vue +8 -8
  46. package/dist/spa/src/afcl/Toggle.vue +32 -0
  47. package/dist/spa/src/afcl/Tooltip.vue +1 -1
  48. package/dist/spa/src/afcl/index.ts +2 -2
  49. package/dist/spa/src/components/AcceptModal.vue +4 -4
  50. package/dist/spa/src/components/ColumnValueInput.vue +21 -2
  51. package/dist/spa/src/components/ColumnValueInputWrapper.vue +1 -0
  52. package/dist/spa/src/components/CustomDatePicker.vue +2 -2
  53. package/dist/spa/src/components/CustomDateRangePicker.vue +1 -0
  54. package/dist/spa/src/components/Filters.vue +73 -28
  55. package/dist/spa/src/components/GroupsTable.vue +3 -3
  56. package/dist/spa/src/components/ResourceForm.vue +61 -26
  57. package/dist/spa/src/components/ResourceListTable.vue +34 -36
  58. package/dist/spa/src/components/ResourceListTableVirtual.vue +23 -25
  59. package/dist/spa/src/components/ShowTable.vue +11 -6
  60. package/dist/spa/src/components/ValueRenderer.vue +4 -4
  61. package/dist/spa/src/controls/BoolToggle.vue +34 -0
  62. package/dist/spa/src/spa_types/core.ts +7 -0
  63. package/dist/spa/src/stores/core.ts +1 -1
  64. package/dist/spa/src/types/Back.ts +46 -12
  65. package/dist/spa/src/types/Common.ts +10 -1
  66. package/dist/spa/src/types/adapters/CompletionAdapter.ts +25 -0
  67. package/dist/spa/src/types/adapters/EmailAdapter.ts +29 -0
  68. package/dist/spa/src/types/adapters/ImageGenerationAdapter.ts +50 -0
  69. package/dist/spa/src/types/adapters/OAuth2Adapter.ts +34 -0
  70. package/dist/spa/src/types/adapters/StorageAdapter.ts +73 -0
  71. package/dist/spa/src/types/adapters/index.ts +5 -0
  72. package/dist/spa/src/utils.ts +209 -0
  73. package/dist/spa/src/views/CreateView.vue +3 -3
  74. package/dist/spa/src/views/EditView.vue +1 -1
  75. package/dist/spa/src/views/ListView.vue +2 -2
  76. package/dist/spa/src/views/LoginView.vue +39 -37
  77. package/dist/spa/src/views/ResourceParent.vue +1 -1
  78. package/dist/spa/src/views/ShowView.vue +3 -3
  79. package/dist/types/Back.d.ts +40 -9
  80. package/dist/types/Back.d.ts.map +1 -1
  81. package/dist/types/Back.js.map +1 -1
  82. package/dist/types/Common.d.ts +9 -0
  83. package/dist/types/Common.d.ts.map +1 -1
  84. package/dist/types/Common.js.map +1 -1
  85. package/dist/types/adapters/CompletionAdapter.d.ts +20 -0
  86. package/dist/types/adapters/CompletionAdapter.d.ts.map +1 -0
  87. package/dist/types/adapters/CompletionAdapter.js +2 -0
  88. package/dist/types/adapters/CompletionAdapter.js.map +1 -0
  89. package/dist/types/adapters/EmailAdapter.d.ts +21 -0
  90. package/dist/types/adapters/EmailAdapter.d.ts.map +1 -0
  91. package/dist/types/adapters/EmailAdapter.js +2 -0
  92. package/dist/types/adapters/EmailAdapter.js.map +1 -0
  93. package/dist/types/adapters/ImageGenerationAdapter.d.ts +37 -0
  94. package/dist/types/adapters/ImageGenerationAdapter.d.ts.map +1 -0
  95. package/dist/types/adapters/ImageGenerationAdapter.js +2 -0
  96. package/dist/types/adapters/ImageGenerationAdapter.js.map +1 -0
  97. package/dist/types/adapters/OAuth2Adapter.d.ts +32 -0
  98. package/dist/types/adapters/OAuth2Adapter.d.ts.map +1 -0
  99. package/dist/types/adapters/OAuth2Adapter.js +2 -0
  100. package/dist/types/adapters/OAuth2Adapter.js.map +1 -0
  101. package/dist/types/adapters/StorageAdapter.d.ts +63 -0
  102. package/dist/types/adapters/StorageAdapter.d.ts.map +1 -0
  103. package/dist/types/adapters/StorageAdapter.js +2 -0
  104. package/dist/types/adapters/StorageAdapter.js.map +1 -0
  105. package/dist/types/adapters/index.d.ts +6 -0
  106. package/dist/types/adapters/index.d.ts.map +1 -0
  107. package/dist/types/adapters/index.js +2 -0
  108. package/dist/types/adapters/index.js.map +1 -0
  109. package/package.json +2 -2
  110. package/dist/spa/src/types/Adapters.ts +0 -213
  111. package/dist/types/Adapters.d.ts +0 -168
  112. package/dist/types/Adapters.d.ts.map +0 -1
  113. package/dist/types/Adapters.js +0 -2
  114. package/dist/types/Adapters.js.map +0 -1
@@ -1,10 +1,12 @@
1
1
  <template>
2
- <div class="overflow-x-auto rounded-default shadow-resourseFormShadow dark:shadow-darkResourseFormShadow">
2
+ <div class="overflow-x-auto shadow-resourseFormShadow dark:shadow-darkResourseFormShadow"
3
+ :class="{'rounded-default' : isRounded}"
4
+ >
3
5
  <div v-if="groupName && !noTitle" class="text-md font-semibold px-6 py-3 flex flex-1 items-center dark:border-gray-600 text-gray-700 bg-lightFormHeading dark:bg-gray-700 dark:text-gray-400 rounded-t-lg">
4
6
  {{ groupName }}
5
7
  </div>
6
8
  <table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 table-fixed">
7
- <thead v-if="!allColumnsHaveCustomComponent" class="text-gray-700 dark:text-gray-400 bg-lightFormHeading dark:bg-gray-700 block md:table-row-group">
9
+ <thead v-if="!allColumnsHaveCustomComponent" class="text-gray-700 dark:text-gray-400 bg-lightFormHeading dark:bg-darkFormHeading dark:border-darkFormBorder block md:table-row-group">
8
10
  <tr>
9
11
  <th scope="col" class="px-6 py-3 text-xs uppercase hidden md:w-52 md:table-cell">
10
12
  {{ $t('Field') }}
@@ -19,7 +21,7 @@
19
21
  v-for="column in columns"
20
22
  :key="column.name"
21
23
  class="bg-lightForm border-t border-gray-100
22
- dark:bg-gray-800 dark:border-gray-700 block md:table-row"
24
+ dark:bg-darkForm dark:border-darkFormBorder block md:table-row"
23
25
  >
24
26
  <component
25
27
  v-if="column.components?.showRow"
@@ -60,7 +62,7 @@
60
62
  import { getCustomComponent } from '@/utils';
61
63
  import { useCoreStore } from '@/stores/core';
62
64
  import { computed } from 'vue';
63
- const props = defineProps<{
65
+ const props = withDefaults(defineProps<{
64
66
  columns: Array<{
65
67
  name: string;
66
68
  label: string;
@@ -80,8 +82,11 @@
80
82
  noTitle?: boolean;
81
83
  resource: Record<string, any>;
82
84
  record: Record<string, any>;
83
- }>();
84
-
85
+ isRounded?: boolean;
86
+ }>(), {
87
+ isRounded: true
88
+ });
89
+
85
90
  const coreStore = useCoreStore();
86
91
  const allColumnsHaveCustomComponent = computed(() => {
87
92
  return props.columns.every(column => {
@@ -27,8 +27,8 @@
27
27
  </span>
28
28
 
29
29
  <span v-else-if="column.type === 'boolean'">
30
- <span v-if="record[column.name] === true" class="bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">{{ $t('Yes') }}</span>
31
- <span v-else-if="record[column.name] === false" class="bg-red-100 whitespace-nowrap text-red-800gg text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">{{ $t('No') }}</span>
30
+ <span v-if="record[column.name] === true" class="af-true-value-icon bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">{{ $t('Yes') }}</span>
31
+ <span v-else-if="record[column.name] === false" class="af-false-value-icon bg-red-100 whitespace-nowrap text-red-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">{{ $t('No') }}</span>
32
32
  <span v-else class="bg-gray-100 whitespace-nowrap text-gray-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-gray-400 border border-gray-400">{{ $t('Unset') }}</span>
33
33
  </span>
34
34
  <span
@@ -39,13 +39,13 @@
39
39
  <span
40
40
  v-if="column.isArray.itemType === 'boolean' && arrayItem"
41
41
  :key="`${column.name}-${arrayItemIndex}`"
42
- class="bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">
42
+ class="af-true-value-icon bg-green-100 whitespace-nowrap text-green-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-green-400 border border-green-400">
43
43
  {{ $t('Yes') }}
44
44
  </span>
45
45
  <span
46
46
  v-else-if="column.isArray.itemType === 'boolean'"
47
47
  :key="`${column.name}-${arrayItemIndex}`"
48
- class="bg-red-100 whitespace-nowrap text-red-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">
48
+ class="af-false-value-icon bg-red-100 whitespace-nowrap text-red-800 text-xs font-medium me-2 px-2.5 py-0.5 rounded dark:bg-gray-700 dark:text-red-400 border border-red-400">
49
49
  {{ $t('No') }}
50
50
  </span>
51
51
  <span
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <Toggle
3
+ :disabled="readonly"
4
+ @update:modelValue="$emit('update:value', $event)"
5
+ :modelValue="valueFromRecord"
6
+ >
7
+ <p>{{text}}</p>
8
+ </Toggle>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import Toggle from '@/afcl/Toggle.vue';
13
+ import type {
14
+ AdminForthResourceColumnCommon,
15
+ AdminForthResourceCommon,
16
+ AdminUser,
17
+ } from "@/types/Common";
18
+
19
+ const props = defineProps<{
20
+ value: boolean,
21
+ text: string,
22
+ column: AdminForthResourceColumnCommon,
23
+ record: any,
24
+ meta: any,
25
+ resource: AdminForthResourceCommon,
26
+ adminUser: AdminUser,
27
+ readonly: boolean
28
+ }>();
29
+ console.log(JSON.stringify(props));
30
+ console.log("Current mode:", props.meta?.mode)
31
+ defineEmits(['update:value']);
32
+ const valueFromRecord = props.record[props.column.name]
33
+ const editReadOnly = props.column.editReadonly;
34
+ </script>
@@ -21,6 +21,7 @@ export type ResourceColumns = {
21
21
 
22
22
  export type CoreConfig = {
23
23
  brandName: string,
24
+ singleTheme?: 'light' | 'dark',
24
25
  brandLogo: string,
25
26
  title: string,
26
27
  datesFormat: string,
@@ -33,12 +34,18 @@ export type CoreConfig = {
33
34
  passwordHashField: string,
34
35
  loginBackgroundImage: string,
35
36
  loginBackgroundPosition: string,
37
+ removeBackgroundBlendMode: boolean,
36
38
  userFullnameField: string,
37
39
  },
38
40
  emptyFieldPlaceholder?: {
39
41
  show?: string,
40
42
  list?: string,
41
43
  } | string,
44
+
45
+ customHeadItems?: {
46
+ tagName: string;
47
+ attributes: { [key: string]: string | boolean };
48
+ }[],
42
49
  }
43
50
 
44
51
 
@@ -118,7 +118,7 @@ export const useCoreStore = defineStore('core', () => {
118
118
  item.badge = badge;
119
119
  }
120
120
  });
121
-
121
+ websocket.unsubscribeAll();
122
122
  subscribeToMenuBadges();
123
123
 
124
124
  }
@@ -92,16 +92,16 @@ export interface IExpressHttpServer extends IHttpServer {
92
92
  * Adds adminUser to request object if user is authorized. Drops request with 401 status if user is not authorized.
93
93
  * @param callable : Function which will be called if user is authorized.
94
94
  *
95
- * Example:
96
95
  *
96
+ * @example
97
97
  * ```ts
98
- * expressApp.get('/myApi', authorize((req, res) => \{
98
+ * expressApp.get('/myApi', authorize((req, res) => {
99
99
  * console.log('User is authorized', req.adminUser);
100
- * res.json(\{ message: 'Hello World' \});
101
- * \}));
102
- * ``
100
+ * res.json({ message: 'Hello World' });
101
+ * }));
102
+ * ```
103
103
  *
104
- */
104
+ */
105
105
  authorize(callable: Function): void;
106
106
  }
107
107
 
@@ -336,7 +336,7 @@ export interface IAdminForth {
336
336
 
337
337
  createResourceRecord(
338
338
  params: { resource: AdminForthResource, record: any, adminUser: AdminUser, extra?: HttpExtra }
339
- ): Promise<{ error?: string, createdRecord?: any }>;
339
+ ): Promise<{ error?: string, createdRecord?: any, newRecordId?: any }>;
340
340
 
341
341
  updateResourceRecord(
342
342
  params: { resource: AdminForthResource, recordId: any, record: any, oldRecord: any, adminUser: AdminUser, extra?: HttpExtra }
@@ -474,7 +474,7 @@ export type BeforeDataSourceRequestFunction = (params: {
474
474
  requestUrl: string,
475
475
  },
476
476
  adminforth: IAdminForth,
477
- }) => Promise<{ok: boolean, error?: string}>;
477
+ }) => Promise<{ok: boolean, error?: string, newRecordId?: string}>;
478
478
 
479
479
  /**
480
480
  * Modify response to change how data is returned after fetching from database.
@@ -525,7 +525,7 @@ export type BeforeEditSaveFunction = (params: {
525
525
  oldRecord: any,
526
526
  adminforth: IAdminForth,
527
527
  extra?: HttpExtra,
528
- }) => Promise<{ok: boolean, error?: string}>;
528
+ }) => Promise<{ok: boolean, error?: string | null}>;
529
529
 
530
530
 
531
531
 
@@ -535,7 +535,7 @@ export type BeforeCreateSaveFunction = (params: {
535
535
  record: any,
536
536
  adminforth: IAdminForth,
537
537
  extra?: HttpExtra,
538
- }) => Promise<{ok: boolean, error?: string}>;
538
+ }) => Promise<{ok: boolean, error?: string | null, newRecordId?: string}>;
539
539
 
540
540
  export type AfterCreateSaveFunction = (params: {
541
541
  resource: AdminForthResource,
@@ -619,6 +619,11 @@ interface AdminForthInputConfigCustomization {
619
619
  */
620
620
  brandName?: string,
621
621
 
622
+ /**
623
+ * Whether to use single theme for the app
624
+ */
625
+ singleTheme?: 'light' | 'dark',
626
+
622
627
  /**
623
628
  * Whether to show brand name in sidebar
624
629
  * default is true
@@ -747,6 +752,7 @@ interface AdminForthInputConfigCustomization {
747
752
  */
748
753
  loginPageInjections?: {
749
754
  underInputs?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
755
+ panelHeader?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
750
756
  }
751
757
 
752
758
  /**
@@ -758,6 +764,16 @@ interface AdminForthInputConfigCustomization {
758
764
  sidebar?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
759
765
  everyPageBottom?: AdminForthComponentDeclaration | Array<AdminForthComponentDeclaration>,
760
766
  }
767
+
768
+ /**
769
+ * Allows adding custom elements (e.g., <link>, <script>, <meta>) to the <head> of the HTML document.
770
+ * Each item must include a tag name and a set of attributes.
771
+ */
772
+ customHeadItems?: {
773
+ tagName: string;
774
+ attributes: Record<string, string | boolean>;
775
+ }[];
776
+
761
777
  }
762
778
 
763
779
  export interface AdminForthActionInput {
@@ -934,6 +950,13 @@ export interface AdminForthInputConfig {
934
950
  */
935
951
  loginBackgroundPosition?: 'over' | '1/2' | '1/3' | '2/3' | '3/4' | '2/5' | '3/5',
936
952
 
953
+ /**
954
+ * If true, background blend mode will be removed from login background image when position is 'over'
955
+ *
956
+ * Default: false
957
+ */
958
+ removeBackgroundBlendMode?: boolean,
959
+
937
960
  /**
938
961
  * Function or functions which will be called before user try to login.
939
962
  * Each function will resive User object as an argument
@@ -1054,6 +1077,7 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
1054
1077
 
1055
1078
  loginPageInjections: {
1056
1079
  underInputs: Array<AdminForthComponentDeclarationFull>,
1080
+ panelHeader: Array<AdminForthComponentDeclarationFull>,
1057
1081
  },
1058
1082
 
1059
1083
  globalInjections: {
@@ -1062,6 +1086,12 @@ export interface AdminForthConfigCustomization extends Omit<AdminForthInputConfi
1062
1086
  sidebar: Array<AdminForthComponentDeclarationFull>,
1063
1087
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1064
1088
  },
1089
+
1090
+ customHeadItems?: {
1091
+ tagName: string;
1092
+ attributes: Record<string, string | boolean>;
1093
+ }[];
1094
+
1065
1095
  }
1066
1096
 
1067
1097
  export interface AdminForthConfig extends Omit<AdminForthInputConfig, 'customization' | 'resources'> {
@@ -1316,9 +1346,13 @@ export interface AdminForthResource extends Omit<AdminForthResourceInput, 'optio
1316
1346
  },
1317
1347
  create?: {
1318
1348
  /**
1349
+ * Should return `ok: true` to continue saving pipeline and allow creating record in database, and `ok: false` to interrupt pipeline and prevent record creation.
1350
+ * If you need to show error on UI, set `error: \<error message\>` in response.
1351
+ *
1319
1352
  * Typical use-cases:
1320
- * - Validate record before saving to database and interrupt execution if validation failed (`allowedActions.create` should be preferred in most cases)
1321
- * - fill-in adminUser as creator of record
1353
+ * - Create record by custom code (return `{ ok: false, newRecordId: <id of created record from custom code> }`)
1354
+ * - Validate record before saving to database and interrupt execution if validation failed (return `{ ok: false, error: <validation error> }`), though `allowedActions.create` should be preferred in most cases
1355
+ * - fill-in adminUser as creator of record (set `record.<some field> = x; return \{ ok: true \}`)
1322
1356
  * - Attach additional data to record before saving to database (mostly fillOnCreate should be used instead)
1323
1357
  */
1324
1358
  beforeSave?: Array<BeforeCreateSaveFunction>,
@@ -584,6 +584,8 @@ export interface AdminForthForeignResourceCommon {
584
584
  polymorphicResources?: Array<AdminForthPolymorphicForeignResource>,
585
585
  polymorphicOn?: string,
586
586
  unsetLabel?: string,
587
+ searchableFields?: string | string[],
588
+ searchIsCaseSensitive?: boolean,
587
589
  }
588
590
 
589
591
  export type FillOnCreateFunction = (params: {
@@ -1055,15 +1057,18 @@ export interface AdminForthConfigForFrontend {
1055
1057
  usernameFieldName: string,
1056
1058
  loginBackgroundImage: string,
1057
1059
  loginBackgroundPosition: string,
1060
+ removeBackgroundBlendMode: boolean,
1058
1061
  title?: string,
1059
1062
  demoCredentials?: string,
1060
1063
  loginPromptHTML?: string,
1061
1064
  loginPageInjections: {
1062
1065
  underInputs: Array<AdminForthComponentDeclaration>,
1066
+ panelHeader: Array<AdminForthComponentDeclaration>,
1063
1067
  },
1064
1068
  rememberMeDays: number,
1065
1069
  showBrandNameInSidebar: boolean,
1066
1070
  brandLogo?: string,
1071
+ singleTheme?: 'light' | 'dark',
1067
1072
  datesFormat: string,
1068
1073
  timeFormat: string,
1069
1074
  auth: any,
@@ -1079,7 +1084,11 @@ export interface AdminForthConfigForFrontend {
1079
1084
  header: Array<AdminForthComponentDeclarationFull>,
1080
1085
  sidebar: Array<AdminForthComponentDeclarationFull>,
1081
1086
  everyPageBottom: Array<AdminForthComponentDeclarationFull>,
1082
- }
1087
+ },
1088
+ customHeadItems?: {
1089
+ tagName: string;
1090
+ attributes: Record<string, string | boolean>;
1091
+ }[],
1083
1092
  }
1084
1093
 
1085
1094
  export interface GetBaseConfigResponse {
@@ -0,0 +1,25 @@
1
+ export interface CompletionAdapter {
2
+
3
+ /**
4
+ * This method is called to validate the configuration of the adapter
5
+ * and should throw a clear user-readbale error if the configuration is invalid.
6
+ */
7
+ validate(): void;
8
+
9
+ /**
10
+ * This method should return a text completion based on the provided content and stop sequence.
11
+ * @param content - The input text to complete
12
+ * @param stop - An array of stop sequences to indicate where to stop the completion
13
+ * @param maxTokens - The maximum number of tokens to generate
14
+ * @returns A promise that resolves to an object containing the completed text and other metadata
15
+ */
16
+ complete(
17
+ content: string,
18
+ stop: string[],
19
+ maxTokens: number,
20
+ ): Promise<{
21
+ content?: string;
22
+ finishReason?: string;
23
+ error?: string;
24
+ }>;
25
+ }
@@ -0,0 +1,29 @@
1
+ interface EmailAdapter {
2
+
3
+ /**
4
+ * This method is called to validate the configuration of the adapter
5
+ * and should throw a clear user-readbale error if the configuration is invalid.
6
+ */
7
+ validate(): Promise<void>;
8
+
9
+ /**
10
+ * This method should send an email using the adapter
11
+ * @param from - The sender's email address
12
+ * @param to - The recipient's email address
13
+ * @param text - The plain text version of the email
14
+ * @param html - The HTML version of the email
15
+ * @param subject - The subject of the email
16
+ */
17
+ sendEmail(
18
+ from: string,
19
+ to: string,
20
+ text: string,
21
+ html: string,
22
+ subject: string
23
+ ): Promise<{
24
+ error?: string;
25
+ ok?: boolean;
26
+ }>;
27
+ }
28
+
29
+ export { EmailAdapter };
@@ -0,0 +1,50 @@
1
+ export interface ImageGenerationAdapter {
2
+
3
+ /**
4
+ * This method is called to validate the configuration of the adapter
5
+ * and should throw a clear user-readbale error if the configuration is invalid.
6
+ */
7
+ validate(): void;
8
+
9
+ /**
10
+ * Return max number of images which model can generate in one request
11
+ */
12
+ outputImagesMaxCountSupported(): number;
13
+
14
+ /**
15
+ * Return the list of supported dimensions in format ["100x500", "200x200"]
16
+ */
17
+ outputDimensionsSupported(): string[];
18
+
19
+ /**
20
+ * Input file extension supported
21
+ */
22
+ inputFileExtensionSupported(): string[];
23
+
24
+ /**
25
+ * This method should generate an image based on the provided prompt and input files.
26
+ * @param prompt - The prompt to generate the image
27
+ * @param inputFiles - An array of input file paths (optional)
28
+ * @param n - The number of images to generate (default is 1)
29
+ * @param size - The size of the generated image (default is the lowest dimension supported)
30
+ * @returns A promise that resolves to an object containing the generated image URLs and any error message
31
+ */
32
+ generate({
33
+ prompt,
34
+ inputFiles,
35
+ n,
36
+ size,
37
+ }: {
38
+ prompt: string,
39
+ inputFiles: string[],
40
+
41
+ // default = lowest dimension supported
42
+ size?: string,
43
+
44
+ // one by default
45
+ n?: number
46
+ }): Promise<{
47
+ imageURLs?: string[];
48
+ error?: string;
49
+ }>;
50
+ }
@@ -0,0 +1,34 @@
1
+
2
+ /**
3
+ * This interface is used to implement OAuth2 authentication adapters.
4
+ */
5
+ export interface OAuth2Adapter {
6
+ /**
7
+ * This method should return navigatable URL to the OAuth2 provider authentication page.
8
+ */
9
+ getAuthUrl(): string;
10
+
11
+ /**
12
+ * This method should return the token from the OAuth2 provider using the provided code and redirect URI.
13
+ * @param code - The authorization code received from the OAuth2 provider
14
+ * @param redirect_uri - The redirect URI used in the authentication request
15
+ * @returns A promise that resolves to an object containing the email address of the authenticated user
16
+ */
17
+ getTokenFromCode(code: string, redirect_uri: string): Promise<{ email: string }>;
18
+
19
+ /**
20
+ * This method should return text (content) of SVG icon which will be used in the UI.
21
+ * Use official SVG icons with simplest possible conent, omit icons which have base64 encoded raster images inside.
22
+ */
23
+ getIcon(): string;
24
+
25
+ /**
26
+ * This method should return the text to be displayed on the button in the UI
27
+ */
28
+ getButtonText?(): string;
29
+
30
+ /**
31
+ * This method should return the name of the adapter
32
+ */
33
+ getName?(): string;
34
+ }
@@ -0,0 +1,73 @@
1
+
2
+ /**
3
+ * Each storage adapter should support two ways of storing files:
4
+ * - publically (public URL) - the file can be accessed by anyone by HTTP GET / HEAD request with plain URL
5
+ * - privately (presigned URL) - the file can be accessed by anyone by HTTP GET / HEAD request only with presigned URLs, limited by expiration time
6
+ *
7
+ */
8
+ export interface StorageAdapter {
9
+ /**
10
+ * This method should return the presigned URL for the given key capable of upload (adapter user will call PUT multipart form data to this URL within expiresIn seconds after link generation).
11
+ * By default file which will be uploaded on PUT should be marked for deletion. So if during 24h it is not marked for not deletion, it adapter should delete it forever.
12
+ * The PUT method should fail if the file already exists.
13
+ *
14
+ * Adapter user will always pass next parameters to the method:
15
+ * @param key - The key of the file to be uploaded e.g. "uploads/file.txt"
16
+ * @param expiresIn - The expiration time in seconds for the presigned URL
17
+ * @param contentType - The content type of the file to be uploaded, e.g. "image/png"
18
+ *
19
+ * @returns A promise that resolves to an object containing the upload URL and any extra parameters which should be sent with PUT multipart form data
20
+ */
21
+ getUploadSignedUrl(key: string, contentType: string, expiresIn?: number): Promise<{
22
+ uploadUrl: string;
23
+ uploadExtraParams?: Record<string, string>;
24
+ }>;
25
+
26
+ /**
27
+ * This method should return the URL for the given key capable of download (200 GET request with response body or 200 HEAD request without response body).
28
+ * If adapter configured to store objects publically, this method should return the public URL of the file.
29
+ * If adapter configured to no allow public storing of images, this method should return the presigned URL for the file.
30
+ *
31
+ * @param key - The key of the file to be downloaded e.g. "uploads/file.txt"
32
+ * @param expiresIn - The expiration time in seconds for the presigned URL
33
+ */
34
+ getDownloadUrl(key: string, expiresIn?: number): Promise<string>;
35
+
36
+ /**
37
+ * This method should mark the file for deletion.
38
+ * If file is marked for delation and exists more then 24h (since creation date) it should be deleted.
39
+ * This method should work even if the file does not exist yet (e.g. only presigned URL was generated).
40
+ * @param key - The key of the file to be uploaded e.g. "uploads/file.txt"
41
+ */
42
+ markKeyForDeletation(key: string): Promise<void>;
43
+
44
+
45
+ /**
46
+ * This method should mark the file to not be deleted.
47
+ * This method should be used to cancel the deletion of the file if it was marked for deletion.
48
+ * @param key - The key of the file to be uploaded e.g. "uploads/file.txt"
49
+ */
50
+ markKeyForNotDeletation(key: string): Promise<void>;
51
+
52
+
53
+ /**
54
+ * This method can start needed schedullers, cron jobs, etc. to clean up the storage.
55
+ * @param adapterUserUniqueRepresentation - The unique representation of the plugin instance which
56
+ * wil use this adapter. Might be handy if you need to distinguish between different instances of the same adapter.
57
+ */
58
+ setupLifecycle(adapterUserUniqueRepresentation: string): Promise<void>;
59
+
60
+ /**
61
+ * If adapter is configured to publically, this method should return true.
62
+ */
63
+ objectCanBeAccesedPublicly(): Promise<boolean>;
64
+
65
+ /**
66
+ * This method should return the key as a data URL (base64 encoded string).
67
+ * @param key - The key of the file to be converted to a data URL
68
+ * @returns A promise that resolves to a string containing the data URL
69
+ */
70
+ getKeyAsDataURL(key: string): Promise<string>;
71
+ }
72
+
73
+
@@ -0,0 +1,5 @@
1
+ export type { EmailAdapter } from './EmailAdapter.js';
2
+ export type { CompletionAdapter } from './CompletionAdapter.js';
3
+ export type { ImageGenerationAdapter } from './ImageGenerationAdapter.js';
4
+ export type { OAuth2Adapter } from './OAuth2Adapter.js';
5
+ export type { StorageAdapter } from './StorageAdapter.js';