@openpolicy/core 0.0.4 → 0.0.7

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 (51) hide show
  1. package/dist/index.d.ts +147 -8
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +530 -240
  4. package/dist/index.js.map +1 -0
  5. package/dist/templates/terms/acceptance.d.ts +3 -0
  6. package/dist/templates/terms/acceptance.d.ts.map +1 -0
  7. package/dist/templates/terms/accounts.d.ts +3 -0
  8. package/dist/templates/terms/accounts.d.ts.map +1 -0
  9. package/dist/templates/terms/availability.d.ts +3 -0
  10. package/dist/templates/terms/availability.d.ts.map +1 -0
  11. package/dist/templates/terms/changes-to-terms.d.ts +3 -0
  12. package/dist/templates/terms/changes-to-terms.d.ts.map +1 -0
  13. package/dist/templates/terms/contact.d.ts +3 -0
  14. package/dist/templates/terms/contact.d.ts.map +1 -0
  15. package/dist/templates/terms/disclaimers.d.ts +3 -0
  16. package/dist/templates/terms/disclaimers.d.ts.map +1 -0
  17. package/dist/templates/terms/dispute-resolution.d.ts +3 -0
  18. package/dist/templates/terms/dispute-resolution.d.ts.map +1 -0
  19. package/dist/templates/terms/eligibility.d.ts +3 -0
  20. package/dist/templates/terms/eligibility.d.ts.map +1 -0
  21. package/dist/templates/terms/governing-law.d.ts +3 -0
  22. package/dist/templates/terms/governing-law.d.ts.map +1 -0
  23. package/dist/templates/terms/indemnification.d.ts +3 -0
  24. package/dist/templates/terms/indemnification.d.ts.map +1 -0
  25. package/dist/templates/terms/intellectual-property.d.ts +3 -0
  26. package/dist/templates/terms/intellectual-property.d.ts.map +1 -0
  27. package/dist/templates/terms/introduction.d.ts +3 -0
  28. package/dist/templates/terms/introduction.d.ts.map +1 -0
  29. package/dist/templates/terms/limitation-of-liability.d.ts +3 -0
  30. package/dist/templates/terms/limitation-of-liability.d.ts.map +1 -0
  31. package/dist/templates/terms/payments.d.ts +3 -0
  32. package/dist/templates/terms/payments.d.ts.map +1 -0
  33. package/dist/templates/terms/prohibited-use.d.ts +3 -0
  34. package/dist/templates/terms/prohibited-use.d.ts.map +1 -0
  35. package/dist/templates/terms/termination.d.ts +3 -0
  36. package/dist/templates/terms/termination.d.ts.map +1 -0
  37. package/dist/templates/terms/third-party-services.d.ts +3 -0
  38. package/dist/templates/terms/third-party-services.d.ts.map +1 -0
  39. package/dist/templates/terms/user-content.d.ts +3 -0
  40. package/dist/templates/terms/user-content.d.ts.map +1 -0
  41. package/dist/terms.d.ts +7 -0
  42. package/dist/terms.d.ts.map +1 -0
  43. package/dist/terms.test.d.ts +2 -0
  44. package/dist/terms.test.d.ts.map +1 -0
  45. package/dist/types.d.ts +80 -2
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/validate-terms.d.ts +3 -0
  48. package/dist/validate-terms.d.ts.map +1 -0
  49. package/dist/validate-terms.test.d.ts +2 -0
  50. package/dist/validate-terms.test.d.ts.map +1 -0
  51. package/package.json +6 -3
package/dist/index.js CHANGED
@@ -1,28 +1,21 @@
1
- // src/renderers/html.ts
2
- function renderHTML(sections) {
3
- return sections.map((section) => `<h2>${section.title}</h2><p>${section.body}</p>`).join(`
4
- `);
5
- }
6
-
7
- // src/renderers/markdown.ts
1
+ import { marked } from "marked";
2
+ //#region src/renderers/markdown.ts
8
3
  function renderMarkdown(sections) {
9
- return sections.map((section) => `## ${section.title}
10
-
11
- ${section.body}`).join(`
12
-
13
- ---
14
-
15
- `);
4
+ return sections.map((section) => `## ${section.title}\n\n${section.body}`).join("\n\n---\n\n");
16
5
  }
17
-
18
- // src/templates/privacy/ccpa-supplement.ts
6
+ //#endregion
7
+ //#region src/renderers/html.ts
8
+ function renderHTML(sections) {
9
+ return marked(renderMarkdown(sections));
10
+ }
11
+ //#endregion
12
+ //#region src/templates/privacy/ccpa-supplement.ts
19
13
  function buildCcpaSupplement(config) {
20
- if (!config.jurisdictions.includes("ca"))
21
- return null;
22
- return {
23
- id: "ccpa-supplement",
24
- title: "California Privacy Rights (CCPA)",
25
- body: `This section applies to California residents under the California Consumer Privacy Act (CCPA) and the California Privacy Rights Act (CPRA).
14
+ if (!config.jurisdictions.includes("ca")) return null;
15
+ return {
16
+ id: "ccpa-supplement",
17
+ title: "California Privacy Rights (CCPA)",
18
+ body: `This section applies to California residents under the California Consumer Privacy Act (CCPA) and the California Privacy Rights Act (CPRA).
26
19
 
27
20
  **Categories of Personal Information Collected:** We collect the categories of personal information described in the "Information We Collect" section above.
28
21
 
@@ -33,258 +26,555 @@ function buildCcpaSupplement(config) {
33
26
  - **Right to Non-Discrimination:** We will not discriminate against you for exercising your California privacy rights.
34
27
 
35
28
  To exercise your rights, contact us at ${config.company.contact}.`
36
- };
29
+ };
37
30
  }
38
-
39
- // src/templates/privacy/contact.ts
40
- function buildContact(config) {
41
- return {
42
- id: "contact",
43
- title: "Contact Us",
44
- body: `If you have questions or concerns about this Privacy Policy or our data practices, please contact us:
31
+ //#endregion
32
+ //#region src/templates/privacy/contact.ts
33
+ function buildContact$1(config) {
34
+ return {
35
+ id: "contact",
36
+ title: "Contact Us",
37
+ body: `If you have questions or concerns about this Privacy Policy or our data practices, please contact us:
45
38
 
46
39
  **${config.company.legalName}**
47
40
  ${config.company.address}
48
41
 
49
42
  Email: ${config.company.contact}`
50
- };
43
+ };
51
44
  }
52
-
53
- // src/templates/privacy/cookies.ts
45
+ //#endregion
46
+ //#region src/templates/privacy/cookies.ts
54
47
  function buildCookies(config) {
55
- const enabled = [];
56
- if (config.cookies.essential)
57
- enabled.push("**Essential cookies** — required for the service to function");
58
- if (config.cookies.analytics)
59
- enabled.push("**Analytics cookies** — help us understand how visitors interact with our service");
60
- if (config.cookies.marketing)
61
- enabled.push("**Marketing cookies** — used to deliver relevant advertisements");
62
- const body = enabled.length > 0 ? `We use the following types of cookies and tracking technologies:
63
-
64
- ${enabled.map((e) => `- ${e}`).join(`
65
- `)}` : "We do not use cookies or tracking technologies on our service.";
66
- return {
67
- id: "cookies",
68
- title: "Cookies and Tracking",
69
- body
70
- };
48
+ const enabled = [];
49
+ if (config.cookies.essential) enabled.push("**Essential cookies** — required for the service to function");
50
+ if (config.cookies.analytics) enabled.push("**Analytics cookies** — help us understand how visitors interact with our service");
51
+ if (config.cookies.marketing) enabled.push("**Marketing cookies** — used to deliver relevant advertisements");
52
+ return {
53
+ id: "cookies",
54
+ title: "Cookies and Tracking",
55
+ body: enabled.length > 0 ? `We use the following types of cookies and tracking technologies:\n\n${enabled.map((e) => `- ${e}`).join("\n")}` : "We do not use cookies or tracking technologies on our service."
56
+ };
71
57
  }
72
-
73
- // src/templates/privacy/data-collected.ts
58
+ //#endregion
59
+ //#region src/templates/privacy/data-collected.ts
74
60
  function buildDataCollected(config) {
75
- const entries = Object.entries(config.dataCollected);
76
- const lines = entries.map(([category, items]) => {
77
- const itemList = items.map((item) => ` - ${item}`).join(`
78
- `);
79
- return `**${category}:**
80
- ${itemList}`;
81
- });
82
- return {
83
- id: "data-collected",
84
- title: "Information We Collect",
85
- body: `We collect the following categories of information:
86
-
87
- ${lines.join(`
88
-
89
- `)}`
90
- };
61
+ return {
62
+ id: "data-collected",
63
+ title: "Information We Collect",
64
+ body: `We collect the following categories of information:\n\n${Object.entries(config.dataCollected).map(([category, items]) => {
65
+ return `**${category}:**\n${items.map((item) => ` - ${item}`).join("\n")}`;
66
+ }).join("\n\n")}`
67
+ };
91
68
  }
92
-
93
- // src/templates/privacy/data-retention.ts
69
+ //#endregion
70
+ //#region src/templates/privacy/data-retention.ts
94
71
  function buildDataRetention(config) {
95
- const entries = Object.entries(config.retention);
96
- const lines = entries.map(([category, period]) => `- **${category}:** ${period}`);
97
- return {
98
- id: "data-retention",
99
- title: "Data Retention",
100
- body: `We retain your information for the following periods:
101
-
102
- ${lines.join(`
103
- `)}`
104
- };
72
+ return {
73
+ id: "data-retention",
74
+ title: "Data Retention",
75
+ body: `We retain your information for the following periods:\n\n${Object.entries(config.retention).map(([category, period]) => `- **${category}:** ${period}`).join("\n")}`
76
+ };
105
77
  }
106
-
107
- // src/templates/privacy/gdpr-supplement.ts
78
+ //#endregion
79
+ //#region src/templates/privacy/gdpr-supplement.ts
108
80
  function buildGdprSupplement(config) {
109
- if (!config.jurisdictions.includes("eu"))
110
- return null;
111
- return {
112
- id: "gdpr-supplement",
113
- title: "GDPR Supplemental Disclosures",
114
- body: `This section applies to individuals in the European Economic Area (EEA) under the General Data Protection Regulation (GDPR).
81
+ if (!config.jurisdictions.includes("eu")) return null;
82
+ return {
83
+ id: "gdpr-supplement",
84
+ title: "GDPR Supplemental Disclosures",
85
+ body: `This section applies to individuals in the European Economic Area (EEA) under the General Data Protection Regulation (GDPR).
115
86
 
116
87
  **Data Controller:** ${config.company.legalName}, ${config.company.address}
117
88
 
118
89
  **Your GDPR Rights:** In addition to the rights listed above, you have the right to lodge a complaint with your local data protection authority if you believe we have not handled your data in accordance with applicable law.
119
90
 
120
91
  **International Transfers:** If we transfer your personal data outside the EEA, we ensure adequate safeguards are in place in accordance with GDPR requirements.`
121
- };
92
+ };
122
93
  }
123
-
124
- // src/templates/privacy/introduction.ts
125
- function buildIntroduction(config) {
126
- return {
127
- id: "introduction",
128
- title: "Introduction",
129
- body: `This Privacy Policy describes how ${config.company.name} ("we", "us", or "our") collects, uses, and shares information about you when you use our services.
94
+ //#endregion
95
+ //#region src/templates/privacy/introduction.ts
96
+ function buildIntroduction$1(config) {
97
+ return {
98
+ id: "introduction",
99
+ title: "Introduction",
100
+ body: `This Privacy Policy describes how ${config.company.name} ("we", "us", or "our") collects, uses, and shares information about you when you use our services.
130
101
 
131
102
  **Effective Date:** ${config.effectiveDate}
132
103
 
133
104
  If you have questions about this policy, please contact us at ${config.company.contact}.`
134
- };
105
+ };
135
106
  }
136
-
137
- // src/templates/privacy/legal-basis.ts
107
+ //#endregion
108
+ //#region src/templates/privacy/legal-basis.ts
138
109
  function buildLegalBasis(config) {
139
- if (!config.jurisdictions.includes("eu"))
140
- return null;
141
- return {
142
- id: "legal-basis",
143
- title: "Legal Basis for Processing",
144
- body: `We process your personal data under the following legal basis:
145
-
146
- ${config.legalBasis}`
147
- };
110
+ if (!config.jurisdictions.includes("eu")) return null;
111
+ return {
112
+ id: "legal-basis",
113
+ title: "Legal Basis for Processing",
114
+ body: `We process your personal data under the following legal basis:\n\n${config.legalBasis}`
115
+ };
148
116
  }
149
-
150
- // src/templates/privacy/third-parties.ts
117
+ //#endregion
118
+ //#region src/templates/privacy/third-parties.ts
151
119
  function buildThirdParties(config) {
152
- const lines = config.thirdParties.map((tp) => `- **${tp.name}** — ${tp.purpose}`);
153
- const body = lines.length > 0 ? `We share data with the following third-party services:
154
-
155
- ${lines.join(`
156
- `)}` : "We do not share your data with third-party services.";
157
- return {
158
- id: "third-parties",
159
- title: "Third-Party Services",
160
- body
161
- };
120
+ const lines = config.thirdParties.map((tp) => `- **${tp.name}** — ${tp.purpose}`);
121
+ return {
122
+ id: "third-parties",
123
+ title: "Third-Party Services",
124
+ body: lines.length > 0 ? `We share data with the following third-party services:\n\n${lines.join("\n")}` : "We do not share your data with third-party services."
125
+ };
162
126
  }
163
-
164
- // src/templates/privacy/user-rights.ts
165
- var RIGHTS_LABELS = {
166
- access: "Right to access your personal data",
167
- rectification: "Right to correct inaccurate data",
168
- erasure: "Right to request deletion of your data",
169
- portability: "Right to receive your data in a portable format",
170
- restriction: "Right to restrict how we process your data",
171
- objection: "Right to object to processing",
172
- opt_out_sale: "Right to opt out of the sale of your personal information",
173
- non_discrimination: "Right to non-discriminatory treatment for exercising your rights"
127
+ //#endregion
128
+ //#region src/templates/privacy/user-rights.ts
129
+ const RIGHTS_LABELS = {
130
+ access: "Right to access your personal data",
131
+ rectification: "Right to correct inaccurate data",
132
+ erasure: "Right to request deletion of your data",
133
+ portability: "Right to receive your data in a portable format",
134
+ restriction: "Right to restrict how we process your data",
135
+ objection: "Right to object to processing",
136
+ opt_out_sale: "Right to opt out of the sale of your personal information",
137
+ non_discrimination: "Right to non-discriminatory treatment for exercising your rights"
174
138
  };
175
139
  function buildUserRights(config) {
176
- const lines = config.userRights.map((right) => {
177
- const label = RIGHTS_LABELS[right] ?? right;
178
- return `- ${label}`;
179
- });
180
- return {
181
- id: "user-rights",
182
- title: "Your Rights",
183
- body: `You have the following rights regarding your personal data:
184
-
185
- ${lines.join(`
186
- `)}`
187
- };
140
+ return {
141
+ id: "user-rights",
142
+ title: "Your Rights",
143
+ body: `You have the following rights regarding your personal data:\n\n${config.userRights.map((right) => {
144
+ return `- ${RIGHTS_LABELS[right] ?? right}`;
145
+ }).join("\n")}`
146
+ };
188
147
  }
189
-
190
- // src/privacy.ts
191
- var SECTION_BUILDERS = [
192
- buildIntroduction,
193
- buildDataCollected,
194
- buildLegalBasis,
195
- buildDataRetention,
196
- buildCookies,
197
- buildThirdParties,
198
- buildUserRights,
199
- buildGdprSupplement,
200
- buildCcpaSupplement,
201
- buildContact
148
+ //#endregion
149
+ //#region src/privacy.ts
150
+ const SECTION_BUILDERS$1 = [
151
+ buildIntroduction$1,
152
+ buildDataCollected,
153
+ buildLegalBasis,
154
+ buildDataRetention,
155
+ buildCookies,
156
+ buildThirdParties,
157
+ buildUserRights,
158
+ buildGdprSupplement,
159
+ buildCcpaSupplement,
160
+ buildContact$1
202
161
  ];
203
162
  function compilePrivacyPolicy(config, options = { formats: ["markdown"] }) {
204
- const sections = SECTION_BUILDERS.map((builder) => builder(config)).filter((s) => s !== null);
205
- return options.formats.map((format) => {
206
- switch (format) {
207
- case "markdown":
208
- return { format, content: renderMarkdown(sections), sections };
209
- case "html":
210
- return { format, content: renderHTML(sections), sections };
211
- case "pdf":
212
- throw new Error("pdf format is not yet implemented");
213
- case "jsx":
214
- throw new Error("jsx format is not yet implemented");
215
- default:
216
- throw new Error(`Unsupported format: ${format}`);
217
- }
218
- });
219
- }
220
- // src/validate.ts
163
+ const sections = SECTION_BUILDERS$1.map((builder) => builder(config)).filter((s) => s !== null);
164
+ return options.formats.map((format) => {
165
+ switch (format) {
166
+ case "markdown": return {
167
+ format,
168
+ content: renderMarkdown(sections),
169
+ sections
170
+ };
171
+ case "html": return {
172
+ format,
173
+ content: renderHTML(sections),
174
+ sections
175
+ };
176
+ case "pdf": throw new Error("pdf format is not yet implemented");
177
+ case "jsx": throw new Error("jsx format is not yet implemented");
178
+ default: throw new Error(`Unsupported format: ${format}`);
179
+ }
180
+ });
181
+ }
182
+ //#endregion
183
+ //#region src/templates/terms/acceptance.ts
184
+ function buildAcceptance(config) {
185
+ return {
186
+ id: "tos-acceptance",
187
+ title: "Acceptance of Terms",
188
+ body: `By accessing or using our services, you agree to be bound by these Terms. You accept these Terms by:\n\n${config.acceptance.methods.map((m) => `- ${m}`).join("\n")}\n\nIf you do not agree to these Terms, you may not use our services.`
189
+ };
190
+ }
191
+ //#endregion
192
+ //#region src/templates/terms/accounts.ts
193
+ function buildAccounts(config) {
194
+ if (!config.accounts) return null;
195
+ const { registrationRequired, userResponsibleForCredentials, companyCanTerminate } = config.accounts;
196
+ const lines = [];
197
+ if (registrationRequired) lines.push("You must create an account to access certain features of our services. You agree to provide accurate, current, and complete information during registration.");
198
+ if (userResponsibleForCredentials) lines.push("You are responsible for maintaining the confidentiality of your account credentials and for all activities that occur under your account. You must notify us immediately of any unauthorized use of your account.");
199
+ if (companyCanTerminate) lines.push(`${config.company.name} reserves the right to suspend or terminate your account at any time, with or without notice, for any reason including violation of these Terms.`);
200
+ return {
201
+ id: "tos-accounts",
202
+ title: "Accounts",
203
+ body: lines.join("\n\n")
204
+ };
205
+ }
206
+ //#endregion
207
+ //#region src/templates/terms/availability.ts
208
+ function buildAvailability(config) {
209
+ if (!config.availability) return null;
210
+ const lines = [];
211
+ if (config.availability.noUptimeGuarantee) lines.push("We do not guarantee that our services will be available at all times. Our services may be subject to interruptions, delays, or errors.");
212
+ if (config.availability.maintenanceWindows) lines.push(`**Maintenance:** ${config.availability.maintenanceWindows}`);
213
+ return {
214
+ id: "tos-availability",
215
+ title: "Service Availability",
216
+ body: lines.join("\n\n")
217
+ };
218
+ }
219
+ //#endregion
220
+ //#region src/templates/terms/changes-to-terms.ts
221
+ function buildChangesToTerms(config) {
222
+ if (!config.changesPolicy) return null;
223
+ const { noticeMethod, noticePeriodDays } = config.changesPolicy;
224
+ return {
225
+ id: "tos-changes",
226
+ title: "Changes to These Terms",
227
+ body: `We may update these Terms from time to time. We will notify you of material changes via ${noticeMethod}${noticePeriodDays ? ` at least **${noticePeriodDays} days** before they take effect` : " before they take effect"}. Your continued use of our services after changes become effective constitutes your acceptance of the revised Terms.`
228
+ };
229
+ }
230
+ //#endregion
231
+ //#region src/templates/terms/contact.ts
232
+ function buildContact(config) {
233
+ return {
234
+ id: "tos-contact",
235
+ title: "Contact Us",
236
+ body: `If you have any questions about these Terms, please contact us at:
237
+
238
+ **${config.company.legalName}**
239
+ ${config.company.address}
240
+ ${config.company.contact}`
241
+ };
242
+ }
243
+ //#endregion
244
+ //#region src/templates/terms/disclaimers.ts
245
+ function buildDisclaimers(config) {
246
+ if (!config.disclaimers) return null;
247
+ const lines = [];
248
+ if (config.disclaimers.serviceProvidedAsIs) lines.push("OUR SERVICES ARE PROVIDED \"AS IS\" AND \"AS AVAILABLE\" WITHOUT WARRANTIES OF ANY KIND.");
249
+ if (config.disclaimers.noWarranties) lines.push(`${config.company.legalName} EXPRESSLY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.`);
250
+ return {
251
+ id: "tos-disclaimers",
252
+ title: "Disclaimer of Warranties",
253
+ body: lines.join("\n\n")
254
+ };
255
+ }
256
+ //#endregion
257
+ //#region src/templates/terms/dispute-resolution.ts
258
+ function buildDisputeResolution(config) {
259
+ if (!config.disputeResolution) return null;
260
+ const { method, venue, classActionWaiver } = config.disputeResolution;
261
+ const lines = [{
262
+ arbitration: "Any disputes arising out of or relating to these Terms or our services shall be resolved by binding arbitration rather than in court.",
263
+ litigation: "Any disputes arising out of or relating to these Terms or our services shall be resolved through litigation in a court of competent jurisdiction.",
264
+ mediation: "Any disputes arising out of or relating to these Terms or our services shall first be submitted to non-binding mediation before pursuing other remedies."
265
+ }[method] ?? "Disputes arising out of or relating to these Terms shall be resolved as described below."];
266
+ if (venue) lines.push(`**Venue:** ${venue}`);
267
+ if (classActionWaiver) lines.push("**Class Action Waiver:** You agree that any dispute resolution proceedings will be conducted only on an individual basis and not in a class, consolidated, or representative action.");
268
+ return {
269
+ id: "tos-dispute-resolution",
270
+ title: "Dispute Resolution",
271
+ body: lines.join("\n\n")
272
+ };
273
+ }
274
+ //#endregion
275
+ //#region src/templates/terms/eligibility.ts
276
+ function buildEligibility(config) {
277
+ if (!config.eligibility) return null;
278
+ const { minimumAge, jurisdictionRestrictions } = config.eligibility;
279
+ let body = `You must be at least **${minimumAge} years old** to use our services. By using our services, you represent and warrant that you meet this age requirement.`;
280
+ if (jurisdictionRestrictions && jurisdictionRestrictions.length > 0) {
281
+ const list = jurisdictionRestrictions.map((r) => `- ${r}`).join("\n");
282
+ body += `\n\nOur services are not available in the following jurisdictions:\n\n${list}`;
283
+ }
284
+ return {
285
+ id: "tos-eligibility",
286
+ title: "Eligibility",
287
+ body
288
+ };
289
+ }
290
+ //#endregion
291
+ //#region src/templates/terms/governing-law.ts
292
+ function buildGoverningLaw(config) {
293
+ return {
294
+ id: "tos-governing-law",
295
+ title: "Governing Law",
296
+ body: `These Terms shall be governed by and construed in accordance with the laws of **${config.governingLaw.jurisdiction}**, without regard to its conflict of law provisions.`
297
+ };
298
+ }
299
+ //#endregion
300
+ //#region src/templates/terms/indemnification.ts
301
+ function buildIndemnification(config) {
302
+ if (!config.indemnification) return null;
303
+ const lines = [];
304
+ if (config.indemnification.userIndemnifiesCompany) lines.push(`You agree to indemnify and hold harmless ${config.company.legalName} and its officers, directors, employees, and agents from and against any claims, liabilities, damages, losses, and expenses arising out of or in any way connected with your access to or use of our services.`);
305
+ if (config.indemnification.scope) lines.push(`**Scope:** ${config.indemnification.scope}`);
306
+ return {
307
+ id: "tos-indemnification",
308
+ title: "Indemnification",
309
+ body: lines.join("\n\n")
310
+ };
311
+ }
312
+ //#endregion
313
+ //#region src/templates/terms/intellectual-property.ts
314
+ function buildIntellectualProperty(config) {
315
+ if (!config.intellectualProperty) return null;
316
+ const { companyOwnsService, usersMayNotCopy } = config.intellectualProperty;
317
+ const lines = [];
318
+ if (companyOwnsService) lines.push(`The services and all content, features, and functionality (including but not limited to text, graphics, logos, and software) are owned by ${config.company.legalName} and are protected by intellectual property laws.`);
319
+ if (usersMayNotCopy) lines.push("You may not copy, modify, distribute, sell, or lease any part of our services or included software, nor may you reverse engineer or attempt to extract the source code of that software.");
320
+ return {
321
+ id: "tos-intellectual-property",
322
+ title: "Intellectual Property",
323
+ body: lines.join("\n\n")
324
+ };
325
+ }
326
+ //#endregion
327
+ //#region src/templates/terms/introduction.ts
328
+ function buildIntroduction(config) {
329
+ const privacyLine = config.privacyPolicyUrl ? `\n\nFor information about how we collect and use your data, please review our [Privacy Policy](${config.privacyPolicyUrl}).` : "";
330
+ return {
331
+ id: "tos-introduction",
332
+ title: "Terms of Service",
333
+ body: `These Terms of Service ("Terms") govern your access to and use of the services provided by ${config.company.name} ("${config.company.name}", "we", "us", or "our"). By using our services, you agree to these Terms.
334
+
335
+ **Effective Date:** ${config.effectiveDate}${privacyLine}`
336
+ };
337
+ }
338
+ //#endregion
339
+ //#region src/templates/terms/limitation-of-liability.ts
340
+ function buildLimitationOfLiability(config) {
341
+ if (!config.limitationOfLiability) return null;
342
+ const lines = [];
343
+ if (config.limitationOfLiability.excludesIndirectDamages) lines.push(`TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, ${config.company.legalName.toUpperCase()} SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, OR ANY LOSS OF PROFITS OR REVENUES, WHETHER INCURRED DIRECTLY OR INDIRECTLY, OR ANY LOSS OF DATA, USE, GOODWILL, OR OTHER INTANGIBLE LOSSES.`);
344
+ if (config.limitationOfLiability.liabilityCap) lines.push(`**Liability Cap:** ${config.limitationOfLiability.liabilityCap}`);
345
+ return {
346
+ id: "tos-limitation-of-liability",
347
+ title: "Limitation of Liability",
348
+ body: lines.join("\n\n")
349
+ };
350
+ }
351
+ //#endregion
352
+ //#region src/templates/terms/payments.ts
353
+ function buildPayments(config) {
354
+ if (!config.payments || !config.payments.hasPaidFeatures) return null;
355
+ const lines = ["Some features of our services require payment. By selecting a paid plan, you agree to pay all applicable fees."];
356
+ if (config.payments.refundPolicy) lines.push(`**Refunds:** ${config.payments.refundPolicy}`);
357
+ if (config.payments.priceChangesNotice) lines.push(`**Price Changes:** ${config.payments.priceChangesNotice}`);
358
+ return {
359
+ id: "tos-payments",
360
+ title: "Payments and Billing",
361
+ body: lines.join("\n\n")
362
+ };
363
+ }
364
+ //#endregion
365
+ //#region src/templates/terms/prohibited-use.ts
366
+ function buildProhibitedUse(config) {
367
+ if (!config.prohibitedUses || config.prohibitedUses.length === 0) return null;
368
+ return {
369
+ id: "tos-prohibited-use",
370
+ title: "Prohibited Uses",
371
+ body: `You agree not to use our services for any of the following purposes:\n\n${config.prohibitedUses.map((u) => `- ${u}`).join("\n")}`
372
+ };
373
+ }
374
+ //#endregion
375
+ //#region src/templates/terms/termination.ts
376
+ function buildTermination(config) {
377
+ if (!config.termination) return null;
378
+ const { companyCanTerminate, userCanTerminate, effectOfTermination } = config.termination;
379
+ const lines = [];
380
+ if (companyCanTerminate) lines.push(`${config.company.name} may suspend or terminate your access to the services at any time, with or without cause, and with or without notice.`);
381
+ if (userCanTerminate) lines.push("You may terminate your account at any time by discontinuing use of our services or by contacting us to close your account.");
382
+ if (effectOfTermination) lines.push(`**Effect of Termination:** ${effectOfTermination}`);
383
+ return {
384
+ id: "tos-termination",
385
+ title: "Termination",
386
+ body: lines.join("\n\n")
387
+ };
388
+ }
389
+ //#endregion
390
+ //#region src/templates/terms/third-party-services.ts
391
+ function buildThirdPartyServices(config) {
392
+ if (!config.thirdPartyServices || config.thirdPartyServices.length === 0) return null;
393
+ return {
394
+ id: "tos-third-party-services",
395
+ title: "Third-Party Services",
396
+ body: `Our services may integrate with or link to third-party services. Your use of those services is governed by their own terms and policies.\n\n${config.thirdPartyServices.map((s) => `- **${s.name}** — ${s.purpose}`).join("\n")}`
397
+ };
398
+ }
399
+ //#endregion
400
+ //#region src/templates/terms/user-content.ts
401
+ function buildUserContent(config) {
402
+ if (!config.userContent) return null;
403
+ const { usersOwnContent, licenseGrantedToCompany, licenseDescription, companyCanRemoveContent } = config.userContent;
404
+ const lines = [];
405
+ if (usersOwnContent) lines.push("You retain ownership of any content you submit, post, or display on or through our services (\"User Content\").");
406
+ if (licenseGrantedToCompany) {
407
+ const desc = licenseDescription ? licenseDescription : "a worldwide, royalty-free, non-exclusive license to use, reproduce, modify, and distribute your User Content in connection with operating and improving our services";
408
+ lines.push(`By submitting User Content, you grant ${config.company.name} ${desc}.`);
409
+ }
410
+ if (companyCanRemoveContent) lines.push(`${config.company.name} reserves the right to remove any User Content that violates these Terms or that we find objectionable, at our sole discretion.`);
411
+ return {
412
+ id: "tos-user-content",
413
+ title: "User Content",
414
+ body: lines.join("\n\n")
415
+ };
416
+ }
417
+ //#endregion
418
+ //#region src/terms.ts
419
+ const SECTION_BUILDERS = [
420
+ buildIntroduction,
421
+ buildAcceptance,
422
+ buildEligibility,
423
+ buildAccounts,
424
+ buildProhibitedUse,
425
+ buildUserContent,
426
+ buildIntellectualProperty,
427
+ buildPayments,
428
+ buildAvailability,
429
+ buildTermination,
430
+ buildDisclaimers,
431
+ buildLimitationOfLiability,
432
+ buildIndemnification,
433
+ buildThirdPartyServices,
434
+ buildDisputeResolution,
435
+ buildGoverningLaw,
436
+ buildChangesToTerms,
437
+ buildContact
438
+ ];
439
+ function compileTermsOfService(config, options = { formats: ["markdown"] }) {
440
+ const sections = SECTION_BUILDERS.map((builder) => builder(config)).filter((s) => s !== null);
441
+ return options.formats.map((format) => {
442
+ switch (format) {
443
+ case "markdown": return {
444
+ format,
445
+ content: renderMarkdown(sections),
446
+ sections
447
+ };
448
+ case "html": return {
449
+ format,
450
+ content: renderHTML(sections),
451
+ sections
452
+ };
453
+ case "pdf": throw new Error("pdf format is not yet implemented");
454
+ case "jsx": throw new Error("jsx format is not yet implemented");
455
+ default: throw new Error(`Unsupported format: ${format}`);
456
+ }
457
+ });
458
+ }
459
+ //#endregion
460
+ //#region src/validate.ts
221
461
  function validatePrivacyPolicy(config) {
222
- const issues = [];
223
- if (!config.effectiveDate)
224
- issues.push({ level: "error", message: "effectiveDate is required" });
225
- if (!config.company.name)
226
- issues.push({ level: "error", message: "company.name is required" });
227
- if (!config.company.legalName)
228
- issues.push({ level: "error", message: "company.legalName is required" });
229
- if (!config.company.address)
230
- issues.push({ level: "error", message: "company.address is required" });
231
- if (!config.company.contact)
232
- issues.push({ level: "error", message: "company.contact is required" });
233
- if (Object.keys(config.dataCollected).length === 0)
234
- issues.push({
235
- level: "error",
236
- message: "dataCollected must have at least one entry"
237
- });
238
- if (config.userRights.length === 0)
239
- issues.push({
240
- level: "warning",
241
- message: "userRights is empty — consider listing applicable rights"
242
- });
243
- if (config.jurisdictions.includes("eu")) {
244
- if (!config.legalBasis)
245
- issues.push({ level: "error", message: "GDPR requires a legalBasis" });
246
- for (const right of [
247
- "access",
248
- "rectification",
249
- "erasure",
250
- "portability",
251
- "restriction",
252
- "objection"
253
- ]) {
254
- if (!config.userRights.includes(right))
255
- issues.push({
256
- level: "warning",
257
- message: `GDPR recommends including the "${right}" right`
258
- });
259
- }
260
- }
261
- if (config.jurisdictions.includes("ca")) {
262
- for (const right of [
263
- "access",
264
- "erasure",
265
- "opt_out_sale",
266
- "non_discrimination"
267
- ]) {
268
- if (!config.userRights.includes(right))
269
- issues.push({
270
- level: "warning",
271
- message: `CCPA recommends including the "${right}" right`
272
- });
273
- }
274
- }
275
- return issues;
276
- }
277
- // src/index.ts
462
+ const issues = [];
463
+ if (!config.effectiveDate) issues.push({
464
+ level: "error",
465
+ message: "effectiveDate is required"
466
+ });
467
+ if (!config.company.name) issues.push({
468
+ level: "error",
469
+ message: "company.name is required"
470
+ });
471
+ if (!config.company.legalName) issues.push({
472
+ level: "error",
473
+ message: "company.legalName is required"
474
+ });
475
+ if (!config.company.address) issues.push({
476
+ level: "error",
477
+ message: "company.address is required"
478
+ });
479
+ if (!config.company.contact) issues.push({
480
+ level: "error",
481
+ message: "company.contact is required"
482
+ });
483
+ if (Object.keys(config.dataCollected).length === 0) issues.push({
484
+ level: "error",
485
+ message: "dataCollected must have at least one entry"
486
+ });
487
+ if (config.userRights.length === 0) issues.push({
488
+ level: "warning",
489
+ message: "userRights is empty — consider listing applicable rights"
490
+ });
491
+ if (config.jurisdictions.includes("eu")) {
492
+ if (!config.legalBasis) issues.push({
493
+ level: "error",
494
+ message: "GDPR requires a legalBasis"
495
+ });
496
+ for (const right of [
497
+ "access",
498
+ "rectification",
499
+ "erasure",
500
+ "portability",
501
+ "restriction",
502
+ "objection"
503
+ ]) if (!config.userRights.includes(right)) issues.push({
504
+ level: "warning",
505
+ message: `GDPR recommends including the "${right}" right`
506
+ });
507
+ }
508
+ if (config.jurisdictions.includes("ca")) {
509
+ for (const right of [
510
+ "access",
511
+ "erasure",
512
+ "opt_out_sale",
513
+ "non_discrimination"
514
+ ]) if (!config.userRights.includes(right)) issues.push({
515
+ level: "warning",
516
+ message: `CCPA recommends including the "${right}" right`
517
+ });
518
+ }
519
+ return issues;
520
+ }
521
+ //#endregion
522
+ //#region src/validate-terms.ts
523
+ function validateTermsOfService(config) {
524
+ const issues = [];
525
+ if (!config.effectiveDate) issues.push({
526
+ level: "error",
527
+ message: "effectiveDate is required"
528
+ });
529
+ if (!config.company.name) issues.push({
530
+ level: "error",
531
+ message: "company.name is required"
532
+ });
533
+ if (!config.company.legalName) issues.push({
534
+ level: "error",
535
+ message: "company.legalName is required"
536
+ });
537
+ if (!config.company.address) issues.push({
538
+ level: "error",
539
+ message: "company.address is required"
540
+ });
541
+ if (!config.company.contact) issues.push({
542
+ level: "error",
543
+ message: "company.contact is required"
544
+ });
545
+ if (!config.governingLaw.jurisdiction) issues.push({
546
+ level: "error",
547
+ message: "governingLaw.jurisdiction is required"
548
+ });
549
+ if (!config.disclaimers) issues.push({
550
+ level: "warning",
551
+ message: "disclaimers is missing — consider adding a disclaimer of warranties"
552
+ });
553
+ if (!config.limitationOfLiability) issues.push({
554
+ level: "warning",
555
+ message: "limitationOfLiability is missing — consider adding a limitation of liability clause"
556
+ });
557
+ if (config.acceptance.methods.length === 0) issues.push({
558
+ level: "warning",
559
+ message: "acceptance.methods is empty — consider listing how users accept these Terms"
560
+ });
561
+ return issues;
562
+ }
563
+ //#endregion
564
+ //#region src/index.ts
278
565
  function compilePolicy(input, options) {
279
- switch (input.type) {
280
- case "privacy": {
281
- const { type: _, ...config } = input;
282
- return compilePrivacyPolicy(config, options);
283
- }
284
- }
285
- }
286
- export {
287
- validatePrivacyPolicy,
288
- compilePrivacyPolicy,
289
- compilePolicy
290
- };
566
+ switch (input.type) {
567
+ case "privacy": {
568
+ const { type: _, ...config } = input;
569
+ return compilePrivacyPolicy(config, options);
570
+ }
571
+ case "terms": {
572
+ const { type: _, ...config } = input;
573
+ return compileTermsOfService(config, options);
574
+ }
575
+ }
576
+ }
577
+ //#endregion
578
+ export { compilePolicy, compilePrivacyPolicy, compileTermsOfService, validatePrivacyPolicy, validateTermsOfService };
579
+
580
+ //# sourceMappingURL=index.js.map