@peax/consent-core 0.6.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/LICENSE +201 -0
- package/README.md +207 -0
- package/dist/ConsentEnforcementError-Bn_ayWJI.js +16 -0
- package/dist/assertStorageIdentifier-BQuj-9bp.js +7 -0
- package/dist/createConsentIframe-Bw-cl--m.js +93 -0
- package/dist/createConsentRequestScope-D7U8uK6m.js +58 -0
- package/dist/createConsentScript-C_4ecSTX.js +102 -0
- package/dist/createDomGuard-CuIEC0HP.js +101 -0
- package/dist/enforcement/axios.d.ts +222 -0
- package/dist/enforcement/axios.js +92 -0
- package/dist/enforcement/fetch.d.ts +222 -0
- package/dist/enforcement/fetch.js +40 -0
- package/dist/enforcement/iframe.d.ts +245 -0
- package/dist/enforcement/iframe.js +2 -0
- package/dist/enforcement/integration.d.ts +230 -0
- package/dist/enforcement/integration.js +181 -0
- package/dist/enforcement/markup.d.ts +214 -0
- package/dist/enforcement/markup.js +300 -0
- package/dist/enforcement/posthog.d.ts +68 -0
- package/dist/enforcement/posthog.js +96 -0
- package/dist/enforcement/request-rules.d.ts +248 -0
- package/dist/enforcement/request-rules.js +434 -0
- package/dist/enforcement/script.d.ts +240 -0
- package/dist/enforcement/script.js +2 -0
- package/dist/index.d.ts +258 -0
- package/dist/index.js +445 -0
- package/dist/storage/localforage.d.ts +23 -0
- package/dist/storage/localforage.js +26 -0
- package/dist/storage/sync.d.ts +278 -0
- package/dist/storage/sync.js +370 -0
- package/dist/storage.d.ts +77 -0
- package/dist/storage.js +207 -0
- package/dist/validate-D16G7mdG.js +15 -0
- package/package.json +128 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as z from 'zod/mini';
|
|
2
|
+
|
|
3
|
+
declare type ConsentState = z.infer<typeof consentStateSchema>;
|
|
4
|
+
|
|
5
|
+
declare const consentStateSchema: z.ZodMiniReadonly<z.ZodMiniObject<{
|
|
6
|
+
choices: z.ZodMiniReadonly<z.ZodMiniArray<z.ZodMiniReadonly<z.ZodMiniObject<{
|
|
7
|
+
useId: z.ZodMiniString<string>;
|
|
8
|
+
consentVersion: z.ZodMiniInt;
|
|
9
|
+
decision: z.ZodMiniEnum<{
|
|
10
|
+
granted: "granted";
|
|
11
|
+
denied: "denied";
|
|
12
|
+
}>;
|
|
13
|
+
}, z.core.$strict>>>>;
|
|
14
|
+
}, z.core.$strict>>;
|
|
15
|
+
|
|
16
|
+
export declare type ConsentStorage = Readonly<{
|
|
17
|
+
/** Null means no record. Invalid or unreadable records return failure, never empty choices. */
|
|
18
|
+
load: () => Promise<ConsentStorageResult<ConsentState | null>>;
|
|
19
|
+
/** Captures validated state at invocation; writes run in invocation order. */
|
|
20
|
+
save: (state: unknown) => Promise<ConsentStorageResult<void>>;
|
|
21
|
+
/** Available only when the adapter supports external record invalidation. Does not load or save. */
|
|
22
|
+
subscribe?: (listener: () => void) => () => void;
|
|
23
|
+
}>;
|
|
24
|
+
|
|
25
|
+
/** One record, scoped by the adapter's key or endpoint. Only null means absent. */
|
|
26
|
+
export declare type ConsentStorageAdapter = Readonly<{
|
|
27
|
+
read: () => string | null | Promise<string | null>;
|
|
28
|
+
write: (record: string) => void | Promise<void>;
|
|
29
|
+
/** Optional lazy, key-scoped external invalidations; notifications contain no stored values. */
|
|
30
|
+
subscribe?: (listener: () => void) => () => void;
|
|
31
|
+
}>;
|
|
32
|
+
|
|
33
|
+
/** Storage failures deliberately exclude raw errors, URLs, headers, and stored values. */
|
|
34
|
+
export declare type ConsentStorageError = Readonly<{
|
|
35
|
+
type: 'read' | 'write';
|
|
36
|
+
}> | Readonly<{
|
|
37
|
+
type: 'validation';
|
|
38
|
+
issues: readonly ValidationIssue[];
|
|
39
|
+
}>;
|
|
40
|
+
|
|
41
|
+
export declare type ConsentStorageResult<T> = Readonly<{
|
|
42
|
+
success: true;
|
|
43
|
+
data: T;
|
|
44
|
+
}> | Readonly<{
|
|
45
|
+
success: false;
|
|
46
|
+
error: ConsentStorageError;
|
|
47
|
+
}>;
|
|
48
|
+
|
|
49
|
+
/** Explicit persistence, independent of any runtime. No reads/writes occur on creation. */
|
|
50
|
+
export declare function createConsentStorage(adapter: ConsentStorageAdapter): ConsentStorage;
|
|
51
|
+
|
|
52
|
+
/** GET returns the wire record (204/404 means absent); PUT replaces it. No retries. */
|
|
53
|
+
export declare function createFetchStorageAdapter({ url, fetch: fetchRequest, requestInit, }: FetchStorageAdapterOptions): ConsentStorageAdapter;
|
|
54
|
+
|
|
55
|
+
export declare function createLocalStorageAdapter({ key, storage }: LocalStorageAdapterOptions): ConsentStorageAdapter;
|
|
56
|
+
|
|
57
|
+
export declare type FetchStorageAdapterOptions = Readonly<{
|
|
58
|
+
url: string;
|
|
59
|
+
fetch?: typeof globalThis.fetch;
|
|
60
|
+
/** GET/PUT, body, no-store caching and rejected redirects are controlled by the adapter. */
|
|
61
|
+
requestInit?: Omit<RequestInit, 'method' | 'body' | 'cache' | 'redirect'>;
|
|
62
|
+
}>;
|
|
63
|
+
|
|
64
|
+
export declare type LocalStorageAdapterOptions = Readonly<{
|
|
65
|
+
key: string;
|
|
66
|
+
/** Defaults to globalThis.localStorage, resolved only during read/write/explicit subscription. */
|
|
67
|
+
storage?: Pick<Storage, 'getItem' | 'setItem'>;
|
|
68
|
+
}>;
|
|
69
|
+
|
|
70
|
+
/** A validation issue without a copy of the rejected input. */
|
|
71
|
+
declare type ValidationIssue = Readonly<{
|
|
72
|
+
code: string;
|
|
73
|
+
path: readonly (string | number)[];
|
|
74
|
+
message: string;
|
|
75
|
+
}>;
|
|
76
|
+
|
|
77
|
+
export { }
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { t as assertStorageIdentifier } from "./assertStorageIdentifier-BQuj-9bp.js";
|
|
2
|
+
import * as z from "zod/mini";
|
|
3
|
+
//#region src/utils/validation.ts
|
|
4
|
+
var nonemptyStringSchema = /* @__PURE__ */ (() => z.string({ error: "Expected a nonempty string." }).check(z.refine((value) => value.trim().length > 0, { error: "Expected a nonempty string." })))();
|
|
5
|
+
var consentVersionSchema = /* @__PURE__ */ (() => z.int({ error: "Expected a positive safe integer consent version." }).check(z.positive({ error: "Expected a positive safe integer consent version." })))();
|
|
6
|
+
/** Internal adapter: keep Zod errors out of the public result contract. */
|
|
7
|
+
function validateWithSchema(schema, input) {
|
|
8
|
+
const result = schema.safeParse(input, { error: (issue) => issue.code === "unrecognized_keys" ? `Unexpected fields: ${issue.keys.join(", ")}.` : issue.code === "invalid_type" ? `Expected ${issue.expected}.` : "Invalid consent data." });
|
|
9
|
+
if (result.success) return {
|
|
10
|
+
success: true,
|
|
11
|
+
data: result.data
|
|
12
|
+
};
|
|
13
|
+
return {
|
|
14
|
+
success: false,
|
|
15
|
+
issues: result.error.issues.map((issue) => ({
|
|
16
|
+
code: issue.code,
|
|
17
|
+
path: issue.path.map((segment) => typeof segment === "number" ? segment : String(segment)),
|
|
18
|
+
message: issue.message
|
|
19
|
+
}))
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/consent/schemas.ts
|
|
24
|
+
var consentDecisionSchema = /* @__PURE__ */ z.enum(["granted", "denied"], { error: "Expected granted or denied." });
|
|
25
|
+
var consentChoiceSchema = /* @__PURE__ */ (() => z.readonly(z.strictObject({
|
|
26
|
+
useId: nonemptyStringSchema,
|
|
27
|
+
consentVersion: consentVersionSchema,
|
|
28
|
+
decision: consentDecisionSchema
|
|
29
|
+
})))();
|
|
30
|
+
var consentStateSchema = /* @__PURE__ */ (() => z.readonly(z.strictObject({ choices: z.readonly(z.array(consentChoiceSchema).check((context) => {
|
|
31
|
+
const ids = /* @__PURE__ */ new Set();
|
|
32
|
+
context.value.forEach((choice, index) => {
|
|
33
|
+
if (ids.has(choice.useId)) context.issues.push({
|
|
34
|
+
code: "custom",
|
|
35
|
+
path: [index, "useId"],
|
|
36
|
+
message: "Only one consent choice per use is allowed.",
|
|
37
|
+
input: choice.useId
|
|
38
|
+
});
|
|
39
|
+
ids.add(choice.useId);
|
|
40
|
+
});
|
|
41
|
+
})) })))();
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/storage/schemas.ts
|
|
44
|
+
var consentRecordV1Schema = /* @__PURE__ */ (() => z.readonly(z.strictObject({
|
|
45
|
+
formatVersion: z.literal(1),
|
|
46
|
+
state: consentStateSchema
|
|
47
|
+
})))();
|
|
48
|
+
var consentRecordHeaderSchema = /* @__PURE__ */ (() => z.object({ formatVersion: z.int().check(z.positive()) }))();
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/storage/decodeConsentState.ts
|
|
51
|
+
function failure(code, message, path = []) {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
issues: [{
|
|
55
|
+
code,
|
|
56
|
+
path,
|
|
57
|
+
message
|
|
58
|
+
}]
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Restores validated choices, not permissions. Missing storage is handled by the caller. */
|
|
62
|
+
function decodeConsentState(input) {
|
|
63
|
+
if (typeof input !== "string") return failure("invalid_type", "Expected a JSON string.");
|
|
64
|
+
let record;
|
|
65
|
+
try {
|
|
66
|
+
record = JSON.parse(input);
|
|
67
|
+
} catch {
|
|
68
|
+
return failure("invalid_json", "Invalid consent JSON.");
|
|
69
|
+
}
|
|
70
|
+
const header = validateWithSchema(consentRecordHeaderSchema, record);
|
|
71
|
+
if (!header.success) return header;
|
|
72
|
+
if (header.data.formatVersion !== 1) return failure("unsupported_format_version", "Unsupported consent storage format version.", ["formatVersion"]);
|
|
73
|
+
const result = validateWithSchema(consentRecordV1Schema, record);
|
|
74
|
+
if (!result.success) return result;
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
data: result.data.state
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/storage/encodeConsentState.ts
|
|
82
|
+
/** Encodes decoded JSON-like choices without policy reconciliation or storage I/O. */
|
|
83
|
+
function encodeConsentState(input) {
|
|
84
|
+
const result = validateWithSchema(consentRecordV1Schema, {
|
|
85
|
+
formatVersion: 1,
|
|
86
|
+
state: input
|
|
87
|
+
});
|
|
88
|
+
if (!result.success) return result;
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
data: JSON.stringify(result.data)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
//#region src/storage/createConsentStorage.ts
|
|
96
|
+
/** Explicit persistence, independent of any runtime. No reads/writes occur on creation. */
|
|
97
|
+
function createConsentStorage(adapter) {
|
|
98
|
+
let pending = Promise.resolve();
|
|
99
|
+
const subscribe = adapter.subscribe;
|
|
100
|
+
function enqueue(operation) {
|
|
101
|
+
const result = pending.then(operation);
|
|
102
|
+
pending = result.then(() => void 0, () => void 0);
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
return Object.freeze({
|
|
106
|
+
...subscribe ? { subscribe: (listener) => subscribe.call(adapter, listener) } : {},
|
|
107
|
+
load: () => enqueue(async () => {
|
|
108
|
+
let record;
|
|
109
|
+
try {
|
|
110
|
+
record = await adapter.read();
|
|
111
|
+
} catch {
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error: { type: "read" }
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (record === null) return {
|
|
118
|
+
success: true,
|
|
119
|
+
data: null
|
|
120
|
+
};
|
|
121
|
+
const decoded = decodeConsentState(record);
|
|
122
|
+
return decoded.success ? decoded : {
|
|
123
|
+
success: false,
|
|
124
|
+
error: {
|
|
125
|
+
type: "validation",
|
|
126
|
+
issues: decoded.issues
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}),
|
|
130
|
+
save: (state) => {
|
|
131
|
+
const encoded = encodeConsentState(state);
|
|
132
|
+
if (!encoded.success) return Promise.resolve({
|
|
133
|
+
success: false,
|
|
134
|
+
error: {
|
|
135
|
+
type: "validation",
|
|
136
|
+
issues: encoded.issues
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
return enqueue(async () => {
|
|
140
|
+
try {
|
|
141
|
+
await adapter.write(encoded.data);
|
|
142
|
+
return {
|
|
143
|
+
success: true,
|
|
144
|
+
data: void 0
|
|
145
|
+
};
|
|
146
|
+
} catch {
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
error: { type: "write" }
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/storage/fetch/createFetchStorageAdapter.ts
|
|
158
|
+
/** GET returns the wire record (204/404 means absent); PUT replaces it. No retries. */
|
|
159
|
+
function createFetchStorageAdapter({ url, fetch: fetchRequest, requestInit }) {
|
|
160
|
+
assertStorageIdentifier(url);
|
|
161
|
+
async function request(method, body) {
|
|
162
|
+
const headers = new Headers(requestInit?.headers);
|
|
163
|
+
headers.set("Accept", "application/json");
|
|
164
|
+
if (method === "PUT") headers.set("Content-Type", "application/json");
|
|
165
|
+
const init = {
|
|
166
|
+
...requestInit,
|
|
167
|
+
method,
|
|
168
|
+
headers,
|
|
169
|
+
body: body ?? null,
|
|
170
|
+
cache: "no-store",
|
|
171
|
+
redirect: "error"
|
|
172
|
+
};
|
|
173
|
+
return fetchRequest ? fetchRequest(url, init) : globalThis.fetch(url, init);
|
|
174
|
+
}
|
|
175
|
+
return Object.freeze({
|
|
176
|
+
read: async () => {
|
|
177
|
+
const response = await request("GET");
|
|
178
|
+
if (response.status === 204 || response.status === 404) return null;
|
|
179
|
+
if (response.status !== 200) throw new Error(`Consent read failed (HTTP ${response.status}).`);
|
|
180
|
+
return response.text();
|
|
181
|
+
},
|
|
182
|
+
write: async (record) => {
|
|
183
|
+
const response = await request("PUT", record);
|
|
184
|
+
if (!response.ok) throw new Error(`Consent write failed (HTTP ${response.status}).`);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
//#endregion
|
|
189
|
+
//#region src/storage/localstorage/createLocalStorageAdapter.ts
|
|
190
|
+
function createLocalStorageAdapter({ key, storage }) {
|
|
191
|
+
assertStorageIdentifier(key);
|
|
192
|
+
return Object.freeze({
|
|
193
|
+
read: () => (storage ?? globalThis.localStorage).getItem(key),
|
|
194
|
+
write: (record) => (storage ?? globalThis.localStorage).setItem(key, record),
|
|
195
|
+
subscribe(listener) {
|
|
196
|
+
if (typeof window === "undefined") return () => {};
|
|
197
|
+
const backend = storage ?? globalThis.localStorage;
|
|
198
|
+
const changed = (event) => {
|
|
199
|
+
if (event.storageArea === backend && (event.key === key || event.key === null)) listener();
|
|
200
|
+
};
|
|
201
|
+
window.addEventListener("storage", changed);
|
|
202
|
+
return () => window.removeEventListener("storage", changed);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
//#endregion
|
|
207
|
+
export { createConsentStorage, createFetchStorageAdapter, createLocalStorageAdapter };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/enforcement/_utils/validate.ts
|
|
2
|
+
/**
|
|
3
|
+
* Constructor guard shared by every enforcement entry point. Runs before any caller-supplied
|
|
4
|
+
* getter, so a malformed guard is rejected at creation rather than during a granted call.
|
|
5
|
+
*/
|
|
6
|
+
function requireConsent(consent) {
|
|
7
|
+
const candidate = consent;
|
|
8
|
+
if (!candidate || typeof candidate.evaluate !== "function" || typeof candidate.subscribe !== "function") throw new TypeError("Expected a consent runtime.");
|
|
9
|
+
}
|
|
10
|
+
/** Use IDs are exact: surrounding whitespace is significant and never trimmed. */
|
|
11
|
+
function requireUseId(useId) {
|
|
12
|
+
if (typeof useId !== "string" || useId.trim().length === 0) throw new TypeError("Expected a non blank use ID.");
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { requireUseId as n, requireConsent as t };
|
package/package.json
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@peax/consent-core",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Framework-independent consent state and runtime primitives.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"consent-management",
|
|
7
|
+
"cookie-consent",
|
|
8
|
+
"privacy",
|
|
9
|
+
"gdpr",
|
|
10
|
+
"typescript",
|
|
11
|
+
"framework-agnostic"
|
|
12
|
+
],
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"homepage": "https://github.com/peaxco/consent",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/peaxco/consent.git",
|
|
18
|
+
"directory": "packages/consent-core"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/peaxco/consent/issues"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"module": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./enforcement/fetch": {
|
|
38
|
+
"types": "./dist/enforcement/fetch.d.ts",
|
|
39
|
+
"import": "./dist/enforcement/fetch.js",
|
|
40
|
+
"default": "./dist/enforcement/fetch.js"
|
|
41
|
+
},
|
|
42
|
+
"./enforcement/axios": {
|
|
43
|
+
"types": "./dist/enforcement/axios.d.ts",
|
|
44
|
+
"import": "./dist/enforcement/axios.js",
|
|
45
|
+
"default": "./dist/enforcement/axios.js"
|
|
46
|
+
},
|
|
47
|
+
"./enforcement/request-rules": {
|
|
48
|
+
"types": "./dist/enforcement/request-rules.d.ts",
|
|
49
|
+
"import": "./dist/enforcement/request-rules.js",
|
|
50
|
+
"default": "./dist/enforcement/request-rules.js"
|
|
51
|
+
},
|
|
52
|
+
"./enforcement/script": {
|
|
53
|
+
"types": "./dist/enforcement/script.d.ts",
|
|
54
|
+
"import": "./dist/enforcement/script.js",
|
|
55
|
+
"default": "./dist/enforcement/script.js"
|
|
56
|
+
},
|
|
57
|
+
"./enforcement/iframe": {
|
|
58
|
+
"types": "./dist/enforcement/iframe.d.ts",
|
|
59
|
+
"import": "./dist/enforcement/iframe.js",
|
|
60
|
+
"default": "./dist/enforcement/iframe.js"
|
|
61
|
+
},
|
|
62
|
+
"./enforcement/integration": {
|
|
63
|
+
"types": "./dist/enforcement/integration.d.ts",
|
|
64
|
+
"import": "./dist/enforcement/integration.js",
|
|
65
|
+
"default": "./dist/enforcement/integration.js"
|
|
66
|
+
},
|
|
67
|
+
"./enforcement/posthog": {
|
|
68
|
+
"types": "./dist/enforcement/posthog.d.ts",
|
|
69
|
+
"import": "./dist/enforcement/posthog.js",
|
|
70
|
+
"default": "./dist/enforcement/posthog.js"
|
|
71
|
+
},
|
|
72
|
+
"./enforcement/markup": {
|
|
73
|
+
"types": "./dist/enforcement/markup.d.ts",
|
|
74
|
+
"import": "./dist/enforcement/markup.js",
|
|
75
|
+
"default": "./dist/enforcement/markup.js"
|
|
76
|
+
},
|
|
77
|
+
"./storage": {
|
|
78
|
+
"types": "./dist/storage.d.ts",
|
|
79
|
+
"import": "./dist/storage.js",
|
|
80
|
+
"default": "./dist/storage.js"
|
|
81
|
+
},
|
|
82
|
+
"./storage/localforage": {
|
|
83
|
+
"types": "./dist/storage/localforage.d.ts",
|
|
84
|
+
"import": "./dist/storage/localforage.js",
|
|
85
|
+
"default": "./dist/storage/localforage.js"
|
|
86
|
+
},
|
|
87
|
+
"./storage/sync": {
|
|
88
|
+
"types": "./dist/storage/sync.d.ts",
|
|
89
|
+
"import": "./dist/storage/sync.js",
|
|
90
|
+
"default": "./dist/storage/sync.js"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"publishConfig": {
|
|
94
|
+
"access": "public",
|
|
95
|
+
"provenance": true,
|
|
96
|
+
"registry": "https://registry.npmjs.org"
|
|
97
|
+
},
|
|
98
|
+
"scripts": {
|
|
99
|
+
"build": "vite build && vite build --mode entries",
|
|
100
|
+
"test": "vitest run",
|
|
101
|
+
"typecheck": "tsc --noEmit"
|
|
102
|
+
},
|
|
103
|
+
"dependencies": {
|
|
104
|
+
"zod": "^4.6.5"
|
|
105
|
+
},
|
|
106
|
+
"peerDependencies": {
|
|
107
|
+
"axios": "^1.20.0",
|
|
108
|
+
"localforage": "^1.10.0"
|
|
109
|
+
},
|
|
110
|
+
"peerDependenciesMeta": {
|
|
111
|
+
"axios": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
114
|
+
"localforage": {
|
|
115
|
+
"optional": true
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"devDependencies": {
|
|
119
|
+
"@types/node": "^26.6.4",
|
|
120
|
+
"axios": "^1.20.0",
|
|
121
|
+
"jsdom": "30.1.1",
|
|
122
|
+
"localforage": "^1.10.0",
|
|
123
|
+
"typescript": "5.9.3",
|
|
124
|
+
"vite": "^8.3.2",
|
|
125
|
+
"vite-plugin-dts": "^5.1.1",
|
|
126
|
+
"vitest": "^5.0.3"
|
|
127
|
+
}
|
|
128
|
+
}
|