@drawbridge/drawbridge-utils 0.0.165 → 0.0.167

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/sendgrid.cjs CHANGED
@@ -116,6 +116,7 @@ var sendgridRequest = ({ apiKey, body, method, path, query, request: request2 =
116
116
  var dnsRows = (dns) => Object.values(dns || {}).filter((row) => (row == null ? void 0 : row.host) && (row == null ? void 0 : row.type)).map((row) => ({
117
117
  data: String(row.data ?? ""),
118
118
  host: String(row.host),
119
+ reason: row.reason ? String(row.reason) : null,
119
120
  type: String(row.type),
120
121
  valid: typeof row.valid === "boolean" ? row.valid : null
121
122
  }));
@@ -141,14 +142,27 @@ var domain = {
141
142
  // Asks SendGrid to look the records up now. `records` carries per-record
142
143
  // validity so a UI can say WHICH record has not landed rather than only that
143
144
  // something has not; `valid` is the whole domain's verdict.
145
+ //
146
+ // TWO CALLS, because SendGrid splits the answer. POST …/validate is what
147
+ // makes it look DNS up now, and it answers per KEY with only `valid` and
148
+ // `reason` — no host, type or data (docs: validation_results.mail_cname /
149
+ // dkim1 / dkim2 / spf, each { valid, reason }). The rows themselves live on
150
+ // the domain, GET …/domains/:id, keyed the same way with host/type/data
151
+ // (and a `valid` of its own, which the validate verdict overrides). Feeding
152
+ // validation_results straight to dnsRows filtered every entry out for want
153
+ // of a host, so this returned `records : []` and no check ever updated a
154
+ // record — the verdicts on screen were the ones from registration.
144
155
  validate: async ({ apiKey, reference, via = sendgridRequest }) => {
145
- const result = await via({
146
- apiKey,
147
- method: "POST",
148
- path: "/v3/whitelabel/domains/" + encodeURIComponent(reference) + "/validate"
149
- });
156
+ const path = "/v3/whitelabel/domains/" + encodeURIComponent(reference);
157
+ const result = await via({ apiKey, method: "POST", path: path + "/validate" });
158
+ const doc = await via({ apiKey, method: "GET", path });
159
+ const verdicts = (result == null ? void 0 : result.validation_results) || {};
160
+ const merged = Object.fromEntries(Object.entries((doc == null ? void 0 : doc.dns) || {}).map(([key, row]) => [
161
+ key,
162
+ { ...row, ...verdicts[key] && { reason: verdicts[key].reason, valid: verdicts[key].valid } }
163
+ ]));
150
164
  return {
151
- records: dnsRows(result == null ? void 0 : result.validation_results),
165
+ records: dnsRows(merged),
152
166
  valid: Boolean(result == null ? void 0 : result.valid)
153
167
  };
154
168
  }
@@ -115,11 +115,20 @@ const sendgridRequest = ({ apiKey, body, method, path, query, request: request$1
115
115
  // flattened to the rows the identity schema stores — the UI then renders
116
116
  // whatever came back instead of naming roles it would have to keep in step
117
117
  // with.
118
+ //
119
+ // `reason` is SendGrid's own sentence for a record that does not validate —
120
+ // "Expected your MX record to be … but found …" — and null when it does. It
121
+ // is what tells a merchant their VALUE is wrong (a typo, a proxied CNAME)
122
+ // rather than that DNS is still propagating, so it is kept verbatim and shown
123
+ // beside the record. Never classified: the docs define it only as a
124
+ // description, and a badge that pattern-matched vendor prose would be right
125
+ // until a sentence changed.
118
126
  const dnsRows = ( dns ) => Object.values( dns || {} )
119
127
  .filter( ( row ) => row?.host && row?.type )
120
128
  .map( ( row ) => ({
121
129
  data : String( row.data ?? '' ),
122
130
  host : String( row.host ),
131
+ reason : row.reason ? String( row.reason ) : null,
123
132
  type : String( row.type ),
124
133
  valid : typeof row.valid === 'boolean' ? row.valid : null
125
134
  }) );
@@ -160,16 +169,33 @@ const domain = {
160
169
  // Asks SendGrid to look the records up now. `records` carries per-record
161
170
  // validity so a UI can say WHICH record has not landed rather than only that
162
171
  // something has not; `valid` is the whole domain's verdict.
172
+ //
173
+ // TWO CALLS, because SendGrid splits the answer. POST …/validate is what
174
+ // makes it look DNS up now, and it answers per KEY with only `valid` and
175
+ // `reason` — no host, type or data (docs: validation_results.mail_cname /
176
+ // dkim1 / dkim2 / spf, each { valid, reason }). The rows themselves live on
177
+ // the domain, GET …/domains/:id, keyed the same way with host/type/data
178
+ // (and a `valid` of its own, which the validate verdict overrides). Feeding
179
+ // validation_results straight to dnsRows filtered every entry out for want
180
+ // of a host, so this returned `records : []` and no check ever updated a
181
+ // record — the verdicts on screen were the ones from registration.
163
182
  validate : async ({ apiKey, reference, via = sendgridRequest }) => {
164
183
 
165
- const result = await via({
166
- apiKey,
167
- method : 'POST',
168
- path : '/v3/whitelabel/domains/' + encodeURIComponent( reference ) + '/validate'
169
- });
184
+ const path = '/v3/whitelabel/domains/' + encodeURIComponent( reference );
185
+
186
+ const result = await via({ apiKey, method : 'POST', path : path + '/validate' });
187
+ const doc = await via({ apiKey, method : 'GET', path });
188
+
189
+ const verdicts = result?.validation_results || {};
190
+
191
+ // `spf` has a verdict but no row; the host/type filter in dnsRows drops it.
192
+ const merged = Object.fromEntries( Object.entries( doc?.dns || {} ).map( ( [ key, row ] ) => [
193
+ key,
194
+ { ...row, ...( verdicts[ key ] && { reason : verdicts[ key ].reason, valid : verdicts[ key ].valid } ) }
195
+ ] ) );
170
196
 
171
197
  return {
172
- records : dnsRows( result?.validation_results ),
198
+ records : dnsRows( merged ),
173
199
  valid : Boolean( result?.valid )
174
200
  };
175
201
 
@@ -115,11 +115,20 @@ const sendgridRequest = ({ apiKey, body, method, path, query, request: request$1
115
115
  // flattened to the rows the identity schema stores — the UI then renders
116
116
  // whatever came back instead of naming roles it would have to keep in step
117
117
  // with.
118
+ //
119
+ // `reason` is SendGrid's own sentence for a record that does not validate —
120
+ // "Expected your MX record to be … but found …" — and null when it does. It
121
+ // is what tells a merchant their VALUE is wrong (a typo, a proxied CNAME)
122
+ // rather than that DNS is still propagating, so it is kept verbatim and shown
123
+ // beside the record. Never classified: the docs define it only as a
124
+ // description, and a badge that pattern-matched vendor prose would be right
125
+ // until a sentence changed.
118
126
  const dnsRows = ( dns ) => Object.values( dns || {} )
119
127
  .filter( ( row ) => row?.host && row?.type )
120
128
  .map( ( row ) => ({
121
129
  data : String( row.data ?? '' ),
122
130
  host : String( row.host ),
131
+ reason : row.reason ? String( row.reason ) : null,
123
132
  type : String( row.type ),
124
133
  valid : typeof row.valid === 'boolean' ? row.valid : null
125
134
  }) );
@@ -160,16 +169,33 @@ const domain = {
160
169
  // Asks SendGrid to look the records up now. `records` carries per-record
161
170
  // validity so a UI can say WHICH record has not landed rather than only that
162
171
  // something has not; `valid` is the whole domain's verdict.
172
+ //
173
+ // TWO CALLS, because SendGrid splits the answer. POST …/validate is what
174
+ // makes it look DNS up now, and it answers per KEY with only `valid` and
175
+ // `reason` — no host, type or data (docs: validation_results.mail_cname /
176
+ // dkim1 / dkim2 / spf, each { valid, reason }). The rows themselves live on
177
+ // the domain, GET …/domains/:id, keyed the same way with host/type/data
178
+ // (and a `valid` of its own, which the validate verdict overrides). Feeding
179
+ // validation_results straight to dnsRows filtered every entry out for want
180
+ // of a host, so this returned `records : []` and no check ever updated a
181
+ // record — the verdicts on screen were the ones from registration.
163
182
  validate : async ({ apiKey, reference, via = sendgridRequest }) => {
164
183
 
165
- const result = await via({
166
- apiKey,
167
- method : 'POST',
168
- path : '/v3/whitelabel/domains/' + encodeURIComponent( reference ) + '/validate'
169
- });
184
+ const path = '/v3/whitelabel/domains/' + encodeURIComponent( reference );
185
+
186
+ const result = await via({ apiKey, method : 'POST', path : path + '/validate' });
187
+ const doc = await via({ apiKey, method : 'GET', path });
188
+
189
+ const verdicts = result?.validation_results || {};
190
+
191
+ // `spf` has a verdict but no row; the host/type filter in dnsRows drops it.
192
+ const merged = Object.fromEntries( Object.entries( doc?.dns || {} ).map( ( [ key, row ] ) => [
193
+ key,
194
+ { ...row, ...( verdicts[ key ] && { reason : verdicts[ key ].reason, valid : verdicts[ key ].valid } ) }
195
+ ] ) );
170
196
 
171
197
  return {
172
- records : dnsRows( result?.validation_results ),
198
+ records : dnsRows( merged ),
173
199
  valid : Boolean( result?.valid )
174
200
  };
175
201
 
package/dist/sendgrid.js CHANGED
@@ -87,6 +87,7 @@ var sendgridRequest = ({ apiKey, body, method, path, query, request: request2 =
87
87
  var dnsRows = (dns) => Object.values(dns || {}).filter((row) => (row == null ? void 0 : row.host) && (row == null ? void 0 : row.type)).map((row) => ({
88
88
  data: String(row.data ?? ""),
89
89
  host: String(row.host),
90
+ reason: row.reason ? String(row.reason) : null,
90
91
  type: String(row.type),
91
92
  valid: typeof row.valid === "boolean" ? row.valid : null
92
93
  }));
@@ -112,14 +113,27 @@ var domain = {
112
113
  // Asks SendGrid to look the records up now. `records` carries per-record
113
114
  // validity so a UI can say WHICH record has not landed rather than only that
114
115
  // something has not; `valid` is the whole domain's verdict.
116
+ //
117
+ // TWO CALLS, because SendGrid splits the answer. POST …/validate is what
118
+ // makes it look DNS up now, and it answers per KEY with only `valid` and
119
+ // `reason` — no host, type or data (docs: validation_results.mail_cname /
120
+ // dkim1 / dkim2 / spf, each { valid, reason }). The rows themselves live on
121
+ // the domain, GET …/domains/:id, keyed the same way with host/type/data
122
+ // (and a `valid` of its own, which the validate verdict overrides). Feeding
123
+ // validation_results straight to dnsRows filtered every entry out for want
124
+ // of a host, so this returned `records : []` and no check ever updated a
125
+ // record — the verdicts on screen were the ones from registration.
115
126
  validate: async ({ apiKey, reference, via = sendgridRequest }) => {
116
- const result = await via({
117
- apiKey,
118
- method: "POST",
119
- path: "/v3/whitelabel/domains/" + encodeURIComponent(reference) + "/validate"
120
- });
127
+ const path = "/v3/whitelabel/domains/" + encodeURIComponent(reference);
128
+ const result = await via({ apiKey, method: "POST", path: path + "/validate" });
129
+ const doc = await via({ apiKey, method: "GET", path });
130
+ const verdicts = (result == null ? void 0 : result.validation_results) || {};
131
+ const merged = Object.fromEntries(Object.entries((doc == null ? void 0 : doc.dns) || {}).map(([key, row]) => [
132
+ key,
133
+ { ...row, ...verdicts[key] && { reason: verdicts[key].reason, valid: verdicts[key].valid } }
134
+ ]));
121
135
  return {
122
- records: dnsRows(result == null ? void 0 : result.validation_results),
136
+ records: dnsRows(merged),
123
137
  valid: Boolean(result == null ? void 0 : result.valid)
124
138
  };
125
139
  }
package/package.json CHANGED
@@ -226,5 +226,5 @@
226
226
  "prepublishOnly": ". \"$HOME/.nvm/nvm.sh\" && nvm use && tsup && node --test"
227
227
  },
228
228
  "types": "dist/index.d.ts",
229
- "version": "0.0.165"
229
+ "version": "0.0.167"
230
230
  }