@aerogel/core 0.0.0-next.59bf5f7cc06e728d0cf6c00de28f1da48d7d6b8e → 0.0.0-next.7f6ed5a1f91688a86bf5ede2adc465e4fd6cfdea
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/dist/aerogel-core.cjs.js +1 -1
- package/dist/aerogel-core.d.ts +68 -414
- package/dist/aerogel-core.esm.js +1 -1
- package/package.json +8 -6
- package/src/bootstrap/bootstrap.test.ts +56 -0
- package/src/bootstrap/hooks.ts +19 -0
- package/src/bootstrap/index.ts +25 -9
- package/src/bootstrap/options.ts +1 -5
- package/src/components/basic/AGMarkdown.vue +5 -20
- package/src/components/forms/AGButton.vue +3 -26
- package/src/components/forms/AGInput.vue +4 -8
- package/src/components/forms/index.ts +1 -2
- package/src/components/headless/forms/AGHeadlessInput.ts +2 -2
- package/src/components/headless/forms/AGHeadlessInput.vue +5 -5
- package/src/components/headless/forms/AGHeadlessInputError.vue +5 -9
- package/src/components/headless/forms/AGHeadlessInputInput.vue +4 -20
- package/src/components/headless/forms/index.ts +4 -6
- package/src/components/headless/modals/AGHeadlessModal.vue +1 -5
- package/src/components/headless/modals/AGHeadlessModalPanel.vue +2 -10
- package/src/components/index.ts +1 -2
- package/src/components/modals/AGAlertModal.vue +2 -13
- package/src/components/modals/AGModal.ts +0 -4
- package/src/components/modals/AGModal.vue +2 -20
- package/src/components/modals/index.ts +1 -4
- package/src/directives/index.ts +3 -5
- package/src/forms/Form.test.ts +0 -21
- package/src/forms/Form.ts +16 -38
- package/src/forms/utils.ts +0 -17
- package/src/lang/Lang.ts +8 -47
- package/src/lang/helpers.ts +5 -0
- package/src/lang/index.ts +76 -17
- package/src/main.ts +0 -4
- package/src/models/index.ts +18 -0
- package/src/routing/index.ts +33 -0
- package/src/services/Service.ts +28 -151
- package/src/services/index.ts +7 -29
- package/src/testing/stubs/lang/en.yaml +1 -0
- package/src/testing/stubs/models/User.ts +3 -0
- package/src/types/vite.d.ts +2 -0
- package/src/ui/UI.state.ts +6 -3
- package/src/ui/UI.ts +2 -35
- package/src/ui/index.ts +13 -19
- package/src/utils/index.ts +0 -3
- package/tsconfig.json +10 -1
- package/vite.config.ts +6 -2
- package/src/components/forms/AGCheckbox.vue +0 -35
- package/src/components/headless/forms/AGHeadlessInputLabel.vue +0 -16
- package/src/components/modals/AGConfirmModal.vue +0 -30
- package/src/components/modals/AGLoadingModal.vue +0 -19
- package/src/errors/Errors.state.ts +0 -31
- package/src/errors/Errors.ts +0 -132
- package/src/errors/index.ts +0 -21
- package/src/globals.ts +0 -6
- package/src/lang/utils.ts +0 -4
- package/src/plugins/Plugin.ts +0 -7
- package/src/plugins/index.ts +0 -7
- package/src/services/App.state.ts +0 -13
- package/src/services/App.ts +0 -17
- package/src/services/store.ts +0 -27
- package/src/utils/composition/forms.ts +0 -11
- package/src/utils/composition/hooks.ts +0 -9
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<AGHeadlessModal
|
|
3
|
-
ref="$headlessModal"
|
|
4
|
-
v-slot="{ close }: IAGHeadlessModalDefaultSlotProps"
|
|
5
|
-
:cancellable="cancellable"
|
|
6
|
-
class="relative z-50"
|
|
7
|
-
>
|
|
2
|
+
<AGHeadlessModal v-slot="{ close }: IAGHeadlessModalDefaultSlotProps" class="relative z-50">
|
|
8
3
|
<div class="fixed inset-0 flex items-center justify-center">
|
|
9
4
|
<AGHeadlessModalPanel class="flex max-h-full max-w-full flex-col overflow-hidden bg-white">
|
|
10
5
|
<div class="flex max-h-full flex-col overflow-auto p-4">
|
|
@@ -16,21 +11,8 @@
|
|
|
16
11
|
</template>
|
|
17
12
|
|
|
18
13
|
<script setup lang="ts">
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
import { booleanProp } from '@/utils';
|
|
22
|
-
import type { IAGHeadlessModal, IAGHeadlessModalDefaultSlotProps } from '@/components/headless/modals/AGHeadlessModal';
|
|
23
|
-
|
|
24
|
-
import type { IAGModal } from './AGModal';
|
|
14
|
+
import type { IAGHeadlessModalDefaultSlotProps } from '@/components/headless/modals/AGHeadlessModal';
|
|
25
15
|
|
|
26
16
|
import AGHeadlessModal from '../headless/modals/AGHeadlessModal.vue';
|
|
27
17
|
import AGHeadlessModalPanel from '../headless/modals/AGHeadlessModalPanel.vue';
|
|
28
|
-
|
|
29
|
-
const $headlessModal = ref<IAGHeadlessModal>();
|
|
30
|
-
|
|
31
|
-
defineProps({ cancellable: booleanProp(true) });
|
|
32
|
-
defineExpose<IAGModal>({
|
|
33
|
-
close: async () => $headlessModal.value?.close(),
|
|
34
|
-
cancellable: computed(() => !!$headlessModal.value?.cancellable),
|
|
35
|
-
});
|
|
36
18
|
</script>
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import AGAlertModal from './AGAlertModal.vue';
|
|
2
|
-
import AGConfirmModal from './AGConfirmModal.vue';
|
|
3
|
-
import AGLoadingModal from './AGLoadingModal.vue';
|
|
4
1
|
import AGModal from './AGModal.vue';
|
|
5
2
|
import AGModalContext from './AGModalContext.vue';
|
|
6
3
|
import { IAGModal } from './AGModal';
|
|
7
4
|
|
|
8
|
-
export {
|
|
5
|
+
export { AGModal, AGModalContext, IAGModal };
|
package/src/directives/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Directive } from 'vue';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { defineBootstrapHook } from '@/bootstrap/hooks';
|
|
4
4
|
|
|
5
5
|
import initialFocus from './initial-focus';
|
|
6
6
|
|
|
@@ -8,8 +8,6 @@ const directives: Record<string, Directive> = {
|
|
|
8
8
|
'initial-focus': initialFocus,
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
export default
|
|
12
|
-
|
|
13
|
-
Object.entries(directives).forEach(([name, directive]) => app.directive(name, directive));
|
|
14
|
-
},
|
|
11
|
+
export default defineBootstrapHook(async (app) => {
|
|
12
|
+
Object.entries(directives).forEach(([name, directive]) => app.directive(name, directive));
|
|
15
13
|
});
|
package/src/forms/Form.test.ts
CHANGED
|
@@ -34,25 +34,4 @@ describe('Form', () => {
|
|
|
34
34
|
expect(form.errors.name).toEqual(['required']);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
it('resets form', () => {
|
|
38
|
-
// Arrange
|
|
39
|
-
const form = useForm({
|
|
40
|
-
name: {
|
|
41
|
-
type: FormFieldTypes.String,
|
|
42
|
-
rules: 'required',
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
form.name = 'Foo bar';
|
|
47
|
-
form.submit();
|
|
48
|
-
|
|
49
|
-
// Act
|
|
50
|
-
form.reset();
|
|
51
|
-
|
|
52
|
-
// Assert
|
|
53
|
-
expect(form.valid).toBe(true);
|
|
54
|
-
expect(form.submitted).toBe(false);
|
|
55
|
-
expect(form.name).toBeNull();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
37
|
});
|
package/src/forms/Form.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { MagicObject } from '@noeldemartin/utils';
|
|
2
|
-
import {
|
|
2
|
+
import { reactive, readonly, ref } from 'vue';
|
|
3
3
|
import type { ObjectValues } from '@noeldemartin/utils';
|
|
4
|
-
import type {
|
|
4
|
+
import type { DeepReadonly, Ref, UnwrapNestedRefs } from 'vue';
|
|
5
5
|
|
|
6
6
|
export const FormFieldTypes = {
|
|
7
7
|
String: 'string',
|
|
8
8
|
Number: 'number',
|
|
9
|
-
Boolean: 'boolean',
|
|
10
9
|
} as const;
|
|
11
10
|
|
|
12
11
|
export interface FormFieldDefinition<TType extends FormFieldType = FormFieldType, TRules extends string = string> {
|
|
@@ -19,7 +18,7 @@ export type FormFieldDefinitions = Record<string, FormFieldDefinition>;
|
|
|
19
18
|
export type FormFieldType = ObjectValues<typeof FormFieldTypes>;
|
|
20
19
|
|
|
21
20
|
export type FormData<T> = {
|
|
22
|
-
|
|
21
|
+
[k in keyof T]: T[k] extends FormFieldDefinition<infer TType, infer TRules>
|
|
23
22
|
? TRules extends 'required'
|
|
24
23
|
? GetFormFieldValue<TType>
|
|
25
24
|
: GetFormFieldValue<TType> | null
|
|
@@ -34,8 +33,6 @@ export type GetFormFieldValue<TType> = TType extends typeof FormFieldTypes.Strin
|
|
|
34
33
|
? string
|
|
35
34
|
: TType extends typeof FormFieldTypes.Number
|
|
36
35
|
? number
|
|
37
|
-
: TType extends typeof FormFieldTypes.Boolean
|
|
38
|
-
? boolean
|
|
39
36
|
: never;
|
|
40
37
|
|
|
41
38
|
export default class Form<Fields extends FormFieldDefinitions = FormFieldDefinitions> extends MagicObject {
|
|
@@ -44,7 +41,7 @@ export default class Form<Fields extends FormFieldDefinitions = FormFieldDefinit
|
|
|
44
41
|
|
|
45
42
|
private _fields: Fields;
|
|
46
43
|
private _data: FormData<Fields>;
|
|
47
|
-
private _valid:
|
|
44
|
+
private _valid: Ref<boolean>;
|
|
48
45
|
private _submitted: Ref<boolean>;
|
|
49
46
|
private _errors: FormErrors<Fields>;
|
|
50
47
|
|
|
@@ -53,9 +50,9 @@ export default class Form<Fields extends FormFieldDefinitions = FormFieldDefinit
|
|
|
53
50
|
|
|
54
51
|
this._fields = fields;
|
|
55
52
|
this._submitted = ref(false);
|
|
53
|
+
this._valid = ref(true);
|
|
56
54
|
this._data = this.getInitialData(fields);
|
|
57
55
|
this._errors = this.getInitialErrors(fields);
|
|
58
|
-
this._valid = computed(() => !Object.values(this._errors).some((error) => error !== null));
|
|
59
56
|
|
|
60
57
|
this.errors = readonly(this._errors);
|
|
61
58
|
}
|
|
@@ -81,22 +78,15 @@ export default class Form<Fields extends FormFieldDefinitions = FormFieldDefinit
|
|
|
81
78
|
}
|
|
82
79
|
|
|
83
80
|
public validate(): boolean {
|
|
84
|
-
const errors = Object.entries(this._fields).reduce((
|
|
85
|
-
|
|
81
|
+
const errors = Object.entries(this._fields).reduce((errors, [name, definition]) => {
|
|
82
|
+
errors[name] = this.getFieldErrors(name, definition);
|
|
86
83
|
|
|
87
|
-
return
|
|
84
|
+
return errors;
|
|
88
85
|
}, {} as Record<string, string[] | null>);
|
|
89
86
|
|
|
90
|
-
this.
|
|
87
|
+
Object.assign(this._errors, errors);
|
|
91
88
|
|
|
92
|
-
return this.
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
public reset(): void {
|
|
96
|
-
this._submitted.value = false;
|
|
97
|
-
|
|
98
|
-
this.resetData();
|
|
99
|
-
this.resetErrors();
|
|
89
|
+
return (this._valid.value = !Object.values(errors).some((error) => error !== null));
|
|
100
90
|
}
|
|
101
91
|
|
|
102
92
|
public submit(): boolean {
|
|
@@ -138,10 +128,10 @@ export default class Form<Fields extends FormFieldDefinitions = FormFieldDefinit
|
|
|
138
128
|
return {} as FormData<Fields>;
|
|
139
129
|
}
|
|
140
130
|
|
|
141
|
-
const data = Object.entries(fields).reduce((
|
|
142
|
-
|
|
131
|
+
const data = Object.entries(fields).reduce((data, [name, definition]) => {
|
|
132
|
+
data[name as keyof Fields] = (definition.default ?? null) as FormData<Fields>[keyof Fields];
|
|
143
133
|
|
|
144
|
-
return
|
|
134
|
+
return data;
|
|
145
135
|
}, {} as FormData<Fields>);
|
|
146
136
|
|
|
147
137
|
return reactive(data) as FormData<Fields>;
|
|
@@ -152,25 +142,13 @@ export default class Form<Fields extends FormFieldDefinitions = FormFieldDefinit
|
|
|
152
142
|
return {} as FormErrors<Fields>;
|
|
153
143
|
}
|
|
154
144
|
|
|
155
|
-
const errors = Object.keys(fields).reduce((
|
|
156
|
-
|
|
145
|
+
const errors = Object.keys(fields).reduce((errors, name) => {
|
|
146
|
+
errors[name as keyof Fields] = null;
|
|
157
147
|
|
|
158
|
-
return
|
|
148
|
+
return errors;
|
|
159
149
|
}, {} as FormErrors<Fields>);
|
|
160
150
|
|
|
161
151
|
return reactive(errors) as FormErrors<Fields>;
|
|
162
152
|
}
|
|
163
153
|
|
|
164
|
-
private resetData(): void {
|
|
165
|
-
for (const [name, field] of Object.entries(this._fields)) {
|
|
166
|
-
this._data[name as keyof Fields] = (field.default ?? null) as FormData<Fields>[keyof Fields];
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
private resetErrors(errors?: Record<string, string[] | null>): void {
|
|
171
|
-
Object.keys(this._errors).forEach((key) => delete this._errors[key as keyof Fields]);
|
|
172
|
-
|
|
173
|
-
errors && Object.assign(this._errors, errors);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
154
|
}
|
package/src/forms/utils.ts
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
import { FormFieldTypes } from './Form';
|
|
2
2
|
import type { FormFieldDefinition } from './Form';
|
|
3
3
|
|
|
4
|
-
export function booleanInput(defaultValue?: boolean): FormFieldDefinition<typeof FormFieldTypes.Boolean> {
|
|
5
|
-
return {
|
|
6
|
-
default: defaultValue,
|
|
7
|
-
type: FormFieldTypes.Boolean,
|
|
8
|
-
};
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function requiredBooleanInput(
|
|
12
|
-
defaultValue?: boolean,
|
|
13
|
-
): FormFieldDefinition<typeof FormFieldTypes.Boolean, 'required'> {
|
|
14
|
-
return {
|
|
15
|
-
default: defaultValue,
|
|
16
|
-
type: FormFieldTypes.Boolean,
|
|
17
|
-
rules: 'required',
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
4
|
export function requiredNumberInput(
|
|
22
5
|
defaultValue?: number,
|
|
23
6
|
): FormFieldDefinition<typeof FormFieldTypes.Number, 'required'> {
|
package/src/lang/Lang.ts
CHANGED
|
@@ -1,58 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useI18n } from 'vue-i18n';
|
|
2
|
+
import { facade } from '@noeldemartin/utils';
|
|
3
|
+
import type { Composer } from 'vue-i18n';
|
|
2
4
|
|
|
3
|
-
import App from '@/services/App';
|
|
4
5
|
import Service from '@/services/Service';
|
|
5
6
|
|
|
6
|
-
export interface LangProvider {
|
|
7
|
-
translate(key: string, parameters?: Record<string, unknown>): string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
7
|
export class LangService extends Service {
|
|
11
8
|
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
constructor() {
|
|
15
|
-
super();
|
|
16
|
-
|
|
17
|
-
this.provider = {
|
|
18
|
-
translate: (key) => {
|
|
19
|
-
// eslint-disable-next-line no-console
|
|
20
|
-
App.isDevelopment && console.warn('Lang provider is missing');
|
|
21
|
-
|
|
22
|
-
return key;
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
}
|
|
9
|
+
private i18n?: Composer;
|
|
26
10
|
|
|
27
|
-
public
|
|
28
|
-
this.
|
|
11
|
+
public setup(): void {
|
|
12
|
+
this.i18n = useI18n();
|
|
29
13
|
}
|
|
30
14
|
|
|
31
|
-
public translate(key: string, parameters
|
|
32
|
-
return this.
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public translateWithDefault(key: string, defaultMessage: string): string;
|
|
36
|
-
public translateWithDefault(key: string, parameters: Record<string, unknown>, defaultMessage: string): string;
|
|
37
|
-
public translateWithDefault(
|
|
38
|
-
key: string,
|
|
39
|
-
defaultMessageOrParameters?: string | Record<string, unknown>,
|
|
40
|
-
defaultMessage?: string,
|
|
41
|
-
): string {
|
|
42
|
-
defaultMessage ??= defaultMessageOrParameters as string;
|
|
43
|
-
|
|
44
|
-
const parameters = typeof defaultMessageOrParameters === 'string' ? {} : defaultMessageOrParameters ?? {};
|
|
45
|
-
const message = this.provider.translate(key, parameters) ?? key;
|
|
46
|
-
|
|
47
|
-
if (message === key) {
|
|
48
|
-
return Object.entries(parameters).reduce(
|
|
49
|
-
(renderedMessage, [name, value]) =>
|
|
50
|
-
renderedMessage.replace(new RegExp(`\\{\\s*${name}\\s*\\}`, 'g'), toString(value)),
|
|
51
|
-
defaultMessage,
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return message;
|
|
15
|
+
public translate(key: string, parameters: Record<string, unknown> = {}): string {
|
|
16
|
+
return this.i18n?.t(key, parameters) ?? key;
|
|
56
17
|
}
|
|
57
18
|
|
|
58
19
|
}
|
package/src/lang/index.ts
CHANGED
|
@@ -1,30 +1,89 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createI18n } from 'vue-i18n';
|
|
2
|
+
import { fail, stringMatch } from '@noeldemartin/utils';
|
|
3
|
+
import type { I18nOptions } from 'vue-i18n';
|
|
4
|
+
import type { Plugin } from 'vue';
|
|
3
5
|
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
+
import { defineBootstrapHook, onAppMounted } from '@/bootstrap/hooks';
|
|
7
|
+
import { bootServices } from '@/services';
|
|
8
|
+
import type { BootstrapOptions } from '@/bootstrap/options';
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
import Lang from './Lang';
|
|
8
11
|
|
|
9
12
|
const services = { $lang: Lang };
|
|
10
13
|
|
|
14
|
+
function getLangOptions(options: BootstrapOptions): LangOptions | null {
|
|
15
|
+
if (options.lang) {
|
|
16
|
+
return options.lang;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (options.langMessages) {
|
|
20
|
+
return { messages: options.langMessages };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getMessageLoaders(messageLoaders: Record<string, unknown>): Record<string, LazyMessages> {
|
|
27
|
+
return Object.entries(messageLoaders).reduce((loaders, [fileName, loader]) => {
|
|
28
|
+
const locale = stringMatch<2>(fileName, /.*\/lang\/(.+)\.yaml/)?.[1];
|
|
29
|
+
|
|
30
|
+
if (locale) {
|
|
31
|
+
loaders[locale] = () =>
|
|
32
|
+
(loader as () => Promise<{ default: Record<string, unknown> }>)().then(
|
|
33
|
+
({ default: messages }) => messages,
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return loaders;
|
|
38
|
+
}, {} as Record<string, LazyMessages>);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function createAppI18n(options: LangOptions): Promise<Plugin> {
|
|
42
|
+
const locale = options.defaultLocale ?? 'en';
|
|
43
|
+
const fallbackLocale = options.fallbackLocale ?? 'en';
|
|
44
|
+
const messageLoaders = getMessageLoaders(options.messages);
|
|
45
|
+
const lazyMessages = messageLoaders[locale] ?? fail<LazyMessages>(`Missing messages for '${locale}' locale`);
|
|
46
|
+
const messages = { [locale]: await lazyMessages() } as I18nOptions['messages'];
|
|
47
|
+
|
|
48
|
+
return createI18n({ locale, fallbackLocale, messages });
|
|
49
|
+
}
|
|
50
|
+
|
|
11
51
|
export type LangServices = typeof services;
|
|
12
52
|
|
|
13
|
-
export
|
|
14
|
-
async install(app) {
|
|
15
|
-
app.config.globalProperties.$t ??= translate;
|
|
16
|
-
app.config.globalProperties.$td = translateWithDefault;
|
|
53
|
+
export type LazyMessages = () => Promise<Record<string, unknown>>;
|
|
17
54
|
|
|
18
|
-
|
|
19
|
-
|
|
55
|
+
export interface LangOptions {
|
|
56
|
+
messages: Record<string, unknown>;
|
|
57
|
+
defaultLocale?: string;
|
|
58
|
+
fallbackLocale?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export * from './helpers';
|
|
62
|
+
export { Lang };
|
|
63
|
+
|
|
64
|
+
export default defineBootstrapHook(async (app, options) => {
|
|
65
|
+
const langOptions = getLangOptions(options);
|
|
66
|
+
|
|
67
|
+
if (!langOptions) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
onAppMounted(() => Lang.setup());
|
|
72
|
+
|
|
73
|
+
const plugin = await createAppI18n(langOptions);
|
|
74
|
+
|
|
75
|
+
app.use(plugin);
|
|
76
|
+
|
|
77
|
+
await bootServices(app, services);
|
|
20
78
|
});
|
|
21
79
|
|
|
22
|
-
declare module '@/
|
|
23
|
-
interface
|
|
80
|
+
declare module '@/bootstrap/options' {
|
|
81
|
+
interface BootstrapOptions {
|
|
82
|
+
lang?: LangOptions;
|
|
83
|
+
langMessages?: Record<string, unknown>;
|
|
84
|
+
}
|
|
24
85
|
}
|
|
25
86
|
|
|
26
|
-
declare module '
|
|
27
|
-
interface
|
|
28
|
-
$td: typeof translateWithDefault;
|
|
29
|
-
}
|
|
87
|
+
declare module '@/services' {
|
|
88
|
+
interface Services extends LangServices {}
|
|
30
89
|
}
|
package/src/main.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import './globals';
|
|
2
|
-
|
|
3
1
|
export * from './bootstrap';
|
|
4
2
|
export * from './components';
|
|
5
|
-
export * from './errors';
|
|
6
3
|
export * from './forms';
|
|
7
4
|
export * from './lang';
|
|
8
|
-
export * from './plugins';
|
|
9
5
|
export * from './services';
|
|
10
6
|
export * from './ui';
|
|
11
7
|
export * from './utils';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IndexedDBEngine, bootModelsFromViteGlob, setEngine } from 'soukai';
|
|
2
|
+
|
|
3
|
+
import { defineBootstrapHook } from '@/bootstrap/hooks';
|
|
4
|
+
|
|
5
|
+
export default defineBootstrapHook(async (_, options) => {
|
|
6
|
+
if (!options.models) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
setEngine(new IndexedDBEngine());
|
|
11
|
+
bootModelsFromViteGlob(options.models);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
declare module '@/bootstrap/options' {
|
|
15
|
+
interface BootstrapOptions {
|
|
16
|
+
models?: Record<string, Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createRouter, createWebHistory } from 'vue-router';
|
|
2
|
+
import type { Plugin } from 'vue';
|
|
3
|
+
|
|
4
|
+
import { defineBootstrapHook } from '@/bootstrap/hooks';
|
|
5
|
+
|
|
6
|
+
function createAppRouter(options: { routes: RouteRecordRaw[]; basePath?: string }): Plugin {
|
|
7
|
+
return createRouter({
|
|
8
|
+
history: createWebHistory(options.basePath),
|
|
9
|
+
routes: options.routes,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default defineBootstrapHook(async (app, options) => {
|
|
14
|
+
if (!options.routes) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const plugin = createAppRouter({
|
|
19
|
+
routes: options.routes,
|
|
20
|
+
basePath: options.basePath ?? __AG_BASE_PATH,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
app.use(plugin);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
declare module '@/bootstrap/options' {
|
|
27
|
+
interface BootstrapOptions {
|
|
28
|
+
routes?: RouteRecordRaw[];
|
|
29
|
+
basePath?: string;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
import type { RouteRecordRaw } from 'vue-router';
|