@shelbyb/daywalker-sdk 0.1.4 → 0.3.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 +31 -2
- package/dist/analytics/index.d.ts +108 -0
- package/dist/analytics/index.js +371 -0
- package/dist/cli.js +5 -0
- package/dist/client.d.ts +15 -1
- package/dist/client.js +59 -12
- package/dist/config.d.ts +6 -0
- package/dist/config.js +22 -0
- package/dist/crypto/signatures.d.ts +18 -5
- package/dist/crypto/signatures.js +100 -41
- package/dist/flags/client.d.ts +102 -0
- package/dist/flags/client.js +302 -0
- package/dist/flags/common/events.d.ts +59 -0
- package/dist/flags/common/events.js +204 -0
- package/dist/flags/common/index.d.ts +5 -0
- package/dist/flags/common/index.js +12 -0
- package/dist/flags/common/sse.d.ts +62 -0
- package/dist/flags/common/sse.js +183 -0
- package/dist/flags/engine/bucket.d.ts +21 -0
- package/dist/flags/engine/bucket.js +41 -0
- package/dist/flags/engine/context.d.ts +30 -0
- package/dist/flags/engine/context.js +81 -0
- package/dist/flags/engine/evaluate.d.ts +54 -0
- package/dist/flags/engine/evaluate.js +177 -0
- package/dist/flags/engine/index.d.ts +7 -0
- package/dist/flags/engine/index.js +7 -0
- package/dist/flags/engine/operators.d.ts +13 -0
- package/dist/flags/engine/operators.js +139 -0
- package/dist/flags/engine/semver.d.ts +13 -0
- package/dist/flags/engine/semver.js +35 -0
- package/dist/flags/engine/sha1.d.ts +6 -0
- package/dist/flags/engine/sha1.js +43 -0
- package/dist/flags/engine/types.d.ts +120 -0
- package/dist/flags/engine/types.js +17 -0
- package/dist/flags/node.d.ts +97 -0
- package/dist/flags/node.js +263 -0
- package/dist/flags/react.d.ts +27 -0
- package/dist/flags/react.js +62 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/next.d.ts +15 -2
- package/dist/next.js +41 -9
- package/dist/openfeature/server.d.ts +26 -0
- package/dist/openfeature/server.js +42 -0
- package/dist/openfeature/shared.d.ts +19 -0
- package/dist/openfeature/shared.js +40 -0
- package/dist/openfeature/web.d.ts +29 -0
- package/dist/openfeature/web.js +50 -0
- package/dist/types.d.ts +3 -0
- package/docs/analytics.md +32 -0
- package/docs/flags-node.md +49 -0
- package/docs/flags-react.md +35 -0
- package/docs/flags.md +53 -0
- package/docs/openfeature.md +30 -0
- package/package.json +62 -7
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { OpenFeatureEventEmitter, ProviderEvents } from "@openfeature/web-sdk";
|
|
2
|
+
import { createClient } from "../flags/client.js";
|
|
3
|
+
import { toDevPulseContext, toResolution, typeCheck } from "./shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* OpenFeature provider for browsers, backed by @shelbyb/daywalker-sdk/flags. Flag
|
|
6
|
+
* values update in real time and emit PROVIDER_CONFIGURATION_CHANGED.
|
|
7
|
+
*
|
|
8
|
+
* await OpenFeature.setContext({ targetingKey: user.id });
|
|
9
|
+
* await OpenFeature.setProviderAndWait(new DevPulseWebProvider(clientSideId, { baseUrl }));
|
|
10
|
+
*/
|
|
11
|
+
export class DevPulseWebProvider {
|
|
12
|
+
clientSideId;
|
|
13
|
+
options;
|
|
14
|
+
metadata = { name: "devpulse" };
|
|
15
|
+
runsOn = "client";
|
|
16
|
+
events = new OpenFeatureEventEmitter();
|
|
17
|
+
client = null;
|
|
18
|
+
constructor(clientSideId, options) {
|
|
19
|
+
this.clientSideId = clientSideId;
|
|
20
|
+
this.options = options;
|
|
21
|
+
}
|
|
22
|
+
async initialize(context) {
|
|
23
|
+
this.client = createClient(this.clientSideId, toDevPulseContext(context ?? {}), { ...this.options, withReasons: true });
|
|
24
|
+
this.client.on("change", (changes) => this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged: Object.keys(changes) }));
|
|
25
|
+
await this.client.waitForInitialization();
|
|
26
|
+
}
|
|
27
|
+
async onContextChange(_old, next) {
|
|
28
|
+
await this.client?.identify(toDevPulseContext(next));
|
|
29
|
+
}
|
|
30
|
+
async onClose() {
|
|
31
|
+
await this.client?.close();
|
|
32
|
+
}
|
|
33
|
+
resolve(key, def, type) {
|
|
34
|
+
if (!this.client)
|
|
35
|
+
return toResolution({ value: def, variationIndex: null, reason: { kind: "ERROR", errorKind: "CLIENT_NOT_READY" } });
|
|
36
|
+
return toResolution(typeCheck(this.client.variationDetail(key, def), type, def));
|
|
37
|
+
}
|
|
38
|
+
resolveBooleanEvaluation(key, def, _ctx, _logger) {
|
|
39
|
+
return this.resolve(key, def, "boolean");
|
|
40
|
+
}
|
|
41
|
+
resolveStringEvaluation(key, def, _ctx, _logger) {
|
|
42
|
+
return this.resolve(key, def, "string");
|
|
43
|
+
}
|
|
44
|
+
resolveNumberEvaluation(key, def, _ctx, _logger) {
|
|
45
|
+
return this.resolve(key, def, "number");
|
|
46
|
+
}
|
|
47
|
+
resolveObjectEvaluation(key, def, _ctx, _logger) {
|
|
48
|
+
return this.resolve(key, def, "object");
|
|
49
|
+
}
|
|
50
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -55,6 +55,9 @@ export interface DaywalkerConfig {
|
|
|
55
55
|
serviceSlug?: string;
|
|
56
56
|
domain?: string;
|
|
57
57
|
daywalkerPublicKey?: string | PublicJwk;
|
|
58
|
+
/** Expected `iss` of offline-verified JWT leases (env DAYWALKER_LEASE_ISSUER). Unchecked when unset. */
|
|
59
|
+
leaseIssuer?: string;
|
|
60
|
+
/** Must be https:// (http:// only for localhost). */
|
|
58
61
|
authUrl?: string;
|
|
59
62
|
cacheTtlMs?: number;
|
|
60
63
|
/** Short cache for failed validations (not 429/network errors). Default 3000ms; 0 disables. */
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# @shelbyb/daywalker-sdk/analytics
|
|
2
|
+
|
|
3
|
+
Product analytics for browsers and Node: events, automatic page views (including client-side navigation), sessions, identify, super properties and feature-flag properties.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @shelbyb/daywalker-sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createAnalytics } from "@shelbyb/daywalker-sdk/analytics";
|
|
11
|
+
|
|
12
|
+
const analytics = createAnalytics({ writeKey: "dpa_…", host: "https://devpulse.example.com" });
|
|
13
|
+
|
|
14
|
+
analytics.capture("project_created", { template: "nextjs" });
|
|
15
|
+
analytics.identify(user.id, { email: user.email, plan: user.plan }); // merges the anonymous history
|
|
16
|
+
analytics.register({ app_version: "2.4.0" }); // sent with every event
|
|
17
|
+
analytics.reset(); // on logout
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Server-side (Node), pass who did it and flush before exit:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
const analytics = createAnalytics({ writeKey: process.env.DEVPULSE_WRITE_KEY!, host: "https://devpulse.example.com" });
|
|
24
|
+
analytics.capture("invoice_paid", { amount: 49 }, { distinctId: customer.id });
|
|
25
|
+
await analytics.shutdown();
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Add each flag's value to events (for breakdowns by variation) with `flags: client` where `client` is a `@shelbyb/daywalker-sdk/flags` instance (anything with `allFlags()`).
|
|
29
|
+
|
|
30
|
+
Options: `autocapturePageviews` (default true), `flushAt` (20), `flushInterval` (2s browser / 10s Node), `maxQueueSize` (1000), `persistence` (`localStorage` | `memory`), `sessionTimeoutMinutes` (30), `respectDoNotTrack`, `optedOut` (consent), `captureFullUrls` (default false: URLs drop the fragment and all query parameters except `utm_*`, `gclid`, `fbclid`, `ref`), `onError`. `host` must be `https://` except on localhost.
|
|
31
|
+
|
|
32
|
+
Events are sent to `POST {host}/a/batch`, which also accepts PostHog's capture format.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @shelbyb/daywalker-sdk/flags/node
|
|
2
|
+
|
|
3
|
+
Server-side feature flags for Node.js from [DevPulse](https://github.com/shelbyb/devpulse). The SDK downloads your flag rules once, keeps them current over a streaming connection, and evaluates locally, so `variation()` adds no network latency.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @shelbyb/daywalker-sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { init } from "@shelbyb/daywalker-sdk/flags/node";
|
|
11
|
+
|
|
12
|
+
export const flags = init(process.env.DEVPULSE_SDK_KEY!, { baseUrl: "https://devpulse.example.com" });
|
|
13
|
+
await flags.waitForInitialization({ timeoutMs: 5000 });
|
|
14
|
+
|
|
15
|
+
const context = { kind: "user", key: user.id, email: user.email, plan: user.plan };
|
|
16
|
+
if (await flags.variation("new-checkout", context, false)) {
|
|
17
|
+
// …
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
flags.on("update:new-checkout", () => console.log("new-checkout changed"));
|
|
21
|
+
flags.track("checkout-completed", context, undefined, order.total);
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Create one client per process and reuse it. Call `await flags.close()` on shutdown to flush analytics.
|
|
25
|
+
|
|
26
|
+
## Next.js (App Router): bootstrap the browser without a flicker
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
// app/layout.tsx (Server Component)
|
|
30
|
+
import { flags } from "@/lib/flags";
|
|
31
|
+
import { Providers } from "./providers";
|
|
32
|
+
|
|
33
|
+
export default async function Layout({ children }) {
|
|
34
|
+
const context = await currentUserContext();
|
|
35
|
+
const bootstrap = (await flags.allFlagsState(context, { clientSideOnly: true })).toJSON();
|
|
36
|
+
const hash = flags.secureModeHash(context); // if secure mode is on
|
|
37
|
+
return <Providers context={context} bootstrap={bootstrap} hash={hash}>{children}</Providers>;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
See `@shelbyb/daywalker-sdk/flags/react` for the `Providers` component.
|
|
42
|
+
|
|
43
|
+
## Options
|
|
44
|
+
|
|
45
|
+
`baseUrl`, `stream` (default `true`; falls back to polling if streaming keeps failing), `pollIntervalMs` (≥ 30s), `sendEvents`, `privateAttributes`, `allAttributesPrivate`, `offline`, `initialData` (fixtures for tests), `logger`.
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
`variation` / `variationDetail` (async) and `variationSync` / `variationDetailSync`, typed helpers (`boolVariation`, …), `allFlagsState(context, { clientSideOnly, withReasons })`, `secureModeHash(context)`, `track`, `identify`, `on("ready" | "failed" | "update" | "update:<key>")`, `flush()`, `close()`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @shelbyb/daywalker-sdk/flags/react
|
|
2
|
+
|
|
3
|
+
React provider and hooks for [DevPulse](https://github.com/shelbyb/devpulse) feature flags. Components re-render when the flags they read change, in real time.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @shelbyb/daywalker-sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
"use client";
|
|
11
|
+
import { DevPulseProvider, useFlag, useTrack } from "@shelbyb/daywalker-sdk/flags/react";
|
|
12
|
+
|
|
13
|
+
export function Providers({ context, bootstrap, hash, children }) {
|
|
14
|
+
return (
|
|
15
|
+
<DevPulseProvider
|
|
16
|
+
clientSideId={process.env.NEXT_PUBLIC_DEVPULSE_CLIENT_ID!}
|
|
17
|
+
context={context}
|
|
18
|
+
options={{ baseUrl: process.env.NEXT_PUBLIC_DEVPULSE_URL!, bootstrap, hash }}
|
|
19
|
+
>
|
|
20
|
+
{children}
|
|
21
|
+
</DevPulseProvider>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function Checkout() {
|
|
26
|
+
const newCheckout = useFlag("new-checkout", false);
|
|
27
|
+
const track = useTrack();
|
|
28
|
+
return newCheckout ? <NewCheckout onDone={(total) => track("checkout-completed", undefined, total)} /> : <OldCheckout />;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- **SSR / React Server Components:** pass `bootstrap` from `@shelbyb/daywalker-sdk/flags/node`'s `allFlagsState(context, { clientSideOnly: true }).toJSON()`. The server render and first client render then match, with no loading flicker. No network connection is opened during server rendering.
|
|
33
|
+
- Changing the `context` prop calls `identify()`.
|
|
34
|
+
|
|
35
|
+
Hooks: `useFlag(key, default)`, `useFlagDetail(key, default)`, `useFlags()`, `useFlagsReady()`, `useTrack()`, `useDevPulseClient()`.
|
package/docs/flags.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @shelbyb/daywalker-sdk/flags
|
|
2
|
+
|
|
3
|
+
Feature flags for browsers (and any JavaScript client) from [DevPulse](https://github.com/shelbyb/devpulse). Flag changes arrive in real time over Server-Sent Events, typically within tens of milliseconds of a change in the dashboard.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @shelbyb/daywalker-sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { createClient } from "@shelbyb/daywalker-sdk/flags";
|
|
11
|
+
|
|
12
|
+
const client = createClient(
|
|
13
|
+
"YOUR_CLIENT_SIDE_ID", // Project → Environments & keys
|
|
14
|
+
{ kind: "user", key: user.id, email: user.email },
|
|
15
|
+
{ baseUrl: "https://devpulse.example.com" },
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
await client.waitForInitialization({ timeoutMs: 3000 });
|
|
19
|
+
|
|
20
|
+
if (client.variation("new-checkout", false)) showNewCheckout();
|
|
21
|
+
|
|
22
|
+
// React to changes made in the dashboard, live
|
|
23
|
+
client.on("change:new-checkout", (enabled) => (enabled ? showNewCheckout() : showOldCheckout()));
|
|
24
|
+
|
|
25
|
+
// Metrics and experiments
|
|
26
|
+
client.track("checkout-completed", { items: 3 }, 129.5);
|
|
27
|
+
|
|
28
|
+
// After login
|
|
29
|
+
await client.identify({ kind: "user", key: newUser.id });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Only flags marked **Available to client-side SDKs** are visible.
|
|
33
|
+
|
|
34
|
+
## Options
|
|
35
|
+
|
|
36
|
+
| Option | Default | |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `baseUrl` | — | Your DevPulse URL |
|
|
39
|
+
| `streaming` | `true` | Real-time updates (SSE). `false` fetches once |
|
|
40
|
+
| `bootstrap` | — | Initial values, e.g. from `@shelbyb/daywalker-sdk/flags/node`'s `allFlagsState().toJSON()` |
|
|
41
|
+
| `hash` | — | Secure mode hash (`HMAC-SHA256(sdkKey, contextKey)`), computed on your server |
|
|
42
|
+
| `withReasons` | `false` | Include evaluation reasons for `variationDetail()` |
|
|
43
|
+
| `sendEvents` | `true` | Analytics for insights and experiments |
|
|
44
|
+
| `privateAttributes` / `allAttributesPrivate` | — | Attributes never sent to DevPulse |
|
|
45
|
+
| `cache` | `false` | Persist the last flags in `localStorage` and use them while loading |
|
|
46
|
+
|
|
47
|
+
## Contexts
|
|
48
|
+
|
|
49
|
+
Single kind: `{ kind: "user", key: "u1", plan: "pro" }`. Multi-kind: `{ kind: "multi", user: { key: "u1" }, organization: { key: "acme" } }`.
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
`variation(key, default)`, `variationDetail(key, default)`, `boolVariation` / `stringVariation` / `numberVariation` / `jsonVariation`, `allFlags()`, `identify(context)`, `track(key, data?, metricValue?)`, `on("ready" | "failed" | "change" | "change:<key>", fn)`, `flush()`, `close()`.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @shelbyb/daywalker-sdk/openfeature
|
|
2
|
+
|
|
3
|
+
[OpenFeature](https://openfeature.dev) providers for DevPulse. Use the vendor-neutral OpenFeature API and swap providers without touching application code.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @shelbyb/daywalker-sdk @openfeature/server-sdk # servers
|
|
7
|
+
npm install @shelbyb/daywalker-sdk @openfeature/web-sdk # browsers
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
// Server
|
|
12
|
+
import { OpenFeature } from "@openfeature/server-sdk";
|
|
13
|
+
import { DevPulseServerProvider } from "@shelbyb/daywalker-sdk/openfeature/server";
|
|
14
|
+
|
|
15
|
+
await OpenFeature.setProviderAndWait(new DevPulseServerProvider(process.env.DEVPULSE_SDK_KEY!, { baseUrl }));
|
|
16
|
+
const client = OpenFeature.getClient();
|
|
17
|
+
const enabled = await client.getBooleanValue("new-checkout", false, { targetingKey: user.id, plan: "pro" });
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
// Browser
|
|
22
|
+
import { OpenFeature } from "@openfeature/web-sdk";
|
|
23
|
+
import { DevPulseWebProvider } from "@shelbyb/daywalker-sdk/openfeature/web";
|
|
24
|
+
|
|
25
|
+
await OpenFeature.setContext({ targetingKey: user.id });
|
|
26
|
+
await OpenFeature.setProviderAndWait(new DevPulseWebProvider(clientSideId, { baseUrl }));
|
|
27
|
+
OpenFeature.getClient().getBooleanValue("new-checkout", false);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`targetingKey` maps to the context key, and a `kind` attribute selects the context kind (default `user`). Flag changes emit `PROVIDER_CONFIGURATION_CHANGED`. Reasons map to OpenFeature's standard reasons: `TARGETING_MATCH`, `SPLIT`, `DEFAULT`, `DISABLED`, `ERROR`.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shelbyb/daywalker-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Daywalker Auth service validation plus the DevPulse client SDKs (feature flags, OpenFeature, product analytics) in one zero-dependency package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -21,6 +21,34 @@
|
|
|
21
21
|
"./express": {
|
|
22
22
|
"types": "./dist/express.d.ts",
|
|
23
23
|
"import": "./dist/express.js"
|
|
24
|
+
},
|
|
25
|
+
"./flags": {
|
|
26
|
+
"types": "./dist/flags/client.d.ts",
|
|
27
|
+
"import": "./dist/flags/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./flags/node": {
|
|
30
|
+
"types": "./dist/flags/node.d.ts",
|
|
31
|
+
"import": "./dist/flags/node.js"
|
|
32
|
+
},
|
|
33
|
+
"./flags/react": {
|
|
34
|
+
"types": "./dist/flags/react.d.ts",
|
|
35
|
+
"import": "./dist/flags/react.js"
|
|
36
|
+
},
|
|
37
|
+
"./flags/engine": {
|
|
38
|
+
"types": "./dist/flags/engine/index.d.ts",
|
|
39
|
+
"import": "./dist/flags/engine/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./openfeature/server": {
|
|
42
|
+
"types": "./dist/openfeature/server.d.ts",
|
|
43
|
+
"import": "./dist/openfeature/server.js"
|
|
44
|
+
},
|
|
45
|
+
"./openfeature/web": {
|
|
46
|
+
"types": "./dist/openfeature/web.d.ts",
|
|
47
|
+
"import": "./dist/openfeature/web.js"
|
|
48
|
+
},
|
|
49
|
+
"./analytics": {
|
|
50
|
+
"types": "./dist/analytics/index.d.ts",
|
|
51
|
+
"import": "./dist/analytics/index.js"
|
|
24
52
|
}
|
|
25
53
|
},
|
|
26
54
|
"bin": {
|
|
@@ -29,6 +57,7 @@
|
|
|
29
57
|
"files": [
|
|
30
58
|
"dist",
|
|
31
59
|
"assets",
|
|
60
|
+
"docs",
|
|
32
61
|
"README.md",
|
|
33
62
|
"LICENSE"
|
|
34
63
|
],
|
|
@@ -52,19 +81,45 @@
|
|
|
52
81
|
},
|
|
53
82
|
"license": "MIT",
|
|
54
83
|
"devDependencies": {
|
|
55
|
-
"@
|
|
56
|
-
"
|
|
57
|
-
"
|
|
84
|
+
"@openfeature/core": "^1.12.0",
|
|
85
|
+
"@openfeature/server-sdk": "^1.23.0",
|
|
86
|
+
"@openfeature/web-sdk": "^1.10.0",
|
|
87
|
+
"@types/node": "^26.6.4",
|
|
88
|
+
"@types/react": "^19.3.0",
|
|
89
|
+
"react": "^19.3.0",
|
|
90
|
+
"tsx": "^4.23.15",
|
|
91
|
+
"typescript": "^7.0.2"
|
|
58
92
|
},
|
|
59
93
|
"keywords": [
|
|
60
|
-
"daywalker",
|
|
61
94
|
"api-token",
|
|
62
95
|
"authentication",
|
|
96
|
+
"daywalker",
|
|
97
|
+
"devpulse",
|
|
63
98
|
"ed25519",
|
|
99
|
+
"feature-flags",
|
|
100
|
+
"openfeature",
|
|
101
|
+
"product-analytics",
|
|
64
102
|
"request-signing"
|
|
65
103
|
],
|
|
66
104
|
"homepage": "https://auth.daywalker.dev/docs",
|
|
67
105
|
"bugs": {
|
|
68
106
|
"url": "https://github.com/Shelbyb/daywalker-sdk/issues"
|
|
69
|
-
}
|
|
107
|
+
},
|
|
108
|
+
"peerDependencies": {
|
|
109
|
+
"@openfeature/server-sdk": "^1.17.0",
|
|
110
|
+
"@openfeature/web-sdk": "^1.5.0",
|
|
111
|
+
"react": ">=18"
|
|
112
|
+
},
|
|
113
|
+
"peerDependenciesMeta": {
|
|
114
|
+
"react": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
117
|
+
"@openfeature/server-sdk": {
|
|
118
|
+
"optional": true
|
|
119
|
+
},
|
|
120
|
+
"@openfeature/web-sdk": {
|
|
121
|
+
"optional": true
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"sideEffects": false
|
|
70
125
|
}
|