@scayle/storefront-nuxt 8.6.1 → 8.7.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.
- package/CHANGELOG.md +57 -0
- package/dist/module.d.mts +21 -1
- package/dist/module.d.ts +21 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +189 -115
- package/dist/runtime/api/purgeAll.js +10 -0
- package/dist/runtime/api/purgeTags.js +10 -0
- package/dist/runtime/api/rpcHandler.d.ts +50 -1
- package/dist/runtime/api/rpcHandler.js +13 -7
- package/dist/runtime/composables/storefront/useStorefrontSearch.d.ts +1 -1
- package/dist/runtime/handler.js +1 -1
- package/dist/runtime/plugin/shop.js +6 -2
- package/dist/runtime/server/middleware/bootstrap.d.ts +1 -10
- package/dist/runtime/server/middleware/redirects.js +3 -0
- package/dist/types.d.mts +2 -1
- package/dist/types.d.ts +2 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# @scayle/storefront-nuxt
|
|
2
2
|
|
|
3
|
+
## 8.7.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
**Dependencies**
|
|
8
|
+
|
|
9
|
+
- Updated dependency to @scayle/storefront-core@8.3.2
|
|
10
|
+
|
|
11
|
+
## 8.7.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- Introduce a flexible interface for registering custom RPC methods from other modules
|
|
16
|
+
|
|
17
|
+
Currently, applications can configure `rpcDir` and `rpcMethodNames` in the module configuration to register custom RPC methods, however this does not extend to modules.
|
|
18
|
+
This release adds a new module hook `storefront:custom-rpc:extend` which can be used to register custom RPC methods.
|
|
19
|
+
By registering a callback to this hook, other modules can add custom RPC methods to the application.
|
|
20
|
+
|
|
21
|
+
The hook functions similarly to `rpcDir` and `rpcMethodNames`. Hook registrants receive an array of custom RPC imports and can add their own. The import definition should include a `source` which defines the file to import the RPC methods from and a `names` array which controls the exports of this file which should be registered as RPC methods.
|
|
22
|
+
|
|
23
|
+
**rpc-methods.ts**
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import type { RpcContext, RpcHandler } from '@scayle/storefront-nuxt'
|
|
27
|
+
|
|
28
|
+
export const foo: RpcHandler<string, number> = function testing(
|
|
29
|
+
param: string,
|
|
30
|
+
_: RpcContext,
|
|
31
|
+
) {
|
|
32
|
+
return param.length
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**module.ts**
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
function setup() {
|
|
40
|
+
const resolver = createResolver(import.meta.url)
|
|
41
|
+
|
|
42
|
+
nuxt.hook('storefront:custom-rpc:extend', (customRpcImports) => {
|
|
43
|
+
customRpcImports.push({
|
|
44
|
+
source: resolver.resolve('./rpc-methods.ts'),
|
|
45
|
+
names: ['foo'],
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
As part of this change, the `RPCMethod` types are automatically extended with all custom RPC methods.
|
|
52
|
+
It is no longer necessary to extend `RpcMethodsStorefront`.
|
|
53
|
+
This applies both for the `rpcDir` + `rpcMethodNames` strategy as well as the new hook-based implementation.
|
|
54
|
+
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- [RPC] Improve warning about missing RPC method overrides
|
|
58
|
+
- Improve error handling when bootstrapping fails due to a missing shop.
|
|
59
|
+
|
|
3
60
|
## 8.6.1
|
|
4
61
|
|
|
5
62
|
### Patch Changes
|
package/dist/module.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
import { HookResult } from '@nuxt/schema';
|
|
2
3
|
import { M as ModuleBaseOptions } from './shared/storefront-nuxt.a816664e.mjs';
|
|
3
4
|
export { d as AdditionalShopConfig, A as AppKeys, h as CheckoutEvent, C as CheckoutShopConfig, i 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 } from './shared/storefront-nuxt.a816664e.mjs';
|
|
4
5
|
export { LogLevel } from '@scayle/storefront-core';
|
|
@@ -6,6 +7,25 @@ import '@scayle/unstorage-compression-driver';
|
|
|
6
7
|
import 'unstorage';
|
|
7
8
|
import '../dist/runtime/utils/zodSchema.js';
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Definition of a custom RPC import
|
|
12
|
+
*/
|
|
13
|
+
interface CustomRpcImport {
|
|
14
|
+
/** The location from which to import the RPC method(s) */
|
|
15
|
+
source: string;
|
|
16
|
+
/** The specifiers to import as RPC methods */
|
|
17
|
+
names: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build-time hooks used by the module
|
|
21
|
+
*/
|
|
22
|
+
interface ModuleHooks {
|
|
23
|
+
'storefront:custom-rpc:extend': (customRpcImports: CustomRpcImport[]) => HookResult;
|
|
24
|
+
}
|
|
25
|
+
declare module '@nuxt/schema' {
|
|
26
|
+
interface NuxtHooks extends ModuleHooks {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
9
29
|
declare const _default: _nuxt_schema.NuxtModule<ModuleBaseOptions, ModuleBaseOptions, false>;
|
|
10
30
|
|
|
11
|
-
export { ModuleBaseOptions, _default as default };
|
|
31
|
+
export { ModuleBaseOptions, type ModuleHooks, _default as default };
|
package/dist/module.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
import { HookResult } from '@nuxt/schema';
|
|
2
3
|
import { M as ModuleBaseOptions } from './shared/storefront-nuxt.a816664e.js';
|
|
3
4
|
export { d as AdditionalShopConfig, A as AppKeys, h as CheckoutEvent, C as CheckoutShopConfig, i 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 } from './shared/storefront-nuxt.a816664e.js';
|
|
4
5
|
export { LogLevel } from '@scayle/storefront-core';
|
|
@@ -6,6 +7,25 @@ import '@scayle/unstorage-compression-driver';
|
|
|
6
7
|
import 'unstorage';
|
|
7
8
|
import '../dist/runtime/utils/zodSchema.js';
|
|
8
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Definition of a custom RPC import
|
|
12
|
+
*/
|
|
13
|
+
interface CustomRpcImport {
|
|
14
|
+
/** The location from which to import the RPC method(s) */
|
|
15
|
+
source: string;
|
|
16
|
+
/** The specifiers to import as RPC methods */
|
|
17
|
+
names: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build-time hooks used by the module
|
|
21
|
+
*/
|
|
22
|
+
interface ModuleHooks {
|
|
23
|
+
'storefront:custom-rpc:extend': (customRpcImports: CustomRpcImport[]) => HookResult;
|
|
24
|
+
}
|
|
25
|
+
declare module '@nuxt/schema' {
|
|
26
|
+
interface NuxtHooks extends ModuleHooks {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
9
29
|
declare const _default: _nuxt_schema.NuxtModule<ModuleBaseOptions, ModuleBaseOptions, false>;
|
|
10
30
|
|
|
11
|
-
export { ModuleBaseOptions, _default as default };
|
|
31
|
+
export { ModuleBaseOptions, type ModuleHooks, _default as default };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, extendViteConfig,
|
|
1
|
+
import { defineNuxtModule, createResolver, extendViteConfig, addTypeTemplate, addPlugin, addImportsDir } from '@nuxt/kit';
|
|
2
2
|
import { rpcMethods } from '@scayle/storefront-core';
|
|
3
3
|
import { defu } from 'defu';
|
|
4
|
-
import { genImport, genSafeVariableName } from 'knitwork';
|
|
4
|
+
import { genImport, genSafeVariableName, genExport } from 'knitwork';
|
|
5
5
|
import { builtinDrivers } from 'unstorage';
|
|
6
6
|
import { createConsola } from 'consola';
|
|
7
7
|
import { getApiBasePath } from '../dist/runtime/server/middleware/bootstrap-utils.js';
|
|
@@ -27,8 +27,7 @@ function getUsedDrivers(options) {
|
|
|
27
27
|
});
|
|
28
28
|
return Array.from(drivers);
|
|
29
29
|
}
|
|
30
|
-
function createVirtualDriverImport(
|
|
31
|
-
const usedDrivers = getUsedDrivers(options);
|
|
30
|
+
function createVirtualDriverImport(usedDrivers) {
|
|
32
31
|
const usesCompression = !stringToBoolean(
|
|
33
32
|
process.env.SFC_OMIT_COMPRESSION,
|
|
34
33
|
false
|
|
@@ -45,7 +44,7 @@ export default {
|
|
|
45
44
|
}`;
|
|
46
45
|
}
|
|
47
46
|
const PACKAGE_NAME = "@scayle/storefront-nuxt";
|
|
48
|
-
const PACKAGE_VERSION = "8.
|
|
47
|
+
const PACKAGE_VERSION = "8.7.1";
|
|
49
48
|
const logger = createConsola({
|
|
50
49
|
fancy: true,
|
|
51
50
|
formatOptions: {
|
|
@@ -59,6 +58,150 @@ const logger = createConsola({
|
|
|
59
58
|
// However when typechecking it will resolve to consola/browser which does have the fancy option
|
|
60
59
|
// This assertion avoids the typescript error
|
|
61
60
|
});
|
|
61
|
+
function createRpcMethodIndex(customRpcImports) {
|
|
62
|
+
return customRpcImports.map(({ source, names }) => genExport(source, names)).join(
|
|
63
|
+
"\n"
|
|
64
|
+
) + `
|
|
65
|
+
export {}`;
|
|
66
|
+
}
|
|
67
|
+
function createRpcMethodTypeDeclaration(customRpcImports) {
|
|
68
|
+
return `// Auto-generated
|
|
69
|
+
type RpcMethodsCustomType = {
|
|
70
|
+
${customRpcImports.reduce(
|
|
71
|
+
(lines, { source, names }) => lines.concat(
|
|
72
|
+
names.map((name) => `${name}: typeof import('${source}')['${name}'],`).join("\n")
|
|
73
|
+
),
|
|
74
|
+
[]
|
|
75
|
+
).join("\n")}
|
|
76
|
+
}
|
|
77
|
+
declare module '@scayle/storefront-nuxt' {
|
|
78
|
+
export interface RpcMethodsStorefront extends RpcMethodsCustomType {}
|
|
79
|
+
}
|
|
80
|
+
export {}`;
|
|
81
|
+
}
|
|
82
|
+
function nitroSetup(nitroConfig, config) {
|
|
83
|
+
const { resolve } = createResolver(import.meta.url);
|
|
84
|
+
const { apiBasePath, customRpcImports, coreMethodNames, usedDrivers } = config;
|
|
85
|
+
nitroConfig.externals = nitroConfig.externals || {};
|
|
86
|
+
nitroConfig.externals.inline = nitroConfig.externals.inline || [];
|
|
87
|
+
const runtimePaths = [
|
|
88
|
+
"handler",
|
|
89
|
+
"error/handler",
|
|
90
|
+
"campaignKey",
|
|
91
|
+
"cached",
|
|
92
|
+
"context",
|
|
93
|
+
"createLog",
|
|
94
|
+
"log",
|
|
95
|
+
"api/cacheAuth",
|
|
96
|
+
"rpc/rpcCall",
|
|
97
|
+
"rpc/rpcRequest",
|
|
98
|
+
"server/middleware/oauth",
|
|
99
|
+
"server/middleware/redirects",
|
|
100
|
+
"server/middleware/cache",
|
|
101
|
+
"server/utils/cacheStorage",
|
|
102
|
+
"utils/zodSchema",
|
|
103
|
+
"nitro/plugins/cacheRuntimeConfig",
|
|
104
|
+
"nitro/plugins/nitroLogger",
|
|
105
|
+
"nitro/plugins/nitroRuntimeStorageConfig",
|
|
106
|
+
"nitro/plugins/nitroSetXPoweredByHeader",
|
|
107
|
+
"nitro/plugins/configValidation"
|
|
108
|
+
];
|
|
109
|
+
runtimePaths.forEach((path) => {
|
|
110
|
+
const file = resolve(`./runtime/${path}`);
|
|
111
|
+
nitroConfig.externals?.inline?.push(file);
|
|
112
|
+
});
|
|
113
|
+
nitroConfig.replace = nitroConfig.replace || {};
|
|
114
|
+
nitroConfig.replace["process.env.SFC_OMIT_MD5"] = stringToBoolean(
|
|
115
|
+
process.env.SFC_OMIT_MD5
|
|
116
|
+
);
|
|
117
|
+
nitroConfig.replace.__sfc_version = PACKAGE_VERSION;
|
|
118
|
+
nitroConfig.virtual = {
|
|
119
|
+
...nitroConfig.virtual,
|
|
120
|
+
"#virtual/storage-drivers": createVirtualDriverImport(
|
|
121
|
+
usedDrivers
|
|
122
|
+
),
|
|
123
|
+
"#virtual/customRpcMethods": createRpcMethodIndex(
|
|
124
|
+
customRpcImports
|
|
125
|
+
)
|
|
126
|
+
};
|
|
127
|
+
nitroConfig.handlers = nitroConfig.handlers ?? [];
|
|
128
|
+
nitroConfig.handlers.unshift({
|
|
129
|
+
middleware: true,
|
|
130
|
+
handler: resolve("./runtime/server/middleware/bootstrap")
|
|
131
|
+
});
|
|
132
|
+
const allRpcNames = customRpcImports.reduce(
|
|
133
|
+
(acc, { names }) => acc.concat(names),
|
|
134
|
+
[]
|
|
135
|
+
).concat(coreMethodNames);
|
|
136
|
+
for (const methodName of allRpcNames) {
|
|
137
|
+
nitroConfig.handlers.push({
|
|
138
|
+
route: `${apiBasePath}/rpc/${methodName}`,
|
|
139
|
+
handler: resolve("./runtime/api/rpcHandler"),
|
|
140
|
+
method: "post"
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
nitroConfig.handlers.push({
|
|
144
|
+
route: `${apiBasePath}/purge/all`,
|
|
145
|
+
handler: resolve("./runtime/api/purgeAll"),
|
|
146
|
+
method: "post"
|
|
147
|
+
});
|
|
148
|
+
nitroConfig.handlers.push({
|
|
149
|
+
route: `${apiBasePath}/purge/tags`,
|
|
150
|
+
handler: resolve("./runtime/api/purgeTags"),
|
|
151
|
+
method: "post"
|
|
152
|
+
});
|
|
153
|
+
nitroConfig.handlers.push({
|
|
154
|
+
route: `${apiBasePath}/up`,
|
|
155
|
+
handler: resolve("./runtime/api/up")
|
|
156
|
+
});
|
|
157
|
+
nitroConfig.plugins = nitroConfig.plugins ?? [];
|
|
158
|
+
nitroConfig.plugins.push(resolve("./runtime/nitro/plugins/nitroLogger"));
|
|
159
|
+
nitroConfig.plugins.push(
|
|
160
|
+
resolve("./runtime/nitro/plugins/nitroRuntimeStorageConfig")
|
|
161
|
+
);
|
|
162
|
+
if (stringToBoolean(process.env.SFC_PLUGIN_CONFIG_VALIDATION_ENABLED, true)) {
|
|
163
|
+
logger.debug("Installing config validation plugin");
|
|
164
|
+
nitroConfig.plugins.push(
|
|
165
|
+
resolve("./runtime/nitro/plugins/configValidation")
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
if (stringToBoolean(process.env.SFC_PLUGIN_POWERED_BY_ENABLED, true)) {
|
|
169
|
+
logger.debug("Installing X-Powered-By plugin");
|
|
170
|
+
nitroConfig.plugins.push(
|
|
171
|
+
resolve("./runtime/nitro/plugins/nitroSetXPoweredByHeader")
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (stringToBoolean(process.env.SFC_PLUGIN_RUNTIME_PERFORMANCE_ENABLED, true)) {
|
|
175
|
+
logger.debug("Installing runtime performance plugin");
|
|
176
|
+
nitroConfig.plugins.push(
|
|
177
|
+
resolve("./runtime/nitro/plugins/cacheRuntimeConfig")
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function validateRpcMethodOverrides(rpcMethodOverrides, customRpcNames, coreRpcNames) {
|
|
182
|
+
const overridenRPCMethodNames = new Set(rpcMethodOverrides);
|
|
183
|
+
for (const rpcMethodName of customRpcNames) {
|
|
184
|
+
if (coreRpcNames.has(rpcMethodName) && !overridenRPCMethodNames.has(rpcMethodName)) {
|
|
185
|
+
logger.warn(`
|
|
186
|
+
Overriding RPC method '${rpcMethodName}' from '@scayle/storefront-nuxt' with a local custom implementation.
|
|
187
|
+
|
|
188
|
+
Should this be done on purpose, please be aware that this can lead to unexpected issues since the '@scayle/storefront-nuxt' package also uses this RPC method internally.
|
|
189
|
+
To silence this warning, you can add '${rpcMethodName}' to 'rpcMethodOverrides' in the '@scayle/storefront-nuxt' config.
|
|
190
|
+
|
|
191
|
+
In the future this will become an error where overrides need to be explicitly defined as an override.
|
|
192
|
+
`);
|
|
193
|
+
} else {
|
|
194
|
+
overridenRPCMethodNames.delete(rpcMethodName);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (overridenRPCMethodNames.size > 0) {
|
|
198
|
+
logger.warn(`
|
|
199
|
+
Detected RPC methods which were supposed to be overridden but are not. This indicates an incorrect configuration and should be adjusted. Check the 'rpcMethodOverrides' property.
|
|
200
|
+
|
|
201
|
+
Missing RPC Method Overrides: ${Array.from(overridenRPCMethodNames).map((name) => `'${name}'`).join(", ")}
|
|
202
|
+
`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
62
205
|
const module = defineNuxtModule({
|
|
63
206
|
meta: {
|
|
64
207
|
name: PACKAGE_NAME,
|
|
@@ -102,7 +245,7 @@ const module = defineNuxtModule({
|
|
|
102
245
|
},
|
|
103
246
|
internalAccessHeader: ""
|
|
104
247
|
},
|
|
105
|
-
setup(options, nuxt) {
|
|
248
|
+
async setup(options, nuxt) {
|
|
106
249
|
const { resolve } = createResolver(import.meta.url);
|
|
107
250
|
const { resolve: appResolve } = createResolver(nuxt.options.srcDir);
|
|
108
251
|
nuxt.options.runtimeConfig.storefront = defu(
|
|
@@ -125,55 +268,40 @@ const module = defineNuxtModule({
|
|
|
125
268
|
"slugify"
|
|
126
269
|
);
|
|
127
270
|
});
|
|
128
|
-
nuxt.options.serverHandlers.unshift({
|
|
129
|
-
middleware: true,
|
|
130
|
-
handler: resolve("./runtime/server/middleware/bootstrap")
|
|
131
|
-
});
|
|
132
271
|
const apiBasePath = getApiBasePath(options, "/");
|
|
133
272
|
const rpcMethodNames = new Set(Object.keys(rpcMethods));
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
273
|
+
const storefrontRpcMethodNames = options.rpcMethodNames ?? [];
|
|
274
|
+
const customRpcImports = [];
|
|
275
|
+
nuxt.hook("modules:done", async () => {
|
|
276
|
+
await nuxt.callHook("storefront:custom-rpc:extend", customRpcImports);
|
|
277
|
+
customRpcImports.forEach((customImport) => {
|
|
278
|
+
customImport.names.forEach((name) => {
|
|
279
|
+
if (rpcMethodNames.has(name)) {
|
|
280
|
+
throw new Error(
|
|
281
|
+
`Core RPC method '${name}' cannot be overriden via the 'storefront:custom-rpc:extend' hook`
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
customImport.names = customImport.names.filter(
|
|
286
|
+
(name) => !storefrontRpcMethodNames.includes(name)
|
|
287
|
+
);
|
|
288
|
+
});
|
|
289
|
+
customRpcImports.push({
|
|
290
|
+
source: appResolve(options.rpcDir ?? "./rpcMethods"),
|
|
291
|
+
names: storefrontRpcMethodNames
|
|
292
|
+
});
|
|
293
|
+
validateRpcMethodOverrides(
|
|
294
|
+
options.rpcMethodOverrides ?? [],
|
|
295
|
+
customRpcImports.reduce(
|
|
296
|
+
(acc, { names }) => acc.concat(names),
|
|
297
|
+
[]
|
|
298
|
+
),
|
|
299
|
+
rpcMethodNames
|
|
300
|
+
);
|
|
301
|
+
addTypeTemplate({
|
|
302
|
+
filename: "types/storefront-custom-rpc.d.ts",
|
|
303
|
+
getContents: () => createRpcMethodTypeDeclaration(customRpcImports)
|
|
162
304
|
});
|
|
163
|
-
});
|
|
164
|
-
addServerHandler({
|
|
165
|
-
route: `${apiBasePath}/purge/all`,
|
|
166
|
-
handler: resolve("./runtime/api/purgeAll"),
|
|
167
|
-
method: "post"
|
|
168
|
-
});
|
|
169
|
-
addServerHandler({
|
|
170
|
-
route: `${apiBasePath}/purge/tags`,
|
|
171
|
-
handler: resolve("./runtime/api/purgeTags"),
|
|
172
|
-
method: "post"
|
|
173
|
-
});
|
|
174
|
-
addServerHandler({
|
|
175
|
-
route: `${apiBasePath}/up`,
|
|
176
|
-
handler: resolve("./runtime/api/up")
|
|
177
305
|
});
|
|
178
306
|
addTypeTemplate({
|
|
179
307
|
filename: "types/storefront-bootstrap.d.ts",
|
|
@@ -183,10 +311,10 @@ Missing RPC Overrides: ${Array.from(overridenRPCMethodNames).map((name) => `'${n
|
|
|
183
311
|
import type { PublicShopConfig } from '@scayle/storefront-nuxt';
|
|
184
312
|
declare module 'h3' {
|
|
185
313
|
interface H3EventContext {
|
|
186
|
-
$rpcContext
|
|
187
|
-
$cache
|
|
188
|
-
$currentShop
|
|
189
|
-
$availableShops
|
|
314
|
+
$rpcContext?: RpcContext,
|
|
315
|
+
$cache?: Cache
|
|
316
|
+
$currentShop?: PublicShopConfig,
|
|
317
|
+
$availableShops?: PublicShopConfig[]
|
|
190
318
|
$log: Log
|
|
191
319
|
}
|
|
192
320
|
}
|
|
@@ -195,64 +323,13 @@ Missing RPC Overrides: ${Array.from(overridenRPCMethodNames).map((name) => `'${n
|
|
|
195
323
|
}
|
|
196
324
|
export {}`
|
|
197
325
|
});
|
|
198
|
-
addServerPlugin(resolve("./runtime/nitro/plugins/nitroLogger"));
|
|
199
|
-
addServerPlugin(
|
|
200
|
-
resolve("./runtime/nitro/plugins/nitroRuntimeStorageConfig")
|
|
201
|
-
);
|
|
202
|
-
if (stringToBoolean(process.env.SFC_PLUGIN_CONFIG_VALIDATION_ENABLED, true)) {
|
|
203
|
-
logger.debug("Installing config validation plugin");
|
|
204
|
-
addServerPlugin(resolve("./runtime/nitro/plugins/configValidation"));
|
|
205
|
-
}
|
|
206
|
-
if (stringToBoolean(process.env.SFC_PLUGIN_POWERED_BY_ENABLED, true)) {
|
|
207
|
-
logger.debug("Installing X-Powered-By plugin");
|
|
208
|
-
addServerPlugin(
|
|
209
|
-
resolve("./runtime/nitro/plugins/nitroSetXPoweredByHeader")
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
if (stringToBoolean(process.env.SFC_PLUGIN_RUNTIME_PERFORMANCE_ENABLED, true)) {
|
|
213
|
-
logger.debug("Installing runtime performance plugin");
|
|
214
|
-
addServerPlugin(resolve("./runtime/nitro/plugins/cacheRuntimeConfig"));
|
|
215
|
-
}
|
|
216
326
|
nuxt.hooks.hook("nitro:config", (nitroConfig) => {
|
|
217
|
-
nitroConfig
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
"campaignKey",
|
|
223
|
-
"cached",
|
|
224
|
-
"context",
|
|
225
|
-
"createLog",
|
|
226
|
-
"log",
|
|
227
|
-
"api/cacheAuth",
|
|
228
|
-
"rpc/rpcCall",
|
|
229
|
-
"rpc/rpcRequest",
|
|
230
|
-
"server/middleware/oauth",
|
|
231
|
-
"server/middleware/redirects",
|
|
232
|
-
"server/middleware/cache",
|
|
233
|
-
"server/utils/cacheStorage",
|
|
234
|
-
"utils/zodSchema",
|
|
235
|
-
"nitro/plugins/cacheRuntimeConfig",
|
|
236
|
-
"nitro/plugins/nitroLogger",
|
|
237
|
-
"nitro/plugins/nitroRuntimeStorageConfig",
|
|
238
|
-
"nitro/plugins/nitroSetXPoweredByHeader",
|
|
239
|
-
"nitro/plugins/configValidation"
|
|
240
|
-
];
|
|
241
|
-
runtimePaths.forEach((path) => {
|
|
242
|
-
const file = resolve(`./runtime/${path}`);
|
|
243
|
-
nitroConfig.externals?.inline?.push(file);
|
|
327
|
+
nitroSetup(nitroConfig, {
|
|
328
|
+
apiBasePath,
|
|
329
|
+
customRpcImports,
|
|
330
|
+
coreMethodNames: [...rpcMethodNames],
|
|
331
|
+
usedDrivers: getUsedDrivers(nuxt.options.runtimeConfig.storefront)
|
|
244
332
|
});
|
|
245
|
-
nitroConfig.replace = nitroConfig.replace || {};
|
|
246
|
-
nitroConfig.replace["process.env.SFC_OMIT_MD5"] = stringToBoolean(
|
|
247
|
-
process.env.SFC_OMIT_MD5
|
|
248
|
-
);
|
|
249
|
-
nitroConfig.replace.__sfc_version = PACKAGE_VERSION;
|
|
250
|
-
nitroConfig.virtual = {
|
|
251
|
-
...nitroConfig.virtual,
|
|
252
|
-
"#virtual/storage-drivers": createVirtualDriverImport(
|
|
253
|
-
nuxt.options.runtimeConfig.storefront
|
|
254
|
-
)
|
|
255
|
-
};
|
|
256
333
|
});
|
|
257
334
|
nuxt.hooks.hook("nitro:init", (nitro) => {
|
|
258
335
|
nitro.hooks.hook("rollup:before", (_nitro, rollupConfig) => {
|
|
@@ -269,9 +346,6 @@ Missing RPC Overrides: ${Array.from(overridenRPCMethodNames).map((name) => `'${n
|
|
|
269
346
|
};
|
|
270
347
|
});
|
|
271
348
|
});
|
|
272
|
-
nuxt.options.alias["#rpcMethods"] = appResolve(
|
|
273
|
-
options.rpcDir ?? "./rpcMethods"
|
|
274
|
-
);
|
|
275
349
|
nuxt.options.alias["#storefront/composables"] = resolve(
|
|
276
350
|
"./runtime/composables"
|
|
277
351
|
);
|
|
@@ -3,6 +3,16 @@ import { HttpStatusCode } from "@scayle/storefront-core";
|
|
|
3
3
|
import { eventHandlerWithCacheAuth } from "./cacheAuth.js";
|
|
4
4
|
export default eventHandlerWithCacheAuth(
|
|
5
5
|
defineEventHandler(async (event) => {
|
|
6
|
+
if (!event.context.$rpcContext) {
|
|
7
|
+
return new Response("No $rpcContext was found for the request", {
|
|
8
|
+
status: HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
if (!event.context.$cache) {
|
|
12
|
+
return new Response("No $cache was found for the request", {
|
|
13
|
+
status: HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
14
|
+
});
|
|
15
|
+
}
|
|
6
16
|
const logger = event.context.$rpcContext.log.space("purge-all");
|
|
7
17
|
try {
|
|
8
18
|
logger.debug("purging cache");
|
|
@@ -3,6 +3,16 @@ import { HttpStatusCode } from "@scayle/storefront-core";
|
|
|
3
3
|
import { eventHandlerWithCacheAuth } from "./cacheAuth.js";
|
|
4
4
|
export default eventHandlerWithCacheAuth(
|
|
5
5
|
defineEventHandler(async (event) => {
|
|
6
|
+
if (!event.context.$rpcContext) {
|
|
7
|
+
return new Response("No $rpcContext was found for the request", {
|
|
8
|
+
status: HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
if (!event.context.$cache) {
|
|
12
|
+
return new Response("No $cache was found for the request", {
|
|
13
|
+
status: HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
14
|
+
});
|
|
15
|
+
}
|
|
6
16
|
const tags = await readBody(event);
|
|
7
17
|
const logger = event.context.$rpcContext.log.space("purge-tags");
|
|
8
18
|
logger.debug(`purging tags: ${tags}`);
|
|
@@ -1,2 +1,51 @@
|
|
|
1
|
-
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<
|
|
1
|
+
declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<string | true | string[] | import("@scayle/storefront-core").ShopUser | Response | import("@scayle/storefront-api").Product | import("@scayle/storefront-api").Product[] | {
|
|
2
|
+
count: number;
|
|
3
|
+
} | {
|
|
4
|
+
filters: import("@scayle/storefront-api").FiltersEndpointResponseData;
|
|
5
|
+
unfilteredCount: number;
|
|
6
|
+
} | {
|
|
7
|
+
products: import("@scayle/storefront-api").Product[];
|
|
8
|
+
pagination: {
|
|
9
|
+
current: number;
|
|
10
|
+
total: number;
|
|
11
|
+
perPage: number;
|
|
12
|
+
page: number;
|
|
13
|
+
first: number;
|
|
14
|
+
prev: number;
|
|
15
|
+
next: number;
|
|
16
|
+
last: number;
|
|
17
|
+
};
|
|
18
|
+
} | {
|
|
19
|
+
basket: import("@scayle/storefront-api").BasketResponseData<import("@scayle/storefront-api").Product, import("@scayle/storefront-api").Variant>;
|
|
20
|
+
} | {
|
|
21
|
+
readonly type: "success";
|
|
22
|
+
readonly basket: import("@scayle/storefront-api").BasketResponseData<import("@scayle/storefront-api").Product, import("@scayle/storefront-api").Variant>;
|
|
23
|
+
} | {
|
|
24
|
+
readonly type: "failure";
|
|
25
|
+
readonly basket: import("@scayle/storefront-api").BasketResponseData<import("@scayle/storefront-api").Product, import("@scayle/storefront-api").Variant>;
|
|
26
|
+
readonly errors: import("@scayle/storefront-api").AddOrUpdateItemError[];
|
|
27
|
+
} | import("@scayle/storefront-api").BrandsEndpointResponseData | import("@scayle/storefront-api").Brand | {
|
|
28
|
+
categories: import("@scayle/storefront-api").Category[];
|
|
29
|
+
activeNode: undefined;
|
|
30
|
+
} | import("@scayle/storefront-api").Category | {
|
|
31
|
+
categories: import("@scayle/storefront-api").Category;
|
|
32
|
+
activeNode: import("@scayle/storefront-api").Category;
|
|
33
|
+
} | import("@scayle/storefront-core").Order | import("@scayle/storefront-api").SearchV2SuggestionsEndpointResponseData | import("@scayle/storefront-api").SearchEntity | import("@scayle/storefront-api").ShopConfiguration | {
|
|
34
|
+
user: import("@scayle/storefront-core").ShopUser | undefined;
|
|
35
|
+
} | import("@scayle/storefront-api").Wishlist | import("@scayle/storefront-core").ShopUserAddress[] | {
|
|
36
|
+
accessToken: string;
|
|
37
|
+
checkoutJwt: string;
|
|
38
|
+
} | import("@scayle/storefront-api").VariantDetail[] | import("@scayle/storefront-api").NavigationAllEndpointResponseData | import("@scayle/storefront-api").NavigationTree | {
|
|
39
|
+
success: true;
|
|
40
|
+
} | {
|
|
41
|
+
success: false;
|
|
42
|
+
} | {
|
|
43
|
+
result: true;
|
|
44
|
+
} | {
|
|
45
|
+
result: false;
|
|
46
|
+
} | import("@scayle/storefront-api").PromotionsEndpointResponseData | {
|
|
47
|
+
[k: string]: string;
|
|
48
|
+
} | {
|
|
49
|
+
message: string;
|
|
50
|
+
} | null | undefined>>;
|
|
2
51
|
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineEventHandler, readBody, createError, getRequestURL } from "h3";
|
|
2
|
-
import { purifySensitiveData } from "@scayle/storefront-core";
|
|
2
|
+
import { purifySensitiveData, HttpStatusCode } from "@scayle/storefront-core";
|
|
3
3
|
import { trace, SpanStatusCode } from "@opentelemetry/api";
|
|
4
4
|
import { handler } from "../handler.js";
|
|
5
5
|
import { resolveError } from "../error/handler.js";
|
|
@@ -9,6 +9,12 @@ const tracer = trace.getTracer(
|
|
|
9
9
|
"__sfc_version"
|
|
10
10
|
);
|
|
11
11
|
export default defineEventHandler(async (event) => {
|
|
12
|
+
const $rpcContext = event.context.$rpcContext;
|
|
13
|
+
if (!$rpcContext) {
|
|
14
|
+
return new Response("No $rpcContext was found for the request", {
|
|
15
|
+
status: HttpStatusCode.INTERNAL_SERVER_ERROR
|
|
16
|
+
});
|
|
17
|
+
}
|
|
12
18
|
const pathComponents = event.path.split("?")[0].split("/");
|
|
13
19
|
const method = pathComponents[pathComponents.length - 1];
|
|
14
20
|
const body = await readBody(event);
|
|
@@ -21,7 +27,7 @@ export default defineEventHandler(async (event) => {
|
|
|
21
27
|
typeof body?.payload !== "object" ? { [typeof body?.payload]: body?.payload } : body?.payload
|
|
22
28
|
)
|
|
23
29
|
);
|
|
24
|
-
|
|
30
|
+
$rpcContext.log.space("sfc").debug(`RPC Handler: ${method}, Payload: ${payloadToBeLogged}`);
|
|
25
31
|
const nitroApp = useNitroApp();
|
|
26
32
|
return await tracer.startActiveSpan(
|
|
27
33
|
`storefront-nuxt.rpc/${method}`,
|
|
@@ -41,14 +47,14 @@ export default defineEventHandler(async (event) => {
|
|
|
41
47
|
await nitroApp.hooks?.callHook(
|
|
42
48
|
"storefront:rpc:before",
|
|
43
49
|
method,
|
|
44
|
-
|
|
50
|
+
$rpcContext,
|
|
45
51
|
body?.payload
|
|
46
52
|
);
|
|
47
|
-
result = await handler(method, body?.payload,
|
|
53
|
+
result = await handler(method, body?.payload, $rpcContext);
|
|
48
54
|
await nitroApp.hooks.callHook(
|
|
49
55
|
"storefront:rpc:after",
|
|
50
56
|
method,
|
|
51
|
-
|
|
57
|
+
$rpcContext,
|
|
52
58
|
result
|
|
53
59
|
);
|
|
54
60
|
if (result instanceof Response && !result.ok) {
|
|
@@ -57,11 +63,11 @@ export default defineEventHandler(async (event) => {
|
|
|
57
63
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
58
64
|
}
|
|
59
65
|
} catch (e) {
|
|
60
|
-
|
|
66
|
+
$rpcContext.log.space("sfc").error(`RPC Handler failed: ${method}`, e);
|
|
61
67
|
await nitroApp.hooks.callHook(
|
|
62
68
|
"storefront:rpc:error",
|
|
63
69
|
method,
|
|
64
|
-
|
|
70
|
+
$rpcContext,
|
|
65
71
|
e
|
|
66
72
|
);
|
|
67
73
|
result = createError(resolveError(e));
|
|
@@ -14,5 +14,5 @@ export declare function useStorefrontSearch(searchQuery: Ref<string>, { params }
|
|
|
14
14
|
error: Ref<unknown, unknown>;
|
|
15
15
|
resetSearch: () => void;
|
|
16
16
|
getSearchSuggestions: () => Promise<void>;
|
|
17
|
-
resolveSearch: () => Promise<
|
|
17
|
+
resolveSearch: () => Promise<import("@scayle/storefront-api").SearchEntity | null | undefined>;
|
|
18
18
|
};
|
package/dist/runtime/handler.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { rpcMethods as coreRpcMethods } from "@scayle/storefront-core";
|
|
2
|
-
import * as storefrontRpcMethods from "#
|
|
2
|
+
import * as storefrontRpcMethods from "#virtual/customRpcMethods";
|
|
3
3
|
export const handler = async (method, payload, rpcContext) => {
|
|
4
4
|
const rpcMethods = {
|
|
5
5
|
...coreRpcMethods,
|
|
@@ -5,8 +5,12 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
5
5
|
const currentShop = useCurrentShop();
|
|
6
6
|
const availableShops = useAvailableShops();
|
|
7
7
|
if (import.meta.server && nuxtApp.ssrContext) {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
if (nuxtApp.ssrContext.event.context.$currentShop) {
|
|
9
|
+
currentShop.value = nuxtApp.ssrContext.event.context.$currentShop;
|
|
10
|
+
}
|
|
11
|
+
if (nuxtApp.ssrContext.event.context.$availableShops) {
|
|
12
|
+
availableShops.value = nuxtApp.ssrContext.event.context.$availableShops;
|
|
13
|
+
}
|
|
10
14
|
}
|
|
11
15
|
return {
|
|
12
16
|
provide: {
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { PublicShopConfig } from '../../../module.js';
|
|
3
|
-
declare module 'h3' {
|
|
4
|
-
interface H3EventContext {
|
|
5
|
-
$rpcContext: RpcContext;
|
|
6
|
-
$cache: Cache;
|
|
7
|
-
$currentShop: PublicShopConfig;
|
|
8
|
-
$availableShops: PublicShopConfig[];
|
|
9
|
-
}
|
|
10
|
-
}
|
|
1
|
+
import type { ShopUser } from '@scayle/storefront-core';
|
|
11
2
|
export interface ShopSessionData {
|
|
12
3
|
user?: ShopUser;
|
|
13
4
|
accessToken?: string;
|
|
@@ -51,6 +51,9 @@ async function fetchRedirectWithCache(sourceUrl, storefrontAPIClient, redirectCa
|
|
|
51
51
|
return sapiResult;
|
|
52
52
|
}
|
|
53
53
|
export async function useRedirects(event) {
|
|
54
|
+
if (!event.context.$rpcContext) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
54
57
|
const config = useRuntimeConfig();
|
|
55
58
|
const $storefrontConfig = config.storefront;
|
|
56
59
|
const options = $storefrontConfig.redirects;
|
package/dist/types.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { NuxtModule } from '@nuxt/schema'
|
|
2
2
|
|
|
3
|
-
import type { default as Module, ModulePublicRuntimeConfig } from './module.js'
|
|
3
|
+
import type { default as Module, ModuleHooks, ModulePublicRuntimeConfig } from './module.js'
|
|
4
4
|
|
|
5
5
|
declare module '@nuxt/schema' {
|
|
6
|
+
interface NuxtHooks extends ModuleHooks {}
|
|
6
7
|
interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}
|
|
7
8
|
}
|
|
8
9
|
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { NuxtModule } from '@nuxt/schema'
|
|
2
2
|
|
|
3
|
-
import type { default as Module, ModulePublicRuntimeConfig } from './module'
|
|
3
|
+
import type { default as Module, ModuleHooks, ModulePublicRuntimeConfig } from './module'
|
|
4
4
|
|
|
5
5
|
declare module '@nuxt/schema' {
|
|
6
|
+
interface NuxtHooks extends ModuleHooks {}
|
|
6
7
|
interface PublicRuntimeConfig extends ModulePublicRuntimeConfig {}
|
|
7
8
|
}
|
|
8
9
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/storefront-nuxt",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.7.1",
|
|
5
5
|
"description": "Nuxt integration for the SCAYLE Commerce Engine and Storefront API",
|
|
6
6
|
"author": "SCAYLE Commerce Engine",
|
|
7
7
|
"license": "MIT",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@opentelemetry/api": "^1.9.0",
|
|
74
74
|
"@scayle/h3-session": "0.6.0",
|
|
75
|
-
"@scayle/storefront-core": "8.3.
|
|
75
|
+
"@scayle/storefront-core": "8.3.2",
|
|
76
76
|
"@scayle/unstorage-compression-driver": "^0.2.3",
|
|
77
77
|
"@vueuse/core": "12.5.0",
|
|
78
78
|
"consola": "^3.2.3",
|