@drivemetadata-ai/sdk 0.1.1-beta.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +107 -0
  4. package/dist/angular/index.cjs +954 -0
  5. package/dist/angular/index.cjs.map +1 -0
  6. package/dist/angular/index.d.cts +26 -0
  7. package/dist/angular/index.d.ts +26 -0
  8. package/dist/angular/index.js +928 -0
  9. package/dist/angular/index.js.map +1 -0
  10. package/dist/browser/index.cjs +914 -0
  11. package/dist/browser/index.cjs.map +1 -0
  12. package/dist/browser/index.d.cts +84 -0
  13. package/dist/browser/index.d.ts +84 -0
  14. package/dist/browser/index.js +874 -0
  15. package/dist/browser/index.js.map +1 -0
  16. package/dist/next/index.cjs +971 -0
  17. package/dist/next/index.cjs.map +1 -0
  18. package/dist/next/index.d.cts +18 -0
  19. package/dist/next/index.d.ts +18 -0
  20. package/dist/next/index.js +928 -0
  21. package/dist/next/index.js.map +1 -0
  22. package/dist/node/index.cjs +239 -0
  23. package/dist/node/index.cjs.map +1 -0
  24. package/dist/node/index.d.cts +85 -0
  25. package/dist/node/index.d.ts +85 -0
  26. package/dist/node/index.js +209 -0
  27. package/dist/node/index.js.map +1 -0
  28. package/dist/react/index.cjs +999 -0
  29. package/dist/react/index.cjs.map +1 -0
  30. package/dist/react/index.d.cts +26 -0
  31. package/dist/react/index.d.ts +26 -0
  32. package/dist/react/index.js +952 -0
  33. package/dist/react/index.js.map +1 -0
  34. package/dist/types-BwtS0ZDu.d.cts +106 -0
  35. package/dist/types-BwtS0ZDu.d.ts +106 -0
  36. package/docs/angular-integration.md +106 -0
  37. package/docs/index.md +19 -0
  38. package/docs/migration-cdn-to-npm.md +99 -0
  39. package/docs/node-server-integration.md +138 -0
  40. package/docs/npm-browser-sdk.md +143 -0
  41. package/docs/react-next-integration.md +168 -0
  42. package/docs/security-privacy.md +128 -0
  43. package/package.json +100 -0
@@ -0,0 +1,138 @@
1
+ # Node Server Integration
2
+
3
+ Use `@drivemetadata/sdk/node` for backend events only.
4
+
5
+ Do not use the browser SDK in server code. Browser analytics depends on DOM, cookies, localStorage, sessionStorage, page lifecycle, and session behavior.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @drivemetadata/sdk
11
+ ```
12
+
13
+ ## Create Client
14
+
15
+ ```ts
16
+ import { createDmdServerClient } from '@drivemetadata/sdk/node';
17
+
18
+ const dmd = createDmdServerClient({
19
+ writeKey: process.env.DMD_SERVER_WRITE_KEY!,
20
+ endpoint: 'https://sdk.drivemetadata.com/v2/data-collector',
21
+ timeoutMs: 5000,
22
+ retry: {
23
+ attempts: 3,
24
+ minDelayMs: 250,
25
+ maxDelayMs: 2000
26
+ }
27
+ });
28
+ ```
29
+
30
+ ## Track Event
31
+
32
+ ```ts
33
+ await dmd.track({
34
+ userId: 'user_123',
35
+ event: 'Invoice Paid',
36
+ messageId: 'evt_123',
37
+ idempotencyKey: 'invoice_123',
38
+ properties: {
39
+ amount: 500,
40
+ currency: 'USD'
41
+ }
42
+ });
43
+ ```
44
+
45
+ ## Idempotency
46
+
47
+ Pass `messageId` when you already have a unique event ID and `idempotencyKey` when retrying business events such as orders, invoices, or subscriptions.
48
+
49
+ ```ts
50
+ await dmd.track({
51
+ userId: 'user_123',
52
+ event: 'Order Completed',
53
+ messageId: 'evt_123',
54
+ idempotencyKey: 'order_123'
55
+ });
56
+ ```
57
+
58
+ ## Batch
59
+
60
+ ```ts
61
+ await dmd.batch([
62
+ { type: 'track', payload: { userId: 'user_123', event: 'Order Completed' } },
63
+ { type: 'identify', payload: { userId: 'user_123', traits: { plan: 'pro' } } }
64
+ ]);
65
+ ```
66
+
67
+ ## Identify User
68
+
69
+ ```ts
70
+ await dmd.identify({
71
+ userId: 'user_123',
72
+ traits: {
73
+ plan: 'enterprise',
74
+ seats: 25
75
+ }
76
+ });
77
+ ```
78
+
79
+ ## Page Event
80
+
81
+ ```ts
82
+ await dmd.page({
83
+ userId: 'user_123',
84
+ name: 'Billing Settings',
85
+ properties: {
86
+ source: 'server_render'
87
+ }
88
+ });
89
+ ```
90
+
91
+ ## Alias User
92
+
93
+ ```ts
94
+ await dmd.alias({
95
+ previousId: 'anonymous_123',
96
+ userId: 'user_123'
97
+ });
98
+ ```
99
+
100
+ ## Group User
101
+
102
+ ```ts
103
+ await dmd.group({
104
+ userId: 'user_123',
105
+ groupId: 'account_456',
106
+ traits: {
107
+ companyName: 'Acme Inc'
108
+ }
109
+ });
110
+ ```
111
+
112
+ ## Runtime Requirements
113
+
114
+ The Node SDK requires Node.js 18+ because it uses global `fetch`. For older runtimes, pass a custom fetch implementation:
115
+
116
+ ```ts
117
+ const dmd = createDmdServerClient({
118
+ writeKey: process.env.DMD_SERVER_WRITE_KEY!,
119
+ fetch: customFetch
120
+ });
121
+ ```
122
+
123
+ ## Server Key Safety
124
+
125
+ Use `@drivemetadata/sdk/node` only in server runtimes. Never import this entry point from browser bundles, React client components, Angular browser bundles, or Next.js client components.
126
+
127
+ Store server keys in backend-only environment variables:
128
+
129
+ ```ts
130
+ const dmd = createDmdServerClient({
131
+ writeKey: process.env.DMD_SERVER_WRITE_KEY!,
132
+ timeoutMs: 3000
133
+ });
134
+ ```
135
+
136
+ ## Reliability
137
+
138
+ Use `timeoutMs` to cap request time and `retry` to retry transient failures such as `408`, `429`, and `5xx` responses. Timeout timers are cleaned up after each request settles.
@@ -0,0 +1,143 @@
1
+ # Browser NPM SDK
2
+
3
+ Install:
4
+
5
+ ```bash
6
+ npm install @drivemetadata/sdk
7
+ ```
8
+
9
+ Import:
10
+
11
+ ```ts
12
+ import {
13
+ alias,
14
+ consent,
15
+ flush,
16
+ getDmdHealth,
17
+ group,
18
+ identify,
19
+ initDmdSDK,
20
+ page,
21
+ reset,
22
+ track
23
+ } from '@drivemetadata/sdk/browser';
24
+ ```
25
+
26
+ Initialize in browser runtime:
27
+
28
+ ```ts
29
+ initDmdSDK({
30
+ clientId: 'client_xxx',
31
+ workspaceId: 'workspace_xxx',
32
+ appId: 'app_xxx',
33
+ writeKey: 'public_write_key',
34
+ consent: {
35
+ analytics: 'granted',
36
+ advertising: 'denied',
37
+ personalization: 'denied',
38
+ functional: 'granted',
39
+ saleOfData: 'denied'
40
+ }
41
+ });
42
+ ```
43
+
44
+ If `consent` is omitted, analytics defaults to `pending` and events are dropped until consent is granted.
45
+
46
+ Track event:
47
+
48
+ ```ts
49
+ track('Product Viewed', {
50
+ productId: 'sku_123'
51
+ });
52
+ ```
53
+
54
+ Identify user:
55
+
56
+ ```ts
57
+ identify('user_123', {
58
+ plan: 'enterprise'
59
+ });
60
+ ```
61
+
62
+ Track page view:
63
+
64
+ ```ts
65
+ page();
66
+ ```
67
+
68
+ Group account:
69
+
70
+ ```ts
71
+ group('account_123', {
72
+ tier: 'enterprise'
73
+ });
74
+ ```
75
+
76
+ Alias anonymous to known user:
77
+
78
+ ```ts
79
+ alias('anonymous_123', 'user_123');
80
+ ```
81
+
82
+ Update consent:
83
+
84
+ ```ts
85
+ consent.update({
86
+ analytics: 'denied',
87
+ advertising: 'denied'
88
+ });
89
+ ```
90
+
91
+ Reset identity on logout:
92
+
93
+ ```ts
94
+ reset();
95
+ ```
96
+
97
+ Inspect health:
98
+
99
+ ```ts
100
+ console.log(getDmdHealth());
101
+ ```
102
+
103
+ Flush queued events:
104
+
105
+ ```ts
106
+ await flush();
107
+ ```
108
+
109
+ SSR note:
110
+
111
+ The browser package can be imported during SSR, but `initDmdSDK` must run only in the browser. For Next.js, call it inside a client component or use the React/Next adapter from a later SDK phase.
112
+
113
+ Diagnostics:
114
+
115
+ `getDmdHealth()` reports initialized state, consent state, queue size, offline state, dropped-event count, last error, and last dropped-event reason.
116
+
117
+ ## Delivery Troubleshooting
118
+
119
+ Use `getDmdHealth()` to inspect queue size, offline state, last error, and dropped delivery records.
120
+
121
+ ```ts
122
+ import { flush, getDmdHealth } from '@drivemetadata/sdk/browser';
123
+
124
+ console.log(getDmdHealth());
125
+ await flush();
126
+ ```
127
+
128
+ Common drop reasons:
129
+
130
+ | Reason | Meaning | Fix |
131
+ |---|---|---|
132
+ | `consent_denied` | Analytics consent is not granted | Call `setConsent({ analytics: 'granted' })` after user consent |
133
+ | `payload_too_large` | Event exceeds configured payload size | Reduce properties or increase `delivery.maxPayloadBytes` |
134
+ | `queue_limit_exceeded` | Offline queue is full | Increase `delivery.maxQueueSize` or flush more often |
135
+ | `queue_ttl_expired` | Event stayed offline past TTL | Increase `delivery.queueTtlMs` if appropriate |
136
+
137
+ Delivery behavior:
138
+
139
+ The browser SDK adds message IDs and idempotency keys to delivery payloads. Queue diagnostics include expired records, and queue flushing uses a cross-tab lease to avoid duplicate ownership when multiple tabs are open.
140
+
141
+ Legacy note:
142
+
143
+ The current CDN script `javascript/dmdSDK_v3.js` remains supported. The npm browser entry now initializes without requiring the CDN global, while legacy script customers keep the global constructor path.
@@ -0,0 +1,168 @@
1
+ # React and Next.js Integration
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install @drivemetadata/sdk
7
+ ```
8
+
9
+ ## React
10
+
11
+ Wrap your application once:
12
+
13
+ ```tsx
14
+ import { DmdProvider } from '@drivemetadata/sdk/react';
15
+
16
+ export function App() {
17
+ return (
18
+ <DmdProvider
19
+ config={{
20
+ clientId: 'client_xxx',
21
+ workspaceId: 'workspace_xxx',
22
+ appId: 'app_xxx',
23
+ writeKey: 'public_write_key',
24
+ consent: { analytics: 'granted', advertising: 'denied' }
25
+ }}
26
+ >
27
+ <Routes />
28
+ </DmdProvider>
29
+ );
30
+ }
31
+ ```
32
+
33
+ Track events:
34
+
35
+ ```tsx
36
+ import { useTrackEvent } from '@drivemetadata/sdk/react';
37
+
38
+ export function CTAButton() {
39
+ const track = useTrackEvent();
40
+
41
+ return (
42
+ <button onClick={() => track('CTA Clicked', { location: 'pricing' })}>
43
+ Start
44
+ </button>
45
+ );
46
+ }
47
+ ```
48
+
49
+ Use the complete browser client surface from hooks:
50
+
51
+ ```tsx
52
+ import {
53
+ useAlias,
54
+ useDmdFlush,
55
+ useGroup,
56
+ useIdentify,
57
+ usePage,
58
+ useReset,
59
+ useTrackEvent
60
+ } from '@drivemetadata/sdk/react';
61
+
62
+ export function AnalyticsActions() {
63
+ const track = useTrackEvent();
64
+ const page = usePage();
65
+ const identify = useIdentify();
66
+ const group = useGroup();
67
+ const alias = useAlias();
68
+ const flush = useDmdFlush();
69
+ const reset = useReset();
70
+
71
+ async function onCheckout() {
72
+ identify('user_123', { plan: 'enterprise' });
73
+ group('account_123', { tier: 'enterprise' });
74
+ alias('anonymous_123', 'user_123');
75
+ page('Checkout');
76
+ track('Checkout Started', { source: 'cart' });
77
+ await flush();
78
+ }
79
+
80
+ return (
81
+ <>
82
+ <button onClick={onCheckout}>Track checkout</button>
83
+ <button onClick={reset}>Reset</button>
84
+ </>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ## Next.js App Router
90
+
91
+ Create a client provider:
92
+
93
+ ```tsx
94
+ 'use client';
95
+
96
+ import { DmdProvider, useDmdAppRouterPageTracking } from '@drivemetadata/sdk/next';
97
+ import { usePathname, useSearchParams } from 'next/navigation';
98
+
99
+ export function AnalyticsProvider({ children }: { children: React.ReactNode }) {
100
+ const pathname = usePathname();
101
+ const searchParams = useSearchParams();
102
+
103
+ useDmdAppRouterPageTracking(pathname, searchParams.toString(), {
104
+ name: 'Route Viewed'
105
+ });
106
+
107
+ return (
108
+ <DmdProvider
109
+ config={{
110
+ clientId: process.env.NEXT_PUBLIC_DMD_CLIENT_ID!,
111
+ workspaceId: process.env.NEXT_PUBLIC_DMD_WORKSPACE_ID!,
112
+ appId: process.env.NEXT_PUBLIC_DMD_APP_ID!,
113
+ writeKey: process.env.NEXT_PUBLIC_DMD_WRITE_KEY!,
114
+ consent: { analytics: 'granted', advertising: 'denied' }
115
+ }}
116
+ >
117
+ {children}
118
+ </DmdProvider>
119
+ );
120
+ }
121
+ ```
122
+
123
+ Use it in `app/layout.tsx`:
124
+
125
+ ```tsx
126
+ import { AnalyticsProvider } from './AnalyticsProvider';
127
+
128
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
129
+ return (
130
+ <html lang="en">
131
+ <body>
132
+ <AnalyticsProvider>{children}</AnalyticsProvider>
133
+ </body>
134
+ </html>
135
+ );
136
+ }
137
+ ```
138
+
139
+ ## Next.js Pages Router
140
+
141
+ Use a provider in `_app.tsx`:
142
+
143
+ ```tsx
144
+ import type { AppProps } from 'next/app';
145
+ import { useRouter } from 'next/router';
146
+ import { DmdProvider, useDmdPagesRouterPageTracking } from '@drivemetadata/sdk/next';
147
+
148
+ function AnalyticsPageTracking() {
149
+ const router = useRouter();
150
+ useDmdPagesRouterPageTracking(router);
151
+ return null;
152
+ }
153
+
154
+ export default function App({ Component, pageProps }: AppProps) {
155
+ return (
156
+ <DmdProvider config={config}>
157
+ <AnalyticsPageTracking />
158
+ <Component {...pageProps} />
159
+ </DmdProvider>
160
+ );
161
+ }
162
+ ```
163
+
164
+ ## SSR Safety
165
+
166
+ `@drivemetadata/sdk/react` and `@drivemetadata/sdk/next` can be imported during server rendering, but SDK initialization must run in the browser. In Next.js App Router, place `DmdProvider` inside a file that starts with `'use client'`.
167
+
168
+ If consent is omitted, analytics defaults to `pending`; call `consent.update()` or pass an explicit consent object after your consent manager resolves.
@@ -0,0 +1,128 @@
1
+ # Security and Privacy
2
+
3
+ ## Public and Server Keys
4
+
5
+ Use public write keys only in browser, React, Next.js, and Angular integrations.
6
+
7
+ Use server write keys only with `@drivemetadata/sdk/node` in backend environments.
8
+
9
+ Never expose server write keys through `NEXT_PUBLIC_`, frontend build variables, script tags, or mobile clients.
10
+
11
+ ## Consent
12
+
13
+ Use consent controls before tracking users in regulated environments:
14
+
15
+ ```ts
16
+ import { consent, initDmdSDK } from '@drivemetadata/sdk/browser';
17
+
18
+ initDmdSDK({
19
+ clientId: 'client_xxx',
20
+ workspaceId: 'workspace_xxx',
21
+ appId: 'app_xxx',
22
+ writeKey: 'public_write_key',
23
+ consent: {
24
+ analytics: 'pending',
25
+ advertising: 'denied',
26
+ personalization: 'denied',
27
+ functional: 'granted',
28
+ saleOfData: 'denied'
29
+ }
30
+ });
31
+
32
+ consent.update({
33
+ analytics: 'granted',
34
+ advertising: 'denied'
35
+ });
36
+ ```
37
+
38
+ Supported consent states:
39
+
40
+ - `pending`
41
+ - `granted`
42
+ - `denied`
43
+
44
+ Supported purposes:
45
+
46
+ - `analytics`
47
+ - `advertising`
48
+ - `personalization`
49
+ - `functional`
50
+ - `saleOfData`
51
+
52
+ When analytics consent is denied, analytics events are dropped. When advertising consent is denied, advertising identifiers should not be collected or forwarded.
53
+
54
+ ## PII Controls
55
+
56
+ Use SDK masking and denylist options to reduce accidental sensitive data collection:
57
+
58
+ ```ts
59
+ initDmdSDK({
60
+ clientId: 'client_xxx',
61
+ workspaceId: 'workspace_xxx',
62
+ appId: 'app_xxx',
63
+ writeKey: 'public_write_key',
64
+ maskAllText: true,
65
+ maskAllElementAttributes: true,
66
+ propertyDenylist: ['password', 'token', 'secret']
67
+ });
68
+ ```
69
+
70
+ The npm browser core removes common raw PII fields such as `email`, `phone`, address fields, `token`, `secret`, and `password` from event properties by default. URL redaction should preserve UTM parameters while replacing sensitive query values.
71
+
72
+ ## Form Capture
73
+
74
+ Sensitive form fields should be denied or masked. Passwords, payment data, tokens, authentication fields, and government identifiers should never be captured as plain text.
75
+
76
+ ## Shopify Privacy
77
+
78
+ The Shopify pixel adapter reads Shopify `customerPrivacy` when available. If `analyticsProcessingAllowed()` returns `false`, checkout and other pixel events are blocked before calling the SDK. The adapter also subscribes to `visitorConsentCollected` so consent changes during the session update tracking behavior.
79
+
80
+ Raw checkout PII is not sent by default. Checkout email, phone, name, and address values are removed from default pixel event payloads.
81
+
82
+ ## Regional Endpoints
83
+
84
+ Use `apiHost` to route events to the correct regional collector endpoint when required by customer policy.
85
+
86
+ ```ts
87
+ initDmdSDK({
88
+ clientId: 'client_xxx',
89
+ workspaceId: 'workspace_xxx',
90
+ appId: 'app_xxx',
91
+ writeKey: 'public_write_key',
92
+ apiHost: 'https://eu-sdk.drivemetadata.com/v2'
93
+ });
94
+ ```
95
+
96
+ ## Diagnostics
97
+
98
+ Use `getDmdHealth()` to inspect SDK state and dropped-event diagnostics during integration:
99
+
100
+ ```ts
101
+ import { getDmdHealth } from '@drivemetadata/sdk/browser';
102
+
103
+ console.log(getDmdHealth());
104
+ ```
105
+
106
+ Browser delivery uses message IDs, idempotency keys, queue TTL diagnostics, and a cross-tab flush lease so multiple tabs do not own queue flushing at the same time.
107
+
108
+ ## Enterprise Privacy Checklist
109
+
110
+ - Default analytics consent is `pending`.
111
+ - Advertising storage must remain denied until advertising consent is granted.
112
+ - Browser examples must use public write keys only.
113
+ - Server write keys must be used only from server runtimes.
114
+ - PII masking is recursive for common direct identifiers.
115
+ - Customers should configure retention, region, DPA, and subprocessor review before production.
116
+
117
+ ## Enterprise Review Topics
118
+
119
+ Customers should complete these reviews before production:
120
+
121
+ | Topic | SDK Support | Customer Action |
122
+ |---|---|---|
123
+ | Legal basis | Consent states and purpose-level controls | Connect SDK consent to CMP |
124
+ | Data retention | Event delivery includes timestamps and customer IDs | Confirm retention policy in backend/product |
125
+ | Data residency | `apiHost` supports regional collectors | Use approved regional endpoint |
126
+ | Server keys | Node entry keeps keys server-side | Store keys only in backend secrets |
127
+ | Subprocessors | Not enforced in SDK code | Review company subprocessor list |
128
+ | PII minimization | Recursive common PII redaction | Configure denylist and avoid sensitive properties |
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "@drivemetadata-ai/sdk",
3
+ "version": "0.1.1-beta.1",
4
+ "description": "Enterprise-grade DriveMetaData browser SDK.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "docs/index.md",
13
+ "docs/npm-browser-sdk.md",
14
+ "docs/react-next-integration.md",
15
+ "docs/angular-integration.md",
16
+ "docs/node-server-integration.md",
17
+ "docs/security-privacy.md",
18
+ "docs/migration-cdn-to-npm.md",
19
+ "README.md",
20
+ "CHANGELOG.md",
21
+ "LICENSE"
22
+ ],
23
+ "sideEffects": false,
24
+ "exports": {
25
+ "./browser": {
26
+ "types": "./dist/browser/index.d.ts",
27
+ "import": "./dist/browser/index.js",
28
+ "require": "./dist/browser/index.cjs"
29
+ },
30
+ "./react": {
31
+ "types": "./dist/react/index.d.ts",
32
+ "import": "./dist/react/index.js",
33
+ "require": "./dist/react/index.cjs"
34
+ },
35
+ "./next": {
36
+ "types": "./dist/next/index.d.ts",
37
+ "import": "./dist/next/index.js",
38
+ "require": "./dist/next/index.cjs"
39
+ },
40
+ "./angular": {
41
+ "types": "./dist/angular/index.d.ts",
42
+ "import": "./dist/angular/index.js",
43
+ "require": "./dist/angular/index.cjs"
44
+ },
45
+ "./node": {
46
+ "types": "./dist/node/index.d.ts",
47
+ "import": "./dist/node/index.js",
48
+ "require": "./dist/node/index.cjs"
49
+ },
50
+ "./package.json": "./package.json"
51
+ },
52
+ "engines": {
53
+ "node": ">=18"
54
+ },
55
+ "scripts": {
56
+ "build": "tsup",
57
+ "typecheck": "tsc --noEmit",
58
+ "test": "vitest run",
59
+ "test:legacy": "node tests/dmdSDK_v3.browser.test.js && node tests/dmdSDK_v3.consent.test.js && node tests/dmdSDK_v3.integration.test.js && node tests/dmdSDK_v3.payload.test.js && node tests/dmdSDK_v3.privacy.test.js && node tests/dmdSDK_v3.schema.unit.test.js && node tests/dmdSDK_v3.singleton.test.js && node tests/dmdSDK_v3.storage.test.js",
60
+ "test:package": "npm run build && vitest run tests/package/package-contents.test.ts tests/package/package-install-smoke.test.ts",
61
+ "pack:check": "npm run build && npm pack --dry-run",
62
+ "release:check": "npm run ci && npm_config_cache=/tmp/npm-cache npm run pack:check",
63
+ "ci": "npm run typecheck && npm run test && npm run test:legacy && npm run build && npm run test:package",
64
+ "ci:phase1": "npm run typecheck && npm run test && npm run test:legacy && npm run build"
65
+ },
66
+ "peerDependencies": {
67
+ "@angular/core": ">=16 <21",
68
+ "next": ">=13 <16",
69
+ "react": ">=18 <20",
70
+ "react-dom": ">=18 <20"
71
+ },
72
+ "peerDependenciesMeta": {
73
+ "@angular/core": {
74
+ "optional": true
75
+ },
76
+ "next": {
77
+ "optional": true
78
+ },
79
+ "react": {
80
+ "optional": true
81
+ },
82
+ "react-dom": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "devDependencies": {
87
+ "@angular/core": "^20.0.0",
88
+ "@testing-library/react": "^16.0.0",
89
+ "@types/node": "^22.0.0",
90
+ "@types/react": "^19.0.0",
91
+ "@types/react-dom": "^19.0.0",
92
+ "jsdom": "^26.0.0",
93
+ "next": "^15.0.0",
94
+ "react": "^19.0.0",
95
+ "react-dom": "^19.0.0",
96
+ "tsup": "^8.0.0",
97
+ "typescript": "^5.0.0",
98
+ "vitest": "^3.0.0"
99
+ }
100
+ }