@drawbridge/drawbridge-utils 0.0.151 → 0.0.153

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.
@@ -1,4 +1,4 @@
1
- import { connections, mergeSettings } from './connections/index.cjs';
1
+ import { vendors, mergeSettings, connections } from './connections/index.cjs';
2
2
  import { decrypt, encrypt } from './encrypt.cjs';
3
3
  import { slugify } from './slugify.cjs';
4
4
  import './connections/oauth.cjs';
@@ -58,27 +58,26 @@ import 'slugify';
58
58
  // `requires` and auth.oauth.client did not have to change when the storage
59
59
  // moved into the database.
60
60
  //
61
- // So the declaration lives on the manifest as `provider : { fields }`, build()
62
- // checks its shape at import, and this module is now only the reading, memoizing
63
- // and encrypting around it.
61
+ // A manifest declares the fields it spends under `provider.vendors.<vendor>`,
62
+ // connections/index.js merges every manifest's declarations into one entry per
63
+ // vendor, and this module is only the reading, memoizing and encrypting around
64
+ // that. The `provider` collection is keyed the same way: one row per vendor.
64
65
  //
65
- // Object.hasOwn, not `connections[ slug ] ||` — a bare property read walks the
66
- // prototype chain, and connections[ 'constructor' ] is a function whose .length
67
- // is 1, so the route's "does this vendor exist" guard passed for it and reached
68
- // the database before throwing.
66
+ // Object.hasOwn, not `vendors[ slug ] ||` — a bare property read walks the
67
+ // prototype chain, and vendors[ 'constructor' ] is a function whose .length is
68
+ // 1, so the route's "does this vendor exist" guard passed for it and reached the
69
+ // database before throwing.
69
70
  const providerFields = ( slug ) => (
70
- Object.hasOwn( connections, slug ) ? ( connections[ slug ].provider?.fields || [] ) : []
71
+ Object.hasOwn( vendors, slug ) ? vendors[ slug ].fields : []
71
72
  );
72
73
 
73
74
  // The vendors an admin can configure, in a stable order.
74
75
  //
75
- // DERIVED FROM WHO DECLARES A PROVIDER BLOCK, not from the catalog: `webhook` is
76
- // a connection with no vendor behind it — nothing to authenticate against and
76
+ // DERIVED FROM WHO DECLARES A VENDOR, not from the catalog: `webhook` is a
77
+ // connection with no vendor behind it — nothing to authenticate against and
77
78
  // nothing to type — so it must not appear on a screen whose whole purpose is
78
79
  // entering credentials.
79
- const providerSlugs = () => Object.keys( connections )
80
- .filter( ( slug ) => connections[ slug ].provider )
81
- .sort();
80
+ const providerSlugs = () => Object.keys( vendors ).sort();
82
81
 
83
82
  // LIVE IS DERIVED, never stored. A stored flag is a second thing to keep in
84
83
  // sync and goes stale the moment a row is edited by hand.
@@ -171,6 +170,29 @@ const providerSettings = async ({ controller, slug }) => {
171
170
 
172
171
  };
173
172
 
173
+ // EVERYTHING A CONNECTION SPENDS, merged across the vendors its manifest
174
+ // declares. `drawbridge` reads SendGrid, Twilio and HubSpot as one object, the
175
+ // way it did when they sat on one row — the row split, the readers did not.
176
+ //
177
+ // Safe to merge because build() refuses a manifest whose vendors share a field
178
+ // key. Each vendor read is memoized on its own, so three vendors are three Map
179
+ // lookups inside the window.
180
+ const vendorSettings = async ({ controller, slug }) => {
181
+
182
+ const declared = Object.hasOwn( connections, slug ) ? Object.keys( connections[ slug ].provider?.vendors || {} ) : [];
183
+
184
+ let merged = {};
185
+
186
+ for( const vendor of declared ){
187
+
188
+ merged = { ...merged, ...await providerSettings({ controller, slug : vendor }) };
189
+
190
+ }
191
+
192
+ return merged;
193
+
194
+ };
195
+
174
196
  // Write a vendor's credentials.
175
197
  //
176
198
  // ONLY THE DECLARED FIELDS. The body arrives over the wire, so anything in it
@@ -325,4 +347,4 @@ const providerCredentials = async ({ controller }) => {
325
347
 
326
348
  };
327
349
 
328
- export { clearProviderMemo, isLive, mask, providerCredentials, providerEnvNames, providerFields, providerMemo, providerSettings, providerSlugs, saveProviderSettings };
350
+ export { clearProviderMemo, isLive, mask, providerCredentials, providerEnvNames, providerFields, providerMemo, providerSettings, providerSlugs, saveProviderSettings, vendorSettings, vendors };
@@ -1,4 +1,4 @@
1
- import { connections, mergeSettings } from './connections/index.js';
1
+ import { vendors, mergeSettings, connections } from './connections/index.js';
2
2
  import { decrypt, encrypt } from './encrypt.js';
3
3
  import { slugify } from './slugify.js';
4
4
  import './connections/oauth.js';
@@ -58,27 +58,26 @@ import 'slugify';
58
58
  // `requires` and auth.oauth.client did not have to change when the storage
59
59
  // moved into the database.
60
60
  //
61
- // So the declaration lives on the manifest as `provider : { fields }`, build()
62
- // checks its shape at import, and this module is now only the reading, memoizing
63
- // and encrypting around it.
61
+ // A manifest declares the fields it spends under `provider.vendors.<vendor>`,
62
+ // connections/index.js merges every manifest's declarations into one entry per
63
+ // vendor, and this module is only the reading, memoizing and encrypting around
64
+ // that. The `provider` collection is keyed the same way: one row per vendor.
64
65
  //
65
- // Object.hasOwn, not `connections[ slug ] ||` — a bare property read walks the
66
- // prototype chain, and connections[ 'constructor' ] is a function whose .length
67
- // is 1, so the route's "does this vendor exist" guard passed for it and reached
68
- // the database before throwing.
66
+ // Object.hasOwn, not `vendors[ slug ] ||` — a bare property read walks the
67
+ // prototype chain, and vendors[ 'constructor' ] is a function whose .length is
68
+ // 1, so the route's "does this vendor exist" guard passed for it and reached the
69
+ // database before throwing.
69
70
  const providerFields = ( slug ) => (
70
- Object.hasOwn( connections, slug ) ? ( connections[ slug ].provider?.fields || [] ) : []
71
+ Object.hasOwn( vendors, slug ) ? vendors[ slug ].fields : []
71
72
  );
72
73
 
73
74
  // The vendors an admin can configure, in a stable order.
74
75
  //
75
- // DERIVED FROM WHO DECLARES A PROVIDER BLOCK, not from the catalog: `webhook` is
76
- // a connection with no vendor behind it — nothing to authenticate against and
76
+ // DERIVED FROM WHO DECLARES A VENDOR, not from the catalog: `webhook` is a
77
+ // connection with no vendor behind it — nothing to authenticate against and
77
78
  // nothing to type — so it must not appear on a screen whose whole purpose is
78
79
  // entering credentials.
79
- const providerSlugs = () => Object.keys( connections )
80
- .filter( ( slug ) => connections[ slug ].provider )
81
- .sort();
80
+ const providerSlugs = () => Object.keys( vendors ).sort();
82
81
 
83
82
  // LIVE IS DERIVED, never stored. A stored flag is a second thing to keep in
84
83
  // sync and goes stale the moment a row is edited by hand.
@@ -171,6 +170,29 @@ const providerSettings = async ({ controller, slug }) => {
171
170
 
172
171
  };
173
172
 
173
+ // EVERYTHING A CONNECTION SPENDS, merged across the vendors its manifest
174
+ // declares. `drawbridge` reads SendGrid, Twilio and HubSpot as one object, the
175
+ // way it did when they sat on one row — the row split, the readers did not.
176
+ //
177
+ // Safe to merge because build() refuses a manifest whose vendors share a field
178
+ // key. Each vendor read is memoized on its own, so three vendors are three Map
179
+ // lookups inside the window.
180
+ const vendorSettings = async ({ controller, slug }) => {
181
+
182
+ const declared = Object.hasOwn( connections, slug ) ? Object.keys( connections[ slug ].provider?.vendors || {} ) : [];
183
+
184
+ let merged = {};
185
+
186
+ for( const vendor of declared ){
187
+
188
+ merged = { ...merged, ...await providerSettings({ controller, slug : vendor }) };
189
+
190
+ }
191
+
192
+ return merged;
193
+
194
+ };
195
+
174
196
  // Write a vendor's credentials.
175
197
  //
176
198
  // ONLY THE DECLARED FIELDS. The body arrives over the wire, so anything in it
@@ -325,4 +347,4 @@ const providerCredentials = async ({ controller }) => {
325
347
 
326
348
  };
327
349
 
328
- export { clearProviderMemo, isLive, mask, providerCredentials, providerEnvNames, providerFields, providerMemo, providerSettings, providerSlugs, saveProviderSettings };
350
+ export { clearProviderMemo, isLive, mask, providerCredentials, providerEnvNames, providerFields, providerMemo, providerSettings, providerSlugs, saveProviderSettings, vendorSettings, vendors };