feat: git mod - package details and redux slice (#36989)
## Description Introduces a new yarn package for git. Includes the yarn package files, redux slice and relevant redux actions Fixes #36808 Fixes #36809 Fixes #36810 This is not integrated into the monolith. So, this doesn't directly impact the product yet ## Automation /ok-to-test tags="@tag.Git" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/11478975801> > Commit: 02c38bff6be96f3572100f348f12c15ea94ae971 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11478975801&attempt=2" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Git` > Spec: > <hr>Wed, 23 Oct 2024 19:42:30 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes - **New Features** - Introduced the `@appsmith/git` package for Git-related functionality. - Added a new `GitTest` component for testing purposes. - Implemented multiple actions for managing Git operations, including commit, connection, branch fetching, metadata fetching, status fetching, and pull actions. - Created a Redux slice for managing Git artifact state. - **Documentation** - Added TypeScript types and interfaces for better state management within the Git context. - Introduced ESLint configuration for consistent code quality across the package. These updates enhance the application's Git capabilities and improve state management, providing a more robust user experience. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
d99789c401
commit
2099fceffa
3
app/client/packages/git/.eslintrc.json
Normal file
3
app/client/packages/git/.eslintrc.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": ["../../.eslintrc.base.json"]
|
||||
}
|
||||
15
app/client/packages/git/package.json
Normal file
15
app/client/packages/git/package.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"name": "@appsmith/git",
|
||||
"description": "This package contains all the git related functionality for Appsmith UI",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"lint": "yarn g:lint",
|
||||
"prettier": "yarn g:prettier",
|
||||
"test:unit": "yarn g:jest --passWithNoTests"
|
||||
},
|
||||
"dependencies": {
|
||||
"@reduxjs/toolkit": "^2.3.0"
|
||||
}
|
||||
}
|
||||
26
app/client/packages/git/src/actions/commitActions.ts
Normal file
26
app/client/packages/git/src/actions/commitActions.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { createSingleArtifactAction } from "./helpers/createSingleArtifactAction";
|
||||
import type { GitArtifactPayloadAction } from "../types";
|
||||
|
||||
export const commitInitAction = createSingleArtifactAction((state) => {
|
||||
state.commit.loading = true;
|
||||
state.commit.error = null;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const commitSuccessAction = createSingleArtifactAction((state) => {
|
||||
state.commit.loading = false;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const commitErrorAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ error: string }>) => {
|
||||
const { error } = action.payload;
|
||||
|
||||
state.commit.loading = false;
|
||||
state.commit.error = error;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
26
app/client/packages/git/src/actions/connectActions.ts
Normal file
26
app/client/packages/git/src/actions/connectActions.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { createSingleArtifactAction } from "./helpers/createSingleArtifactAction";
|
||||
import type { GitArtifactPayloadAction } from "../types";
|
||||
|
||||
export const connectInitAction = createSingleArtifactAction((state) => {
|
||||
state.connect.loading = true;
|
||||
state.connect.error = null;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const connectSuccessAction = createSingleArtifactAction((state) => {
|
||||
state.connect.loading = false;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const connectErrorAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ error: string }>) => {
|
||||
const { error } = action.payload;
|
||||
|
||||
state.connect.loading = false;
|
||||
state.connect.error = error;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
29
app/client/packages/git/src/actions/fetchBranchesActions.ts
Normal file
29
app/client/packages/git/src/actions/fetchBranchesActions.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import type { GitArtifactPayloadAction, GitBranches } from "../types";
|
||||
import { createSingleArtifactAction } from "./helpers/createSingleArtifactAction";
|
||||
|
||||
export const fetchBranchesInitAction = createSingleArtifactAction((state) => {
|
||||
state.branches.loading = true;
|
||||
state.branches.error = null;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const fetchBranchesSuccessAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ branches: GitBranches }>) => {
|
||||
state.branches.loading = false;
|
||||
state.branches.value = action.payload.branches;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
|
||||
export const fetchBranchesErrorAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ error: string }>) => {
|
||||
const { error } = action.payload;
|
||||
|
||||
state.branches.loading = false;
|
||||
state.branches.error = error;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
29
app/client/packages/git/src/actions/fetchMetadataActions.ts
Normal file
29
app/client/packages/git/src/actions/fetchMetadataActions.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import type { GitArtifactPayloadAction, GitMetadata } from "../types";
|
||||
import { createSingleArtifactAction } from "./helpers/createSingleArtifactAction";
|
||||
|
||||
export const fetchMetadataInitAction = createSingleArtifactAction((state) => {
|
||||
state.metadata.loading = true;
|
||||
state.metadata.error = null;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const fetchMetadataSuccessAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ metadata: GitMetadata }>) => {
|
||||
state.metadata.loading = false;
|
||||
state.metadata.value = action.payload.metadata;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
|
||||
export const fetchMetadataErrorAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ error: string }>) => {
|
||||
const { error } = action.payload;
|
||||
|
||||
state.metadata.loading = false;
|
||||
state.metadata.error = error;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
29
app/client/packages/git/src/actions/fetchStatusActions.ts
Normal file
29
app/client/packages/git/src/actions/fetchStatusActions.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import type { GitArtifactPayloadAction, GitStatus } from "../types";
|
||||
import { createSingleArtifactAction } from "./helpers/createSingleArtifactAction";
|
||||
|
||||
export const fetchStatusInitAction = createSingleArtifactAction((state) => {
|
||||
state.status.loading = true;
|
||||
state.status.error = null;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const fetchStatusSuccessAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ status: GitStatus }>) => {
|
||||
state.status.loading = false;
|
||||
state.status.value = action.payload.status;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
|
||||
export const fetchStatusErrorAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ error: string }>) => {
|
||||
const { error } = action.payload;
|
||||
|
||||
state.status.loading = false;
|
||||
state.status.error = error;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import type {
|
||||
GitArtifactPayloadAction,
|
||||
GitArtifactReduxState,
|
||||
GitSingleArtifactReduxState,
|
||||
} from "../../types";
|
||||
|
||||
type SingleArtifactStateCb<T> = (
|
||||
singleArtifactState: GitSingleArtifactReduxState,
|
||||
action: GitArtifactPayloadAction<T>,
|
||||
) => GitSingleArtifactReduxState;
|
||||
|
||||
export const gitSingleArtifactInitialState: GitSingleArtifactReduxState = {
|
||||
metadata: {
|
||||
value: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
},
|
||||
connect: {
|
||||
loading: false,
|
||||
error: null,
|
||||
},
|
||||
branches: {
|
||||
value: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
},
|
||||
status: {
|
||||
value: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
},
|
||||
commit: {
|
||||
loading: false,
|
||||
error: null,
|
||||
},
|
||||
pull: {
|
||||
loading: false,
|
||||
error: null,
|
||||
},
|
||||
};
|
||||
|
||||
export const createSingleArtifactAction = <T>(
|
||||
singleArtifactStateCb: SingleArtifactStateCb<T>,
|
||||
) => {
|
||||
return (
|
||||
state: GitArtifactReduxState,
|
||||
action: GitArtifactPayloadAction<T>,
|
||||
) => {
|
||||
const { artifactType, baseArtifactId } = action.payload;
|
||||
|
||||
state[artifactType] ??= {};
|
||||
state[artifactType][baseArtifactId] ??= gitSingleArtifactInitialState;
|
||||
|
||||
const singleArtifactState = state[artifactType][baseArtifactId];
|
||||
|
||||
state[artifactType][baseArtifactId] = singleArtifactStateCb(
|
||||
singleArtifactState,
|
||||
action,
|
||||
);
|
||||
|
||||
return state;
|
||||
};
|
||||
};
|
||||
28
app/client/packages/git/src/actions/mountActions.ts
Normal file
28
app/client/packages/git/src/actions/mountActions.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import type { PayloadAction } from "@reduxjs/toolkit";
|
||||
import type { GitArtifactBasePayload, GitArtifactReduxState } from "../types";
|
||||
import { gitSingleArtifactInitialState } from "./helpers/createSingleArtifactAction";
|
||||
|
||||
// ! This might be removed later
|
||||
|
||||
export const mountAction = (
|
||||
state: GitArtifactReduxState,
|
||||
action: PayloadAction<GitArtifactBasePayload>,
|
||||
) => {
|
||||
const { artifactType, baseArtifactId } = action.payload;
|
||||
|
||||
state[artifactType] ??= {};
|
||||
state[artifactType][baseArtifactId] ??= gitSingleArtifactInitialState;
|
||||
|
||||
return state;
|
||||
};
|
||||
|
||||
export const unmountAction = (
|
||||
state: GitArtifactReduxState,
|
||||
action: PayloadAction<GitArtifactBasePayload>,
|
||||
) => {
|
||||
const { artifactType, baseArtifactId } = action.payload;
|
||||
|
||||
delete state?.[artifactType]?.[baseArtifactId];
|
||||
|
||||
return state;
|
||||
};
|
||||
26
app/client/packages/git/src/actions/pullActions.ts
Normal file
26
app/client/packages/git/src/actions/pullActions.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { createSingleArtifactAction } from "./helpers/createSingleArtifactAction";
|
||||
import type { GitArtifactPayloadAction } from "../types";
|
||||
|
||||
export const pullInitAction = createSingleArtifactAction((state) => {
|
||||
state.pull.loading = true;
|
||||
state.pull.error = null;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const pullSuccessAction = createSingleArtifactAction((state) => {
|
||||
state.pull.loading = false;
|
||||
|
||||
return state;
|
||||
});
|
||||
|
||||
export const pullErrorAction = createSingleArtifactAction(
|
||||
(state, action: GitArtifactPayloadAction<{ error: string }>) => {
|
||||
const { error } = action.payload;
|
||||
|
||||
state.pull.loading = false;
|
||||
state.pull.error = error;
|
||||
|
||||
return state;
|
||||
},
|
||||
);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import React from "react";
|
||||
|
||||
function GitTest() {
|
||||
return <div>GitTest</div>;
|
||||
}
|
||||
|
||||
export default GitTest;
|
||||
67
app/client/packages/git/src/store/gitArtifactSlice.ts
Normal file
67
app/client/packages/git/src/store/gitArtifactSlice.ts
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* eslint-disable padding-line-between-statements */
|
||||
import { createSlice } from "@reduxjs/toolkit";
|
||||
import type { GitArtifactReduxState } from "../types";
|
||||
import { mountAction, unmountAction } from "../actions/mountActions";
|
||||
import {
|
||||
connectErrorAction,
|
||||
connectInitAction,
|
||||
connectSuccessAction,
|
||||
} from "../actions/connectActions";
|
||||
import {
|
||||
fetchMetadataErrorAction,
|
||||
fetchMetadataInitAction,
|
||||
fetchMetadataSuccessAction,
|
||||
} from "../actions/fetchMetadataActions";
|
||||
import {
|
||||
fetchBranchesErrorAction,
|
||||
fetchBranchesInitAction,
|
||||
fetchBranchesSuccessAction,
|
||||
} from "../actions/fetchBranchesActions";
|
||||
import {
|
||||
fetchStatusErrorAction,
|
||||
fetchStatusInitAction,
|
||||
fetchStatusSuccessAction,
|
||||
} from "../actions/fetchStatusActions";
|
||||
import {
|
||||
commitErrorAction,
|
||||
commitInitAction,
|
||||
commitSuccessAction,
|
||||
} from "../actions/commitActions";
|
||||
import {
|
||||
pullErrorAction,
|
||||
pullInitAction,
|
||||
pullSuccessAction,
|
||||
} from "../actions/pullActions";
|
||||
|
||||
const initialState: GitArtifactReduxState = {};
|
||||
|
||||
export const gitArtifactSlice = createSlice({
|
||||
name: "gitArtifact",
|
||||
initialState,
|
||||
reducers: {
|
||||
mount: mountAction,
|
||||
unmount: unmountAction,
|
||||
connectInit: connectInitAction,
|
||||
connectSuccess: connectSuccessAction,
|
||||
connectError: connectErrorAction,
|
||||
fetchMetadataInit: fetchMetadataInitAction,
|
||||
fetchMetadataSuccess: fetchMetadataSuccessAction,
|
||||
fetchMetadataError: fetchMetadataErrorAction,
|
||||
fetchBranchesInit: fetchBranchesInitAction,
|
||||
fetchBranchesSuccess: fetchBranchesSuccessAction,
|
||||
fetchBranchesError: fetchBranchesErrorAction,
|
||||
fetchStatusInit: fetchStatusInitAction,
|
||||
fetchStatusSuccess: fetchStatusSuccessAction,
|
||||
fetchStatusError: fetchStatusErrorAction,
|
||||
commitInit: commitInitAction,
|
||||
commitSuccess: commitSuccessAction,
|
||||
commitError: commitErrorAction,
|
||||
pullInit: pullInitAction,
|
||||
pullSuccess: pullSuccessAction,
|
||||
pullError: pullErrorAction,
|
||||
},
|
||||
});
|
||||
|
||||
export const gitArtifactActions = gitArtifactSlice.actions;
|
||||
|
||||
export default gitArtifactSlice.reducer;
|
||||
0
app/client/packages/git/src/store/index.ts
Normal file
0
app/client/packages/git/src/store/index.ts
Normal file
35
app/client/packages/git/src/types.ts
Normal file
35
app/client/packages/git/src/types.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import type { PayloadAction } from "@reduxjs/toolkit";
|
||||
|
||||
// These will be updated when contracts are finalized
|
||||
export type GitMetadata = Record<string, unknown>;
|
||||
|
||||
export type GitBranches = Record<string, unknown>;
|
||||
|
||||
export type GitStatus = Record<string, unknown>;
|
||||
|
||||
interface AsyncState<T = unknown> {
|
||||
value: T | null;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
export interface GitSingleArtifactReduxState {
|
||||
metadata: AsyncState<GitMetadata>;
|
||||
connect: Omit<AsyncState, "value">;
|
||||
branches: AsyncState<GitBranches>;
|
||||
status: AsyncState<GitStatus>;
|
||||
commit: Omit<AsyncState, "value">;
|
||||
pull: Omit<AsyncState, "value">;
|
||||
}
|
||||
|
||||
export interface GitArtifactReduxState {
|
||||
[key: string]: Record<string, GitSingleArtifactReduxState>;
|
||||
}
|
||||
|
||||
export interface GitArtifactBasePayload {
|
||||
artifactType: string;
|
||||
baseArtifactId: string;
|
||||
}
|
||||
|
||||
export type GitArtifactPayloadAction<T = Record<string, unknown>> =
|
||||
PayloadAction<GitArtifactBasePayload & T>;
|
||||
4
app/client/packages/git/tsconfig.json
Normal file
4
app/client/packages/git/tsconfig.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["./src/**/*"]
|
||||
}
|
||||
|
|
@ -192,6 +192,14 @@ __metadata:
|
|||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@appsmith/git@workspace:packages/git":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@appsmith/git@workspace:packages/git"
|
||||
dependencies:
|
||||
"@reduxjs/toolkit": ^2.3.0
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@appsmith/utils@workspace:^, @appsmith/utils@workspace:packages/utils":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@appsmith/utils@workspace:packages/utils"
|
||||
|
|
@ -8011,6 +8019,26 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@reduxjs/toolkit@npm:^2.3.0":
|
||||
version: 2.3.0
|
||||
resolution: "@reduxjs/toolkit@npm:2.3.0"
|
||||
dependencies:
|
||||
immer: ^10.0.3
|
||||
redux: ^5.0.1
|
||||
redux-thunk: ^3.1.0
|
||||
reselect: ^5.1.0
|
||||
peerDependencies:
|
||||
react: ^16.9.0 || ^17.0.0 || ^18
|
||||
react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-redux:
|
||||
optional: true
|
||||
checksum: 1a0d85978f99a44f7ceabec8623f46cdd2a2dc25d809dfb0d5c9cd13e2aa12cf116cffe34a4ed949169804dc6125ef9cf68143225e9527f861b597ea701e8bb5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@rollup/plugin-babel@npm:^5.2.0":
|
||||
version: 5.3.1
|
||||
resolution: "@rollup/plugin-babel@npm:5.3.1"
|
||||
|
|
@ -20770,10 +20798,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"immer@npm:^10.0.3":
|
||||
version: 10.1.1
|
||||
resolution: "immer@npm:10.1.1"
|
||||
checksum: 07c67970b7d22aded73607193d84861bf786f07d47f7d7c98bb10016c7a88f6654ad78ae1e220b3c623695b133aabbf24f5eb8d9e8060cff11e89ccd81c9c10b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"immer@npm:^9.0.6, immer@npm:^9.0.7":
|
||||
version: 9.0.14
|
||||
resolution: "immer@npm:9.0.14"
|
||||
checksum: 17f1365c06d653e672a4f609f08e7203e9ab4b4284818332d6ca9b3f3577a0e3c0066ca7933b636fbae560df79a4b3fde70ed717ce3c6e95c39bf3d5861d5be9
|
||||
version: 9.0.21
|
||||
resolution: "immer@npm:9.0.21"
|
||||
checksum: 70e3c274165995352f6936695f0ef4723c52c92c92dd0e9afdfe008175af39fa28e76aafb3a2ca9d57d1fb8f796efc4dd1e1cc36f18d33fa5b74f3dfb0375432
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
@ -29630,6 +29665,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redux-thunk@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "redux-thunk@npm:3.1.0"
|
||||
peerDependencies:
|
||||
redux: ^5.0.0
|
||||
checksum: bea96f8233975aad4c9f24ca1ffd08ac7ec91eaefc26e7ba9935544dc55d7f09ba2aa726676dab53dc79d0c91e8071f9729cddfea927f4c41839757d2ade0f50
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redux@npm:^3.6.0 || ^4.0.0, redux@npm:^4.0.0, redux@npm:^4.0.1, redux@npm:^4.0.4, redux@npm:^4.0.5":
|
||||
version: 4.0.5
|
||||
resolution: "redux@npm:4.0.5"
|
||||
|
|
@ -29640,6 +29684,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redux@npm:^5.0.1":
|
||||
version: 5.0.1
|
||||
resolution: "redux@npm:5.0.1"
|
||||
checksum: e74affa9009dd5d994878b9a1ce30d6569d986117175056edb003de2651c05b10fe7819d6fa94aea1a94de9a82f252f986547f007a2fbeb35c317a2e5f5ecf2c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reflect.getprototypeof@npm:^1.0.4":
|
||||
version: 1.0.4
|
||||
resolution: "reflect.getprototypeof@npm:1.0.4"
|
||||
|
|
@ -29931,6 +29982,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"reselect@npm:^5.1.0":
|
||||
version: 5.1.1
|
||||
resolution: "reselect@npm:5.1.1"
|
||||
checksum: 5d32d48be29071ddda21a775945c2210cf4ca3fccde1c4a0e1582ac3bf99c431c6c2330ef7ca34eae4c06feea617e7cb2c275c4b33ccf9a930836dfc98b49b13
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"resize-observer-polyfill@npm:^1.5.0, resize-observer-polyfill@npm:^1.5.1":
|
||||
version: 1.5.1
|
||||
resolution: "resize-observer-polyfill@npm:1.5.1"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user