@vesperjs/vue 0.1.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.
- package/README.md +3 -0
- package/dist/index.d.mts +21654 -0
- package/dist/index.mjs +282 -0
- package/package.json +44 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { computed, ref } from "@vue/reactivity";
|
|
2
|
+
import { persistentAtom } from "@nanostores/persistent";
|
|
3
|
+
import { ofetch } from "ofetch";
|
|
4
|
+
import { createI18n } from "vue-i18n";
|
|
5
|
+
//#region src/stores/nano/base-url.ts
|
|
6
|
+
const $baseUrl = persistentAtom("baseURL", "");
|
|
7
|
+
persistentAtom("timeZone", "");
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/stores/use-base-url-store.ts
|
|
10
|
+
function useBaseUrlStore() {
|
|
11
|
+
return { baseURL: computed({
|
|
12
|
+
get() {
|
|
13
|
+
return $baseUrl.get();
|
|
14
|
+
},
|
|
15
|
+
set(value) {
|
|
16
|
+
$baseUrl.set(value);
|
|
17
|
+
}
|
|
18
|
+
}) };
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/composables/backend/api/use-api-constants.ts
|
|
22
|
+
function useApiConstants() {
|
|
23
|
+
const { baseURL } = useBaseUrlStore();
|
|
24
|
+
return { baseURL };
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/composables/backend/api/use-ofetch.ts
|
|
28
|
+
const useOFetch = async (url, options) => {
|
|
29
|
+
const pending = ref(true);
|
|
30
|
+
const data = ref();
|
|
31
|
+
const error = ref();
|
|
32
|
+
try {
|
|
33
|
+
data.value = await ofetch(url, options);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
error.value = err;
|
|
36
|
+
}
|
|
37
|
+
pending.value = false;
|
|
38
|
+
return {
|
|
39
|
+
data: data.value,
|
|
40
|
+
error: error.value,
|
|
41
|
+
pending: pending.value
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/i18n/i18n.ts
|
|
46
|
+
const i18n = createI18n({
|
|
47
|
+
legacy: false,
|
|
48
|
+
locale: "en",
|
|
49
|
+
fallbackLocale: "en",
|
|
50
|
+
messages: {
|
|
51
|
+
en: { backend: { error: {
|
|
52
|
+
api: "An error has occurred.({message})",
|
|
53
|
+
login: "Please log in.",
|
|
54
|
+
not_found: "This {source} has been deleted."
|
|
55
|
+
} } },
|
|
56
|
+
ja: { backend: { error: {
|
|
57
|
+
api: "不具合が発生しました。({message})",
|
|
58
|
+
login: "ログインしなおしてください。",
|
|
59
|
+
not_found: "この{source}は削除されています。"
|
|
60
|
+
} } }
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/composables/use-locale.ts
|
|
65
|
+
const useLocale = () => {
|
|
66
|
+
const { locale, availableLocales, fallbackLocale } = i18n.global;
|
|
67
|
+
const autoDetect = () => {
|
|
68
|
+
const viewLocale = globalThis.navigator.languages[0];
|
|
69
|
+
locale.value = availableLocales.includes(viewLocale) ? viewLocale : fallbackLocale.value;
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
locale,
|
|
73
|
+
autoDetect
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/composables/backend/api/use-http-headers.ts
|
|
78
|
+
const useHttpHeaders = () => {
|
|
79
|
+
const { locale } = useLocale();
|
|
80
|
+
return { commonHeaders: computed(() => ({
|
|
81
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
82
|
+
Accept: "application/json",
|
|
83
|
+
"Accept-Language": locale.value
|
|
84
|
+
})) };
|
|
85
|
+
};
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/composables/backend/api/use-query-api.ts
|
|
88
|
+
const useQueryApi = async (url, options) => {
|
|
89
|
+
const { commonHeaders } = useHttpHeaders();
|
|
90
|
+
const { baseURL } = useApiConstants();
|
|
91
|
+
const tokenRef = ref();
|
|
92
|
+
const headers = commonHeaders.value;
|
|
93
|
+
if (options?.token) {
|
|
94
|
+
headers.Authorization = `Bearer ${options.token}`;
|
|
95
|
+
tokenRef.value = options.token;
|
|
96
|
+
}
|
|
97
|
+
const getOptions = {
|
|
98
|
+
baseURL: baseURL.value,
|
|
99
|
+
method: "get",
|
|
100
|
+
query: options?.query ?? {},
|
|
101
|
+
headers,
|
|
102
|
+
onResponse({ response }) {
|
|
103
|
+
if (!tokenRef.value) tokenRef.value = response.headers.get("Authorization")?.split(" ")[1];
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
if (options?.signal) getOptions.signal = options.signal;
|
|
107
|
+
if (options?.onRequestError) getOptions.onRequestError = options.onRequestError;
|
|
108
|
+
if (options?.onResponseError) getOptions.onResponseError = options.onResponseError;
|
|
109
|
+
const { data, error, pending } = await useOFetch(url, getOptions);
|
|
110
|
+
return {
|
|
111
|
+
token: tokenRef.value,
|
|
112
|
+
data,
|
|
113
|
+
error,
|
|
114
|
+
pending
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/composables/backend/api/use-mutation-api.ts
|
|
119
|
+
const useMutationApi = async (url, { method, body = {}, token = null, onRequestError, onResponseError }) => {
|
|
120
|
+
const { commonHeaders } = useHttpHeaders();
|
|
121
|
+
const { baseURL } = useApiConstants();
|
|
122
|
+
const headers = commonHeaders.value;
|
|
123
|
+
const tokenRef = ref();
|
|
124
|
+
if (token) {
|
|
125
|
+
headers.Authorization = `Bearer ${token}`;
|
|
126
|
+
tokenRef.value = token;
|
|
127
|
+
}
|
|
128
|
+
const options = {
|
|
129
|
+
baseURL: baseURL.value,
|
|
130
|
+
headers,
|
|
131
|
+
method
|
|
132
|
+
};
|
|
133
|
+
if (onRequestError) options.onRequestError = onRequestError;
|
|
134
|
+
if (onResponseError) options.onResponseError = onResponseError;
|
|
135
|
+
if (method == "post" || method == "put") {
|
|
136
|
+
options.body = body;
|
|
137
|
+
options.onResponse = ({ response }) => {
|
|
138
|
+
if (method == "post" && !tokenRef.value || method == "put") tokenRef.value = response.headers.get("Authorization")?.split(" ")[1];
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
const { data, error, pending } = await useOFetch(url, options);
|
|
142
|
+
return {
|
|
143
|
+
token: tokenRef.value,
|
|
144
|
+
data,
|
|
145
|
+
error,
|
|
146
|
+
pending
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/composables/backend/error/use-external-errors.ts
|
|
151
|
+
function useExternalErrors({ flash }) {
|
|
152
|
+
const errors = ref({});
|
|
153
|
+
const externalErrors = computed({
|
|
154
|
+
get() {
|
|
155
|
+
return errors.value;
|
|
156
|
+
},
|
|
157
|
+
set(value) {
|
|
158
|
+
if (errors.value) for (const key in value) errors.value[key] = value[key] ?? [];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
const clearExternalErrors = () => {
|
|
162
|
+
externalErrors.value = {};
|
|
163
|
+
};
|
|
164
|
+
const isSuccess = () => {
|
|
165
|
+
let result = true;
|
|
166
|
+
for (const key in errors.value) if (errors.value[key].length > 0) result = false;
|
|
167
|
+
if (flash.value.alert) result = false;
|
|
168
|
+
return result;
|
|
169
|
+
};
|
|
170
|
+
return {
|
|
171
|
+
externalErrors,
|
|
172
|
+
clearExternalErrors,
|
|
173
|
+
isSuccess
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/composables/backend/error/use-backend-error-info.ts
|
|
178
|
+
function useBackendErrorInfo() {
|
|
179
|
+
const info = ref({});
|
|
180
|
+
const backendErrorInfo = computed(() => {
|
|
181
|
+
return info.value;
|
|
182
|
+
});
|
|
183
|
+
const clearBackendErrorInfo = () => {
|
|
184
|
+
info.value = {};
|
|
185
|
+
};
|
|
186
|
+
return {
|
|
187
|
+
backendErrorInfo,
|
|
188
|
+
clearBackendErrorInfo
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/composables/backend/use-alert.ts
|
|
193
|
+
function useAlert({ flash, caller }) {
|
|
194
|
+
const { backendErrorInfo, clearBackendErrorInfo } = useBackendErrorInfo();
|
|
195
|
+
const setError = function(error, options) {
|
|
196
|
+
const off = options?.off ?? false;
|
|
197
|
+
clearBackendErrorInfo();
|
|
198
|
+
backendErrorInfo.value.status = error.status;
|
|
199
|
+
if (off) switch (error.status) {
|
|
200
|
+
case 401:
|
|
201
|
+
if (caller && "clearAccount" in caller && caller.clearAccount) caller.clearAccount();
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
else switch (error.status) {
|
|
205
|
+
case 401:
|
|
206
|
+
flash.value.alert = i18n.global.t("backend.error.login");
|
|
207
|
+
if (caller && "clearAccount" in caller && caller.clearAccount) caller.clearAccount();
|
|
208
|
+
break;
|
|
209
|
+
case 404:
|
|
210
|
+
{
|
|
211
|
+
const backendError = error.data;
|
|
212
|
+
backendErrorInfo.value.error = backendError;
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
case 422:
|
|
216
|
+
if (caller && "externalErrors" in caller && caller.externalErrors && error.data) {
|
|
217
|
+
const { errors } = error.data;
|
|
218
|
+
caller.externalErrors.value = errors;
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
default: flash.value.alert = i18n.global.t("backend.error.api", { message: error.message });
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
const reload = () => {
|
|
225
|
+
if (backendErrorInfo.value.status == 404) globalThis.setTimeout(() => {
|
|
226
|
+
globalThis.location.reload();
|
|
227
|
+
}, 1e3);
|
|
228
|
+
};
|
|
229
|
+
return {
|
|
230
|
+
backendErrorInfo,
|
|
231
|
+
setError,
|
|
232
|
+
reload
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/composables/util/use-date.ts
|
|
237
|
+
function useDate() {
|
|
238
|
+
const isValidDate = (str) => {
|
|
239
|
+
return !!str && !!str.match(/\d{4}\/\d{2}\/\d{2}/) && !isNaN(Date.parse(str));
|
|
240
|
+
};
|
|
241
|
+
return { isValidDate };
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/composables/use-entity.ts
|
|
245
|
+
function useEntity() {
|
|
246
|
+
const create = ({ from }) => {
|
|
247
|
+
const model = {};
|
|
248
|
+
Object.assign(model, from);
|
|
249
|
+
return model;
|
|
250
|
+
};
|
|
251
|
+
const copy = ({ from, to }) => {
|
|
252
|
+
Object.assign(to, from);
|
|
253
|
+
};
|
|
254
|
+
return {
|
|
255
|
+
create,
|
|
256
|
+
copy
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
//#endregion
|
|
260
|
+
//#region src/composables/use-flash.ts
|
|
261
|
+
function useFlash() {
|
|
262
|
+
const flash = ref({});
|
|
263
|
+
const clearFlash = () => {
|
|
264
|
+
flash.value = {};
|
|
265
|
+
};
|
|
266
|
+
return {
|
|
267
|
+
flash,
|
|
268
|
+
clearFlash
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
//#endregion
|
|
272
|
+
//#region src/composables/use-nano-route.ts
|
|
273
|
+
function useNanoRoute(router) {
|
|
274
|
+
const page = router.get();
|
|
275
|
+
return {
|
|
276
|
+
params: page?.params,
|
|
277
|
+
query: page?.search,
|
|
278
|
+
path: page?.path
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
//#endregion
|
|
282
|
+
export { i18n, useAlert, useApiConstants, useDate, useEntity, useExternalErrors, useFlash, useLocale, useMutationApi, useNanoRoute, useOFetch, useQueryApi };
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vesperjs/vue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"keywords": [
|
|
5
|
+
"vue.js"
|
|
6
|
+
],
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"author": "Yasumada Ashida",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./dist/index.mjs",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@formkit/tempo": "^1.0.0",
|
|
19
|
+
"@nanostores/persistent": "^1.3.3",
|
|
20
|
+
"@nanostores/router": "^1.0.0",
|
|
21
|
+
"@vue/reactivity": "^3.6.0-beta.8",
|
|
22
|
+
"nanostores": "^1.2.0",
|
|
23
|
+
"ofetch": "1.5.1",
|
|
24
|
+
"undici": "7.24.4",
|
|
25
|
+
"vue-i18n": "11.3.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^8.57.0",
|
|
29
|
+
"@typescript-eslint/parser": "^8.57.0",
|
|
30
|
+
"@vue/eslint-config-typescript": "^14.7.0",
|
|
31
|
+
"eslint": "^9.39.4",
|
|
32
|
+
"eslint-plugin-vue": "^10.8.0",
|
|
33
|
+
"oxfmt": "^0.41.0",
|
|
34
|
+
"tsdown": "^0.21.4",
|
|
35
|
+
"typescript": "5.9.3"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "tsdown --dts",
|
|
39
|
+
"build:check": "tsc--noEmit",
|
|
40
|
+
"lint": "eslint --fix './src/**/*.{js,ts}'",
|
|
41
|
+
"fmt": "oxfmt",
|
|
42
|
+
"fmt:check": "oxfmt --check"
|
|
43
|
+
}
|
|
44
|
+
}
|