1- import { buildClient , ClientConfigOptions } from '../packages/dashboard-client' ;
2-
31import { fetch as ponyfillFetch } from '@whatwg-node/fetch' ;
2+ import {
3+ ApiError ,
4+ buildClient ,
5+ Client ,
6+ ClientConfigOptions ,
7+ } from '../packages/dashboard-client' ;
48
59const fetchFn = typeof fetch === 'undefined' ? ponyfillFetch : fetch ;
610
@@ -9,27 +13,77 @@ export const baseConfigOptions: Partial<ClientConfigOptions> = {
913 fetchFn,
1014} ;
1115
16+ function shuffleArray < T > ( source : T [ ] ) {
17+ const array = [ ...source ] ;
18+
19+ for ( let i = array . length - 1 ; i > 0 ; i -- ) {
20+ const j = Math . floor ( Math . random ( ) * ( i + 1 ) ) ;
21+ const temp = array [ i ] ;
22+ array [ i ] = array [ j ] ;
23+ array [ j ] = temp ;
24+ }
25+ return array ;
26+ }
27+
1228export async function generateNewDashboardClient (
1329 extraConfig ?: Partial < ClientConfigOptions > ,
14- ) {
15- const randomString =
16- Math . random ( ) . toString ( 36 ) . substring ( 7 ) + new Date ( ) . getTime ( ) ;
17-
18- const client = buildClient ( {
19- apiToken : null ,
20- ...baseConfigOptions ,
21- } ) ;
22-
23- const account = await client . account . create ( {
24- email : `${ randomString } @delete-this-at-midnight-utc.tk` ,
25- password : 'STRONG_pass123!' ,
26- first_name : 'Test' ,
27- company : 'DatoCMS' ,
28- } ) ;
29-
30- return buildClient ( {
31- ...extraConfig ,
32- apiToken : account . id ,
33- ...baseConfigOptions ,
34- } ) ;
30+ ) : Promise < Client > {
31+ if ( process . env . DATOCMS_SESSION_ID ) {
32+ return buildClient ( {
33+ ...extraConfig ,
34+ apiToken : process . env . DATOCMS_SESSION_ID ,
35+ organization : process . env . DATOCMS_ORGANIZATION_ID ,
36+ ...baseConfigOptions ,
37+ } ) ;
38+ }
39+
40+ if (
41+ ! process . env . DATOCMS_ACCOUNT_EMAIL ||
42+ ! process . env . DATOCMS_ACCOUNT_PASSWORD
43+ ) {
44+ throw new Error (
45+ 'DATOCMS_ACCOUNT_EMAIL, DATOCMS_ACCOUNT_PASSWORD (and optionally DATOCMS_ORGANIZATION_ID) environment variables must be set on .env file!' ,
46+ ) ;
47+ }
48+
49+ // To avoid incurring in rate limits, a pool of accouts that share the same
50+ // password and organization membership can be used.
51+
52+ const emails = shuffleArray (
53+ process . env . DATOCMS_ACCOUNT_EMAIL . split ( / \s * , \s * / ) ,
54+ ) ;
55+
56+ for ( const email of emails ) {
57+ const client = buildClient ( {
58+ ...extraConfig ,
59+ apiToken : null ,
60+ autoRetry : false ,
61+ ...baseConfigOptions ,
62+ } ) ;
63+
64+ try {
65+ const account = await client . session . rawCreate ( {
66+ data : {
67+ type : 'email_credentials' ,
68+ attributes : {
69+ email : email ,
70+ password : process . env . DATOCMS_ACCOUNT_PASSWORD ,
71+ } ,
72+ } ,
73+ } ) ;
74+
75+ process . env . DATOCMS_SESSION_ID = account . data . id ;
76+
77+ return generateNewDashboardClient ( extraConfig ) ;
78+ } catch ( e ) {
79+ // Let's try with next account
80+ if ( e instanceof ApiError && e . findError ( 'RATE_LIMIT_EXCEEDED' ) ) {
81+ continue ;
82+ }
83+
84+ throw e ;
85+ }
86+ }
87+
88+ throw new Error ( 'Account pool exhausted!' ) ;
3589}
0 commit comments