fork refine

This commit is contained in:
Stefan Pejcic
2024-02-05 10:23:04 +01:00
parent 3fffde9a8f
commit 8496a83edb
3634 changed files with 715528 additions and 2 deletions

View File

@@ -0,0 +1,11 @@
node_modules
.DS_Store
test
jest.config.js
**/*.spec.ts
**/*.spec.tsx
**/*.test.ts
**/*.test.tsx
tsup.config.ts
tsconfig.test.json
tsconfig.declarations.json

View File

@@ -0,0 +1,86 @@
# @refinedev/devtools-shared
## 1.1.2
### Patch Changes
- [#5022](https://github.com/refinedev/refine/pull/5022) [`80513a4e42f`](https://github.com/refinedev/refine/commit/80513a4e42f8dda39e01157643594a9e4c32001b) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update README.md
- fix grammar errors.
- make all README.md files consistent.
- add code example code snippets.
## 1.1.1
### Patch Changes
- [#5022](https://github.com/refinedev/refine/pull/5022) [`80513a4e42f`](https://github.com/refinedev/refine/commit/80513a4e42f8dda39e01157643594a9e4c32001b) Thanks [@BatuhanW](https://github.com/BatuhanW)! - chore: update README.md
- fix grammar errors.
- make all README.md files consistent.
- add code example code snippets.
![refine devtools](https://github.com/refinedev/refine/assets/1110414/15ed6907-d0c8-4213-9024-2f6b0a09968f)
## 1.0.0
### Major Changes
- [#4960](https://github.com/refinedev/refine/pull/4960) [`d8e464fa2c4`](https://github.com/refinedev/refine/commit/d8e464fa2c461d0fd60050cf18247758ecdc42e3) Thanks [@aliemir](https://github.com/aliemir)! - Initial beta release of refine devtools.🎉
We're releasing refine devtools in beta. refine devtools is designed to help you debug and develop your refine apps. It will be a collection of features including monitoring queries and mutations, testing out inferencer generated codes, adding and updating refine packages from the UI and more. 🤯
## Usage
Install the dependencies using your package manager.
```bash
npm i @refinedev/devtools@next @refinedev/cli@next @refinedev/core@next
```
Add `<DevtoolsProvider />` and `<DevtoolsPanel />` components to your app:
You'll need to wrap your app with `<DevtoolsProvider />` component and add `<DevtoolsPanel />` component to your app to access the devtools UI.
```tsx
import { DevtoolsPanel, DevtoolsProvider } from "@refinedev/devtools";
const App = () => {
return (
<DevtoolsProvider>
<Refine
// ...
>
{/* ... */}
</Refine>
<DevtoolsPanel />
</DevtoolsProvider>
);
};
```
Then you're good to go 🙌, `<DevtoolsProvider />` will tell refine to connect to the devtools server and track your queries and mutations. `<DevtoolsPanel />` will render the devtools UI in your app.
note: Devtools only works in development mode and have no overhead on production builds. You don't need to do anything special to exclude DevTools from your bundle.
Devtools is integrated with `@refinedev/cli` and it will be started automatically in development mode if you have `@refinedev/devtools` installed.
If you want to start devtools manually or have a custom dev script, you can run `refine devtools` in your project directory or add the following scripts to your `package.json`:
```js
{
"scripts": {
// If you have not customized the start script.
"start": "refine dev", // The devtools server runs automatically; you don't need to do anything.
// If you have customized the start script.
"start": "my-custom-dev-script & refine devtools" // Run the devtools server manually.
// other scripts
}
}
```
If you don't have `@refinedev/cli` installed already, you can follow the [installation guide](https://refine.dev/docs/packages/documentation/cli/#how-to-add-to-an-existing-project) to add it to your project.
These commands will start the devtools server. If you want to access the devtools UI outside of your app without depending on the `<DevtoolsPanel />` component, you can go to `http://localhost:5001` in your browser. 🚀

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Refine Dev Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,37 @@
<div align="center" style="margin: 30px;">
<a href="https://refine.dev">
<img alt="refine logo" src="https://refine.ams3.cdn.digitaloceanspaces.com/readme/refine-readme-banner.png">
</a>
</div>
<br/>
<div align="center">refine is an open-source, headless React framework for developers building enterprise web applications.
It eliminates repetitive tasks in CRUD operations and provides industry-standard solutions for critical project components like **authentication**, **access control**, **routing**, **networking**, **state management**, and **i18n**.
</div>
<br/>
<div align="center">
<sub>Created by <a href="https://refine.dev">refine</a></sub>
</div>
## About
[refine](https://refine.dev/) is **headless by design**, offering unlimited styling and customization options. Moreover, refine ships with ready-made integrations for [Ant Design](https://ant.design/), [Material UI](https://mui.com/material-ui/getting-started/overview/), [Mantine](https://mantine.dev/), and [Chakra UI](https://chakra-ui.com/) for convenience.
refine has connectors for 15+ backend services, including REST API, [GraphQL](https://graphql.org/), and popular services like [Airtable](https://www.airtable.com/), [Strapi](https://strapi.io/), [Supabase](https://supabase.com/), [Firebase](https://firebase.google.com/), and [Directus](https://directus.io/)
[Refer to documentation for more info about refine&#8594](https://refine.dev/docs/)
[Step up to refine tutorials &#8594](https://refine.dev/docs/tutorial/introduction/index/)
## Documentation
This package is an internal package and a part of the `@refinedev/devtools` package.
For more detailed information an usage, refer to the [refine devtools documentation](https://refine.dev/docs/packages/devtools)
## Install
```
npm install @refinedev/devtools
```

View File

@@ -0,0 +1,15 @@
module.exports = {
preset: "ts-jest",
rootDir: "./",
displayName: "react-hook-form",
testPathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/dist/"],
testEnvironment: "jsdom",
transform: {
"^.+\\.tsx?$": [
"ts-jest",
{
tsconfig: "<rootDir>/tsconfig.test.json",
},
],
},
};

View File

@@ -0,0 +1,55 @@
{
"version": "1.1.2",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"private": false,
"sideEffects": false,
"files": [
"dist",
"src"
],
"engines": {
"node": ">=10"
},
"scripts": {
"start": "tsup --watch --format esm,cjs,iife --legacy-output",
"build": "tsup --format esm,cjs,iife --minify --legacy-output",
"test": "jest --passWithNoTests --runInBand",
"prepare": "npm run build"
},
"name": "@refinedev/devtools-shared",
"description": "refine devtools offers a set of features from monitoring to quickly prototyping a UI.",
"author": "refine",
"module": "dist/esm/index.js",
"dependencies": {
"@tanstack/react-query": "^4.10.1",
"error-stack-parser": "^2.1.4"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0",
"@types/react": "^17.0.0 || ^18.0.0",
"@types/react-dom": "^17.0.0 || ^18.0.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@esbuild-plugins/node-resolve": "^0.1.4",
"@types/jest": "^29.2.4",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"react-router-dom": "^6.8.1",
"ts-jest": "^29.0.3",
"tslib": "^2.3.1",
"tsup": "^6.7.0"
},
"repository": {
"type": "git",
"url": "https://github.com/refinedev/refine.git",
"directory": "packages/devtools"
},
"gitHead": "829f5a516f98c06f666d6be3e6e6099c75c07719",
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,89 @@
import React from "react";
import { DevtoolsEvent } from "./event-types";
import { send } from "./send";
import { receive } from "./receive";
type DevToolsContextValue = {
__devtools: boolean;
port: number;
url: string;
secure: boolean;
ws: WebSocket | null;
devtoolsUrl?: string;
};
export const DevToolsContext = React.createContext<DevToolsContextValue>({
__devtools: false,
port: 5002,
url: "localhost",
secure: false,
ws: null,
});
type Props = React.PropsWithChildren<
Partial<Pick<DevToolsContextValue, "port" | "__devtools">>
>;
export const DevToolsContextProvider: React.FC<Props> = ({
__devtools,
port,
children,
}) => {
const [values, setValues] = React.useState<DevToolsContextValue>({
__devtools: __devtools ?? false,
port: port ?? 5002,
url: "localhost",
secure: false,
ws: null,
});
const [ws, setWs] = React.useState<WebSocket | null>(null);
React.useEffect(() => {
const wsInstance = new WebSocket(
`${values.secure ? "wss" : "ws"}://localhost:${values.port}`,
);
const unsubscribe = receive(
wsInstance,
DevtoolsEvent.DEVTOOLS_HANDSHAKE,
(data) => {
setValues((v) => ({
...v,
devtoolsUrl: data.url,
}));
unsubscribe();
},
);
wsInstance.addEventListener("open", () => {
if (!values.__devtools) {
send(wsInstance, DevtoolsEvent.DEVTOOLS_INIT, {
url: window.location.origin,
});
}
});
setWs(wsInstance);
return () => {
unsubscribe();
wsInstance.close(1000, window.location.origin);
};
}, []);
const contextValues = React.useMemo<DevToolsContextValue>(
() => ({
...values,
ws,
}),
[values, ws],
);
return (
<DevToolsContext.Provider value={contextValues}>
{children}
</DevToolsContext.Provider>
);
};

View File

@@ -0,0 +1,71 @@
import {
Mutation,
MutationKey,
MutationStatus,
QueryKey,
QueryState,
QueryStatus,
} from "@tanstack/react-query";
import { TraceType } from "./trace";
export enum DevtoolsEvent {
RELOAD = "devtools:reload",
DEVTOOLS_INIT = "devtools:init",
DEVTOOLS_HANDSHAKE = "devtools:handshake",
DEVTOOLS_ALREADY_CONNECTED = "devtools:already-connected",
ACTIVITY = "devtools:send-activity",
DEVTOOLS_ACTIVITY_UPDATE = "devtools:activity-update",
DEVTOOLS_CONNECTED_APP = "devtools:connected-app",
DEVTOOLS_DISCONNECTED_APP = "devtools:disconnected-app",
DEVTOOLS_HIGHLIGHT_IN_MONITOR = "devtools:highlight-in-monitor",
DEVTOOLS_HIGHLIGHT_IN_MONITOR_ACTION = "devtools:highlight-in-monitor-action",
DEVTOOLS_LOGIN_SUCCESS = "devtools:login-success",
DEVTOOLS_RELOAD_AFTER_LOGIN = "devtools:reload-after-login",
}
type Timestamps = {
createdAt: number;
updatedAt: number;
};
type ActivityPayload =
| {
type: "mutation";
identifier: string;
key?: MutationKey;
status?: MutationStatus;
trace?: TraceType[];
state: Mutation<any, any, any, any>["state"];
variables?: Mutation<any, any, any, any>["state"]["variables"];
hookName: string;
resourcePath: string | null;
legacyKey: boolean;
}
| {
type: "query";
identifier: string;
key?: QueryKey;
status?: QueryStatus;
trace?: TraceType[];
state: QueryState<any, any>;
hookName: string;
resourcePath: string | null;
legacyKey: boolean;
};
export type DevtoolsEventPayloads = {
[DevtoolsEvent.RELOAD]: {};
[DevtoolsEvent.DEVTOOLS_INIT]: { url: string };
[DevtoolsEvent.DEVTOOLS_HANDSHAKE]: { url: string };
[DevtoolsEvent.DEVTOOLS_ALREADY_CONNECTED]: { url: string };
[DevtoolsEvent.ACTIVITY]: ActivityPayload;
[DevtoolsEvent.DEVTOOLS_ACTIVITY_UPDATE]: {
updatedActivities: (ActivityPayload & Timestamps)[];
};
[DevtoolsEvent.DEVTOOLS_CONNECTED_APP]: { url: string | null };
[DevtoolsEvent.DEVTOOLS_DISCONNECTED_APP]: {};
[DevtoolsEvent.DEVTOOLS_HIGHLIGHT_IN_MONITOR]: { name: string };
[DevtoolsEvent.DEVTOOLS_HIGHLIGHT_IN_MONITOR_ACTION]: { name: string };
[DevtoolsEvent.DEVTOOLS_LOGIN_SUCCESS]: {};
[DevtoolsEvent.DEVTOOLS_RELOAD_AFTER_LOGIN]: {};
};

View File

@@ -0,0 +1,12 @@
export type FeedSection = {
content: string;
// frontmatter
title: string;
featured?: boolean;
date: string;
author: string;
avatar: string;
cover?: string;
};
export type Feed = FeedSection[];

View File

@@ -0,0 +1,14 @@
export { DevtoolsEvent, DevtoolsEventPayloads } from "./event-types";
export { TraceType } from "./trace";
export { Feed, FeedSection } from "./feed";
export {
PackageType,
PackageLatestVersionType,
AvailablePackageType,
} from "./package";
export { RefineHook, Scopes, hooksByScope, scopes } from "./scopes";
export { DevToolsContextProvider, DevToolsContext } from "./context";
export { send } from "./send";
export { receive } from "./receive";

View File

@@ -0,0 +1,19 @@
export type PackageType = {
name: string;
currentVersion: string;
description?: string;
changelog?: string;
documentation?: string;
};
export type PackageLatestVersionType = {
name: string;
latestVersion: string;
};
export type AvailablePackageType = {
name: string;
description: string;
install: string;
usage: string;
};

View File

@@ -0,0 +1,22 @@
// receive ws message by adding a listener to the ws object
import { DevtoolsEvent, DevtoolsEventPayloads } from "./event-types";
export function receive<T extends DevtoolsEvent>(
ws: WebSocket,
event: T,
callback: (payload: DevtoolsEventPayloads[T]) => void,
) {
const listener = (e: MessageEvent) => {
const { event: receivedEvent, payload } = JSON.parse(e.data);
if (event === receivedEvent) {
callback(payload);
}
};
ws.addEventListener("message", listener);
return () => {
ws.removeEventListener("message", listener);
};
}

View File

@@ -0,0 +1,67 @@
export type RefineHook =
| "useCan"
| "useLog"
| "useLogList"
| "useCreate"
| "useCreateMany"
| "useCustom"
| "useCustomMutation"
| "useDelete"
| "useDeleteMany"
| "useInfiniteList"
| "useList"
| "useMany"
| "useOne"
| "useUpdate"
| "useUpdateMany"
| "useForgotPassword"
| "useGetIdentity"
| "useIsAuthenticated"
| "useLogin"
| "useLogout"
| "useOnError"
| "usePermissions"
| "useRegister"
| "useUpdatePassword";
export type Scopes = "data" | "audit-log" | "access-control" | "auth";
export const scopes: Record<RefineHook, Scopes> = {
useCan: "access-control",
useLog: "audit-log",
useLogList: "audit-log",
useCreate: "data",
useCreateMany: "data",
useCustom: "data",
useCustomMutation: "data",
useDelete: "data",
useDeleteMany: "data",
useInfiniteList: "data",
useList: "data",
useMany: "data",
useOne: "data",
useUpdate: "data",
useUpdateMany: "data",
useForgotPassword: "auth",
useGetIdentity: "auth",
useIsAuthenticated: "auth",
useLogin: "auth",
useLogout: "auth",
useOnError: "auth",
usePermissions: "auth",
useRegister: "auth",
useUpdatePassword: "auth",
};
export const hooksByScope = Object.entries(scopes).reduce(
(acc, [hook, scope]) => {
if (!acc[scope]) {
acc[scope] = [];
}
acc[scope].push(hook as RefineHook);
return acc;
},
{} as Record<Scopes, RefineHook[]>,
);

View File

@@ -0,0 +1,25 @@
import { DevtoolsEvent, DevtoolsEventPayloads } from "./event-types";
export async function send<T extends DevtoolsEvent>(
ws: WebSocket,
event: T,
payload: DevtoolsEventPayloads[T],
) {
// check if the socket is open
// if not, wait for it to open
if (ws.readyState !== ws.OPEN) {
await new Promise<void>((resolve) => {
const listener = () => {
ws.send(JSON.stringify({ event, payload }));
resolve();
ws.removeEventListener("open", listener);
};
ws.addEventListener("open", listener);
});
return;
} else {
ws.send(JSON.stringify({ event, payload }));
return;
}
}

View File

@@ -0,0 +1,8 @@
export type TraceType = {
file?: string;
line?: number;
column?: number;
function?: string;
isRefine: boolean;
packageName?: string;
};

View File

@@ -0,0 +1,22 @@
{
"extends": "./tsconfig.json",
"exclude": [
"node_modules",
"dist",
"test",
"../test/**/*",
"**/*.spec.ts",
"**/*.test.ts",
"**/*.spec.tsx",
"**/*.test.tsx"
],
"compilerOptions": {
"outDir": "dist",
"declarationDir": "dist",
"declaration": true,
"emitDeclarationOnly": true,
"noEmit": false,
"declarationMap": true,
"paths": {}
}
}

View File

@@ -0,0 +1,13 @@
{
"include": ["src", "types"],
"extends": "../../tsconfig.build.json",
"compilerOptions": {
"types": ["node", "jest", "@testing-library/jest-dom"],
"rootDir": "./src",
"baseUrl": ".",
"paths": {
"@test/*": ["test/*"],
"@test": ["test"]
}
}
}

View File

@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"include": ["test", "src"],
"compilerOptions": {
"rootDir": ".",
"types": ["node", "jest", "@testing-library/jest-dom"],
"typeRoots": ["../../node_modules/@types", "src"]
}
}

View File

@@ -0,0 +1,24 @@
import { defineConfig } from "tsup";
import { NodeResolvePlugin } from "@esbuild-plugins/node-resolve";
export default defineConfig({
entry: ["src/index.ts"],
splitting: false,
sourcemap: true,
clean: false,
platform: "browser",
esbuildPlugins: [
NodeResolvePlugin({
extensions: [".js", "ts", "tsx", "jsx"],
onResolved: (resolved) => {
if (resolved.includes("node_modules")) {
return {
external: true,
};
}
return resolved;
},
}),
],
onSuccess: "tsc --project tsconfig.declarations.json",
});