@vixt/core 0.10.1 → 0.11.1

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.
@@ -1,4 +1,6 @@
1
- //#region src/client/app.d.ts
1
+ import * as _$nitro_types0 from "nitro/types";
2
+
3
+ //#region src/client/types/app.d.ts
2
4
  interface VixtApp {
3
5
  app: any;
4
6
  appConfig: VixtAppConfig;
@@ -8,16 +10,13 @@ interface CreateOptions {
8
10
  app: any;
9
11
  appConfig: VixtAppConfig;
10
12
  }
11
- interface VixtAppConfig extends Record<string, any> {
13
+ interface VixtAppConfig {
12
14
  readonly baseURL?: string;
13
15
  readonly rootId?: string;
16
+ [key: string]: any;
14
17
  }
15
- declare function defineAppConfig(config: VixtAppConfig): VixtAppConfig;
16
- declare function useAppConfig(): VixtAppConfig;
17
- declare function useVixtApp(): VixtApp;
18
- declare function createVixtApp(options: CreateOptions): VixtApp;
19
18
  //#endregion
20
- //#region src/client/plugin.d.ts
19
+ //#region src/client/types/plugin.d.ts
21
20
  interface PluginDefinition {
22
21
  name?: string;
23
22
  setup?: (this: void, vixt: VixtApp) => any;
@@ -27,7 +26,56 @@ interface VixtPlugin {
27
26
  /** @internal */
28
27
  _name?: string;
29
28
  }
29
+ //#endregion
30
+ //#region src/client/app.d.ts
31
+ /**
32
+ * Define the app config.
33
+ * @example
34
+ * ```ts
35
+ * // src/app.config.ts
36
+ * export default defineAppConfig({
37
+ * title: 'My Vixt App',
38
+ * description: 'A Vixt App',
39
+ * })
40
+ * ```
41
+ */
42
+ declare function defineAppConfig(config: VixtAppConfig): VixtAppConfig;
43
+ /** Access the app config defined in the project. */
44
+ declare function useAppConfig(): VixtAppConfig;
45
+ /** Create a Vixt App instance. */
46
+ declare function createVixtApp(options: CreateOptions): VixtApp;
47
+ /** Access the shared runtime context of the Vixt Application. */
48
+ declare function useVixtApp(): VixtApp;
49
+ //#endregion
50
+ //#region src/client/fetch.d.ts
51
+ declare const $fetch: _$nitro_types0.$Fetch;
52
+ //#endregion
53
+ //#region src/client/plugin.d.ts
54
+ /**
55
+ * A helper function for creating Vixt plugins.
56
+ * @example
57
+ * ```ts
58
+ * // src/plugins/my-plugin.ts
59
+ * interface PluginOptions {
60
+ * enabled?: boolean
61
+ * }
62
+ *
63
+ * declare module '@vixt/core/client' {
64
+ * interface VixtAppConfig {
65
+ * myPlugin?: PluginOptions
66
+ * }
67
+ * }
68
+ *
69
+ * export default defineVixtPlugin<PluginOptions>({
70
+ * name: 'my-plugin',
71
+ * setup(vixt) {
72
+ * console.log(vixt) // { app, router, routes, pinia, appConfig }
73
+ * }
74
+ * })
75
+ * ```
76
+ */
30
77
  declare function defineVixtPlugin(definition: PluginDefinition | VixtPlugin): VixtPlugin;
78
+ /** Applies plugins to a Vixt app. */
31
79
  declare function applyPlugins(vixt: VixtApp, plugins: VixtPlugin[]): void;
32
80
  //#endregion
33
- export { CreateOptions, PluginDefinition, VixtApp, VixtAppConfig, VixtPlugin, applyPlugins, createVixtApp, defineAppConfig, defineVixtPlugin, useAppConfig, useVixtApp };
81
+ export { $fetch, CreateOptions, PluginDefinition, VixtApp, VixtAppConfig, VixtPlugin, applyPlugins, createVixtApp, defineAppConfig, defineVixtPlugin, useAppConfig, useVixtApp };
@@ -1,28 +1,330 @@
1
1
  //#region src/client/app.ts
2
+ /**
3
+ * Define the app config.
4
+ * @example
5
+ * ```ts
6
+ * // src/app.config.ts
7
+ * export default defineAppConfig({
8
+ * title: 'My Vixt App',
9
+ * description: 'A Vixt App',
10
+ * })
11
+ * ```
12
+ */
2
13
  function defineAppConfig(config) {
3
14
  return config;
4
15
  }
16
+ /** Access the app config defined in the project. */
5
17
  function useAppConfig() {
6
18
  return useVixtApp()?.appConfig ?? {};
7
19
  }
8
- function useVixtApp() {
9
- return globalThis.useVixtApp?.();
10
- }
20
+ /** Create a Vixt App instance. */
11
21
  function createVixtApp(options) {
12
22
  const vixtApp = { ...options };
13
23
  globalThis.useVixtApp = () => vixtApp;
14
24
  return vixtApp;
15
25
  }
26
+ /** Access the shared runtime context of the Vixt Application. */
27
+ function useVixtApp() {
28
+ return globalThis.useVixtApp?.();
29
+ }
30
+ //#endregion
31
+ //#region ../../node_modules/.pnpm/ofetch@2.0.0-alpha.3/node_modules/ofetch/dist/index.mjs
32
+ /**
33
+ * Joins the given base URL and path, ensuring that there is only one slash between them.
34
+ */
35
+ function joinURL(base, path) {
36
+ if (!base || base === "/") return path || "/";
37
+ if (!path || path === "/") return base || "/";
38
+ const baseHasTrailing = base[base.length - 1] === "/";
39
+ const pathHasLeading = path[0] === "/";
40
+ if (baseHasTrailing && pathHasLeading) return base + path.slice(1);
41
+ if (!baseHasTrailing && !pathHasLeading) return `${base}/${path}`;
42
+ return base + path;
43
+ }
44
+ /**
45
+ * Adds the base path to the input path, if it is not already present.
46
+ */
47
+ function withBase(input = "", base = "") {
48
+ if (!base || base === "/") return input;
49
+ const _base = withoutTrailingSlash(base);
50
+ if (input.startsWith(_base)) return input;
51
+ return joinURL(_base, input);
52
+ }
53
+ function withoutTrailingSlash(path) {
54
+ if (!path || path === "/") return "/";
55
+ return path[path.length - 1] === "/" ? path.slice(0, -1) : path;
56
+ }
57
+ /**
58
+ * Returns the URL with the given query parameters. If a query parameter is undefined, it is omitted.
59
+ */
60
+ function withQuery(input, query) {
61
+ if (!query || Object.keys(query).length === 0) return input;
62
+ const searchIndex = input.indexOf("?");
63
+ if (searchIndex === -1) {
64
+ const normalizedQuery = Object.entries(query).filter(([, value]) => value !== void 0).flatMap(([key, value]) => {
65
+ if (Array.isArray(value)) return value.map((item) => [key, normalizeQueryValue(item)]);
66
+ return [[key, normalizeQueryValue(value)]];
67
+ });
68
+ const queryString$1 = new URLSearchParams(normalizedQuery).toString();
69
+ return queryString$1 ? `${input}?${queryString$1}` : input;
70
+ }
71
+ const searchParams = new URLSearchParams(input.slice(searchIndex + 1));
72
+ const base = input.slice(0, searchIndex);
73
+ for (const [key, value] of Object.entries(query)) if (value === void 0) searchParams.delete(key);
74
+ else if (Array.isArray(value)) for (const item of value) searchParams.append(key, normalizeQueryValue(item));
75
+ else searchParams.set(key, normalizeQueryValue(value));
76
+ const queryString = searchParams.toString();
77
+ return queryString ? `${base}?${queryString}` : base;
78
+ }
79
+ function normalizeQueryValue(value) {
80
+ if (value === null) return "";
81
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
82
+ if (typeof value === "object") return JSON.stringify(value);
83
+ return String(value);
84
+ }
85
+ var FetchError = class extends Error {
86
+ constructor(message, opts) {
87
+ super(message, opts);
88
+ this.name = "FetchError";
89
+ if (opts?.cause && !this.cause) this.cause = opts.cause;
90
+ }
91
+ };
92
+ function createFetchError(ctx) {
93
+ const errorMessage = ctx.error?.message || ctx.error?.toString() || "";
94
+ const method = ctx.request?.method || ctx.options?.method || "GET";
95
+ const url = ctx.request?.url || String(ctx.request) || "/";
96
+ const fetchError = new FetchError(`${`[${method}] ${JSON.stringify(url)}`}: ${ctx.response ? `${ctx.response.status} ${ctx.response.statusText}` : "<no response>"}${errorMessage ? ` ${errorMessage}` : ""}`, ctx.error ? { cause: ctx.error } : void 0);
97
+ for (const key of [
98
+ "request",
99
+ "options",
100
+ "response"
101
+ ]) Object.defineProperty(fetchError, key, { get() {
102
+ return ctx[key];
103
+ } });
104
+ for (const [key, refKey] of [
105
+ ["data", "_data"],
106
+ ["status", "status"],
107
+ ["statusCode", "status"],
108
+ ["statusText", "statusText"],
109
+ ["statusMessage", "statusText"]
110
+ ]) Object.defineProperty(fetchError, key, { get() {
111
+ return ctx.response && ctx.response[refKey];
112
+ } });
113
+ return fetchError;
114
+ }
115
+ const payloadMethods = new Set(Object.freeze([
116
+ "PATCH",
117
+ "POST",
118
+ "PUT",
119
+ "DELETE"
120
+ ]));
121
+ function isPayloadMethod(method = "GET") {
122
+ return payloadMethods.has(method.toUpperCase());
123
+ }
124
+ function isJSONSerializable(value) {
125
+ if (value === void 0) return false;
126
+ const t = typeof value;
127
+ if (t === "string" || t === "number" || t === "boolean" || t === null) return true;
128
+ if (t !== "object") return false;
129
+ if (Array.isArray(value)) return true;
130
+ if (value.buffer) return false;
131
+ if (value instanceof FormData || value instanceof URLSearchParams) return false;
132
+ return value.constructor && value.constructor.name === "Object" || typeof value.toJSON === "function";
133
+ }
134
+ const textTypes = new Set([
135
+ "image/svg",
136
+ "application/xml",
137
+ "application/xhtml",
138
+ "application/html"
139
+ ]);
140
+ const JSON_RE = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(;.+)?$/i;
141
+ function detectResponseType(_contentType = "") {
142
+ if (!_contentType) return "json";
143
+ const contentType = _contentType.split(";").shift() || "";
144
+ if (JSON_RE.test(contentType)) return "json";
145
+ if (contentType === "text/event-stream") return "stream";
146
+ if (textTypes.has(contentType) || contentType.startsWith("text/")) return "text";
147
+ return "blob";
148
+ }
149
+ function resolveFetchOptions(request, input, defaults, Headers$1) {
150
+ const headers = mergeHeaders(input?.headers ?? request?.headers, defaults?.headers, Headers$1);
151
+ let query;
152
+ if (defaults?.query || defaults?.params || input?.params || input?.query) query = {
153
+ ...defaults?.params,
154
+ ...defaults?.query,
155
+ ...input?.params,
156
+ ...input?.query
157
+ };
158
+ return {
159
+ ...defaults,
160
+ ...input,
161
+ query,
162
+ params: query,
163
+ headers
164
+ };
165
+ }
166
+ function mergeHeaders(input, defaults, Headers$1) {
167
+ if (!defaults) return new Headers$1(input);
168
+ const headers = new Headers$1(defaults);
169
+ if (input) for (const [key, value] of Symbol.iterator in input || Array.isArray(input) ? input : new Headers$1(input)) headers.set(key, value);
170
+ return headers;
171
+ }
172
+ async function callHooks(context, hooks) {
173
+ if (hooks) if (Array.isArray(hooks)) for (const hook of hooks) await hook(context);
174
+ else await hooks(context);
175
+ }
176
+ const retryStatusCodes = new Set([
177
+ 408,
178
+ 409,
179
+ 425,
180
+ 429,
181
+ 500,
182
+ 502,
183
+ 503,
184
+ 504
185
+ ]);
186
+ const nullBodyResponses = new Set([
187
+ 101,
188
+ 204,
189
+ 205,
190
+ 304
191
+ ]);
192
+ function createFetch(globalOptions = {}) {
193
+ const { fetch: fetch$1 = globalThis.fetch } = globalOptions;
194
+ async function onError(context) {
195
+ const isAbort = context.error && context.error.name === "AbortError" && !context.options.timeout || false;
196
+ if (context.options.retry !== false && !isAbort) {
197
+ let retries;
198
+ if (typeof context.options.retry === "number") retries = context.options.retry;
199
+ else retries = isPayloadMethod(context.options.method) ? 0 : 1;
200
+ const responseCode = context.response && context.response.status || 500;
201
+ if (retries > 0 && (Array.isArray(context.options.retryStatusCodes) ? context.options.retryStatusCodes.includes(responseCode) : retryStatusCodes.has(responseCode))) {
202
+ const retryDelay = typeof context.options.retryDelay === "function" ? context.options.retryDelay(context) : context.options.retryDelay || 0;
203
+ if (retryDelay > 0) await new Promise((resolve) => setTimeout(resolve, retryDelay));
204
+ return $fetchRaw(context.request, {
205
+ ...context.options,
206
+ retry: retries - 1
207
+ });
208
+ }
209
+ }
210
+ const error = createFetchError(context);
211
+ if (Error.captureStackTrace) Error.captureStackTrace(error, $fetchRaw);
212
+ throw error;
213
+ }
214
+ const $fetchRaw = async function $fetchRaw$1(_request, _options = {}) {
215
+ const context = {
216
+ request: _request,
217
+ options: resolveFetchOptions(_request, _options, globalOptions.defaults, Headers),
218
+ response: void 0,
219
+ error: void 0
220
+ };
221
+ if (context.options.method) context.options.method = context.options.method.toUpperCase();
222
+ if (context.options.onRequest) await callHooks(context, context.options.onRequest);
223
+ if (typeof context.request === "string") {
224
+ if (context.options.baseURL) context.request = withBase(context.request, context.options.baseURL);
225
+ if (context.options.query) {
226
+ context.request = withQuery(context.request, context.options.query);
227
+ delete context.options.query;
228
+ }
229
+ if ("query" in context.options) delete context.options.query;
230
+ if ("params" in context.options) delete context.options.params;
231
+ }
232
+ if (context.options.body && isPayloadMethod(context.options.method)) {
233
+ if (isJSONSerializable(context.options.body)) {
234
+ const contentType = context.options.headers.get("content-type");
235
+ if (typeof context.options.body !== "string") context.options.body = contentType === "application/x-www-form-urlencoded" ? new URLSearchParams(context.options.body).toString() : JSON.stringify(context.options.body);
236
+ context.options.headers = new Headers(context.options.headers || {});
237
+ if (!contentType) context.options.headers.set("content-type", "application/json");
238
+ if (!context.options.headers.has("accept")) context.options.headers.set("accept", "application/json");
239
+ } else if ("pipeTo" in context.options.body && typeof context.options.body.pipeTo === "function" || typeof context.options.body.pipe === "function") {
240
+ if (!("duplex" in context.options)) context.options.duplex = "half";
241
+ }
242
+ }
243
+ if (context.options.timeout) context.options.signal = context.options.signal ? AbortSignal.any([AbortSignal.timeout(context.options.timeout), context.options.signal]) : AbortSignal.timeout(context.options.timeout);
244
+ try {
245
+ context.response = await fetch$1(context.request, context.options);
246
+ } catch (error) {
247
+ context.error = error;
248
+ if (context.options.onRequestError) await callHooks(context, context.options.onRequestError);
249
+ return await onError(context);
250
+ }
251
+ if ((context.response.body || context.response._bodyInit) && !nullBodyResponses.has(context.response.status) && context.options.method !== "HEAD") {
252
+ const responseType = (context.options.parseResponse ? "json" : context.options.responseType) || detectResponseType(context.response.headers.get("content-type") || "");
253
+ switch (responseType) {
254
+ case "json": {
255
+ const data = await context.response.text();
256
+ if (data) {
257
+ const parseFunction = context.options.parseResponse || JSON.parse;
258
+ context.response._data = parseFunction(data);
259
+ }
260
+ break;
261
+ }
262
+ case "stream":
263
+ context.response._data = context.response.body || context.response._bodyInit;
264
+ break;
265
+ default: context.response._data = await context.response[responseType]();
266
+ }
267
+ }
268
+ if (context.options.onResponse) await callHooks(context, context.options.onResponse);
269
+ if (!context.options.ignoreResponseError && context.response.status >= 400 && context.response.status < 600) {
270
+ if (context.options.onResponseError) await callHooks(context, context.options.onResponseError);
271
+ return await onError(context);
272
+ }
273
+ return context.response;
274
+ };
275
+ const $fetch$1 = async function $fetch$2(request, options) {
276
+ return (await $fetchRaw(request, options))._data;
277
+ };
278
+ $fetch$1.raw = $fetchRaw;
279
+ $fetch$1.native = (...args) => fetch$1(...args);
280
+ $fetch$1.create = (defaultOptions = {}, customGlobalOptions = {}) => createFetch({
281
+ ...globalOptions,
282
+ ...customGlobalOptions,
283
+ defaults: {
284
+ ...globalOptions.defaults,
285
+ ...customGlobalOptions.defaults,
286
+ ...defaultOptions
287
+ }
288
+ });
289
+ return $fetch$1;
290
+ }
291
+ //#endregion
292
+ //#region src/client/fetch.ts
293
+ const $fetch = createFetch({ fetch: globalThis.fetch ? (...args) => globalThis.fetch(...args) : () => Promise.reject(/* @__PURE__ */ new Error("[ofetch] global.fetch is not supported!")) });
16
294
  //#endregion
17
295
  //#region src/client/plugin.ts
296
+ /**
297
+ * A helper function for creating Vixt plugins.
298
+ * @example
299
+ * ```ts
300
+ * // src/plugins/my-plugin.ts
301
+ * interface PluginOptions {
302
+ * enabled?: boolean
303
+ * }
304
+ *
305
+ * declare module '@vixt/core/client' {
306
+ * interface VixtAppConfig {
307
+ * myPlugin?: PluginOptions
308
+ * }
309
+ * }
310
+ *
311
+ * export default defineVixtPlugin<PluginOptions>({
312
+ * name: 'my-plugin',
313
+ * setup(vixt) {
314
+ * console.log(vixt) // { app, router, routes, pinia, appConfig }
315
+ * }
316
+ * })
317
+ * ```
318
+ */
18
319
  function defineVixtPlugin(definition) {
19
320
  if (typeof definition == "function") return definition;
20
321
  const pluginName = definition.name;
21
322
  const pluginSetup = definition.setup || (() => {});
22
323
  return Object.assign(pluginSetup, { _name: pluginName });
23
324
  }
325
+ /** Applies plugins to a Vixt app. */
24
326
  function applyPlugins(vixt, plugins) {
25
327
  for (const plugin of plugins) typeof plugin === "function" && plugin(vixt);
26
328
  }
27
329
  //#endregion
28
- export { applyPlugins, createVixtApp, defineAppConfig, defineVixtPlugin, useAppConfig, useVixtApp };
330
+ export { $fetch, applyPlugins, createVixtApp, defineAppConfig, defineVixtPlugin, useAppConfig, useVixtApp };