@lunora/privacy 0.0.0-stage → 1.0.0-alpha.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.
- package/LICENSE.md +240 -0
- package/README.md +34 -2
- package/dist/de.d.mts +22 -0
- package/dist/de.d.ts +22 -0
- package/dist/de.mjs +1 -0
- package/dist/eu.d.mts +23 -0
- package/dist/eu.d.ts +23 -0
- package/dist/eu.mjs +1 -0
- package/dist/index.d.mts +54 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.mjs +1 -0
- package/dist/packem_shared/ERASE_BATCH-BqeymwxG.mjs +1 -0
- package/dist/packem_shared/OPEN_STATUSES-B_NpOD7X.mjs +1 -0
- package/dist/packem_shared/actionCacheDataset-BoSTUArg.mjs +1 -0
- package/dist/packem_shared/deadlines-DlEH-01d.mjs +1 -0
- package/dist/packem_shared/define.d-B0cbIvBs.d.mts +368 -0
- package/dist/packem_shared/define.d-Dv7btZmk.d.ts +368 -0
- package/dist/packem_shared/defineDataset-BoLQrc_1.mjs +1 -0
- package/dist/packem_shared/definePrivacy-DsCj6Gwv.mjs +1 -0
- package/dist/packem_shared/fromRequestRow-D-Vn3ieZ.mjs +1 -0
- package/dist/packem_shared/isTerminal-C0AnfFUl.mjs +1 -0
- package/dist/packem_shared/privacy-coverage-Edq9aBy0.mjs +1 -0
- package/dist/packem_shared/privacyExtension-EMCPGigC.mjs +1 -0
- package/dist/packem_shared/retain-BtQqIGNh.mjs +1 -0
- package/dist/packem_shared/rules.d-DJa3SIb3.d.mts +48 -0
- package/dist/packem_shared/rules.d-DJa3SIb3.d.ts +48 -0
- package/dist/packem_shared/wire-codec-C0ExsJJg.mjs +1 -0
- package/dist/workflow.d.mts +22 -0
- package/dist/workflow.d.ts +22 -0
- package/dist/workflow.mjs +1 -0
- package/package.json +72 -3
package/LICENSE.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, Apache 2.0 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-Apache-2.0
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 anolilab and contributors
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or service
|
|
34
|
+
that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software that
|
|
39
|
+
exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee using
|
|
52
|
+
the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to the
|
|
59
|
+
infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN
|
|
79
|
+
IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following will
|
|
93
|
+
apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
|
106
|
+
|
|
107
|
+
<!-- DEPENDENCIES -->
|
|
108
|
+
|
|
109
|
+
# Licenses of bundled dependencies
|
|
110
|
+
The published @lunora/privacy artifact additionally contains code with the following licenses:
|
|
111
|
+
MIT
|
|
112
|
+
|
|
113
|
+
# Bundled dependencies:
|
|
114
|
+
## @visulima/path
|
|
115
|
+
License: MIT
|
|
116
|
+
By: Daniel Bannert
|
|
117
|
+
Repository: git+https://github.com/visulima/visulima.git
|
|
118
|
+
|
|
119
|
+
> MIT License
|
|
120
|
+
>
|
|
121
|
+
> Copyright (c) 2026 visulima
|
|
122
|
+
>
|
|
123
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
124
|
+
> of this software and associated documentation files (the "Software"), to deal
|
|
125
|
+
> in the Software without restriction, including without limitation the rights
|
|
126
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
127
|
+
> copies of the Software, and to permit persons to whom the Software is
|
|
128
|
+
> furnished to do so, subject to the following conditions:
|
|
129
|
+
>
|
|
130
|
+
> The above copyright notice and this permission notice shall be included in all
|
|
131
|
+
> copies or substantial portions of the Software.
|
|
132
|
+
>
|
|
133
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
134
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
135
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
136
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
137
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
138
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
139
|
+
> SOFTWARE.
|
|
140
|
+
>
|
|
141
|
+
> ---
|
|
142
|
+
>
|
|
143
|
+
> MIT License
|
|
144
|
+
>
|
|
145
|
+
> Copyright (c) Pooya Parsa <pooya@pi0.io> - Daniel Roe <daniel@roe.dev>
|
|
146
|
+
>
|
|
147
|
+
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
148
|
+
> of this software and associated documentation files (the "Software"), to deal
|
|
149
|
+
> in the Software without restriction, including without limitation the rights
|
|
150
|
+
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
151
|
+
> copies of the Software, and to permit persons to whom the Software is
|
|
152
|
+
> furnished to do so, subject to the following conditions:
|
|
153
|
+
>
|
|
154
|
+
> The above copyright notice and this permission notice shall be included in all
|
|
155
|
+
> copies or substantial portions of the Software.
|
|
156
|
+
>
|
|
157
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
158
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
159
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
160
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
161
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
162
|
+
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
163
|
+
> SOFTWARE.
|
|
164
|
+
>
|
|
165
|
+
> ---
|
|
166
|
+
>
|
|
167
|
+
> Copyright Joyent, Inc. and other Node contributors.
|
|
168
|
+
>
|
|
169
|
+
> Permission is hereby granted, free of charge, to any person obtaining a
|
|
170
|
+
> copy of this software and associated documentation files (the
|
|
171
|
+
> "Software"), to deal in the Software without restriction, including
|
|
172
|
+
> without limitation the rights to use, copy, modify, merge, publish,
|
|
173
|
+
> distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
174
|
+
> persons to whom the Software is furnished to do so, subject to the
|
|
175
|
+
> following conditions:
|
|
176
|
+
>
|
|
177
|
+
> The above copyright notice and this permission notice shall be included
|
|
178
|
+
> in all copies or substantial portions of the Software.
|
|
179
|
+
>
|
|
180
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
181
|
+
> OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
182
|
+
> MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|
183
|
+
> NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
184
|
+
> DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
185
|
+
> OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
186
|
+
> USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
187
|
+
>
|
|
188
|
+
> ---
|
|
189
|
+
>
|
|
190
|
+
> Bundled zeptomatch (https://github.com/fabiospampinato/zeptomatch)
|
|
191
|
+
>
|
|
192
|
+
> The MIT License (MIT)
|
|
193
|
+
>
|
|
194
|
+
> Copyright (c) 2023-present Fabio Spampinato
|
|
195
|
+
>
|
|
196
|
+
> Permission is hereby granted, free of charge, to any person obtaining a
|
|
197
|
+
> copy of this software and associated documentation files (the "Software"),
|
|
198
|
+
> to deal in the Software without restriction, including without limitation
|
|
199
|
+
> the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
200
|
+
> and/or sell copies of the Software, and to permit persons to whom the
|
|
201
|
+
> Software is furnished to do so, subject to the following conditions:
|
|
202
|
+
>
|
|
203
|
+
> The above copyright notice and this permission notice shall be included in
|
|
204
|
+
> all copies or substantial portions of the Software.
|
|
205
|
+
>
|
|
206
|
+
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
207
|
+
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
208
|
+
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
209
|
+
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
210
|
+
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
211
|
+
> FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
212
|
+
> DEALINGS IN THE SOFTWARE.
|
|
213
|
+
>
|
|
214
|
+
>
|
|
215
|
+
>
|
|
216
|
+
> # Licenses of bundled dependencies
|
|
217
|
+
> The published @visulima/path artifact additionally contains code with the following licenses:
|
|
218
|
+
> MIT
|
|
219
|
+
>
|
|
220
|
+
> # Bundled dependencies:
|
|
221
|
+
> ## binary-extensions
|
|
222
|
+
> License: MIT
|
|
223
|
+
> By: Sindre Sorhus
|
|
224
|
+
> Repository: sindresorhus/binary-extensions
|
|
225
|
+
>
|
|
226
|
+
> > MIT License
|
|
227
|
+
> >
|
|
228
|
+
> > Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
|
|
229
|
+
> > Copyright (c) Paul Miller (https://paulmillr.com)
|
|
230
|
+
> >
|
|
231
|
+
> > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
232
|
+
> >
|
|
233
|
+
> > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
234
|
+
> >
|
|
235
|
+
> > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
236
|
+
|
|
237
|
+
<!-- /DEPENDENCIES -->
|
|
238
|
+
|
|
239
|
+
<!-- TYPE_DEPENDENCIES -->
|
|
240
|
+
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @lunora/privacy
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Data-subject rights for Lunora apps: the GDPR Art. 15 and 20 export, Art. 17
|
|
4
|
+
erasure, and retention holds for records the law says to keep.
|
|
5
|
+
|
|
6
|
+
> **Not reviewed by a lawyer.** The legal and tax values in this package are research, not
|
|
7
|
+
> legal advice, and no lawyer or tax adviser has checked them. The sources and open
|
|
8
|
+
> questions are in `docs/legal.mdx`. Do not rely on a default until a qualified
|
|
9
|
+
> lawyer and a tax adviser have reviewed it against your own processing.
|
|
10
|
+
>
|
|
11
|
+
> **Experimental.** The package is under development and is not released.
|
|
12
|
+
|
|
13
|
+
## What is built
|
|
14
|
+
|
|
15
|
+
- `retain`: a retention hold on a table's rows, naming a rule from a preset.
|
|
16
|
+
- `definePrivacy`: the bound API, `privacyFor(ctx, identity?)`. Its `tick` reports requests near or past the Art. 12(3)
|
|
17
|
+
deadline, counted in calendar months under Reg. 1182/71 Art. 3(2)(c). Its `coverage` flags a table
|
|
18
|
+
that no dataset covers and that no exclusion explains. Its export decides, per
|
|
19
|
+
dataset, whether the archive lists Art. 15 only or Art. 15 and 20.
|
|
20
|
+
- `@lunora/privacy/workflow`: the port RPC a durable workflow needs (`dispatchPort`,
|
|
21
|
+
`remotePorts`, the wire codec), derived from one method table.
|
|
22
|
+
- `@lunora/privacy/eu`: the EU response time and erasure grace.
|
|
23
|
+
- `@lunora/privacy/de`: the HGB §257 and AO §147 retention periods.
|
|
24
|
+
|
|
25
|
+
## Status
|
|
26
|
+
|
|
27
|
+
- Built and tested: the deadline and lifecycle rules, the request service, datasets,
|
|
28
|
+
the export archive, erasure, the deadline sweep, the signed download, restore
|
|
29
|
+
tombstones, the retention archive purge and the operator surface.
|
|
30
|
+
- The Studio has a Privacy requests tab. It appears only when the app declares
|
|
31
|
+
`@lunora/privacy`.
|
|
32
|
+
- Not finished: the runnable example app (`examples/privacy`) is not merged, the
|
|
33
|
+
workerd suite for the storage paths is not written, and registering the workflow
|
|
34
|
+
handlers from the per-call factory has not been checked against codegen (plan §4.2).
|
|
35
|
+
- Not reviewed: every legal and tax value. See `docs/legal.mdx`.
|
package/dist/de.d.mts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { P as PrivacyPreset, R as RetentionRule } from "./packem_shared/rules.d-DJa3SIb3.mjs";
|
|
2
|
+
/** Options for the German preset. Every option defaults to the decided value. */
|
|
3
|
+
interface GermanyOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The retention period for Buchungsbelege (vouchers and invoices): 8 is the statute for
|
|
6
|
+
* non-regulated businesses; 10 is the value decided on 2026-10-11, kept as the default. Regulated
|
|
7
|
+
* institutions keep 10 regardless of this option (HGB §257(4) S. 2).
|
|
8
|
+
*/
|
|
9
|
+
readonly voucherYears?: 8 | 10;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* German statutory retention periods (HGB §257, AO §147). Every rule is pending
|
|
13
|
+
* tax review. The package does not decide which table is a voucher; apps bind
|
|
14
|
+
* tables to these rules explicitly.
|
|
15
|
+
*/
|
|
16
|
+
declare const germany: (options?: GermanyOptions) => PrivacyPreset;
|
|
17
|
+
/**
|
|
18
|
+
* The legal-claims hold. It is opt-in, because it applies only when the controller
|
|
19
|
+
* relies on Art. 17(3)(e) for specific data (LR L11).
|
|
20
|
+
*/
|
|
21
|
+
declare const legalClaimsHold: RetentionRule;
|
|
22
|
+
export { type GermanyOptions, germany, legalClaimsHold };
|
package/dist/de.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { P as PrivacyPreset, R as RetentionRule } from "./packem_shared/rules.d-DJa3SIb3.js";
|
|
2
|
+
/** Options for the German preset. Every option defaults to the decided value. */
|
|
3
|
+
interface GermanyOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The retention period for Buchungsbelege (vouchers and invoices): 8 is the statute for
|
|
6
|
+
* non-regulated businesses; 10 is the value decided on 2026-10-11, kept as the default. Regulated
|
|
7
|
+
* institutions keep 10 regardless of this option (HGB §257(4) S. 2).
|
|
8
|
+
*/
|
|
9
|
+
readonly voucherYears?: 8 | 10;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* German statutory retention periods (HGB §257, AO §147). Every rule is pending
|
|
13
|
+
* tax review. The package does not decide which table is a voucher; apps bind
|
|
14
|
+
* tables to these rules explicitly.
|
|
15
|
+
*/
|
|
16
|
+
declare const germany: (options?: GermanyOptions) => PrivacyPreset;
|
|
17
|
+
/**
|
|
18
|
+
* The legal-claims hold. It is opt-in, because it applies only when the controller
|
|
19
|
+
* relies on Art. 17(3)(e) for specific data (LR L11).
|
|
20
|
+
*/
|
|
21
|
+
declare const legalClaimsHold: RetentionRule;
|
|
22
|
+
export { type GermanyOptions, germany, legalClaimsHold };
|
package/dist/de.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=e=>e===8?"Set to the statutory 8 years (HGB §257(4) S. 1, AO §147(3) S. 1). Regulated institutions keep 10 years. Confirm with a tax adviser.":"Set to 10 years, the decided conservative value. The statute sets 8 years for Buchungsbelege (HGB §257(4) S. 1, AO §147(3) S. 1) and 10 years for regulated institutions. Keeping 10 years for non-regulated businesses conflicts with GDPR Art. 5(1)(e). Maintainer decision pending.",a=(e={})=>{const r=e.voucherYears??10;return{id:"de",retention:[{citation:"HGB §257(1) Nr. 1, (4) S. 1; AO §147(1) Nr. 1, (3) S. 1 (10 years, Handelsbücher and Jahresabschlüsse)",id:"de.books",reviewRequired:!0,start:"endOfCalendarYear",years:10},{citation:"HGB §257(1) Nr. 4, (4) S. 1; AO §147(1) Nr. 4, (3) S. 1 (statute: 8 years; see note)",id:"de.voucher",note:t(r),reviewRequired:!0,start:"endOfCalendarYear",years:r},{citation:"HGB §257(4) S. 2 (10 years for Kreditinstitute, Versicherungsunternehmen, Wertpapierinstitute)",id:"de.voucher.regulated",reviewRequired:!0,start:"endOfCalendarYear",years:10},{citation:"HGB §257(1) Nr. 2, 3, (4) S. 1; AO §147(1) Nr. 2, 3, (3) S. 1 (6 years, Handels- and Geschäftsbriefe)",id:"de.correspondence",reviewRequired:!0,start:"endOfCalendarYear",years:6}]}},s={citation:"BGB §195, §199(1)",id:"de.legalClaims",reviewRequired:!0,start:"endOfCalendarYear",years:3};export{a as germany,s as legalClaimsHold};
|
package/dist/eu.d.mts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { P as PrivacyPreset } from "./packem_shared/rules.d-DJa3SIb3.mjs";
|
|
2
|
+
/** Art. 12(3): months from receipt to the response. LR review (L1) is still open. */
|
|
3
|
+
declare const EU_RESPONSE_MONTHS = 1;
|
|
4
|
+
/** The default erasure grace in days: decision D3. Capped before the deadline (L9). */
|
|
5
|
+
declare const DEFAULT_ERASURE_GRACE_DAYS = 14;
|
|
6
|
+
/** The longest grace an app may set, in days. Beyond this the cap is the only protection. */
|
|
7
|
+
declare const MAX_ERASURE_GRACE_DAYS = 14;
|
|
8
|
+
/** Options for the EU preset. Every option defaults to the decided value. */
|
|
9
|
+
interface EuOptions {
|
|
10
|
+
/** Days between an accepted erasure request and the start of erasure. Integer, 0 to 14. Default 14. */
|
|
11
|
+
readonly erasureGraceDays?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Refuse a grace that is not a whole number of days in range. Used by the preset and
|
|
15
|
+
* by `definePrivacy`, so both enforce the same range.
|
|
16
|
+
*/
|
|
17
|
+
declare const checkErasureGraceDays: (days: number) => number;
|
|
18
|
+
/**
|
|
19
|
+
* EU GDPR preset: the response time and the erasure grace. Every value carries
|
|
20
|
+
* `reviewRequired`. The legal basis for each value is in `docs/legal.mdx`.
|
|
21
|
+
*/
|
|
22
|
+
declare const eu: (options?: EuOptions) => PrivacyPreset;
|
|
23
|
+
export { DEFAULT_ERASURE_GRACE_DAYS, EU_RESPONSE_MONTHS, EuOptions, MAX_ERASURE_GRACE_DAYS, checkErasureGraceDays, eu };
|
package/dist/eu.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { P as PrivacyPreset } from "./packem_shared/rules.d-DJa3SIb3.js";
|
|
2
|
+
/** Art. 12(3): months from receipt to the response. LR review (L1) is still open. */
|
|
3
|
+
declare const EU_RESPONSE_MONTHS = 1;
|
|
4
|
+
/** The default erasure grace in days: decision D3. Capped before the deadline (L9). */
|
|
5
|
+
declare const DEFAULT_ERASURE_GRACE_DAYS = 14;
|
|
6
|
+
/** The longest grace an app may set, in days. Beyond this the cap is the only protection. */
|
|
7
|
+
declare const MAX_ERASURE_GRACE_DAYS = 14;
|
|
8
|
+
/** Options for the EU preset. Every option defaults to the decided value. */
|
|
9
|
+
interface EuOptions {
|
|
10
|
+
/** Days between an accepted erasure request and the start of erasure. Integer, 0 to 14. Default 14. */
|
|
11
|
+
readonly erasureGraceDays?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Refuse a grace that is not a whole number of days in range. Used by the preset and
|
|
15
|
+
* by `definePrivacy`, so both enforce the same range.
|
|
16
|
+
*/
|
|
17
|
+
declare const checkErasureGraceDays: (days: number) => number;
|
|
18
|
+
/**
|
|
19
|
+
* EU GDPR preset: the response time and the erasure grace. Every value carries
|
|
20
|
+
* `reviewRequired`. The legal basis for each value is in `docs/legal.mdx`.
|
|
21
|
+
*/
|
|
22
|
+
declare const eu: (options?: EuOptions) => PrivacyPreset;
|
|
23
|
+
export { DEFAULT_ERASURE_GRACE_DAYS, EU_RESPONSE_MONTHS, EuOptions, MAX_ERASURE_GRACE_DAYS, checkErasureGraceDays, eu };
|
package/dist/eu.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as o}from"@lunora/errors";const t=1,n=14,r=14,s=e=>{if(!Number.isInteger(e)||e<0||e>r)throw new o("BAD_REQUEST",`The erasure grace must be a whole number of days from 0 to ${String(r)}; got ${String(e)}.`);return e},E=(e={})=>({id:"eu",policy:{erasureGraceDays:s(e.erasureGraceDays??n),extensionMonths:2,responseMonths:t,reviewRequired:!0},retention:[]});export{n as DEFAULT_ERASURE_GRACE_DAYS,t as EU_RESPONSE_MONTHS,r as MAX_ERASURE_GRACE_DAYS,s as checkErasureGraceDays,E as eu};
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { A as AUTH_DEFAULT_TABLES, D as Dataset, R as RequestStatus, b as RequestType, c as RequestRecord } from "./packem_shared/define.d-B0cbIvBs.mjs";
|
|
2
|
+
export { type d as ArchivePort, type C as CoverageProblem, type e as DataOrigin, type f as DataPort, type g as DatasetPhase, type h as DatasetPlacement, type i as DatasetSpec, type j as Disposition, E as ERASE_BATCH, type k as ErasureOptions, type l as ErasureOutcome, type m as ExportOutcome, type L as LegalBasis, type n as Privacy, type P as PrivacyConfig, type o as PrivacyFor, type p as PrivacyIdentity, type a as PrivacyPorts, type q as PrivacyWorkflowContext, type r as RequestStore, type s as RetryResult, type t as RowDisposition, type S as StorePort, type u as SweepResult, type T as TableErasure, type v as TableSpec, type w as TombstonePort, x as defineDataset, y as definePrivacy, z as dispositionFor, B as isTerminal } from "./packem_shared/define.d-B0cbIvBs.mjs";
|
|
3
|
+
export { type a as PrivacyPolicy, type P as PrivacyPreset, type b as RetainDirective, type R as RetentionRule, type c as RetentionStart, r as retain } from "./packem_shared/rules.d-DJa3SIb3.mjs";
|
|
4
|
+
import { TableDefinition, SchemaExtension } from '@lunora/server';
|
|
5
|
+
/** The better-auth table names `authDataset` covers by default. Codegen's coverage check reads the same list. */
|
|
6
|
+
type AuthTable = (typeof AUTH_DEFAULT_TABLES)[number];
|
|
7
|
+
/** The better-auth tables that hold a user's data, renamed. A table left out keeps its default name. */
|
|
8
|
+
type AuthTableNames = { readonly [T in AuthTable]?: string; };
|
|
9
|
+
/**
|
|
10
|
+
* The sign-in dataset. Table names default to better-auth's; `@lunora/auth` does
|
|
11
|
+
* not define these tables itself, so an app that renamed them passes the names.
|
|
12
|
+
*/
|
|
13
|
+
declare const authDataset: (names?: AuthTableNames) => Dataset;
|
|
14
|
+
/** The document history: an append-only record of past row versions, written by table triggers. */
|
|
15
|
+
declare const documentHistoryDataset: (table?: string) => Dataset;
|
|
16
|
+
/** Cached action results. They are derived from the subject's own requests, and expire on their own. */
|
|
17
|
+
declare const actionCacheDataset: (table?: string) => Dataset;
|
|
18
|
+
/** The subject's files in object storage, under the key prefix `prefix` returns for that subject. */
|
|
19
|
+
declare const storageObjectsDataset: (prefix: (subjectId: string) => string) => Dataset;
|
|
20
|
+
/** Every status that is not terminal, for a `listOpen` that reads a status index once per status. */
|
|
21
|
+
declare const OPEN_STATUSES: ReadonlyArray<RequestStatus>;
|
|
22
|
+
/** The columns of a `privacy_requests` row. Dates are epoch milliseconds; `requestId` is the package's id. */
|
|
23
|
+
interface RequestRow {
|
|
24
|
+
readonly dueAt: number;
|
|
25
|
+
readonly erasureGraceUntil?: number;
|
|
26
|
+
readonly expiresAt?: number;
|
|
27
|
+
readonly extendedDueAt?: number;
|
|
28
|
+
readonly reason?: string;
|
|
29
|
+
readonly receivedAt: number;
|
|
30
|
+
readonly requestId: string;
|
|
31
|
+
readonly status: RequestStatus;
|
|
32
|
+
readonly storageKey?: string;
|
|
33
|
+
readonly subjectId: string;
|
|
34
|
+
readonly type: RequestType;
|
|
35
|
+
}
|
|
36
|
+
/** A stored row as the package sees it: every date a `Date`. */
|
|
37
|
+
declare const fromRequestRow: (row: RequestRow) => RequestRecord;
|
|
38
|
+
/** A request as the row `RequestStore.insert` writes. */
|
|
39
|
+
declare const toRequestRow: (record: RequestRecord) => RequestRow;
|
|
40
|
+
/** A `RequestStore.update` patch as row columns. Only the keys the patch sets are written; `subjectId` is one of them. */
|
|
41
|
+
declare const toRequestPatch: (patch: Partial<Omit<RequestRecord, "id">>) => Partial<Omit<RequestRow, "requestId">>;
|
|
42
|
+
/** The three tables, before the `privacy_` prefix. */
|
|
43
|
+
declare const privacyExtension: SchemaExtension<Record<"archive" | "events" | "requests", TableDefinition>, "privacy">;
|
|
44
|
+
export {
|
|
45
|
+
/**
|
|
46
|
+
* `@lunora/privacy`: data-subject rights for Lunora apps. Export (GDPR Art. 15
|
|
47
|
+
* and 20), erasure (Art. 17) and retention holds. This entry holds the pure core;
|
|
48
|
+
* the jurisdiction presets live at `./eu` and `./de`.
|
|
49
|
+
*
|
|
50
|
+
* The surface is what an app calls or annotates: the datasets, the bound API, the
|
|
51
|
+
* ports it implements and the retention directives. The services behind them stay
|
|
52
|
+
* internal, so the app reaches them through `definePrivacy`.
|
|
53
|
+
*/
|
|
54
|
+
type AuthTableNames, type Dataset, OPEN_STATUSES, type RequestRecord, type RequestRow, type RequestStatus, type RequestType, actionCacheDataset, authDataset, documentHistoryDataset, fromRequestRow, privacyExtension, storageObjectsDataset, toRequestPatch, toRequestRow };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { A as AUTH_DEFAULT_TABLES, D as Dataset, R as RequestStatus, b as RequestType, c as RequestRecord } from "./packem_shared/define.d-Dv7btZmk.js";
|
|
2
|
+
export { type d as ArchivePort, type C as CoverageProblem, type e as DataOrigin, type f as DataPort, type g as DatasetPhase, type h as DatasetPlacement, type i as DatasetSpec, type j as Disposition, E as ERASE_BATCH, type k as ErasureOptions, type l as ErasureOutcome, type m as ExportOutcome, type L as LegalBasis, type n as Privacy, type P as PrivacyConfig, type o as PrivacyFor, type p as PrivacyIdentity, type a as PrivacyPorts, type q as PrivacyWorkflowContext, type r as RequestStore, type s as RetryResult, type t as RowDisposition, type S as StorePort, type u as SweepResult, type T as TableErasure, type v as TableSpec, type w as TombstonePort, x as defineDataset, y as definePrivacy, z as dispositionFor, B as isTerminal } from "./packem_shared/define.d-Dv7btZmk.js";
|
|
3
|
+
export { type a as PrivacyPolicy, type P as PrivacyPreset, type b as RetainDirective, type R as RetentionRule, type c as RetentionStart, r as retain } from "./packem_shared/rules.d-DJa3SIb3.js";
|
|
4
|
+
import { TableDefinition, SchemaExtension } from '@lunora/server';
|
|
5
|
+
/** The better-auth table names `authDataset` covers by default. Codegen's coverage check reads the same list. */
|
|
6
|
+
type AuthTable = (typeof AUTH_DEFAULT_TABLES)[number];
|
|
7
|
+
/** The better-auth tables that hold a user's data, renamed. A table left out keeps its default name. */
|
|
8
|
+
type AuthTableNames = { readonly [T in AuthTable]?: string; };
|
|
9
|
+
/**
|
|
10
|
+
* The sign-in dataset. Table names default to better-auth's; `@lunora/auth` does
|
|
11
|
+
* not define these tables itself, so an app that renamed them passes the names.
|
|
12
|
+
*/
|
|
13
|
+
declare const authDataset: (names?: AuthTableNames) => Dataset;
|
|
14
|
+
/** The document history: an append-only record of past row versions, written by table triggers. */
|
|
15
|
+
declare const documentHistoryDataset: (table?: string) => Dataset;
|
|
16
|
+
/** Cached action results. They are derived from the subject's own requests, and expire on their own. */
|
|
17
|
+
declare const actionCacheDataset: (table?: string) => Dataset;
|
|
18
|
+
/** The subject's files in object storage, under the key prefix `prefix` returns for that subject. */
|
|
19
|
+
declare const storageObjectsDataset: (prefix: (subjectId: string) => string) => Dataset;
|
|
20
|
+
/** Every status that is not terminal, for a `listOpen` that reads a status index once per status. */
|
|
21
|
+
declare const OPEN_STATUSES: ReadonlyArray<RequestStatus>;
|
|
22
|
+
/** The columns of a `privacy_requests` row. Dates are epoch milliseconds; `requestId` is the package's id. */
|
|
23
|
+
interface RequestRow {
|
|
24
|
+
readonly dueAt: number;
|
|
25
|
+
readonly erasureGraceUntil?: number;
|
|
26
|
+
readonly expiresAt?: number;
|
|
27
|
+
readonly extendedDueAt?: number;
|
|
28
|
+
readonly reason?: string;
|
|
29
|
+
readonly receivedAt: number;
|
|
30
|
+
readonly requestId: string;
|
|
31
|
+
readonly status: RequestStatus;
|
|
32
|
+
readonly storageKey?: string;
|
|
33
|
+
readonly subjectId: string;
|
|
34
|
+
readonly type: RequestType;
|
|
35
|
+
}
|
|
36
|
+
/** A stored row as the package sees it: every date a `Date`. */
|
|
37
|
+
declare const fromRequestRow: (row: RequestRow) => RequestRecord;
|
|
38
|
+
/** A request as the row `RequestStore.insert` writes. */
|
|
39
|
+
declare const toRequestRow: (record: RequestRecord) => RequestRow;
|
|
40
|
+
/** A `RequestStore.update` patch as row columns. Only the keys the patch sets are written; `subjectId` is one of them. */
|
|
41
|
+
declare const toRequestPatch: (patch: Partial<Omit<RequestRecord, "id">>) => Partial<Omit<RequestRow, "requestId">>;
|
|
42
|
+
/** The three tables, before the `privacy_` prefix. */
|
|
43
|
+
declare const privacyExtension: SchemaExtension<Record<"archive" | "events" | "requests", TableDefinition>, "privacy">;
|
|
44
|
+
export {
|
|
45
|
+
/**
|
|
46
|
+
* `@lunora/privacy`: data-subject rights for Lunora apps. Export (GDPR Art. 15
|
|
47
|
+
* and 20), erasure (Art. 17) and retention holds. This entry holds the pure core;
|
|
48
|
+
* the jurisdiction presets live at `./eu` and `./de`.
|
|
49
|
+
*
|
|
50
|
+
* The surface is what an app calls or annotates: the datasets, the bound API, the
|
|
51
|
+
* ports it implements and the retention directives. The services behind them stay
|
|
52
|
+
* internal, so the app reaches them through `definePrivacy`.
|
|
53
|
+
*/
|
|
54
|
+
type AuthTableNames, type Dataset, OPEN_STATUSES, type RequestRecord, type RequestRow, type RequestStatus, type RequestType, actionCacheDataset, authDataset, documentHistoryDataset, fromRequestRow, privacyExtension, storageObjectsDataset, toRequestPatch, toRequestRow };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{actionCacheDataset as o,authDataset as r,documentHistoryDataset as a,storageObjectsDataset as s}from"./packem_shared/actionCacheDataset-BoSTUArg.mjs";import{defineDataset as i}from"./packem_shared/defineDataset-BoLQrc_1.mjs";import{definePrivacy as p}from"./packem_shared/definePrivacy-DsCj6Gwv.mjs";import{ERASE_BATCH as n,dispositionFor as c}from"./packem_shared/ERASE_BATCH-BqeymwxG.mjs";import{OPEN_STATUSES as R}from"./packem_shared/OPEN_STATUSES-B_NpOD7X.mjs";import{fromRequestRow as D,toRequestPatch as E,toRequestRow as S}from"./packem_shared/fromRequestRow-D-Vn3ieZ.mjs";import{retain as h}from"./packem_shared/retain-BtQqIGNh.mjs";import{default as y}from"./packem_shared/privacyExtension-EMCPGigC.mjs";import{isTerminal as P}from"./packem_shared/isTerminal-C0AnfFUl.mjs";export{n as ERASE_BATCH,R as OPEN_STATUSES,o as actionCacheDataset,r as authDataset,i as defineDataset,p as definePrivacy,c as dispositionFor,a as documentHistoryDataset,D as fromRequestRow,P as isTerminal,y as privacyExtension,h as retain,s as storageObjectsDataset,E as toRequestPatch,S as toRequestRow};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as s}from"@lunora/errors";import{retentionRulesOf as a,retainUntil as u}from"./retain-BtQqIGNh.mjs";const h=100,f=(e,n,t,r)=>{if(e.from===void 0)return t;const o=n[e.from],i=o instanceof Date||typeof o=="number"?new Date(o):void 0;if(i===void 0||Number.isNaN(i.getTime()))throw new s("BAD_REQUEST",`Retention for ${r} starts from column "${e.from}", which must hold a Date or epoch milliseconds; got ${o===null?"null":typeof o}.`);return i},m=(e,n,t,r,o)=>{const i=t.get(e.rule);if(i===void 0)throw new s("BAD_REQUEST",`Retention rule "${e.rule}" is not in the preset set.`);const l=u(i,f(e,n,r,o));return l.getTime()>r.getTime()?{kind:"keep",until:l}:{kind:"delete"}},c=e=>(n,t,r,o)=>{const i=n.tables[t]?.erase??"delete";return i==="delete"||i==="anonymise"?{kind:i}:m(i,r,e,o,`${n.id}.${t}`)},E=async(e,n=1e4)=>{for(let t=1;t<=n;t+=1)if(!(await e()).hasMore)return t;throw new s("INTERNAL",`Erasure did not finish within ${String(n)} batches; the table may be refilling.`)},w=(e,n={})=>{const t=Object.entries(e).filter(([r,o])=>o>(n[r]??0)).map(([r])=>r).toSorted((r,o)=>r.localeCompare(o));return{complete:t.length===0,leftover:t}},g=e=>c(a(e));export{h as ERASE_BATCH,c as dispositionFor,g as dispositionForPresets,E as drainUntilEmpty,w as verifyErasure};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as m}from"@lunora/errors";import{isTerminal as s,REQUEST_STATUSES as i}from"./isTerminal-C0AnfFUl.mjs";import{D as r}from"./deadlines-DlEH-01d.mjs";const p=e=>e.extendedDueAt??e.dueAt,u=e=>!s(e)&&e!=="ready",x=(e,t)=>u(e.status)&&t.getTime()>p(e).getTime(),c={erasure:"grace",export:"received"},T=new Set(Object.values(c)),A={cancelled:[],completed:[],expired:[],failed:["processing"],grace:["failed","processing"],processing:["completed","failed","ready"],ready:["expired"],received:["failed","processing"]};class E extends m{constructor(t,n){super("UNPROCESSABLE",`A privacy request cannot move from "${t}" to "${n}".`),this.from=t,this.to=n,this.name="InvalidTransitionError"}from;to}const N=e=>i.includes(e),h=i.filter(e=>!s(e)),S=(e,t)=>t==="cancelled"?T.has(e):A[e].includes(t),I=(e,t)=>{if(!S(e,t))throw new E(e,t);return t},_=(e,t)=>c[e]===t,C=(e,t)=>e.extendedDueAt===void 0&&t.getTime()<e.dueAt.getTime(),g=3,L=(e,t,n,o)=>{const a=Math.max(g,o),d=e.getTime()+n*r,l=t.getTime()-a*r;return new Date(Math.min(d,l))};export{E as InvalidTransitionError,g as MIN_DRAIN_BUDGET_DAYS,h as OPEN_STATUSES,u as awaitsResponse,_ as canCancel,C as canExtend,S as canTransition,p as effectiveDueAt,L as erasureGraceUntil,x as isOverdue,N as isRequestStatus,s as isTerminal,I as transition};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as a}from"./privacy-coverage-Edq9aBy0.mjs";import{defineDataset as t}from"./defineDataset-BoLQrc_1.mjs";const r={account:["password","accessToken","refreshToken","idToken"],apikey:["key"],member:[],passkey:[],session:["token"],teamMember:[],twoFactor:["secret","backupCodes"],user:[]},c=(e={})=>t("auth",{legalBasis:"contract",origin:"provided",purpose:"Sign-in identity: the account, its sessions, linked sign-in methods and second factors",tables:Object.fromEntries(a.map(s=>{const o=r[s];return[e[s]??s,o.length===0?{}:{omit:o}]}))}),d=(e="documentHistory")=>t("documentHistory",{legalBasis:"contract",origin:"observed",purpose:"Earlier versions of the subject's rows, kept for undo and for the record of changes",tables:{[e]:{}}}),p=(e="actionCache")=>t("actionCache",{legalBasis:"legitimate_interest",origin:"derived",purpose:"Cached results of the subject's own requests, kept for a short time to save repeated work",tables:{[e]:{}}}),u=e=>t("storageObjects",{files:{prefix:e},legalBasis:"contract",origin:"provided",purpose:"Files the subject uploaded",tables:{}});export{p as actionCacheDataset,c as authDataset,d as documentHistoryDataset,u as storageObjectsDataset};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const U=864e5,n=(e,t)=>{const a=e.getUTCFullYear(),T=e.getUTCMonth()+t,s=new Date(Date.UTC(a,T,1)),C=new Date(Date.UTC(s.getUTCFullYear(),s.getUTCMonth()+1,0)).getUTCDate();return s.setUTCDate(Math.min(e.getUTCDate(),C)),s.setUTCHours(e.getUTCHours(),e.getUTCMinutes(),e.getUTCSeconds(),e.getUTCMilliseconds()),s},o={extensionMonths:2,responseMonths:1},r=(e,t=o)=>n(e,t.responseMonths),D=(e,t=o)=>n(e,t.responseMonths+t.extensionMonths);export{U as D,n as a,o as b,r as d,D as e};
|