@wix/sdk 1.14.4 → 1.15.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/build/auth/AppStrategy.d.ts +11 -2
- package/build/auth/AppStrategy.js +10 -16
- package/build/web-method-modules.d.ts +35 -0
- package/build/web-method-modules.js +112 -0
- package/build/wixClient.d.ts +3 -0
- package/build/wixClient.js +24 -17
- package/cjs/build/auth/AppStrategy.d.ts +11 -2
- package/cjs/build/auth/AppStrategy.js +28 -23
- package/cjs/build/web-method-modules.d.ts +35 -0
- package/cjs/build/web-method-modules.js +117 -0
- package/cjs/build/wixClient.d.ts +3 -0
- package/cjs/build/wixClient.js +24 -17
- package/package.json +17 -16
|
@@ -17,7 +17,7 @@ export type AppStrategy = AuthenticationStrategy<undefined> & {
|
|
|
17
17
|
*/
|
|
18
18
|
elevated(): Promise<AppStrategy>;
|
|
19
19
|
/**
|
|
20
|
-
* Returns
|
|
20
|
+
* Returns information about the active token
|
|
21
21
|
*/
|
|
22
22
|
getTokenInfo(): Promise<{
|
|
23
23
|
active: boolean;
|
|
@@ -73,7 +73,6 @@ export declare function AppStrategy(opts: {
|
|
|
73
73
|
appId: string;
|
|
74
74
|
appSecret?: string;
|
|
75
75
|
publicKey?: string;
|
|
76
|
-
authServerBaseUrl?: string;
|
|
77
76
|
} & ({
|
|
78
77
|
refreshToken?: string;
|
|
79
78
|
} | {
|
|
@@ -81,3 +80,13 @@ export declare function AppStrategy(opts: {
|
|
|
81
80
|
} | {
|
|
82
81
|
accessToken?: string;
|
|
83
82
|
})): AppStrategy;
|
|
83
|
+
export declare function getTokenInfo(token: string): Promise<{
|
|
84
|
+
active: boolean;
|
|
85
|
+
subjectType: 'APP' | 'USER' | 'MEMBER' | 'VISITOR' | 'UNKNOWN';
|
|
86
|
+
subjectId: string;
|
|
87
|
+
exp: number;
|
|
88
|
+
iat: number;
|
|
89
|
+
clientId?: string;
|
|
90
|
+
siteId: string;
|
|
91
|
+
instanceId?: string;
|
|
92
|
+
}>;
|
|
@@ -40,7 +40,6 @@ import { parsePublicKeyIfEncoded } from '../helpers.js';
|
|
|
40
40
|
*/
|
|
41
41
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
42
42
|
export function AppStrategy(opts) {
|
|
43
|
-
const authServerBaseUrl = opts.authServerBaseUrl ?? 'https://www.wixapis.com';
|
|
44
43
|
let refreshToken = 'refreshToken' in opts ? opts.refreshToken : undefined;
|
|
45
44
|
let cachedToken;
|
|
46
45
|
return {
|
|
@@ -70,8 +69,7 @@ export function AppStrategy(opts) {
|
|
|
70
69
|
if (!code || !instanceId) {
|
|
71
70
|
throw new Error('Invalid OAuth callback URL. Make sure you pass the url including the code and instanceId query params.');
|
|
72
71
|
}
|
|
73
|
-
const
|
|
74
|
-
const tokensRes = await fetch(tokenUrl.href, {
|
|
72
|
+
const tokensRes = await fetch('https://www.wixapis.com/oauth/access', {
|
|
75
73
|
method: 'POST',
|
|
76
74
|
headers: {
|
|
77
75
|
'Content-Type': 'application/json',
|
|
@@ -104,10 +102,9 @@ export function AppStrategy(opts) {
|
|
|
104
102
|
}
|
|
105
103
|
if ('refreshToken' in opts || refreshToken) {
|
|
106
104
|
if (!opts.appSecret) {
|
|
107
|
-
throw new Error('App secret is required for
|
|
105
|
+
throw new Error('App secret is required for retrieving app-level access tokens. Make sure to pass it to the AppStrategy');
|
|
108
106
|
}
|
|
109
|
-
const
|
|
110
|
-
const tokensRes = await fetch(tokenUrl.href, {
|
|
107
|
+
const tokensRes = await fetch('https://www.wixapis.com/oauth/access', {
|
|
111
108
|
method: 'POST',
|
|
112
109
|
headers: {
|
|
113
110
|
'Content-Type': 'application/json',
|
|
@@ -132,10 +129,9 @@ export function AppStrategy(opts) {
|
|
|
132
129
|
}
|
|
133
130
|
else if ('instanceId' in opts) {
|
|
134
131
|
if (!opts.appSecret) {
|
|
135
|
-
throw new Error('App secret is required for
|
|
132
|
+
throw new Error('App secret is required for retrieving app-level access tokens. Make sure to pass it to the AppStrategy');
|
|
136
133
|
}
|
|
137
|
-
const
|
|
138
|
-
const tokensRes = await fetch(tokenUrl.href, {
|
|
134
|
+
const tokensRes = await fetch('https://www.wixapis.com/oauth2/token', {
|
|
139
135
|
method: 'POST',
|
|
140
136
|
headers: {
|
|
141
137
|
'Content-Type': 'application/json',
|
|
@@ -162,7 +158,7 @@ export function AppStrategy(opts) {
|
|
|
162
158
|
};
|
|
163
159
|
}
|
|
164
160
|
else if ('accessToken' in opts && opts.accessToken) {
|
|
165
|
-
const tokenRes = await fetch(
|
|
161
|
+
const tokenRes = await fetch('https://www.wixapis.com/oauth2/token', {
|
|
166
162
|
method: 'POST',
|
|
167
163
|
headers: {
|
|
168
164
|
'Content-Type': 'application/json',
|
|
@@ -193,7 +189,7 @@ export function AppStrategy(opts) {
|
|
|
193
189
|
},
|
|
194
190
|
async elevated() {
|
|
195
191
|
if ('accessToken' in opts && opts.accessToken) {
|
|
196
|
-
const tokenInfo = await getTokenInfo(opts.accessToken
|
|
192
|
+
const tokenInfo = await getTokenInfo(opts.accessToken);
|
|
197
193
|
if (tokenInfo.clientId !== opts.appId) {
|
|
198
194
|
throw new Error(`Invalid access token. The token is not issued for the app with ID "${opts.appId}"`);
|
|
199
195
|
}
|
|
@@ -205,7 +201,6 @@ export function AppStrategy(opts) {
|
|
|
205
201
|
appSecret: opts.appSecret,
|
|
206
202
|
publicKey: opts.publicKey,
|
|
207
203
|
instanceId: tokenInfo.instanceId,
|
|
208
|
-
authServerBaseUrl: opts.authServerBaseUrl,
|
|
209
204
|
});
|
|
210
205
|
}
|
|
211
206
|
else {
|
|
@@ -236,16 +231,15 @@ export function AppStrategy(opts) {
|
|
|
236
231
|
if (!tokenToCheck) {
|
|
237
232
|
throw new Error('Missing token to get info for. Either pass the token as an argument or provide it when initializing the AppStrategy');
|
|
238
233
|
}
|
|
239
|
-
return getTokenInfo(tokenToCheck
|
|
234
|
+
return getTokenInfo(tokenToCheck);
|
|
240
235
|
},
|
|
241
236
|
getActiveToken() {
|
|
242
237
|
return 'accessToken' in opts ? opts.accessToken : refreshToken;
|
|
243
238
|
},
|
|
244
239
|
};
|
|
245
240
|
}
|
|
246
|
-
async function getTokenInfo(token
|
|
247
|
-
const
|
|
248
|
-
const tokenInfoRes = await fetch(tokenInfoUrl.href, {
|
|
241
|
+
export async function getTokenInfo(token) {
|
|
242
|
+
const tokenInfoRes = await fetch('https://www.wixapis.com/oauth2/token-info', {
|
|
249
243
|
method: 'POST',
|
|
250
244
|
headers: {
|
|
251
245
|
'Content-Type': 'application/json',
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const isWebMethodModules: (val: any) => val is WebMethodModules;
|
|
2
|
+
export type WebMethodClient = {
|
|
3
|
+
processRequest(request: Request, devMode?: boolean): Promise<Response>;
|
|
4
|
+
callWebMethod(options: {
|
|
5
|
+
filename: string;
|
|
6
|
+
method: string;
|
|
7
|
+
args: unknown[];
|
|
8
|
+
baseURL: string;
|
|
9
|
+
}): Promise<unknown>;
|
|
10
|
+
};
|
|
11
|
+
declare enum Permissions {
|
|
12
|
+
Anyone = "anyone",
|
|
13
|
+
Admin = "admin",
|
|
14
|
+
SiteMember = "site-member"
|
|
15
|
+
}
|
|
16
|
+
type WebMethod<T extends unknown[], R> = {
|
|
17
|
+
handler: (...args: T) => R;
|
|
18
|
+
permission: Permissions;
|
|
19
|
+
__type: 'web-method-module';
|
|
20
|
+
};
|
|
21
|
+
type WebMethodModule = Record<string, WebMethod<unknown[], unknown>>;
|
|
22
|
+
export type WebMethodModules = Record<string, () => Promise<WebMethodModule>>;
|
|
23
|
+
export declare function webMethodModules(fetchWithAuth: (urlOrRequest: string | URL | Request, requestInit?: RequestInit) => Promise<Response>): {
|
|
24
|
+
initModule(webMethodModule: WebMethodModules): void;
|
|
25
|
+
client: {
|
|
26
|
+
processRequest(request: Request, devMode?: boolean | undefined): Promise<Response>;
|
|
27
|
+
callWebMethod({ baseURL, filename, method, args }: {
|
|
28
|
+
filename: string;
|
|
29
|
+
method: string;
|
|
30
|
+
args: unknown[];
|
|
31
|
+
baseURL: string;
|
|
32
|
+
}): Promise<any>;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { serializeError } from 'serialize-error';
|
|
2
|
+
import { getTokenInfo } from './auth/AppStrategy.js';
|
|
3
|
+
export const isWebMethodModules = (val) => val.__type === 'web-method-module';
|
|
4
|
+
var Permissions;
|
|
5
|
+
(function (Permissions) {
|
|
6
|
+
Permissions["Anyone"] = "anyone";
|
|
7
|
+
Permissions["Admin"] = "admin";
|
|
8
|
+
Permissions["SiteMember"] = "site-member";
|
|
9
|
+
})(Permissions || (Permissions = {}));
|
|
10
|
+
async function checkPermission(request, permission) {
|
|
11
|
+
const accessToken = request.headers.get('Authorization');
|
|
12
|
+
if (!accessToken) {
|
|
13
|
+
throw new Error('Request is missing authentication data');
|
|
14
|
+
}
|
|
15
|
+
const { subjectType } = await getTokenInfo(accessToken);
|
|
16
|
+
switch (permission) {
|
|
17
|
+
case Permissions.Anyone: {
|
|
18
|
+
if (subjectType !== 'VISITOR' &&
|
|
19
|
+
subjectType !== 'MEMBER' &&
|
|
20
|
+
subjectType !== 'USER') {
|
|
21
|
+
throw new Error('Insufficient permissions');
|
|
22
|
+
}
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case Permissions.SiteMember: {
|
|
26
|
+
if (subjectType !== 'MEMBER' && subjectType !== 'USER') {
|
|
27
|
+
throw new Error('Insufficient permissions');
|
|
28
|
+
}
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
case Permissions.Admin: {
|
|
32
|
+
if (subjectType !== 'USER') {
|
|
33
|
+
throw new Error('Insufficient permissions');
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const urlRegex = /\/_webMethods\/(.+\..+)\/(.+\..+)/;
|
|
40
|
+
// /_webMethods/backend/my-module.web.js/multiply.ajax
|
|
41
|
+
function extractUrlParts(url) {
|
|
42
|
+
const parts = url.match(urlRegex);
|
|
43
|
+
if (parts) {
|
|
44
|
+
return [parts[1], parts[2].replace('.ajax', '')];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function isRequestBodyValid(body) {
|
|
48
|
+
return !!body && typeof body === 'object' && Array.isArray(body);
|
|
49
|
+
}
|
|
50
|
+
const productionErrorMessage = 'Error: Unable to handle the request. Contact the site administrator or view site monitoring logs for more information.';
|
|
51
|
+
export function webMethodModules(fetchWithAuth) {
|
|
52
|
+
const webMethods = {};
|
|
53
|
+
const client = {
|
|
54
|
+
async processRequest(request, devMode = false) {
|
|
55
|
+
const urlParts = extractUrlParts(request.url);
|
|
56
|
+
if (!urlParts) {
|
|
57
|
+
return new Response('invalid request', { status: 400 });
|
|
58
|
+
}
|
|
59
|
+
const [file, method] = urlParts;
|
|
60
|
+
const body = (await request.json());
|
|
61
|
+
if (!isRequestBodyValid(body)) {
|
|
62
|
+
return new Response('invalid request', { status: 400 });
|
|
63
|
+
}
|
|
64
|
+
const loadWebMethodFile = webMethods[`/${file}`];
|
|
65
|
+
try {
|
|
66
|
+
if (!loadWebMethodFile) {
|
|
67
|
+
throw new Error(`Error loading web module ${file}: Cannot find module '${file}'`);
|
|
68
|
+
}
|
|
69
|
+
const webMethodFile = await loadWebMethodFile();
|
|
70
|
+
const webMethod = webMethodFile[method];
|
|
71
|
+
if (!webMethod) {
|
|
72
|
+
throw new Error(`Error loading function from web module ${file}: function '${method}' not found`);
|
|
73
|
+
}
|
|
74
|
+
await checkPermission(request, webMethod.permission);
|
|
75
|
+
return Response.json({
|
|
76
|
+
result: await webMethod.handler(...body),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const serializedError = serializeError(error, { maxDepth: 1 });
|
|
81
|
+
return Response.json({
|
|
82
|
+
result: devMode || !(error instanceof Error)
|
|
83
|
+
? serializedError
|
|
84
|
+
: {
|
|
85
|
+
...serializedError,
|
|
86
|
+
message: productionErrorMessage,
|
|
87
|
+
stack: productionErrorMessage,
|
|
88
|
+
},
|
|
89
|
+
exception: true,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
async callWebMethod({ baseURL, filename, method, args }) {
|
|
94
|
+
const response = await fetchWithAuth(`${baseURL}/_webMethods/${filename}/${method}.ajax`, {
|
|
95
|
+
body: JSON.stringify(args),
|
|
96
|
+
method: 'POST',
|
|
97
|
+
});
|
|
98
|
+
const json = await response.json();
|
|
99
|
+
// request failed
|
|
100
|
+
if (json.exception === true) {
|
|
101
|
+
throw json.result;
|
|
102
|
+
}
|
|
103
|
+
return json.result;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
initModule(webMethodModule) {
|
|
108
|
+
Object.assign(webMethods, webMethodModule);
|
|
109
|
+
},
|
|
110
|
+
client,
|
|
111
|
+
};
|
|
112
|
+
}
|
package/build/wixClient.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { EmptyObject } from 'type-fest/source/empty-object.js';
|
|
|
3
3
|
import type { GraphQLFormattedError } from 'graphql';
|
|
4
4
|
import { EventHandlersClient } from './event-handlers-modules.js';
|
|
5
5
|
import { ServicePluginsClient } from './service-plugin-modules.js';
|
|
6
|
+
import { WebMethodClient, WebMethodModules } from './web-method-modules.js';
|
|
6
7
|
export type ContextType = 'global' | 'module';
|
|
7
8
|
type Headers = Record<string, string>;
|
|
8
9
|
/**
|
|
@@ -46,11 +47,13 @@ export type WixClient<H extends Host<any> | undefined = undefined, Z extends Aut
|
|
|
46
47
|
}>;
|
|
47
48
|
webhooks: EventHandlersClient;
|
|
48
49
|
servicePlugins: ServicePluginsClient;
|
|
50
|
+
webMethods: WebMethodClient;
|
|
49
51
|
} & BuildDescriptors<T, H>;
|
|
50
52
|
export declare function createClient<H extends Host<any> | undefined = undefined, Z extends AuthenticationStrategy<H> = AuthenticationStrategy<H>, T extends Descriptors = EmptyObject>(config: {
|
|
51
53
|
modules?: H extends Host<any> ? AssertHostMatches<T, H> : T;
|
|
52
54
|
auth?: Z;
|
|
53
55
|
headers?: Headers;
|
|
54
56
|
host?: H;
|
|
57
|
+
webMethods?: WebMethodModules;
|
|
55
58
|
}): WixClient<H, Z, T>;
|
|
56
59
|
export {};
|
package/build/wixClient.js
CHANGED
|
@@ -9,6 +9,7 @@ import { buildRESTDescriptor } from './rest-modules.js';
|
|
|
9
9
|
import { eventHandlersModules, isEventHandlerModule, } from './event-handlers-modules.js';
|
|
10
10
|
import { isServicePluginModule, servicePluginsModules, } from './service-plugin-modules.js';
|
|
11
11
|
import { runWithoutContext } from '@wix/sdk-runtime/context';
|
|
12
|
+
import { isWebMethodModules, webMethodModules, } from './web-method-modules.js';
|
|
12
13
|
export function createClient(config) {
|
|
13
14
|
const _headers = config.headers || { Authorization: '' };
|
|
14
15
|
const authStrategy = config.auth ||
|
|
@@ -17,8 +18,26 @@ export function createClient(config) {
|
|
|
17
18
|
};
|
|
18
19
|
const boundGetAuthHeaders = authStrategy.getAuthHeaders.bind(undefined, config.host);
|
|
19
20
|
authStrategy.getAuthHeaders = boundGetAuthHeaders;
|
|
21
|
+
const fetchWithAuth = async (urlOrRequest, requestInit) => {
|
|
22
|
+
if (typeof urlOrRequest === 'string' || urlOrRequest instanceof URL) {
|
|
23
|
+
return fetch(urlOrRequest, {
|
|
24
|
+
...requestInit,
|
|
25
|
+
headers: {
|
|
26
|
+
...requestInit?.headers,
|
|
27
|
+
...(await boundGetAuthHeaders()).headers,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
for (const [k, v] of Object.entries((await boundGetAuthHeaders()).headers)) {
|
|
33
|
+
urlOrRequest.headers.set(k, v);
|
|
34
|
+
}
|
|
35
|
+
return fetch(urlOrRequest, requestInit);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
20
38
|
const { client: servicePluginsClient, initModule: initServicePluginModule } = servicePluginsModules(authStrategy);
|
|
21
39
|
const { client: eventHandlersClient, initModule: initEventHandlerModule } = eventHandlersModules(authStrategy);
|
|
40
|
+
const { client: webMethodClient, initModule } = webMethodModules(fetchWithAuth);
|
|
22
41
|
const boundFetch = async (url, options) => {
|
|
23
42
|
const authHeaders = await boundGetAuthHeaders();
|
|
24
43
|
const defaultContentTypeHeader = getDefaultContentHeader(options);
|
|
@@ -46,6 +65,9 @@ export function createClient(config) {
|
|
|
46
65
|
else if (isHostModule(modules) && config.host) {
|
|
47
66
|
return buildHostModule(modules, config.host);
|
|
48
67
|
}
|
|
68
|
+
else if (isWebMethodModules(modules)) {
|
|
69
|
+
return initModule(modules);
|
|
70
|
+
}
|
|
49
71
|
else if (typeof modules === 'function') {
|
|
50
72
|
// The generated namespaces all have the error classes on them and
|
|
51
73
|
// a class is also a function, so we need to explicitly ignore these
|
|
@@ -126,23 +148,7 @@ export function createClient(config) {
|
|
|
126
148
|
finalUrl.protocol = 'https';
|
|
127
149
|
return boundFetch(finalUrl.toString(), options);
|
|
128
150
|
},
|
|
129
|
-
fetchWithAuth
|
|
130
|
-
if (typeof urlOrRequest === 'string' || urlOrRequest instanceof URL) {
|
|
131
|
-
return fetch(urlOrRequest, {
|
|
132
|
-
...requestInit,
|
|
133
|
-
headers: {
|
|
134
|
-
...requestInit?.headers,
|
|
135
|
-
...(await boundGetAuthHeaders()).headers,
|
|
136
|
-
},
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
for (const [k, v] of Object.entries((await boundGetAuthHeaders()).headers)) {
|
|
141
|
-
urlOrRequest.headers.set(k, v);
|
|
142
|
-
}
|
|
143
|
-
return fetch(urlOrRequest, requestInit);
|
|
144
|
-
}
|
|
145
|
-
},
|
|
151
|
+
fetchWithAuth,
|
|
146
152
|
async graphql(query, variables, opts = {
|
|
147
153
|
apiVersion: 'alpha',
|
|
148
154
|
}) {
|
|
@@ -161,6 +167,7 @@ export function createClient(config) {
|
|
|
161
167
|
return { data: data ?? {}, errors };
|
|
162
168
|
},
|
|
163
169
|
webhooks: eventHandlersClient,
|
|
170
|
+
webMethods: webMethodClient,
|
|
164
171
|
servicePlugins: servicePluginsClient,
|
|
165
172
|
};
|
|
166
173
|
}
|
|
@@ -17,7 +17,7 @@ export type AppStrategy = AuthenticationStrategy<undefined> & {
|
|
|
17
17
|
*/
|
|
18
18
|
elevated(): Promise<AppStrategy>;
|
|
19
19
|
/**
|
|
20
|
-
* Returns
|
|
20
|
+
* Returns information about the active token
|
|
21
21
|
*/
|
|
22
22
|
getTokenInfo(): Promise<{
|
|
23
23
|
active: boolean;
|
|
@@ -73,7 +73,6 @@ export declare function AppStrategy(opts: {
|
|
|
73
73
|
appId: string;
|
|
74
74
|
appSecret?: string;
|
|
75
75
|
publicKey?: string;
|
|
76
|
-
authServerBaseUrl?: string;
|
|
77
76
|
} & ({
|
|
78
77
|
refreshToken?: string;
|
|
79
78
|
} | {
|
|
@@ -81,3 +80,13 @@ export declare function AppStrategy(opts: {
|
|
|
81
80
|
} | {
|
|
82
81
|
accessToken?: string;
|
|
83
82
|
})): AppStrategy;
|
|
83
|
+
export declare function getTokenInfo(token: string): Promise<{
|
|
84
|
+
active: boolean;
|
|
85
|
+
subjectType: 'APP' | 'USER' | 'MEMBER' | 'VISITOR' | 'UNKNOWN';
|
|
86
|
+
subjectId: string;
|
|
87
|
+
exp: number;
|
|
88
|
+
iat: number;
|
|
89
|
+
clientId?: string;
|
|
90
|
+
siteId: string;
|
|
91
|
+
instanceId?: string;
|
|
92
|
+
}>;
|
|
@@ -15,15 +15,26 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.AppStrategy = AppStrategy;
|
|
37
|
+
exports.getTokenInfo = getTokenInfo;
|
|
27
38
|
const helpers_js_1 = require("../helpers.js");
|
|
28
39
|
/**
|
|
29
40
|
* Creates an authentication strategy for Wix Apps OAuth installation process.
|
|
@@ -66,7 +77,6 @@ const helpers_js_1 = require("../helpers.js");
|
|
|
66
77
|
*/
|
|
67
78
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
68
79
|
function AppStrategy(opts) {
|
|
69
|
-
const authServerBaseUrl = opts.authServerBaseUrl ?? 'https://www.wixapis.com';
|
|
70
80
|
let refreshToken = 'refreshToken' in opts ? opts.refreshToken : undefined;
|
|
71
81
|
let cachedToken;
|
|
72
82
|
return {
|
|
@@ -96,8 +106,7 @@ function AppStrategy(opts) {
|
|
|
96
106
|
if (!code || !instanceId) {
|
|
97
107
|
throw new Error('Invalid OAuth callback URL. Make sure you pass the url including the code and instanceId query params.');
|
|
98
108
|
}
|
|
99
|
-
const
|
|
100
|
-
const tokensRes = await fetch(tokenUrl.href, {
|
|
109
|
+
const tokensRes = await fetch('https://www.wixapis.com/oauth/access', {
|
|
101
110
|
method: 'POST',
|
|
102
111
|
headers: {
|
|
103
112
|
'Content-Type': 'application/json',
|
|
@@ -130,10 +139,9 @@ function AppStrategy(opts) {
|
|
|
130
139
|
}
|
|
131
140
|
if ('refreshToken' in opts || refreshToken) {
|
|
132
141
|
if (!opts.appSecret) {
|
|
133
|
-
throw new Error('App secret is required for
|
|
142
|
+
throw new Error('App secret is required for retrieving app-level access tokens. Make sure to pass it to the AppStrategy');
|
|
134
143
|
}
|
|
135
|
-
const
|
|
136
|
-
const tokensRes = await fetch(tokenUrl.href, {
|
|
144
|
+
const tokensRes = await fetch('https://www.wixapis.com/oauth/access', {
|
|
137
145
|
method: 'POST',
|
|
138
146
|
headers: {
|
|
139
147
|
'Content-Type': 'application/json',
|
|
@@ -158,10 +166,9 @@ function AppStrategy(opts) {
|
|
|
158
166
|
}
|
|
159
167
|
else if ('instanceId' in opts) {
|
|
160
168
|
if (!opts.appSecret) {
|
|
161
|
-
throw new Error('App secret is required for
|
|
169
|
+
throw new Error('App secret is required for retrieving app-level access tokens. Make sure to pass it to the AppStrategy');
|
|
162
170
|
}
|
|
163
|
-
const
|
|
164
|
-
const tokensRes = await fetch(tokenUrl.href, {
|
|
171
|
+
const tokensRes = await fetch('https://www.wixapis.com/oauth2/token', {
|
|
165
172
|
method: 'POST',
|
|
166
173
|
headers: {
|
|
167
174
|
'Content-Type': 'application/json',
|
|
@@ -188,7 +195,7 @@ function AppStrategy(opts) {
|
|
|
188
195
|
};
|
|
189
196
|
}
|
|
190
197
|
else if ('accessToken' in opts && opts.accessToken) {
|
|
191
|
-
const tokenRes = await fetch(
|
|
198
|
+
const tokenRes = await fetch('https://www.wixapis.com/oauth2/token', {
|
|
192
199
|
method: 'POST',
|
|
193
200
|
headers: {
|
|
194
201
|
'Content-Type': 'application/json',
|
|
@@ -219,7 +226,7 @@ function AppStrategy(opts) {
|
|
|
219
226
|
},
|
|
220
227
|
async elevated() {
|
|
221
228
|
if ('accessToken' in opts && opts.accessToken) {
|
|
222
|
-
const tokenInfo = await getTokenInfo(opts.accessToken
|
|
229
|
+
const tokenInfo = await getTokenInfo(opts.accessToken);
|
|
223
230
|
if (tokenInfo.clientId !== opts.appId) {
|
|
224
231
|
throw new Error(`Invalid access token. The token is not issued for the app with ID "${opts.appId}"`);
|
|
225
232
|
}
|
|
@@ -231,7 +238,6 @@ function AppStrategy(opts) {
|
|
|
231
238
|
appSecret: opts.appSecret,
|
|
232
239
|
publicKey: opts.publicKey,
|
|
233
240
|
instanceId: tokenInfo.instanceId,
|
|
234
|
-
authServerBaseUrl: opts.authServerBaseUrl,
|
|
235
241
|
});
|
|
236
242
|
}
|
|
237
243
|
else {
|
|
@@ -262,16 +268,15 @@ function AppStrategy(opts) {
|
|
|
262
268
|
if (!tokenToCheck) {
|
|
263
269
|
throw new Error('Missing token to get info for. Either pass the token as an argument or provide it when initializing the AppStrategy');
|
|
264
270
|
}
|
|
265
|
-
return getTokenInfo(tokenToCheck
|
|
271
|
+
return getTokenInfo(tokenToCheck);
|
|
266
272
|
},
|
|
267
273
|
getActiveToken() {
|
|
268
274
|
return 'accessToken' in opts ? opts.accessToken : refreshToken;
|
|
269
275
|
},
|
|
270
276
|
};
|
|
271
277
|
}
|
|
272
|
-
async function getTokenInfo(token
|
|
273
|
-
const
|
|
274
|
-
const tokenInfoRes = await fetch(tokenInfoUrl.href, {
|
|
278
|
+
async function getTokenInfo(token) {
|
|
279
|
+
const tokenInfoRes = await fetch('https://www.wixapis.com/oauth2/token-info', {
|
|
275
280
|
method: 'POST',
|
|
276
281
|
headers: {
|
|
277
282
|
'Content-Type': 'application/json',
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export declare const isWebMethodModules: (val: any) => val is WebMethodModules;
|
|
2
|
+
export type WebMethodClient = {
|
|
3
|
+
processRequest(request: Request, devMode?: boolean): Promise<Response>;
|
|
4
|
+
callWebMethod(options: {
|
|
5
|
+
filename: string;
|
|
6
|
+
method: string;
|
|
7
|
+
args: unknown[];
|
|
8
|
+
baseURL: string;
|
|
9
|
+
}): Promise<unknown>;
|
|
10
|
+
};
|
|
11
|
+
declare enum Permissions {
|
|
12
|
+
Anyone = "anyone",
|
|
13
|
+
Admin = "admin",
|
|
14
|
+
SiteMember = "site-member"
|
|
15
|
+
}
|
|
16
|
+
type WebMethod<T extends unknown[], R> = {
|
|
17
|
+
handler: (...args: T) => R;
|
|
18
|
+
permission: Permissions;
|
|
19
|
+
__type: 'web-method-module';
|
|
20
|
+
};
|
|
21
|
+
type WebMethodModule = Record<string, WebMethod<unknown[], unknown>>;
|
|
22
|
+
export type WebMethodModules = Record<string, () => Promise<WebMethodModule>>;
|
|
23
|
+
export declare function webMethodModules(fetchWithAuth: (urlOrRequest: string | URL | Request, requestInit?: RequestInit) => Promise<Response>): {
|
|
24
|
+
initModule(webMethodModule: WebMethodModules): void;
|
|
25
|
+
client: {
|
|
26
|
+
processRequest(request: Request, devMode?: boolean | undefined): Promise<Response>;
|
|
27
|
+
callWebMethod({ baseURL, filename, method, args }: {
|
|
28
|
+
filename: string;
|
|
29
|
+
method: string;
|
|
30
|
+
args: unknown[];
|
|
31
|
+
baseURL: string;
|
|
32
|
+
}): Promise<any>;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isWebMethodModules = void 0;
|
|
4
|
+
exports.webMethodModules = webMethodModules;
|
|
5
|
+
const serialize_error_1 = require("serialize-error");
|
|
6
|
+
const AppStrategy_js_1 = require("./auth/AppStrategy.js");
|
|
7
|
+
const isWebMethodModules = (val) => val.__type === 'web-method-module';
|
|
8
|
+
exports.isWebMethodModules = isWebMethodModules;
|
|
9
|
+
var Permissions;
|
|
10
|
+
(function (Permissions) {
|
|
11
|
+
Permissions["Anyone"] = "anyone";
|
|
12
|
+
Permissions["Admin"] = "admin";
|
|
13
|
+
Permissions["SiteMember"] = "site-member";
|
|
14
|
+
})(Permissions || (Permissions = {}));
|
|
15
|
+
async function checkPermission(request, permission) {
|
|
16
|
+
const accessToken = request.headers.get('Authorization');
|
|
17
|
+
if (!accessToken) {
|
|
18
|
+
throw new Error('Request is missing authentication data');
|
|
19
|
+
}
|
|
20
|
+
const { subjectType } = await (0, AppStrategy_js_1.getTokenInfo)(accessToken);
|
|
21
|
+
switch (permission) {
|
|
22
|
+
case Permissions.Anyone: {
|
|
23
|
+
if (subjectType !== 'VISITOR' &&
|
|
24
|
+
subjectType !== 'MEMBER' &&
|
|
25
|
+
subjectType !== 'USER') {
|
|
26
|
+
throw new Error('Insufficient permissions');
|
|
27
|
+
}
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
case Permissions.SiteMember: {
|
|
31
|
+
if (subjectType !== 'MEMBER' && subjectType !== 'USER') {
|
|
32
|
+
throw new Error('Insufficient permissions');
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
case Permissions.Admin: {
|
|
37
|
+
if (subjectType !== 'USER') {
|
|
38
|
+
throw new Error('Insufficient permissions');
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const urlRegex = /\/_webMethods\/(.+\..+)\/(.+\..+)/;
|
|
45
|
+
// /_webMethods/backend/my-module.web.js/multiply.ajax
|
|
46
|
+
function extractUrlParts(url) {
|
|
47
|
+
const parts = url.match(urlRegex);
|
|
48
|
+
if (parts) {
|
|
49
|
+
return [parts[1], parts[2].replace('.ajax', '')];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function isRequestBodyValid(body) {
|
|
53
|
+
return !!body && typeof body === 'object' && Array.isArray(body);
|
|
54
|
+
}
|
|
55
|
+
const productionErrorMessage = 'Error: Unable to handle the request. Contact the site administrator or view site monitoring logs for more information.';
|
|
56
|
+
function webMethodModules(fetchWithAuth) {
|
|
57
|
+
const webMethods = {};
|
|
58
|
+
const client = {
|
|
59
|
+
async processRequest(request, devMode = false) {
|
|
60
|
+
const urlParts = extractUrlParts(request.url);
|
|
61
|
+
if (!urlParts) {
|
|
62
|
+
return new Response('invalid request', { status: 400 });
|
|
63
|
+
}
|
|
64
|
+
const [file, method] = urlParts;
|
|
65
|
+
const body = (await request.json());
|
|
66
|
+
if (!isRequestBodyValid(body)) {
|
|
67
|
+
return new Response('invalid request', { status: 400 });
|
|
68
|
+
}
|
|
69
|
+
const loadWebMethodFile = webMethods[`/${file}`];
|
|
70
|
+
try {
|
|
71
|
+
if (!loadWebMethodFile) {
|
|
72
|
+
throw new Error(`Error loading web module ${file}: Cannot find module '${file}'`);
|
|
73
|
+
}
|
|
74
|
+
const webMethodFile = await loadWebMethodFile();
|
|
75
|
+
const webMethod = webMethodFile[method];
|
|
76
|
+
if (!webMethod) {
|
|
77
|
+
throw new Error(`Error loading function from web module ${file}: function '${method}' not found`);
|
|
78
|
+
}
|
|
79
|
+
await checkPermission(request, webMethod.permission);
|
|
80
|
+
return Response.json({
|
|
81
|
+
result: await webMethod.handler(...body),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
const serializedError = (0, serialize_error_1.serializeError)(error, { maxDepth: 1 });
|
|
86
|
+
return Response.json({
|
|
87
|
+
result: devMode || !(error instanceof Error)
|
|
88
|
+
? serializedError
|
|
89
|
+
: {
|
|
90
|
+
...serializedError,
|
|
91
|
+
message: productionErrorMessage,
|
|
92
|
+
stack: productionErrorMessage,
|
|
93
|
+
},
|
|
94
|
+
exception: true,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
async callWebMethod({ baseURL, filename, method, args }) {
|
|
99
|
+
const response = await fetchWithAuth(`${baseURL}/_webMethods/${filename}/${method}.ajax`, {
|
|
100
|
+
body: JSON.stringify(args),
|
|
101
|
+
method: 'POST',
|
|
102
|
+
});
|
|
103
|
+
const json = await response.json();
|
|
104
|
+
// request failed
|
|
105
|
+
if (json.exception === true) {
|
|
106
|
+
throw json.result;
|
|
107
|
+
}
|
|
108
|
+
return json.result;
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
initModule(webMethodModule) {
|
|
113
|
+
Object.assign(webMethods, webMethodModule);
|
|
114
|
+
},
|
|
115
|
+
client,
|
|
116
|
+
};
|
|
117
|
+
}
|
package/cjs/build/wixClient.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { EmptyObject } from 'type-fest/source/empty-object.js';
|
|
|
3
3
|
import type { GraphQLFormattedError } from 'graphql';
|
|
4
4
|
import { EventHandlersClient } from './event-handlers-modules.js';
|
|
5
5
|
import { ServicePluginsClient } from './service-plugin-modules.js';
|
|
6
|
+
import { WebMethodClient, WebMethodModules } from './web-method-modules.js';
|
|
6
7
|
export type ContextType = 'global' | 'module';
|
|
7
8
|
type Headers = Record<string, string>;
|
|
8
9
|
/**
|
|
@@ -46,11 +47,13 @@ export type WixClient<H extends Host<any> | undefined = undefined, Z extends Aut
|
|
|
46
47
|
}>;
|
|
47
48
|
webhooks: EventHandlersClient;
|
|
48
49
|
servicePlugins: ServicePluginsClient;
|
|
50
|
+
webMethods: WebMethodClient;
|
|
49
51
|
} & BuildDescriptors<T, H>;
|
|
50
52
|
export declare function createClient<H extends Host<any> | undefined = undefined, Z extends AuthenticationStrategy<H> = AuthenticationStrategy<H>, T extends Descriptors = EmptyObject>(config: {
|
|
51
53
|
modules?: H extends Host<any> ? AssertHostMatches<T, H> : T;
|
|
52
54
|
auth?: Z;
|
|
53
55
|
headers?: Headers;
|
|
54
56
|
host?: H;
|
|
57
|
+
webMethods?: WebMethodModules;
|
|
55
58
|
}): WixClient<H, Z, T>;
|
|
56
59
|
export {};
|
package/cjs/build/wixClient.js
CHANGED
|
@@ -12,6 +12,7 @@ const rest_modules_js_1 = require("./rest-modules.js");
|
|
|
12
12
|
const event_handlers_modules_js_1 = require("./event-handlers-modules.js");
|
|
13
13
|
const service_plugin_modules_js_1 = require("./service-plugin-modules.js");
|
|
14
14
|
const context_1 = require("@wix/sdk-runtime/context");
|
|
15
|
+
const web_method_modules_js_1 = require("./web-method-modules.js");
|
|
15
16
|
function createClient(config) {
|
|
16
17
|
const _headers = config.headers || { Authorization: '' };
|
|
17
18
|
const authStrategy = config.auth ||
|
|
@@ -20,8 +21,26 @@ function createClient(config) {
|
|
|
20
21
|
};
|
|
21
22
|
const boundGetAuthHeaders = authStrategy.getAuthHeaders.bind(undefined, config.host);
|
|
22
23
|
authStrategy.getAuthHeaders = boundGetAuthHeaders;
|
|
24
|
+
const fetchWithAuth = async (urlOrRequest, requestInit) => {
|
|
25
|
+
if (typeof urlOrRequest === 'string' || urlOrRequest instanceof URL) {
|
|
26
|
+
return fetch(urlOrRequest, {
|
|
27
|
+
...requestInit,
|
|
28
|
+
headers: {
|
|
29
|
+
...requestInit?.headers,
|
|
30
|
+
...(await boundGetAuthHeaders()).headers,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
for (const [k, v] of Object.entries((await boundGetAuthHeaders()).headers)) {
|
|
36
|
+
urlOrRequest.headers.set(k, v);
|
|
37
|
+
}
|
|
38
|
+
return fetch(urlOrRequest, requestInit);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
23
41
|
const { client: servicePluginsClient, initModule: initServicePluginModule } = (0, service_plugin_modules_js_1.servicePluginsModules)(authStrategy);
|
|
24
42
|
const { client: eventHandlersClient, initModule: initEventHandlerModule } = (0, event_handlers_modules_js_1.eventHandlersModules)(authStrategy);
|
|
43
|
+
const { client: webMethodClient, initModule } = (0, web_method_modules_js_1.webMethodModules)(fetchWithAuth);
|
|
25
44
|
const boundFetch = async (url, options) => {
|
|
26
45
|
const authHeaders = await boundGetAuthHeaders();
|
|
27
46
|
const defaultContentTypeHeader = (0, helpers_js_1.getDefaultContentHeader)(options);
|
|
@@ -49,6 +68,9 @@ function createClient(config) {
|
|
|
49
68
|
else if ((0, host_modules_js_1.isHostModule)(modules) && config.host) {
|
|
50
69
|
return (0, host_modules_js_1.buildHostModule)(modules, config.host);
|
|
51
70
|
}
|
|
71
|
+
else if ((0, web_method_modules_js_1.isWebMethodModules)(modules)) {
|
|
72
|
+
return initModule(modules);
|
|
73
|
+
}
|
|
52
74
|
else if (typeof modules === 'function') {
|
|
53
75
|
// The generated namespaces all have the error classes on them and
|
|
54
76
|
// a class is also a function, so we need to explicitly ignore these
|
|
@@ -129,23 +151,7 @@ function createClient(config) {
|
|
|
129
151
|
finalUrl.protocol = 'https';
|
|
130
152
|
return boundFetch(finalUrl.toString(), options);
|
|
131
153
|
},
|
|
132
|
-
fetchWithAuth
|
|
133
|
-
if (typeof urlOrRequest === 'string' || urlOrRequest instanceof URL) {
|
|
134
|
-
return fetch(urlOrRequest, {
|
|
135
|
-
...requestInit,
|
|
136
|
-
headers: {
|
|
137
|
-
...requestInit?.headers,
|
|
138
|
-
...(await boundGetAuthHeaders()).headers,
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
for (const [k, v] of Object.entries((await boundGetAuthHeaders()).headers)) {
|
|
144
|
-
urlOrRequest.headers.set(k, v);
|
|
145
|
-
}
|
|
146
|
-
return fetch(urlOrRequest, requestInit);
|
|
147
|
-
}
|
|
148
|
-
},
|
|
154
|
+
fetchWithAuth,
|
|
149
155
|
async graphql(query, variables, opts = {
|
|
150
156
|
apiVersion: 'alpha',
|
|
151
157
|
}) {
|
|
@@ -164,6 +170,7 @@ function createClient(config) {
|
|
|
164
170
|
return { data: data ?? {}, errors };
|
|
165
171
|
},
|
|
166
172
|
webhooks: eventHandlersClient,
|
|
173
|
+
webMethods: webMethodClient,
|
|
167
174
|
servicePlugins: servicePluginsClient,
|
|
168
175
|
};
|
|
169
176
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Ronny Ringel",
|
|
@@ -63,34 +63,35 @@
|
|
|
63
63
|
"*.{js,ts}": "yarn lint"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@wix/identity": "^1.0.
|
|
67
|
-
"@wix/image-kit": "^1.
|
|
68
|
-
"@wix/redirects": "^1.0.
|
|
66
|
+
"@wix/identity": "^1.0.89",
|
|
67
|
+
"@wix/image-kit": "^1.96.0",
|
|
68
|
+
"@wix/redirects": "^1.0.64",
|
|
69
69
|
"@wix/sdk-context": "^0.0.1",
|
|
70
|
-
"@wix/sdk-runtime": "0.3.
|
|
71
|
-
"@wix/sdk-types": "^1.12.
|
|
70
|
+
"@wix/sdk-runtime": "0.3.25",
|
|
71
|
+
"@wix/sdk-types": "^1.12.5",
|
|
72
72
|
"jose": "^5.9.6",
|
|
73
|
-
"
|
|
73
|
+
"serialize-error": "^8.1.0",
|
|
74
|
+
"type-fest": "^4.29.0"
|
|
74
75
|
},
|
|
75
76
|
"optionalDependencies": {
|
|
76
77
|
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
|
|
77
78
|
},
|
|
78
79
|
"devDependencies": {
|
|
79
80
|
"@types/is-ci": "^3.0.4",
|
|
80
|
-
"@types/node": "^20.17.
|
|
81
|
+
"@types/node": "^20.17.9",
|
|
81
82
|
"@vitest/ui": "^1.6.0",
|
|
82
|
-
"@wix/ecom": "^1.0.
|
|
83
|
-
"@wix/events": "^1.0.
|
|
84
|
-
"@wix/metro": "^1.0.
|
|
85
|
-
"@wix/metro-runtime": "^1.
|
|
86
|
-
"@wix/sdk-runtime": "0.3.
|
|
83
|
+
"@wix/ecom": "^1.0.845",
|
|
84
|
+
"@wix/events": "^1.0.347",
|
|
85
|
+
"@wix/metro": "^1.0.90",
|
|
86
|
+
"@wix/metro-runtime": "^1.1864.0",
|
|
87
|
+
"@wix/sdk-runtime": "0.3.25",
|
|
87
88
|
"eslint": "^8.57.1",
|
|
88
89
|
"eslint-config-sdk": "0.0.0",
|
|
89
90
|
"graphql": "^16.8.0",
|
|
90
91
|
"is-ci": "^3.0.1",
|
|
91
92
|
"jsdom": "^22.1.0",
|
|
92
|
-
"msw": "^2.6.
|
|
93
|
-
"typescript": "^5.
|
|
93
|
+
"msw": "^2.6.6",
|
|
94
|
+
"typescript": "^5.7.2",
|
|
94
95
|
"vitest": "^1.6.0",
|
|
95
96
|
"vitest-teamcity-reporter": "^0.3.1"
|
|
96
97
|
},
|
|
@@ -117,5 +118,5 @@
|
|
|
117
118
|
"wallaby": {
|
|
118
119
|
"autoDetect": true
|
|
119
120
|
},
|
|
120
|
-
"falconPackageHash": "
|
|
121
|
+
"falconPackageHash": "3ea83646bf7d33d3735730b3593ad9567e0c166c2a4c76515505bf41"
|
|
121
122
|
}
|