@sampuli/data 0.3.1 → 0.3.2

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/README.md CHANGED
@@ -87,6 +87,12 @@ generate('de.person')
87
87
  // }
88
88
 
89
89
  generateMany('br.person', 500) // → 500 coherent Brazilian records
90
+
91
+ // Beyond people — companies and products, correct for the country:
92
+ generate('de.company') // → { name: 'Nova Labs GmbH', industry: 'Software',
93
+ // vat: 'DE114...', phone: '0179...', currency: 'EUR', … }
94
+ generate('jp.product') // → { name: 'Pro Speaker', price: 8250, currency: 'JPY',
95
+ // ean: '4988... ' (valid EAN-13), sku: 'KT-402917', … }
90
96
  ```
91
97
 
92
98
  Every pack uses the same spec shape — swap the country code. A pack's fields
package/dist/cli.js CHANGED
@@ -12950,6 +12950,203 @@ for (const [code, pack] of Object.entries(LOCALES)) {
12950
12950
  }
12951
12951
  }
12952
12952
 
12953
+ // ../../src/lib/catalog.js
12954
+ var SUFFIX = {
12955
+ DE: "GmbH",
12956
+ AT: "GmbH",
12957
+ CH: "AG",
12958
+ LU: "S.\xE0 r.l.",
12959
+ FR: "SARL",
12960
+ BE: "SA",
12961
+ NL: "B.V.",
12962
+ IT: "S.p.A.",
12963
+ ES: "S.L.",
12964
+ PT: "Lda.",
12965
+ SE: "AB",
12966
+ NO: "AS",
12967
+ DK: "A/S",
12968
+ FI: "Oy",
12969
+ IS: "ehf.",
12970
+ PL: "Sp. z o.o.",
12971
+ CZ: "s.r.o.",
12972
+ SK: "s.r.o.",
12973
+ HU: "Kft.",
12974
+ RO: "S.R.L.",
12975
+ HR: "d.o.o.",
12976
+ SI: "d.o.o.",
12977
+ RS: "d.o.o.",
12978
+ BG: "OOD",
12979
+ GR: "A.E.",
12980
+ UA: "TOV",
12981
+ EE: "O\xDC",
12982
+ LV: "SIA",
12983
+ LT: "UAB",
12984
+ ZA: "(Pty) Ltd",
12985
+ NG: "Ltd",
12986
+ KE: "Ltd",
12987
+ GH: "Ltd",
12988
+ AU: "Pty Ltd",
12989
+ NZ: "Ltd",
12990
+ JP: "K.K.",
12991
+ KR: "Co., Ltd.",
12992
+ CN: "Co., Ltd.",
12993
+ HK: "Ltd",
12994
+ SG: "Pte Ltd",
12995
+ IN: "Pvt Ltd",
12996
+ PK: "Pvt Ltd",
12997
+ BD: "Ltd",
12998
+ LK: "Ltd",
12999
+ MY: "Sdn Bhd",
13000
+ ID: "PT",
13001
+ TH: "Co., Ltd.",
13002
+ VN: "Co., Ltd.",
13003
+ PH: "Inc.",
13004
+ US: "Inc.",
13005
+ CA: "Inc.",
13006
+ BR: "Ltda.",
13007
+ MX: "S.A. de C.V.",
13008
+ AR: "S.A.",
13009
+ CL: "SpA",
13010
+ CO: "S.A.S.",
13011
+ PE: "S.A.C.",
13012
+ EC: "S.A.",
13013
+ UY: "S.A.",
13014
+ AE: "LLC",
13015
+ SA: "LLC",
13016
+ QA: "W.L.L.",
13017
+ KW: "W.L.L.",
13018
+ BH: "W.L.L.",
13019
+ OM: "LLC",
13020
+ JO: "LLC",
13021
+ LB: "SAL",
13022
+ IL: "Ltd",
13023
+ TR: "A.\u015E."
13024
+ };
13025
+ var NAME_A = ["Blue", "North", "Bright", "Prime", "Cedar", "Iron", "Silver", "Summit", "Vertex", "Pioneer", "Meridian", "Atlas", "Harbor", "Crescent", "Nova", "Orbit", "Granite", "Union", "Delta", "Apex", "Evergreen", "Coral", "Amber", "Onyx", "Quantum"];
13026
+ var NAME_B = ["Systems", "Labs", "Works", "Technologies", "Industries", "Group", "Partners", "Trading", "Foods", "Logistics", "Digital", "Networks", "Holdings", "Solutions", "Analytics", "Dynamics", "Ventures", "Motors", "Textiles", "Energy"];
13027
+ var INDUSTRIES = ["Software", "Manufacturing", "Retail", "Financial Services", "Healthcare", "Logistics", "Agriculture", "Construction", "Telecommunications", "Hospitality", "Energy", "Education", "Media", "Real Estate", "Pharmaceuticals", "Automotive", "Consumer Goods", "Mining", "Consulting", "Insurance"];
13028
+ var CATEGORIES = ["Electronics", "Home & Kitchen", "Apparel", "Beauty", "Sports & Outdoors", "Toys & Games", "Grocery", "Office", "Automotive", "Health", "Garden", "Pet Supplies", "Books", "Tools", "Footwear"];
13029
+ var PROD_A = ["Ultra", "Pro", "Eco", "Smart", "Classic", "Premium", "Compact", "Max", "Lite", "Active", "Prime", "Nano", "Turbo", "Flex"];
13030
+ var PROD_B = ["Blender", "Headphones", "Backpack", "Sneakers", "Water Bottle", "Desk Lamp", "Keyboard", "Jacket", "Speaker", "Kettle", "Monitor", "Chair", "Charger", "Watch", "Mixer", "Toaster", "Camera", "Trimmer"];
13031
+ var CUR_FACTOR = {
13032
+ USD: 1,
13033
+ EUR: 1,
13034
+ GBP: 0.8,
13035
+ CHF: 0.9,
13036
+ CAD: 1.35,
13037
+ AUD: 1.5,
13038
+ NZD: 1.65,
13039
+ JPY: 150,
13040
+ CNY: 7.2,
13041
+ HKD: 7.8,
13042
+ SGD: 1.35,
13043
+ INR: 83,
13044
+ PKR: 280,
13045
+ BDT: 110,
13046
+ LKR: 300,
13047
+ KRW: 1350,
13048
+ IDR: 15600,
13049
+ THB: 36,
13050
+ VND: 24e3,
13051
+ MYR: 4.7,
13052
+ PHP: 56,
13053
+ KES: 130,
13054
+ NGN: 1500,
13055
+ ZAR: 18,
13056
+ GHS: 15,
13057
+ TZS: 2500,
13058
+ UGX: 3800,
13059
+ RWF: 1300,
13060
+ ETB: 115,
13061
+ EGP: 48,
13062
+ MAD: 10,
13063
+ XOF: 600,
13064
+ XAF: 600,
13065
+ MUR: 46,
13066
+ NAD: 18,
13067
+ ZMW: 26,
13068
+ BWP: 13.5,
13069
+ BRL: 5,
13070
+ MXN: 17,
13071
+ ARS: 900,
13072
+ CLP: 950,
13073
+ COP: 3900,
13074
+ PEN: 3.7,
13075
+ UYU: 40,
13076
+ AED: 3.67,
13077
+ SAR: 3.75,
13078
+ QAR: 3.64,
13079
+ KWD: 0.31,
13080
+ BHD: 0.38,
13081
+ OMR: 0.38,
13082
+ JOD: 0.71,
13083
+ LBP: 89e3,
13084
+ ILS: 3.7,
13085
+ TRY: 33,
13086
+ SEK: 10.5,
13087
+ NOK: 10.7,
13088
+ DKK: 6.9,
13089
+ PLN: 4,
13090
+ CZK: 23,
13091
+ HUF: 360,
13092
+ RON: 4.6,
13093
+ BGN: 1.96,
13094
+ HRK: 7,
13095
+ RSD: 108,
13096
+ ISK: 138,
13097
+ UAH: 41
13098
+ };
13099
+ var slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "");
13100
+ function fieldGen(pack, key, s) {
13101
+ const f = pack.fields.find((x) => x.key === key);
13102
+ return f ? f.gen({}, s) : void 0;
13103
+ }
13104
+ function pickFields(obj, fields) {
13105
+ if (!Array.isArray(fields)) return obj;
13106
+ const out = {};
13107
+ for (const k of fields) if (k in obj) out[k] = obj[k];
13108
+ return out;
13109
+ }
13110
+ function companyRecord(pack, s = {}) {
13111
+ const base = `${pick(NAME_A)} ${pick(NAME_B)}`;
13112
+ const suffix = SUFFIX[pack.code] || "Ltd";
13113
+ const domain = `${slug(base)}.com`;
13114
+ const rec = {
13115
+ name: `${base} ${suffix}`,
13116
+ industry: pick(INDUSTRIES),
13117
+ founded: ri(1975, 2023),
13118
+ employees: pick([12, 45, 130, 260, 540, 1200, 3400, 8600]),
13119
+ phone: fieldGen(pack, "phone", s),
13120
+ email: `hello@${domain}`,
13121
+ website: `https://${domain}`,
13122
+ vat: fieldGen(pack, "tax", s) ?? fieldGen(pack, "id", s),
13123
+ country: pack.name,
13124
+ currency: pack.currency.code
13125
+ };
13126
+ return pickFields(rec, s.fields);
13127
+ }
13128
+ function productRecord(pack, s = {}) {
13129
+ const name = `${pick(PROD_A)} ${pick(PROD_B)}`;
13130
+ const factor = CUR_FACTOR[pack.currency.code] ?? 1;
13131
+ const usd2 = [4.99, 9.99, 14.99, 19.99, 24.99, 39.99, 49.99, 79.99, 99.99, 149.99, 199.99, 299.99][ri(0, 11)];
13132
+ const raw = usd2 * factor;
13133
+ const price = pack.currency.decimals === 0 ? Math.round(raw) : Math.round(raw * 100) / 100;
13134
+ const b12 = digits(12);
13135
+ const rec = {
13136
+ name,
13137
+ brand: pick(NAME_A) + " " + pick(NAME_B.slice(0, 8)),
13138
+ category: pick(CATEGORIES),
13139
+ sku: String.fromCharCode(65 + ri(0, 25)) + String.fromCharCode(65 + ri(0, 25)) + "-" + digits(6),
13140
+ price,
13141
+ currency: pack.currency.code,
13142
+ ean: b12 + ean13Check(b12),
13143
+ in_stock: ri(0, 9) > 1,
13144
+ rating: Math.round(30 + ri(0, 20)) / 10
13145
+ // 3.0–5.0
13146
+ };
13147
+ return pickFields(rec, s.fields);
13148
+ }
13149
+
12953
13150
  // src/index.js
12954
13151
  var REGISTRY = { ...LOCALES };
12955
13152
  var MAX_ROWS = 1e6;
@@ -13015,6 +13212,8 @@ function buildRecord(pack, settings) {
13015
13212
  }
13016
13213
  function oneValue(pack, sel, settings) {
13017
13214
  if (sel === "person") return buildRecord(pack, settings);
13215
+ if (sel === "company") return companyRecord(pack, settings);
13216
+ if (sel === "product") return productRecord(pack, settings);
13018
13217
  if (sel.startsWith("preset:")) {
13019
13218
  const key2 = sel.slice("preset:".length);
13020
13219
  const preset = pack.presets.find((p) => p.key === key2);
@@ -13025,6 +13224,12 @@ function oneValue(pack, sel, settings) {
13025
13224
  }
13026
13225
  return preset.gen(settings);
13027
13226
  }
13227
+ if (sel === "iban" && !pack.fields.some((f2) => f2.key === "iban")) {
13228
+ const acct2 = pack.fields.find((f2) => f2.key === "account");
13229
+ const v = acct2 && acct2.gen({}, settings);
13230
+ if (v && /^[A-Z]{2}\d{2}[A-Z0-9]{8,}$/.test(String(v))) return v;
13231
+ throw new Error(`${pack.code} does not use IBANs. Try "${pack.code.toLowerCase()}.account".`);
13232
+ }
13028
13233
  const key = ALIASES[sel] || sel;
13029
13234
  const f = pack.fields.find((x) => x.key === key);
13030
13235
  if (!f) {
@@ -13064,6 +13269,8 @@ Usage:
13064
13269
 
13065
13270
  Spec is <country>.<selector>:
13066
13271
  ke.person a full coherent record
13272
+ ke.company a synthetic company
13273
+ ke.product a product / catalogue row (valid EAN-13)
13067
13274
  ke.phone a single field value
13068
13275
  ke.kra_pin a single field (aliases work)
13069
13276
  ke.preset:kyc a scenario (ordered rows)
package/dist/index.cjs CHANGED
@@ -12978,6 +12978,203 @@ for (const [code, pack] of Object.entries(LOCALES)) {
12978
12978
  }
12979
12979
  }
12980
12980
 
12981
+ // ../../src/lib/catalog.js
12982
+ var SUFFIX = {
12983
+ DE: "GmbH",
12984
+ AT: "GmbH",
12985
+ CH: "AG",
12986
+ LU: "S.\xE0 r.l.",
12987
+ FR: "SARL",
12988
+ BE: "SA",
12989
+ NL: "B.V.",
12990
+ IT: "S.p.A.",
12991
+ ES: "S.L.",
12992
+ PT: "Lda.",
12993
+ SE: "AB",
12994
+ NO: "AS",
12995
+ DK: "A/S",
12996
+ FI: "Oy",
12997
+ IS: "ehf.",
12998
+ PL: "Sp. z o.o.",
12999
+ CZ: "s.r.o.",
13000
+ SK: "s.r.o.",
13001
+ HU: "Kft.",
13002
+ RO: "S.R.L.",
13003
+ HR: "d.o.o.",
13004
+ SI: "d.o.o.",
13005
+ RS: "d.o.o.",
13006
+ BG: "OOD",
13007
+ GR: "A.E.",
13008
+ UA: "TOV",
13009
+ EE: "O\xDC",
13010
+ LV: "SIA",
13011
+ LT: "UAB",
13012
+ ZA: "(Pty) Ltd",
13013
+ NG: "Ltd",
13014
+ KE: "Ltd",
13015
+ GH: "Ltd",
13016
+ AU: "Pty Ltd",
13017
+ NZ: "Ltd",
13018
+ JP: "K.K.",
13019
+ KR: "Co., Ltd.",
13020
+ CN: "Co., Ltd.",
13021
+ HK: "Ltd",
13022
+ SG: "Pte Ltd",
13023
+ IN: "Pvt Ltd",
13024
+ PK: "Pvt Ltd",
13025
+ BD: "Ltd",
13026
+ LK: "Ltd",
13027
+ MY: "Sdn Bhd",
13028
+ ID: "PT",
13029
+ TH: "Co., Ltd.",
13030
+ VN: "Co., Ltd.",
13031
+ PH: "Inc.",
13032
+ US: "Inc.",
13033
+ CA: "Inc.",
13034
+ BR: "Ltda.",
13035
+ MX: "S.A. de C.V.",
13036
+ AR: "S.A.",
13037
+ CL: "SpA",
13038
+ CO: "S.A.S.",
13039
+ PE: "S.A.C.",
13040
+ EC: "S.A.",
13041
+ UY: "S.A.",
13042
+ AE: "LLC",
13043
+ SA: "LLC",
13044
+ QA: "W.L.L.",
13045
+ KW: "W.L.L.",
13046
+ BH: "W.L.L.",
13047
+ OM: "LLC",
13048
+ JO: "LLC",
13049
+ LB: "SAL",
13050
+ IL: "Ltd",
13051
+ TR: "A.\u015E."
13052
+ };
13053
+ var NAME_A = ["Blue", "North", "Bright", "Prime", "Cedar", "Iron", "Silver", "Summit", "Vertex", "Pioneer", "Meridian", "Atlas", "Harbor", "Crescent", "Nova", "Orbit", "Granite", "Union", "Delta", "Apex", "Evergreen", "Coral", "Amber", "Onyx", "Quantum"];
13054
+ var NAME_B = ["Systems", "Labs", "Works", "Technologies", "Industries", "Group", "Partners", "Trading", "Foods", "Logistics", "Digital", "Networks", "Holdings", "Solutions", "Analytics", "Dynamics", "Ventures", "Motors", "Textiles", "Energy"];
13055
+ var INDUSTRIES = ["Software", "Manufacturing", "Retail", "Financial Services", "Healthcare", "Logistics", "Agriculture", "Construction", "Telecommunications", "Hospitality", "Energy", "Education", "Media", "Real Estate", "Pharmaceuticals", "Automotive", "Consumer Goods", "Mining", "Consulting", "Insurance"];
13056
+ var CATEGORIES = ["Electronics", "Home & Kitchen", "Apparel", "Beauty", "Sports & Outdoors", "Toys & Games", "Grocery", "Office", "Automotive", "Health", "Garden", "Pet Supplies", "Books", "Tools", "Footwear"];
13057
+ var PROD_A = ["Ultra", "Pro", "Eco", "Smart", "Classic", "Premium", "Compact", "Max", "Lite", "Active", "Prime", "Nano", "Turbo", "Flex"];
13058
+ var PROD_B = ["Blender", "Headphones", "Backpack", "Sneakers", "Water Bottle", "Desk Lamp", "Keyboard", "Jacket", "Speaker", "Kettle", "Monitor", "Chair", "Charger", "Watch", "Mixer", "Toaster", "Camera", "Trimmer"];
13059
+ var CUR_FACTOR = {
13060
+ USD: 1,
13061
+ EUR: 1,
13062
+ GBP: 0.8,
13063
+ CHF: 0.9,
13064
+ CAD: 1.35,
13065
+ AUD: 1.5,
13066
+ NZD: 1.65,
13067
+ JPY: 150,
13068
+ CNY: 7.2,
13069
+ HKD: 7.8,
13070
+ SGD: 1.35,
13071
+ INR: 83,
13072
+ PKR: 280,
13073
+ BDT: 110,
13074
+ LKR: 300,
13075
+ KRW: 1350,
13076
+ IDR: 15600,
13077
+ THB: 36,
13078
+ VND: 24e3,
13079
+ MYR: 4.7,
13080
+ PHP: 56,
13081
+ KES: 130,
13082
+ NGN: 1500,
13083
+ ZAR: 18,
13084
+ GHS: 15,
13085
+ TZS: 2500,
13086
+ UGX: 3800,
13087
+ RWF: 1300,
13088
+ ETB: 115,
13089
+ EGP: 48,
13090
+ MAD: 10,
13091
+ XOF: 600,
13092
+ XAF: 600,
13093
+ MUR: 46,
13094
+ NAD: 18,
13095
+ ZMW: 26,
13096
+ BWP: 13.5,
13097
+ BRL: 5,
13098
+ MXN: 17,
13099
+ ARS: 900,
13100
+ CLP: 950,
13101
+ COP: 3900,
13102
+ PEN: 3.7,
13103
+ UYU: 40,
13104
+ AED: 3.67,
13105
+ SAR: 3.75,
13106
+ QAR: 3.64,
13107
+ KWD: 0.31,
13108
+ BHD: 0.38,
13109
+ OMR: 0.38,
13110
+ JOD: 0.71,
13111
+ LBP: 89e3,
13112
+ ILS: 3.7,
13113
+ TRY: 33,
13114
+ SEK: 10.5,
13115
+ NOK: 10.7,
13116
+ DKK: 6.9,
13117
+ PLN: 4,
13118
+ CZK: 23,
13119
+ HUF: 360,
13120
+ RON: 4.6,
13121
+ BGN: 1.96,
13122
+ HRK: 7,
13123
+ RSD: 108,
13124
+ ISK: 138,
13125
+ UAH: 41
13126
+ };
13127
+ var slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "");
13128
+ function fieldGen(pack, key, s) {
13129
+ const f = pack.fields.find((x) => x.key === key);
13130
+ return f ? f.gen({}, s) : void 0;
13131
+ }
13132
+ function pickFields(obj, fields) {
13133
+ if (!Array.isArray(fields)) return obj;
13134
+ const out = {};
13135
+ for (const k of fields) if (k in obj) out[k] = obj[k];
13136
+ return out;
13137
+ }
13138
+ function companyRecord(pack, s = {}) {
13139
+ const base = `${pick(NAME_A)} ${pick(NAME_B)}`;
13140
+ const suffix = SUFFIX[pack.code] || "Ltd";
13141
+ const domain = `${slug(base)}.com`;
13142
+ const rec = {
13143
+ name: `${base} ${suffix}`,
13144
+ industry: pick(INDUSTRIES),
13145
+ founded: ri(1975, 2023),
13146
+ employees: pick([12, 45, 130, 260, 540, 1200, 3400, 8600]),
13147
+ phone: fieldGen(pack, "phone", s),
13148
+ email: `hello@${domain}`,
13149
+ website: `https://${domain}`,
13150
+ vat: fieldGen(pack, "tax", s) ?? fieldGen(pack, "id", s),
13151
+ country: pack.name,
13152
+ currency: pack.currency.code
13153
+ };
13154
+ return pickFields(rec, s.fields);
13155
+ }
13156
+ function productRecord(pack, s = {}) {
13157
+ const name = `${pick(PROD_A)} ${pick(PROD_B)}`;
13158
+ const factor = CUR_FACTOR[pack.currency.code] ?? 1;
13159
+ const usd2 = [4.99, 9.99, 14.99, 19.99, 24.99, 39.99, 49.99, 79.99, 99.99, 149.99, 199.99, 299.99][ri(0, 11)];
13160
+ const raw = usd2 * factor;
13161
+ const price = pack.currency.decimals === 0 ? Math.round(raw) : Math.round(raw * 100) / 100;
13162
+ const b12 = digits(12);
13163
+ const rec = {
13164
+ name,
13165
+ brand: pick(NAME_A) + " " + pick(NAME_B.slice(0, 8)),
13166
+ category: pick(CATEGORIES),
13167
+ sku: String.fromCharCode(65 + ri(0, 25)) + String.fromCharCode(65 + ri(0, 25)) + "-" + digits(6),
13168
+ price,
13169
+ currency: pack.currency.code,
13170
+ ean: b12 + ean13Check(b12),
13171
+ in_stock: ri(0, 9) > 1,
13172
+ rating: Math.round(30 + ri(0, 20)) / 10
13173
+ // 3.0–5.0
13174
+ };
13175
+ return pickFields(rec, s.fields);
13176
+ }
13177
+
12981
13178
  // src/index.js
12982
13179
  var REGISTRY = { ...LOCALES };
12983
13180
  var MAX_ROWS = 1e6;
@@ -13049,6 +13246,8 @@ function buildRecord(pack, settings) {
13049
13246
  }
13050
13247
  function oneValue(pack, sel, settings) {
13051
13248
  if (sel === "person") return buildRecord(pack, settings);
13249
+ if (sel === "company") return companyRecord(pack, settings);
13250
+ if (sel === "product") return productRecord(pack, settings);
13052
13251
  if (sel.startsWith("preset:")) {
13053
13252
  const key2 = sel.slice("preset:".length);
13054
13253
  const preset = pack.presets.find((p) => p.key === key2);
@@ -13059,6 +13258,12 @@ function oneValue(pack, sel, settings) {
13059
13258
  }
13060
13259
  return preset.gen(settings);
13061
13260
  }
13261
+ if (sel === "iban" && !pack.fields.some((f2) => f2.key === "iban")) {
13262
+ const acct2 = pack.fields.find((f2) => f2.key === "account");
13263
+ const v = acct2 && acct2.gen({}, settings);
13264
+ if (v && /^[A-Z]{2}\d{2}[A-Z0-9]{8,}$/.test(String(v))) return v;
13265
+ throw new Error(`${pack.code} does not use IBANs. Try "${pack.code.toLowerCase()}.account".`);
13266
+ }
13062
13267
  const key = ALIASES[sel] || sel;
13063
13268
  const f = pack.fields.find((x) => x.key === key);
13064
13269
  if (!f) {
package/dist/index.js CHANGED
@@ -12948,6 +12948,203 @@ for (const [code, pack] of Object.entries(LOCALES)) {
12948
12948
  }
12949
12949
  }
12950
12950
 
12951
+ // ../../src/lib/catalog.js
12952
+ var SUFFIX = {
12953
+ DE: "GmbH",
12954
+ AT: "GmbH",
12955
+ CH: "AG",
12956
+ LU: "S.\xE0 r.l.",
12957
+ FR: "SARL",
12958
+ BE: "SA",
12959
+ NL: "B.V.",
12960
+ IT: "S.p.A.",
12961
+ ES: "S.L.",
12962
+ PT: "Lda.",
12963
+ SE: "AB",
12964
+ NO: "AS",
12965
+ DK: "A/S",
12966
+ FI: "Oy",
12967
+ IS: "ehf.",
12968
+ PL: "Sp. z o.o.",
12969
+ CZ: "s.r.o.",
12970
+ SK: "s.r.o.",
12971
+ HU: "Kft.",
12972
+ RO: "S.R.L.",
12973
+ HR: "d.o.o.",
12974
+ SI: "d.o.o.",
12975
+ RS: "d.o.o.",
12976
+ BG: "OOD",
12977
+ GR: "A.E.",
12978
+ UA: "TOV",
12979
+ EE: "O\xDC",
12980
+ LV: "SIA",
12981
+ LT: "UAB",
12982
+ ZA: "(Pty) Ltd",
12983
+ NG: "Ltd",
12984
+ KE: "Ltd",
12985
+ GH: "Ltd",
12986
+ AU: "Pty Ltd",
12987
+ NZ: "Ltd",
12988
+ JP: "K.K.",
12989
+ KR: "Co., Ltd.",
12990
+ CN: "Co., Ltd.",
12991
+ HK: "Ltd",
12992
+ SG: "Pte Ltd",
12993
+ IN: "Pvt Ltd",
12994
+ PK: "Pvt Ltd",
12995
+ BD: "Ltd",
12996
+ LK: "Ltd",
12997
+ MY: "Sdn Bhd",
12998
+ ID: "PT",
12999
+ TH: "Co., Ltd.",
13000
+ VN: "Co., Ltd.",
13001
+ PH: "Inc.",
13002
+ US: "Inc.",
13003
+ CA: "Inc.",
13004
+ BR: "Ltda.",
13005
+ MX: "S.A. de C.V.",
13006
+ AR: "S.A.",
13007
+ CL: "SpA",
13008
+ CO: "S.A.S.",
13009
+ PE: "S.A.C.",
13010
+ EC: "S.A.",
13011
+ UY: "S.A.",
13012
+ AE: "LLC",
13013
+ SA: "LLC",
13014
+ QA: "W.L.L.",
13015
+ KW: "W.L.L.",
13016
+ BH: "W.L.L.",
13017
+ OM: "LLC",
13018
+ JO: "LLC",
13019
+ LB: "SAL",
13020
+ IL: "Ltd",
13021
+ TR: "A.\u015E."
13022
+ };
13023
+ var NAME_A = ["Blue", "North", "Bright", "Prime", "Cedar", "Iron", "Silver", "Summit", "Vertex", "Pioneer", "Meridian", "Atlas", "Harbor", "Crescent", "Nova", "Orbit", "Granite", "Union", "Delta", "Apex", "Evergreen", "Coral", "Amber", "Onyx", "Quantum"];
13024
+ var NAME_B = ["Systems", "Labs", "Works", "Technologies", "Industries", "Group", "Partners", "Trading", "Foods", "Logistics", "Digital", "Networks", "Holdings", "Solutions", "Analytics", "Dynamics", "Ventures", "Motors", "Textiles", "Energy"];
13025
+ var INDUSTRIES = ["Software", "Manufacturing", "Retail", "Financial Services", "Healthcare", "Logistics", "Agriculture", "Construction", "Telecommunications", "Hospitality", "Energy", "Education", "Media", "Real Estate", "Pharmaceuticals", "Automotive", "Consumer Goods", "Mining", "Consulting", "Insurance"];
13026
+ var CATEGORIES = ["Electronics", "Home & Kitchen", "Apparel", "Beauty", "Sports & Outdoors", "Toys & Games", "Grocery", "Office", "Automotive", "Health", "Garden", "Pet Supplies", "Books", "Tools", "Footwear"];
13027
+ var PROD_A = ["Ultra", "Pro", "Eco", "Smart", "Classic", "Premium", "Compact", "Max", "Lite", "Active", "Prime", "Nano", "Turbo", "Flex"];
13028
+ var PROD_B = ["Blender", "Headphones", "Backpack", "Sneakers", "Water Bottle", "Desk Lamp", "Keyboard", "Jacket", "Speaker", "Kettle", "Monitor", "Chair", "Charger", "Watch", "Mixer", "Toaster", "Camera", "Trimmer"];
13029
+ var CUR_FACTOR = {
13030
+ USD: 1,
13031
+ EUR: 1,
13032
+ GBP: 0.8,
13033
+ CHF: 0.9,
13034
+ CAD: 1.35,
13035
+ AUD: 1.5,
13036
+ NZD: 1.65,
13037
+ JPY: 150,
13038
+ CNY: 7.2,
13039
+ HKD: 7.8,
13040
+ SGD: 1.35,
13041
+ INR: 83,
13042
+ PKR: 280,
13043
+ BDT: 110,
13044
+ LKR: 300,
13045
+ KRW: 1350,
13046
+ IDR: 15600,
13047
+ THB: 36,
13048
+ VND: 24e3,
13049
+ MYR: 4.7,
13050
+ PHP: 56,
13051
+ KES: 130,
13052
+ NGN: 1500,
13053
+ ZAR: 18,
13054
+ GHS: 15,
13055
+ TZS: 2500,
13056
+ UGX: 3800,
13057
+ RWF: 1300,
13058
+ ETB: 115,
13059
+ EGP: 48,
13060
+ MAD: 10,
13061
+ XOF: 600,
13062
+ XAF: 600,
13063
+ MUR: 46,
13064
+ NAD: 18,
13065
+ ZMW: 26,
13066
+ BWP: 13.5,
13067
+ BRL: 5,
13068
+ MXN: 17,
13069
+ ARS: 900,
13070
+ CLP: 950,
13071
+ COP: 3900,
13072
+ PEN: 3.7,
13073
+ UYU: 40,
13074
+ AED: 3.67,
13075
+ SAR: 3.75,
13076
+ QAR: 3.64,
13077
+ KWD: 0.31,
13078
+ BHD: 0.38,
13079
+ OMR: 0.38,
13080
+ JOD: 0.71,
13081
+ LBP: 89e3,
13082
+ ILS: 3.7,
13083
+ TRY: 33,
13084
+ SEK: 10.5,
13085
+ NOK: 10.7,
13086
+ DKK: 6.9,
13087
+ PLN: 4,
13088
+ CZK: 23,
13089
+ HUF: 360,
13090
+ RON: 4.6,
13091
+ BGN: 1.96,
13092
+ HRK: 7,
13093
+ RSD: 108,
13094
+ ISK: 138,
13095
+ UAH: 41
13096
+ };
13097
+ var slug = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, "");
13098
+ function fieldGen(pack, key, s) {
13099
+ const f = pack.fields.find((x) => x.key === key);
13100
+ return f ? f.gen({}, s) : void 0;
13101
+ }
13102
+ function pickFields(obj, fields) {
13103
+ if (!Array.isArray(fields)) return obj;
13104
+ const out = {};
13105
+ for (const k of fields) if (k in obj) out[k] = obj[k];
13106
+ return out;
13107
+ }
13108
+ function companyRecord(pack, s = {}) {
13109
+ const base = `${pick(NAME_A)} ${pick(NAME_B)}`;
13110
+ const suffix = SUFFIX[pack.code] || "Ltd";
13111
+ const domain = `${slug(base)}.com`;
13112
+ const rec = {
13113
+ name: `${base} ${suffix}`,
13114
+ industry: pick(INDUSTRIES),
13115
+ founded: ri(1975, 2023),
13116
+ employees: pick([12, 45, 130, 260, 540, 1200, 3400, 8600]),
13117
+ phone: fieldGen(pack, "phone", s),
13118
+ email: `hello@${domain}`,
13119
+ website: `https://${domain}`,
13120
+ vat: fieldGen(pack, "tax", s) ?? fieldGen(pack, "id", s),
13121
+ country: pack.name,
13122
+ currency: pack.currency.code
13123
+ };
13124
+ return pickFields(rec, s.fields);
13125
+ }
13126
+ function productRecord(pack, s = {}) {
13127
+ const name = `${pick(PROD_A)} ${pick(PROD_B)}`;
13128
+ const factor = CUR_FACTOR[pack.currency.code] ?? 1;
13129
+ const usd2 = [4.99, 9.99, 14.99, 19.99, 24.99, 39.99, 49.99, 79.99, 99.99, 149.99, 199.99, 299.99][ri(0, 11)];
13130
+ const raw = usd2 * factor;
13131
+ const price = pack.currency.decimals === 0 ? Math.round(raw) : Math.round(raw * 100) / 100;
13132
+ const b12 = digits(12);
13133
+ const rec = {
13134
+ name,
13135
+ brand: pick(NAME_A) + " " + pick(NAME_B.slice(0, 8)),
13136
+ category: pick(CATEGORIES),
13137
+ sku: String.fromCharCode(65 + ri(0, 25)) + String.fromCharCode(65 + ri(0, 25)) + "-" + digits(6),
13138
+ price,
13139
+ currency: pack.currency.code,
13140
+ ean: b12 + ean13Check(b12),
13141
+ in_stock: ri(0, 9) > 1,
13142
+ rating: Math.round(30 + ri(0, 20)) / 10
13143
+ // 3.0–5.0
13144
+ };
13145
+ return pickFields(rec, s.fields);
13146
+ }
13147
+
12951
13148
  // src/index.js
12952
13149
  var REGISTRY = { ...LOCALES };
12953
13150
  var MAX_ROWS = 1e6;
@@ -13019,6 +13216,8 @@ function buildRecord(pack, settings) {
13019
13216
  }
13020
13217
  function oneValue(pack, sel, settings) {
13021
13218
  if (sel === "person") return buildRecord(pack, settings);
13219
+ if (sel === "company") return companyRecord(pack, settings);
13220
+ if (sel === "product") return productRecord(pack, settings);
13022
13221
  if (sel.startsWith("preset:")) {
13023
13222
  const key2 = sel.slice("preset:".length);
13024
13223
  const preset = pack.presets.find((p) => p.key === key2);
@@ -13029,6 +13228,12 @@ function oneValue(pack, sel, settings) {
13029
13228
  }
13030
13229
  return preset.gen(settings);
13031
13230
  }
13231
+ if (sel === "iban" && !pack.fields.some((f2) => f2.key === "iban")) {
13232
+ const acct2 = pack.fields.find((f2) => f2.key === "account");
13233
+ const v = acct2 && acct2.gen({}, settings);
13234
+ if (v && /^[A-Z]{2}\d{2}[A-Z0-9]{8,}$/.test(String(v))) return v;
13235
+ throw new Error(`${pack.code} does not use IBANs. Try "${pack.code.toLowerCase()}.account".`);
13236
+ }
13032
13237
  const key = ALIASES[sel] || sel;
13033
13238
  const f = pack.fields.find((x) => x.key === key);
13034
13239
  if (!f) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sampuli/data",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Synthetic, format-true test data for countries worldwide — national IDs, tax numbers, IBANs & SWIFT/BIC, bank accounts, phone numbers and ready-made KYC/transfer/payment scenarios, each correct for its own country. For QA and CI at banks and fintechs anywhere. Entirely synthetic: real formats, never real or registered data. Free, no caps. The engine behind Sampuli.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",