@reddoorla/maintenance 0.40.0 → 0.41.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.
package/dist/index.d.ts CHANGED
@@ -179,6 +179,25 @@ declare function fromAirtableBase(base: AirtableBase, opts?: AirtableInventoryOp
179
179
 
180
180
  type Frequency = "None" | "Monthly" | "Quarterly" | "Yearly";
181
181
  type Status = "in development" | "launch period" | "maintenance" | "hosting" | "probably not our problem" | "deprecated";
182
+ /**
183
+ * Per-site notification routing. When present on a `maintenance` site, the form
184
+ * notification is addressed by the value of a submission field (`field`, read from
185
+ * `extraFields`) — e.g. route a contact form's `interest` to a different recipient
186
+ * per option, always CC-ing a shared address. Absent (`null`) → the site keeps the
187
+ * default single-POC behavior. Recipients live HERE (server-side Airtable config),
188
+ * never supplied by the submitting site, so the ingest can't be turned into an open
189
+ * relay.
190
+ */
191
+ type NotifyRouting = {
192
+ /** The `extraFields` key whose value selects a route, e.g. "interest". */
193
+ field: string;
194
+ /** Field-value → recipient address(es). */
195
+ routes: Record<string, string | string[]>;
196
+ /** Recipient(s) when the value matches no route. */
197
+ default?: string | string[];
198
+ /** Address(es) CC'd on every routed (maintenance) send. */
199
+ cc?: string[];
200
+ };
182
201
  type WebsiteRow = {
183
202
  id: string;
184
203
  name: string;
@@ -247,6 +266,7 @@ type WebsiteRow = {
247
266
  defaultBranchCi: string | null;
248
267
  lastCommitAt: string | null;
249
268
  githubSignalsAt: string | null;
269
+ notifyRouting: NotifyRouting | null;
250
270
  };
251
271
 
252
272
  type ResolvedCopy = {
package/dist/index.js CHANGED
@@ -2620,6 +2620,28 @@ function trimToNull(raw) {
2620
2620
  const trimmed = raw.trim();
2621
2621
  return trimmed.length > 0 ? trimmed : null;
2622
2622
  }
2623
+ function parseNotifyRouting(raw) {
2624
+ if (typeof raw !== "string") return null;
2625
+ const trimmed = raw.trim();
2626
+ if (!trimmed) return null;
2627
+ let parsed;
2628
+ try {
2629
+ parsed = JSON.parse(trimmed);
2630
+ } catch {
2631
+ return null;
2632
+ }
2633
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
2634
+ const o = parsed;
2635
+ if (typeof o.field !== "string" || !o.field.trim()) return null;
2636
+ if (!o.routes || typeof o.routes !== "object" || Array.isArray(o.routes)) return null;
2637
+ const routing = {
2638
+ field: o.field,
2639
+ routes: o.routes
2640
+ };
2641
+ if (o.default !== void 0) routing.default = o.default;
2642
+ if (Array.isArray(o.cc)) routing.cc = o.cc.filter((x) => typeof x === "string");
2643
+ return routing;
2644
+ }
2623
2645
  var ACTIVE_STATUSES = /* @__PURE__ */ new Set([
2624
2646
  "maintenance",
2625
2647
  "launch period"
@@ -2663,6 +2685,7 @@ function mapRow(rec) {
2663
2685
  copyFooter: trimToNull(f["Copy \u2014 Footer"]),
2664
2686
  launchedAt: f["Launched at"] ?? null,
2665
2687
  newsletterWebhook: trimToNull(f["Newsletter Webhook"]),
2688
+ notifyRouting: parseNotifyRouting(f["Notify Routing"]),
2666
2689
  mailchimpApiKey: trimToNull(f["Mailchimp API Key"]),
2667
2690
  mailchimpAudienceId: trimToNull(f["Mailchimp Audience ID"]),
2668
2691
  renovateFailingCis: f["Renovate Failing CIs"] ?? null,