Setting the file. One moment.
CSV Regional · Rp Source CSV · wix/skills · Skills Docs
ContentsBack to the top of the page 35.11
Shopify
Bundled file
lib/ csv-regional.js
JavaScript · 118 lines · 5 KB
buildSourceRegional
,
12 knownCurrency ,
13 validateSourceRegional ,
14 writeAdapterSourceRegional ,
15 ADAPTER_FILE_NAME ,
16 } = require ( '../../../lib/source-regional.js' );
17 const { ADAPTER_RAW_DIRS } = require ( '../../../lib/source-coverage.js' );
18 const { normalizeHeaderName } = require ( './csv-parse.js' );
19
20 const INTAKE_EVIDENCE = 'intake' ;
21 // Normalized header names that hold a per-row currency code.
22 const CURRENCY_COLUMNS = new Set ([
23 'currency' , 'currencycode' , 'ordercurrency' , 'pricecurrency' , 'presentmentcurrency' , 'currencyiso' , 'iso4217' ,
24 ]);
25
26 // Indexes of the header's currency columns (normalized, exact match).
27 function currencyColumnIndexes ( header ) {
28 const indexes = [];
29 (header || []). forEach (( name , index ) => {
30 if ( CURRENCY_COLUMNS . has ( normalizeHeaderName (name))) indexes. push (index);
31 });
32 return indexes;
33 }
34
35 // Streaming counter: `add(values)` per row, `counts()` at the end. `null` when the file has no
36 // currency column; a blank or non-code cell is not counted (counts hold valid ISO codes only).
37 function createCurrencyCounter ( header ) {
38 const indexes = currencyColumnIndexes (header);
39 const counts = {};
40 return {
41 hasColumn: indexes. length > 0 ,
42 add ( values ) {
43 for ( const index of indexes) {
44 const code = String (values[index] === undefined ? '' : values[index]). trim (). toUpperCase ();
45 if ( knownCurrency (code)) counts[code] = (counts[code] || 0 ) + 1 ;
46 }
47 },
48 counts () { return indexes. length > 0 ? { ... counts } : null ; },
49 };
50 }
51
52 // Sum the per-file counts; `null` when no file had a currency column.
53 function mergeCurrencyCounts ( list ) {
54 let merged = null ;
55 for ( const counts of list) {
56 if ( ! counts) continue ;
57 merged = merged || {};
58 for ( const [ code , n ] of Object. entries (counts)) merged[code] = (merged[code] || 0 ) + n;
59 }
60 return merged;
61 }
62
63 // A person-typed value, trimmed and case-folded to the shape the validators expect. Anything that
64 // still fails validation stays an `unreadable` unknown; nothing is repaired beyond case and space.
65 function clean ( value ) {
66 if (value === undefined || value === null ) return '' ;
67 return String (value). trim ();
68 }
69
70 function supplied ( value , evidence = INTAKE_EVIDENCE , extra = {}) {
71 return value === '' ? undefined : { state: 'supplied' , value, evidence, ... extra };
72 }
73
74 // `supplied`: { currency, timeZone, language, country } -- all optional strings (a `he-IL` language
75 // supplies the locale tag too). Currency-column counts stay in CSV discovery evidence.
76 function buildCsvSourceRegional ({ supplied : input = {}, generatedAt } = {}) {
77 const currency = clean (input.currency). toUpperCase ();
78 const timeZone = clean (input.timeZone);
79 const country = clean (input.country). toUpperCase ();
80 const languageInput = clean (input.language);
81 const tag = / ^ ( [A-Za-z] {2} ) [-_] ( [A-Za-z] {2} ) $ / . exec (languageInput);
82 const language = tag ? tag[ 1 ]. toLowerCase () : languageInput. toLowerCase ();
83 const locale = tag ? `${ tag [ 1 ]. toLowerCase () }-${ tag [ 2 ]. toUpperCase () }` : undefined ;
84 return buildSourceRegional ({
85 adapter: 'csv' ,
86 generatedAt,
87 currency: supplied (currency),
88 timeZone: supplied (timeZone),
89 primaryLanguage: supplied (language, INTAKE_EVIDENCE , locale ? { locale } : {}),
90 country: supplied (country),
91 });
92 }
93
94 // Writes `<outDir>/source-locale.json`. The library writer takes the project directory, so it is
95 // used when the capture directory is the adapter's raw directory; any other directory gets the same
96 // validated file written directly.
97 async function writeCsvSourceRegional ( outDir , file ) {
98 const rawDir = path. resolve (outDir);
99 const suffix = path.sep + path. normalize ( ADAPTER_RAW_DIRS .csv);
100 if (rawDir. endsWith (suffix)) {
101 return writeAdapterSourceRegional (rawDir. slice ( 0 , rawDir. length - suffix. length ), 'csv' , file);
102 }
103 const result = validateSourceRegional (file);
104 if ( ! result.ok) throw new Error ( `source regional file is invalid: ${ result . errors . join ( '; ' ) }` );
105 await fs. mkdir (rawDir, { recursive: true });
106 const target = path. join (rawDir, ADAPTER_FILE_NAME );
107 await fs. writeFile (target, `${ JSON . stringify ( file , null , 2 ) } \n ` , 'utf8' );
108 return target;
109 }
110
111 module . exports = {
112 CURRENCY_COLUMNS,
113 currencyColumnIndexes,
114 createCurrencyCounter,
115 mergeCurrencyCounts,
116 buildCsvSourceRegional,
117 writeCsvSourceRegional,
118 };