woocommerce/bin/packages/js/components/phone-number-input/build-data.js

132 lines
3.0 KiB
JavaScript

#!/usr/bin/env node
const https = require( 'https' );
const vm = require( 'vm' );
const fs = require( 'fs' );
const path = require( 'path' );
const intlUrl =
'https://raw.githubusercontent.com/jackocnr/intl-tel-input/master/src/js/data.js';
const phoneUrl =
'https://raw.githubusercontent.com/AfterShip/phone/master/src/data/country_phone_data.ts';
const fetch = ( url ) =>
new Promise( ( resolve, reject ) => {
https
.get( url, ( res ) => {
let body = '';
res.on( 'data', ( chunk ) => {
body += chunk;
} );
res.on( 'end', () => {
resolve( body );
} );
} )
.on( 'error', reject );
} );
const numberOrString = ( str ) =>
Number( str ).toString().length !== str.length ? str : Number( str );
const evaluate = ( code ) => {
const script = new vm.Script( code );
const context = vm.createContext();
script.runInContext( context );
return context;
};
const parse = ( data /*: any[]*/ ) /*: DataType*/ =>
data.reduce(
( acc, item ) => ( {
...acc,
[ item[ 0 ] ]: {
alpha2: item[ 0 ],
code: item[ 1 ].toString(),
priority: item[ 2 ] || 0,
start: item[ 3 ]?.map( String ),
lengths: item[ 4 ],
},
} ),
{}
);
const saveToFile = ( data ) => {
const dataString = JSON.stringify( data ).replace( /null/g, '' );
const parseString = parse.toString().replace( / \/\*(.+?)\*\//g, '$1' );
const code = [
'// Do not edit this file directly.',
'// Generated by /bin/packages/js/components/phone-number-input/build-data.js',
'',
'/* eslint-disable */',
'',
'import type { DataType } from "./types";',
'',
`const parse = ${ parseString }`,
'',
`const data = ${ dataString }`,
'',
'export default parse(data);',
].join( '\n' );
const filePath = path.resolve(
'packages/js/components/src/phone-number-input/data.ts'
);
fs.writeFileSync( filePath, code );
};
( async () => {
const intlData = await fetch( intlUrl ).then( evaluate );
const phoneData = await fetch( phoneUrl )
.then( ( data ) => 'var data = ' + data.substring( 15 ) )
.then( evaluate );
// Convert phoneData array to object
const phoneCountries = phoneData.data.reduce(
( acc, item ) => ( {
...acc,
[ item.alpha2.toLowerCase() ]: item,
} ),
{}
);
// Traverse intlData to create a new array with required fields
const countries = intlData.allCountries.map( ( item ) => {
const phoneCountry = phoneCountries[ item.iso2 ];
const result = [
item.iso2.toUpperCase(), // alpha2
Number( item.dialCode ), // code
/* [2] priority */
/* [3] start */
/* [4] lengths */
,
,
,
];
if ( item.priority ) {
result[ 2 ] = item.priority;
}
const areaCodes = item.areaCodes || [];
const beginWith = phoneCountry?.mobile_begin_with || [];
if ( areaCodes.length || beginWith.length ) {
result[ 3 ] = [ ...new Set( [ ...areaCodes, ...beginWith ] ) ].map(
numberOrString
);
}
if ( phoneCountry?.phone_number_lengths ) {
result[ 4 ] = phoneCountry.phone_number_lengths;
}
return result;
} );
saveToFile( countries );
} )();