featuretoggle-sdk-react 1.0.0
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/README.md +43 -0
- package/dist/index.cjs +166 -0
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +147 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# featuretoggle-sdk-react
|
|
2
|
+
|
|
3
|
+
React adapter for [featuretoggle-sdk-typescript](https://www.npmjs.com/package/featuretoggle-sdk-typescript) — `FeatureToggleProvider`, `useFeature`, and `useFeatureToggle`.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add featuretoggle-sdk-react featuretoggle-sdk-typescript react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Peers: `react` (≥18), `featuretoggle-sdk-typescript` (^1.0.0).
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { FeatureToggleProvider, useFeature } from "featuretoggle-sdk-react";
|
|
17
|
+
|
|
18
|
+
function App() {
|
|
19
|
+
return (
|
|
20
|
+
<FeatureToggleProvider apiKey={import.meta.env.VITE_FT_API_KEY}>
|
|
21
|
+
<Checkout />
|
|
22
|
+
</FeatureToggleProvider>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function Checkout() {
|
|
27
|
+
const { enabled, loading } = useFeature("new-checkout");
|
|
28
|
+
if (loading) return null;
|
|
29
|
+
return enabled ? <NewCheckout /> : <LegacyCheckout />;
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Integration patterns
|
|
34
|
+
|
|
35
|
+
See the [integration cookbook](https://github.com/feature-toggle/feature-toggle-monorepo/blob/main/docs/17-sdk-integration-patterns.md) for SSR seed, BYO client, `autoInit={false}`, and more (patterns I–N).
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
- `<FeatureToggleProvider>` — `apiKey`, optional `client`, `initialFeatures`, `initialEtag`, `autoInit` (default `true`)
|
|
40
|
+
- `useFeature(key)` — `{ enabled, value, loading, error }`
|
|
41
|
+
- `useFeatureToggle()` — `{ init, refresh, getFeatures, loading, error }`
|
|
42
|
+
|
|
43
|
+
Import `FeatureResponse` from `featuretoggle-sdk-typescript` — not re-exported from this package.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
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.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
FeatureToggleProvider: () => FeatureToggleProvider,
|
|
24
|
+
useFeature: () => useFeature,
|
|
25
|
+
useFeatureToggle: () => useFeatureToggle
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
|
|
29
|
+
// src/provider.tsx
|
|
30
|
+
var import_featuretoggle_sdk_typescript = require("featuretoggle-sdk-typescript");
|
|
31
|
+
var import_react2 = require("react");
|
|
32
|
+
|
|
33
|
+
// src/context.ts
|
|
34
|
+
var import_react = require("react");
|
|
35
|
+
var FeatureToggleContext = (0, import_react.createContext)(
|
|
36
|
+
null
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// src/provider.tsx
|
|
40
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
|
+
function useFeatureToggleContext() {
|
|
42
|
+
const value = (0, import_react2.useContext)(FeatureToggleContext);
|
|
43
|
+
if (!value) {
|
|
44
|
+
throw new Error("useFeature must be used within FeatureToggleProvider");
|
|
45
|
+
}
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
function isSeeded(initialFeatures) {
|
|
49
|
+
return initialFeatures !== void 0;
|
|
50
|
+
}
|
|
51
|
+
function FeatureToggleProvider({
|
|
52
|
+
apiKey,
|
|
53
|
+
client: clientProp,
|
|
54
|
+
initialFeatures,
|
|
55
|
+
initialEtag,
|
|
56
|
+
autoInit = true,
|
|
57
|
+
pollInterval: _pollInterval,
|
|
58
|
+
children
|
|
59
|
+
}) {
|
|
60
|
+
const ownsClient = clientProp === void 0;
|
|
61
|
+
const seeded = isSeeded(initialFeatures);
|
|
62
|
+
const initGenerationRef = (0, import_react2.useRef)(0);
|
|
63
|
+
const clientRef = (0, import_react2.useRef)(null);
|
|
64
|
+
const apiKeyRef = (0, import_react2.useRef)(apiKey);
|
|
65
|
+
if (clientProp) {
|
|
66
|
+
clientRef.current = null;
|
|
67
|
+
} else if (apiKey) {
|
|
68
|
+
if (!clientRef.current || apiKeyRef.current !== apiKey) {
|
|
69
|
+
clientRef.current?.close();
|
|
70
|
+
clientRef.current = new import_featuretoggle_sdk_typescript.FeatureToggle({
|
|
71
|
+
apiKey,
|
|
72
|
+
initialFeatures,
|
|
73
|
+
initialEtag
|
|
74
|
+
});
|
|
75
|
+
apiKeyRef.current = apiKey;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
throw new Error("FeatureToggleProvider requires apiKey or client");
|
|
79
|
+
}
|
|
80
|
+
const client = clientProp ?? clientRef.current;
|
|
81
|
+
const [loading, setLoading] = (0, import_react2.useState)(() => !seeded);
|
|
82
|
+
const [error, setError] = (0, import_react2.useState)(null);
|
|
83
|
+
const runInit = (0, import_react2.useCallback)(async () => {
|
|
84
|
+
const generation = ++initGenerationRef.current;
|
|
85
|
+
setError(null);
|
|
86
|
+
if (!seeded) {
|
|
87
|
+
setLoading(true);
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
await client.init();
|
|
91
|
+
if (initGenerationRef.current !== generation) return;
|
|
92
|
+
setLoading(false);
|
|
93
|
+
} catch (unknownError) {
|
|
94
|
+
if (initGenerationRef.current !== generation) return;
|
|
95
|
+
const nextError = unknownError instanceof Error ? unknownError : new Error(String(unknownError));
|
|
96
|
+
setError(nextError);
|
|
97
|
+
setLoading(false);
|
|
98
|
+
throw nextError;
|
|
99
|
+
}
|
|
100
|
+
}, [client, seeded]);
|
|
101
|
+
const refresh = (0, import_react2.useCallback)(async () => {
|
|
102
|
+
await client.refresh();
|
|
103
|
+
}, [client]);
|
|
104
|
+
(0, import_react2.useEffect)(() => {
|
|
105
|
+
if (!autoInit) return;
|
|
106
|
+
void runInit().catch(() => void 0);
|
|
107
|
+
}, [autoInit, runInit]);
|
|
108
|
+
(0, import_react2.useEffect)(() => {
|
|
109
|
+
if (!ownsClient) return;
|
|
110
|
+
return () => {
|
|
111
|
+
initGenerationRef.current += 1;
|
|
112
|
+
clientRef.current?.close();
|
|
113
|
+
clientRef.current = null;
|
|
114
|
+
};
|
|
115
|
+
}, [ownsClient]);
|
|
116
|
+
const contextValue = (0, import_react2.useMemo)(
|
|
117
|
+
() => ({
|
|
118
|
+
client,
|
|
119
|
+
loading,
|
|
120
|
+
error,
|
|
121
|
+
init: runInit,
|
|
122
|
+
refresh
|
|
123
|
+
}),
|
|
124
|
+
[client, loading, error, runInit, refresh]
|
|
125
|
+
);
|
|
126
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FeatureToggleContext.Provider, { value: contextValue, children });
|
|
127
|
+
}
|
|
128
|
+
function useFeature(key) {
|
|
129
|
+
const { client, loading, error } = useFeatureToggleContext();
|
|
130
|
+
const snapshot = (0, import_react2.useSyncExternalStore)(
|
|
131
|
+
(listener) => client.subscribe(listener),
|
|
132
|
+
() => JSON.stringify({
|
|
133
|
+
enabled: client.isEnabled(key),
|
|
134
|
+
value: client.getValue(key)
|
|
135
|
+
}),
|
|
136
|
+
() => JSON.stringify({ enabled: false, value: void 0 })
|
|
137
|
+
);
|
|
138
|
+
const parsed = JSON.parse(snapshot);
|
|
139
|
+
return {
|
|
140
|
+
enabled: parsed.enabled,
|
|
141
|
+
value: parsed.value,
|
|
142
|
+
loading,
|
|
143
|
+
error
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function useFeatureToggle() {
|
|
147
|
+
const { client, loading, error, init, refresh } = useFeatureToggleContext();
|
|
148
|
+
(0, import_react2.useSyncExternalStore)(
|
|
149
|
+
(listener) => client.subscribe(listener),
|
|
150
|
+
() => JSON.stringify(client.getFeatures()),
|
|
151
|
+
() => "[]"
|
|
152
|
+
);
|
|
153
|
+
return {
|
|
154
|
+
init,
|
|
155
|
+
refresh,
|
|
156
|
+
getFeatures: (options) => client.getFeatures(options),
|
|
157
|
+
loading,
|
|
158
|
+
error
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
162
|
+
0 && (module.exports = {
|
|
163
|
+
FeatureToggleProvider,
|
|
164
|
+
useFeature,
|
|
165
|
+
useFeatureToggle
|
|
166
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { FeatureToggle, FeatureResponse } from 'featuretoggle-sdk-typescript';
|
|
3
|
+
|
|
4
|
+
type FeatureToggleProviderProps = {
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
client?: FeatureToggle;
|
|
7
|
+
pollInterval?: number;
|
|
8
|
+
initialFeatures?: FeatureResponse[];
|
|
9
|
+
initialEtag?: string;
|
|
10
|
+
autoInit?: boolean;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
};
|
|
13
|
+
type UseFeatureResult<T = unknown> = {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
value: T | undefined;
|
|
16
|
+
loading: boolean;
|
|
17
|
+
error: Error | null;
|
|
18
|
+
};
|
|
19
|
+
type UseFeatureToggleResult = {
|
|
20
|
+
init: () => Promise<void>;
|
|
21
|
+
refresh: () => Promise<void>;
|
|
22
|
+
getFeatures: (options?: Parameters<FeatureToggle["getFeatures"]>[0]) => FeatureResponse[];
|
|
23
|
+
loading: boolean;
|
|
24
|
+
error: Error | null;
|
|
25
|
+
};
|
|
26
|
+
type FeatureToggleContextValue = {
|
|
27
|
+
client: FeatureToggle;
|
|
28
|
+
loading: boolean;
|
|
29
|
+
error: Error | null;
|
|
30
|
+
init: () => Promise<void>;
|
|
31
|
+
refresh: () => Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
declare function FeatureToggleProvider({ apiKey, client: clientProp, initialFeatures, initialEtag, autoInit, pollInterval: _pollInterval, children, }: FeatureToggleProviderProps): react.JSX.Element;
|
|
35
|
+
declare function useFeature<T = unknown>(key: string): UseFeatureResult<T>;
|
|
36
|
+
declare function useFeatureToggle(): UseFeatureToggleResult;
|
|
37
|
+
|
|
38
|
+
export { type FeatureToggleContextValue, FeatureToggleProvider, type FeatureToggleProviderProps, type UseFeatureResult, type UseFeatureToggleResult, useFeature, useFeatureToggle };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { FeatureToggle, FeatureResponse } from 'featuretoggle-sdk-typescript';
|
|
3
|
+
|
|
4
|
+
type FeatureToggleProviderProps = {
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
client?: FeatureToggle;
|
|
7
|
+
pollInterval?: number;
|
|
8
|
+
initialFeatures?: FeatureResponse[];
|
|
9
|
+
initialEtag?: string;
|
|
10
|
+
autoInit?: boolean;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
};
|
|
13
|
+
type UseFeatureResult<T = unknown> = {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
value: T | undefined;
|
|
16
|
+
loading: boolean;
|
|
17
|
+
error: Error | null;
|
|
18
|
+
};
|
|
19
|
+
type UseFeatureToggleResult = {
|
|
20
|
+
init: () => Promise<void>;
|
|
21
|
+
refresh: () => Promise<void>;
|
|
22
|
+
getFeatures: (options?: Parameters<FeatureToggle["getFeatures"]>[0]) => FeatureResponse[];
|
|
23
|
+
loading: boolean;
|
|
24
|
+
error: Error | null;
|
|
25
|
+
};
|
|
26
|
+
type FeatureToggleContextValue = {
|
|
27
|
+
client: FeatureToggle;
|
|
28
|
+
loading: boolean;
|
|
29
|
+
error: Error | null;
|
|
30
|
+
init: () => Promise<void>;
|
|
31
|
+
refresh: () => Promise<void>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
declare function FeatureToggleProvider({ apiKey, client: clientProp, initialFeatures, initialEtag, autoInit, pollInterval: _pollInterval, children, }: FeatureToggleProviderProps): react.JSX.Element;
|
|
35
|
+
declare function useFeature<T = unknown>(key: string): UseFeatureResult<T>;
|
|
36
|
+
declare function useFeatureToggle(): UseFeatureToggleResult;
|
|
37
|
+
|
|
38
|
+
export { type FeatureToggleContextValue, FeatureToggleProvider, type FeatureToggleProviderProps, type UseFeatureResult, type UseFeatureToggleResult, useFeature, useFeatureToggle };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/provider.tsx
|
|
2
|
+
import {
|
|
3
|
+
FeatureToggle
|
|
4
|
+
} from "featuretoggle-sdk-typescript";
|
|
5
|
+
import {
|
|
6
|
+
useCallback,
|
|
7
|
+
useContext,
|
|
8
|
+
useEffect,
|
|
9
|
+
useMemo,
|
|
10
|
+
useRef,
|
|
11
|
+
useState,
|
|
12
|
+
useSyncExternalStore
|
|
13
|
+
} from "react";
|
|
14
|
+
|
|
15
|
+
// src/context.ts
|
|
16
|
+
import { createContext } from "react";
|
|
17
|
+
var FeatureToggleContext = createContext(
|
|
18
|
+
null
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// src/provider.tsx
|
|
22
|
+
import { jsx } from "react/jsx-runtime";
|
|
23
|
+
function useFeatureToggleContext() {
|
|
24
|
+
const value = useContext(FeatureToggleContext);
|
|
25
|
+
if (!value) {
|
|
26
|
+
throw new Error("useFeature must be used within FeatureToggleProvider");
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function isSeeded(initialFeatures) {
|
|
31
|
+
return initialFeatures !== void 0;
|
|
32
|
+
}
|
|
33
|
+
function FeatureToggleProvider({
|
|
34
|
+
apiKey,
|
|
35
|
+
client: clientProp,
|
|
36
|
+
initialFeatures,
|
|
37
|
+
initialEtag,
|
|
38
|
+
autoInit = true,
|
|
39
|
+
pollInterval: _pollInterval,
|
|
40
|
+
children
|
|
41
|
+
}) {
|
|
42
|
+
const ownsClient = clientProp === void 0;
|
|
43
|
+
const seeded = isSeeded(initialFeatures);
|
|
44
|
+
const initGenerationRef = useRef(0);
|
|
45
|
+
const clientRef = useRef(null);
|
|
46
|
+
const apiKeyRef = useRef(apiKey);
|
|
47
|
+
if (clientProp) {
|
|
48
|
+
clientRef.current = null;
|
|
49
|
+
} else if (apiKey) {
|
|
50
|
+
if (!clientRef.current || apiKeyRef.current !== apiKey) {
|
|
51
|
+
clientRef.current?.close();
|
|
52
|
+
clientRef.current = new FeatureToggle({
|
|
53
|
+
apiKey,
|
|
54
|
+
initialFeatures,
|
|
55
|
+
initialEtag
|
|
56
|
+
});
|
|
57
|
+
apiKeyRef.current = apiKey;
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
throw new Error("FeatureToggleProvider requires apiKey or client");
|
|
61
|
+
}
|
|
62
|
+
const client = clientProp ?? clientRef.current;
|
|
63
|
+
const [loading, setLoading] = useState(() => !seeded);
|
|
64
|
+
const [error, setError] = useState(null);
|
|
65
|
+
const runInit = useCallback(async () => {
|
|
66
|
+
const generation = ++initGenerationRef.current;
|
|
67
|
+
setError(null);
|
|
68
|
+
if (!seeded) {
|
|
69
|
+
setLoading(true);
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
await client.init();
|
|
73
|
+
if (initGenerationRef.current !== generation) return;
|
|
74
|
+
setLoading(false);
|
|
75
|
+
} catch (unknownError) {
|
|
76
|
+
if (initGenerationRef.current !== generation) return;
|
|
77
|
+
const nextError = unknownError instanceof Error ? unknownError : new Error(String(unknownError));
|
|
78
|
+
setError(nextError);
|
|
79
|
+
setLoading(false);
|
|
80
|
+
throw nextError;
|
|
81
|
+
}
|
|
82
|
+
}, [client, seeded]);
|
|
83
|
+
const refresh = useCallback(async () => {
|
|
84
|
+
await client.refresh();
|
|
85
|
+
}, [client]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (!autoInit) return;
|
|
88
|
+
void runInit().catch(() => void 0);
|
|
89
|
+
}, [autoInit, runInit]);
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (!ownsClient) return;
|
|
92
|
+
return () => {
|
|
93
|
+
initGenerationRef.current += 1;
|
|
94
|
+
clientRef.current?.close();
|
|
95
|
+
clientRef.current = null;
|
|
96
|
+
};
|
|
97
|
+
}, [ownsClient]);
|
|
98
|
+
const contextValue = useMemo(
|
|
99
|
+
() => ({
|
|
100
|
+
client,
|
|
101
|
+
loading,
|
|
102
|
+
error,
|
|
103
|
+
init: runInit,
|
|
104
|
+
refresh
|
|
105
|
+
}),
|
|
106
|
+
[client, loading, error, runInit, refresh]
|
|
107
|
+
);
|
|
108
|
+
return /* @__PURE__ */ jsx(FeatureToggleContext.Provider, { value: contextValue, children });
|
|
109
|
+
}
|
|
110
|
+
function useFeature(key) {
|
|
111
|
+
const { client, loading, error } = useFeatureToggleContext();
|
|
112
|
+
const snapshot = useSyncExternalStore(
|
|
113
|
+
(listener) => client.subscribe(listener),
|
|
114
|
+
() => JSON.stringify({
|
|
115
|
+
enabled: client.isEnabled(key),
|
|
116
|
+
value: client.getValue(key)
|
|
117
|
+
}),
|
|
118
|
+
() => JSON.stringify({ enabled: false, value: void 0 })
|
|
119
|
+
);
|
|
120
|
+
const parsed = JSON.parse(snapshot);
|
|
121
|
+
return {
|
|
122
|
+
enabled: parsed.enabled,
|
|
123
|
+
value: parsed.value,
|
|
124
|
+
loading,
|
|
125
|
+
error
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function useFeatureToggle() {
|
|
129
|
+
const { client, loading, error, init, refresh } = useFeatureToggleContext();
|
|
130
|
+
useSyncExternalStore(
|
|
131
|
+
(listener) => client.subscribe(listener),
|
|
132
|
+
() => JSON.stringify(client.getFeatures()),
|
|
133
|
+
() => "[]"
|
|
134
|
+
);
|
|
135
|
+
return {
|
|
136
|
+
init,
|
|
137
|
+
refresh,
|
|
138
|
+
getFeatures: (options) => client.getFeatures(options),
|
|
139
|
+
loading,
|
|
140
|
+
error
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
FeatureToggleProvider,
|
|
145
|
+
useFeature,
|
|
146
|
+
useFeatureToggle
|
|
147
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "featuretoggle-sdk-react",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/feature-toggle/sdk-react.git"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"test": "bun run --filter featuretoggle-sdk-typescript build && bun test --preload ./test/preload.ts",
|
|
24
|
+
"lint": "eslint .",
|
|
25
|
+
"check-types": "tsc --noEmit"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": ">=18",
|
|
29
|
+
"featuretoggle-sdk-typescript": "^1.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@eslint/js": "^9.28.0",
|
|
33
|
+
"@testing-library/react": "^16.3.0",
|
|
34
|
+
"@types/react": "^19.2.0",
|
|
35
|
+
"@happy-dom/global-registrator": "^20.0.10",
|
|
36
|
+
"eslint": "^9.28.0",
|
|
37
|
+
"featuretoggle-sdk-typescript": "workspace:*",
|
|
38
|
+
"react": "^19.2.0",
|
|
39
|
+
"react-dom": "^19.2.0",
|
|
40
|
+
"tsup": "^8.5.0",
|
|
41
|
+
"typescript": "^5.8.3",
|
|
42
|
+
"typescript-eslint": "^8.33.1"
|
|
43
|
+
}
|
|
44
|
+
}
|