@openpolicy/vite 0.0.3 → 0.0.6
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/dist/index.d.ts +19 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +138 -644
- package/dist/index.js.map +1 -0
- package/package.json +9 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { OutputFormat } from "@openpolicy/core";
|
|
2
|
+
import { Plugin } from "vite";
|
|
3
|
+
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
type PolicyConfigEntry = string | {
|
|
6
|
+
config: string;
|
|
7
|
+
type?: "privacy" | "terms";
|
|
8
|
+
};
|
|
9
|
+
interface OpenPolicyOptions {
|
|
10
|
+
configs?: PolicyConfigEntry[];
|
|
11
|
+
config?: string;
|
|
12
|
+
formats?: OutputFormat[];
|
|
13
|
+
outDir?: string;
|
|
14
|
+
type?: "privacy" | "terms";
|
|
7
15
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
declare function writeScaffold(configPath: string, type?: "privacy" | "terms"): Promise<void>;
|
|
17
|
+
declare function generatePolicies(configPath: string, outDir: string, formats: OutputFormat[], type?: "privacy" | "terms"): Promise<void>;
|
|
18
|
+
declare function openPolicy(options?: OpenPolicyOptions): Plugin;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { OpenPolicyOptions, PolicyConfigEntry, generatePolicies, openPolicy, writeScaffold };
|
|
11
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KAcY,iBAAA;EAEP,MAAA;EAAgB,IAAA;AAAA;AAAA,UAEJ,iBAAA;EAChB,OAAA,GAAU,iBAAA;EACV,MAAA;EACA,OAAA,GAAU,YAAA;EACV,MAAA;EACA,IAAA;AAAA;AAAA,iBAyGqB,aAAA,CACrB,UAAA,UACA,IAAA,yBACE,OAAA;AAAA,iBAMmB,gBAAA,CACrB,UAAA,UACA,MAAA,UACA,OAAA,EAAS,YAAA,IACT,IAAA,yBACE,OAAA;AAAA,iBA+Ca,UAAA,CAAW,OAAA,GAAS,iBAAA,GAAyB,MAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,590 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- **Right to Know:** You may request information about the personal information we have collected about you, including the categories of sources, the business purpose for collection, and the categories of third parties with whom we share information.
|
|
27
|
-
- **Right to Delete:** You may request deletion of personal information we have collected from you, subject to certain exceptions.
|
|
28
|
-
- **Right to Opt-Out:** You may opt out of the sale or sharing of your personal information.
|
|
29
|
-
- **Right to Non-Discrimination:** We will not discriminate against you for exercising your California privacy rights.
|
|
30
|
-
|
|
31
|
-
To exercise your rights, contact us at ${config.company.contact}.`
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
function buildContact(config) {
|
|
35
|
-
return {
|
|
36
|
-
id: "contact",
|
|
37
|
-
title: "Contact Us",
|
|
38
|
-
body: `If you have questions or concerns about this Privacy Policy or our data practices, please contact us:
|
|
39
|
-
|
|
40
|
-
**${config.company.legalName}**
|
|
41
|
-
${config.company.address}
|
|
42
|
-
|
|
43
|
-
Email: ${config.company.contact}`
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function buildCookies(config) {
|
|
47
|
-
const enabled = [];
|
|
48
|
-
if (config.cookies.essential)
|
|
49
|
-
enabled.push("**Essential cookies** — required for the service to function");
|
|
50
|
-
if (config.cookies.analytics)
|
|
51
|
-
enabled.push("**Analytics cookies** — help us understand how visitors interact with our service");
|
|
52
|
-
if (config.cookies.marketing)
|
|
53
|
-
enabled.push("**Marketing cookies** — used to deliver relevant advertisements");
|
|
54
|
-
const body = enabled.length > 0 ? `We use the following types of cookies and tracking technologies:
|
|
55
|
-
|
|
56
|
-
${enabled.map((e) => `- ${e}`).join(`
|
|
57
|
-
`)}` : "We do not use cookies or tracking technologies on our service.";
|
|
58
|
-
return {
|
|
59
|
-
id: "cookies",
|
|
60
|
-
title: "Cookies and Tracking",
|
|
61
|
-
body
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
function buildDataCollected(config) {
|
|
65
|
-
const entries = Object.entries(config.dataCollected);
|
|
66
|
-
const lines = entries.map(([category, items]) => {
|
|
67
|
-
const itemList = items.map((item) => ` - ${item}`).join(`
|
|
68
|
-
`);
|
|
69
|
-
return `**${category}:**
|
|
70
|
-
${itemList}`;
|
|
71
|
-
});
|
|
72
|
-
return {
|
|
73
|
-
id: "data-collected",
|
|
74
|
-
title: "Information We Collect",
|
|
75
|
-
body: `We collect the following categories of information:
|
|
76
|
-
|
|
77
|
-
${lines.join(`
|
|
78
|
-
|
|
79
|
-
`)}`
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function buildDataRetention(config) {
|
|
83
|
-
const entries = Object.entries(config.retention);
|
|
84
|
-
const lines = entries.map(([category, period]) => `- **${category}:** ${period}`);
|
|
85
|
-
return {
|
|
86
|
-
id: "data-retention",
|
|
87
|
-
title: "Data Retention",
|
|
88
|
-
body: `We retain your information for the following periods:
|
|
89
|
-
|
|
90
|
-
${lines.join(`
|
|
91
|
-
`)}`
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
function buildGdprSupplement(config) {
|
|
95
|
-
if (!config.jurisdictions.includes("eu"))
|
|
96
|
-
return null;
|
|
97
|
-
return {
|
|
98
|
-
id: "gdpr-supplement",
|
|
99
|
-
title: "GDPR Supplemental Disclosures",
|
|
100
|
-
body: `This section applies to individuals in the European Economic Area (EEA) under the General Data Protection Regulation (GDPR).
|
|
101
|
-
|
|
102
|
-
**Data Controller:** ${config.company.legalName}, ${config.company.address}
|
|
103
|
-
|
|
104
|
-
**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.
|
|
105
|
-
|
|
106
|
-
**International Transfers:** If we transfer your personal data outside the EEA, we ensure adequate safeguards are in place in accordance with GDPR requirements.`
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
function buildIntroduction(config) {
|
|
110
|
-
return {
|
|
111
|
-
id: "introduction",
|
|
112
|
-
title: "Introduction",
|
|
113
|
-
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.
|
|
114
|
-
|
|
115
|
-
**Effective Date:** ${config.effectiveDate}
|
|
116
|
-
|
|
117
|
-
If you have questions about this policy, please contact us at ${config.company.contact}.`
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
function buildLegalBasis(config) {
|
|
121
|
-
if (!config.jurisdictions.includes("eu"))
|
|
122
|
-
return null;
|
|
123
|
-
return {
|
|
124
|
-
id: "legal-basis",
|
|
125
|
-
title: "Legal Basis for Processing",
|
|
126
|
-
body: `We process your personal data under the following legal basis:
|
|
127
|
-
|
|
128
|
-
${config.legalBasis}`
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
function buildThirdParties(config) {
|
|
132
|
-
const lines = config.thirdParties.map((tp) => `- **${tp.name}** — ${tp.purpose}`);
|
|
133
|
-
const body = lines.length > 0 ? `We share data with the following third-party services:
|
|
134
|
-
|
|
135
|
-
${lines.join(`
|
|
136
|
-
`)}` : "We do not share your data with third-party services.";
|
|
137
|
-
return {
|
|
138
|
-
id: "third-parties",
|
|
139
|
-
title: "Third-Party Services",
|
|
140
|
-
body
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
var RIGHTS_LABELS = {
|
|
144
|
-
access: "Right to access your personal data",
|
|
145
|
-
rectification: "Right to correct inaccurate data",
|
|
146
|
-
erasure: "Right to request deletion of your data",
|
|
147
|
-
portability: "Right to receive your data in a portable format",
|
|
148
|
-
restriction: "Right to restrict how we process your data",
|
|
149
|
-
objection: "Right to object to processing",
|
|
150
|
-
opt_out_sale: "Right to opt out of the sale of your personal information",
|
|
151
|
-
non_discrimination: "Right to non-discriminatory treatment for exercising your rights"
|
|
152
|
-
};
|
|
153
|
-
function buildUserRights(config) {
|
|
154
|
-
const lines = config.userRights.map((right) => {
|
|
155
|
-
const label = RIGHTS_LABELS[right] ?? right;
|
|
156
|
-
return `- ${label}`;
|
|
157
|
-
});
|
|
158
|
-
return {
|
|
159
|
-
id: "user-rights",
|
|
160
|
-
title: "Your Rights",
|
|
161
|
-
body: `You have the following rights regarding your personal data:
|
|
162
|
-
|
|
163
|
-
${lines.join(`
|
|
164
|
-
`)}`
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
var SECTION_BUILDERS = [
|
|
168
|
-
buildIntroduction,
|
|
169
|
-
buildDataCollected,
|
|
170
|
-
buildLegalBasis,
|
|
171
|
-
buildDataRetention,
|
|
172
|
-
buildCookies,
|
|
173
|
-
buildThirdParties,
|
|
174
|
-
buildUserRights,
|
|
175
|
-
buildGdprSupplement,
|
|
176
|
-
buildCcpaSupplement,
|
|
177
|
-
buildContact
|
|
178
|
-
];
|
|
179
|
-
function compilePrivacyPolicy(config, options = { formats: ["markdown"] }) {
|
|
180
|
-
const sections = SECTION_BUILDERS.map((builder) => builder(config)).filter((s) => s !== null);
|
|
181
|
-
return options.formats.map((format) => {
|
|
182
|
-
switch (format) {
|
|
183
|
-
case "markdown":
|
|
184
|
-
return { format, content: renderMarkdown(sections), sections };
|
|
185
|
-
case "html":
|
|
186
|
-
return { format, content: renderHTML(sections), sections };
|
|
187
|
-
case "pdf":
|
|
188
|
-
throw new Error("pdf format is not yet implemented");
|
|
189
|
-
case "jsx":
|
|
190
|
-
throw new Error("jsx format is not yet implemented");
|
|
191
|
-
default:
|
|
192
|
-
throw new Error(`Unsupported format: ${format}`);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
function validatePrivacyPolicy(config) {
|
|
197
|
-
const issues = [];
|
|
198
|
-
if (!config.effectiveDate)
|
|
199
|
-
issues.push({ level: "error", message: "effectiveDate is required" });
|
|
200
|
-
if (!config.company.name)
|
|
201
|
-
issues.push({ level: "error", message: "company.name is required" });
|
|
202
|
-
if (!config.company.legalName)
|
|
203
|
-
issues.push({ level: "error", message: "company.legalName is required" });
|
|
204
|
-
if (!config.company.address)
|
|
205
|
-
issues.push({ level: "error", message: "company.address is required" });
|
|
206
|
-
if (!config.company.contact)
|
|
207
|
-
issues.push({ level: "error", message: "company.contact is required" });
|
|
208
|
-
if (Object.keys(config.dataCollected).length === 0)
|
|
209
|
-
issues.push({
|
|
210
|
-
level: "error",
|
|
211
|
-
message: "dataCollected must have at least one entry"
|
|
212
|
-
});
|
|
213
|
-
if (config.userRights.length === 0)
|
|
214
|
-
issues.push({
|
|
215
|
-
level: "warning",
|
|
216
|
-
message: "userRights is empty — consider listing applicable rights"
|
|
217
|
-
});
|
|
218
|
-
if (config.jurisdictions.includes("eu")) {
|
|
219
|
-
if (!config.legalBasis)
|
|
220
|
-
issues.push({ level: "error", message: "GDPR requires a legalBasis" });
|
|
221
|
-
for (const right of [
|
|
222
|
-
"access",
|
|
223
|
-
"rectification",
|
|
224
|
-
"erasure",
|
|
225
|
-
"portability",
|
|
226
|
-
"restriction",
|
|
227
|
-
"objection"
|
|
228
|
-
]) {
|
|
229
|
-
if (!config.userRights.includes(right))
|
|
230
|
-
issues.push({
|
|
231
|
-
level: "warning",
|
|
232
|
-
message: `GDPR recommends including the "${right}" right`
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
if (config.jurisdictions.includes("ca")) {
|
|
237
|
-
for (const right of [
|
|
238
|
-
"access",
|
|
239
|
-
"erasure",
|
|
240
|
-
"opt_out_sale",
|
|
241
|
-
"non_discrimination"
|
|
242
|
-
]) {
|
|
243
|
-
if (!config.userRights.includes(right))
|
|
244
|
-
issues.push({
|
|
245
|
-
level: "warning",
|
|
246
|
-
message: `CCPA recommends including the "${right}" right`
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return issues;
|
|
251
|
-
}
|
|
252
|
-
function compilePolicy(input, options) {
|
|
253
|
-
switch (input.type) {
|
|
254
|
-
case "privacy": {
|
|
255
|
-
const { type: _, ...config } = input;
|
|
256
|
-
return compilePrivacyPolicy(config, options);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// node:path
|
|
262
|
-
function assertPath(path) {
|
|
263
|
-
if (typeof path !== "string")
|
|
264
|
-
throw new TypeError("Path must be a string. Received " + JSON.stringify(path));
|
|
265
|
-
}
|
|
266
|
-
function normalizeStringPosix(path, allowAboveRoot) {
|
|
267
|
-
var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
|
|
268
|
-
for (var i = 0;i <= path.length; ++i) {
|
|
269
|
-
if (i < path.length)
|
|
270
|
-
code = path.charCodeAt(i);
|
|
271
|
-
else if (code === 47)
|
|
272
|
-
break;
|
|
273
|
-
else
|
|
274
|
-
code = 47;
|
|
275
|
-
if (code === 47) {
|
|
276
|
-
if (lastSlash === i - 1 || dots === 1)
|
|
277
|
-
;
|
|
278
|
-
else if (lastSlash !== i - 1 && dots === 2) {
|
|
279
|
-
if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
|
|
280
|
-
if (res.length > 2) {
|
|
281
|
-
var lastSlashIndex = res.lastIndexOf("/");
|
|
282
|
-
if (lastSlashIndex !== res.length - 1) {
|
|
283
|
-
if (lastSlashIndex === -1)
|
|
284
|
-
res = "", lastSegmentLength = 0;
|
|
285
|
-
else
|
|
286
|
-
res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
|
|
287
|
-
lastSlash = i, dots = 0;
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
} else if (res.length === 2 || res.length === 1) {
|
|
291
|
-
res = "", lastSegmentLength = 0, lastSlash = i, dots = 0;
|
|
292
|
-
continue;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
if (allowAboveRoot) {
|
|
296
|
-
if (res.length > 0)
|
|
297
|
-
res += "/..";
|
|
298
|
-
else
|
|
299
|
-
res = "..";
|
|
300
|
-
lastSegmentLength = 2;
|
|
301
|
-
}
|
|
302
|
-
} else {
|
|
303
|
-
if (res.length > 0)
|
|
304
|
-
res += "/" + path.slice(lastSlash + 1, i);
|
|
305
|
-
else
|
|
306
|
-
res = path.slice(lastSlash + 1, i);
|
|
307
|
-
lastSegmentLength = i - lastSlash - 1;
|
|
308
|
-
}
|
|
309
|
-
lastSlash = i, dots = 0;
|
|
310
|
-
} else if (code === 46 && dots !== -1)
|
|
311
|
-
++dots;
|
|
312
|
-
else
|
|
313
|
-
dots = -1;
|
|
314
|
-
}
|
|
315
|
-
return res;
|
|
316
|
-
}
|
|
317
|
-
function _format(sep, pathObject) {
|
|
318
|
-
var dir = pathObject.dir || pathObject.root, base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
|
|
319
|
-
if (!dir)
|
|
320
|
-
return base;
|
|
321
|
-
if (dir === pathObject.root)
|
|
322
|
-
return dir + base;
|
|
323
|
-
return dir + sep + base;
|
|
324
|
-
}
|
|
325
|
-
function resolve() {
|
|
326
|
-
var resolvedPath = "", resolvedAbsolute = false, cwd;
|
|
327
|
-
for (var i = arguments.length - 1;i >= -1 && !resolvedAbsolute; i--) {
|
|
328
|
-
var path;
|
|
329
|
-
if (i >= 0)
|
|
330
|
-
path = arguments[i];
|
|
331
|
-
else {
|
|
332
|
-
if (cwd === undefined)
|
|
333
|
-
cwd = process.cwd();
|
|
334
|
-
path = cwd;
|
|
335
|
-
}
|
|
336
|
-
if (assertPath(path), path.length === 0)
|
|
337
|
-
continue;
|
|
338
|
-
resolvedPath = path + "/" + resolvedPath, resolvedAbsolute = path.charCodeAt(0) === 47;
|
|
339
|
-
}
|
|
340
|
-
if (resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute), resolvedAbsolute)
|
|
341
|
-
if (resolvedPath.length > 0)
|
|
342
|
-
return "/" + resolvedPath;
|
|
343
|
-
else
|
|
344
|
-
return "/";
|
|
345
|
-
else if (resolvedPath.length > 0)
|
|
346
|
-
return resolvedPath;
|
|
347
|
-
else
|
|
348
|
-
return ".";
|
|
349
|
-
}
|
|
350
|
-
function normalize(path) {
|
|
351
|
-
if (assertPath(path), path.length === 0)
|
|
352
|
-
return ".";
|
|
353
|
-
var isAbsolute = path.charCodeAt(0) === 47, trailingSeparator = path.charCodeAt(path.length - 1) === 47;
|
|
354
|
-
if (path = normalizeStringPosix(path, !isAbsolute), path.length === 0 && !isAbsolute)
|
|
355
|
-
path = ".";
|
|
356
|
-
if (path.length > 0 && trailingSeparator)
|
|
357
|
-
path += "/";
|
|
358
|
-
if (isAbsolute)
|
|
359
|
-
return "/" + path;
|
|
360
|
-
return path;
|
|
361
|
-
}
|
|
362
|
-
function isAbsolute(path) {
|
|
363
|
-
return assertPath(path), path.length > 0 && path.charCodeAt(0) === 47;
|
|
364
|
-
}
|
|
365
|
-
function join() {
|
|
366
|
-
if (arguments.length === 0)
|
|
367
|
-
return ".";
|
|
368
|
-
var joined;
|
|
369
|
-
for (var i = 0;i < arguments.length; ++i) {
|
|
370
|
-
var arg = arguments[i];
|
|
371
|
-
if (assertPath(arg), arg.length > 0)
|
|
372
|
-
if (joined === undefined)
|
|
373
|
-
joined = arg;
|
|
374
|
-
else
|
|
375
|
-
joined += "/" + arg;
|
|
376
|
-
}
|
|
377
|
-
if (joined === undefined)
|
|
378
|
-
return ".";
|
|
379
|
-
return normalize(joined);
|
|
380
|
-
}
|
|
381
|
-
function relative(from, to) {
|
|
382
|
-
if (assertPath(from), assertPath(to), from === to)
|
|
383
|
-
return "";
|
|
384
|
-
if (from = resolve(from), to = resolve(to), from === to)
|
|
385
|
-
return "";
|
|
386
|
-
var fromStart = 1;
|
|
387
|
-
for (;fromStart < from.length; ++fromStart)
|
|
388
|
-
if (from.charCodeAt(fromStart) !== 47)
|
|
389
|
-
break;
|
|
390
|
-
var fromEnd = from.length, fromLen = fromEnd - fromStart, toStart = 1;
|
|
391
|
-
for (;toStart < to.length; ++toStart)
|
|
392
|
-
if (to.charCodeAt(toStart) !== 47)
|
|
393
|
-
break;
|
|
394
|
-
var toEnd = to.length, toLen = toEnd - toStart, length = fromLen < toLen ? fromLen : toLen, lastCommonSep = -1, i = 0;
|
|
395
|
-
for (;i <= length; ++i) {
|
|
396
|
-
if (i === length) {
|
|
397
|
-
if (toLen > length) {
|
|
398
|
-
if (to.charCodeAt(toStart + i) === 47)
|
|
399
|
-
return to.slice(toStart + i + 1);
|
|
400
|
-
else if (i === 0)
|
|
401
|
-
return to.slice(toStart + i);
|
|
402
|
-
} else if (fromLen > length) {
|
|
403
|
-
if (from.charCodeAt(fromStart + i) === 47)
|
|
404
|
-
lastCommonSep = i;
|
|
405
|
-
else if (i === 0)
|
|
406
|
-
lastCommonSep = 0;
|
|
407
|
-
}
|
|
408
|
-
break;
|
|
409
|
-
}
|
|
410
|
-
var fromCode = from.charCodeAt(fromStart + i), toCode = to.charCodeAt(toStart + i);
|
|
411
|
-
if (fromCode !== toCode)
|
|
412
|
-
break;
|
|
413
|
-
else if (fromCode === 47)
|
|
414
|
-
lastCommonSep = i;
|
|
415
|
-
}
|
|
416
|
-
var out = "";
|
|
417
|
-
for (i = fromStart + lastCommonSep + 1;i <= fromEnd; ++i)
|
|
418
|
-
if (i === fromEnd || from.charCodeAt(i) === 47)
|
|
419
|
-
if (out.length === 0)
|
|
420
|
-
out += "..";
|
|
421
|
-
else
|
|
422
|
-
out += "/..";
|
|
423
|
-
if (out.length > 0)
|
|
424
|
-
return out + to.slice(toStart + lastCommonSep);
|
|
425
|
-
else {
|
|
426
|
-
if (toStart += lastCommonSep, to.charCodeAt(toStart) === 47)
|
|
427
|
-
++toStart;
|
|
428
|
-
return to.slice(toStart);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
function _makeLong(path) {
|
|
432
|
-
return path;
|
|
433
|
-
}
|
|
434
|
-
function dirname(path) {
|
|
435
|
-
if (assertPath(path), path.length === 0)
|
|
436
|
-
return ".";
|
|
437
|
-
var code = path.charCodeAt(0), hasRoot = code === 47, end = -1, matchedSlash = true;
|
|
438
|
-
for (var i = path.length - 1;i >= 1; --i)
|
|
439
|
-
if (code = path.charCodeAt(i), code === 47) {
|
|
440
|
-
if (!matchedSlash) {
|
|
441
|
-
end = i;
|
|
442
|
-
break;
|
|
443
|
-
}
|
|
444
|
-
} else
|
|
445
|
-
matchedSlash = false;
|
|
446
|
-
if (end === -1)
|
|
447
|
-
return hasRoot ? "/" : ".";
|
|
448
|
-
if (hasRoot && end === 1)
|
|
449
|
-
return "//";
|
|
450
|
-
return path.slice(0, end);
|
|
451
|
-
}
|
|
452
|
-
function basename(path, ext) {
|
|
453
|
-
if (ext !== undefined && typeof ext !== "string")
|
|
454
|
-
throw new TypeError('"ext" argument must be a string');
|
|
455
|
-
assertPath(path);
|
|
456
|
-
var start = 0, end = -1, matchedSlash = true, i;
|
|
457
|
-
if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
|
|
458
|
-
if (ext.length === path.length && ext === path)
|
|
459
|
-
return "";
|
|
460
|
-
var extIdx = ext.length - 1, firstNonSlashEnd = -1;
|
|
461
|
-
for (i = path.length - 1;i >= 0; --i) {
|
|
462
|
-
var code = path.charCodeAt(i);
|
|
463
|
-
if (code === 47) {
|
|
464
|
-
if (!matchedSlash) {
|
|
465
|
-
start = i + 1;
|
|
466
|
-
break;
|
|
467
|
-
}
|
|
468
|
-
} else {
|
|
469
|
-
if (firstNonSlashEnd === -1)
|
|
470
|
-
matchedSlash = false, firstNonSlashEnd = i + 1;
|
|
471
|
-
if (extIdx >= 0)
|
|
472
|
-
if (code === ext.charCodeAt(extIdx)) {
|
|
473
|
-
if (--extIdx === -1)
|
|
474
|
-
end = i;
|
|
475
|
-
} else
|
|
476
|
-
extIdx = -1, end = firstNonSlashEnd;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
if (start === end)
|
|
480
|
-
end = firstNonSlashEnd;
|
|
481
|
-
else if (end === -1)
|
|
482
|
-
end = path.length;
|
|
483
|
-
return path.slice(start, end);
|
|
484
|
-
} else {
|
|
485
|
-
for (i = path.length - 1;i >= 0; --i)
|
|
486
|
-
if (path.charCodeAt(i) === 47) {
|
|
487
|
-
if (!matchedSlash) {
|
|
488
|
-
start = i + 1;
|
|
489
|
-
break;
|
|
490
|
-
}
|
|
491
|
-
} else if (end === -1)
|
|
492
|
-
matchedSlash = false, end = i + 1;
|
|
493
|
-
if (end === -1)
|
|
494
|
-
return "";
|
|
495
|
-
return path.slice(start, end);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
function extname(path) {
|
|
499
|
-
assertPath(path);
|
|
500
|
-
var startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0;
|
|
501
|
-
for (var i = path.length - 1;i >= 0; --i) {
|
|
502
|
-
var code = path.charCodeAt(i);
|
|
503
|
-
if (code === 47) {
|
|
504
|
-
if (!matchedSlash) {
|
|
505
|
-
startPart = i + 1;
|
|
506
|
-
break;
|
|
507
|
-
}
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
if (end === -1)
|
|
511
|
-
matchedSlash = false, end = i + 1;
|
|
512
|
-
if (code === 46) {
|
|
513
|
-
if (startDot === -1)
|
|
514
|
-
startDot = i;
|
|
515
|
-
else if (preDotState !== 1)
|
|
516
|
-
preDotState = 1;
|
|
517
|
-
} else if (startDot !== -1)
|
|
518
|
-
preDotState = -1;
|
|
519
|
-
}
|
|
520
|
-
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
|
|
521
|
-
return "";
|
|
522
|
-
return path.slice(startDot, end);
|
|
523
|
-
}
|
|
524
|
-
function format(pathObject) {
|
|
525
|
-
if (pathObject === null || typeof pathObject !== "object")
|
|
526
|
-
throw new TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
|
|
527
|
-
return _format("/", pathObject);
|
|
528
|
-
}
|
|
529
|
-
function parse(path) {
|
|
530
|
-
assertPath(path);
|
|
531
|
-
var ret = { root: "", dir: "", base: "", ext: "", name: "" };
|
|
532
|
-
if (path.length === 0)
|
|
533
|
-
return ret;
|
|
534
|
-
var code = path.charCodeAt(0), isAbsolute2 = code === 47, start;
|
|
535
|
-
if (isAbsolute2)
|
|
536
|
-
ret.root = "/", start = 1;
|
|
537
|
-
else
|
|
538
|
-
start = 0;
|
|
539
|
-
var startDot = -1, startPart = 0, end = -1, matchedSlash = true, i = path.length - 1, preDotState = 0;
|
|
540
|
-
for (;i >= start; --i) {
|
|
541
|
-
if (code = path.charCodeAt(i), code === 47) {
|
|
542
|
-
if (!matchedSlash) {
|
|
543
|
-
startPart = i + 1;
|
|
544
|
-
break;
|
|
545
|
-
}
|
|
546
|
-
continue;
|
|
547
|
-
}
|
|
548
|
-
if (end === -1)
|
|
549
|
-
matchedSlash = false, end = i + 1;
|
|
550
|
-
if (code === 46) {
|
|
551
|
-
if (startDot === -1)
|
|
552
|
-
startDot = i;
|
|
553
|
-
else if (preDotState !== 1)
|
|
554
|
-
preDotState = 1;
|
|
555
|
-
} else if (startDot !== -1)
|
|
556
|
-
preDotState = -1;
|
|
557
|
-
}
|
|
558
|
-
if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|
559
|
-
if (end !== -1)
|
|
560
|
-
if (startPart === 0 && isAbsolute2)
|
|
561
|
-
ret.base = ret.name = path.slice(1, end);
|
|
562
|
-
else
|
|
563
|
-
ret.base = ret.name = path.slice(startPart, end);
|
|
564
|
-
} else {
|
|
565
|
-
if (startPart === 0 && isAbsolute2)
|
|
566
|
-
ret.name = path.slice(1, startDot), ret.base = path.slice(1, end);
|
|
567
|
-
else
|
|
568
|
-
ret.name = path.slice(startPart, startDot), ret.base = path.slice(startPart, end);
|
|
569
|
-
ret.ext = path.slice(startDot, end);
|
|
570
|
-
}
|
|
571
|
-
if (startPart > 0)
|
|
572
|
-
ret.dir = path.slice(0, startPart - 1);
|
|
573
|
-
else if (isAbsolute2)
|
|
574
|
-
ret.dir = "/";
|
|
575
|
-
return ret;
|
|
576
|
-
}
|
|
577
|
-
var sep = "/";
|
|
578
|
-
var delimiter = ":";
|
|
579
|
-
var posix = ((p) => (p.posix = p, p))({ resolve, normalize, isAbsolute, join, relative, _makeLong, dirname, basename, extname, format, parse, sep, delimiter, win32: null, posix: null });
|
|
580
|
-
|
|
581
|
-
// src/index.ts
|
|
582
|
-
var {existsSync} = (() => ({}));
|
|
583
|
-
var {writeFile, mkdir} = (() => ({}));
|
|
584
|
-
var SCAFFOLD_TEMPLATE = `import { definePrivacyPolicy } from "@openpolicy/sdk";
|
|
1
|
+
import { access, mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { compilePolicy, validatePrivacyPolicy, validateTermsOfService } from "@openpolicy/core";
|
|
4
|
+
//#region src/index.ts
|
|
5
|
+
function detectType(filename) {
|
|
6
|
+
return filename.includes("terms") ? "terms" : "privacy";
|
|
7
|
+
}
|
|
8
|
+
function normalizeEntries(options) {
|
|
9
|
+
if (options.configs) return options.configs.map((entry) => {
|
|
10
|
+
if (typeof entry === "string") return {
|
|
11
|
+
configFile: entry,
|
|
12
|
+
type: detectType(entry)
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
configFile: entry.config,
|
|
16
|
+
type: entry.type ?? detectType(entry.config)
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
const configFile = options.type === "terms" ? "terms.config.ts" : "privacy.config.ts";
|
|
20
|
+
return [{
|
|
21
|
+
configFile: options.config ?? configFile,
|
|
22
|
+
type: options.type ?? "privacy"
|
|
23
|
+
}];
|
|
24
|
+
}
|
|
25
|
+
const PRIVACY_SCAFFOLD_TEMPLATE = `import { definePrivacyPolicy } from "@openpolicy/sdk";
|
|
585
26
|
|
|
586
27
|
export default definePrivacyPolicy({
|
|
587
|
-
effectiveDate: "${new Date().toISOString().slice(0, 10)}",
|
|
28
|
+
effectiveDate: "${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}",
|
|
588
29
|
company: {
|
|
589
30
|
name: "Your Company",
|
|
590
31
|
legalName: "Your Company, Inc.",
|
|
@@ -604,64 +45,117 @@ export default definePrivacyPolicy({
|
|
|
604
45
|
jurisdictions: ["us"],
|
|
605
46
|
});
|
|
606
47
|
`;
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
48
|
+
const TERMS_SCAFFOLD_TEMPLATE = `import { defineTermsOfService } from "@openpolicy/sdk";
|
|
49
|
+
|
|
50
|
+
export default defineTermsOfService({
|
|
51
|
+
effectiveDate: "${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}",
|
|
52
|
+
company: {
|
|
53
|
+
name: "Your Company",
|
|
54
|
+
legalName: "Your Company, Inc.",
|
|
55
|
+
address: "123 Main St, City, State, ZIP",
|
|
56
|
+
contact: "legal@yourcompany.com",
|
|
57
|
+
},
|
|
58
|
+
acceptance: {
|
|
59
|
+
methods: ["using the service", "creating an account"],
|
|
60
|
+
},
|
|
61
|
+
eligibility: {
|
|
62
|
+
minimumAge: 13,
|
|
63
|
+
},
|
|
64
|
+
accounts: {
|
|
65
|
+
registrationRequired: false,
|
|
66
|
+
userResponsibleForCredentials: true,
|
|
67
|
+
companyCanTerminate: true,
|
|
68
|
+
},
|
|
69
|
+
prohibitedUses: [
|
|
70
|
+
"Violating any applicable laws or regulations",
|
|
71
|
+
"Infringing on intellectual property rights",
|
|
72
|
+
],
|
|
73
|
+
intellectualProperty: {
|
|
74
|
+
companyOwnsService: true,
|
|
75
|
+
usersMayNotCopy: true,
|
|
76
|
+
},
|
|
77
|
+
termination: {
|
|
78
|
+
companyCanTerminate: true,
|
|
79
|
+
userCanTerminate: true,
|
|
80
|
+
},
|
|
81
|
+
disclaimers: {
|
|
82
|
+
serviceProvidedAsIs: true,
|
|
83
|
+
noWarranties: true,
|
|
84
|
+
},
|
|
85
|
+
limitationOfLiability: {
|
|
86
|
+
excludesIndirectDamages: true,
|
|
87
|
+
},
|
|
88
|
+
governingLaw: {
|
|
89
|
+
jurisdiction: "Delaware, USA",
|
|
90
|
+
},
|
|
91
|
+
changesPolicy: {
|
|
92
|
+
noticeMethod: "email or prominent notice on our website",
|
|
93
|
+
noticePeriodDays: 30,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
`;
|
|
97
|
+
async function writeScaffold(configPath, type = "privacy") {
|
|
98
|
+
await writeFile(configPath, type === "terms" ? TERMS_SCAFFOLD_TEMPLATE : PRIVACY_SCAFFOLD_TEMPLATE, "utf8");
|
|
99
|
+
}
|
|
100
|
+
async function generatePolicies(configPath, outDir, formats, type = "privacy") {
|
|
101
|
+
const mod = await import(`${configPath}?t=${Date.now()}`);
|
|
102
|
+
const config = mod["default"] ?? mod["module.exports"] ?? mod;
|
|
103
|
+
if (config === null || config === void 0 || typeof config !== "object") throw new Error(`[openpolicy] Config must export a non-null object: ${configPath}`);
|
|
104
|
+
const issues = type === "terms" ? validateTermsOfService(config) : validatePrivacyPolicy(config);
|
|
105
|
+
for (const issue of issues) {
|
|
106
|
+
if (issue.level === "error") throw new Error(`[openpolicy] Validation error: ${issue.message}`);
|
|
107
|
+
console.warn(`[openpolicy] Warning: ${issue.message}`);
|
|
108
|
+
}
|
|
109
|
+
const results = compilePolicy(type === "terms" ? {
|
|
110
|
+
type: "terms",
|
|
111
|
+
...config
|
|
112
|
+
} : {
|
|
113
|
+
type: "privacy",
|
|
114
|
+
...config
|
|
115
|
+
}, { formats });
|
|
116
|
+
const outputFilename = type === "terms" ? "terms-of-service" : "privacy-policy";
|
|
117
|
+
await mkdir(outDir, { recursive: true });
|
|
118
|
+
for (const result of results) await writeFile(join(outDir, `${outputFilename}.${result.format === "markdown" ? "md" : result.format}`), result.content, "utf8");
|
|
629
119
|
}
|
|
630
120
|
function openPolicy(options = {}) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
}
|
|
121
|
+
const formats = options.formats ?? ["markdown"];
|
|
122
|
+
let resolvedOutDir;
|
|
123
|
+
let resolvedEntries;
|
|
124
|
+
return {
|
|
125
|
+
name: "openpolicy",
|
|
126
|
+
configResolved(config) {
|
|
127
|
+
resolvedOutDir = resolve(config.root, options.outDir ?? "public/policies");
|
|
128
|
+
resolvedEntries = normalizeEntries(options).map((e) => ({
|
|
129
|
+
configPath: resolve(config.root, e.configFile),
|
|
130
|
+
type: e.type
|
|
131
|
+
}));
|
|
132
|
+
},
|
|
133
|
+
async buildStart() {
|
|
134
|
+
for (const entry of resolvedEntries) {
|
|
135
|
+
if (!await access(entry.configPath).then(() => true, () => false)) {
|
|
136
|
+
await writeScaffold(entry.configPath, entry.type);
|
|
137
|
+
console.log(`[openpolicy] Scaffolded config at ${entry.configPath}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
await generatePolicies(entry.configPath, resolvedOutDir, formats, entry.type);
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
configureServer(server) {
|
|
144
|
+
for (const entry of resolvedEntries) server.watcher.add(entry.configPath);
|
|
145
|
+
server.watcher.on("change", async (path) => {
|
|
146
|
+
const entry = resolvedEntries.find((e) => e.configPath === path);
|
|
147
|
+
if (!entry) return;
|
|
148
|
+
try {
|
|
149
|
+
await generatePolicies(entry.configPath, resolvedOutDir, formats, entry.type);
|
|
150
|
+
console.log("[openpolicy] Policies regenerated");
|
|
151
|
+
} catch (err) {
|
|
152
|
+
console.error("[openpolicy]", err);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
export { generatePolicies, openPolicy, writeScaffold };
|
|
160
|
+
|
|
161
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport { join, resolve } from \"node:path\";\nimport type {\n\tOutputFormat,\n\tPrivacyPolicyConfig,\n\tTermsOfServiceConfig,\n} from \"@openpolicy/core\";\nimport {\n\tcompilePolicy,\n\tvalidatePrivacyPolicy,\n\tvalidateTermsOfService,\n} from \"@openpolicy/core\";\nimport type { Plugin } from \"vite\";\n\nexport type PolicyConfigEntry =\n\t| string\n\t| { config: string; type?: \"privacy\" | \"terms\" };\n\nexport interface OpenPolicyOptions {\n\tconfigs?: PolicyConfigEntry[];\n\tconfig?: string;\n\tformats?: OutputFormat[];\n\toutDir?: string;\n\ttype?: \"privacy\" | \"terms\";\n}\n\nfunction detectType(filename: string): \"privacy\" | \"terms\" {\n\treturn filename.includes(\"terms\") ? \"terms\" : \"privacy\";\n}\n\nfunction normalizeEntries(\n\toptions: OpenPolicyOptions,\n): Array<{ configFile: string; type: \"privacy\" | \"terms\" }> {\n\tif (options.configs) {\n\t\treturn options.configs.map((entry) => {\n\t\t\tif (typeof entry === \"string\") {\n\t\t\t\treturn { configFile: entry, type: detectType(entry) };\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tconfigFile: entry.config,\n\t\t\t\ttype: entry.type ?? detectType(entry.config),\n\t\t\t};\n\t\t});\n\t}\n\tconst configFile =\n\t\toptions.type === \"terms\" ? \"terms.config.ts\" : \"privacy.config.ts\";\n\treturn [\n\t\t{\n\t\t\tconfigFile: options.config ?? configFile,\n\t\t\ttype: options.type ?? \"privacy\",\n\t\t},\n\t];\n}\n\nconst PRIVACY_SCAFFOLD_TEMPLATE = `import { definePrivacyPolicy } from \"@openpolicy/sdk\";\n\nexport default definePrivacyPolicy({\n effectiveDate: \"${new Date().toISOString().slice(0, 10)}\",\n company: {\n name: \"Your Company\",\n legalName: \"Your Company, Inc.\",\n address: \"123 Main St, City, State, ZIP\",\n contact: \"privacy@yourcompany.com\",\n },\n dataCollected: {\n \"Personal Information\": [\"Full name\", \"Email address\"],\n },\n legalBasis: \"Legitimate interests and consent\",\n retention: {\n \"All personal data\": \"As long as necessary for the purposes described in this policy\",\n },\n cookies: { essential: true, analytics: false, marketing: false },\n thirdParties: [],\n userRights: [\"access\", \"erasure\"],\n jurisdictions: [\"us\"],\n});\n`;\n\nconst TERMS_SCAFFOLD_TEMPLATE = `import { defineTermsOfService } from \"@openpolicy/sdk\";\n\nexport default defineTermsOfService({\n effectiveDate: \"${new Date().toISOString().slice(0, 10)}\",\n company: {\n name: \"Your Company\",\n legalName: \"Your Company, Inc.\",\n address: \"123 Main St, City, State, ZIP\",\n contact: \"legal@yourcompany.com\",\n },\n acceptance: {\n methods: [\"using the service\", \"creating an account\"],\n },\n eligibility: {\n minimumAge: 13,\n },\n accounts: {\n registrationRequired: false,\n userResponsibleForCredentials: true,\n companyCanTerminate: true,\n },\n prohibitedUses: [\n \"Violating any applicable laws or regulations\",\n \"Infringing on intellectual property rights\",\n ],\n intellectualProperty: {\n companyOwnsService: true,\n usersMayNotCopy: true,\n },\n termination: {\n companyCanTerminate: true,\n userCanTerminate: true,\n },\n disclaimers: {\n serviceProvidedAsIs: true,\n noWarranties: true,\n },\n limitationOfLiability: {\n excludesIndirectDamages: true,\n },\n governingLaw: {\n jurisdiction: \"Delaware, USA\",\n },\n changesPolicy: {\n noticeMethod: \"email or prominent notice on our website\",\n noticePeriodDays: 30,\n },\n});\n`;\n\nexport async function writeScaffold(\n\tconfigPath: string,\n\ttype: \"privacy\" | \"terms\" = \"privacy\",\n): Promise<void> {\n\tconst template =\n\t\ttype === \"terms\" ? TERMS_SCAFFOLD_TEMPLATE : PRIVACY_SCAFFOLD_TEMPLATE;\n\tawait writeFile(configPath, template, \"utf8\");\n}\n\nexport async function generatePolicies(\n\tconfigPath: string,\n\toutDir: string,\n\tformats: OutputFormat[],\n\ttype: \"privacy\" | \"terms\" = \"privacy\",\n): Promise<void> {\n\tconst mod = await import(`${configPath}?t=${Date.now()}`);\n\tconst config =\n\t\t(mod as Record<string, unknown>)[\"default\"] ??\n\t\t(mod as Record<string, unknown>)[\"module.exports\"] ??\n\t\tmod;\n\n\tif (config === null || config === undefined || typeof config !== \"object\") {\n\t\tthrow new Error(\n\t\t\t`[openpolicy] Config must export a non-null object: ${configPath}`,\n\t\t);\n\t}\n\n\tconst issues =\n\t\ttype === \"terms\"\n\t\t\t? validateTermsOfService(config as TermsOfServiceConfig)\n\t\t\t: validatePrivacyPolicy(config as PrivacyPolicyConfig);\n\n\tfor (const issue of issues) {\n\t\tif (issue.level === \"error\") {\n\t\t\tthrow new Error(`[openpolicy] Validation error: ${issue.message}`);\n\t\t}\n\t\tconsole.warn(`[openpolicy] Warning: ${issue.message}`);\n\t}\n\n\tconst results = compilePolicy(\n\t\ttype === \"terms\"\n\t\t\t? { type: \"terms\", ...(config as TermsOfServiceConfig) }\n\t\t\t: { type: \"privacy\", ...(config as PrivacyPolicyConfig) },\n\t\t{ formats },\n\t);\n\n\tconst outputFilename =\n\t\ttype === \"terms\" ? \"terms-of-service\" : \"privacy-policy\";\n\n\tawait mkdir(outDir, { recursive: true });\n\n\tfor (const result of results) {\n\t\tconst ext = result.format === \"markdown\" ? \"md\" : result.format;\n\t\tawait writeFile(\n\t\t\tjoin(outDir, `${outputFilename}.${ext}`),\n\t\t\tresult.content,\n\t\t\t\"utf8\",\n\t\t);\n\t}\n}\n\nexport function openPolicy(options: OpenPolicyOptions = {}): Plugin {\n\tconst formats: OutputFormat[] = options.formats ?? [\"markdown\"];\n\tlet resolvedOutDir: string;\n\tlet resolvedEntries: Array<{ configPath: string; type: \"privacy\" | \"terms\" }>;\n\n\treturn {\n\t\tname: \"openpolicy\",\n\n\t\tconfigResolved(config) {\n\t\t\tresolvedOutDir = resolve(\n\t\t\t\tconfig.root,\n\t\t\t\toptions.outDir ?? \"public/policies\",\n\t\t\t);\n\t\t\tresolvedEntries = normalizeEntries(options).map((e) => ({\n\t\t\t\tconfigPath: resolve(config.root, e.configFile),\n\t\t\t\ttype: e.type,\n\t\t\t}));\n\t\t},\n\n\t\tasync buildStart() {\n\t\t\tfor (const entry of resolvedEntries) {\n\t\t\t\tconst configExists = await access(entry.configPath).then(\n\t\t\t\t\t() => true,\n\t\t\t\t\t() => false,\n\t\t\t\t);\n\t\t\t\tif (!configExists) {\n\t\t\t\t\tawait writeScaffold(entry.configPath, entry.type);\n\t\t\t\t\tconsole.log(`[openpolicy] Scaffolded config at ${entry.configPath}`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tawait generatePolicies(\n\t\t\t\t\tentry.configPath,\n\t\t\t\t\tresolvedOutDir,\n\t\t\t\t\tformats,\n\t\t\t\t\tentry.type,\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\tconfigureServer(server) {\n\t\t\tfor (const entry of resolvedEntries) {\n\t\t\t\tserver.watcher.add(entry.configPath);\n\t\t\t}\n\t\t\tserver.watcher.on(\"change\", async (path) => {\n\t\t\t\tconst entry = resolvedEntries.find((e) => e.configPath === path);\n\t\t\t\tif (!entry) return;\n\t\t\t\ttry {\n\t\t\t\t\tawait generatePolicies(\n\t\t\t\t\t\tentry.configPath,\n\t\t\t\t\t\tresolvedOutDir,\n\t\t\t\t\t\tformats,\n\t\t\t\t\t\tentry.type,\n\t\t\t\t\t);\n\t\t\t\t\tconsole.log(\"[openpolicy] Policies regenerated\");\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconsole.error(\"[openpolicy]\", err);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t};\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpolicy/vite",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vite plugin for compiling OpenPolicy privacy policy documents at build time",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,26 +14,24 @@
|
|
|
14
14
|
"README.md"
|
|
15
15
|
],
|
|
16
16
|
"exports": {
|
|
17
|
-
".":
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
"exports": {
|
|
21
|
-
".": {
|
|
22
|
-
"import": "./dist/index.js",
|
|
23
|
-
"types": "./dist/index.d.ts"
|
|
24
|
-
}
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts"
|
|
25
20
|
}
|
|
26
21
|
},
|
|
27
22
|
"scripts": {
|
|
28
|
-
"
|
|
23
|
+
"dev": "rolldown -c --watch",
|
|
24
|
+
"build": "rolldown -c",
|
|
29
25
|
"check-types": "tsc --noEmit",
|
|
30
26
|
"test": "bun test"
|
|
31
27
|
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@openpolicy/core": "workspace:*"
|
|
30
|
+
},
|
|
32
31
|
"peerDependencies": {
|
|
33
32
|
"vite": ">=4.0.0"
|
|
34
33
|
},
|
|
35
34
|
"devDependencies": {
|
|
36
|
-
"@openpolicy/core": "workspace:*",
|
|
37
35
|
"@openpolicy/tooling": "workspace:*",
|
|
38
36
|
"vite": "^5.0.0"
|
|
39
37
|
}
|