adminforth 2.22.0 → 2.23.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.
@@ -13,6 +13,9 @@ import Handlebars from 'handlebars';
13
13
  import { promisify } from 'util';
14
14
  import { getVersion } from '../cli.js';
15
15
 
16
+ import { URL } from 'url'
17
+ import net from 'net'
18
+
16
19
  const execAsync = promisify(exec);
17
20
 
18
21
  function detectAdminforthVersion() {
@@ -159,6 +162,44 @@ function checkForExistingPackageJson(options) {
159
162
  }
160
163
  }
161
164
 
165
+ function checkIfDatabaseLocal(urlString) {
166
+ if (urlString.startsWith('sqlite')) {
167
+ return true;
168
+ }
169
+ try {
170
+ const url = new URL(urlString)
171
+
172
+ const host = url.hostname
173
+
174
+ if (!host) return false
175
+
176
+ // localhost
177
+ if (host === 'localhost') return true
178
+
179
+ // loopback ipv4
180
+ if (host === '127.0.0.1') return true
181
+
182
+ // loopback ipv6
183
+ if (host === '::1') return true
184
+
185
+ // private IP ranges
186
+ if (net.isIP(host)) {
187
+ if (
188
+ host.startsWith('10.') ||
189
+ host.startsWith('192.168.') ||
190
+ host.match(/^172\.(1[6-9]|2\d|3[0-1])\./)
191
+ ) {
192
+ return true
193
+ }
194
+ }
195
+
196
+
197
+ return false
198
+ } catch {
199
+ return false
200
+ }
201
+ }
202
+
162
203
  async function scaffoldProject(ctx, options, cwd) {
163
204
  const projectDir = path.join(cwd, options.appName);
164
205
  await fse.ensureDir(projectDir);
@@ -253,7 +294,7 @@ async function writeTemplateFiles(dirname, cwd, options) {
253
294
  {
254
295
  src: '.env.local.hbs',
255
296
  dest: '.env.local',
256
- data: { dbUrl, prismaDbUrl },
297
+ data: { dbUrl: checkIfDatabaseLocal(dbUrl) ? dbUrl : null, prismaDbUrl },
257
298
  },
258
299
  {
259
300
  src: '.env.prod.hbs',
@@ -269,8 +310,7 @@ async function writeTemplateFiles(dirname, cwd, options) {
269
310
  // We'll write .env using the same content as .env.sample
270
311
  src: '.env.local.hbs',
271
312
  dest: '.env',
272
- data: {},
273
- empty: true,
313
+ data: {dbUrl, prismaDbUrl},
274
314
  },
275
315
  {
276
316
  src: 'adminuser.ts.hbs',
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "devDependencies": {
31
31
  "@rushstack/eslint-patch": "^1.8.0",
32
+ "@tailwindcss/typography": "^0.5.19",
32
33
  "@tsconfig/node20": "^20.1.4",
33
34
  "@types/node": "^20.12.5",
34
35
  "@vitejs/plugin-vue": "^5.0.4",
@@ -1165,6 +1166,33 @@
1165
1166
  "@svgdotjs/svg.js": "^3.2.4"
1166
1167
  }
1167
1168
  },
1169
+ "node_modules/@tailwindcss/typography": {
1170
+ "version": "0.5.19",
1171
+ "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.19.tgz",
1172
+ "integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==",
1173
+ "dev": true,
1174
+ "license": "MIT",
1175
+ "dependencies": {
1176
+ "postcss-selector-parser": "6.0.10"
1177
+ },
1178
+ "peerDependencies": {
1179
+ "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
1180
+ }
1181
+ },
1182
+ "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
1183
+ "version": "6.0.10",
1184
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
1185
+ "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
1186
+ "dev": true,
1187
+ "license": "MIT",
1188
+ "dependencies": {
1189
+ "cssesc": "^3.0.0",
1190
+ "util-deprecate": "^1.0.2"
1191
+ },
1192
+ "engines": {
1193
+ "node": ">=4"
1194
+ }
1195
+ },
1168
1196
  "node_modules/@tsconfig/node20": {
1169
1197
  "version": "20.1.4",
1170
1198
  "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
@@ -34,6 +34,7 @@
34
34
  },
35
35
  "devDependencies": {
36
36
  "@rushstack/eslint-patch": "^1.8.0",
37
+ "@tailwindcss/typography": "^0.5.19",
37
38
  "@tsconfig/node20": "^20.1.4",
38
39
  "@types/node": "^20.12.5",
39
40
  "@vitejs/plugin-vue": "^5.0.4",
@@ -132,6 +132,7 @@ class FrontendAPI implements FrontendAPIInterface {
132
132
  return new Promise((resolve, reject) => {
133
133
  this.modalStore.setModalContent({
134
134
  content: params.message,
135
+ contentHTML: params.messageHtml,
135
136
  acceptText: params.yes || 'Yes',
136
137
  cancelText: params.no || 'Cancel'
137
138
  })
@@ -12,9 +12,7 @@
12
12
  ref="input"
13
13
  v-bind="$attrs"
14
14
  :type="type"
15
- :min="min"
16
- :max="max"
17
- @input="onInput"
15
+ @input="$emit('update:modelValue', type === 'number' ? Number(($event.target as HTMLInputElement)?.value) : ($event.target as HTMLInputElement)?.value)"
18
16
  :value="modelValue"
19
17
  aria-describedby="helper-text-explanation"
20
18
  class="afcl-input inline-flex bg-lightInputBackground text-lightInputText dark:text-darkInputText border border-lightInputBorder rounded-0 focus:ring-lightPrimary focus:border-lightPrimary dark:focus:ring-darkPrimary dark:focus:border-darkPrimary
@@ -50,31 +48,8 @@ const props = defineProps<{
50
48
  suffix?: string,
51
49
  prefix?: string,
52
50
  readonly?: boolean,
53
- min?: number | null,
54
- max?: number | null,
55
51
  }>()
56
52
 
57
- const emit = defineEmits<{
58
- (e: 'update:modelValue', value: number | null): void
59
- }>();
60
-
61
- const onInput = (e: Event) => {
62
- const el = e.target as HTMLInputElement;
63
-
64
- if (props.type === 'number') {
65
- let val = Number(el.value);
66
-
67
- if (props.min != null && val < props.min) val = props.min;
68
- if (props.max != null && val > props.max) val = props.max;
69
-
70
- el.value = String(val);
71
- emit('update:modelValue', val);
72
- } else {
73
- emit('update:modelValue', el.value);
74
- }
75
- };
76
-
77
-
78
53
  const input = ref<HTMLInputElement | null>(null)
79
54
 
80
55
  defineExpose({
@@ -14,6 +14,8 @@
14
14
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 11V6m0 8h.01M19 10a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
15
15
  </svg>
16
16
  <h3 class="afcl-confirmation-title mb-5 text-lg font-normal text-lightAcceptModalText dark:text-darkAcceptModalText">{{ modalStore?.modalContent?.content }}</h3>
17
+ <h3 class=" afcl-confirmation-title mb-5 text-lg font-normal text-lightAcceptModalText dark:text-darkAcceptModalText" v-html="modalStore?.modalContent?.contentHTML"></h3>
18
+
17
19
  <button @click="()=>{ modalStore.onAcceptFunction(true);modalStore.togleModal()}" type="button" class="afcl-confirmation-accept-button text-lightAcceptModalConfirmButtonText bg-lightAcceptModalConfirmButtonBackground hover:bg-lightAcceptModalConfirmButtonBackgroundHover focus:ring-4 focus:outline-none focus:ring-lightAcceptModalConfirmButtonFocus font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center dark:text-darkAcceptModalConfirmButtonText dark:bg-darkAcceptModalConfirmButtonBackground dark:hover:bg-darkAcceptModalConfirmButtonBackgroundHover dark:focus:ring-darkAcceptModalConfirmButtonFocus">
18
20
  {{ modalStore?.modalContent?.acceptText }}
19
21
  </button>
@@ -4,6 +4,7 @@ import { defineStore } from 'pinia'
4
4
  type ModalContentType = {
5
5
  title?: string;
6
6
  content?: string;
7
+ contentHTML?: string;
7
8
  acceptText?: string;
8
9
  cancelText?: string;
9
10
  }
@@ -12,7 +13,8 @@ import { defineStore } from 'pinia'
12
13
  export const useModalStore = defineStore('modal', () => {
13
14
  const modalContent = ref({
14
15
  title: 'title',
15
- content: 'content',
16
+ content: '',
17
+ contentHTML: '',
16
18
  acceptText: 'acceptText',
17
19
  cancelText: 'cancelText',
18
20
  });
@@ -31,7 +33,8 @@ export const useModalStore = defineStore('modal', () => {
31
33
  function setModalContent(content: ModalContentType) {
32
34
  modalContent.value = {
33
35
  title: content.title || 'title',
34
- content: content.content || 'content',
36
+ content: content.content || '',
37
+ contentHTML: content.contentHTML || '',
35
38
  acceptText: content.acceptText || 'acceptText',
36
39
  cancelText: content.cancelText || 'cancelText',
37
40
  };
@@ -41,6 +44,7 @@ export const useModalStore = defineStore('modal', () => {
41
44
  modalContent.value = {
42
45
  title: 'title',
43
46
  content: 'content',
47
+ contentHTML: '',
44
48
  acceptText: 'acceptText',
45
49
  cancelText: 'cancelText',
46
50
  };
@@ -159,6 +159,10 @@ export type ConfirmParams = {
159
159
  * The message to display in the dialog
160
160
  */
161
161
  message?: string;
162
+ /**
163
+ * Message to display in the dialog as HTML (can be used instead of message)
164
+ */
165
+ messageHtml?: string;
162
166
  /**
163
167
  * The text to display in the "accept" button
164
168
  */
@@ -23,4 +23,11 @@ export interface CompletionAdapter {
23
23
  finishReason?: string;
24
24
  error?: string;
25
25
  }>;
26
+
27
+ /**
28
+ * This method should return the number of tokens in the input content.
29
+ * @param content - The input text for which to measure the token count
30
+ * @returns The number of tokens in the input content
31
+ */
32
+ measureTokensCount(content: string): Promise<number> | number;
26
33
  }
@@ -10,6 +10,7 @@ import sanitizeHtml from 'sanitize-html'
10
10
  import debounce from 'debounce';
11
11
  import type { AdminForthResourceColumnInputCommon, Predicate } from '@/types/Common';
12
12
  import { i18nInstance } from '../i18n'
13
+ import { useI18n } from 'vue-i18n';
13
14
 
14
15
 
15
16
 
@@ -524,9 +525,10 @@ export function atob_function(source: string): string {
524
525
  return atob(source);
525
526
  }
526
527
 
527
- export function compareOldAndNewRecord(oldRecord: Record<string, any>, newRecord: Record<string, any>): boolean {
528
+ export function compareOldAndNewRecord(oldRecord: Record<string, any>, newRecord: Record<string, any>): {ok: boolean, changedFields: Record<string, {oldValue: any, newValue: any}>} {
528
529
  const newKeys = Object.keys(newRecord);
529
530
  const coreStore = useCoreStore();
531
+ const changedColumns: Record<string, { oldValue: any, newValue: any }> = {};
530
532
 
531
533
  for (const key of newKeys) {
532
534
  const oldValue = typeof oldRecord[key] === 'object' && oldRecord[key] !== null ? JSON.stringify(oldRecord[key]) : oldRecord[key];
@@ -537,21 +539,23 @@ export function compareOldAndNewRecord(oldRecord: Record<string, any>, newRecord
537
539
  oldValue === undefined ||
538
540
  oldValue === null ||
539
541
  oldValue === '' ||
540
- (Array.isArray(oldValue) && oldValue.length === 0)
542
+ (Array.isArray(oldValue) && oldValue.length === 0) ||
543
+ oldValue === '[]'
541
544
  )
542
545
  &&
543
546
  (
544
547
  newValue === undefined ||
545
548
  newValue === null ||
546
549
  newValue === '' ||
547
- (Array.isArray(newValue) && newValue.length === 0)
550
+ (Array.isArray(newValue) && newValue.length === 0) ||
551
+ newValue === '[]'
548
552
  )
549
553
  ) {
550
554
  // console.log(`Value for key ${key} is considered equal (empty)`)
551
555
  continue;
552
556
  }
553
557
 
554
- const column = coreStore.resource.columns.find((c) => c.name === key);
558
+ const column = coreStore.resource?.columns.find((c) => c.name === key);
555
559
  if (column?.foreignResource) {
556
560
  if (newRecord[key] === oldRecord[key]?.pk) {
557
561
  // console.log(`Value for key ${key} is considered equal (foreign key)`)
@@ -559,8 +563,39 @@ export function compareOldAndNewRecord(oldRecord: Record<string, any>, newRecord
559
563
  }
560
564
  }
561
565
  // console.log(`Value for key ${key} is different`, { oldValue: oldValue, newValue: newValue });
562
- return false;
566
+ changedColumns[key] = { oldValue, newValue };
563
567
  }
564
568
  }
565
- return true;
569
+ return { ok: Object.keys(changedColumns).length !== 0, changedFields: changedColumns };
570
+ }
571
+
572
+ export function generateMessageHtmlForRecordChange(changedFields: Record<string, { oldValue: any, newValue: any }>, t: ReturnType<typeof useI18n>['t']): string {
573
+ const coreStore = useCoreStore();
574
+
575
+ const escapeHtml = (value: any) => {
576
+ if (value === null || value === undefined || value === '') return `<em>${t('empty')}</em>`;
577
+ let s: string;
578
+ if (typeof value === 'object') {
579
+ try {
580
+ s = JSON.stringify(value);
581
+ } catch (e) {
582
+ s = String(value);
583
+ }
584
+ } else {
585
+ s = String(value);
586
+ }
587
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
588
+ };
589
+
590
+ const items = Object.keys(changedFields || {}).map(key => {
591
+ const column = coreStore.resource?.columns?.find((c: any) => c.name === key);
592
+ const label = column?.label || key;
593
+ const oldV = escapeHtml(changedFields[key].oldValue);
594
+ const newV = escapeHtml(changedFields[key].newValue);
595
+ return `<li class="truncate"><strong>${escapeHtml(label)}</strong>: <span class="af-old-value text-muted">${oldV}</span> &#8594; <span class="af-new-value">${newV}</span></li>`;
596
+ }).join('');
597
+
598
+ const listHtml = items ? `<ul class="mt-2 list-disc list-inside">${items}</ul>` : '';
599
+ const messageHtml = `<div>${escapeHtml(t('There are unsaved changes. Are you sure you want to leave this page?'))}${listHtml}</div>`;
600
+ return messageHtml;
566
601
  }
@@ -79,7 +79,7 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
79
79
  import ResourceForm from '@/components/ResourceForm.vue';
80
80
  import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
81
81
  import { useCoreStore } from '@/stores/core';
82
- import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown, checkShowIf, compareOldAndNewRecord } from '@/utils';
82
+ import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown, checkShowIf, compareOldAndNewRecord, generateMessageHtmlForRecordChange } from '@/utils';
83
83
  import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
84
84
  import { onMounted, onBeforeMount, onBeforeUnmount, ref, watch, nextTick } from 'vue';
85
85
  import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router';
@@ -121,7 +121,7 @@ async function onUpdateRecord(newRecord: any) {
121
121
  }
122
122
 
123
123
  function checkIfWeCanLeavePage() {
124
- return wasSaveSuccessful.value || cancelButtonClicked.value || compareOldAndNewRecord(initialValues.value, record.value);
124
+ return wasSaveSuccessful.value || cancelButtonClicked.value || compareOldAndNewRecord(initialValues.value, record.value).ok === false;
125
125
  }
126
126
 
127
127
  function onBeforeUnload(event: BeforeUnloadEvent) {
@@ -139,8 +139,12 @@ onBeforeUnmount(() => {
139
139
 
140
140
  onBeforeRouteLeave(async (to, from, next) => {
141
141
  if (!checkIfWeCanLeavePage()) {
142
- const answer = await confirm({message: t('There are unsaved changes. Are you sure you want to leave this page?'), yes: 'Yes', no: 'No'});
143
- if (!answer) return next(false);
142
+ const { changedFields } = compareOldAndNewRecord(initialValues.value, record.value);
143
+
144
+ const messageHtml = generateMessageHtmlForRecordChange(changedFields, t);
145
+
146
+ const answer = await confirm({ messageHtml: messageHtml, yes: t('Yes'), no: t('No') });
147
+ if (!answer) return next(false);
144
148
  }
145
149
  next();
146
150
  });
@@ -74,7 +74,7 @@ import BreadcrumbsWithButtons from '@/components/BreadcrumbsWithButtons.vue';
74
74
  import ResourceForm from '@/components/ResourceForm.vue';
75
75
  import SingleSkeletLoader from '@/components/SingleSkeletLoader.vue';
76
76
  import { useCoreStore } from '@/stores/core';
77
- import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown, compareOldAndNewRecord } from '@/utils';
77
+ import { callAdminForthApi, getCustomComponent,checkAcessByAllowedActions, initThreeDotsDropdown, compareOldAndNewRecord, generateMessageHtmlForRecordChange } from '@/utils';
78
78
  import { IconFloppyDiskSolid } from '@iconify-prerendered/vue-flowbite';
79
79
  import { computed, onMounted, onBeforeMount, ref, type Ref, nextTick, watch, onBeforeUnmount } from 'vue';
80
80
  import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router';
@@ -113,7 +113,7 @@ function onBeforeUnload(event: BeforeUnloadEvent) {
113
113
  }
114
114
 
115
115
  function checkIfWeCanLeavePage() {
116
- return wasSaveSuccessful.value || cancelButtonClicked.value || compareOldAndNewRecord(initialRecord.value, record.value);
116
+ return wasSaveSuccessful.value || cancelButtonClicked.value || compareOldAndNewRecord(initialRecord.value, record.value).ok === false;
117
117
  }
118
118
 
119
119
  window.addEventListener('beforeunload', onBeforeUnload);
@@ -124,8 +124,12 @@ onBeforeUnmount(() => {
124
124
 
125
125
  onBeforeRouteLeave(async (to, from, next) => {
126
126
  if (!checkIfWeCanLeavePage()) {
127
- const answer = await confirm({message: t('There are unsaved changes. Are you sure you want to leave this page?'), yes: 'Yes', no: 'No'});
128
- if (!answer) return next(false);
127
+ const { changedFields } = compareOldAndNewRecord(initialRecord.value, record.value);
128
+
129
+ const messageHtml = generateMessageHtmlForRecordChange(changedFields, t);
130
+
131
+ const answer = await confirm({ messageHtml: messageHtml, yes: t('Yes'), no: t('No') });
132
+ if (!answer) return next(false);
129
133
  }
130
134
  next();
131
135
  });
@@ -10,7 +10,7 @@ export default {
10
10
 
11
11
  darkMode: 'class',
12
12
  plugins: [
13
-
13
+ require('@tailwindcss/typography'),
14
14
  ],
15
15
  }
16
16
 
@@ -156,6 +156,10 @@ export type ConfirmParams = {
156
156
  * The message to display in the dialog
157
157
  */
158
158
  message?: string;
159
+ /**
160
+ * Message to display in the dialog as HTML (can be used instead of message)
161
+ */
162
+ messageHtml?: string;
159
163
  /**
160
164
  * The text to display in the "accept" button
161
165
  */
@@ -1 +1 @@
1
- {"version":3,"file":"FrontendAPI.d.ts","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IAEjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjD;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,EAAC,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAG3D,IAAI,EAAE;QAEF;;WAEG;QACH,OAAO,IAAI,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAExC;;;;WAIG;QACH,aAAa,IAAI,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAE9C;;WAEG;QACH,gBAAgB,CAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAEzD;;WAEG;QACH,sBAAsB,IAAI,IAAI,CAAC;QAE/B;;;;;;;;;;;;;;;;;;;;;;;;;WAyBG;QACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEtC;;;;;;;;;;;;;;;;;WAiBG;QACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEzC;;WAEG;QACH,YAAY,IAAI,IAAI,CAAC;KACxB,CAAA;IAED,IAAI,EAAE;QACF;;;WAGG;QACH,OAAO,IAAI,IAAI,CAAC;KACnB,CAAA;IAED,IAAI,EAAE;QACF;;WAEG;QACH,iBAAiB,IAAI,IAAI,CAAC;KAC7B,CAAA;IAED;;OAEG;IACH,qBAAqB,IAAI,IAAI,CAAC;IAE9B;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAC,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KAAE,CAAC,CAAC;IAE5K;;;;OAIG;IACH,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,MAAM,aAAa,GAAG;IACxB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CAEf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,OAAO,YAAY,CAAC;IAEnD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;CAE3C,CAAA;AAID,oBAAY,YAAY;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd"}
1
+ {"version":3,"file":"FrontendAPI.d.ts","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA6B,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3E,MAAM,WAAW,oBAAoB;IAEjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjD;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,MAAM,EAAC,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAG3D,IAAI,EAAE;QAEF;;WAEG;QACH,OAAO,IAAI,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAExC;;;;WAIG;QACH,aAAa,IAAI,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAE9C;;WAEG;QACH,gBAAgB,CAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC;YAAE,KAAK,CAAC,EAAG,MAAM,CAAA;SAAE,CAAC,CAAC;QAEzD;;WAEG;QACH,sBAAsB,IAAI,IAAI,CAAC;QAE/B;;;;;;;;;;;;;;;;;;;;;;;;;WAyBG;QACH,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEtC;;;;;;;;;;;;;;;;;WAiBG;QACH,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;QAEzC;;WAEG;QACH,YAAY,IAAI,IAAI,CAAC;KACxB,CAAA;IAED,IAAI,EAAE;QACF;;;WAGG;QACH,OAAO,IAAI,IAAI,CAAC;KACnB,CAAA;IAED,IAAI,EAAE;QACF;;WAEG;QACH,iBAAiB,IAAI,IAAI,CAAC;KAC7B,CAAA;IAED;;OAEG;IACH,qBAAqB,IAAI,IAAI,CAAC;IAE9B;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,QAAQ,GAAC,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,GAAG,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;KAAE,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;KAAE,CAAC,CAAC;IAE5K;;;;OAIG;IACH,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,MAAM,aAAa,GAAG;IACxB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;CAEf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACtB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,OAAO,YAAY,CAAC;IAEnD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,EAAE;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;CAE3C,CAAA;AAID,oBAAY,YAAY;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd"}
@@ -1 +1 @@
1
- {"version":3,"file":"FrontendAPI.js","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AA2MA,MAAM,CAAN,IAAY,YAKT;AALH,WAAY,YAAY;IACpB,iCAAiB,CAAA;IACjB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,6BAAa,CAAA;AACf,CAAC,EALS,YAAY,KAAZ,YAAY,QAKrB"}
1
+ {"version":3,"file":"FrontendAPI.js","sourceRoot":"","sources":["../../types/FrontendAPI.ts"],"names":[],"mappings":"AA+MA,MAAM,CAAN,IAAY,YAKT;AALH,WAAY,YAAY;IACpB,iCAAiB,CAAA;IACjB,mCAAmB,CAAA;IACnB,mCAAmB,CAAA;IACnB,6BAAa,CAAA;AACf,CAAC,EALS,YAAY,KAAZ,YAAY,QAKrB"}
@@ -16,5 +16,11 @@ export interface CompletionAdapter {
16
16
  finishReason?: string;
17
17
  error?: string;
18
18
  }>;
19
+ /**
20
+ * This method should return the number of tokens in the input content.
21
+ * @param content - The input text for which to measure the token count
22
+ * @returns The number of tokens in the input content
23
+ */
24
+ measureTokensCount(content: string): Promise<number> | number;
19
25
  }
20
26
  //# sourceMappingURL=CompletionAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CompletionAdapter.d.ts","sourceRoot":"","sources":["../../../types/adapters/CompletionAdapter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAEhC;;;OAGG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;;;;;OAMG;IACH,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,GAAG,GACjB,OAAO,CAAC;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ"}
1
+ {"version":3,"file":"CompletionAdapter.d.ts","sourceRoot":"","sources":["../../../types/adapters/CompletionAdapter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAEhC;;;OAGG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;;;;;OAMG;IACH,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,GAAG,GACjB,OAAO,CAAC;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IAEH;;;;OAIG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;CAC/D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "2.22.0",
3
+ "version": "2.23.0",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",