@tantainnovative/ndpr-toolkit 4.0.0 → 5.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/dist/chunk-4FXRJH37.js +1 -0
  3. package/dist/{chunk-3XU6FL2I.js → chunk-6YFPDGNB.js} +1 -1
  4. package/dist/{chunk-WMISQDSV.js → chunk-ASEUTU45.js} +1 -1
  5. package/dist/chunk-BRJKIF7E.mjs +1 -0
  6. package/dist/{chunk-XYGGUGTO.js → chunk-CSE36REY.js} +4 -4
  7. package/dist/chunk-DKLJ5DYN.js +1 -0
  8. package/dist/chunk-FRMVSG4N.mjs +1 -0
  9. package/dist/chunk-MAD7QYRK.js +1 -0
  10. package/dist/chunk-NBOJ2KGN.mjs +1 -0
  11. package/dist/chunk-PQ5IPUJN.mjs +1 -0
  12. package/dist/{chunk-BGV2AKT7.mjs → chunk-PSPYIRIF.mjs} +1 -1
  13. package/dist/chunk-QKXGVT2Q.js +1 -0
  14. package/dist/chunk-R2ZZMATR.js +1 -0
  15. package/dist/chunk-R3ZKV2J7.mjs +1 -0
  16. package/dist/chunk-RRVML7CU.mjs +1 -0
  17. package/dist/{chunk-NB6SKG76.mjs → chunk-SBSYHCPK.mjs} +1 -1
  18. package/dist/chunk-TLIHFGIJ.js +1 -0
  19. package/dist/{chunk-5F2IAUWJ.js → chunk-TVA6D6S4.js} +1 -1
  20. package/dist/{chunk-42JPSNVV.mjs → chunk-WPH6CJDL.mjs} +4 -4
  21. package/dist/{chunk-GUERZD4O.mjs → chunk-ZSRO4L3C.mjs} +1 -1
  22. package/dist/consent.d.mts +59 -19
  23. package/dist/consent.d.ts +59 -19
  24. package/dist/consent.js +1 -1
  25. package/dist/consent.mjs +1 -1
  26. package/dist/core.d.mts +124 -69
  27. package/dist/core.d.ts +124 -69
  28. package/dist/core.js +1 -1
  29. package/dist/core.mjs +1 -1
  30. package/dist/cross-border.d.mts +7 -6
  31. package/dist/cross-border.d.ts +7 -6
  32. package/dist/cross-border.js +1 -1
  33. package/dist/cross-border.mjs +1 -1
  34. package/dist/dsr.d.mts +86 -54
  35. package/dist/dsr.d.ts +86 -54
  36. package/dist/dsr.js +1 -1
  37. package/dist/dsr.mjs +1 -1
  38. package/dist/headless.d.mts +23 -9
  39. package/dist/headless.d.ts +23 -9
  40. package/dist/headless.js +1 -1
  41. package/dist/headless.mjs +1 -1
  42. package/dist/hooks.d.mts +23 -9
  43. package/dist/hooks.d.ts +23 -9
  44. package/dist/hooks.js +1 -1
  45. package/dist/hooks.mjs +1 -1
  46. package/dist/index.d.mts +144 -95
  47. package/dist/index.d.ts +144 -95
  48. package/dist/index.js +1 -1
  49. package/dist/index.mjs +1 -1
  50. package/dist/lawful-basis.d.mts +6 -6
  51. package/dist/lawful-basis.d.ts +6 -6
  52. package/dist/lawful-basis.js +1 -1
  53. package/dist/lawful-basis.mjs +1 -1
  54. package/dist/presets.d.mts +87 -2
  55. package/dist/presets.d.ts +87 -2
  56. package/dist/presets.js +1 -1
  57. package/dist/presets.mjs +1 -1
  58. package/dist/ropa-lite.d.mts +4 -1
  59. package/dist/ropa-lite.d.ts +4 -1
  60. package/dist/ropa-lite.js +1 -1
  61. package/dist/ropa-lite.mjs +1 -1
  62. package/dist/ropa.d.mts +16 -16
  63. package/dist/ropa.d.ts +16 -16
  64. package/dist/ropa.js +1 -1
  65. package/dist/ropa.mjs +1 -1
  66. package/dist/server.d.mts +123 -68
  67. package/dist/server.d.ts +123 -68
  68. package/dist/server.js +1 -1
  69. package/dist/server.mjs +1 -1
  70. package/dist/styles.css +18 -16
  71. package/package.json +1 -1
  72. package/dist/chunk-7FXNGGMO.js +0 -1
  73. package/dist/chunk-B46SJB5V.js +0 -1
  74. package/dist/chunk-BL5W472Q.js +0 -1
  75. package/dist/chunk-HOAC5VUF.js +0 -1
  76. package/dist/chunk-IHNAFXDM.mjs +0 -1
  77. package/dist/chunk-O2WEABB3.js +0 -1
  78. package/dist/chunk-OZHUINWS.js +0 -1
  79. package/dist/chunk-PJNKQPQP.mjs +0 -1
  80. package/dist/chunk-RBKFNCGO.mjs +0 -1
  81. package/dist/chunk-VPNK7OID.mjs +0 -1
  82. package/dist/chunk-WKUC65HL.mjs +0 -1
  83. package/dist/chunk-Z2M5VJX2.mjs +0 -1
package/dist/core.d.mts CHANGED
@@ -16,6 +16,10 @@ export declare type AdequacyStatus = 'adequate' | 'inadequate' | 'pending_review
16
16
  */
17
17
  export declare function appendAuditEntry(entry: ConsentAuditEntry, storageKey?: string): void;
18
18
 
19
+ export declare const arabicLocale: Required<{
20
+ [K in keyof NDPRLocale]: Required<NonNullable<NDPRLocale[K]>>;
21
+ }>;
22
+
19
23
  /**
20
24
  * Assemble an ordered, NDPA-aligned array of privacy-policy sections from
21
25
  * a {@link TemplateContext}. This is the canonical "compute the policy"
@@ -811,7 +815,7 @@ export declare type DSRStatus = 'pending' | 'awaitingVerification' | 'inProgress
811
815
  /**
812
816
  * Validated DSR submission shape — matches what `<DSRRequestForm onSubmit>`
813
817
  * emits client-side. Use this as the typed parameter for your server-side
814
- * handler after `validateDsrSubmission` returns `valid: true`.
818
+ * handler after `validateDsrSubmissionStructured` returns `valid: true`.
815
819
  */
816
820
  export declare interface DsrSubmissionPayload {
817
821
  requestType: string;
@@ -826,16 +830,6 @@ export declare interface DsrSubmissionPayload {
826
830
  submittedAt: number;
827
831
  }
828
832
 
829
- /** Result of validating a raw DSR submission payload. */
830
- export declare interface DsrSubmissionValidationResult {
831
- /** True when the payload conforms to the DSR submission contract. */
832
- valid: boolean;
833
- /** Field-keyed error messages. Empty when `valid` is true. */
834
- errors: Record<string, string>;
835
- /** The narrowed, typed payload — only populated when `valid` is true. */
836
- data?: DsrSubmissionPayload;
837
- }
838
-
839
833
  /**
840
834
  * Data Subject Rights types aligned with NDPA 2023 Part VI (Sections 34-38)
841
835
  * and the related provisions in Part V (Section 27 — information to the data subject)
@@ -932,15 +926,33 @@ export declare function exportROPAToCSV(ropa: RecordOfProcessingActivities): str
932
926
  export declare function findUnfilledTokens(rendered: string): string[];
933
927
 
934
928
  /**
935
- * Formats a DSR request for display or submission
936
- * @param request The DSR request to format
937
- * @returns Formatted request data
938
- */
939
- export declare function formatDSRRequest(request: DSRRequest): {
929
+ * Format a DSR request for display or submission. Returns the formatted
930
+ * payload plus a typed `errors` array of `{ field, code, message }` for any
931
+ * required fields missing from the source request.
932
+ *
933
+ * Codes emitted:
934
+ * - `request_id_required`
935
+ * - `request_type_required`
936
+ * - `request_status_required`
937
+ * - `created_at_required`
938
+ * - `subject_name_required`
939
+ * - `subject_email_required`
940
+ */
941
+ export declare function formatDSRRequestStructured(request: DSRRequest): FormatDSRRequestStructuredResult;
942
+
943
+ /** Result of {@link formatDSRRequestStructured}. */
944
+ export declare interface FormatDSRRequestStructuredResult {
945
+ valid: boolean;
946
+ errors: StructuredValidationError[];
947
+ /** Formatted request payload — always populated regardless of `valid`. */
940
948
  formattedRequest: Record<string, unknown>;
941
- isValid: boolean;
942
- validationErrors: string[];
943
- };
949
+ /** Narrowed input — populated only on `valid: true`. */
950
+ data?: DSRRequest;
951
+ }
952
+
953
+ export declare const frenchLocale: Required<{
954
+ [K in keyof NDPRLocale]: Required<NonNullable<NDPRLocale[K]>>;
955
+ }>;
944
956
 
945
957
  /**
946
958
  * Generates a summary of all lawful basis documentation across processing activities.
@@ -2007,6 +2019,30 @@ export declare interface StorageAdapter<T = unknown> {
2007
2019
  remove(): void | Promise<void>;
2008
2020
  }
2009
2021
 
2022
+ /**
2023
+ * Single structured validation error with a stable, locale-independent
2024
+ * `code` consumers can switch on programmatically.
2025
+ */
2026
+ export declare interface StructuredValidationError {
2027
+ /** Dot-path of the offending field (e.g. `'timestamp'`, `'dataSubject.email'`, `'options[0].purpose'`). */
2028
+ field: string;
2029
+ /** Stable, snake_case error code — safe to switch on across locales. */
2030
+ code: string;
2031
+ /** Human-readable English message — informational only; do not regex-match. */
2032
+ message: string;
2033
+ }
2034
+
2035
+ /**
2036
+ * Result of a structured validator. `errors` is an array (one entry per
2037
+ * failed rule). `data` is the narrowed, typed payload, only populated on
2038
+ * `valid: true`.
2039
+ */
2040
+ export declare interface StructuredValidationResult<T> {
2041
+ valid: boolean;
2042
+ errors: StructuredValidationError[];
2043
+ data?: T;
2044
+ }
2045
+
2010
2046
  /** Full context used to generate an adaptive privacy policy. */
2011
2047
  export declare interface TemplateContext {
2012
2048
  /** Organisation details, extended with industry and size. */
@@ -2146,66 +2182,43 @@ export declare function useNDPRConfig(): NDPRConfig;
2146
2182
  export declare function useNDPRLocale(): typeof defaultLocale;
2147
2183
 
2148
2184
  /**
2149
- * Validates consent settings to ensure they meet NDPA requirements
2150
- * @param settings The consent settings to validate
2151
- * @returns An object containing validation result and any error messages
2152
- */
2153
- export declare function validateConsent(settings: ConsentSettings): {
2154
- valid: boolean;
2155
- errors: string[];
2156
- };
2157
-
2158
- /**
2159
- * Validates that consent options meet NDPA Section 26 requirements.
2160
- * Each consent option must specify a purpose for which data will be processed,
2161
- * as consent must be specific and informed per the Nigeria Data Protection Act.
2162
- * @param options The consent options to validate
2163
- * @returns An object containing validation result and any error messages
2185
+ * Validates consent options against NDPA Section 26 requirements. Each option
2186
+ * is checked for a non-empty `purpose`. Failing options are reported with
2187
+ * `field: 'options[i].purpose'` so consumers can map errors back to the
2188
+ * originating option index.
2189
+ *
2190
+ * Codes emitted:
2191
+ * - `options_required` — empty / missing options array
2192
+ * - `purpose_required` — single option missing a purpose
2164
2193
  */
2165
- export declare function validateConsentOptions(options: ConsentOption[]): {
2166
- valid: boolean;
2167
- errors: string[];
2168
- };
2194
+ export declare function validateConsentOptionsStructured(options: ConsentOption[]): StructuredValidationResult<ConsentOption[]>;
2169
2195
 
2170
2196
  /**
2171
- * Validate a raw DSR submission payload against the same rules
2172
- * `<DSRRequestForm />` enforces client-side. Designed to be called from a
2173
- * server-side handler (Next.js Route Handler, NestJS controller, Express
2174
- * middleware, Cloudflare Worker) so client and server stay in sync without
2175
- * the consumer hand-rolling zod / class-validator schemas.
2197
+ * Validates consent settings against NDPA requirements. Returns structured
2198
+ * `{ field, code, message }[]` errors so consumers can switch on `code`
2199
+ * across locales without regex-matching English strings.
2176
2200
  *
2177
- * Defensive — accepts `unknown` and narrows. Safe to call directly on
2178
- * `await request.json()`.
2201
+ * Codes emitted:
2202
+ * - `consents_required`
2203
+ * - `timestamp_required`
2204
+ * - `timestamp_invalid`
2205
+ * - `version_required`
2206
+ * - `method_required`
2207
+ * - `has_interacted_required`
2208
+ * - `consent_stale`
2179
2209
  *
2180
- * @example **Next.js Route Handler**
2210
+ * @example
2181
2211
  * ```ts
2182
- * // app/api/dsr/route.ts
2183
- * import { validateDsrSubmission } from '@tantainnovative/ndpr-toolkit/server';
2184
- *
2185
- * export async function POST(req: Request) {
2186
- * const { valid, errors, data } = validateDsrSubmission(await req.json());
2187
- * if (!valid) return Response.json({ errors }, { status: 422 });
2188
- * // `data` is the typed DsrSubmissionPayload
2189
- * await dsrStore.create(data);
2190
- * return Response.json({ ok: true }, { status: 201 });
2212
+ * const { valid, errors, data } = validateConsentStructured(settings);
2213
+ * if (!valid) {
2214
+ * const stale = errors.find((e) => e.code === 'consent_stale');
2215
+ * if (stale) showRefreshBanner();
2191
2216
  * }
2192
2217
  * ```
2193
- *
2194
- * @example **Lock to specific request types**
2195
- * ```ts
2196
- * validateDsrSubmission(payload, {
2197
- * allowedRequestTypes: ['access', 'erasure', 'rectification'],
2198
- * });
2199
- * ```
2200
- *
2201
- * @example **Skip identity verification (e.g. authenticated session)**
2202
- * ```ts
2203
- * validateDsrSubmission(payload, { requireIdentityVerification: false });
2204
- * ```
2205
2218
  */
2206
- export declare function validateDsrSubmission(payload: unknown, options?: ValidateDsrSubmissionOptions): DsrSubmissionValidationResult;
2219
+ export declare function validateConsentStructured(settings: ConsentSettings): StructuredValidationResult<ConsentSettings>;
2207
2220
 
2208
- /** Options for {@link validateDsrSubmission}. */
2221
+ /** Options for {@link validateDsrSubmissionStructured}. */
2209
2222
  export declare interface ValidateDsrSubmissionOptions {
2210
2223
  /**
2211
2224
  * Whether the data subject is required to provide an identifier
@@ -2222,6 +2235,48 @@ export declare interface ValidateDsrSubmissionOptions {
2222
2235
  allowedRequestTypes?: string[];
2223
2236
  }
2224
2237
 
2238
+ /**
2239
+ * Validate a raw DSR submission payload against the same rules
2240
+ * `<DSRRequestForm />` enforces client-side. Designed to be called from a
2241
+ * server-side handler (Next.js Route Handler, NestJS controller, Express
2242
+ * middleware, Cloudflare Worker) so client and server stay in sync without
2243
+ * the consumer hand-rolling zod / class-validator schemas.
2244
+ *
2245
+ * Defensive — accepts `unknown` and narrows. Safe to call directly on
2246
+ * `await request.json()`. Returns `{ field, code, message }[]` errors so
2247
+ * callers can switch on `code` programmatically across locales.
2248
+ *
2249
+ * Codes emitted:
2250
+ * - `payload_not_object`
2251
+ * - `request_type_required`
2252
+ * - `request_type_not_allowed`
2253
+ * - `data_subject_required`
2254
+ * - `full_name_required`
2255
+ * - `email_required`
2256
+ * - `email_invalid_format`
2257
+ * - `phone_invalid_type`
2258
+ * - `identifier_type_required`
2259
+ * - `identifier_value_required`
2260
+ * - `submitted_at_invalid`
2261
+ * - `additional_info_invalid_type`
2262
+ * - `payload_final_narrowing_failed`
2263
+ *
2264
+ * @example **Next.js Route Handler**
2265
+ * ```ts
2266
+ * import { validateDsrSubmissionStructured } from '@tantainnovative/ndpr-toolkit/server';
2267
+ *
2268
+ * export async function POST(req: Request) {
2269
+ * const { valid, errors, data } = validateDsrSubmissionStructured(await req.json());
2270
+ * if (!valid) {
2271
+ * return Response.json({ errors }, { status: 422 });
2272
+ * }
2273
+ * await dsrStore.create(data);
2274
+ * return Response.json({ ok: true }, { status: 201 });
2275
+ * }
2276
+ * ```
2277
+ */
2278
+ export declare function validateDsrSubmissionStructured(payload: unknown, options?: ValidateDsrSubmissionOptions): StructuredValidationResult<DsrSubmissionPayload>;
2279
+
2225
2280
  /**
2226
2281
  * Validates that all required fields are present on a processing activity
2227
2282
  * and that the lawful basis is properly documented.
package/dist/core.d.ts CHANGED
@@ -16,6 +16,10 @@ export declare type AdequacyStatus = 'adequate' | 'inadequate' | 'pending_review
16
16
  */
17
17
  export declare function appendAuditEntry(entry: ConsentAuditEntry, storageKey?: string): void;
18
18
 
19
+ export declare const arabicLocale: Required<{
20
+ [K in keyof NDPRLocale]: Required<NonNullable<NDPRLocale[K]>>;
21
+ }>;
22
+
19
23
  /**
20
24
  * Assemble an ordered, NDPA-aligned array of privacy-policy sections from
21
25
  * a {@link TemplateContext}. This is the canonical "compute the policy"
@@ -811,7 +815,7 @@ export declare type DSRStatus = 'pending' | 'awaitingVerification' | 'inProgress
811
815
  /**
812
816
  * Validated DSR submission shape — matches what `<DSRRequestForm onSubmit>`
813
817
  * emits client-side. Use this as the typed parameter for your server-side
814
- * handler after `validateDsrSubmission` returns `valid: true`.
818
+ * handler after `validateDsrSubmissionStructured` returns `valid: true`.
815
819
  */
816
820
  export declare interface DsrSubmissionPayload {
817
821
  requestType: string;
@@ -826,16 +830,6 @@ export declare interface DsrSubmissionPayload {
826
830
  submittedAt: number;
827
831
  }
828
832
 
829
- /** Result of validating a raw DSR submission payload. */
830
- export declare interface DsrSubmissionValidationResult {
831
- /** True when the payload conforms to the DSR submission contract. */
832
- valid: boolean;
833
- /** Field-keyed error messages. Empty when `valid` is true. */
834
- errors: Record<string, string>;
835
- /** The narrowed, typed payload — only populated when `valid` is true. */
836
- data?: DsrSubmissionPayload;
837
- }
838
-
839
833
  /**
840
834
  * Data Subject Rights types aligned with NDPA 2023 Part VI (Sections 34-38)
841
835
  * and the related provisions in Part V (Section 27 — information to the data subject)
@@ -932,15 +926,33 @@ export declare function exportROPAToCSV(ropa: RecordOfProcessingActivities): str
932
926
  export declare function findUnfilledTokens(rendered: string): string[];
933
927
 
934
928
  /**
935
- * Formats a DSR request for display or submission
936
- * @param request The DSR request to format
937
- * @returns Formatted request data
938
- */
939
- export declare function formatDSRRequest(request: DSRRequest): {
929
+ * Format a DSR request for display or submission. Returns the formatted
930
+ * payload plus a typed `errors` array of `{ field, code, message }` for any
931
+ * required fields missing from the source request.
932
+ *
933
+ * Codes emitted:
934
+ * - `request_id_required`
935
+ * - `request_type_required`
936
+ * - `request_status_required`
937
+ * - `created_at_required`
938
+ * - `subject_name_required`
939
+ * - `subject_email_required`
940
+ */
941
+ export declare function formatDSRRequestStructured(request: DSRRequest): FormatDSRRequestStructuredResult;
942
+
943
+ /** Result of {@link formatDSRRequestStructured}. */
944
+ export declare interface FormatDSRRequestStructuredResult {
945
+ valid: boolean;
946
+ errors: StructuredValidationError[];
947
+ /** Formatted request payload — always populated regardless of `valid`. */
940
948
  formattedRequest: Record<string, unknown>;
941
- isValid: boolean;
942
- validationErrors: string[];
943
- };
949
+ /** Narrowed input — populated only on `valid: true`. */
950
+ data?: DSRRequest;
951
+ }
952
+
953
+ export declare const frenchLocale: Required<{
954
+ [K in keyof NDPRLocale]: Required<NonNullable<NDPRLocale[K]>>;
955
+ }>;
944
956
 
945
957
  /**
946
958
  * Generates a summary of all lawful basis documentation across processing activities.
@@ -2007,6 +2019,30 @@ export declare interface StorageAdapter<T = unknown> {
2007
2019
  remove(): void | Promise<void>;
2008
2020
  }
2009
2021
 
2022
+ /**
2023
+ * Single structured validation error with a stable, locale-independent
2024
+ * `code` consumers can switch on programmatically.
2025
+ */
2026
+ export declare interface StructuredValidationError {
2027
+ /** Dot-path of the offending field (e.g. `'timestamp'`, `'dataSubject.email'`, `'options[0].purpose'`). */
2028
+ field: string;
2029
+ /** Stable, snake_case error code — safe to switch on across locales. */
2030
+ code: string;
2031
+ /** Human-readable English message — informational only; do not regex-match. */
2032
+ message: string;
2033
+ }
2034
+
2035
+ /**
2036
+ * Result of a structured validator. `errors` is an array (one entry per
2037
+ * failed rule). `data` is the narrowed, typed payload, only populated on
2038
+ * `valid: true`.
2039
+ */
2040
+ export declare interface StructuredValidationResult<T> {
2041
+ valid: boolean;
2042
+ errors: StructuredValidationError[];
2043
+ data?: T;
2044
+ }
2045
+
2010
2046
  /** Full context used to generate an adaptive privacy policy. */
2011
2047
  export declare interface TemplateContext {
2012
2048
  /** Organisation details, extended with industry and size. */
@@ -2146,66 +2182,43 @@ export declare function useNDPRConfig(): NDPRConfig;
2146
2182
  export declare function useNDPRLocale(): typeof defaultLocale;
2147
2183
 
2148
2184
  /**
2149
- * Validates consent settings to ensure they meet NDPA requirements
2150
- * @param settings The consent settings to validate
2151
- * @returns An object containing validation result and any error messages
2152
- */
2153
- export declare function validateConsent(settings: ConsentSettings): {
2154
- valid: boolean;
2155
- errors: string[];
2156
- };
2157
-
2158
- /**
2159
- * Validates that consent options meet NDPA Section 26 requirements.
2160
- * Each consent option must specify a purpose for which data will be processed,
2161
- * as consent must be specific and informed per the Nigeria Data Protection Act.
2162
- * @param options The consent options to validate
2163
- * @returns An object containing validation result and any error messages
2185
+ * Validates consent options against NDPA Section 26 requirements. Each option
2186
+ * is checked for a non-empty `purpose`. Failing options are reported with
2187
+ * `field: 'options[i].purpose'` so consumers can map errors back to the
2188
+ * originating option index.
2189
+ *
2190
+ * Codes emitted:
2191
+ * - `options_required` — empty / missing options array
2192
+ * - `purpose_required` — single option missing a purpose
2164
2193
  */
2165
- export declare function validateConsentOptions(options: ConsentOption[]): {
2166
- valid: boolean;
2167
- errors: string[];
2168
- };
2194
+ export declare function validateConsentOptionsStructured(options: ConsentOption[]): StructuredValidationResult<ConsentOption[]>;
2169
2195
 
2170
2196
  /**
2171
- * Validate a raw DSR submission payload against the same rules
2172
- * `<DSRRequestForm />` enforces client-side. Designed to be called from a
2173
- * server-side handler (Next.js Route Handler, NestJS controller, Express
2174
- * middleware, Cloudflare Worker) so client and server stay in sync without
2175
- * the consumer hand-rolling zod / class-validator schemas.
2197
+ * Validates consent settings against NDPA requirements. Returns structured
2198
+ * `{ field, code, message }[]` errors so consumers can switch on `code`
2199
+ * across locales without regex-matching English strings.
2176
2200
  *
2177
- * Defensive — accepts `unknown` and narrows. Safe to call directly on
2178
- * `await request.json()`.
2201
+ * Codes emitted:
2202
+ * - `consents_required`
2203
+ * - `timestamp_required`
2204
+ * - `timestamp_invalid`
2205
+ * - `version_required`
2206
+ * - `method_required`
2207
+ * - `has_interacted_required`
2208
+ * - `consent_stale`
2179
2209
  *
2180
- * @example **Next.js Route Handler**
2210
+ * @example
2181
2211
  * ```ts
2182
- * // app/api/dsr/route.ts
2183
- * import { validateDsrSubmission } from '@tantainnovative/ndpr-toolkit/server';
2184
- *
2185
- * export async function POST(req: Request) {
2186
- * const { valid, errors, data } = validateDsrSubmission(await req.json());
2187
- * if (!valid) return Response.json({ errors }, { status: 422 });
2188
- * // `data` is the typed DsrSubmissionPayload
2189
- * await dsrStore.create(data);
2190
- * return Response.json({ ok: true }, { status: 201 });
2212
+ * const { valid, errors, data } = validateConsentStructured(settings);
2213
+ * if (!valid) {
2214
+ * const stale = errors.find((e) => e.code === 'consent_stale');
2215
+ * if (stale) showRefreshBanner();
2191
2216
  * }
2192
2217
  * ```
2193
- *
2194
- * @example **Lock to specific request types**
2195
- * ```ts
2196
- * validateDsrSubmission(payload, {
2197
- * allowedRequestTypes: ['access', 'erasure', 'rectification'],
2198
- * });
2199
- * ```
2200
- *
2201
- * @example **Skip identity verification (e.g. authenticated session)**
2202
- * ```ts
2203
- * validateDsrSubmission(payload, { requireIdentityVerification: false });
2204
- * ```
2205
2218
  */
2206
- export declare function validateDsrSubmission(payload: unknown, options?: ValidateDsrSubmissionOptions): DsrSubmissionValidationResult;
2219
+ export declare function validateConsentStructured(settings: ConsentSettings): StructuredValidationResult<ConsentSettings>;
2207
2220
 
2208
- /** Options for {@link validateDsrSubmission}. */
2221
+ /** Options for {@link validateDsrSubmissionStructured}. */
2209
2222
  export declare interface ValidateDsrSubmissionOptions {
2210
2223
  /**
2211
2224
  * Whether the data subject is required to provide an identifier
@@ -2222,6 +2235,48 @@ export declare interface ValidateDsrSubmissionOptions {
2222
2235
  allowedRequestTypes?: string[];
2223
2236
  }
2224
2237
 
2238
+ /**
2239
+ * Validate a raw DSR submission payload against the same rules
2240
+ * `<DSRRequestForm />` enforces client-side. Designed to be called from a
2241
+ * server-side handler (Next.js Route Handler, NestJS controller, Express
2242
+ * middleware, Cloudflare Worker) so client and server stay in sync without
2243
+ * the consumer hand-rolling zod / class-validator schemas.
2244
+ *
2245
+ * Defensive — accepts `unknown` and narrows. Safe to call directly on
2246
+ * `await request.json()`. Returns `{ field, code, message }[]` errors so
2247
+ * callers can switch on `code` programmatically across locales.
2248
+ *
2249
+ * Codes emitted:
2250
+ * - `payload_not_object`
2251
+ * - `request_type_required`
2252
+ * - `request_type_not_allowed`
2253
+ * - `data_subject_required`
2254
+ * - `full_name_required`
2255
+ * - `email_required`
2256
+ * - `email_invalid_format`
2257
+ * - `phone_invalid_type`
2258
+ * - `identifier_type_required`
2259
+ * - `identifier_value_required`
2260
+ * - `submitted_at_invalid`
2261
+ * - `additional_info_invalid_type`
2262
+ * - `payload_final_narrowing_failed`
2263
+ *
2264
+ * @example **Next.js Route Handler**
2265
+ * ```ts
2266
+ * import { validateDsrSubmissionStructured } from '@tantainnovative/ndpr-toolkit/server';
2267
+ *
2268
+ * export async function POST(req: Request) {
2269
+ * const { valid, errors, data } = validateDsrSubmissionStructured(await req.json());
2270
+ * if (!valid) {
2271
+ * return Response.json({ errors }, { status: 422 });
2272
+ * }
2273
+ * await dsrStore.create(data);
2274
+ * return Response.json({ ok: true }, { status: 201 });
2275
+ * }
2276
+ * ```
2277
+ */
2278
+ export declare function validateDsrSubmissionStructured(payload: unknown, options?: ValidateDsrSubmissionOptions): StructuredValidationResult<DsrSubmissionPayload>;
2279
+
2225
2280
  /**
2226
2281
  * Validates that all required fields are present on a processing activity
2227
2282
  * and that the lawful basis is properly documented.
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunk3XU6FL2I_js=require('./chunk-3XU6FL2I.js'),chunkNUOHT3LO_js=require('./chunk-NUOHT3LO.js'),chunkRDALAH3Y_js=require('./chunk-RDALAH3Y.js'),chunk3YTAOT5O_js=require('./chunk-3YTAOT5O.js'),chunkD2ZKDQVL_js=require('./chunk-D2ZKDQVL.js'),chunk6LJHLE6G_js=require('./chunk-6LJHLE6G.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js'),chunkWZYCBW2R_js=require('./chunk-WZYCBW2R.js'),chunk4CVBQC66_js=require('./chunk-4CVBQC66.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkB46SJB5V_js=require('./chunk-B46SJB5V.js'),chunkUXUMYP4L_js=require('./chunk-UXUMYP4L.js'),chunkOZHUINWS_js=require('./chunk-OZHUINWS.js'),chunkTQZWJGJ2_js=require('./chunk-TQZWJGJ2.js'),chunkZVOIR4QH_js=require('./chunk-ZVOIR4QH.js'),chunkYDKWD6MQ_js=require('./chunk-YDKWD6MQ.js'),chunkTTMGFC6C_js=require('./chunk-TTMGFC6C.js');require('./chunk-RFPLZDIO.js');Object.defineProperty(exports,"hausaLocale",{enumerable:true,get:function(){return chunk3XU6FL2I_js.c}});Object.defineProperty(exports,"igboLocale",{enumerable:true,get:function(){return chunk3XU6FL2I_js.b}});Object.defineProperty(exports,"pidginLocale",{enumerable:true,get:function(){return chunk3XU6FL2I_js.d}});Object.defineProperty(exports,"yorubaLocale",{enumerable:true,get:function(){return chunk3XU6FL2I_js.a}});Object.defineProperty(exports,"ORG_POLICY_TEMPLATE_REGISTRY",{enumerable:true,get:function(){return chunkNUOHT3LO_js.a}});Object.defineProperty(exports,"createOrgTemplate",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"templateContextFor",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"getComplianceScore",{enumerable:true,get:function(){return chunkRDALAH3Y_js.a}});Object.defineProperty(exports,"calculateBreachSeverity",{enumerable:true,get:function(){return chunk3YTAOT5O_js.a}});Object.defineProperty(exports,"DEFAULT_POLICY_SECTIONS",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.c}});Object.defineProperty(exports,"DEFAULT_POLICY_VARIABLES",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.d}});Object.defineProperty(exports,"createBusinessPolicyTemplate",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.e}});Object.defineProperty(exports,"findUnfilledTokens",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.a}});Object.defineProperty(exports,"generatePolicyText",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.b}});Object.defineProperty(exports,"assemblePolicy",{enumerable:true,get:function(){return chunk6LJHLE6G_js.c}});Object.defineProperty(exports,"createDefaultContext",{enumerable:true,get:function(){return chunk6LJHLE6G_js.e}});Object.defineProperty(exports,"evaluatePolicyCompliance",{enumerable:true,get:function(){return chunk6LJHLE6G_js.f}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});Object.defineProperty(exports,"assessComplianceGaps",{enumerable:true,get:function(){return chunkWZYCBW2R_js.c}});Object.defineProperty(exports,"generateLawfulBasisSummary",{enumerable:true,get:function(){return chunkWZYCBW2R_js.d}});Object.defineProperty(exports,"getLawfulBasisDescription",{enumerable:true,get:function(){return chunkWZYCBW2R_js.b}});Object.defineProperty(exports,"validateProcessingActivity",{enumerable:true,get:function(){return chunkWZYCBW2R_js.a}});Object.defineProperty(exports,"exportROPAToCSV",{enumerable:true,get:function(){return chunk4CVBQC66_js.c}});Object.defineProperty(exports,"generateROPASummary",{enumerable:true,get:function(){return chunk4CVBQC66_js.b}});Object.defineProperty(exports,"identifyComplianceGaps",{enumerable:true,get:function(){return chunk4CVBQC66_js.d}});Object.defineProperty(exports,"validateProcessingRecord",{enumerable:true,get:function(){return chunk4CVBQC66_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"validateConsent",{enumerable:true,get:function(){return chunkB46SJB5V_js.a}});Object.defineProperty(exports,"validateConsentOptions",{enumerable:true,get:function(){return chunkB46SJB5V_js.b}});Object.defineProperty(exports,"sanitizeInput",{enumerable:true,get:function(){return chunkUXUMYP4L_js.a}});Object.defineProperty(exports,"formatDSRRequest",{enumerable:true,get:function(){return chunkOZHUINWS_js.b}});Object.defineProperty(exports,"validateDsrSubmission",{enumerable:true,get:function(){return chunkOZHUINWS_js.a}});Object.defineProperty(exports,"assessDPIARisk",{enumerable:true,get:function(){return chunkTQZWJGJ2_js.a}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_LONG",{enumerable:true,get:function(){return chunkZVOIR4QH_js.b}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_SHORT",{enumerable:true,get:function(){return chunkZVOIR4QH_js.a}});Object.defineProperty(exports,"legalDisclaimerBlock",{enumerable:true,get:function(){return chunkZVOIR4QH_js.c}});Object.defineProperty(exports,"NDPRProvider",{enumerable:true,get:function(){return chunkYDKWD6MQ_js.a}});Object.defineProperty(exports,"useNDPRConfig",{enumerable:true,get:function(){return chunkYDKWD6MQ_js.b}});Object.defineProperty(exports,"useNDPRLocale",{enumerable:true,get:function(){return chunkYDKWD6MQ_js.c}});Object.defineProperty(exports,"defaultLocale",{enumerable:true,get:function(){return chunkTTMGFC6C_js.a}});Object.defineProperty(exports,"mergeLocale",{enumerable:true,get:function(){return chunkTTMGFC6C_js.b}});
1
+ 'use strict';var chunk6YFPDGNB_js=require('./chunk-6YFPDGNB.js'),chunkNUOHT3LO_js=require('./chunk-NUOHT3LO.js'),chunkRDALAH3Y_js=require('./chunk-RDALAH3Y.js'),chunk3YTAOT5O_js=require('./chunk-3YTAOT5O.js'),chunkD2ZKDQVL_js=require('./chunk-D2ZKDQVL.js'),chunk6LJHLE6G_js=require('./chunk-6LJHLE6G.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js'),chunkWZYCBW2R_js=require('./chunk-WZYCBW2R.js'),chunk4CVBQC66_js=require('./chunk-4CVBQC66.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkDKLJ5DYN_js=require('./chunk-DKLJ5DYN.js'),chunkUXUMYP4L_js=require('./chunk-UXUMYP4L.js'),chunkR2ZZMATR_js=require('./chunk-R2ZZMATR.js'),chunkTQZWJGJ2_js=require('./chunk-TQZWJGJ2.js'),chunkZVOIR4QH_js=require('./chunk-ZVOIR4QH.js'),chunkYDKWD6MQ_js=require('./chunk-YDKWD6MQ.js'),chunkTTMGFC6C_js=require('./chunk-TTMGFC6C.js');require('./chunk-RFPLZDIO.js');Object.defineProperty(exports,"arabicLocale",{enumerable:true,get:function(){return chunk6YFPDGNB_js.e}});Object.defineProperty(exports,"frenchLocale",{enumerable:true,get:function(){return chunk6YFPDGNB_js.f}});Object.defineProperty(exports,"hausaLocale",{enumerable:true,get:function(){return chunk6YFPDGNB_js.c}});Object.defineProperty(exports,"igboLocale",{enumerable:true,get:function(){return chunk6YFPDGNB_js.b}});Object.defineProperty(exports,"pidginLocale",{enumerable:true,get:function(){return chunk6YFPDGNB_js.d}});Object.defineProperty(exports,"yorubaLocale",{enumerable:true,get:function(){return chunk6YFPDGNB_js.a}});Object.defineProperty(exports,"ORG_POLICY_TEMPLATE_REGISTRY",{enumerable:true,get:function(){return chunkNUOHT3LO_js.a}});Object.defineProperty(exports,"createOrgTemplate",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"templateContextFor",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"getComplianceScore",{enumerable:true,get:function(){return chunkRDALAH3Y_js.a}});Object.defineProperty(exports,"calculateBreachSeverity",{enumerable:true,get:function(){return chunk3YTAOT5O_js.a}});Object.defineProperty(exports,"DEFAULT_POLICY_SECTIONS",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.c}});Object.defineProperty(exports,"DEFAULT_POLICY_VARIABLES",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.d}});Object.defineProperty(exports,"createBusinessPolicyTemplate",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.e}});Object.defineProperty(exports,"findUnfilledTokens",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.a}});Object.defineProperty(exports,"generatePolicyText",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.b}});Object.defineProperty(exports,"assemblePolicy",{enumerable:true,get:function(){return chunk6LJHLE6G_js.c}});Object.defineProperty(exports,"createDefaultContext",{enumerable:true,get:function(){return chunk6LJHLE6G_js.e}});Object.defineProperty(exports,"evaluatePolicyCompliance",{enumerable:true,get:function(){return chunk6LJHLE6G_js.f}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});Object.defineProperty(exports,"assessComplianceGaps",{enumerable:true,get:function(){return chunkWZYCBW2R_js.c}});Object.defineProperty(exports,"generateLawfulBasisSummary",{enumerable:true,get:function(){return chunkWZYCBW2R_js.d}});Object.defineProperty(exports,"getLawfulBasisDescription",{enumerable:true,get:function(){return chunkWZYCBW2R_js.b}});Object.defineProperty(exports,"validateProcessingActivity",{enumerable:true,get:function(){return chunkWZYCBW2R_js.a}});Object.defineProperty(exports,"exportROPAToCSV",{enumerable:true,get:function(){return chunk4CVBQC66_js.c}});Object.defineProperty(exports,"generateROPASummary",{enumerable:true,get:function(){return chunk4CVBQC66_js.b}});Object.defineProperty(exports,"identifyComplianceGaps",{enumerable:true,get:function(){return chunk4CVBQC66_js.d}});Object.defineProperty(exports,"validateProcessingRecord",{enumerable:true,get:function(){return chunk4CVBQC66_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"validateConsentOptionsStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.b}});Object.defineProperty(exports,"validateConsentStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.a}});Object.defineProperty(exports,"sanitizeInput",{enumerable:true,get:function(){return chunkUXUMYP4L_js.a}});Object.defineProperty(exports,"formatDSRRequestStructured",{enumerable:true,get:function(){return chunkR2ZZMATR_js.b}});Object.defineProperty(exports,"validateDsrSubmissionStructured",{enumerable:true,get:function(){return chunkR2ZZMATR_js.a}});Object.defineProperty(exports,"assessDPIARisk",{enumerable:true,get:function(){return chunkTQZWJGJ2_js.a}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_LONG",{enumerable:true,get:function(){return chunkZVOIR4QH_js.b}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_SHORT",{enumerable:true,get:function(){return chunkZVOIR4QH_js.a}});Object.defineProperty(exports,"legalDisclaimerBlock",{enumerable:true,get:function(){return chunkZVOIR4QH_js.c}});Object.defineProperty(exports,"NDPRProvider",{enumerable:true,get:function(){return chunkYDKWD6MQ_js.a}});Object.defineProperty(exports,"useNDPRConfig",{enumerable:true,get:function(){return chunkYDKWD6MQ_js.b}});Object.defineProperty(exports,"useNDPRLocale",{enumerable:true,get:function(){return chunkYDKWD6MQ_js.c}});Object.defineProperty(exports,"defaultLocale",{enumerable:true,get:function(){return chunkTTMGFC6C_js.a}});Object.defineProperty(exports,"mergeLocale",{enumerable:true,get:function(){return chunkTTMGFC6C_js.b}});
package/dist/core.mjs CHANGED
@@ -1 +1 @@
1
- export{c as hausaLocale,b as igboLocale,d as pidginLocale,a as yorubaLocale}from'./chunk-BGV2AKT7.mjs';export{a as ORG_POLICY_TEMPLATE_REGISTRY,b as createOrgTemplate,b as templateContextFor}from'./chunk-CWY2FMIC.mjs';export{a as getComplianceScore}from'./chunk-7RBO42IW.mjs';export{a as calculateBreachSeverity}from'./chunk-WTGKZX7J.mjs';export{c as DEFAULT_POLICY_SECTIONS,d as DEFAULT_POLICY_VARIABLES,e as createBusinessPolicyTemplate,a as findUnfilledTokens,b as generatePolicyText}from'./chunk-NBQQ2GN3.mjs';export{c as assemblePolicy,e as createDefaultContext,f as evaluatePolicyCompliance}from'./chunk-BIJSMSUU.mjs';export{h as assessTransferRisk,f as getTransferMechanismDescription,e as isNDPCApprovalRequired,g as validateTransfer}from'./chunk-7BJXI2HI.mjs';export{c as assessComplianceGaps,d as generateLawfulBasisSummary,b as getLawfulBasisDescription,a as validateProcessingActivity}from'./chunk-LWIKDDSU.mjs';export{c as exportROPAToCSV,b as generateROPASummary,d as identifyComplianceGaps,a as validateProcessingRecord}from'./chunk-XP5PL6K7.mjs';export{c as appendAuditEntry,a as createAuditEntry,b as getAuditLog}from'./chunk-V7UFP6QU.mjs';export{a as validateConsent,b as validateConsentOptions}from'./chunk-PJNKQPQP.mjs';export{a as sanitizeInput}from'./chunk-EWVK45Z3.mjs';export{b as formatDSRRequest,a as validateDsrSubmission}from'./chunk-VPNK7OID.mjs';export{a as assessDPIARisk}from'./chunk-LRRENTT5.mjs';export{b as LEGAL_DISCLAIMER_LONG,a as LEGAL_DISCLAIMER_SHORT,c as legalDisclaimerBlock}from'./chunk-ITCY2Z66.mjs';export{a as NDPRProvider,b as useNDPRConfig,c as useNDPRLocale}from'./chunk-FRQFU44F.mjs';export{a as defaultLocale,b as mergeLocale}from'./chunk-V5TZJJWU.mjs';import'./chunk-ZJYULEER.mjs';
1
+ export{e as arabicLocale,f as frenchLocale,c as hausaLocale,b as igboLocale,d as pidginLocale,a as yorubaLocale}from'./chunk-PSPYIRIF.mjs';export{a as ORG_POLICY_TEMPLATE_REGISTRY,b as createOrgTemplate,b as templateContextFor}from'./chunk-CWY2FMIC.mjs';export{a as getComplianceScore}from'./chunk-7RBO42IW.mjs';export{a as calculateBreachSeverity}from'./chunk-WTGKZX7J.mjs';export{c as DEFAULT_POLICY_SECTIONS,d as DEFAULT_POLICY_VARIABLES,e as createBusinessPolicyTemplate,a as findUnfilledTokens,b as generatePolicyText}from'./chunk-NBQQ2GN3.mjs';export{c as assemblePolicy,e as createDefaultContext,f as evaluatePolicyCompliance}from'./chunk-BIJSMSUU.mjs';export{h as assessTransferRisk,f as getTransferMechanismDescription,e as isNDPCApprovalRequired,g as validateTransfer}from'./chunk-7BJXI2HI.mjs';export{c as assessComplianceGaps,d as generateLawfulBasisSummary,b as getLawfulBasisDescription,a as validateProcessingActivity}from'./chunk-LWIKDDSU.mjs';export{c as exportROPAToCSV,b as generateROPASummary,d as identifyComplianceGaps,a as validateProcessingRecord}from'./chunk-XP5PL6K7.mjs';export{c as appendAuditEntry,a as createAuditEntry,b as getAuditLog}from'./chunk-V7UFP6QU.mjs';export{b as validateConsentOptionsStructured,a as validateConsentStructured}from'./chunk-R3ZKV2J7.mjs';export{a as sanitizeInput}from'./chunk-EWVK45Z3.mjs';export{b as formatDSRRequestStructured,a as validateDsrSubmissionStructured}from'./chunk-RRVML7CU.mjs';export{a as assessDPIARisk}from'./chunk-LRRENTT5.mjs';export{b as LEGAL_DISCLAIMER_LONG,a as LEGAL_DISCLAIMER_SHORT,c as legalDisclaimerBlock}from'./chunk-ITCY2Z66.mjs';export{a as NDPRProvider,b as useNDPRConfig,c as useNDPRLocale}from'./chunk-FRQFU44F.mjs';export{a as defaultLocale,b as mergeLocale}from'./chunk-V5TZJJWU.mjs';import'./chunk-ZJYULEER.mjs';
@@ -215,17 +215,18 @@ declare interface CrossBorderTransferManagerProps {
215
215
  */
216
216
  transfers: CrossBorderTransfer[];
217
217
  /**
218
- * Callback when a new transfer is added
218
+ * Callback when a new transfer is added.
219
219
  */
220
- onAddTransfer?: (transfer: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>) => void;
220
+ onAdd?: (transfer: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>) => void;
221
221
  /**
222
- * Callback when a transfer is updated
222
+ * Callback when a transfer is updated.
223
223
  */
224
- onUpdateTransfer?: (id: string, updates: Partial<CrossBorderTransfer>) => void;
224
+ onUpdate?: (id: string, updates: Partial<CrossBorderTransfer>) => void;
225
225
  /**
226
- * Callback when a transfer is removed
226
+ * Callback when a transfer is archived. NDPA preference is soft-delete
227
+ * over hard-delete; consumers should treat this as an archive signal.
227
228
  */
228
- onRemoveTransfer?: (id: string) => void;
229
+ onArchive?: (id: string) => void;
229
230
  /**
230
231
  * Compliance summary data
231
232
  */
@@ -215,17 +215,18 @@ declare interface CrossBorderTransferManagerProps {
215
215
  */
216
216
  transfers: CrossBorderTransfer[];
217
217
  /**
218
- * Callback when a new transfer is added
218
+ * Callback when a new transfer is added.
219
219
  */
220
- onAddTransfer?: (transfer: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>) => void;
220
+ onAdd?: (transfer: Omit<CrossBorderTransfer, 'id' | 'createdAt' | 'updatedAt'>) => void;
221
221
  /**
222
- * Callback when a transfer is updated
222
+ * Callback when a transfer is updated.
223
223
  */
224
- onUpdateTransfer?: (id: string, updates: Partial<CrossBorderTransfer>) => void;
224
+ onUpdate?: (id: string, updates: Partial<CrossBorderTransfer>) => void;
225
225
  /**
226
- * Callback when a transfer is removed
226
+ * Callback when a transfer is archived. NDPA preference is soft-delete
227
+ * over hard-delete; consumers should treat this as an archive signal.
227
228
  */
228
- onRemoveTransfer?: (id: string) => void;
229
+ onArchive?: (id: string) => void;
229
230
  /**
230
231
  * Compliance summary data
231
232
  */
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- 'use strict';var chunkXYGGUGTO_js=require('./chunk-XYGGUGTO.js'),chunkHHK5LHEG_js=require('./chunk-HHK5LHEG.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js');require('./chunk-AME4HJR4.js'),require('./chunk-YDKWD6MQ.js'),require('./chunk-TTMGFC6C.js'),require('./chunk-VWED6UTN.js'),require('./chunk-RFPLZDIO.js');var react=require('react'),jsxRuntime=require('react/jsx-runtime');var s=react.createContext(null);function A(){let r=react.useContext(s);if(!r)throw new Error("CrossBorder compound components must be wrapped in <CrossBorder.Provider>. Example: <CrossBorder.Provider><CrossBorder.Manager /></CrossBorder.Provider>");return r}var t=({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f,children:i})=>{let m=chunkHHK5LHEG_js.a({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f});return jsxRuntime.jsx(s.Provider,{value:m,children:i})};var q={Provider:t,Manager:chunkXYGGUGTO_js.a};Object.defineProperty(exports,"CrossBorderTransferManager",{enumerable:true,get:function(){return chunkXYGGUGTO_js.a}});Object.defineProperty(exports,"useCrossBorderTransfer",{enumerable:true,get:function(){return chunkHHK5LHEG_js.a}});Object.defineProperty(exports,"COUNTRY_ADEQUACY_MAP",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.a}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getAdequateCountries",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.c}});Object.defineProperty(exports,"getCountryAdequacy",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.b}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"requiresNDPCApproval",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.d}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});exports.CrossBorder=q;exports.CrossBorderProvider=t;exports.useCrossBorderCompound=A;
2
+ 'use strict';var chunkCSE36REY_js=require('./chunk-CSE36REY.js'),chunkHHK5LHEG_js=require('./chunk-HHK5LHEG.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js');require('./chunk-AME4HJR4.js'),require('./chunk-YDKWD6MQ.js'),require('./chunk-TTMGFC6C.js'),require('./chunk-VWED6UTN.js'),require('./chunk-RFPLZDIO.js');var react=require('react'),jsxRuntime=require('react/jsx-runtime');var s=react.createContext(null);function A(){let r=react.useContext(s);if(!r)throw new Error("CrossBorder compound components must be wrapped in <CrossBorder.Provider>. Example: <CrossBorder.Provider><CrossBorder.Manager /></CrossBorder.Provider>");return r}var t=({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f,children:i})=>{let m=chunkHHK5LHEG_js.a({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f});return jsxRuntime.jsx(s.Provider,{value:m,children:i})};var q={Provider:t,Manager:chunkCSE36REY_js.a};Object.defineProperty(exports,"CrossBorderTransferManager",{enumerable:true,get:function(){return chunkCSE36REY_js.a}});Object.defineProperty(exports,"useCrossBorderTransfer",{enumerable:true,get:function(){return chunkHHK5LHEG_js.a}});Object.defineProperty(exports,"COUNTRY_ADEQUACY_MAP",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.a}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getAdequateCountries",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.c}});Object.defineProperty(exports,"getCountryAdequacy",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.b}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"requiresNDPCApproval",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.d}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});exports.CrossBorder=q;exports.CrossBorderProvider=t;exports.useCrossBorderCompound=A;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import {a}from'./chunk-42JPSNVV.mjs';export{a as CrossBorderTransferManager}from'./chunk-42JPSNVV.mjs';import {a as a$1}from'./chunk-KDAZQO3N.mjs';export{a as useCrossBorderTransfer}from'./chunk-KDAZQO3N.mjs';export{a as COUNTRY_ADEQUACY_MAP,h as assessTransferRisk,c as getAdequateCountries,b as getCountryAdequacy,f as getTransferMechanismDescription,e as isNDPCApprovalRequired,d as requiresNDPCApproval,g as validateTransfer}from'./chunk-7BJXI2HI.mjs';import'./chunk-SFGW37LE.mjs';import'./chunk-FRQFU44F.mjs';import'./chunk-V5TZJJWU.mjs';import'./chunk-DBZSN4WP.mjs';import'./chunk-ZJYULEER.mjs';import {createContext,useContext}from'react';import {jsx}from'react/jsx-runtime';var s=createContext(null);function A(){let r=useContext(s);if(!r)throw new Error("CrossBorder compound components must be wrapped in <CrossBorder.Provider>. Example: <CrossBorder.Provider><CrossBorder.Manager /></CrossBorder.Provider>");return r}var t=({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f,children:i})=>{let m=a$1({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f});return jsx(s.Provider,{value:m,children:i})};var q={Provider:t,Manager:a};export{q as CrossBorder,t as CrossBorderProvider,A as useCrossBorderCompound};
2
+ import {a}from'./chunk-WPH6CJDL.mjs';export{a as CrossBorderTransferManager}from'./chunk-WPH6CJDL.mjs';import {a as a$1}from'./chunk-KDAZQO3N.mjs';export{a as useCrossBorderTransfer}from'./chunk-KDAZQO3N.mjs';export{a as COUNTRY_ADEQUACY_MAP,h as assessTransferRisk,c as getAdequateCountries,b as getCountryAdequacy,f as getTransferMechanismDescription,e as isNDPCApprovalRequired,d as requiresNDPCApproval,g as validateTransfer}from'./chunk-7BJXI2HI.mjs';import'./chunk-SFGW37LE.mjs';import'./chunk-FRQFU44F.mjs';import'./chunk-V5TZJJWU.mjs';import'./chunk-DBZSN4WP.mjs';import'./chunk-ZJYULEER.mjs';import {createContext,useContext}from'react';import {jsx}from'react/jsx-runtime';var s=createContext(null);function A(){let r=useContext(s);if(!r)throw new Error("CrossBorder compound components must be wrapped in <CrossBorder.Provider>. Example: <CrossBorder.Provider><CrossBorder.Manager /></CrossBorder.Provider>");return r}var t=({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f,children:i})=>{let m=a$1({adapter:r,storageKey:d,useLocalStorage:a,initialTransfers:n,onAdd:p,onUpdate:C,onRemove:f});return jsx(s.Provider,{value:m,children:i})};var q={Provider:t,Manager:a};export{q as CrossBorder,t as CrossBorderProvider,A as useCrossBorderCompound};