@geekmidas/manifest 10.0.0-alpha.139 → 10.0.0-alpha.140

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.cjs CHANGED
@@ -79,6 +79,7 @@ const PUBLIC = {
79
79
  objects: [],
80
80
  "file-server": ["url"],
81
81
  email: ["inboxUrl"],
82
+ inbox: [],
82
83
  database: [],
83
84
  "database-reader": [],
84
85
  "database-schema": [],
@@ -1119,6 +1120,65 @@ var NoUrlForStage = class extends Error {
1119
1120
  */
1120
1121
  const CLIENT_IP_HEADER = "x-gkm-client-ip";
1121
1122
  //#endregion
1123
+ //#region src/inbox.ts
1124
+ /** The event type a received message is announced as on its inbox's topic. */
1125
+ const INBOX_EVENT = "email.received";
1126
+ /**
1127
+ * Where an inbox's raw messages are kept in its bucket: SES's S3 action
1128
+ * writes `<prefix><message id>`, and `gkm dev` and the test mailbox write the
1129
+ * same layout.
1130
+ */
1131
+ const INBOX_MESSAGES_PREFIX = "messages/";
1132
+ /**
1133
+ * The recipient `address` is to `inbox` on `domain`, or `undefined` when the
1134
+ * inbox does not receive at it.
1135
+ *
1136
+ * - The local part is a declared address, or one with a `+tag` after it.
1137
+ * - Without `subdomains`, the domain is the stage's domain itself; with it,
1138
+ * exactly one label in front of the stage's domain — `acme.fixwell.example`
1139
+ * — and never the bare domain, whose mail would belong to no tenant.
1140
+ *
1141
+ * Case-insensitive, as mail addresses are in practice.
1142
+ */
1143
+ function inboxRecipient(address, inbox, domain) {
1144
+ const normalized = address.trim().toLowerCase();
1145
+ const at = normalized.lastIndexOf("@");
1146
+ if (at <= 0) return void 0;
1147
+ const localPart = normalized.slice(0, at);
1148
+ const host = normalized.slice(at + 1);
1149
+ const base = domain.toLowerCase();
1150
+ let subdomain;
1151
+ if (inbox.subdomains) {
1152
+ if (!host.endsWith(`.${base}`)) return void 0;
1153
+ subdomain = host.slice(0, -(base.length + 1));
1154
+ if (!subdomain || subdomain.includes(".")) return void 0;
1155
+ } else if (host !== base) return;
1156
+ const plus = localPart.indexOf("+");
1157
+ const local = plus === -1 ? localPart : localPart.slice(0, plus);
1158
+ const tag = plus === -1 ? void 0 : localPart.slice(plus + 1);
1159
+ if (!inbox.addresses.some((declared) => declared.toLowerCase() === local)) return;
1160
+ return {
1161
+ address: normalized,
1162
+ local,
1163
+ ...tag ? { tag } : {},
1164
+ ...subdomain ? { subdomain } : {}
1165
+ };
1166
+ }
1167
+ /**
1168
+ * The recipients a deployed receipt rule names for `inbox` on `domain`.
1169
+ *
1170
+ * Without `subdomains`, each address on the domain: SES matches an address
1171
+ * condition's `+label` variants too, so `requests@` takes `requests+t_8f3k@`.
1172
+ * With it, every subdomain (`.fixwell.example`): a condition cannot say
1173
+ * "`requests` on any subdomain", so the rule takes the subdomains' mail and
1174
+ * the decoder in front of the handler drops what {@link inboxRecipient} does
1175
+ * not match.
1176
+ */
1177
+ function receiptRecipients(inbox, domain) {
1178
+ const base = domain.toLowerCase();
1179
+ return inbox.subdomains ? [`.${base}`] : inbox.addresses.map((address) => `${address.toLowerCase()}@${base}`);
1180
+ }
1181
+ //#endregion
1122
1182
  //#region src/migrations.ts
1123
1183
  /** Where every construct's folder lives, from the project root. */
1124
1184
  const MIGRATIONS_ROOT = "db";
@@ -1319,6 +1379,8 @@ exports.DEFAULT_POSTGRES_VERSION = DEFAULT_POSTGRES_VERSION;
1319
1379
  exports.DEFAULT_STAGE_URL = DEFAULT_STAGE_URL;
1320
1380
  exports.DERIVED_PREFIX = DERIVED_PREFIX;
1321
1381
  exports.DERIVES_FROM = DERIVES_FROM;
1382
+ exports.INBOX_EVENT = INBOX_EVENT;
1383
+ exports.INBOX_MESSAGES_PREFIX = INBOX_MESSAGES_PREFIX;
1322
1384
  exports.IllegalDerivation = IllegalDerivation;
1323
1385
  exports.InvalidConstructId = InvalidConstructId;
1324
1386
  exports.KMS_SCHEME = KMS_SCHEME;
@@ -1343,6 +1405,7 @@ exports.dependentsOf = dependentsOf;
1343
1405
  exports.drawSecret = drawSecret;
1344
1406
  exports.environmentCase = environmentCase;
1345
1407
  exports.externalApiUrl = externalApiUrl;
1408
+ exports.inboxRecipient = inboxRecipient;
1346
1409
  exports.isDerived = isDerived;
1347
1410
  exports.isWebOrigin = isWebOrigin;
1348
1411
  exports.isWildcardSite = isWildcardSite;
@@ -1355,6 +1418,7 @@ exports.provideKey = provideKey;
1355
1418
  exports.providedKeyFor = providedKeyFor;
1356
1419
  exports.provisionOrder = provisionOrder;
1357
1420
  exports.publicEnvFor = publicEnvFor;
1421
+ exports.receiptRecipients = receiptRecipients;
1358
1422
  exports.schemeBase = schemeBase;
1359
1423
  exports.scopedName = scopedName;
1360
1424
  exports.seedFolder = seedFolder;