feat: login support
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
"firebase": "^9.15.0",
|
"firebase": "^9.15.0",
|
||||||
"idb-keyval": "^6.2.0",
|
"idb-keyval": "^6.2.0",
|
||||||
"ky": "^0.33.0",
|
"ky": "^0.33.0",
|
||||||
|
"ky-universal": "^0.11.0",
|
||||||
"lib0": "^0.2.58",
|
"lib0": "^0.2.58",
|
||||||
"swr": "^2.0.0",
|
"swr": "^2.0.0",
|
||||||
"yjs": "^13.5.43",
|
"yjs": "^13.5.43",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Workspace } from '@blocksuite/store';
|
import { Workspace } from '@blocksuite/store';
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
|
||||||
import type { BaseProvider } from './provider/index.js';
|
import { AffineProvider, BaseProvider } from './provider/index.js';
|
||||||
import { MemoryProvider } from './provider/index.js';
|
import { MemoryProvider } from './provider/index.js';
|
||||||
import { getKVConfigure } from './store.js';
|
import { getKVConfigure } from './store.js';
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ export class DataCenter {
|
|||||||
|
|
||||||
static async init(): Promise<DataCenter> {
|
static async init(): Promise<DataCenter> {
|
||||||
const dc = new DataCenter();
|
const dc = new DataCenter();
|
||||||
|
dc.addProvider(AffineProvider);
|
||||||
dc.addProvider(MemoryProvider);
|
dc.addProvider(MemoryProvider);
|
||||||
|
|
||||||
return dc;
|
return dc;
|
||||||
@@ -31,10 +32,10 @@ export class DataCenter {
|
|||||||
const Provider = this._providers.get(providerId);
|
const Provider = this._providers.get(providerId);
|
||||||
assert(Provider);
|
assert(Provider);
|
||||||
const provider = new Provider();
|
const provider = new Provider();
|
||||||
|
|
||||||
console.log(`Loading workspace ${id} with provider ${Provider.id}`);
|
console.log(`Loading workspace ${id} with provider ${Provider.id}`);
|
||||||
await provider.init(getKVConfigure(id), workspace);
|
await provider.init(getKVConfigure(id), workspace);
|
||||||
await provider.initData();
|
await provider.initData();
|
||||||
|
|
||||||
console.log(`Workspace ${id} loaded`);
|
console.log(`Workspace ${id} loaded`);
|
||||||
|
|
||||||
return provider;
|
return provider;
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { AccessTokenMessage } from './token';
|
||||||
|
|
||||||
|
export type Callback = (user: AccessTokenMessage | null) => void;
|
||||||
|
|
||||||
|
export class AuthorizationEvent {
|
||||||
|
private callbacks: Callback[] = [];
|
||||||
|
private lastState: AccessTokenMessage | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback will execute when call this function.
|
||||||
|
*/
|
||||||
|
onChange(callback: Callback) {
|
||||||
|
this.callbacks.push(callback);
|
||||||
|
callback(this.lastState);
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerChange(user: AccessTokenMessage | null) {
|
||||||
|
this.lastState = user;
|
||||||
|
this.callbacks.forEach(callback => callback(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCallback(callback: Callback) {
|
||||||
|
const index = this.callbacks.indexOf(callback);
|
||||||
|
if (index > -1) {
|
||||||
|
this.callbacks.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { AffineProvider } from './provider.js';
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import assert from 'assert';
|
||||||
|
import { Workspace } from '@blocksuite/store';
|
||||||
|
import { BaseProvider } from '../base.js';
|
||||||
|
import { ConfigStore } from '../index.js';
|
||||||
|
import { token } from './token.js';
|
||||||
|
import { Callback } from './events.js';
|
||||||
|
|
||||||
|
export class AffineProvider extends BaseProvider {
|
||||||
|
static id = 'affine';
|
||||||
|
private _onTokenRefresh?: Callback = undefined;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(config: ConfigStore, workspace: Workspace) {
|
||||||
|
super.init(config, workspace);
|
||||||
|
|
||||||
|
this._onTokenRefresh = () => {
|
||||||
|
if (token.refresh) {
|
||||||
|
this._config.set('token', token.refresh);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
assert(this._onTokenRefresh);
|
||||||
|
|
||||||
|
token.onChange(this._onTokenRefresh);
|
||||||
|
if (token.isExpired) {
|
||||||
|
const refreshToken = await this._config.get('token');
|
||||||
|
await token.refreshToken(refreshToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async destroy() {
|
||||||
|
if (this._onTokenRefresh) {
|
||||||
|
token.offChange(this._onTokenRefresh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async initData() {
|
||||||
|
console.log('initData', token.isLogin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import ky from 'ky-universal';
|
||||||
|
import { token } from './token.js';
|
||||||
|
|
||||||
|
export const bareClient = ky.extend({
|
||||||
|
prefixUrl: 'http://localhost:8080',
|
||||||
|
retry: 1,
|
||||||
|
hooks: {
|
||||||
|
// afterResponse: [
|
||||||
|
// async (_request, _options, response) => {
|
||||||
|
// if (response.status === 200) {
|
||||||
|
// const data = await response.json();
|
||||||
|
// if (data.error) {
|
||||||
|
// return new Response(data.error.message, {
|
||||||
|
// status: data.error.code,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return response;
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const client = bareClient.extend({
|
||||||
|
hooks: {
|
||||||
|
beforeRequest: [
|
||||||
|
async request => {
|
||||||
|
if (token.isLogin) {
|
||||||
|
if (token.isExpired) await token.refreshToken();
|
||||||
|
request.headers.set('Authorization', token.token);
|
||||||
|
} else {
|
||||||
|
return new Response('Unauthorized', { status: 401 });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
beforeRetry: [
|
||||||
|
async ({ request }) => {
|
||||||
|
await token.refreshToken();
|
||||||
|
request.headers.set('Authorization', token.token);
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type { AccessTokenMessage } from './token';
|
||||||
|
export { token };
|
||||||
117
packages/data-center/src/datacenter/provider/affine/token.ts
Normal file
117
packages/data-center/src/datacenter/provider/affine/token.ts
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import { bareClient } from './request.js';
|
||||||
|
import { AuthorizationEvent, Callback } from './events.js';
|
||||||
|
|
||||||
|
export interface AccessTokenMessage {
|
||||||
|
create_at: number;
|
||||||
|
exp: number;
|
||||||
|
email: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
avatar_url: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginParams = {
|
||||||
|
type: 'Google' | 'Refresh';
|
||||||
|
token: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type LoginResponse = {
|
||||||
|
// access token, expires in a very short time
|
||||||
|
token: string;
|
||||||
|
// Refresh token
|
||||||
|
refresh: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const login = (params: LoginParams): Promise<LoginResponse> =>
|
||||||
|
bareClient.post('api/user/token', { json: params }).json();
|
||||||
|
|
||||||
|
function b64DecodeUnicode(str: string) {
|
||||||
|
// Going backwards: from byte stream, to percent-encoding, to original string.
|
||||||
|
return decodeURIComponent(
|
||||||
|
window
|
||||||
|
.atob(str)
|
||||||
|
.split('')
|
||||||
|
.map(function (c) {
|
||||||
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
})
|
||||||
|
.join('')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Token {
|
||||||
|
private readonly _event: AuthorizationEvent;
|
||||||
|
private _accessToken!: string;
|
||||||
|
private _refreshToken!: string;
|
||||||
|
|
||||||
|
private _user!: AccessTokenMessage | null;
|
||||||
|
private _padding?: Promise<LoginResponse>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._event = new AuthorizationEvent();
|
||||||
|
this._setToken(); // fill with default value
|
||||||
|
}
|
||||||
|
|
||||||
|
private _setToken(login?: LoginResponse) {
|
||||||
|
this._accessToken = login?.token || '';
|
||||||
|
this._refreshToken = login?.refresh || '';
|
||||||
|
|
||||||
|
this._user = Token.parse(this._accessToken);
|
||||||
|
this._event.triggerChange(this._user);
|
||||||
|
}
|
||||||
|
|
||||||
|
async initToken(token: string) {
|
||||||
|
this._setToken(await login({ token, type: 'Google' }));
|
||||||
|
}
|
||||||
|
|
||||||
|
async refreshToken(token?: string) {
|
||||||
|
if (!this._refreshToken && !token) {
|
||||||
|
throw new Error('No authorization token.');
|
||||||
|
}
|
||||||
|
if (!this._padding) {
|
||||||
|
this._padding = login({
|
||||||
|
type: 'Refresh',
|
||||||
|
token: this._refreshToken || token!,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this._setToken(await this._padding);
|
||||||
|
this._padding = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
get token() {
|
||||||
|
return this._accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
get refresh() {
|
||||||
|
return this._refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isLogin() {
|
||||||
|
return !!this._refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isExpired() {
|
||||||
|
if (!this._user) return true;
|
||||||
|
return Date.now() - this._user.create_at > this._user.exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static parse(token: string): AccessTokenMessage | null {
|
||||||
|
try {
|
||||||
|
const message: AccessTokenMessage = JSON.parse(
|
||||||
|
b64DecodeUnicode(token.split('.')[1])
|
||||||
|
);
|
||||||
|
return message;
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(callback: Callback) {
|
||||||
|
this._event.onChange(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
offChange(callback: Callback) {
|
||||||
|
this._event.removeCallback(callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const token = new Token();
|
||||||
@@ -16,6 +16,10 @@ export class BaseProvider {
|
|||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async destroy() {
|
||||||
|
// Nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
async initData() {
|
async initData() {
|
||||||
throw Error('Not implemented: initData');
|
throw Error('Not implemented: initData');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,5 @@
|
|||||||
|
export type { ConfigStore } from '../store';
|
||||||
|
|
||||||
export { BaseProvider } from './base.js';
|
export { BaseProvider } from './base.js';
|
||||||
|
export { AffineProvider } from './affine/index.js';
|
||||||
export { MemoryProvider } from './memory.js';
|
export { MemoryProvider } from './memory.js';
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const scopedIndexedDB = () => {
|
|||||||
return <T = any>(scope: string): Readonly<ConfigStore<T>> => {
|
return <T = any>(scope: string): Readonly<ConfigStore<T>> => {
|
||||||
if (!storeCache.has(scope)) {
|
if (!storeCache.has(scope)) {
|
||||||
const store = {
|
const store = {
|
||||||
get: (key: string) => idb.get(`${scope}:${key}`),
|
get: async (key: string) => idb.get(`${scope}:${key}`),
|
||||||
set: (key: string, value: T) => idb.set(`${scope}:${key}`, value),
|
set: (key: string, value: T) => idb.set(`${scope}:${key}`, value),
|
||||||
keys: () =>
|
keys: () =>
|
||||||
idb
|
idb
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ test('can init data center', async () => {
|
|||||||
const dataCenter = await getDataCenter();
|
const dataCenter = await getDataCenter();
|
||||||
expect(dataCenter).toBeTruthy();
|
expect(dataCenter).toBeTruthy();
|
||||||
|
|
||||||
dataCenter.setWorkspaceConfig('test', 'key', 'value');
|
|
||||||
|
|
||||||
const workspace = await dataCenter.initWorkspace('test');
|
const workspace = await dataCenter.initWorkspace('test');
|
||||||
|
|
||||||
expect(workspace).toBeTruthy();
|
expect(workspace).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -21,3 +18,14 @@ test('should init error', async () => {
|
|||||||
test.fail();
|
test.fail();
|
||||||
await dataCenter.initWorkspace('test', 'not exist provider');
|
await dataCenter.initWorkspace('test', 'not exist provider');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('can init affine provider', async () => {
|
||||||
|
const dataCenter = await getDataCenter();
|
||||||
|
|
||||||
|
// TODO: set constant token for testing
|
||||||
|
await dataCenter.setWorkspaceConfig('test', 'token', '');
|
||||||
|
|
||||||
|
const workspace = await dataCenter.initWorkspace('test', 'affine');
|
||||||
|
|
||||||
|
expect(workspace).toBeTruthy();
|
||||||
|
});
|
||||||
|
|||||||
91
pnpm-lock.yaml
generated
91
pnpm-lock.yaml
generated
@@ -138,17 +138,19 @@ importers:
|
|||||||
firebase: ^9.15.0
|
firebase: ^9.15.0
|
||||||
idb-keyval: ^6.2.0
|
idb-keyval: ^6.2.0
|
||||||
ky: ^0.33.0
|
ky: ^0.33.0
|
||||||
|
ky-universal: ^0.11.0
|
||||||
lib0: ^0.2.58
|
lib0: ^0.2.58
|
||||||
swr: ^2.0.0
|
swr: ^2.0.0
|
||||||
typescript: ^4.8.4
|
typescript: ^4.8.4
|
||||||
y-protocols: ^1.0.5
|
y-protocols: ^1.0.5
|
||||||
yjs: ^13.5.43
|
yjs: ^13.5.43
|
||||||
dependencies:
|
dependencies:
|
||||||
'@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.43
|
'@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44
|
||||||
encoding: 0.1.13
|
encoding: 0.1.13
|
||||||
firebase: 9.15.0_encoding@0.1.13
|
firebase: 9.15.0_encoding@0.1.13
|
||||||
idb-keyval: 6.2.0
|
idb-keyval: 6.2.0
|
||||||
ky: 0.33.1
|
ky: 0.33.1
|
||||||
|
ky-universal: 0.11.0_ky@0.33.1
|
||||||
lib0: 0.2.58
|
lib0: 0.2.58
|
||||||
swr: 2.0.0
|
swr: 2.0.0
|
||||||
y-protocols: 1.0.5
|
y-protocols: 1.0.5
|
||||||
@@ -1532,6 +1534,27 @@ packages:
|
|||||||
react: 18.2.0
|
react: 18.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@blocksuite/store/0.3.0-20221228162706-9576a3a_yjs@13.5.44:
|
||||||
|
resolution: {integrity: sha512-uMbLD+zfhHasDwCmE1ZTtFtK9GNwN37Iaugbj/rtdwhQbdE6qfKHidSY0UzwKtNrQaUdAmp2IpnBpQ0vgk0ArQ==}
|
||||||
|
peerDependencies:
|
||||||
|
yjs: ^13
|
||||||
|
dependencies:
|
||||||
|
'@types/flexsearch': 0.7.3
|
||||||
|
'@types/quill': 1.3.10
|
||||||
|
buffer: 6.0.3
|
||||||
|
flexsearch: 0.7.21
|
||||||
|
idb-keyval: 6.2.0
|
||||||
|
ky: 0.33.1
|
||||||
|
lib0: 0.2.58
|
||||||
|
y-protocols: 1.0.5
|
||||||
|
y-webrtc: 10.2.3
|
||||||
|
yjs: 13.5.44
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- supports-color
|
||||||
|
- utf-8-validate
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@blocksuite/store/0.3.1_yjs@13.5.44:
|
/@blocksuite/store/0.3.1_yjs@13.5.44:
|
||||||
resolution: {integrity: sha512-kynVTDfNCSChz2JI2rtGHxRIV2YrLzvAgVajcbfDVCuXKG0siBoEjLasG1a0kvevbvW/FabrNAj+xaIplklioA==}
|
resolution: {integrity: sha512-kynVTDfNCSChz2JI2rtGHxRIV2YrLzvAgVajcbfDVCuXKG0siBoEjLasG1a0kvevbvW/FabrNAj+xaIplklioA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -3927,6 +3950,13 @@ packages:
|
|||||||
eslint-visitor-keys: 3.3.0
|
eslint-visitor-keys: 3.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/abort-controller/3.0.0:
|
||||||
|
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||||
|
engines: {node: '>=6.5'}
|
||||||
|
dependencies:
|
||||||
|
event-target-shim: 5.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/acorn-jsx/5.3.2_acorn@8.8.0:
|
/acorn-jsx/5.3.2_acorn@8.8.0:
|
||||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -4710,6 +4740,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/data-uri-to-buffer/4.0.0:
|
||||||
|
resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==}
|
||||||
|
engines: {node: '>= 12'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/dayjs/1.11.7:
|
/dayjs/1.11.7:
|
||||||
resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==}
|
resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -5567,6 +5602,11 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/event-target-shim/5.0.1:
|
||||||
|
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/eventemitter3/2.0.3:
|
/eventemitter3/2.0.3:
|
||||||
resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==}
|
resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==}
|
||||||
dev: false
|
dev: false
|
||||||
@@ -5690,6 +5730,14 @@ packages:
|
|||||||
bser: 2.1.1
|
bser: 2.1.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fetch-blob/3.2.0:
|
||||||
|
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||||
|
engines: {node: ^12.20 || >= 14.13}
|
||||||
|
dependencies:
|
||||||
|
node-domexception: 1.0.0
|
||||||
|
web-streams-polyfill: 3.2.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/file-entry-cache/6.0.1:
|
/file-entry-cache/6.0.1:
|
||||||
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
|
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
@@ -5810,6 +5858,13 @@ packages:
|
|||||||
engines: {node: '>= 14.17'}
|
engines: {node: '>= 14.17'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/formdata-polyfill/4.0.10:
|
||||||
|
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||||
|
engines: {node: '>=12.20.0'}
|
||||||
|
dependencies:
|
||||||
|
fetch-blob: 3.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fs-extra/7.0.1:
|
/fs-extra/7.0.1:
|
||||||
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
|
resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
|
||||||
engines: {node: '>=6 <7 || >=8'}
|
engines: {node: '>=6 <7 || >=8'}
|
||||||
@@ -7037,6 +7092,21 @@ packages:
|
|||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/ky-universal/0.11.0_ky@0.33.1:
|
||||||
|
resolution: {integrity: sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==}
|
||||||
|
engines: {node: '>=14.16'}
|
||||||
|
peerDependencies:
|
||||||
|
ky: '>=0.31.4'
|
||||||
|
web-streams-polyfill: '>=3.2.1'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
web-streams-polyfill:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
abort-controller: 3.0.0
|
||||||
|
ky: 0.33.1
|
||||||
|
node-fetch: 3.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/ky/0.33.1:
|
/ky/0.33.1:
|
||||||
resolution: {integrity: sha512-zZ9OlhgM4UEunvgJBH1bBl7+a7vas1HnCLSezu2CJawc4Ka+yJculRAVKbakUece4gW7kC5Dz+UGvbXIlpDt1w==}
|
resolution: {integrity: sha512-zZ9OlhgM4UEunvgJBH1bBl7+a7vas1HnCLSezu2CJawc4Ka+yJculRAVKbakUece4gW7kC5Dz+UGvbXIlpDt1w==}
|
||||||
engines: {node: '>=14.16'}
|
engines: {node: '>=14.16'}
|
||||||
@@ -7545,6 +7615,11 @@ packages:
|
|||||||
- '@babel/core'
|
- '@babel/core'
|
||||||
- babel-plugin-macros
|
- babel-plugin-macros
|
||||||
|
|
||||||
|
/node-domexception/1.0.0:
|
||||||
|
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
|
||||||
|
engines: {node: '>=10.5.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/node-fetch/2.6.7_encoding@0.1.13:
|
/node-fetch/2.6.7_encoding@0.1.13:
|
||||||
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
|
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
|
||||||
engines: {node: 4.x || >=6.0.0}
|
engines: {node: 4.x || >=6.0.0}
|
||||||
@@ -7558,6 +7633,15 @@ packages:
|
|||||||
whatwg-url: 5.0.0
|
whatwg-url: 5.0.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/node-fetch/3.3.0:
|
||||||
|
resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==}
|
||||||
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
dependencies:
|
||||||
|
data-uri-to-buffer: 4.0.0
|
||||||
|
fetch-blob: 3.2.0
|
||||||
|
formdata-polyfill: 4.0.10
|
||||||
|
dev: false
|
||||||
|
|
||||||
/node-int64/0.4.0:
|
/node-int64/0.4.0:
|
||||||
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
|
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -9307,6 +9391,11 @@ packages:
|
|||||||
defaults: 1.0.4
|
defaults: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/web-streams-polyfill/3.2.1:
|
||||||
|
resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==}
|
||||||
|
engines: {node: '>= 8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/webidl-conversions/3.0.1:
|
/webidl-conversions/3.0.1:
|
||||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|||||||
Reference in New Issue
Block a user