@echoxyz/sonar-react 0.0.3 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -1
- package/README.md +149 -0
- package/dist/index.cjs +116 -0
- package/dist/index.d.cts +30 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +87 -0
- package/package.json +10 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
# @echoxyz/sonar-react
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 95d0235: Include dist in build output for publishing
|
|
8
|
+
- Updated dependencies [95d0235]
|
|
9
|
+
- @echoxyz/sonar-core@0.1.1
|
|
10
|
+
|
|
11
|
+
## 0.1.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 41247e9: Initial implementation of core/react wrapper.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [41247e9]
|
|
20
|
+
- @echoxyz/sonar-core@0.1.0
|
|
21
|
+
|
|
3
22
|
## 0.0.3
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
6
25
|
|
|
7
26
|
- 52ddd3f: Initial commit (empty)
|
|
8
27
|
- Updated dependencies [52ddd3f]
|
|
9
|
-
|
|
28
|
+
- @echoxyz/sonar-core@0.0.3
|
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# @echoxyz/sonar-react
|
|
2
|
+
|
|
3
|
+
React provider and hooks for Echo’s Sonar APIs, built on `@echoxyz/sonar-core`.
|
|
4
|
+
|
|
5
|
+
- Framework/router agnostic (works with React Router, Next.js, etc.).
|
|
6
|
+
- Handles PKCE OAuth redirect flow and token storage for the browser.
|
|
7
|
+
- Exposes a ready-to-use API client bound to a single `saleUUID`.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add @echoxyz/sonar-react @echoxyz/sonar-core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Peer dependency: `react@>=18`.
|
|
16
|
+
|
|
17
|
+
## Quick start
|
|
18
|
+
|
|
19
|
+
1. Wrap your app with `SonarProvider`:
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { SonarProvider } from "@echoxyz/sonar-react";
|
|
23
|
+
|
|
24
|
+
export function AppRoot({ children }: { children: React.ReactNode }) {
|
|
25
|
+
return (
|
|
26
|
+
<SonarProvider
|
|
27
|
+
config={{
|
|
28
|
+
saleUUID: "<your-sale-uuid>",
|
|
29
|
+
clientUUID: "<your-oauth-client-id>",
|
|
30
|
+
redirectURI: window.location.origin + "/oauth/callback",
|
|
31
|
+
// Optional:
|
|
32
|
+
// apiURL: "https://api.echo.xyz",
|
|
33
|
+
// tokenStorageKey: "sonar:auth-token",
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
{children}
|
|
37
|
+
</SonarProvider>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
2. Trigger login with PKCE + redirect:
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { useSonarAuth } from "@echoxyz/sonar-react";
|
|
46
|
+
|
|
47
|
+
export function LoginButton() {
|
|
48
|
+
const { login, authenticated } = useSonarAuth();
|
|
49
|
+
if (authenticated()) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
return <button onClick={() => login()}>Sign in with Echo</button>;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
3. Complete OAuth on your callback route/page:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { useEffect } from "react";
|
|
60
|
+
import { useSonarAuth } from "@echoxyz/sonar-react";
|
|
61
|
+
|
|
62
|
+
export default function OAuthCallback() {
|
|
63
|
+
const { completeOAuth } = useSonarAuth();
|
|
64
|
+
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
const params = new URLSearchParams(window.location.search);
|
|
67
|
+
const code = params.get("code");
|
|
68
|
+
const state = params.get("state");
|
|
69
|
+
if (!code || !state) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
completeOAuth({ code, state }).catch((err) => {
|
|
73
|
+
console.error("OAuth completion failed", err);
|
|
74
|
+
});
|
|
75
|
+
}, [completeOAuth]);
|
|
76
|
+
|
|
77
|
+
return <p>Completing sign-in…</p>;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
4. Call APIs using the low-level client:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { useEffect } from "react";
|
|
85
|
+
import { useSonarAuth, useSonarClient } from "@echoxyz/sonar-react";
|
|
86
|
+
import { EntityType } from "@echoxyz/sonar-core";
|
|
87
|
+
|
|
88
|
+
export function Example() {
|
|
89
|
+
const { authenticated } = useSonarAuth();
|
|
90
|
+
const client = useSonarClient();
|
|
91
|
+
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
if (!authenticated()) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
(async () => {
|
|
98
|
+
const { Entities } = await client.listAvailableEntities({ saleUUID: "<your-sale-uuid>" });
|
|
99
|
+
if (Entities.length === 0) return;
|
|
100
|
+
|
|
101
|
+
const entity = Entities[0];
|
|
102
|
+
const pre = await client.prePurchaseCheck({
|
|
103
|
+
saleUUID: "<your-sale-uuid>",
|
|
104
|
+
entityUUID: entity.EntityUUID,
|
|
105
|
+
entityType: EntityType.USER,
|
|
106
|
+
walletAddress: "0x1234...abcd" as `0x${string}`,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (pre.ReadyToPurchase) {
|
|
110
|
+
const permit = await client.generatePurchasePermit({
|
|
111
|
+
saleUUID: "<your-sale-uuid>",
|
|
112
|
+
entityUUID: entity.EntityUUID,
|
|
113
|
+
entityType: EntityType.USER,
|
|
114
|
+
walletAddress: "0x1234...abcd" as `0x${string}`,
|
|
115
|
+
});
|
|
116
|
+
console.log(permit.Signature, permit.Permit);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const alloc = await client.fetchAllocation({
|
|
120
|
+
saleUUID: "<your-sale-uuid>",
|
|
121
|
+
walletAddress: "0x1234...abcd" as `0x${string}`,
|
|
122
|
+
});
|
|
123
|
+
console.log(alloc);
|
|
124
|
+
})();
|
|
125
|
+
}, [authenticated, client]);
|
|
126
|
+
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## API
|
|
132
|
+
|
|
133
|
+
- `SonarProvider`
|
|
134
|
+
- Props `config`:
|
|
135
|
+
- `saleUUID: string` (required) – Sale to scope API calls against.
|
|
136
|
+
- `clientUUID: string` (required) – Echo OAuth Client ID.
|
|
137
|
+
- `redirectURI: string` (required) – Your OAuth callback URI.
|
|
138
|
+
- `apiURL?: string` (default: `https://api.echo.xyz`) – API base URL.
|
|
139
|
+
- `tokenStorageKey?: string` (default: `sonar:auth-token`) – Browser storage key for the access token.
|
|
140
|
+
|
|
141
|
+
- `useSonarAuth()` → `{ authenticated, token?, login(), completeOAuth({ code, state }), logout() }`
|
|
142
|
+
|
|
143
|
+
- `useSonarClient()` → low-level `SonarClient` instance.
|
|
144
|
+
|
|
145
|
+
## Notes
|
|
146
|
+
|
|
147
|
+
- Tokens are not auto-refreshed. On expiry, call `logout()` and re-run the OAuth flow.
|
|
148
|
+
- This package doesn’t depend on a specific router. Use it in Next.js, React Router, or any custom setup.
|
|
149
|
+
- Wallet addresses are typed as template literals `0x${string}`.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.tsx
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
SonarProvider: () => SonarProvider,
|
|
24
|
+
useSonarAuth: () => useSonarAuth,
|
|
25
|
+
useSonarClient: () => useSonarClient
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
|
|
29
|
+
// src/react.tsx
|
|
30
|
+
var import_sonar_core = require("@echoxyz/sonar-core");
|
|
31
|
+
var import_react = require("react");
|
|
32
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
33
|
+
var AuthContext = (0, import_react.createContext)(void 0);
|
|
34
|
+
var ClientContext = (0, import_react.createContext)(void 0);
|
|
35
|
+
function SonarProvider({ children, config }) {
|
|
36
|
+
const client = (0, import_react.useMemo)(() => {
|
|
37
|
+
return (0, import_sonar_core.createClient)({
|
|
38
|
+
saleUUID: config.saleUUID,
|
|
39
|
+
apiURL: config.apiURL,
|
|
40
|
+
tokenKey: config.tokenStorageKey
|
|
41
|
+
});
|
|
42
|
+
}, [config.apiURL, config.saleUUID, config.tokenStorageKey]);
|
|
43
|
+
const login = (0, import_react.useCallback)(async () => {
|
|
44
|
+
const { codeVerifier, codeChallenge, state } = await (0, import_sonar_core.generatePKCEParams)();
|
|
45
|
+
if (typeof window === "undefined") {
|
|
46
|
+
throw new Error("window is not available for OAuth flow");
|
|
47
|
+
}
|
|
48
|
+
window.sessionStorage.setItem("sonar:oauth:state", state);
|
|
49
|
+
window.sessionStorage.setItem("sonar:oauth:verifier", codeVerifier);
|
|
50
|
+
const url = (0, import_sonar_core.buildAuthorizationUrl)({
|
|
51
|
+
saleUUID: config.saleUUID,
|
|
52
|
+
clientUUID: config.clientUUID,
|
|
53
|
+
redirectURI: config.redirectURI,
|
|
54
|
+
state,
|
|
55
|
+
codeChallenge,
|
|
56
|
+
frontendURL: config.frontendURL
|
|
57
|
+
});
|
|
58
|
+
window.location.href = url.toString();
|
|
59
|
+
}, [config.saleUUID, config.clientUUID, config.redirectURI, config.frontendURL]);
|
|
60
|
+
const completeOAuth = (0, import_react.useCallback)(
|
|
61
|
+
async ({ code, state }) => {
|
|
62
|
+
if (typeof window === "undefined") {
|
|
63
|
+
throw new Error("window is not available for OAuth verification");
|
|
64
|
+
}
|
|
65
|
+
const expectedState = window.sessionStorage.getItem("sonar:oauth:state");
|
|
66
|
+
const codeVerifier = window.sessionStorage.getItem("sonar:oauth:verifier");
|
|
67
|
+
if (state !== expectedState || !codeVerifier) {
|
|
68
|
+
throw new Error("Invalid OAuth state or missing verifier");
|
|
69
|
+
}
|
|
70
|
+
const { token } = await client.exchangeAuthorizationCode({
|
|
71
|
+
code,
|
|
72
|
+
codeVerifier,
|
|
73
|
+
redirectURI: config.redirectURI
|
|
74
|
+
});
|
|
75
|
+
client.setToken(token);
|
|
76
|
+
window.sessionStorage.removeItem("sonar:oauth:state");
|
|
77
|
+
window.sessionStorage.removeItem("sonar:oauth:verifier");
|
|
78
|
+
},
|
|
79
|
+
[client, config.redirectURI]
|
|
80
|
+
);
|
|
81
|
+
const logout = (0, import_react.useCallback)(() => {
|
|
82
|
+
client.clear();
|
|
83
|
+
}, []);
|
|
84
|
+
const authValue = (0, import_react.useMemo)(
|
|
85
|
+
() => ({
|
|
86
|
+
login,
|
|
87
|
+
logout,
|
|
88
|
+
authenticated: () => Boolean(client.getToken()),
|
|
89
|
+
token: client.getToken() ?? void 0,
|
|
90
|
+
completeOAuth
|
|
91
|
+
}),
|
|
92
|
+
[client, login, completeOAuth, logout]
|
|
93
|
+
);
|
|
94
|
+
const clientValue = (0, import_react.useMemo)(() => ({ client }), [client]);
|
|
95
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AuthContext.Provider, { value: authValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClientContext.Provider, { value: clientValue, children }) });
|
|
96
|
+
}
|
|
97
|
+
function useSonarAuth() {
|
|
98
|
+
const ctx = (0, import_react.useContext)(AuthContext);
|
|
99
|
+
if (!ctx) {
|
|
100
|
+
throw new Error("useSonarAuth must be used within a SonarProvider");
|
|
101
|
+
}
|
|
102
|
+
return ctx;
|
|
103
|
+
}
|
|
104
|
+
function useSonarClient() {
|
|
105
|
+
const ctx = (0, import_react.useContext)(ClientContext);
|
|
106
|
+
if (!ctx) {
|
|
107
|
+
throw new Error("useSonarClient must be used within a SonarProvider");
|
|
108
|
+
}
|
|
109
|
+
return ctx.client;
|
|
110
|
+
}
|
|
111
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
112
|
+
0 && (module.exports = {
|
|
113
|
+
SonarProvider,
|
|
114
|
+
useSonarAuth,
|
|
115
|
+
useSonarClient
|
|
116
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { SonarClient } from '@echoxyz/sonar-core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
type SonarProviderProps = {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
config: {
|
|
8
|
+
saleUUID: string;
|
|
9
|
+
clientUUID: string;
|
|
10
|
+
redirectURI: string;
|
|
11
|
+
apiURL?: string;
|
|
12
|
+
frontendURL?: string;
|
|
13
|
+
tokenStorageKey?: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
type AuthContextValue = {
|
|
17
|
+
authenticated: () => boolean;
|
|
18
|
+
token?: string;
|
|
19
|
+
login: () => Promise<void>;
|
|
20
|
+
completeOAuth: (args: {
|
|
21
|
+
code: string;
|
|
22
|
+
state: string;
|
|
23
|
+
}) => Promise<void>;
|
|
24
|
+
logout: () => void;
|
|
25
|
+
};
|
|
26
|
+
declare function SonarProvider({ children, config }: SonarProviderProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function useSonarAuth(): AuthContextValue;
|
|
28
|
+
declare function useSonarClient(): SonarClient;
|
|
29
|
+
|
|
30
|
+
export { SonarProvider, useSonarAuth, useSonarClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { SonarClient } from '@echoxyz/sonar-core';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
type SonarProviderProps = {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
config: {
|
|
8
|
+
saleUUID: string;
|
|
9
|
+
clientUUID: string;
|
|
10
|
+
redirectURI: string;
|
|
11
|
+
apiURL?: string;
|
|
12
|
+
frontendURL?: string;
|
|
13
|
+
tokenStorageKey?: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
type AuthContextValue = {
|
|
17
|
+
authenticated: () => boolean;
|
|
18
|
+
token?: string;
|
|
19
|
+
login: () => Promise<void>;
|
|
20
|
+
completeOAuth: (args: {
|
|
21
|
+
code: string;
|
|
22
|
+
state: string;
|
|
23
|
+
}) => Promise<void>;
|
|
24
|
+
logout: () => void;
|
|
25
|
+
};
|
|
26
|
+
declare function SonarProvider({ children, config }: SonarProviderProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function useSonarAuth(): AuthContextValue;
|
|
28
|
+
declare function useSonarClient(): SonarClient;
|
|
29
|
+
|
|
30
|
+
export { SonarProvider, useSonarAuth, useSonarClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/react.tsx
|
|
2
|
+
import { buildAuthorizationUrl, createClient, generatePKCEParams } from "@echoxyz/sonar-core";
|
|
3
|
+
import { createContext, useCallback, useContext, useMemo } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
var AuthContext = createContext(void 0);
|
|
6
|
+
var ClientContext = createContext(void 0);
|
|
7
|
+
function SonarProvider({ children, config }) {
|
|
8
|
+
const client = useMemo(() => {
|
|
9
|
+
return createClient({
|
|
10
|
+
saleUUID: config.saleUUID,
|
|
11
|
+
apiURL: config.apiURL,
|
|
12
|
+
tokenKey: config.tokenStorageKey
|
|
13
|
+
});
|
|
14
|
+
}, [config.apiURL, config.saleUUID, config.tokenStorageKey]);
|
|
15
|
+
const login = useCallback(async () => {
|
|
16
|
+
const { codeVerifier, codeChallenge, state } = await generatePKCEParams();
|
|
17
|
+
if (typeof window === "undefined") {
|
|
18
|
+
throw new Error("window is not available for OAuth flow");
|
|
19
|
+
}
|
|
20
|
+
window.sessionStorage.setItem("sonar:oauth:state", state);
|
|
21
|
+
window.sessionStorage.setItem("sonar:oauth:verifier", codeVerifier);
|
|
22
|
+
const url = buildAuthorizationUrl({
|
|
23
|
+
saleUUID: config.saleUUID,
|
|
24
|
+
clientUUID: config.clientUUID,
|
|
25
|
+
redirectURI: config.redirectURI,
|
|
26
|
+
state,
|
|
27
|
+
codeChallenge,
|
|
28
|
+
frontendURL: config.frontendURL
|
|
29
|
+
});
|
|
30
|
+
window.location.href = url.toString();
|
|
31
|
+
}, [config.saleUUID, config.clientUUID, config.redirectURI, config.frontendURL]);
|
|
32
|
+
const completeOAuth = useCallback(
|
|
33
|
+
async ({ code, state }) => {
|
|
34
|
+
if (typeof window === "undefined") {
|
|
35
|
+
throw new Error("window is not available for OAuth verification");
|
|
36
|
+
}
|
|
37
|
+
const expectedState = window.sessionStorage.getItem("sonar:oauth:state");
|
|
38
|
+
const codeVerifier = window.sessionStorage.getItem("sonar:oauth:verifier");
|
|
39
|
+
if (state !== expectedState || !codeVerifier) {
|
|
40
|
+
throw new Error("Invalid OAuth state or missing verifier");
|
|
41
|
+
}
|
|
42
|
+
const { token } = await client.exchangeAuthorizationCode({
|
|
43
|
+
code,
|
|
44
|
+
codeVerifier,
|
|
45
|
+
redirectURI: config.redirectURI
|
|
46
|
+
});
|
|
47
|
+
client.setToken(token);
|
|
48
|
+
window.sessionStorage.removeItem("sonar:oauth:state");
|
|
49
|
+
window.sessionStorage.removeItem("sonar:oauth:verifier");
|
|
50
|
+
},
|
|
51
|
+
[client, config.redirectURI]
|
|
52
|
+
);
|
|
53
|
+
const logout = useCallback(() => {
|
|
54
|
+
client.clear();
|
|
55
|
+
}, []);
|
|
56
|
+
const authValue = useMemo(
|
|
57
|
+
() => ({
|
|
58
|
+
login,
|
|
59
|
+
logout,
|
|
60
|
+
authenticated: () => Boolean(client.getToken()),
|
|
61
|
+
token: client.getToken() ?? void 0,
|
|
62
|
+
completeOAuth
|
|
63
|
+
}),
|
|
64
|
+
[client, login, completeOAuth, logout]
|
|
65
|
+
);
|
|
66
|
+
const clientValue = useMemo(() => ({ client }), [client]);
|
|
67
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value: authValue, children: /* @__PURE__ */ jsx(ClientContext.Provider, { value: clientValue, children }) });
|
|
68
|
+
}
|
|
69
|
+
function useSonarAuth() {
|
|
70
|
+
const ctx = useContext(AuthContext);
|
|
71
|
+
if (!ctx) {
|
|
72
|
+
throw new Error("useSonarAuth must be used within a SonarProvider");
|
|
73
|
+
}
|
|
74
|
+
return ctx;
|
|
75
|
+
}
|
|
76
|
+
function useSonarClient() {
|
|
77
|
+
const ctx = useContext(ClientContext);
|
|
78
|
+
if (!ctx) {
|
|
79
|
+
throw new Error("useSonarClient must be used within a SonarProvider");
|
|
80
|
+
}
|
|
81
|
+
return ctx.client;
|
|
82
|
+
}
|
|
83
|
+
export {
|
|
84
|
+
SonarProvider,
|
|
85
|
+
useSonarAuth,
|
|
86
|
+
useSonarClient
|
|
87
|
+
};
|
package/package.json
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@echoxyz/sonar-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
|
-
"module": "./dist/index.
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
16
|
"react": ">=18"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@echoxyz/sonar-core": "0.
|
|
19
|
+
"@echoxyz/sonar-core": "0.1.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"tsup": "^8.0.0",
|
|
23
|
-
"vitest": "^2.0.0"
|
|
23
|
+
"vitest": "^2.0.0",
|
|
24
|
+
"@types/react": "^18"
|
|
24
25
|
},
|
|
25
26
|
"repository": {
|
|
26
27
|
"type": "git",
|
|
@@ -36,8 +37,8 @@
|
|
|
36
37
|
"package.json"
|
|
37
38
|
],
|
|
38
39
|
"scripts": {
|
|
39
|
-
"build": "tsup src/index.
|
|
40
|
-
"dev": "tsup src/index.
|
|
40
|
+
"build": "tsup src/index.tsx --format esm,cjs --dts",
|
|
41
|
+
"dev": "tsup src/index.tsx --format esm,cjs --dts --watch",
|
|
41
42
|
"test": "vitest run"
|
|
42
43
|
}
|
|
43
44
|
}
|