@scayle/storefront-nuxt 8.24.1 → 8.25.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/CHANGELOG.md CHANGED
@@ -1,5 +1,73 @@
1
1
  # @scayle/storefront-nuxt
2
2
 
3
+ ## 8.25.0
4
+
5
+ ### Minor Changes
6
+
7
+ - This change introduces the ability for the host application to define its own storage mounts, enhancing the flexibility of managing cache and session storage options within the Nuxt project.
8
+ To provide preconfigured storage mounts, the host application needs to mount storage drivers with specific names. The names `storefront-session` and `storefront-cache` are used for general cache and session storage, respectively. Additionally, shop-specific cache and session drivers can be configured by appending `:<shopId>` to the name, such as `storefront-session:1001` and `storefront-cache:1001`.
9
+
10
+ Preconfigured storage mounts can be implemented via a Nuxt server plugin within `./server/plugins`. If necessary, the `runtimeConfig` can be utilized to store the drivers' configuration:
11
+
12
+ ```ts
13
+ import fsDriver from 'unstorage/drivers/fs'
14
+ import compressionDriver from "@scayle/unstorage-compression-driver"
15
+ import { defineNitroPlugin, useStorage } from '#imports'
16
+
17
+ export default defineNitroPlugin(() => {
18
+ const storage = useStorage()
19
+ const config = useRuntimeConfig()
20
+ // Configure global storage (used as base config for all shops)
21
+ storage.mount('storefront-session', fsDriver({
22
+ base: config.sessionStorageBase,
23
+ }))
24
+ storage.mount('storefront-cache', fsDriver({
25
+ base: './cache',
26
+ }))
27
+
28
+ // The storage configuration can be overwritten on shop level if needed
29
+ storage.mount('storefront-cache:1001', compressionDriver(
30
+ encoding: 'brotli',
31
+ passthroughDriver: fsDriver({ base: './cache_1001' })
32
+ ))
33
+ })
34
+ ```
35
+
36
+ In scenarios where the build must not be runtime agnostic, the storage can also be configured statically in the `nuxt.config.ts` file. However, this is not the recommended approach:
37
+
38
+ ```ts
39
+ export default defineNuxtConfig({
40
+ nitro: {
41
+ storage: {
42
+ redis: {
43
+ driver: 'redis',
44
+ host: 'localhost',
45
+ },
46
+ db: {
47
+ driver: 'fs',
48
+ base: './.data/db',
49
+ },
50
+ },
51
+ },
52
+ })
53
+ ```
54
+
55
+ With the introduction of the new approach for configuring storefront storage mounts, the global and shop-specific `storage` option within the `@scayle/storefront-nuxt` runtime configuration has been deprecated.
56
+
57
+ ### Patch Changes
58
+
59
+ - Fix `.d.ts` validation errors reported by AreTheTypesWrong.
60
+ - Fix an issue caused by Nitro 2.11.7 which caused the context to be lost between RPC requests.
61
+
62
+ **Dependencies**
63
+
64
+ - Updated dependency to @scayle/h3-session@0.6.1
65
+
66
+ **@scayle/storefront-core v8.25.0**
67
+
68
+ - Patch
69
+ - **\[Code Style\]** Refactored brands and navigation tree RPCs to avoid destructuring the RPC context within function signatures
70
+
3
71
  ## 8.24.1
4
72
 
5
73
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,14 +1,10 @@
1
- export { d as AdditionalShopConfig, A as AppKeys, i as CheckoutEvent, C as CheckoutShopConfig, M as ModuleBaseOptions, j as ModulePublicRuntimeConfig, P as PublicShopConfig, c as SapiConfig, S as SessionConfig, e as ShopConfig, f as ShopConfigIndexed, b as StorageConfig, a as StorageEntity, g as StorefrontConfig, h as SupportedDriverName } from './shared/storefront-nuxt.CRtTNUi9.mjs';
1
+ export * from '../dist/runtime/types/module.js';
2
2
  export { ModuleHooks } from './module.mjs';
3
3
  export { rpcCall } from '../dist/runtime/rpc/rpcCall.js';
4
4
  export { extendPromise } from '../dist/runtime/utils/promise.js';
5
5
  export * from '../dist/runtime/utils/seo.js';
6
6
  export * from '@scayle/storefront-core';
7
- export { LogLevel } from '@scayle/storefront-core';
8
7
  export { unwrap } from '@scayle/storefront-core/dist/utils/response';
9
- import '@scayle/unstorage-compression-driver';
10
- import 'unstorage';
11
- import '../dist/runtime/utils/zodSchema.js';
12
8
  import '@nuxt/schema';
13
9
 
14
10
  interface RpcMethodsStorefront {
package/dist/module.d.mts CHANGED
@@ -1,11 +1,7 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
2
  import { HookResult } from '@nuxt/schema';
3
- import { M as ModuleBaseOptions } from './shared/storefront-nuxt.CRtTNUi9.mjs';
4
- export { d as AdditionalShopConfig, A as AppKeys, i as CheckoutEvent, C as CheckoutShopConfig, j as ModulePublicRuntimeConfig, P as PublicShopConfig, c as SapiConfig, S as SessionConfig, e as ShopConfig, f as ShopConfigIndexed, b as StorageConfig, a as StorageEntity, g as StorefrontConfig, h as SupportedDriverName } from './shared/storefront-nuxt.CRtTNUi9.mjs';
5
- export { LogLevel } from '@scayle/storefront-core';
6
- import '@scayle/unstorage-compression-driver';
7
- import 'unstorage';
8
- import '../dist/runtime/utils/zodSchema.js';
3
+ import { ModuleBaseOptions } from '../dist/runtime/types/module.js';
4
+ export * from '../dist/runtime/types/module.js';
9
5
 
10
6
  /**
11
7
  * Definition of a custom RPC import
@@ -58,5 +54,5 @@ declare module '@nuxt/schema' {
58
54
  */
59
55
  declare const _default: _nuxt_schema.NuxtModule<ModuleBaseOptions, ModuleBaseOptions, false>;
60
56
 
61
- export { ModuleBaseOptions, _default as default };
57
+ export { _default as default };
62
58
  export type { ModuleHooks };
package/dist/module.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@scayle/storefront-nuxt",
3
- "version": "8.24.1",
3
+ "version": "8.25.0",
4
4
  "configKey": "storefront",
5
5
  "compatibility": {
6
6
  "nuxt": "^3.9.0"
7
7
  },
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.1",
10
- "unbuild": "2.0.0"
10
+ "unbuild": "3.5.0"
11
11
  }
12
12
  }
package/dist/module.mjs CHANGED
@@ -7,6 +7,7 @@ import { builtinDrivers } from 'unstorage';
7
7
  import { createConsola } from 'consola';
8
8
  import { nodeFileTrace } from '@vercel/nft';
9
9
  import { getApiBasePath } from '../dist/runtime/server/middleware/bootstrap-utils.js';
10
+ export * from '../dist/runtime/types/module.js';
10
11
 
11
12
  function stringToBoolean(value, defaultValue = false) {
12
13
  return value ? value.toLowerCase() === "true" : defaultValue;
@@ -53,7 +54,7 @@ export default {
53
54
  }`;
54
55
  }
55
56
  const PACKAGE_NAME = "@scayle/storefront-nuxt";
56
- const PACKAGE_VERSION = "8.24.1";
57
+ const PACKAGE_VERSION = "8.25.0";
57
58
  const logger = createConsola({
58
59
  fancy: true,
59
60
  formatOptions: {
@@ -88,7 +89,7 @@ function createRpcMethodTypeDeclaration(customRpcImports) {
88
89
  }
89
90
  export {}`;
90
91
  }
91
- async function nitroSetup(nitroConfig, config) {
92
+ async function nitroSetup(nitroConfig, config, moduleOptions) {
92
93
  const { resolve, resolvePath } = createResolver(import.meta.url);
93
94
  const { apiBasePath, customRpcImports, coreMethodNames, usedDrivers } = config;
94
95
  nitroConfig.replace = nitroConfig.replace || {};
@@ -138,8 +139,15 @@ async function nitroSetup(nitroConfig, config) {
138
139
  nitroConfig.plugins = nitroConfig.plugins ?? [];
139
140
  nitroConfig.plugins.push(resolve("./runtime/nitro/plugins/nitroLogger"));
140
141
  nitroConfig.plugins.push(resolve("./runtime/nitro/plugins/redirectOnError"));
142
+ if (!!moduleOptions?.storage || Object.values(moduleOptions?.shops || {}).some(
143
+ (shopConfig) => !!shopConfig.storage
144
+ )) {
145
+ nitroConfig.plugins.push(
146
+ resolve("./runtime/nitro/plugins/nitroLegacyStorageConfig")
147
+ );
148
+ }
141
149
  nitroConfig.plugins.push(
142
- resolve("./runtime/nitro/plugins/nitroRuntimeStorageConfig")
150
+ resolve("./runtime/nitro/plugins/internalFetch")
143
151
  );
144
152
  if (stringToBoolean(process.env.SFC_PLUGIN_CONFIG_VALIDATION_ENABLED, true)) {
145
153
  logger.debug("Installing config validation plugin");
@@ -175,6 +183,16 @@ async function nitroSetup(nitroConfig, config) {
175
183
  nitroConfig.externals.inline = nitroConfig.externals.inline ?? [];
176
184
  nitroConfig.externals.inline.push(...tracedImports);
177
185
  }
186
+ async function nitroPostInit(moduleOptions, nitroApp) {
187
+ const { resolve } = createResolver(import.meta.url);
188
+ if (!moduleOptions?.storage && !Object.values(moduleOptions?.shops || {}).some(
189
+ (shopConfig) => !!shopConfig.storage
190
+ )) {
191
+ nitroApp.options.plugins.push(
192
+ resolve("./runtime/nitro/plugins/nitroStorageConfig")
193
+ );
194
+ }
195
+ }
178
196
  function validateRpcMethodOverrides(rpcMethodOverrides, customRpcNames, coreRpcNames) {
179
197
  const overriddenRPCMethodNames = new Set(rpcMethodOverrides);
180
198
  for (const rpcMethodName of customRpcNames) {
@@ -336,9 +354,10 @@ const module = defineNuxtModule({
336
354
  customRpcImports,
337
355
  coreMethodNames: [...rpcMethodNames],
338
356
  usedDrivers: getUsedDrivers(nuxt.options.runtimeConfig.storefront)
339
- });
357
+ }, nuxt.options.runtimeConfig.storefront);
340
358
  });
341
- nuxt.hooks.hook("nitro:init", (nitro) => {
359
+ nuxt.hooks.hook("nitro:init", async (nitro) => {
360
+ await nitroPostInit(nuxt.options.runtimeConfig.storefront, nitro);
342
361
  nitro.hooks.hook("rollup:before", (_nitro, rollupConfig) => {
343
362
  const existingHandler = rollupConfig.onwarn;
344
363
  rollupConfig.onwarn = (warning, handler) => {
@@ -1,4 +1,4 @@
1
- import type { PublicShopConfig } from '../../../module.js';
1
+ import type { PublicShopConfig } from '../../types/module.js';
2
2
  /**
3
3
  * Provides a reactive list of available shops.
4
4
  *
@@ -1,5 +1,5 @@
1
1
  import type { Ref } from 'vue';
2
- import type { PublicShopConfig } from '../../../module.js';
2
+ import type { PublicShopConfig } from '../../types/module.js';
3
3
  /**
4
4
  * Provides a reactive reference to the current shop configuration.
5
5
  *
@@ -8,9 +8,9 @@ import { useCurrentShop } from "./useCurrentShop.js";
8
8
  import { toValue, isRef } from "vue";
9
9
  import { useRuntimeConfig } from "#app/nuxt";
10
10
  function getFetch(nuxtApp, log) {
11
- const fetch = nuxtApp.ssrContext?.event.$fetch ?? $fetch;
12
- if (nuxtApp.ssrContext?.event && !nuxtApp.ssrContext?.event.$fetch) {
13
- log.error("event.$fetch was not found!");
11
+ const fetch = nuxtApp.ssrContext?.event.context.$fetchWithContext ?? $fetch;
12
+ if (nuxtApp.ssrContext?.event && !nuxtApp.ssrContext?.event.context.$fetchWithContext) {
13
+ log.error("event.$fetchWithContext was not found!");
14
14
  }
15
15
  return fetch;
16
16
  }
@@ -31,7 +31,7 @@ async function getBasketKey(appKeys, session, $log, $shopConfig) {
31
31
  }) : session?.id;
32
32
  }
33
33
  function buildRpcCall(event, shopConfig, apiBasePath) {
34
- const fetch = event.$fetch;
34
+ const fetch = event.context.$fetchWithContext;
35
35
  return async function rpcCall(method, params = void 0) {
36
36
  const data = await fetch(`${apiBasePath}/rpc/${method}`, {
37
37
  // @ts-expect-error Type '"POST"' is not assignable to type 'AvailableRouterMethod<`${string}/rpc/${N}`> | Uppercase<AvailableRouterMethod<`${string}/rpc/${N}`>> | undefined'.ts(2322)
@@ -0,0 +1,21 @@
1
+ declare module 'h3' {
2
+ interface H3EventContext {
3
+ $fetchWithContext: typeof globalThis.$fetch;
4
+ }
5
+ }
6
+ /**
7
+ * Nitro plugin to provide an internal fetch function on the event.
8
+ *
9
+ * Nitro includes an `event.$fetch` function for internal fetch requests to allow sharing the headers and
10
+ * context across requests. However, as of 2.11.7, the context is no longer shared, just the headers. As our
11
+ * bootstrapping depends on this behavior, we create a custom function with the pre-2.11.7 behavior. This enables
12
+ * compability with 2.11.7 as well as earlier versions.
13
+ *
14
+ * @see https://nitro.build/guide/plugins
15
+ *
16
+ * @param nitroApp The nitro app instance.
17
+ *
18
+ * @returns Nitro plugin function
19
+ */
20
+ declare const _default: import("nitropack").NitroAppPlugin;
21
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import { defineNitroPlugin } from "nitropack/runtime/plugin";
2
+ import { fetchWithEvent } from "h3";
3
+ export default defineNitroPlugin((nitroApp) => {
4
+ nitroApp.hooks.hook("request", (event) => {
5
+ const $fetch = globalThis.$fetch;
6
+ const envContext = (
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ event.node.req?.__unenv__
9
+ );
10
+ if (envContext) {
11
+ Object.assign(event.context, envContext);
12
+ }
13
+ event.context.$fetchWithContext = (req, init) => fetchWithEvent(event, req, init, {
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ fetch: $fetch
16
+ });
17
+ });
18
+ });
@@ -9,6 +9,7 @@ import drivers from "#virtual/storage-drivers";
9
9
  import { defineNitroPlugin } from "nitropack/runtime/plugin";
10
10
  import { useStorage } from "nitropack/runtime/storage";
11
11
  import { useRuntimeConfig } from "#imports";
12
+ import { getAvailableMounts } from "../../utils/storage.js";
12
13
  function createMountDriver(options) {
13
14
  if (options?.driver) {
14
15
  const compression = options?.compression;
@@ -25,7 +26,7 @@ function createMountDriver(options) {
25
26
  }
26
27
  function mountStorage(storage, options) {
27
28
  const { config, base } = options;
28
- const mounts = storage.getMounts().map((existingMount) => existingMount.base.replace(":", ""));
29
+ const mounts = getAvailableMounts(storage);
29
30
  if (!mounts.includes(base)) {
30
31
  if (config) {
31
32
  storage.mount(base, createMountDriver(config));
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This plugin expects a `storefront-cache` and `storefront-session` mount point to be provided.
3
+ * It will then mount a shop-specific storage mounts for each shop in the configuration.
4
+ * When a shop-specific mount is already provided, it will not be overridden.
5
+ */
6
+ declare const _default: import("nitropack").NitroAppPlugin;
7
+ export default _default;
@@ -0,0 +1,57 @@
1
+ import { createConsola } from "consola";
2
+ import {
3
+ STORAGE_MOUNT_CACHE,
4
+ STORAGE_MOUNT_SESSION
5
+ } from "../../server/utils/cacheStorage.js";
6
+ import createLog from "../../createLog.js";
7
+ import { JSONReporter } from "../../JSONReporter.js";
8
+ import { defineNitroPlugin } from "nitropack/runtime/plugin";
9
+ import { useStorage } from "nitropack/runtime/storage";
10
+ import { useRuntimeConfig } from "#imports";
11
+ import { getAvailableMounts, mountStorage } from "../../utils/storage.js";
12
+ export default defineNitroPlugin(async () => {
13
+ const storage = useStorage();
14
+ const config = useRuntimeConfig();
15
+ const { shops } = config.storefront;
16
+ const logConfig = config.public.storefront.log;
17
+ const log = createLog(
18
+ (opts) => createConsola({
19
+ ...logConfig.json ? { reporters: [new JSONReporter()] } : void 0,
20
+ stderr: logConfig.output === "stdout" ? process.stdout : process.stderr,
21
+ stdout: logConfig.output === "stderr" ? process.stderr : process.stdout,
22
+ ...opts
23
+ }),
24
+ logConfig.name,
25
+ logConfig.level
26
+ );
27
+ const availableMounts = getAvailableMounts(storage);
28
+ if (!availableMounts.includes(STORAGE_MOUNT_SESSION)) {
29
+ log.warn(
30
+ `${STORAGE_MOUNT_SESSION} storage mount not provided. Falling back to memory driver.`
31
+ );
32
+ }
33
+ if (!availableMounts.includes(STORAGE_MOUNT_CACHE)) {
34
+ log.warn(
35
+ `${STORAGE_MOUNT_CACHE} storage mount not provided. Falling back to memory driver.`
36
+ );
37
+ }
38
+ const mountShopStorage = async (shopId, mount) => {
39
+ try {
40
+ if (!availableMounts.includes(mount)) {
41
+ await mountStorage(storage, mount);
42
+ }
43
+ } catch (error) {
44
+ log.error(
45
+ `Unable to create required storage mount '${mount}'.`,
46
+ error
47
+ );
48
+ }
49
+ };
50
+ for (const shop of Object.values(shops)) {
51
+ await mountShopStorage(shop.shopId, `${STORAGE_MOUNT_CACHE}:${shop.shopId}`);
52
+ await mountShopStorage(
53
+ shop.shopId,
54
+ `${STORAGE_MOUNT_SESSION}:${shop.shopId}`
55
+ );
56
+ }
57
+ });
@@ -1,6 +1,6 @@
1
1
  import type { RpcContext, RpcMethodName, RpcMethodParameters, RpcMethodReturnType } from '@scayle/storefront-core';
2
2
  import type { NuxtApp } from 'nuxt/app';
3
- import type { PublicShopConfig } from '../../index.js';
3
+ import type { PublicShopConfig } from '../types/module.js';
4
4
  /**
5
5
  * Invokes an RPC method on the client or server.
6
6
  * Uses an HTTP request on the client and a direct call on the server via `$fetch`.
@@ -1,6 +1,6 @@
1
1
  import { unwrap } from "@scayle/storefront-core/dist/utils/response";
2
2
  export const rpcCall = (nuxtApp, method, shop) => {
3
- const fetch = nuxtApp.ssrContext?.event.$fetch ?? $fetch;
3
+ const fetch = nuxtApp.ssrContext?.event.context.$fetchWithContext ?? $fetch;
4
4
  return async (params = void 0) => {
5
5
  const data = await fetch(`${shop.apiBasePath ?? "/api"}/rpc/${method}`, {
6
6
  // @ts-expect-error Type '"POST"' is not assignable to type 'AvailableRouterMethod<`${string}/rpc/${N}`> | Uppercase<AvailableRouterMethod<`${string}/rpc/${N}`>> | undefined'.ts(2322)
@@ -1,21 +1,21 @@
1
- import { WithParams, rpcMethods, StorefrontHooks, RpcContext, RpcMethodName, HashAlgorithm, ShopUser } from '@scayle/storefront-core';
2
- import { CompressionEncodings } from '@scayle/unstorage-compression-driver';
3
- import { BuiltinDriverName, BuiltinDriverOptions } from 'unstorage';
4
- import { StorefrontConfigType, ShopSelectorType, RedirectType, ShopConfigType, ModulePublicRuntimeConfigType, CheckoutShopConfigType, SessionType, StorageType, SapiConfigType, IdpType } from '../../dist/runtime/utils/zodSchema.js';
5
- import { HookResult } from '@nuxt/schema';
6
-
1
+ import type { HashAlgorithm, ShopUser, WithParams, rpcMethods, StorefrontHooks, RpcMethodName, RpcContext } from '@scayle/storefront-core';
2
+ import type { CompressionEncodings } from '@scayle/unstorage-compression-driver';
3
+ import type { BuiltinDriverName, BuiltinDriverOptions } from 'unstorage';
4
+ import type { CheckoutShopConfigType, SessionType, StorageType, SapiConfigType, ShopConfigType, StorefrontConfigType, ShopSelectorType, ModulePublicRuntimeConfigType, RedirectType, IdpType } from '../utils/zodSchema.js';
5
+ import type { HookResult } from '@nuxt/schema';
6
+ export type { LogLevel } from '@scayle/storefront-core';
7
7
  /**
8
8
  * Represents shop-specific configuration relating to the SCAYLE Checkout.
9
9
  *
10
10
  * @see https://scayle.dev/en/checkout-guide/authentication-accounts/general#create-api-client
11
11
  */
12
- type CheckoutShopConfig = CheckoutShopConfigType;
12
+ export type CheckoutShopConfig = CheckoutShopConfigType;
13
13
  /**
14
14
  * Representation of options to configure how the storefront core manages sessions
15
15
  *
16
16
  * @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/sessions#configuration
17
17
  */
18
- type SessionConfig = SessionType;
18
+ export type SessionConfig = SessionType;
19
19
  /**
20
20
  * Representation of a custom [Unstorage](https://unstorage.unjs.io/) driver name.
21
21
  *
@@ -32,7 +32,7 @@ type CustomDriverName = string & {
32
32
  *
33
33
  * @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/caching#storefront-storage-cache-configuration
34
34
  */
35
- type StorageEntity<Driver extends SupportedDriverName | CustomDriverName | unknown = unknown, DriverOptions = Driver extends keyof BuiltinDriverOptions ? BuiltinDriverOptions[Driver] : unknown> = {
35
+ export type StorageEntity<Driver extends SupportedDriverName | CustomDriverName | unknown = unknown, DriverOptions = Driver extends keyof BuiltinDriverOptions ? BuiltinDriverOptions[Driver] : unknown> = {
36
36
  driver: Driver;
37
37
  compression?: CompressionEncodings;
38
38
  } & DriverOptions;
@@ -43,7 +43,7 @@ type StorageEntity<Driver extends SupportedDriverName | CustomDriverName | unkno
43
43
  *
44
44
  * @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/introduction#storage
45
45
  */
46
- interface StorageConfig {
46
+ export interface StorageConfig {
47
47
  /**
48
48
  * The cache storage configuration.
49
49
  *
@@ -69,14 +69,14 @@ interface StorageConfig {
69
69
  * @see https://scayle.dev/en/api-guides/storefront-api/getting-started/authentication
70
70
  * @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/introduction#storefront-api
71
71
  */
72
- type SapiConfig = SapiConfigType;
72
+ export type SapiConfig = SapiConfigType;
73
73
  /**
74
74
  * Representation of Application-specific keys,
75
75
  * defining how keys are generated for baskets and wishlists.
76
76
  *
77
77
  * @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/authentication#app-keys-for-baskets-and-wishlists
78
78
  */
79
- interface AppKeys {
79
+ export interface AppKeys {
80
80
  /** The wishlist key used as prefix to generate user-specific wishlist identifier. */
81
81
  wishlistKey: string;
82
82
  /** The basket key used as prefix to generate user-specific basket identifier. */
@@ -91,20 +91,20 @@ interface AppKeys {
91
91
  *
92
92
  * @see https://scayle.dev/en/storefront-guide/developer-guide/basic-setup/introduction#additional-shop-data
93
93
  */
94
- interface AdditionalShopConfig {
94
+ export interface AdditionalShopConfig {
95
95
  }
96
96
  /**
97
97
  * Shop configuration.
98
98
  */
99
- type ShopConfig = ShopConfigType & AdditionalShopConfig;
99
+ export type ShopConfig = ShopConfigType & AdditionalShopConfig;
100
100
  /**
101
101
  * Shop configuration indexed by shop ID.
102
102
  */
103
- type ShopConfigIndexed = Record<string, ShopConfig>;
103
+ export type ShopConfigIndexed = Record<string, ShopConfig>;
104
104
  /**
105
105
  * Public shop configuration. This configuration is accessible on the client-side.
106
106
  */
107
- interface PublicShopConfig extends Pick<ShopConfig, 'shopId' | 'domain' | 'locale' | 'currency' | 'currencyFractionDigits'> {
107
+ export interface PublicShopConfig extends Pick<ShopConfig, 'shopId' | 'domain' | 'locale' | 'currency' | 'currencyFractionDigits'> {
108
108
  /** Checkout configuration. */
109
109
  checkout: Pick<CheckoutShopConfig, 'host'>;
110
110
  /** API base path. */
@@ -117,7 +117,7 @@ interface PublicShopConfig extends Pick<ShopConfig, 'shopId' | 'domain' | 'local
117
117
  /**
118
118
  * Storefront configuration.
119
119
  */
120
- type StorefrontConfig = StorefrontConfigType & {
120
+ export type StorefrontConfig = StorefrontConfigType & {
121
121
  /**
122
122
  * Default "with" parameters for Storefront API requests. These are used as defaults
123
123
  * within composables like `useWishlist` and can be overridden if needed. Some
@@ -185,11 +185,11 @@ type ModuleOption = {
185
185
  */
186
186
  shops: ShopConfigIndexed;
187
187
  };
188
- type SupportedDriverName = BuiltinDriverName | 'scayleKv';
188
+ export type SupportedDriverName = BuiltinDriverName | 'scayleKv';
189
189
  /**
190
190
  * Module base options. Extends `StorefrontConfig` and `ModuleOption`.
191
191
  */
192
- type ModuleBaseOptions = StorefrontConfig & ModuleOption & {
192
+ export type ModuleBaseOptions = StorefrontConfig & ModuleOption & {
193
193
  /**
194
194
  * The RPC directory where the custom application RPCs are defined.
195
195
  * The directory should have an `index.ts` file where all RPCs are exported using their name.
@@ -209,7 +209,7 @@ type ModuleBaseOptions = StorefrontConfig & ModuleOption & {
209
209
  *
210
210
  * @see https://scayle.dev/en/checkout-guide/integration/webcomponent#tracking
211
211
  */
212
- interface CheckoutEvent {
212
+ export interface CheckoutEvent {
213
213
  /** Action. */
214
214
  action?: 'authenticated';
215
215
  /** Type. */
@@ -237,7 +237,7 @@ interface CheckoutEvent {
237
237
  status: 'successful' | 'error';
238
238
  };
239
239
  }
240
- interface ModulePublicRuntimeConfig extends ModulePublicRuntimeConfigType {
240
+ export interface ModulePublicRuntimeConfig extends ModulePublicRuntimeConfigType {
241
241
  }
242
242
  declare module '@nuxt/schema' {
243
243
  interface RuntimeConfig {
@@ -264,5 +264,3 @@ declare module 'nitropack' {
264
264
  'storefront:rpc:error': (rpcName: RpcMethodName, context: RpcContext, error: unknown) => HookResult;
265
265
  }
266
266
  }
267
-
268
- export type { AppKeys as A, CheckoutShopConfig as C, ModuleBaseOptions as M, PublicShopConfig as P, SessionConfig as S, StorageEntity as a, StorageConfig as b, SapiConfig as c, AdditionalShopConfig as d, ShopConfig as e, ShopConfigIndexed as f, StorefrontConfig as g, SupportedDriverName as h, CheckoutEvent as i, ModulePublicRuntimeConfig as j };
File without changes
@@ -0,0 +1,19 @@
1
+ import type { Storage } from 'unstorage';
2
+ /**
3
+ * Returns a list of available mount points for the provided storage instance.
4
+ * The mount points are normalized by removing the tailing `:`.
5
+ * @param storage - The storage instance.
6
+ * @returns List of available mount points.
7
+ */
8
+ export declare const getAvailableMounts: (storage: Storage) => string[];
9
+ /**
10
+ * Mounts a {@link Storage | storage}.
11
+ *
12
+ * It checks if a mount with the given base path already exists and
13
+ * mounts a new storage instance if not. It prioritizes a provided configuration,
14
+ * falling back to the default memory driver.
15
+ *
16
+ * @param storage - The storage instance to mount to.
17
+ * @param mount - Mount name.
18
+ */
19
+ export declare const mountStorage: (storage: Storage, mount: string) => Promise<void>;
@@ -0,0 +1,13 @@
1
+ export const getAvailableMounts = (storage) => {
2
+ return storage.getMounts().map((existingMount) => existingMount.base.replace(/:$/, ""));
3
+ };
4
+ export const mountStorage = async (storage, mount) => {
5
+ const mounts = getAvailableMounts(storage);
6
+ if (!mounts.includes(mount)) {
7
+ const { driver: baseDriver } = storage.getMount(mount);
8
+ storage.mount(
9
+ mount,
10
+ baseDriver
11
+ );
12
+ }
13
+ };
@@ -251,6 +251,7 @@ declare const ShopConfigSchema: z.ZodObject<{
251
251
  host: string;
252
252
  token: string;
253
253
  }>>;
254
+ /** @deprecated The `storage` option within `shopConfig` is deprecated. Consider using nuxt storage configuration instead. */
254
255
  storage: z.ZodOptional<z.ZodObject<{
255
256
  session: z.ZodOptional<z.ZodDiscriminatedUnion<"driver", [z.ZodObject<{
256
257
  driver: z.ZodEnum<[BuiltinDriverName, ...BuiltinDriverName[]]>;
@@ -615,6 +616,7 @@ declare const StorefrontConfigSchema: z.ZodObject<{
615
616
  secret?: string | string[] | undefined;
616
617
  domain?: string | undefined;
617
618
  }>>;
619
+ /** @deprecated The `storage` option within `storefront` is deprecated. Consider using nuxt storage configuration instead. */
618
620
  storage: z.ZodOptional<z.ZodObject<{
619
621
  session: z.ZodOptional<z.ZodDiscriminatedUnion<"driver", [z.ZodObject<{
620
622
  driver: z.ZodEnum<[BuiltinDriverName, ...BuiltinDriverName[]]>;
@@ -1194,6 +1196,7 @@ export declare const RuntimeConfigSchema: z.ZodObject<{
1194
1196
  host: string;
1195
1197
  token: string;
1196
1198
  }>>;
1199
+ /** @deprecated The `storage` option within `shopConfig` is deprecated. Consider using nuxt storage configuration instead. */
1197
1200
  storage: z.ZodOptional<z.ZodObject<{
1198
1201
  session: z.ZodOptional<z.ZodDiscriminatedUnion<"driver", [z.ZodObject<{
1199
1202
  driver: z.ZodEnum<[BuiltinDriverName, ...BuiltinDriverName[]]>;
@@ -1726,6 +1729,7 @@ export declare const RuntimeConfigSchema: z.ZodObject<{
1726
1729
  secret?: string | string[] | undefined;
1727
1730
  domain?: string | undefined;
1728
1731
  }>>;
1732
+ /** @deprecated The `storage` option within `storefront` is deprecated. Consider using nuxt storage configuration instead. */
1729
1733
  storage: z.ZodOptional<z.ZodObject<{
1730
1734
  session: z.ZodOptional<z.ZodDiscriminatedUnion<"driver", [z.ZodObject<{
1731
1735
  driver: z.ZodEnum<[BuiltinDriverName, ...BuiltinDriverName[]]>;
@@ -102,6 +102,7 @@ const ShopConfigSchema = z.object({
102
102
  isEnabled: z.boolean().optional(),
103
103
  sessionConfig: SessionSchema.optional(),
104
104
  sapi: SapiSchema.optional(),
105
+ /** @deprecated The `storage` option within `shopConfig` is deprecated. Consider using nuxt storage configuration instead. */
105
106
  storage: z.object({
106
107
  session: StorageSchema.optional(),
107
108
  cache: StorageSchema.optional()
@@ -118,6 +119,7 @@ const CacheSchema = z.object({
118
119
  const ShopSelectorSchema = z.enum(["path", "domain", "path_or_default"]);
119
120
  const StorefrontConfigSchema = z.object({
120
121
  session: SessionSchema.optional(),
122
+ /** @deprecated The `storage` option within `storefront` is deprecated. Consider using nuxt storage configuration instead. */
121
123
  storage: z.object({
122
124
  session: StorageSchema.optional(),
123
125
  cache: StorageSchema.optional()
@@ -1,12 +1,8 @@
1
1
  import { Factory } from 'fishery';
2
- import { M as ModuleBaseOptions, e as ShopConfig } from '../shared/storefront-nuxt.CRtTNUi9.mjs';
2
+ import { ModuleBaseOptions, ShopConfig } from '../../dist/runtime/types/module.js';
3
3
  import { RpcContext } from '@scayle/storefront-core';
4
4
  import { RouteLocationNormalizedLoadedGeneric } from 'vue-router';
5
5
  export * from '@scayle/storefront-core/dist/test/factories';
6
- import '@scayle/unstorage-compression-driver';
7
- import 'unstorage';
8
- import '../../dist/runtime/utils/zodSchema.js';
9
- import '@nuxt/schema';
10
6
 
11
7
  interface ModuleOptionsFactoryParams {
12
8
  shops: ShopConfig[];
package/dist/types.d.mts CHANGED
@@ -1,18 +1,15 @@
1
1
  import type { NuxtModule } from '@nuxt/schema'
2
2
 
3
- import type { default as Module, ModuleHooks, ModulePublicRuntimeConfig } from './module.mjs'
3
+ import type { default as Module, ModuleHooks } from './module.mjs'
4
4
 
5
5
  declare module '@nuxt/schema' {
6
6
  interface NuxtHooks extends ModuleHooks {}
7
- interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}
8
7
  }
9
8
 
10
9
  export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
11
10
 
12
- export { type AdditionalShopConfig, type AppKeys, type CheckoutEvent, type CheckoutShopConfig, type ModulePublicRuntimeConfig, type PublicShopConfig, type SapiConfig, type SessionConfig, type ShopConfig, type ShopConfigIndexed, type StorageConfig, type StorageEntity, type StorefrontConfig, type SupportedDriverName } from './shared/storefront-nuxt.CRtTNUi9.mjs'
13
-
14
- export { type LogLevel } from '@scayle/storefront-core'
15
-
16
- export { type ModuleBaseOptions, default } from './module.mjs'
11
+ export { default } from './module.mjs'
17
12
 
18
13
  export { type ModuleHooks } from './module.mjs'
14
+
15
+ export * from '../dist/runtime/types/module.js'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@scayle/storefront-nuxt",
3
3
  "type": "module",
4
- "version": "8.24.1",
4
+ "version": "8.25.0",
5
5
  "description": "Nuxt integration for the SCAYLE Commerce Engine and Storefront API",
6
6
  "author": "SCAYLE Commerce Engine",
7
7
  "license": "MIT",
@@ -65,7 +65,7 @@
65
65
  "build": "nuxt-module-build build",
66
66
  "dev": "nuxi dev playground",
67
67
  "dev:build": "nuxi build playground",
68
- "prep": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
68
+ "prep": "nuxt-module-build prepare && nuxi prepare playground",
69
69
  "format": "dprint check",
70
70
  "format:fix": "dprint fmt",
71
71
  "lint": "eslint .",
@@ -73,14 +73,15 @@
73
73
  "lint:fix": "eslint . --fix",
74
74
  "typecheck": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
75
75
  "package:lint": "publint",
76
+ "verify-packaging": "attw --pack . --profile esm-only",
76
77
  "test": "vitest run",
77
78
  "test:ci": "vitest --run --passWithNoTests --coverage --reporter=default --reporter=junit --outputFile=./coverage/junit.xml",
78
79
  "test:watch": "vitest watch"
79
80
  },
80
81
  "dependencies": {
81
82
  "@opentelemetry/api": "^1.9.0",
82
- "@scayle/h3-session": "0.6.0",
83
- "@scayle/storefront-core": "8.24.1",
83
+ "@scayle/h3-session": "0.6.1",
84
+ "@scayle/storefront-core": "8.25.0",
84
85
  "@scayle/unstorage-compression-driver": "^0.2.6",
85
86
  "@vercel/nft": "0.29.2",
86
87
  "@vueuse/core": "13.1.0",
@@ -99,30 +100,32 @@
99
100
  "schema-dts": "1.1.5"
100
101
  },
101
102
  "devDependencies": {
103
+ "@arethetypeswrong/cli": "0.17.4",
102
104
  "@eslint/eslintrc": "3.3.1",
103
105
  "@nuxt/eslint": "1.3.0",
104
- "@nuxt/kit": "3.15.4",
106
+ "@nuxt/kit": "3.16.2",
105
107
  "@nuxt/module-builder": "1.0.1",
106
- "@nuxt/schema": "3.15.4",
108
+ "@nuxt/schema": "3.16.2",
107
109
  "@nuxt/test-utils": "3.17.2",
108
110
  "@scayle/eslint-config-storefront": "4.5.0",
109
111
  "@scayle/eslint-plugin-vue-composable": "0.2.1",
110
112
  "@scayle/unstorage-scayle-kv-driver": "0.1.1",
111
- "@types/node": "22.14.1",
113
+ "@types/node": "22.15.2",
112
114
  "dprint": "0.49.1",
113
- "eslint-formatter-gitlab": "5.1.0",
114
- "eslint": "9.24.0",
115
+ "eslint-formatter-gitlab": "6.0.0",
116
+ "eslint": "9.25.1",
115
117
  "fishery": "2.2.3",
116
- "h3": "1.15.0",
117
- "nitropack": "2.10.4",
118
+ "h3": "1.15.1",
119
+ "nitropack": "2.11.9",
120
+ "nitro-test-utils": "0.9.2",
118
121
  "node-mocks-http": "1.16.2",
119
- "nuxi": "3.24.1",
120
- "nuxt": "3.15.4",
122
+ "nuxi": "3.25.0",
123
+ "nuxt": "3.16.2",
121
124
  "publint": "0.2.12",
122
125
  "typescript": "5.8.3",
123
- "unbuild": "2.0.0",
124
- "vitest": "3.1.1",
125
- "vue-tsc": "2.2.8"
126
+ "unbuild": "3.5.0",
127
+ "vitest": "3.1.2",
128
+ "vue-tsc": "2.2.10"
126
129
  },
127
130
  "peerDependencies": {
128
131
  "@nuxt/kit": ">=3.12.2",