@ucptools/validator 1.0.0 → 1.0.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/.claude/settings.local.json +60 -0
- package/.vercel/README.txt +11 -0
- package/.vercel/project.json +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +279 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/compliance/compliance-generator.d.ts +34 -0
- package/dist/compliance/compliance-generator.d.ts.map +1 -0
- package/dist/compliance/compliance-generator.js +320 -0
- package/dist/compliance/compliance-generator.js.map +1 -0
- package/dist/compliance/index.d.ts +8 -0
- package/dist/compliance/index.d.ts.map +1 -0
- package/dist/compliance/index.js +17 -0
- package/dist/compliance/index.js.map +1 -0
- package/dist/compliance/templates.d.ts +34 -0
- package/dist/compliance/templates.d.ts.map +1 -0
- package/{src/compliance/templates.ts → dist/compliance/templates.js} +117 -155
- package/dist/compliance/templates.js.map +1 -0
- package/dist/compliance/types.d.ts +64 -0
- package/dist/compliance/types.d.ts.map +1 -0
- package/dist/compliance/types.js +64 -0
- package/dist/compliance/types.js.map +1 -0
- package/dist/db/index.d.ts +11 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +63 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +444 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +65 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts +26 -0
- package/dist/feed-analyzer/feed-analyzer.d.ts.map +1 -0
- package/{src/feed-analyzer/feed-analyzer.ts → dist/feed-analyzer/feed-analyzer.js} +642 -726
- package/dist/feed-analyzer/feed-analyzer.js.map +1 -0
- package/dist/feed-analyzer/index.d.ts +8 -0
- package/dist/feed-analyzer/index.d.ts.map +1 -0
- package/dist/feed-analyzer/index.js +19 -0
- package/dist/feed-analyzer/index.js.map +1 -0
- package/dist/feed-analyzer/types.d.ts +204 -0
- package/dist/feed-analyzer/types.d.ts.map +1 -0
- package/dist/feed-analyzer/types.js +162 -0
- package/dist/feed-analyzer/types.js.map +1 -0
- package/{src/generator/index.ts → dist/generator/index.d.ts} +1 -1
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +13 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/key-generator.d.ts +24 -0
- package/dist/generator/key-generator.d.ts.map +1 -0
- package/dist/generator/key-generator.js +144 -0
- package/dist/generator/key-generator.js.map +1 -0
- package/dist/generator/profile-builder.d.ts +15 -0
- package/dist/generator/profile-builder.d.ts.map +1 -0
- package/dist/generator/profile-builder.js +338 -0
- package/dist/generator/profile-builder.js.map +1 -0
- package/dist/hosting/artifacts-generator.d.ts +10 -0
- package/dist/hosting/artifacts-generator.d.ts.map +1 -0
- package/{src/hosting/artifacts-generator.ts → dist/hosting/artifacts-generator.js} +191 -241
- package/dist/hosting/artifacts-generator.js.map +1 -0
- package/{src/hosting/index.ts → dist/hosting/index.d.ts} +1 -1
- package/dist/hosting/index.d.ts.map +1 -0
- package/dist/hosting/index.js +10 -0
- package/dist/hosting/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +78 -0
- package/dist/index.js.map +1 -0
- package/{src/security/index.ts → dist/security/index.d.ts} +8 -15
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +12 -0
- package/dist/security/index.js.map +1 -0
- package/dist/security/security-scanner.d.ts +10 -0
- package/dist/security/security-scanner.d.ts.map +1 -0
- package/dist/security/security-scanner.js +541 -0
- package/dist/security/security-scanner.js.map +1 -0
- package/dist/security/types.d.ts +48 -0
- package/dist/security/types.d.ts.map +1 -0
- package/dist/security/types.js +21 -0
- package/dist/security/types.js.map +1 -0
- package/dist/services/directory.d.ts +104 -0
- package/dist/services/directory.d.ts.map +1 -0
- package/dist/services/directory.js +333 -0
- package/dist/services/directory.js.map +1 -0
- package/dist/simulator/agent-simulator.d.ts +69 -0
- package/dist/simulator/agent-simulator.d.ts.map +1 -0
- package/{src/simulator/agent-simulator.ts → dist/simulator/agent-simulator.js} +650 -941
- package/dist/simulator/agent-simulator.js.map +1 -0
- package/{src/simulator/index.ts → dist/simulator/index.d.ts} +7 -7
- package/dist/simulator/index.d.ts.map +1 -0
- package/dist/simulator/index.js +23 -0
- package/dist/simulator/index.js.map +1 -0
- package/{src/simulator/types.ts → dist/simulator/types.d.ts} +145 -170
- package/dist/simulator/types.d.ts.map +1 -0
- package/dist/simulator/types.js +18 -0
- package/dist/simulator/types.js.map +1 -0
- package/dist/types/generator.d.ts +106 -0
- package/dist/types/generator.d.ts.map +1 -0
- package/dist/types/generator.js +6 -0
- package/dist/types/generator.js.map +1 -0
- package/{src/types/index.ts → dist/types/index.d.ts} +1 -1
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +23 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/ucp-profile.d.ts +103 -0
- package/dist/types/ucp-profile.d.ts.map +1 -0
- package/dist/types/ucp-profile.js +45 -0
- package/dist/types/ucp-profile.js.map +1 -0
- package/dist/types/validation.d.ts +68 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +32 -0
- package/dist/types/validation.js.map +1 -0
- package/dist/validator/index.d.ts +26 -0
- package/dist/validator/index.d.ts.map +1 -0
- package/dist/validator/index.js +161 -0
- package/dist/validator/index.js.map +1 -0
- package/dist/validator/network-validator.d.ts +28 -0
- package/dist/validator/network-validator.d.ts.map +1 -0
- package/dist/validator/network-validator.js +319 -0
- package/dist/validator/network-validator.js.map +1 -0
- package/dist/validator/rules-validator.d.ts +11 -0
- package/dist/validator/rules-validator.d.ts.map +1 -0
- package/dist/validator/rules-validator.js +257 -0
- package/dist/validator/rules-validator.js.map +1 -0
- package/dist/validator/sdk-validator.d.ts +58 -0
- package/dist/validator/sdk-validator.d.ts.map +1 -0
- package/{src/validator/sdk-validator.ts → dist/validator/sdk-validator.js} +273 -330
- package/dist/validator/sdk-validator.js.map +1 -0
- package/dist/validator/structural-validator.d.ts +11 -0
- package/dist/validator/structural-validator.d.ts.map +1 -0
- package/dist/validator/structural-validator.js +415 -0
- package/dist/validator/structural-validator.js.map +1 -0
- package/package.json +1 -1
- package/publish-output.txt +0 -0
- package/CLAUDE.md +0 -109
- package/api/analyze-feed.js +0 -140
- package/api/badge.js +0 -185
- package/api/benchmark.js +0 -177
- package/api/directory-stats.ts +0 -29
- package/api/directory.ts +0 -73
- package/api/generate-compliance.js +0 -143
- package/api/generate-schema.js +0 -457
- package/api/generate.js +0 -132
- package/api/security-scan.js +0 -133
- package/api/simulate.js +0 -187
- package/api/tsconfig.json +0 -10
- package/api/validate.js +0 -1351
- package/apify-actor/.actor/actor.json +0 -68
- package/apify-actor/.actor/input_schema.json +0 -32
- package/apify-actor/APIFY-STORE-LISTING.md +0 -412
- package/apify-actor/Dockerfile +0 -8
- package/apify-actor/README.md +0 -166
- package/apify-actor/main.ts +0 -111
- package/apify-actor/package.json +0 -17
- package/apify-actor/src/main.js +0 -199
- package/docs/BRAND-IDENTITY.md +0 -238
- package/docs/BRAND-STYLE-GUIDE.md +0 -356
- package/drizzle/0000_black_king_cobra.sql +0 -39
- package/drizzle/meta/0000_snapshot.json +0 -309
- package/drizzle/meta/_journal.json +0 -13
- package/drizzle.config.ts +0 -10
- package/public/.well-known/ucp +0 -25
- package/public/android-chrome-192x192.png +0 -0
- package/public/android-chrome-512x512.png +0 -0
- package/public/apple-touch-icon.png +0 -0
- package/public/brand.css +0 -321
- package/public/directory.html +0 -701
- package/public/favicon-16x16.png +0 -0
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/guides/bigcommerce.html +0 -743
- package/public/guides/fastucp.html +0 -838
- package/public/guides/magento.html +0 -779
- package/public/guides/shopify.html +0 -726
- package/public/guides/squarespace.html +0 -749
- package/public/guides/wix.html +0 -747
- package/public/guides/woocommerce.html +0 -733
- package/public/index.html +0 -3835
- package/public/learn.html +0 -396
- package/public/logo.jpeg +0 -0
- package/public/og-image-icon.png +0 -0
- package/public/og-image.png +0 -0
- package/public/robots.txt +0 -6
- package/public/site.webmanifest +0 -31
- package/public/sitemap.xml +0 -69
- package/public/social/linkedin-banner-1128x191.png +0 -0
- package/public/social/temp.PNG +0 -0
- package/public/social/x-header-1500x500.png +0 -0
- package/public/verify.html +0 -410
- package/scripts/generate-favicons.js +0 -44
- package/scripts/generate-ico.js +0 -23
- package/scripts/generate-og-image.js +0 -45
- package/scripts/reset-db.ts +0 -77
- package/scripts/seed-db.ts +0 -71
- package/scripts/setup-benchmark-db.js +0 -70
- package/src/api/server.ts +0 -266
- package/src/cli/index.ts +0 -302
- package/src/compliance/compliance-generator.ts +0 -452
- package/src/compliance/index.ts +0 -28
- package/src/compliance/types.ts +0 -170
- package/src/db/index.ts +0 -28
- package/src/db/schema.ts +0 -84
- package/src/feed-analyzer/index.ts +0 -34
- package/src/feed-analyzer/types.ts +0 -354
- package/src/generator/key-generator.ts +0 -124
- package/src/generator/profile-builder.ts +0 -402
- package/src/index.ts +0 -105
- package/src/security/security-scanner.ts +0 -604
- package/src/security/types.ts +0 -55
- package/src/services/directory.ts +0 -434
- package/src/types/generator.ts +0 -140
- package/src/types/ucp-profile.ts +0 -140
- package/src/types/validation.ts +0 -89
- package/src/validator/index.ts +0 -194
- package/src/validator/network-validator.ts +0 -417
- package/src/validator/rules-validator.ts +0 -297
- package/src/validator/structural-validator.ts +0 -476
- package/tests/fixtures/non-compliant-profile.json +0 -25
- package/tests/fixtures/official-sample-profile.json +0 -75
- package/tests/integration/benchmark.test.ts +0 -207
- package/tests/integration/database.test.ts +0 -163
- package/tests/integration/directory-api.test.ts +0 -268
- package/tests/integration/simulate-api.test.ts +0 -230
- package/tests/integration/validate-api.test.ts +0 -269
- package/tests/setup.ts +0 -15
- package/tests/unit/agent-simulator.test.ts +0 -575
- package/tests/unit/compliance-generator.test.ts +0 -374
- package/tests/unit/directory-service.test.ts +0 -272
- package/tests/unit/feed-analyzer.test.ts +0 -517
- package/tests/unit/lint-suggestions.test.ts +0 -423
- package/tests/unit/official-samples.test.ts +0 -211
- package/tests/unit/pdf-report.test.ts +0 -390
- package/tests/unit/sdk-validator.test.ts +0 -531
- package/tests/unit/security-scanner.test.ts +0 -410
- package/tests/unit/validation.test.ts +0 -390
- package/vercel.json +0 -34
- package/vitest.config.ts +0 -22
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GDPR/Privacy Compliance Generator
|
|
3
|
-
* Generates privacy policy addendums and consent language for agentic commerce
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
ComplianceGeneratorInput,
|
|
8
|
-
ComplianceGeneratorOutput,
|
|
9
|
-
ComplianceDocument,
|
|
10
|
-
ComplianceSection,
|
|
11
|
-
DataProcessor,
|
|
12
|
-
ComplianceRegion,
|
|
13
|
-
} from './types.js';
|
|
14
|
-
import {
|
|
15
|
-
AI_PLATFORM_PROCESSORS,
|
|
16
|
-
REGION_NAMES,
|
|
17
|
-
LAWFUL_BASIS_DESCRIPTIONS,
|
|
18
|
-
} from './types.js';
|
|
19
|
-
import {
|
|
20
|
-
generateAiCommerceSection,
|
|
21
|
-
generateProcessorDisclosures,
|
|
22
|
-
generateConsentLanguage,
|
|
23
|
-
generateMarketingOptIn,
|
|
24
|
-
generateDataSubjectRights,
|
|
25
|
-
generateTrackingNotice,
|
|
26
|
-
generateDisclaimer,
|
|
27
|
-
} from './templates.js';
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Generate complete compliance documentation
|
|
31
|
-
*/
|
|
32
|
-
export function generateComplianceDocuments(
|
|
33
|
-
input: ComplianceGeneratorInput
|
|
34
|
-
): ComplianceGeneratorOutput {
|
|
35
|
-
// Validate input
|
|
36
|
-
validateInput(input);
|
|
37
|
-
|
|
38
|
-
// Build list of data processors
|
|
39
|
-
const processors = buildProcessorList(input);
|
|
40
|
-
|
|
41
|
-
// Generate all sections
|
|
42
|
-
const aiCommerceSection = generateAiCommerceSection(
|
|
43
|
-
input.companyName,
|
|
44
|
-
processors,
|
|
45
|
-
input.lawfulBasis,
|
|
46
|
-
input.regions
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const processorDisclosures = generateProcessorDisclosures(
|
|
50
|
-
processors,
|
|
51
|
-
input.regions
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const consentLanguage = generateConsentLanguage(
|
|
55
|
-
input.companyName,
|
|
56
|
-
input.lawfulBasis,
|
|
57
|
-
input.includeMarketingConsent || false
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
const marketingOptIn = input.includeMarketingConsent
|
|
61
|
-
? generateMarketingOptIn(input.companyName)
|
|
62
|
-
: undefined;
|
|
63
|
-
|
|
64
|
-
const dataSubjectRights = generateDataSubjectRights(
|
|
65
|
-
input.companyName,
|
|
66
|
-
input.companyEmail || 'privacy@yourcompany.com',
|
|
67
|
-
input.dpoEmail,
|
|
68
|
-
input.regions
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const trackingNotice = generateTrackingNotice(
|
|
72
|
-
input.companyName,
|
|
73
|
-
input.regions
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
const disclaimer = generateDisclaimer();
|
|
77
|
-
|
|
78
|
-
// Build the full privacy addendum document
|
|
79
|
-
const privacyAddendum = buildPrivacyAddendum(
|
|
80
|
-
input,
|
|
81
|
-
aiCommerceSection,
|
|
82
|
-
processorDisclosures,
|
|
83
|
-
dataSubjectRights,
|
|
84
|
-
trackingNotice,
|
|
85
|
-
disclaimer
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
// Generate embed HTML
|
|
89
|
-
const embedHtml = generateEmbedHtml(
|
|
90
|
-
input.companyName,
|
|
91
|
-
aiCommerceSection,
|
|
92
|
-
processorDisclosures,
|
|
93
|
-
dataSubjectRights,
|
|
94
|
-
trackingNotice,
|
|
95
|
-
disclaimer
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
// Generate plain text
|
|
99
|
-
const plainText = generatePlainText(
|
|
100
|
-
input.companyName,
|
|
101
|
-
aiCommerceSection,
|
|
102
|
-
processorDisclosures,
|
|
103
|
-
consentLanguage,
|
|
104
|
-
marketingOptIn,
|
|
105
|
-
dataSubjectRights,
|
|
106
|
-
trackingNotice,
|
|
107
|
-
disclaimer
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
privacyAddendum,
|
|
112
|
-
snippets: {
|
|
113
|
-
aiCommerceSection,
|
|
114
|
-
processorDisclosures,
|
|
115
|
-
consentLanguage,
|
|
116
|
-
marketingOptIn,
|
|
117
|
-
dataSubjectRights,
|
|
118
|
-
trackingNotice,
|
|
119
|
-
},
|
|
120
|
-
embedHtml,
|
|
121
|
-
plainText,
|
|
122
|
-
generatedAt: new Date().toISOString(),
|
|
123
|
-
lawfulBasis: input.lawfulBasis,
|
|
124
|
-
regions: input.regions,
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Validate generator input
|
|
130
|
-
*/
|
|
131
|
-
function validateInput(input: ComplianceGeneratorInput): void {
|
|
132
|
-
if (!input.companyName || input.companyName.trim() === '') {
|
|
133
|
-
throw new Error('Company name is required');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (!input.regions || input.regions.length === 0) {
|
|
137
|
-
throw new Error('At least one region must be selected');
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (!input.platforms || input.platforms.length === 0) {
|
|
141
|
-
throw new Error('At least one AI platform must be selected');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (!input.lawfulBasis) {
|
|
145
|
-
throw new Error('Lawful basis must be specified');
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Build the list of data processors from input
|
|
151
|
-
*/
|
|
152
|
-
function buildProcessorList(input: ComplianceGeneratorInput): DataProcessor[] {
|
|
153
|
-
const processors: DataProcessor[] = [];
|
|
154
|
-
|
|
155
|
-
// Add AI platform processors
|
|
156
|
-
for (const platform of input.platforms) {
|
|
157
|
-
if (platform !== 'other') {
|
|
158
|
-
processors.push(AI_PLATFORM_PROCESSORS[platform]);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Add custom processors
|
|
163
|
-
if (input.additionalProcessors) {
|
|
164
|
-
processors.push(...input.additionalProcessors);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return processors;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Build the full privacy addendum document
|
|
172
|
-
*/
|
|
173
|
-
function buildPrivacyAddendum(
|
|
174
|
-
input: ComplianceGeneratorInput,
|
|
175
|
-
aiCommerceSection: string,
|
|
176
|
-
processorDisclosures: string,
|
|
177
|
-
dataSubjectRights: string,
|
|
178
|
-
trackingNotice: string,
|
|
179
|
-
disclaimer: string
|
|
180
|
-
): ComplianceDocument {
|
|
181
|
-
const sections: ComplianceSection[] = [
|
|
182
|
-
{
|
|
183
|
-
id: 'ai-commerce',
|
|
184
|
-
title: 'AI-Powered Shopping and Agentic Commerce',
|
|
185
|
-
content: aiCommerceSection,
|
|
186
|
-
required: true,
|
|
187
|
-
applicableRegions: ['eu', 'uk', 'california', 'global'],
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
id: 'processors',
|
|
191
|
-
title: 'Third-Party Data Processors',
|
|
192
|
-
content: processorDisclosures,
|
|
193
|
-
required: true,
|
|
194
|
-
applicableRegions: ['eu', 'uk', 'california', 'global'],
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
id: 'rights',
|
|
198
|
-
title: 'Your Data Rights',
|
|
199
|
-
content: dataSubjectRights,
|
|
200
|
-
required: true,
|
|
201
|
-
applicableRegions: ['eu', 'uk', 'california', 'global'],
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
id: 'tracking',
|
|
205
|
-
title: 'Tracking and Cookies',
|
|
206
|
-
content: trackingNotice,
|
|
207
|
-
required: false,
|
|
208
|
-
applicableRegions: ['eu', 'uk', 'global'],
|
|
209
|
-
},
|
|
210
|
-
];
|
|
211
|
-
|
|
212
|
-
// Add data retention section if requested
|
|
213
|
-
if (input.includeDataRetention) {
|
|
214
|
-
const retentionYears = input.retentionPeriodYears || 7;
|
|
215
|
-
sections.push({
|
|
216
|
-
id: 'retention',
|
|
217
|
-
title: 'Data Retention',
|
|
218
|
-
content: generateDataRetentionSection(input.companyName, retentionYears, input.regions),
|
|
219
|
-
required: false,
|
|
220
|
-
applicableRegions: ['eu', 'uk', 'california', 'global'],
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return {
|
|
225
|
-
title: `Privacy Policy Addendum: AI Commerce - ${input.companyName}`,
|
|
226
|
-
sections,
|
|
227
|
-
disclaimer,
|
|
228
|
-
generatedAt: new Date().toISOString(),
|
|
229
|
-
regions: input.regions,
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Generate data retention section
|
|
235
|
-
*/
|
|
236
|
-
function generateDataRetentionSection(
|
|
237
|
-
companyName: string,
|
|
238
|
-
retentionYears: number,
|
|
239
|
-
regions: ComplianceRegion[]
|
|
240
|
-
): string {
|
|
241
|
-
let section = `## Data Retention for AI Commerce Transactions
|
|
242
|
-
|
|
243
|
-
${companyName} retains personal data from AI agent transactions for the following periods:
|
|
244
|
-
|
|
245
|
-
| Data Category | Retention Period | Purpose |
|
|
246
|
-
|--------------|------------------|---------|
|
|
247
|
-
| Order Information | ${retentionYears} years | Legal/tax compliance, warranty claims |
|
|
248
|
-
| Transaction Records | ${retentionYears} years | Financial records, dispute resolution |
|
|
249
|
-
| Delivery Information | 2 years | Customer service, delivery issues |
|
|
250
|
-
| Communication Records | 3 years | Customer support, quality assurance |
|
|
251
|
-
| Payment Confirmations | ${retentionYears} years | Financial audit requirements |
|
|
252
|
-
|
|
253
|
-
### Retention Principles
|
|
254
|
-
|
|
255
|
-
- Data is retained only as long as necessary for the stated purposes
|
|
256
|
-
- We regularly review and delete data that is no longer needed
|
|
257
|
-
- You may request earlier deletion, subject to legal retention requirements
|
|
258
|
-
`;
|
|
259
|
-
|
|
260
|
-
if (regions.includes('eu') || regions.includes('uk')) {
|
|
261
|
-
section += `
|
|
262
|
-
### GDPR Storage Limitation
|
|
263
|
-
|
|
264
|
-
In accordance with Article 5(1)(e) of the GDPR, we do not keep personal data for longer than necessary. Retention periods are based on:
|
|
265
|
-
- Contractual obligations
|
|
266
|
-
- Legal requirements (tax, accounting)
|
|
267
|
-
- Legitimate business needs
|
|
268
|
-
- Applicable limitation periods for legal claims
|
|
269
|
-
`;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return section;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Generate embeddable HTML
|
|
277
|
-
*/
|
|
278
|
-
function generateEmbedHtml(
|
|
279
|
-
companyName: string,
|
|
280
|
-
aiCommerceSection: string,
|
|
281
|
-
processorDisclosures: string,
|
|
282
|
-
dataSubjectRights: string,
|
|
283
|
-
trackingNotice: string,
|
|
284
|
-
disclaimer: string
|
|
285
|
-
): string {
|
|
286
|
-
// Convert markdown to simple HTML
|
|
287
|
-
const convertMarkdown = (md: string): string => {
|
|
288
|
-
return md
|
|
289
|
-
// Headers
|
|
290
|
-
.replace(/^### (.+)$/gm, '<h4>$1</h4>')
|
|
291
|
-
.replace(/^## (.+)$/gm, '<h3>$1</h3>')
|
|
292
|
-
.replace(/^# (.+)$/gm, '<h2>$1</h2>')
|
|
293
|
-
// Bold
|
|
294
|
-
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
|
295
|
-
// Lists
|
|
296
|
-
.replace(/^- (.+)$/gm, '<li>$1</li>')
|
|
297
|
-
// Blockquotes
|
|
298
|
-
.replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>')
|
|
299
|
-
// Paragraphs
|
|
300
|
-
.replace(/\n\n/g, '</p><p>')
|
|
301
|
-
// Tables (basic)
|
|
302
|
-
.replace(/\|(.+)\|/g, (match) => {
|
|
303
|
-
const cells = match.split('|').filter(c => c.trim());
|
|
304
|
-
return '<tr>' + cells.map(c => `<td>${c.trim()}</td>`).join('') + '</tr>';
|
|
305
|
-
})
|
|
306
|
-
// Links
|
|
307
|
-
.replace(/\[(.+?)\]\((.+?)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
return `<!-- AI Commerce Privacy Policy Addendum - Generated by UCP.tools -->
|
|
311
|
-
<div class="ucp-privacy-addendum">
|
|
312
|
-
<style>
|
|
313
|
-
.ucp-privacy-addendum {
|
|
314
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
315
|
-
line-height: 1.6;
|
|
316
|
-
color: #333;
|
|
317
|
-
max-width: 800px;
|
|
318
|
-
}
|
|
319
|
-
.ucp-privacy-addendum h2 { font-size: 1.5em; margin-top: 2em; border-bottom: 2px solid #2E86AB; padding-bottom: 0.5em; }
|
|
320
|
-
.ucp-privacy-addendum h3 { font-size: 1.2em; margin-top: 1.5em; color: #2E86AB; }
|
|
321
|
-
.ucp-privacy-addendum h4 { font-size: 1em; margin-top: 1em; }
|
|
322
|
-
.ucp-privacy-addendum table { width: 100%; border-collapse: collapse; margin: 1em 0; }
|
|
323
|
-
.ucp-privacy-addendum th, .ucp-privacy-addendum td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
324
|
-
.ucp-privacy-addendum th { background: #f5f5f5; }
|
|
325
|
-
.ucp-privacy-addendum blockquote { border-left: 4px solid #2E86AB; margin: 1em 0; padding: 0.5em 1em; background: #f9f9f9; }
|
|
326
|
-
.ucp-privacy-addendum .disclaimer { margin-top: 2em; padding: 1em; background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; font-size: 0.9em; }
|
|
327
|
-
</style>
|
|
328
|
-
|
|
329
|
-
<h2>Privacy Policy Addendum: AI Commerce</h2>
|
|
330
|
-
<p><em>Effective Date: ${new Date().toLocaleDateString()}</em></p>
|
|
331
|
-
<p>This addendum describes how ${companyName} handles personal data when you make purchases through AI shopping agents.</p>
|
|
332
|
-
|
|
333
|
-
<div class="section">
|
|
334
|
-
${convertMarkdown(aiCommerceSection)}
|
|
335
|
-
</div>
|
|
336
|
-
|
|
337
|
-
<div class="section">
|
|
338
|
-
${convertMarkdown(processorDisclosures)}
|
|
339
|
-
</div>
|
|
340
|
-
|
|
341
|
-
<div class="section">
|
|
342
|
-
${convertMarkdown(dataSubjectRights)}
|
|
343
|
-
</div>
|
|
344
|
-
|
|
345
|
-
<div class="section">
|
|
346
|
-
${convertMarkdown(trackingNotice)}
|
|
347
|
-
</div>
|
|
348
|
-
|
|
349
|
-
<div class="disclaimer">
|
|
350
|
-
${convertMarkdown(disclaimer)}
|
|
351
|
-
</div>
|
|
352
|
-
</div>
|
|
353
|
-
<!-- End AI Commerce Privacy Policy Addendum -->`;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Generate plain text version
|
|
358
|
-
*/
|
|
359
|
-
function generatePlainText(
|
|
360
|
-
companyName: string,
|
|
361
|
-
aiCommerceSection: string,
|
|
362
|
-
processorDisclosures: string,
|
|
363
|
-
consentLanguage: string,
|
|
364
|
-
marketingOptIn: string | undefined,
|
|
365
|
-
dataSubjectRights: string,
|
|
366
|
-
trackingNotice: string,
|
|
367
|
-
disclaimer: string
|
|
368
|
-
): string {
|
|
369
|
-
const divider = '='.repeat(60);
|
|
370
|
-
|
|
371
|
-
let text = `${divider}
|
|
372
|
-
PRIVACY POLICY ADDENDUM: AI COMMERCE
|
|
373
|
-
${companyName}
|
|
374
|
-
Generated: ${new Date().toISOString()}
|
|
375
|
-
${divider}
|
|
376
|
-
|
|
377
|
-
${aiCommerceSection}
|
|
378
|
-
|
|
379
|
-
${divider}
|
|
380
|
-
|
|
381
|
-
${processorDisclosures}
|
|
382
|
-
|
|
383
|
-
${divider}
|
|
384
|
-
|
|
385
|
-
${consentLanguage}
|
|
386
|
-
`;
|
|
387
|
-
|
|
388
|
-
if (marketingOptIn) {
|
|
389
|
-
text += `
|
|
390
|
-
${divider}
|
|
391
|
-
|
|
392
|
-
${marketingOptIn}
|
|
393
|
-
`;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
text += `
|
|
397
|
-
${divider}
|
|
398
|
-
|
|
399
|
-
${dataSubjectRights}
|
|
400
|
-
|
|
401
|
-
${divider}
|
|
402
|
-
|
|
403
|
-
${trackingNotice}
|
|
404
|
-
|
|
405
|
-
${divider}
|
|
406
|
-
|
|
407
|
-
${disclaimer}
|
|
408
|
-
`;
|
|
409
|
-
|
|
410
|
-
return text;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Get available regions with descriptions
|
|
415
|
-
*/
|
|
416
|
-
export function getAvailableRegions(): Array<{ id: ComplianceRegion; name: string }> {
|
|
417
|
-
return Object.entries(REGION_NAMES).map(([id, name]) => ({
|
|
418
|
-
id: id as ComplianceRegion,
|
|
419
|
-
name,
|
|
420
|
-
}));
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Get lawful basis options with descriptions
|
|
425
|
-
*/
|
|
426
|
-
export function getLawfulBasisOptions(): Array<{
|
|
427
|
-
id: string;
|
|
428
|
-
title: string;
|
|
429
|
-
description: string;
|
|
430
|
-
gdprArticle: string;
|
|
431
|
-
}> {
|
|
432
|
-
return Object.entries(LAWFUL_BASIS_DESCRIPTIONS).map(([id, info]) => ({
|
|
433
|
-
id,
|
|
434
|
-
...info,
|
|
435
|
-
}));
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* Get AI platform options
|
|
440
|
-
*/
|
|
441
|
-
export function getAiPlatformOptions(): Array<{
|
|
442
|
-
id: string;
|
|
443
|
-
name: string;
|
|
444
|
-
description: string;
|
|
445
|
-
}> {
|
|
446
|
-
return [
|
|
447
|
-
{ id: 'openai', name: 'OpenAI (ChatGPT Shopping)', description: 'ChatGPT-powered shopping assistant' },
|
|
448
|
-
{ id: 'google', name: 'Google (AI Mode / Gemini)', description: 'Google AI shopping agent' },
|
|
449
|
-
{ id: 'microsoft', name: 'Microsoft (Copilot)', description: 'Microsoft Copilot checkout' },
|
|
450
|
-
{ id: 'other', name: 'Other AI Platforms', description: 'Other AI shopping agents' },
|
|
451
|
-
];
|
|
452
|
-
}
|
package/src/compliance/index.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GDPR/Privacy Compliance Generator Module
|
|
3
|
-
* Generates privacy policy addendums and consent language for agentic commerce
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
generateComplianceDocuments,
|
|
8
|
-
getAvailableRegions,
|
|
9
|
-
getLawfulBasisOptions,
|
|
10
|
-
getAiPlatformOptions,
|
|
11
|
-
} from './compliance-generator.js';
|
|
12
|
-
|
|
13
|
-
export type {
|
|
14
|
-
ComplianceRegion,
|
|
15
|
-
LawfulBasis,
|
|
16
|
-
AgentPlatform,
|
|
17
|
-
ComplianceGeneratorInput,
|
|
18
|
-
ComplianceGeneratorOutput,
|
|
19
|
-
ComplianceDocument,
|
|
20
|
-
ComplianceSection,
|
|
21
|
-
DataProcessor,
|
|
22
|
-
} from './types.js';
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
AI_PLATFORM_PROCESSORS,
|
|
26
|
-
REGION_NAMES,
|
|
27
|
-
LAWFUL_BASIS_DESCRIPTIONS,
|
|
28
|
-
} from './types.js';
|
package/src/compliance/types.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GDPR/Privacy Compliance Generator Types
|
|
3
|
-
* Types for generating privacy policy addendums and consent language
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Supported regions/jurisdictions
|
|
7
|
-
export type ComplianceRegion = 'eu' | 'uk' | 'california' | 'global';
|
|
8
|
-
|
|
9
|
-
// GDPR Article 6 lawful bases
|
|
10
|
-
export type LawfulBasis =
|
|
11
|
-
| 'contract' // Performance of a contract
|
|
12
|
-
| 'consent' // Consent
|
|
13
|
-
| 'legitimate' // Legitimate interests
|
|
14
|
-
| 'legal'; // Legal obligation
|
|
15
|
-
|
|
16
|
-
// AI agent platforms
|
|
17
|
-
export type AgentPlatform =
|
|
18
|
-
| 'openai' // ChatGPT Shopping
|
|
19
|
-
| 'google' // Google AI Mode / Gemini
|
|
20
|
-
| 'microsoft' // Microsoft Copilot
|
|
21
|
-
| 'other';
|
|
22
|
-
|
|
23
|
-
// Input options for compliance generator
|
|
24
|
-
export interface ComplianceGeneratorInput {
|
|
25
|
-
// Company information
|
|
26
|
-
companyName: string;
|
|
27
|
-
companyEmail?: string;
|
|
28
|
-
companyAddress?: string;
|
|
29
|
-
dpoEmail?: string; // Data Protection Officer email
|
|
30
|
-
|
|
31
|
-
// Regions to comply with
|
|
32
|
-
regions: ComplianceRegion[];
|
|
33
|
-
|
|
34
|
-
// AI platforms being used
|
|
35
|
-
platforms: AgentPlatform[];
|
|
36
|
-
|
|
37
|
-
// Lawful basis for processing
|
|
38
|
-
lawfulBasis: LawfulBasis;
|
|
39
|
-
|
|
40
|
-
// Optional features
|
|
41
|
-
includeMarketingConsent?: boolean;
|
|
42
|
-
includeDataRetention?: boolean;
|
|
43
|
-
retentionPeriodYears?: number;
|
|
44
|
-
|
|
45
|
-
// Custom data processors
|
|
46
|
-
additionalProcessors?: DataProcessor[];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Data processor information
|
|
50
|
-
export interface DataProcessor {
|
|
51
|
-
name: string;
|
|
52
|
-
purpose: string;
|
|
53
|
-
country?: string;
|
|
54
|
-
privacyPolicyUrl?: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Generated compliance document
|
|
58
|
-
export interface ComplianceDocument {
|
|
59
|
-
title: string;
|
|
60
|
-
sections: ComplianceSection[];
|
|
61
|
-
disclaimer: string;
|
|
62
|
-
generatedAt: string;
|
|
63
|
-
regions: ComplianceRegion[];
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Section of a compliance document
|
|
67
|
-
export interface ComplianceSection {
|
|
68
|
-
id: string;
|
|
69
|
-
title: string;
|
|
70
|
-
content: string;
|
|
71
|
-
required: boolean;
|
|
72
|
-
applicableRegions: ComplianceRegion[];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Complete generator output
|
|
76
|
-
export interface ComplianceGeneratorOutput {
|
|
77
|
-
// Full privacy policy addendum
|
|
78
|
-
privacyAddendum: ComplianceDocument;
|
|
79
|
-
|
|
80
|
-
// Individual snippets for easy copy/paste
|
|
81
|
-
snippets: {
|
|
82
|
-
// Privacy policy section for AI commerce
|
|
83
|
-
aiCommerceSection: string;
|
|
84
|
-
|
|
85
|
-
// Data processor disclosures
|
|
86
|
-
processorDisclosures: string;
|
|
87
|
-
|
|
88
|
-
// Consent language for checkout
|
|
89
|
-
consentLanguage: string;
|
|
90
|
-
|
|
91
|
-
// Marketing opt-in text
|
|
92
|
-
marketingOptIn?: string;
|
|
93
|
-
|
|
94
|
-
// Data subject rights notice
|
|
95
|
-
dataSubjectRights: string;
|
|
96
|
-
|
|
97
|
-
// Cookie/tracking notice for agent transactions
|
|
98
|
-
trackingNotice: string;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
// Combined HTML for embedding
|
|
102
|
-
embedHtml: string;
|
|
103
|
-
|
|
104
|
-
// Plain text version
|
|
105
|
-
plainText: string;
|
|
106
|
-
|
|
107
|
-
// Metadata
|
|
108
|
-
generatedAt: string;
|
|
109
|
-
lawfulBasis: LawfulBasis;
|
|
110
|
-
regions: ComplianceRegion[];
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Predefined data processors for AI platforms
|
|
114
|
-
export const AI_PLATFORM_PROCESSORS: Record<AgentPlatform, DataProcessor> = {
|
|
115
|
-
openai: {
|
|
116
|
-
name: 'OpenAI, LLC',
|
|
117
|
-
purpose: 'AI-powered shopping assistant and checkout processing',
|
|
118
|
-
country: 'United States',
|
|
119
|
-
privacyPolicyUrl: 'https://openai.com/privacy/',
|
|
120
|
-
},
|
|
121
|
-
google: {
|
|
122
|
-
name: 'Google LLC',
|
|
123
|
-
purpose: 'AI shopping agent (Google AI Mode, Gemini) and checkout processing',
|
|
124
|
-
country: 'United States',
|
|
125
|
-
privacyPolicyUrl: 'https://policies.google.com/privacy',
|
|
126
|
-
},
|
|
127
|
-
microsoft: {
|
|
128
|
-
name: 'Microsoft Corporation',
|
|
129
|
-
purpose: 'AI shopping assistant (Copilot) and checkout processing',
|
|
130
|
-
country: 'United States',
|
|
131
|
-
privacyPolicyUrl: 'https://privacy.microsoft.com/privacystatement',
|
|
132
|
-
},
|
|
133
|
-
other: {
|
|
134
|
-
name: 'Third-party AI Agent Provider',
|
|
135
|
-
purpose: 'AI-powered shopping and checkout assistance',
|
|
136
|
-
country: 'Various',
|
|
137
|
-
},
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
// Region display names
|
|
141
|
-
export const REGION_NAMES: Record<ComplianceRegion, string> = {
|
|
142
|
-
eu: 'European Union (GDPR)',
|
|
143
|
-
uk: 'United Kingdom (UK GDPR)',
|
|
144
|
-
california: 'California (CCPA/CPRA)',
|
|
145
|
-
global: 'Global (General Best Practices)',
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// Lawful basis descriptions
|
|
149
|
-
export const LAWFUL_BASIS_DESCRIPTIONS: Record<LawfulBasis, { title: string; description: string; gdprArticle: string }> = {
|
|
150
|
-
contract: {
|
|
151
|
-
title: 'Performance of a Contract',
|
|
152
|
-
description: 'Processing is necessary for the performance of a contract with the data subject or to take steps at their request prior to entering into a contract.',
|
|
153
|
-
gdprArticle: 'Article 6(1)(b)',
|
|
154
|
-
},
|
|
155
|
-
consent: {
|
|
156
|
-
title: 'Consent',
|
|
157
|
-
description: 'The data subject has given consent to the processing of their personal data for one or more specific purposes.',
|
|
158
|
-
gdprArticle: 'Article 6(1)(a)',
|
|
159
|
-
},
|
|
160
|
-
legitimate: {
|
|
161
|
-
title: 'Legitimate Interests',
|
|
162
|
-
description: 'Processing is necessary for the purposes of the legitimate interests pursued by the controller or by a third party.',
|
|
163
|
-
gdprArticle: 'Article 6(1)(f)',
|
|
164
|
-
},
|
|
165
|
-
legal: {
|
|
166
|
-
title: 'Legal Obligation',
|
|
167
|
-
description: 'Processing is necessary for compliance with a legal obligation to which the controller is subject.',
|
|
168
|
-
gdprArticle: 'Article 6(1)(c)',
|
|
169
|
-
},
|
|
170
|
-
};
|
package/src/db/index.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { drizzle, NeonHttpDatabase } from 'drizzle-orm/neon-http';
|
|
2
|
-
import { neon } from '@neondatabase/serverless';
|
|
3
|
-
import * as schema from './schema.js';
|
|
4
|
-
|
|
5
|
-
// Type for our database instance
|
|
6
|
-
type Database = NeonHttpDatabase<typeof schema>;
|
|
7
|
-
|
|
8
|
-
// Lazy-loaded database instance (for serverless cold starts)
|
|
9
|
-
let dbInstance: Database | null = null;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Get the Drizzle database instance.
|
|
13
|
-
* Lazily creates the connection on first use.
|
|
14
|
-
*/
|
|
15
|
-
export function getDb(): Database {
|
|
16
|
-
if (!dbInstance) {
|
|
17
|
-
if (!process.env.DATABASE_URL) {
|
|
18
|
-
throw new Error('DATABASE_URL environment variable is not set');
|
|
19
|
-
}
|
|
20
|
-
const sql = neon(process.env.DATABASE_URL);
|
|
21
|
-
dbInstance = drizzle(sql, { schema });
|
|
22
|
-
}
|
|
23
|
-
return dbInstance;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Re-export schema for convenience
|
|
27
|
-
export * from './schema.js';
|
|
28
|
-
export { schema };
|