@vue-storefront/nuxt 0.0.0-20250722194236
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/LICENSE.md +21 -0
- package/README.md +74 -0
- package/dist/module.d.mts +43 -0
- package/dist/module.json +12 -0
- package/dist/module.mjs +160 -0
- package/dist/runtime/defineGetConfigSwitcherHeader.template +1 -0
- package/dist/runtime/defineSdkConfig.template +193 -0
- package/dist/runtime/errorHandler.template +5 -0
- package/dist/runtime/logger.template +37 -0
- package/dist/runtime/plugin.template +16 -0
- package/dist/runtime/serverMiddleware.d.ts +2 -0
- package/dist/runtime/serverMiddleware.js +6 -0
- package/dist/runtime/types.template +49 -0
- package/dist/runtime/useSdk.template +10 -0
- package/dist/runtime/useSfState.template +17 -0
- package/dist/runtime/utils/defaults.d.ts +37 -0
- package/dist/runtime/utils/defaults.js +21 -0
- package/dist/types.d.mts +7 -0
- package/package.json +49 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Vue Storefront
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @vue-storefront/nuxt
|
|
2
|
+
|
|
3
|
+
## Quick Setup
|
|
4
|
+
|
|
5
|
+
1. Add `@vue-storefront/nuxt` dependency to your project
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Using pnpm
|
|
9
|
+
pnpm add -D @vue-storefront/nuxt
|
|
10
|
+
|
|
11
|
+
# Using yarn
|
|
12
|
+
yarn add --dev @vue-storefront/nuxt
|
|
13
|
+
|
|
14
|
+
# Using npm
|
|
15
|
+
npm install --save-dev @vue-storefront/nuxt
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
2. Add `@vue-storefront/nuxt` to the `modules` section of `nuxt.config.ts`
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
export default defineNuxtConfig({
|
|
22
|
+
modules: ["@vue-storefront/nuxt"],
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Configure the module
|
|
27
|
+
|
|
28
|
+
To configure the module, use `vsf` key in the Nuxt configuration object and provide necessary information such as the Middleware instance address:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
export default defineNuxtConfig({
|
|
32
|
+
modules: ["@vue-storefront/nuxt"],
|
|
33
|
+
vsf: {
|
|
34
|
+
middleware: {
|
|
35
|
+
apiUrl: "http://localhost:4000",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
4. Create SDK config file - `sdk.config.ts` in root directory of your project:
|
|
42
|
+
|
|
43
|
+
The `defineSdkConfig` function is used for this purpose. The parameter for calling this function should be an anonymous function that receives an injected context from the module, containing:
|
|
44
|
+
|
|
45
|
+
- the `buildModule` function,
|
|
46
|
+
- the middleware URL (`middlewareUrl`),
|
|
47
|
+
- a function for retrieving the Cookie header with cookie values (`getCookieHeader`).
|
|
48
|
+
|
|
49
|
+
You should import all other SDK configuration components. See the example below illustrating the SDK configuration with Unified and Contentful modules.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import {
|
|
53
|
+
contentfulModule,
|
|
54
|
+
ContentfulModuleType,
|
|
55
|
+
} from "@vsf-enterprise/contentful-sdk";
|
|
56
|
+
import { unifiedModule } from "@vsf-enterprise/unified-sdk";
|
|
57
|
+
import type { UnifiedApiExtension } from "../storefront-middleware/middleware.config";
|
|
58
|
+
|
|
59
|
+
export default defineSdkConfig(
|
|
60
|
+
({ buildModule, middlewareUrl, getCookieHeader }) => ({
|
|
61
|
+
unified: buildModule(unifiedModule<UnifiedApiExtension>, {
|
|
62
|
+
apiUrl: middlewareUrl + "/commerce",
|
|
63
|
+
requestOptions: {
|
|
64
|
+
headers: getCookieHeader,
|
|
65
|
+
},
|
|
66
|
+
}),
|
|
67
|
+
contentful: buildModule<ContentfulModuleType>(contentfulModule, {
|
|
68
|
+
apiUrl: middlewareUrl + "/cntf",
|
|
69
|
+
}),
|
|
70
|
+
}),
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
That's it! You can now use VueStorefront Module in your Nuxt app ✨
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface MiddlewareConfig {
|
|
4
|
+
/**
|
|
5
|
+
* The URL of the middleware.
|
|
6
|
+
* @example "http://localhost:4000"
|
|
7
|
+
*/
|
|
8
|
+
apiUrl: string;
|
|
9
|
+
/**
|
|
10
|
+
* This is identifier used to invalidate the cache on CDN when the assets change.
|
|
11
|
+
* Usually it's a commit hash.
|
|
12
|
+
* @example "2c106d9619c71c3082c9b59b1d72817363c8ecb9"
|
|
13
|
+
* @default "no-cache-busting-id-set"
|
|
14
|
+
*/
|
|
15
|
+
cdnCacheBustingId?: string;
|
|
16
|
+
/**
|
|
17
|
+
* The URL of the middleware for server-side rendering.
|
|
18
|
+
* @example "http://localhost:4000"
|
|
19
|
+
*/
|
|
20
|
+
ssrApiUrl: string;
|
|
21
|
+
}
|
|
22
|
+
interface MultistoreConfig {
|
|
23
|
+
/**
|
|
24
|
+
* Whether the multistore is enabled or not.
|
|
25
|
+
* @example false
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
}
|
|
30
|
+
type LogVerbosity = "alert" | "critical" | "debug" | "emergency" | "error" | "info" | "notice" | "warning";
|
|
31
|
+
type LoggerOptions = Partial<{
|
|
32
|
+
includeStackTrace: boolean;
|
|
33
|
+
verbosity: LogVerbosity;
|
|
34
|
+
}>;
|
|
35
|
+
interface AlokaiModuleOptions {
|
|
36
|
+
logger?: LoggerOptions;
|
|
37
|
+
middleware: MiddlewareConfig;
|
|
38
|
+
multistore?: MultistoreConfig;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare const _default: _nuxt_schema.NuxtModule<AlokaiModuleOptions, AlokaiModuleOptions, false>;
|
|
42
|
+
|
|
43
|
+
export { _default as default };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, installModule, addTypeTemplate, addImports, addTemplate, addPluginTemplate, addImportsSources, addServerHandler } from '@nuxt/kit';
|
|
2
|
+
import { defu } from 'defu';
|
|
3
|
+
import { genInlineTypeImport } from 'knitwork';
|
|
4
|
+
|
|
5
|
+
const RUNTIME_CONFIG = {
|
|
6
|
+
public: {}
|
|
7
|
+
};
|
|
8
|
+
const module = defineNuxtModule({
|
|
9
|
+
defaults: {
|
|
10
|
+
logger: {
|
|
11
|
+
includeStackTrace: false,
|
|
12
|
+
verbosity: "debug"
|
|
13
|
+
},
|
|
14
|
+
middleware: {
|
|
15
|
+
apiUrl: "",
|
|
16
|
+
cdnCacheBustingId: "no-cache-busting-id-set",
|
|
17
|
+
ssrApiUrl: ""
|
|
18
|
+
},
|
|
19
|
+
multistore: {
|
|
20
|
+
enabled: false
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
meta: {
|
|
24
|
+
compatibility: {
|
|
25
|
+
nuxt: "^3.0.0"
|
|
26
|
+
},
|
|
27
|
+
configKey: "alokai",
|
|
28
|
+
name: "@vue-storefront/nuxt"
|
|
29
|
+
},
|
|
30
|
+
async setup(options, nuxt) {
|
|
31
|
+
const projectLayer = nuxt.options._layers[0];
|
|
32
|
+
const projectRootResolver = createResolver(projectLayer.config.rootDir);
|
|
33
|
+
const buildDirectoryResolver = createResolver(nuxt.options.buildDir);
|
|
34
|
+
const localResolver = createResolver(import.meta.url);
|
|
35
|
+
await installModule("@pinia/nuxt");
|
|
36
|
+
nuxt.options.runtimeConfig.public.alokai = defu(
|
|
37
|
+
nuxt.options.runtimeConfig.public?.alokai,
|
|
38
|
+
options
|
|
39
|
+
);
|
|
40
|
+
Object.assign(
|
|
41
|
+
nuxt.options.appConfig,
|
|
42
|
+
defu(nuxt.options.appConfig, {
|
|
43
|
+
alokaiVersion: process.env.NUXT_PUBLIC_ALOKAI_VERSION
|
|
44
|
+
})
|
|
45
|
+
);
|
|
46
|
+
Object.assign(
|
|
47
|
+
nuxt.options.runtimeConfig,
|
|
48
|
+
defu(nuxt.options.runtimeConfig, RUNTIME_CONFIG)
|
|
49
|
+
);
|
|
50
|
+
nuxt.options.app.head.meta = [
|
|
51
|
+
...nuxt.options.app.head.meta ?? [],
|
|
52
|
+
{
|
|
53
|
+
content: "Alokai Storefront",
|
|
54
|
+
name: "generator"
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
nuxt.hooks.hook("nitro:config", async (nitroConfig) => {
|
|
58
|
+
nitroConfig.externals = nitroConfig.externals || {};
|
|
59
|
+
nitroConfig.externals.inline = nitroConfig.externals.inline || [];
|
|
60
|
+
nitroConfig.externals.inline.push(localResolver.resolve("./runtime"));
|
|
61
|
+
});
|
|
62
|
+
addTypeTemplate({
|
|
63
|
+
filename: "sdk.config.d.ts",
|
|
64
|
+
getContents: () => `
|
|
65
|
+
export type SdkConfig = ${genInlineTypeImport(
|
|
66
|
+
projectRootResolver.resolve("sdk.config")
|
|
67
|
+
)}
|
|
68
|
+
`
|
|
69
|
+
});
|
|
70
|
+
addTypeTemplate({
|
|
71
|
+
filename: "alokaiModule.d.ts",
|
|
72
|
+
src: localResolver.resolve("./runtime/types.template")
|
|
73
|
+
});
|
|
74
|
+
addImports({
|
|
75
|
+
as: "getDefaultMethodsRequestConfig",
|
|
76
|
+
from: localResolver.resolve("./runtime/utils/defaults"),
|
|
77
|
+
name: "getDefaultMethodsRequestConfig"
|
|
78
|
+
});
|
|
79
|
+
addTemplate({
|
|
80
|
+
filename: "useSdk.ts",
|
|
81
|
+
src: localResolver.resolve("./runtime/useSdk.template"),
|
|
82
|
+
write: true
|
|
83
|
+
});
|
|
84
|
+
addTemplate({
|
|
85
|
+
filename: "defineSdkConfig.ts",
|
|
86
|
+
options: {
|
|
87
|
+
moduleConfig: JSON.stringify(options)
|
|
88
|
+
},
|
|
89
|
+
src: localResolver.resolve("./runtime/defineSdkConfig.template"),
|
|
90
|
+
write: true
|
|
91
|
+
});
|
|
92
|
+
addTemplate({
|
|
93
|
+
filename: "defineGetConfigSwitcherHeader.ts",
|
|
94
|
+
options: {
|
|
95
|
+
moduleConfig: JSON.stringify(options)
|
|
96
|
+
},
|
|
97
|
+
src: localResolver.resolve(
|
|
98
|
+
"./runtime/defineGetConfigSwitcherHeader.template"
|
|
99
|
+
),
|
|
100
|
+
write: true
|
|
101
|
+
});
|
|
102
|
+
addTemplate({
|
|
103
|
+
filename: "useSfState.ts",
|
|
104
|
+
src: localResolver.resolve("./runtime/useSfState.template"),
|
|
105
|
+
write: true
|
|
106
|
+
});
|
|
107
|
+
addTemplate({
|
|
108
|
+
filename: "logger.ts",
|
|
109
|
+
options: {
|
|
110
|
+
moduleConfig: JSON.stringify(options)
|
|
111
|
+
},
|
|
112
|
+
src: localResolver.resolve("./runtime/logger.template"),
|
|
113
|
+
write: true
|
|
114
|
+
});
|
|
115
|
+
addTemplate({
|
|
116
|
+
filename: "errorHandler.ts",
|
|
117
|
+
src: localResolver.resolve("./runtime/errorHandler.template"),
|
|
118
|
+
write: true
|
|
119
|
+
});
|
|
120
|
+
addPluginTemplate({
|
|
121
|
+
filename: "alokaiPlugin.ts",
|
|
122
|
+
options: {
|
|
123
|
+
moduleConfig: JSON.stringify(options)
|
|
124
|
+
},
|
|
125
|
+
src: localResolver.resolve("./runtime/plugin.template"),
|
|
126
|
+
write: true
|
|
127
|
+
});
|
|
128
|
+
await installModule("@alokai/instrumentation-nuxt3-module");
|
|
129
|
+
addImportsSources([
|
|
130
|
+
{
|
|
131
|
+
from: buildDirectoryResolver.resolve("useSdk.ts"),
|
|
132
|
+
imports: ["useSdk"]
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
from: buildDirectoryResolver.resolve("defineSdkConfig.ts"),
|
|
136
|
+
imports: ["defineSdkConfig", "defineSdkModule"]
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
from: buildDirectoryResolver.resolve(
|
|
140
|
+
"defineGetConfigSwitcherHeader.ts"
|
|
141
|
+
),
|
|
142
|
+
imports: ["defineGetConfigSwitcherHeader"]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
from: buildDirectoryResolver.resolve("useSfState.ts"),
|
|
146
|
+
imports: ["useSfState"]
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
from: buildDirectoryResolver.resolve("logger.ts"),
|
|
150
|
+
imports: ["logger"]
|
|
151
|
+
}
|
|
152
|
+
]);
|
|
153
|
+
addServerHandler({
|
|
154
|
+
handler: localResolver.resolve("./runtime/serverMiddleware"),
|
|
155
|
+
middleware: true
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
export { module as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { defineGetConfigSwitcherHeader } from '@alokai/connect/sdk';
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { Extension, Module } from "@alokai/connect/sdk";
|
|
2
|
+
import { buildModule, middlewareModule } from "@alokai/connect/sdk";
|
|
3
|
+
import { useNuxtApp, useRequestHeaders, getDefaultMethodsRequestConfig } from "#imports";
|
|
4
|
+
import type { Composer } from '#i18n';
|
|
5
|
+
import type { AlokaiModuleOptions } from "./alokaiModule";
|
|
6
|
+
|
|
7
|
+
type InjectedContext = {
|
|
8
|
+
buildModule: typeof buildModule;
|
|
9
|
+
middlewareModule: typeof middlewareModule;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated
|
|
12
|
+
* Use `getRequestHeaders` instead.
|
|
13
|
+
*/
|
|
14
|
+
getCookieHeader: () => Record<string, string>;
|
|
15
|
+
getRequestHeaders: () => Record<string, string>;
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated
|
|
18
|
+
* Use `config.defaults` instead.
|
|
19
|
+
*/
|
|
20
|
+
defaults: ReturnType<typeof getDefaultMethodsRequestConfig>;
|
|
21
|
+
config: {
|
|
22
|
+
apiUrl: string;
|
|
23
|
+
ssrApiUrl: string;
|
|
24
|
+
defaultMethodsRequestConfig: ReturnType<typeof getDefaultMethodsRequestConfig>;
|
|
25
|
+
cdnCacheBustingId: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type Config<TConfig> = (context: InjectedContext) => TConfig;
|
|
30
|
+
|
|
31
|
+
const moduleConfig: AlokaiModuleOptions = <%= options.moduleConfig %>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Define SDK config function
|
|
35
|
+
*
|
|
36
|
+
* @param config - Function that returns SDK config or a record of SDK modules
|
|
37
|
+
*
|
|
38
|
+
* @example Using a function:
|
|
39
|
+
* ```ts
|
|
40
|
+
* import type { UnifiedEndpoints } from 'storefront-middleware/types';
|
|
41
|
+
* import { getConfigSwitcherHeader } from './utils';
|
|
42
|
+
*
|
|
43
|
+
* export default defineSdkConfig(
|
|
44
|
+
* ({ buildModule, middlewareModule, config, getRequestHeaders }) => ({
|
|
45
|
+
* unified: buildModule(middlewareModule<UnifiedEndpoints>, {
|
|
46
|
+
* apiUrl: config.apiUrl + "/commerce/unified",
|
|
47
|
+
* ssrApiUrl: config.ssrApiUrl + "/commerce/unified",
|
|
48
|
+
* cdnCacheBustingId: config.cdnCacheBustingId,
|
|
49
|
+
* defaultRequestConfig: {
|
|
50
|
+
* getConfigSwitcherHeader,
|
|
51
|
+
* headers: getRequestHeaders(),
|
|
52
|
+
* },
|
|
53
|
+
* methodsRequestConfig: config.defaultMethodsRequestConfig.unifiedCommerce.middlewareModule,
|
|
54
|
+
* }),
|
|
55
|
+
* }),
|
|
56
|
+
* );
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Using a record of modules:
|
|
60
|
+
* ```ts
|
|
61
|
+
* import type { UnifiedEndpoints } from 'storefront-middleware/types';
|
|
62
|
+
* import { getConfigSwitcherHeader } from './utils';
|
|
63
|
+
*
|
|
64
|
+
* const unified = defineSdkModule(({ buildModule, config, getRequestHeaders, middlewareModule }) =>
|
|
65
|
+
* buildModule(middlewareModule<UnifiedEndpoints>, {
|
|
66
|
+
* apiUrl: config.apiUrl + "/commerce/unified",
|
|
67
|
+
* ssrApiUrl: config.ssrApiUrl + "/commerce/unified",
|
|
68
|
+
* cdnCacheBustingId: config.cdnCacheBustingId,
|
|
69
|
+
* defaultRequestConfig: {
|
|
70
|
+
* getConfigSwitcherHeader,
|
|
71
|
+
* headers: getRequestHeaders(),
|
|
72
|
+
* },
|
|
73
|
+
* methodsRequestConfig: config.defaultMethodsRequestConfig.unifiedCommerce.middlewareModule,
|
|
74
|
+
* }),
|
|
75
|
+
* );
|
|
76
|
+
*
|
|
77
|
+
* export default defineSdkConfig({
|
|
78
|
+
* unified,
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function defineSdkConfig<TConfig>(config: Config<TConfig>): () => TConfig;
|
|
83
|
+
export function defineSdkConfig<TModules extends Record<string, DefineSdkModule>>(
|
|
84
|
+
modules: TModules,
|
|
85
|
+
): () => {
|
|
86
|
+
[K in keyof TModules]: ReturnType<TModules[K]>;
|
|
87
|
+
};
|
|
88
|
+
export function defineSdkConfig<TConfig>(
|
|
89
|
+
config: Config<TConfig> | Record<string, DefineSdkModule>,
|
|
90
|
+
) {
|
|
91
|
+
return () => {
|
|
92
|
+
const nuxtApp = useNuxtApp()
|
|
93
|
+
const runtimeConfig = useRuntimeConfig();
|
|
94
|
+
|
|
95
|
+
const requestHeaders = useRequestHeaders(["x-forwarded-host", "host"]);
|
|
96
|
+
const resolvedOptions = resolveOptions(runtimeConfig.public.alokai);
|
|
97
|
+
|
|
98
|
+
const getCookieHeader = () => useRequestHeaders(["cookie"]);
|
|
99
|
+
const getRequestHeaders = () => ({
|
|
100
|
+
"x-alokai-locale": (nuxtApp as unknown as { $i18n: Composer }).$i18n?.locale?.value,
|
|
101
|
+
...useRequestHeaders()
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const context = {
|
|
105
|
+
buildModule,
|
|
106
|
+
middlewareModule,
|
|
107
|
+
getCookieHeader,
|
|
108
|
+
getRequestHeaders,
|
|
109
|
+
defaults: getDefaultMethodsRequestConfig(),
|
|
110
|
+
config: {
|
|
111
|
+
apiUrl: resolvedOptions.middleware.apiUrl,
|
|
112
|
+
ssrApiUrl: resolvedOptions.middleware.ssrApiUrl,
|
|
113
|
+
defaultMethodsRequestConfig: getDefaultMethodsRequestConfig(),
|
|
114
|
+
cdnCacheBustingId: runtimeConfig.public.alokai.middleware.cdnCacheBustingId,
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (typeof config === 'function') {
|
|
119
|
+
return config(context);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return buildModules(config)(context);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
type DefineSdkModule = (
|
|
127
|
+
context: InjectedContext,
|
|
128
|
+
) => ReturnType<typeof buildModule>;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Defines an SDK module that can be used with defineSdkConfig.
|
|
132
|
+
* Each module is a function that takes the InjectedContext and returns a built module.
|
|
133
|
+
*
|
|
134
|
+
* @param moduleDefinition - A function that takes InjectedContext and returns a built module
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* import type { UnifiedEndpoints } from 'storefront-middleware/types';
|
|
139
|
+
* import { getConfigSwitcherHeader } from './utils';
|
|
140
|
+
*
|
|
141
|
+
* export const unified = defineSdkModule(({ buildModule, config, getRequestHeaders, middlewareModule }) =>
|
|
142
|
+
* buildModule(middlewareModule<UnifiedEndpoints>, {
|
|
143
|
+
* apiUrl: config.apiUrl + "/commerce/unified",
|
|
144
|
+
* ssrApiUrl: config.ssrApiUrl + "/commerce/unified",
|
|
145
|
+
* cdnCacheBustingId: config.cdnCacheBustingId,
|
|
146
|
+
* defaultRequestConfig: {
|
|
147
|
+
* getConfigSwitcherHeader,
|
|
148
|
+
* headers: getRequestHeaders(),
|
|
149
|
+
* },
|
|
150
|
+
* methodsRequestConfig: config.defaultMethodsRequestConfig.unifiedCommerce.middlewareModule,
|
|
151
|
+
* }),
|
|
152
|
+
* );
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export function defineSdkModule<TModuleDefinition extends DefineSdkModule>(
|
|
156
|
+
moduleDefinition: TModuleDefinition,
|
|
157
|
+
) {
|
|
158
|
+
return moduleDefinition;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function buildModules<TModules extends Record<string, DefineSdkModule>>(
|
|
162
|
+
modules: TModules,
|
|
163
|
+
) {
|
|
164
|
+
return (context: InjectedContext) =>
|
|
165
|
+
Object.fromEntries(
|
|
166
|
+
Object.entries(modules).map(([key, module]) => [key, module(context)]),
|
|
167
|
+
) as {
|
|
168
|
+
[K in keyof TModules]: ReturnType<TModules[K]>;
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Helper function to resolve the SDK options based on the configuration.
|
|
174
|
+
*
|
|
175
|
+
* @privateRemarks
|
|
176
|
+
* For now this file only verifies the type of the input and simply returns it.
|
|
177
|
+
* However, in the future we might need it to perform true input resolution.
|
|
178
|
+
*
|
|
179
|
+
* @param input - The options for creating the SDK.
|
|
180
|
+
* @param options - The configuration object, that allows to customize the API Url creation on enabled multistore.
|
|
181
|
+
*
|
|
182
|
+
* @returns The resolved SDK options.
|
|
183
|
+
*/
|
|
184
|
+
function resolveOptions(
|
|
185
|
+
input: Omit<AlokaiModuleOptions, 'logger'>,
|
|
186
|
+
_options: Partial<ResolveSdkOptionsConfig> = {}
|
|
187
|
+
): AlokaiModuleOptions {
|
|
188
|
+
return input;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
type ResolveSdkOptionsConfig = {
|
|
192
|
+
customSuffix: string;
|
|
193
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { LoggerFactory, LoggerType, type LoggerInterface } from "@alokai/connect/logger";
|
|
2
|
+
import type { AlokaiModuleOptions, LoggerOptions } from "./alokaiModule";
|
|
3
|
+
|
|
4
|
+
function injectMetadata(
|
|
5
|
+
logger: LoggerInterface,
|
|
6
|
+
externalData: Record<string, any>,
|
|
7
|
+
): LoggerInterface {
|
|
8
|
+
return new Proxy(logger, {
|
|
9
|
+
get(target, prop) {
|
|
10
|
+
const targetProp = target[prop as keyof LoggerInterface];
|
|
11
|
+
if (typeof targetProp === "function") {
|
|
12
|
+
return (...args: Parameters<typeof targetProp>[]) => {
|
|
13
|
+
const [logData, metadata] = args;
|
|
14
|
+
targetProp(logData, {
|
|
15
|
+
...metadata,
|
|
16
|
+
...externalData,
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return targetProp;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const moduleConfig: AlokaiModuleOptions = <%= options.moduleConfig %>;
|
|
26
|
+
|
|
27
|
+
const createLogger = (options?: LoggerOptions) => {
|
|
28
|
+
const logger = LoggerFactory.create(LoggerType.ConsolaGcp, options);
|
|
29
|
+
|
|
30
|
+
return injectMetadata(logger, {
|
|
31
|
+
alokai: {
|
|
32
|
+
context: "storefront",
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const logger = createLogger(moduleConfig.logger);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { initSDK, type SDKApi } from "@alokai/connect/sdk";
|
|
2
|
+
import sdkConfig from "~/sdk.config";
|
|
3
|
+
import type { SdkConfig } from "./sdk.config";
|
|
4
|
+
import { defineNuxtPlugin } from '#app';
|
|
5
|
+
|
|
6
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
7
|
+
const getSdk: () => SDKApi<ReturnType<SdkConfig>> = () => {
|
|
8
|
+
return initSDK(sdkConfig());
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
provide: {
|
|
13
|
+
alokai: { getSdk },
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export interface MiddlewareConfig {
|
|
2
|
+
/**
|
|
3
|
+
* The URL of the middleware.
|
|
4
|
+
* @example "http://localhost:4000"
|
|
5
|
+
*/
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
/**
|
|
8
|
+
* The URL of the middleware for server-side rendering.
|
|
9
|
+
* @example "http://localhost:4000"
|
|
10
|
+
*/
|
|
11
|
+
ssrApiUrl: string;
|
|
12
|
+
/**
|
|
13
|
+
* This is identifier used to invalidate the cache on CDN when the assets change.
|
|
14
|
+
* Usually it's a commit hash.
|
|
15
|
+
* @example "2c106d9619c71c3082c9b59b1d72817363c8ecb9"
|
|
16
|
+
* @default "no-cache-busting-id-set"
|
|
17
|
+
*/
|
|
18
|
+
cdnCacheBustingId?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface MultistoreConfig {
|
|
22
|
+
/**
|
|
23
|
+
* Whether the multistore is enabled or not.
|
|
24
|
+
* @example false
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type LogVerbosity =
|
|
31
|
+
| "emergency"
|
|
32
|
+
| "alert"
|
|
33
|
+
| "critical"
|
|
34
|
+
| "error"
|
|
35
|
+
| "warning"
|
|
36
|
+
| "notice"
|
|
37
|
+
| "info"
|
|
38
|
+
| "debug";
|
|
39
|
+
|
|
40
|
+
export type LoggerOptions = Partial<{
|
|
41
|
+
verbosity: LogVerbosity;
|
|
42
|
+
includeStackTrace: boolean;
|
|
43
|
+
}>;
|
|
44
|
+
|
|
45
|
+
export interface AlokaiModuleOptions {
|
|
46
|
+
middleware: MiddlewareConfig;
|
|
47
|
+
multistore?: MultistoreConfig;
|
|
48
|
+
logger?: LoggerOptions;
|
|
49
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SdkConfig } from "./sdk.config";
|
|
2
|
+
import type { SDKApi } from '@alokai/connect/sdk';
|
|
3
|
+
import { useNuxtApp } from "#imports";
|
|
4
|
+
|
|
5
|
+
export const useSdk = () => {
|
|
6
|
+
const nuxtApp = useNuxtApp();
|
|
7
|
+
const { getSdk } = nuxtApp.$alokai as { getSdk: ()=> SDKApi<ReturnType<SdkConfig>> };
|
|
8
|
+
|
|
9
|
+
return getSdk();
|
|
10
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
SfCart,
|
|
3
|
+
SfCurrency,
|
|
4
|
+
SfCustomer,
|
|
5
|
+
SfLocale,
|
|
6
|
+
} from "~/types";
|
|
7
|
+
|
|
8
|
+
export const useSfState = defineStore("SfState", () => {
|
|
9
|
+
const cart = ref<SfCart | null>(null);
|
|
10
|
+
const customer = ref<SfCustomer | null>(null);
|
|
11
|
+
const currencies = ref<SfCurrency[]>([]);
|
|
12
|
+
const currency = ref<SfCurrency>();
|
|
13
|
+
const locale = ref<SfLocale>();
|
|
14
|
+
const locales = ref<SfLocale[]>([]);
|
|
15
|
+
|
|
16
|
+
return { customer, cart, currencies, currency, locales, locale };
|
|
17
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare function getDefaultMethodsRequestConfig(): {
|
|
2
|
+
readonly unifiedCms: {
|
|
3
|
+
readonly middlewareModule: {
|
|
4
|
+
readonly getEntries: {
|
|
5
|
+
readonly method: "GET";
|
|
6
|
+
};
|
|
7
|
+
readonly getPage: {
|
|
8
|
+
readonly method: "GET";
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
readonly unifiedCommerce: {
|
|
13
|
+
readonly middlewareModule: {
|
|
14
|
+
readonly getCategories: {
|
|
15
|
+
readonly method: "GET";
|
|
16
|
+
};
|
|
17
|
+
readonly getCategory: {
|
|
18
|
+
readonly method: "GET";
|
|
19
|
+
};
|
|
20
|
+
readonly getCurrencies: {
|
|
21
|
+
readonly method: "GET";
|
|
22
|
+
};
|
|
23
|
+
readonly getProductDetails: {
|
|
24
|
+
readonly method: "GET";
|
|
25
|
+
};
|
|
26
|
+
readonly getProductReviews: {
|
|
27
|
+
readonly method: "GET";
|
|
28
|
+
};
|
|
29
|
+
readonly getProducts: {
|
|
30
|
+
readonly method: "GET";
|
|
31
|
+
};
|
|
32
|
+
readonly searchProducts: {
|
|
33
|
+
readonly method: "GET";
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function getDefaultMethodsRequestConfig() {
|
|
2
|
+
return {
|
|
3
|
+
unifiedCms: {
|
|
4
|
+
middlewareModule: {
|
|
5
|
+
getEntries: { method: "GET" },
|
|
6
|
+
getPage: { method: "GET" }
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
unifiedCommerce: {
|
|
10
|
+
middlewareModule: {
|
|
11
|
+
getCategories: { method: "GET" },
|
|
12
|
+
getCategory: { method: "GET" },
|
|
13
|
+
getCurrencies: { method: "GET" },
|
|
14
|
+
getProductDetails: { method: "GET" },
|
|
15
|
+
getProductReviews: { method: "GET" },
|
|
16
|
+
getProducts: { method: "GET" },
|
|
17
|
+
searchProducts: { method: "GET" }
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
package/dist/types.d.mts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vue-storefront/nuxt",
|
|
3
|
+
"version": "0.0.0-20250722194236",
|
|
4
|
+
"description": "Alokai dedicated features for Nuxt",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/types.d.mts",
|
|
10
|
+
"import": "./dist/module.mjs"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"types": "./dist/types.d.mts",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "yarn prepare && nuxt-module-build build",
|
|
19
|
+
"lint": "yarn prepare && eslint",
|
|
20
|
+
"lint:fix": "yarn prepare && eslint --fix",
|
|
21
|
+
"format": "prettier --write .",
|
|
22
|
+
"prepare": "nuxi prepare",
|
|
23
|
+
"version": "cp CHANGELOG.md ../../docs/enterprise/content/storefront/6.change-log/nuxt.md"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@alokai/instrumentation-nuxt3-module": "0.0.0-20250722194236",
|
|
27
|
+
"@nuxt/kit": "^3.7.4",
|
|
28
|
+
"@nuxt/schema": "^3.7.4",
|
|
29
|
+
"@pinia/nuxt": "^0.5.1",
|
|
30
|
+
"defu": "^6.0.0",
|
|
31
|
+
"knitwork": "^1.0.0",
|
|
32
|
+
"pinia": "^2.1.7"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@alokai/connect": "0.0.0-20250722194236",
|
|
36
|
+
"@nuxt/devtools": "1.7.0",
|
|
37
|
+
"@nuxt/module-builder": "1.0.1",
|
|
38
|
+
"@types/node": "^22.0.0",
|
|
39
|
+
"eslint": "9.23.0",
|
|
40
|
+
"nuxt": "3.13.2",
|
|
41
|
+
"prettier": "3.3.2"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@alokai/connect": "0.0.0-20250722194236"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
}
|
|
49
|
+
}
|