@echoxyz/sonar-react 0.1.0 → 0.1.2
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 +16 -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 +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @echoxyz/sonar-react
|
|
2
2
|
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4907b74: Remove unused dependency
|
|
8
|
+
- Updated dependencies [4907b74]
|
|
9
|
+
- @echoxyz/sonar-core@0.1.2
|
|
10
|
+
|
|
11
|
+
## 0.1.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 95d0235: Include dist in build output for publishing
|
|
16
|
+
- Updated dependencies [95d0235]
|
|
17
|
+
- @echoxyz/sonar-core@0.1.1
|
|
18
|
+
|
|
3
19
|
## 0.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@echoxyz/sonar-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"react": ">=18"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@echoxyz/sonar-core": "0.1.
|
|
19
|
+
"@echoxyz/sonar-core": "0.1.2"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"tsup": "^8.0.0",
|