@contractspec/bundle.marketing 1.12.0 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/.turbo/turbo-build.log +146 -175
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +57 -0
  4. package/dist/browser/components/marketing/ChangelogPage.js +92 -0
  5. package/dist/browser/components/marketing/CofounderPage.js +581 -0
  6. package/dist/browser/components/marketing/ContactClient.js +1379 -0
  7. package/dist/browser/components/marketing/ContributePage.js +487 -0
  8. package/dist/browser/components/marketing/DesignPartnerPage.js +272 -0
  9. package/dist/browser/components/marketing/LandingPage.js +629 -0
  10. package/dist/browser/components/marketing/PricingClient.js +1972 -0
  11. package/dist/browser/components/marketing/ProductClientPage.js +563 -0
  12. package/dist/browser/components/marketing/index.js +4818 -0
  13. package/dist/browser/components/marketing/pricing-thinking-modal.js +258 -0
  14. package/dist/browser/components/marketing/sections/AudienceSection.js +90 -0
  15. package/dist/browser/components/marketing/sections/CorePositioningSection.js +72 -0
  16. package/dist/browser/components/marketing/sections/CtaSection.js +67 -0
  17. package/dist/browser/components/marketing/sections/DevelopersSection.js +50 -0
  18. package/dist/browser/components/marketing/sections/FearsSection.js +105 -0
  19. package/dist/browser/components/marketing/sections/HeroMarketingSection.js +93 -0
  20. package/dist/browser/components/marketing/sections/IconGridSection.js +63 -0
  21. package/dist/browser/components/marketing/sections/OutputsSection.js +116 -0
  22. package/dist/browser/components/marketing/sections/ProblemSection.js +103 -0
  23. package/dist/browser/components/marketing/sections/SolutionSection.js +103 -0
  24. package/dist/browser/components/marketing/sections/StepsSection.js +109 -0
  25. package/dist/browser/components/marketing/waitlist-section.js +1104 -0
  26. package/dist/browser/components/templates/TemplatesClientPage.js +5662 -0
  27. package/dist/browser/components/templates/TemplatesPage.js +177 -0
  28. package/dist/browser/components/templates/TemplatesPreviewModal.js +124 -0
  29. package/dist/browser/components/templates/index.js +5831 -0
  30. package/dist/browser/index.js +6485 -0
  31. package/dist/browser/libs/email/client.js +122 -0
  32. package/dist/browser/libs/email/contact.js +190 -0
  33. package/dist/browser/libs/email/newsletter.js +215 -0
  34. package/dist/browser/libs/email/types.js +2 -0
  35. package/dist/browser/libs/email/utils.js +16 -0
  36. package/dist/browser/libs/email/waitlist-application.js +295 -0
  37. package/dist/browser/libs/email/waitlist.js +225 -0
  38. package/dist/browser/libs/pricing-examples.js +26 -0
  39. package/dist/browser/registry/engine.js +5293 -0
  40. package/dist/browser/registry/factory.js +52 -0
  41. package/dist/browser/registry/index.js +5358 -0
  42. package/dist/browser/registry/registry-docs.js +343 -0
  43. package/dist/browser/registry/registry-landing.js +4937 -0
  44. package/dist/browser/registry/registry.js +5279 -0
  45. package/dist/browser/registry/types.js +0 -0
  46. package/dist/browser/registry/utils.js +5340 -0
  47. package/dist/components/marketing/ChangelogPage.d.ts +11 -17
  48. package/dist/components/marketing/ChangelogPage.d.ts.map +1 -1
  49. package/dist/components/marketing/ChangelogPage.js +84 -62
  50. package/dist/components/marketing/CofounderPage.d.ts +1 -6
  51. package/dist/components/marketing/CofounderPage.d.ts.map +1 -1
  52. package/dist/components/marketing/CofounderPage.js +544 -436
  53. package/dist/components/marketing/ContactClient.d.ts +1 -6
  54. package/dist/components/marketing/ContactClient.d.ts.map +1 -1
  55. package/dist/components/marketing/ContactClient.js +1371 -155
  56. package/dist/components/marketing/ContributePage.d.ts +3 -8
  57. package/dist/components/marketing/ContributePage.d.ts.map +1 -1
  58. package/dist/components/marketing/ContributePage.js +478 -358
  59. package/dist/components/marketing/DesignPartnerPage.d.ts +3 -8
  60. package/dist/components/marketing/DesignPartnerPage.d.ts.map +1 -1
  61. package/dist/components/marketing/DesignPartnerPage.js +263 -211
  62. package/dist/components/marketing/LandingPage.d.ts +1 -6
  63. package/dist/components/marketing/LandingPage.d.ts.map +1 -1
  64. package/dist/components/marketing/LandingPage.js +623 -37
  65. package/dist/components/marketing/PricingClient.d.ts +1 -6
  66. package/dist/components/marketing/PricingClient.d.ts.map +1 -1
  67. package/dist/components/marketing/PricingClient.js +1962 -516
  68. package/dist/components/marketing/ProductClientPage.d.ts +1 -6
  69. package/dist/components/marketing/ProductClientPage.d.ts.map +1 -1
  70. package/dist/components/marketing/ProductClientPage.js +556 -458
  71. package/dist/components/marketing/index.d.ts +11 -11
  72. package/dist/components/marketing/index.d.ts.map +1 -0
  73. package/dist/components/marketing/index.js +4813 -12
  74. package/dist/components/marketing/pricing-thinking-modal.d.ts +5 -13
  75. package/dist/components/marketing/pricing-thinking-modal.d.ts.map +1 -1
  76. package/dist/components/marketing/pricing-thinking-modal.js +248 -197
  77. package/dist/components/marketing/sections/AudienceSection.d.ts +1 -6
  78. package/dist/components/marketing/sections/AudienceSection.d.ts.map +1 -1
  79. package/dist/components/marketing/sections/AudienceSection.js +80 -63
  80. package/dist/components/marketing/sections/CorePositioningSection.d.ts +1 -6
  81. package/dist/components/marketing/sections/CorePositioningSection.d.ts.map +1 -1
  82. package/dist/components/marketing/sections/CorePositioningSection.js +62 -54
  83. package/dist/components/marketing/sections/CtaSection.d.ts +1 -6
  84. package/dist/components/marketing/sections/CtaSection.d.ts.map +1 -1
  85. package/dist/components/marketing/sections/CtaSection.js +58 -50
  86. package/dist/components/marketing/sections/DevelopersSection.d.ts +1 -6
  87. package/dist/components/marketing/sections/DevelopersSection.d.ts.map +1 -1
  88. package/dist/components/marketing/sections/DevelopersSection.js +40 -40
  89. package/dist/components/marketing/sections/FearsSection.d.ts +1 -6
  90. package/dist/components/marketing/sections/FearsSection.d.ts.map +1 -1
  91. package/dist/components/marketing/sections/FearsSection.js +96 -44
  92. package/dist/components/marketing/sections/HeroMarketingSection.d.ts +1 -6
  93. package/dist/components/marketing/sections/HeroMarketingSection.d.ts.map +1 -1
  94. package/dist/components/marketing/sections/HeroMarketingSection.js +82 -71
  95. package/dist/components/marketing/sections/IconGridSection.d.ts +25 -39
  96. package/dist/components/marketing/sections/IconGridSection.d.ts.map +1 -1
  97. package/dist/components/marketing/sections/IconGridSection.js +55 -41
  98. package/dist/components/marketing/sections/OutputsSection.d.ts +1 -6
  99. package/dist/components/marketing/sections/OutputsSection.d.ts.map +1 -1
  100. package/dist/components/marketing/sections/OutputsSection.js +107 -55
  101. package/dist/components/marketing/sections/ProblemSection.d.ts +1 -6
  102. package/dist/components/marketing/sections/ProblemSection.d.ts.map +1 -1
  103. package/dist/components/marketing/sections/ProblemSection.js +94 -42
  104. package/dist/components/marketing/sections/SolutionSection.d.ts +1 -6
  105. package/dist/components/marketing/sections/SolutionSection.d.ts.map +1 -1
  106. package/dist/components/marketing/sections/SolutionSection.js +94 -42
  107. package/dist/components/marketing/sections/StepsSection.d.ts +1 -6
  108. package/dist/components/marketing/sections/StepsSection.d.ts.map +1 -1
  109. package/dist/components/marketing/sections/StepsSection.js +100 -48
  110. package/dist/components/marketing/waitlist-section.d.ts +5 -12
  111. package/dist/components/marketing/waitlist-section.d.ts.map +1 -1
  112. package/dist/components/marketing/waitlist-section.js +1089 -568
  113. package/dist/components/templates/TemplatesClientPage.d.ts +1 -6
  114. package/dist/components/templates/TemplatesClientPage.d.ts.map +1 -1
  115. package/dist/components/templates/TemplatesClientPage.js +5649 -617
  116. package/dist/components/templates/TemplatesPage.d.ts +1 -6
  117. package/dist/components/templates/TemplatesPage.d.ts.map +1 -1
  118. package/dist/components/templates/TemplatesPage.js +163 -116
  119. package/dist/components/templates/TemplatesPreviewModal.d.ts +5 -12
  120. package/dist/components/templates/TemplatesPreviewModal.d.ts.map +1 -1
  121. package/dist/components/templates/TemplatesPreviewModal.js +113 -131
  122. package/dist/components/templates/index.d.ts +4 -4
  123. package/dist/components/templates/index.d.ts.map +1 -0
  124. package/dist/components/templates/index.js +5825 -4
  125. package/dist/index.d.ts +9 -29
  126. package/dist/index.d.ts.map +1 -0
  127. package/dist/index.js +6480 -28
  128. package/dist/libs/email/client.d.ts +9 -12
  129. package/dist/libs/email/client.d.ts.map +1 -1
  130. package/dist/libs/email/client.js +109 -105
  131. package/dist/libs/email/client.test.d.ts +2 -0
  132. package/dist/libs/email/client.test.d.ts.map +1 -0
  133. package/dist/libs/email/contact.d.ts +2 -6
  134. package/dist/libs/email/contact.d.ts.map +1 -1
  135. package/dist/libs/email/contact.js +155 -41
  136. package/dist/libs/email/newsletter.d.ts +2 -6
  137. package/dist/libs/email/newsletter.d.ts.map +1 -1
  138. package/dist/libs/email/newsletter.js +169 -54
  139. package/dist/libs/email/types.d.ts +48 -52
  140. package/dist/libs/email/types.d.ts.map +1 -1
  141. package/dist/libs/email/types.js +3 -1
  142. package/dist/libs/email/utils.d.ts +2 -5
  143. package/dist/libs/email/utils.d.ts.map +1 -1
  144. package/dist/libs/email/utils.js +10 -6
  145. package/dist/libs/email/waitlist-application.d.ts +2 -6
  146. package/dist/libs/email/waitlist-application.d.ts.map +1 -1
  147. package/dist/libs/email/waitlist-application.js +191 -71
  148. package/dist/libs/email/waitlist.d.ts +2 -6
  149. package/dist/libs/email/waitlist.d.ts.map +1 -1
  150. package/dist/libs/email/waitlist.js +171 -56
  151. package/dist/libs/pricing-examples.d.ts +13 -16
  152. package/dist/libs/pricing-examples.d.ts.map +1 -1
  153. package/dist/libs/pricing-examples.js +20 -20
  154. package/dist/node/components/marketing/ChangelogPage.js +87 -0
  155. package/dist/node/components/marketing/CofounderPage.js +576 -0
  156. package/dist/node/components/marketing/ContactClient.js +1374 -0
  157. package/dist/node/components/marketing/ContributePage.js +482 -0
  158. package/dist/node/components/marketing/DesignPartnerPage.js +267 -0
  159. package/dist/node/components/marketing/LandingPage.js +624 -0
  160. package/dist/node/components/marketing/PricingClient.js +1967 -0
  161. package/dist/node/components/marketing/ProductClientPage.js +558 -0
  162. package/dist/node/components/marketing/index.js +4813 -0
  163. package/dist/node/components/marketing/pricing-thinking-modal.js +253 -0
  164. package/dist/node/components/marketing/sections/AudienceSection.js +85 -0
  165. package/dist/node/components/marketing/sections/CorePositioningSection.js +67 -0
  166. package/dist/node/components/marketing/sections/CtaSection.js +62 -0
  167. package/dist/node/components/marketing/sections/DevelopersSection.js +45 -0
  168. package/dist/node/components/marketing/sections/FearsSection.js +100 -0
  169. package/dist/node/components/marketing/sections/HeroMarketingSection.js +88 -0
  170. package/dist/node/components/marketing/sections/IconGridSection.js +58 -0
  171. package/dist/node/components/marketing/sections/OutputsSection.js +111 -0
  172. package/dist/node/components/marketing/sections/ProblemSection.js +98 -0
  173. package/dist/node/components/marketing/sections/SolutionSection.js +98 -0
  174. package/dist/node/components/marketing/sections/StepsSection.js +104 -0
  175. package/dist/node/components/marketing/waitlist-section.js +1099 -0
  176. package/dist/node/components/templates/TemplatesClientPage.js +5657 -0
  177. package/dist/node/components/templates/TemplatesPage.js +172 -0
  178. package/dist/node/components/templates/TemplatesPreviewModal.js +119 -0
  179. package/dist/node/components/templates/index.js +5826 -0
  180. package/dist/node/index.js +6480 -0
  181. package/dist/node/libs/email/client.js +117 -0
  182. package/dist/node/libs/email/contact.js +185 -0
  183. package/dist/node/libs/email/newsletter.js +210 -0
  184. package/dist/node/libs/email/types.js +2 -0
  185. package/dist/node/libs/email/utils.js +11 -0
  186. package/dist/node/libs/email/waitlist-application.js +290 -0
  187. package/dist/node/libs/email/waitlist.js +220 -0
  188. package/dist/node/libs/pricing-examples.js +21 -0
  189. package/dist/node/registry/engine.js +5288 -0
  190. package/dist/node/registry/factory.js +47 -0
  191. package/dist/node/registry/index.js +5353 -0
  192. package/dist/node/registry/registry-docs.js +338 -0
  193. package/dist/node/registry/registry-landing.js +4932 -0
  194. package/dist/node/registry/registry.js +5274 -0
  195. package/dist/node/registry/types.js +0 -0
  196. package/dist/node/registry/utils.js +5335 -0
  197. package/dist/registry/engine.d.ts +4 -8
  198. package/dist/registry/engine.d.ts.map +1 -1
  199. package/dist/registry/engine.js +5287 -23
  200. package/dist/registry/factory.d.ts +30 -34
  201. package/dist/registry/factory.d.ts.map +1 -1
  202. package/dist/registry/factory.js +42 -56
  203. package/dist/registry/index.d.ts +8 -8
  204. package/dist/registry/index.d.ts.map +1 -0
  205. package/dist/registry/index.js +5353 -8
  206. package/dist/registry/registry-docs.d.ts +4 -8
  207. package/dist/registry/registry-docs.d.ts.map +1 -1
  208. package/dist/registry/registry-docs.js +242 -209
  209. package/dist/registry/registry-landing.d.ts +5 -9
  210. package/dist/registry/registry-landing.d.ts.map +1 -1
  211. package/dist/registry/registry-landing.js +4930 -93
  212. package/dist/registry/registry.d.ts +7 -11
  213. package/dist/registry/registry.d.ts.map +1 -1
  214. package/dist/registry/registry.js +5262 -49
  215. package/dist/registry/types.d.ts +6 -10
  216. package/dist/registry/types.d.ts.map +1 -1
  217. package/dist/registry/types.js +1 -0
  218. package/dist/registry/utils.d.ts +10 -14
  219. package/dist/registry/utils.d.ts.map +1 -1
  220. package/dist/registry/utils.js +5330 -49
  221. package/package.json +355 -73
  222. package/tsdown.config.js +1 -2
  223. package/.turbo/turbo-build$colon$types.log +0 -1
  224. package/.turbo/turbo-lint.log +0 -3
  225. package/dist/components/marketing/ChangelogPage.js.map +0 -1
  226. package/dist/components/marketing/CofounderPage.js.map +0 -1
  227. package/dist/components/marketing/ContactClient.js.map +0 -1
  228. package/dist/components/marketing/ContributePage.js.map +0 -1
  229. package/dist/components/marketing/DesignPartnerPage.js.map +0 -1
  230. package/dist/components/marketing/LandingPage.js.map +0 -1
  231. package/dist/components/marketing/PricingClient.js.map +0 -1
  232. package/dist/components/marketing/ProductClientPage.js.map +0 -1
  233. package/dist/components/marketing/pricing-thinking-modal.js.map +0 -1
  234. package/dist/components/marketing/sections/AudienceSection.js.map +0 -1
  235. package/dist/components/marketing/sections/CorePositioningSection.js.map +0 -1
  236. package/dist/components/marketing/sections/CtaSection.js.map +0 -1
  237. package/dist/components/marketing/sections/DevelopersSection.js.map +0 -1
  238. package/dist/components/marketing/sections/FearsSection.js.map +0 -1
  239. package/dist/components/marketing/sections/HeroMarketingSection.js.map +0 -1
  240. package/dist/components/marketing/sections/IconGridSection.js.map +0 -1
  241. package/dist/components/marketing/sections/OutputsSection.js.map +0 -1
  242. package/dist/components/marketing/sections/ProblemSection.js.map +0 -1
  243. package/dist/components/marketing/sections/SolutionSection.js.map +0 -1
  244. package/dist/components/marketing/sections/StepsSection.js.map +0 -1
  245. package/dist/components/marketing/waitlist-section.js.map +0 -1
  246. package/dist/components/templates/TemplatesClientPage.js.map +0 -1
  247. package/dist/components/templates/TemplatesPage.js.map +0 -1
  248. package/dist/components/templates/TemplatesPreviewModal.js.map +0 -1
  249. package/dist/libs/email/client.js.map +0 -1
  250. package/dist/libs/email/contact.js.map +0 -1
  251. package/dist/libs/email/newsletter.js.map +0 -1
  252. package/dist/libs/email/utils.js.map +0 -1
  253. package/dist/libs/email/waitlist-application.js.map +0 -1
  254. package/dist/libs/email/waitlist.js.map +0 -1
  255. package/dist/libs/pricing-examples.js.map +0 -1
  256. package/dist/registry/engine.js.map +0 -1
  257. package/dist/registry/factory.js.map +0 -1
  258. package/dist/registry/registry-docs.js.map +0 -1
  259. package/dist/registry/registry-landing.js.map +0 -1
  260. package/dist/registry/registry.js.map +0 -1
  261. package/dist/registry/utils.js.map +0 -1
  262. package/tsconfig.tsbuildinfo +0 -1
@@ -1,50 +1,170 @@
1
- 'use server';
1
+ // @bun
2
+ var __require = import.meta.require;
2
3
 
3
- import { getEmailConfig, sendEmail } from "./client.js";
4
- import { escapeHtml, formatMultilineHtml } from "./utils.js";
4
+ // src/libs/email/client.ts
5
+ import { createClient, Temv1alpha1 } from "@scaleway/sdk";
6
+ import { Logger } from "@contractspec/lib.logger";
7
+ var DEFAULT_FROM = {
8
+ email: "noreply@transactional.contractspec.io",
9
+ name: "ContractSpec"
10
+ };
11
+ var DEFAULT_TEAM_INBOX = {
12
+ email: "contact@contractspec.io",
13
+ name: "ContractSpec Team"
14
+ };
15
+ var DEFAULT_REGION = "fr-par";
16
+ var cachedConfig = null;
17
+ var cachedClient = null;
18
+ var apiFactory = (client) => new Temv1alpha1.API(client);
19
+ var mapRegion = (value) => {
20
+ const normalized = value?.trim().toLowerCase();
21
+ if (normalized === "par" || normalized === "fr-par")
22
+ return "fr-par";
23
+ if (normalized === "ams" || normalized === "nl-ams")
24
+ return "nl-ams";
25
+ if (normalized === "waw" || normalized === "pl-waw")
26
+ return "pl-waw";
27
+ return DEFAULT_REGION;
28
+ };
29
+ var getEmailConfig = () => {
30
+ if (cachedConfig) {
31
+ return { ok: true, config: cachedConfig };
32
+ }
33
+ const accessKey = process.env.SCALEWAY_ACCESS_KEY || process.env.SCALEWAY_ACCESS_KEY_QUEUE;
34
+ const secretKey = process.env.SCALEWAY_SECRET_KEY || process.env.SCALEWAY_SECRET_KEY_QUEUE;
35
+ const projectId = process.env.SCALEWAY_PROJECT_ID;
36
+ if (!accessKey || !secretKey || !projectId) {
37
+ return {
38
+ ok: false,
39
+ errorMessage: "Email service is not configured. Please contact us directly at contact@contractspec.io."
40
+ };
41
+ }
42
+ const region = mapRegion(process.env.SCALEWAY_REGION);
43
+ cachedConfig = {
44
+ accessKey,
45
+ secretKey,
46
+ projectId,
47
+ region,
48
+ defaultZone: `${region}-1`,
49
+ from: {
50
+ email: process.env.SCALEWAY_EMAIL_FROM_EMAIL ?? DEFAULT_FROM.email,
51
+ name: process.env.SCALEWAY_EMAIL_FROM_NAME ?? DEFAULT_FROM.name
52
+ },
53
+ teamInbox: {
54
+ email: process.env.SCALEWAY_EMAIL_TEAM_EMAIL ?? DEFAULT_TEAM_INBOX.email,
55
+ name: process.env.SCALEWAY_EMAIL_TEAM_NAME ?? DEFAULT_TEAM_INBOX.name
56
+ }
57
+ };
58
+ return { ok: true, config: cachedConfig };
59
+ };
60
+ var getTemClient = (config) => {
61
+ if (cachedClient) {
62
+ return cachedClient;
63
+ }
64
+ const client = createClient({
65
+ accessKey: config.accessKey,
66
+ secretKey: config.secretKey,
67
+ defaultProjectId: config.projectId,
68
+ defaultRegion: config.region,
69
+ defaultZone: config.defaultZone
70
+ });
71
+ cachedClient = apiFactory(client);
72
+ return cachedClient;
73
+ };
74
+ var sendEmail = async (config, request) => {
75
+ try {
76
+ const client = getTemClient(config);
77
+ await client.createEmail({
78
+ region: config.region,
79
+ projectId: config.projectId,
80
+ from: config.from,
81
+ to: request.to,
82
+ subject: request.subject,
83
+ text: request.text,
84
+ html: request.html || request.text,
85
+ additionalHeaders: request.replyTo ? [{ key: "Reply-To", value: request.replyTo }] : undefined
86
+ });
87
+ return { success: true };
88
+ } catch (error) {
89
+ new Logger().error("scaleway_tem_email_send_failed", {
90
+ context: request.context ?? "email",
91
+ error: error instanceof Error ? error.message : error
92
+ });
93
+ return {
94
+ success: false,
95
+ error,
96
+ errorMessage: "Failed to send email via Scaleway."
97
+ };
98
+ }
99
+ };
100
+ var __internal = {
101
+ resetCaches() {
102
+ cachedClient = null;
103
+ cachedConfig = null;
104
+ apiFactory = (client) => new Temv1alpha1.API(client);
105
+ },
106
+ setApiFactory(factory) {
107
+ apiFactory = factory;
108
+ },
109
+ setClient(client) {
110
+ cachedClient = client;
111
+ }
112
+ };
113
+
114
+ // src/libs/email/utils.ts
115
+ var escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
116
+ var formatMultilineHtml = (value) => escapeHtml(value).replaceAll(`
117
+ `, "<br />");
5
118
 
6
- //#region src/libs/email/waitlist-application.ts
7
- const APPLICATION_MISSING_CONFIG = "Waitlist application service is not configured. Please try again later.";
8
- const APPLICATION_SEND_ERROR = "Failed to submit application. Please try again later or contact us directly.";
9
- const submitWaitlistApplication = async (formData) => {
10
- const email = (formData.get("email") ?? "").toString().trim();
11
- const name = (formData.get("name") ?? "").toString().trim();
12
- const company = (formData.get("company") ?? "").toString().trim();
13
- const role = (formData.get("role") ?? "").toString().trim();
14
- const useCase = (formData.get("useCase") ?? "").toString().trim();
15
- const currentStack = (formData.get("currentStack") ?? "").toString().trim();
16
- const whatBuilding = (formData.get("whatBuilding") ?? "").toString().trim();
17
- const whatSolving = (formData.get("whatSolving") ?? "").toString().trim();
18
- const teamSize = (formData.get("teamSize") ?? "").toString().trim();
19
- const timeline = (formData.get("timeline") ?? "").toString().trim();
20
- const openToSessions = formData.get("openToSessions") === "on";
21
- const okayWithCaseStudies = formData.get("okayWithCaseStudies") === "on";
22
- if (!email || !email.includes("@")) return {
23
- success: false,
24
- text: "Please enter a valid email address."
25
- };
26
- if (!name || !whatBuilding || !whatSolving) return {
27
- success: false,
28
- text: "Please fill in all required fields."
29
- };
30
- const configResult = getEmailConfig();
31
- if (!configResult.ok || !configResult.config) return {
32
- success: false,
33
- text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG
34
- };
35
- const applicantText = `
119
+ // src/libs/email/waitlist-application.ts
120
+ "use server";
121
+ var APPLICATION_MISSING_CONFIG = "Waitlist application service is not configured. Please try again later.";
122
+ var APPLICATION_SEND_ERROR = "Failed to submit application. Please try again later or contact us directly.";
123
+ var submitWaitlistApplication = async (formData) => {
124
+ const email = (formData.get("email") ?? "").toString().trim();
125
+ const name = (formData.get("name") ?? "").toString().trim();
126
+ const company = (formData.get("company") ?? "").toString().trim();
127
+ const role = (formData.get("role") ?? "").toString().trim();
128
+ const useCase = (formData.get("useCase") ?? "").toString().trim();
129
+ const currentStack = (formData.get("currentStack") ?? "").toString().trim();
130
+ const whatBuilding = (formData.get("whatBuilding") ?? "").toString().trim();
131
+ const whatSolving = (formData.get("whatSolving") ?? "").toString().trim();
132
+ const teamSize = (formData.get("teamSize") ?? "").toString().trim();
133
+ const timeline = (formData.get("timeline") ?? "").toString().trim();
134
+ const openToSessions = formData.get("openToSessions") === "on";
135
+ const okayWithCaseStudies = formData.get("okayWithCaseStudies") === "on";
136
+ if (!email || !email.includes("@")) {
137
+ return {
138
+ success: false,
139
+ text: "Please enter a valid email address."
140
+ };
141
+ }
142
+ if (!name || !whatBuilding || !whatSolving) {
143
+ return {
144
+ success: false,
145
+ text: "Please fill in all required fields."
146
+ };
147
+ }
148
+ const configResult = getEmailConfig();
149
+ if (!configResult.ok || !configResult.config) {
150
+ return {
151
+ success: false,
152
+ text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG
153
+ };
154
+ }
155
+ const applicantText = `
36
156
  You're on the list.
37
157
 
38
158
  Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.
39
159
 
40
160
  What happens next:
41
- We review applications weekly
42
- If selected, we'll reach out via email to schedule an intro call
43
- During early access, you'll get hands-on support and influence over the roadmap
161
+ \u2022 We review applications weekly
162
+ \u2022 If selected, we'll reach out via email to schedule an intro call
163
+ \u2022 During early access, you'll get hands-on support and influence over the roadmap
44
164
 
45
165
  In the meantime:
46
- Check out our docs: https://contractspec.io/docs
47
- Book a demo call: https://contractspec.io/contact
166
+ \u2022 Check out our docs: https://contractspec.io/docs
167
+ \u2022 Book a demo call: https://contractspec.io/contact
48
168
 
49
169
  We're excited about the possibility of working together!
50
170
 
@@ -52,11 +172,7 @@ We're excited about the possibility of working together!
52
172
  ContractSpec Team
53
173
  https://contractspec.io
54
174
  `.trim();
55
- if (!(await sendEmail(configResult.config, {
56
- to: [{ email }],
57
- subject: "You're on the ContractSpec design partner waitlist!",
58
- text: applicantText,
59
- html: `
175
+ const applicantHtml = `
60
176
  <div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
61
177
  <h1 style="color: #8b5cf6;">You're on the list.</h1>
62
178
  <p>Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.</p>
@@ -78,17 +194,22 @@ https://contractspec.io
78
194
  <a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
79
195
  </p>
80
196
  </div>
81
- `,
82
- context: "waitlist-application-welcome"
83
- })).success) return {
84
- success: false,
85
- text: APPLICATION_SEND_ERROR
86
- };
87
- const preferencesText = `
197
+ `;
198
+ const applicantSend = await sendEmail(configResult.config, {
199
+ to: [{ email }],
200
+ subject: "You're on the ContractSpec design partner waitlist!",
201
+ text: applicantText,
202
+ html: applicantHtml,
203
+ context: "waitlist-application-welcome"
204
+ });
205
+ if (!applicantSend.success) {
206
+ return { success: false, text: APPLICATION_SEND_ERROR };
207
+ }
208
+ const preferencesText = `
88
209
  Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
89
210
  Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
90
211
  `.trim();
91
- const teamEmailText = `
212
+ const teamEmailText = `
92
213
  New Design Partner Waitlist Application
93
214
 
94
215
  Contact Information:
@@ -116,7 +237,7 @@ Preferences:
116
237
  ---
117
238
  Submitted via ContractSpec waitlist application form
118
239
  `.trim();
119
- const teamEmailHtml = `
240
+ const teamEmailHtml = `
120
241
  <div style="font-family: sans-serif; max-width: 720px; margin: 0 auto;">
121
242
  <h1 style="color: #8b5cf6;">New Design Partner Waitlist Application</h1>
122
243
  <h2 style="color: #8b5cf6; margin: 16px 0 8px;">Contact Information</h2>
@@ -148,23 +269,22 @@ Submitted via ContractSpec waitlist application form
148
269
  <p style="color: #6b7280; font-size: 12px; margin-top: 20px;">Submitted via ContractSpec waitlist application form</p>
149
270
  </div>
150
271
  `;
151
- if (!(await sendEmail(configResult.config, {
152
- to: [configResult.config.teamInbox],
153
- subject: `New Design Partner Application: ${name} (${email})`,
154
- text: teamEmailText,
155
- html: teamEmailHtml,
156
- replyTo: email,
157
- context: "waitlist-application-team-notification"
158
- })).success) return {
159
- success: false,
160
- text: APPLICATION_SEND_ERROR
161
- };
162
- return {
163
- success: true,
164
- text: "Application submitted successfully!"
165
- };
272
+ const teamSend = await sendEmail(configResult.config, {
273
+ to: [configResult.config.teamInbox],
274
+ subject: `New Design Partner Application: ${name} (${email})`,
275
+ text: teamEmailText,
276
+ html: teamEmailHtml,
277
+ replyTo: email,
278
+ context: "waitlist-application-team-notification"
279
+ });
280
+ if (!teamSend.success) {
281
+ return { success: false, text: APPLICATION_SEND_ERROR };
282
+ }
283
+ return {
284
+ success: true,
285
+ text: "Application submitted successfully!"
286
+ };
287
+ };
288
+ export {
289
+ submitWaitlistApplication
166
290
  };
167
-
168
- //#endregion
169
- export { submitWaitlistApplication };
170
- //# sourceMappingURL=waitlist-application.js.map
@@ -1,7 +1,3 @@
1
- import { SubmitWaitlistResult } from "./types.js";
2
-
3
- //#region src/libs/email/waitlist.d.ts
4
- declare const joinWaitlist: (formData: FormData) => Promise<SubmitWaitlistResult>;
5
- //#endregion
6
- export { joinWaitlist };
1
+ import type { SubmitWaitlistResult } from './types';
2
+ export declare const joinWaitlist: (formData: FormData) => Promise<SubmitWaitlistResult>;
7
3
  //# sourceMappingURL=waitlist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"waitlist.d.ts","names":[],"sources":["../../../src/libs/email/waitlist.ts"],"mappings":";;;cAWa,YAAA,GACX,QAAA,EAAU,QAAA,KACT,OAAA,CAAQ,oBAAA"}
1
+ {"version":3,"file":"waitlist.d.ts","sourceRoot":"","sources":["../../../src/libs/email/waitlist.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAOpD,eAAO,MAAM,YAAY,GACvB,UAAU,QAAQ,KACjB,OAAO,CAAC,oBAAoB,CAwG9B,CAAC"}
@@ -1,37 +1,155 @@
1
- 'use server';
1
+ // @bun
2
+ var __require = import.meta.require;
2
3
 
3
- import { getEmailConfig, sendEmail } from "./client.js";
4
- import { formatMultilineHtml } from "./utils.js";
4
+ // src/libs/email/client.ts
5
+ import { createClient, Temv1alpha1 } from "@scaleway/sdk";
6
+ import { Logger } from "@contractspec/lib.logger";
7
+ var DEFAULT_FROM = {
8
+ email: "noreply@transactional.contractspec.io",
9
+ name: "ContractSpec"
10
+ };
11
+ var DEFAULT_TEAM_INBOX = {
12
+ email: "contact@contractspec.io",
13
+ name: "ContractSpec Team"
14
+ };
15
+ var DEFAULT_REGION = "fr-par";
16
+ var cachedConfig = null;
17
+ var cachedClient = null;
18
+ var apiFactory = (client) => new Temv1alpha1.API(client);
19
+ var mapRegion = (value) => {
20
+ const normalized = value?.trim().toLowerCase();
21
+ if (normalized === "par" || normalized === "fr-par")
22
+ return "fr-par";
23
+ if (normalized === "ams" || normalized === "nl-ams")
24
+ return "nl-ams";
25
+ if (normalized === "waw" || normalized === "pl-waw")
26
+ return "pl-waw";
27
+ return DEFAULT_REGION;
28
+ };
29
+ var getEmailConfig = () => {
30
+ if (cachedConfig) {
31
+ return { ok: true, config: cachedConfig };
32
+ }
33
+ const accessKey = process.env.SCALEWAY_ACCESS_KEY || process.env.SCALEWAY_ACCESS_KEY_QUEUE;
34
+ const secretKey = process.env.SCALEWAY_SECRET_KEY || process.env.SCALEWAY_SECRET_KEY_QUEUE;
35
+ const projectId = process.env.SCALEWAY_PROJECT_ID;
36
+ if (!accessKey || !secretKey || !projectId) {
37
+ return {
38
+ ok: false,
39
+ errorMessage: "Email service is not configured. Please contact us directly at contact@contractspec.io."
40
+ };
41
+ }
42
+ const region = mapRegion(process.env.SCALEWAY_REGION);
43
+ cachedConfig = {
44
+ accessKey,
45
+ secretKey,
46
+ projectId,
47
+ region,
48
+ defaultZone: `${region}-1`,
49
+ from: {
50
+ email: process.env.SCALEWAY_EMAIL_FROM_EMAIL ?? DEFAULT_FROM.email,
51
+ name: process.env.SCALEWAY_EMAIL_FROM_NAME ?? DEFAULT_FROM.name
52
+ },
53
+ teamInbox: {
54
+ email: process.env.SCALEWAY_EMAIL_TEAM_EMAIL ?? DEFAULT_TEAM_INBOX.email,
55
+ name: process.env.SCALEWAY_EMAIL_TEAM_NAME ?? DEFAULT_TEAM_INBOX.name
56
+ }
57
+ };
58
+ return { ok: true, config: cachedConfig };
59
+ };
60
+ var getTemClient = (config) => {
61
+ if (cachedClient) {
62
+ return cachedClient;
63
+ }
64
+ const client = createClient({
65
+ accessKey: config.accessKey,
66
+ secretKey: config.secretKey,
67
+ defaultProjectId: config.projectId,
68
+ defaultRegion: config.region,
69
+ defaultZone: config.defaultZone
70
+ });
71
+ cachedClient = apiFactory(client);
72
+ return cachedClient;
73
+ };
74
+ var sendEmail = async (config, request) => {
75
+ try {
76
+ const client = getTemClient(config);
77
+ await client.createEmail({
78
+ region: config.region,
79
+ projectId: config.projectId,
80
+ from: config.from,
81
+ to: request.to,
82
+ subject: request.subject,
83
+ text: request.text,
84
+ html: request.html || request.text,
85
+ additionalHeaders: request.replyTo ? [{ key: "Reply-To", value: request.replyTo }] : undefined
86
+ });
87
+ return { success: true };
88
+ } catch (error) {
89
+ new Logger().error("scaleway_tem_email_send_failed", {
90
+ context: request.context ?? "email",
91
+ error: error instanceof Error ? error.message : error
92
+ });
93
+ return {
94
+ success: false,
95
+ error,
96
+ errorMessage: "Failed to send email via Scaleway."
97
+ };
98
+ }
99
+ };
100
+ var __internal = {
101
+ resetCaches() {
102
+ cachedClient = null;
103
+ cachedConfig = null;
104
+ apiFactory = (client) => new Temv1alpha1.API(client);
105
+ },
106
+ setApiFactory(factory) {
107
+ apiFactory = factory;
108
+ },
109
+ setClient(client) {
110
+ cachedClient = client;
111
+ }
112
+ };
113
+
114
+ // src/libs/email/utils.ts
115
+ var escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
116
+ var formatMultilineHtml = (value) => escapeHtml(value).replaceAll(`
117
+ `, "<br />");
5
118
 
6
- //#region src/libs/email/waitlist.ts
7
- const WAITLIST_MISSING_CONFIG = "Waitlist service is not configured. Please try again later.";
8
- const WAITLIST_SEND_ERROR = "Failed to join waitlist. Please try again later or contact us directly.";
9
- const joinWaitlist = async (formData) => {
10
- const email = (formData.get("email") ?? "").toString().trim();
11
- if (!email || !email.includes("@")) return {
12
- success: false,
13
- text: "Please enter a valid email address."
14
- };
15
- const configResult = getEmailConfig();
16
- if (!configResult.ok || !configResult.config) return {
17
- success: false,
18
- text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG
19
- };
20
- const waitlistText = `
119
+ // src/libs/email/waitlist.ts
120
+ "use server";
121
+ var WAITLIST_MISSING_CONFIG = "Waitlist service is not configured. Please try again later.";
122
+ var WAITLIST_SEND_ERROR = "Failed to join waitlist. Please try again later or contact us directly.";
123
+ var joinWaitlist = async (formData) => {
124
+ const email = (formData.get("email") ?? "").toString().trim();
125
+ if (!email || !email.includes("@")) {
126
+ return {
127
+ success: false,
128
+ text: "Please enter a valid email address."
129
+ };
130
+ }
131
+ const configResult = getEmailConfig();
132
+ if (!configResult.ok || !configResult.config) {
133
+ return {
134
+ success: false,
135
+ text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG
136
+ };
137
+ }
138
+ const waitlistText = `
21
139
  You're on the waitlist!
22
140
 
23
141
  Thanks for joining the ContractSpec waitlist. You're now in line for early access to:
24
142
 
25
- Stabilize your AI-generated code with ContractSpec
26
- Multi-surface consistency (API, DB, UI, events)
27
- Safe regeneration without breaking changes
28
- AI governance and contract enforcement
143
+ \u2022 Stabilize your AI-generated code with ContractSpec
144
+ \u2022 Multi-surface consistency (API, DB, UI, events)
145
+ \u2022 Safe regeneration without breaking changes
146
+ \u2022 AI governance and contract enforcement
29
147
 
30
148
  We'll notify you as soon as early access is available. In the meantime, you can:
31
149
 
32
- Check out our docs: https://contractspec.io/docs
33
- Follow our progress on GitHub
34
- Book a demo call to see ContractSpec in action
150
+ \u2022 Check out our docs: https://contractspec.io/docs
151
+ \u2022 Follow our progress on GitHub
152
+ \u2022 Book a demo call to see ContractSpec in action
35
153
 
36
154
  We're excited to have you on board!
37
155
 
@@ -41,11 +159,7 @@ https://contractspec.io
41
159
 
42
160
  To remove yourself from the waitlist, reply to this email with "remove"
43
161
  `.trim();
44
- if (!(await sendEmail(configResult.config, {
45
- to: [{ email }],
46
- subject: "You're on the ContractSpec waitlist!",
47
- text: waitlistText,
48
- html: `
162
+ const waitlistHtml = `
49
163
  <div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
50
164
  <h1 style="color: #8b5cf6;">You're on the waitlist!</h1>
51
165
  <p>Thanks for joining the ContractSpec waitlist. You're now in line for early access to:</p>
@@ -71,35 +185,36 @@ To remove yourself from the waitlist, reply to this email with "remove"
71
185
  To remove yourself from the waitlist, reply to this email with "remove"
72
186
  </p>
73
187
  </div>
74
- `,
75
- context: "waitlist-welcome"
76
- })).success) return {
77
- success: false,
78
- text: WAITLIST_SEND_ERROR
79
- };
80
- const teamNotificationText = `New waitlist signup from: ${email}`;
81
- const teamNotificationHtml = `
188
+ `;
189
+ const userSend = await sendEmail(configResult.config, {
190
+ to: [{ email }],
191
+ subject: "You're on the ContractSpec waitlist!",
192
+ text: waitlistText,
193
+ html: waitlistHtml,
194
+ context: "waitlist-welcome"
195
+ });
196
+ if (!userSend.success) {
197
+ return { success: false, text: WAITLIST_SEND_ERROR };
198
+ }
199
+ const teamNotificationText = `New waitlist signup from: ${email}`;
200
+ const teamNotificationHtml = `
82
201
  <div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
83
202
  <p style="margin: 0 0 8px;">New waitlist signup</p>
84
203
  <p style="margin: 0;"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>
85
204
  </div>
86
205
  `;
87
- if (!(await sendEmail(configResult.config, {
88
- to: [configResult.config.teamInbox],
89
- subject: `New Waitlist Signup: ${email}`,
90
- text: teamNotificationText,
91
- html: teamNotificationHtml,
92
- context: "waitlist-team-notification"
93
- })).success) return {
94
- success: false,
95
- text: WAITLIST_SEND_ERROR
96
- };
97
- return {
98
- success: true,
99
- text: "Successfully joined waitlist!"
100
- };
206
+ const teamSend = await sendEmail(configResult.config, {
207
+ to: [configResult.config.teamInbox],
208
+ subject: `New Waitlist Signup: ${email}`,
209
+ text: teamNotificationText,
210
+ html: teamNotificationHtml,
211
+ context: "waitlist-team-notification"
212
+ });
213
+ if (!teamSend.success) {
214
+ return { success: false, text: WAITLIST_SEND_ERROR };
215
+ }
216
+ return { success: true, text: "Successfully joined waitlist!" };
217
+ };
218
+ export {
219
+ joinWaitlist
101
220
  };
102
-
103
- //#endregion
104
- export { joinWaitlist };
105
- //# sourceMappingURL=waitlist.js.map
@@ -1,22 +1,19 @@
1
- //#region src/libs/pricing-examples.d.ts
2
1
  /**
3
2
  * Tentative pricing example values for UI display.
4
3
  * These are examples only and subject to change based on learnings from design partners.
5
4
  */
6
- declare const PRICING_EXAMPLES: {
7
- readonly free: {
8
- readonly regenerationsPerMonth: 200;
9
- readonly aiActionsPerMonth: 100;
10
- readonly projects: 1;
11
- };
12
- readonly builder: {
13
- readonly regenerationsPerMonthHint: "1,000–2,000+";
14
- readonly aiActionsPerMonthHint: "1,000+";
15
- };
16
- readonly team: {
17
- readonly description: "Higher limits + cheaper per-regen at scale";
18
- };
5
+ export declare const PRICING_EXAMPLES: {
6
+ readonly free: {
7
+ readonly regenerationsPerMonth: 200;
8
+ readonly aiActionsPerMonth: 100;
9
+ readonly projects: 1;
10
+ };
11
+ readonly builder: {
12
+ readonly regenerationsPerMonthHint: "1,000–2,000+";
13
+ readonly aiActionsPerMonthHint: "1,000+";
14
+ };
15
+ readonly team: {
16
+ readonly description: "Higher limits + cheaper per-regen at scale";
17
+ };
19
18
  };
20
- //#endregion
21
- export { PRICING_EXAMPLES };
22
19
  //# sourceMappingURL=pricing-examples.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pricing-examples.d.ts","names":[],"sources":["../../src/libs/pricing-examples.ts"],"mappings":";;AAKA;;;cAAa,gBAAA;EAAA"}
1
+ {"version":3,"file":"pricing-examples.d.ts","sourceRoot":"","sources":["../../src/libs/pricing-examples.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;CAanB,CAAC"}
@@ -1,21 +1,21 @@
1
- //#region src/libs/pricing-examples.ts
2
- /**
3
- * Tentative pricing example values for UI display.
4
- * These are examples only and subject to change based on learnings from design partners.
5
- */
6
- const PRICING_EXAMPLES = {
7
- free: {
8
- regenerationsPerMonth: 200,
9
- aiActionsPerMonth: 100,
10
- projects: 1
11
- },
12
- builder: {
13
- regenerationsPerMonthHint: "1,000–2,000+",
14
- aiActionsPerMonthHint: "1,000+"
15
- },
16
- team: { description: "Higher limits + cheaper per-regen at scale" }
17
- };
1
+ // @bun
2
+ var __require = import.meta.require;
18
3
 
19
- //#endregion
20
- export { PRICING_EXAMPLES };
21
- //# sourceMappingURL=pricing-examples.js.map
4
+ // src/libs/pricing-examples.ts
5
+ var PRICING_EXAMPLES = {
6
+ free: {
7
+ regenerationsPerMonth: 200,
8
+ aiActionsPerMonth: 100,
9
+ projects: 1
10
+ },
11
+ builder: {
12
+ regenerationsPerMonthHint: "1,000\u20132,000+",
13
+ aiActionsPerMonthHint: "1,000+"
14
+ },
15
+ team: {
16
+ description: "Higher limits + cheaper per-regen at scale"
17
+ }
18
+ };
19
+ export {
20
+ PRICING_EXAMPLES
21
+ };