@datawheel/bespoke 0.3.21 → 0.4.0

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/dist/server.js CHANGED
@@ -11,7 +11,7 @@ import { formatAbbreviate } from 'd3plus-format';
11
11
  import { date } from 'd3plus-axis';
12
12
  import { assign, closest, merge, isObject } from 'd3plus-common';
13
13
  import { strip, titleCase } from 'd3plus-text';
14
- import axios5 from 'axios';
14
+ import axios6 from 'axios';
15
15
  import slugifyFn from 'slugify';
16
16
  import lunr from 'lunr';
17
17
  import lunrStemmer from 'lunr-languages/lunr.stemmer.support';
@@ -24,6 +24,7 @@ import { createContext, createElement } from 'react';
24
24
  import { renderToString } from 'react-dom/server';
25
25
  import * as allIcons from '@tabler/icons-react';
26
26
  import NextCors from 'nextjs-cors';
27
+ import imageType from 'image-type';
27
28
  import formidable from 'formidable';
28
29
  import puppeteer from 'puppeteer';
29
30
  import DomParser from 'dom-parser';
@@ -1338,10 +1339,10 @@ var getDB = () => {
1338
1339
  // libs/configs/getLocales.ts
1339
1340
  var getLocales_default = () => {
1340
1341
  const localeDefault11 = process.env.NEXT_PUBLIC_REPORTS_LOCALE_DEFAULT || "en";
1341
- const locales9 = process.env.NEXT_PUBLIC_REPORTS_LOCALES?.split(",") || [localeDefault11];
1342
- if (!locales9.includes(localeDefault11))
1343
- locales9.push(localeDefault11);
1344
- return { localeDefault: localeDefault11, locales: locales9 };
1342
+ const locales10 = process.env.NEXT_PUBLIC_REPORTS_LOCALES?.split(",") || [localeDefault11];
1343
+ if (!locales10.includes(localeDefault11))
1344
+ locales10.push(localeDefault11);
1345
+ return { localeDefault: localeDefault11, locales: locales10 };
1345
1346
  };
1346
1347
 
1347
1348
  // libs/js/stripHTML.ts
@@ -1390,14 +1391,25 @@ function slugify(str) {
1390
1391
  }
1391
1392
  var slugify_default = slugify;
1392
1393
 
1394
+ // libs/settings/variant.tsx
1395
+ var getVariantSettingsDefaults = (settings) => ({
1396
+ overrideNames: settings && typeof settings.overrideNames !== "undefined" ? settings.overrideNames : false,
1397
+ overrideRelevance: settings && typeof settings.overrideRelevance !== "undefined" ? settings.overrideRelevance : false,
1398
+ regenerateSlugs: settings && typeof settings.regenerateSlugs !== "undefined" ? settings.regenerateSlugs : false,
1399
+ keepOldMembers: settings && typeof settings.keepOldMembers !== "undefined" ? settings.keepOldMembers : true,
1400
+ doIngest: settings && typeof settings.doIngest !== "undefined" ? settings.doIngest : false,
1401
+ overrideAttributes: settings && typeof settings.overrideAttributes !== "undefined" ? settings.overrideAttributes : false
1402
+ });
1403
+
1393
1404
  // api/db/member/ingestMembers.ts
1394
1405
  var { localeDefault } = getLocales_default();
1395
1406
  function ingestMembersFactory(db) {
1396
1407
  const { search: Search, search_content: SearchContent } = db;
1397
1408
  return ingestMembers;
1398
1409
  async function ingestMembers(variant) {
1399
- const { id, config = {} } = variant;
1410
+ const { id, config = {}, settings = {} } = variant;
1400
1411
  const defaultLocale = config[localeDefault] ? localeDefault : Object.keys(config)[0];
1412
+ const { overrideNames, overrideAttributes } = getVariantSettingsDefaults(settings);
1401
1413
  const {
1402
1414
  accessor,
1403
1415
  path,
@@ -1406,15 +1418,24 @@ function ingestMembersFactory(db) {
1406
1418
  } = config[localeDefault];
1407
1419
  if (!path || !idKey || !labelKey)
1408
1420
  return;
1409
- const memberFetch = await axios5.get(path).catch((e) => ({ data: [], error: e }));
1421
+ const memberFetch = await axios6.get(path).catch((e) => ({ data: [], error: e }));
1410
1422
  const members = keyDiver(memberFetch.data, accessor);
1423
+ let toUpdateContent = [];
1411
1424
  try {
1412
- await ingestDefaultMembers(variant, defaultLocale, members);
1425
+ toUpdateContent = await ingestDefaultMembers(variant, defaultLocale, members);
1413
1426
  } catch (error) {
1414
1427
  const errorMsg = `[ERROR] Ingesting default member items for ${defaultLocale}`;
1415
1428
  console.error(errorMsg, error);
1416
1429
  throw new BackendError(500, errorMsg);
1417
1430
  }
1431
+ const contentHash = await Search.findAll({ where: { variant_id: id } }).then((arr) => Object.fromEntries(
1432
+ arr.map(
1433
+ (content) => [
1434
+ content.id,
1435
+ { content_id: content.content_id, needsUpdate: toUpdateContent.includes(content.content_id) }
1436
+ ]
1437
+ )
1438
+ ));
1418
1439
  const ingestions = Object.entries(config).map(async ([locale, config2]) => {
1419
1440
  const {
1420
1441
  path: path2,
@@ -1425,24 +1446,45 @@ function ingestMembersFactory(db) {
1425
1446
  } = config2;
1426
1447
  if (!path2 || !idKey2 || !labelKey2)
1427
1448
  return;
1428
- const memberFetch2 = await axios5.get(path2).catch((e) => ({ data: [], error: e }));
1449
+ const memberFetch2 = await axios6.get(path2).catch((e) => ({ data: [], error: e }));
1429
1450
  const members2 = keyDiver(memberFetch2.data, accessor2);
1430
- const contentHash = await Search.findAll({ where: { variant_id: id } }).then((arr) => Object.fromEntries(
1431
- arr.map((content) => [content.id, content.content_id])
1432
- ));
1433
- const contentMembers = members2.filter((member) => member[idKey2] && member[idKey2] !== "" && member[labelKey2] && member[labelKey2] !== "").map((d) => ({
1434
- id: contentHash[d[idKey2]],
1435
- locale,
1436
- name: d[labelKey2],
1437
- attributes: Object.fromEntries(
1451
+ const oldIngestedContents = await SearchContent.findAll({
1452
+ // attributes: ["id", "zvalue", "slug"],
1453
+ where: { id: toUpdateContent, locale }
1454
+ }).then((arr) => Object.fromEntries(arr.map((item) => {
1455
+ return [item.id, item.toJSON()];
1456
+ })));
1457
+ const contentMembers = members2.filter((member) => member[idKey2] && member[idKey2] !== "" && member[labelKey2] && member[labelKey2] !== "").map((d) => {
1458
+ const searchElement = contentHash[d[idKey2]];
1459
+ let contentMember;
1460
+ const calculatedAttributes = Object.fromEntries(
1438
1461
  attributes.map((attr) => [
1439
1462
  attr.name,
1440
1463
  attr.type === "constant" ? attr.value : d[attr.value] || ""
1441
1464
  ])
1442
- )
1443
- }));
1465
+ );
1466
+ if (searchElement.needsUpdate && oldIngestedContents[searchElement.content_id]) {
1467
+ contentMember = {
1468
+ ...oldIngestedContents[searchElement.content_id]
1469
+ };
1470
+ if (overrideNames) {
1471
+ contentMember.name = d[labelKey2];
1472
+ }
1473
+ if (overrideAttributes) {
1474
+ contentMember.attributes = calculatedAttributes;
1475
+ }
1476
+ } else {
1477
+ contentMember = {
1478
+ id: searchElement.content_id,
1479
+ locale,
1480
+ name: d[labelKey2],
1481
+ attributes: calculatedAttributes
1482
+ };
1483
+ }
1484
+ return contentMember;
1485
+ });
1444
1486
  try {
1445
- await SearchContent.bulkCreate(contentMembers);
1487
+ return SearchContent.bulkCreate(contentMembers, { updateOnDuplicate: ["name", "attributes"] });
1446
1488
  } catch (error) {
1447
1489
  const errorMsg = `[ERROR] Ingesting search content items for ${locale}`;
1448
1490
  console.error(errorMsg, error);
@@ -1455,7 +1497,14 @@ function ingestMembersFactory(db) {
1455
1497
  const { id, dimension_id, slug } = variant;
1456
1498
  const { report_id } = variant.dimension;
1457
1499
  const { idKey, labelKey, zValueKey } = variant.config[locale];
1458
- const allSlugsFromOtherMembers = await Search.findAll({
1500
+ const {
1501
+ overrideNames,
1502
+ regenerateSlugs,
1503
+ keepOldMembers,
1504
+ overrideRelevance,
1505
+ overrideAttributes
1506
+ } = getVariantSettingsDefaults(variant.settings);
1507
+ const allSlugsFromOtherMembersQuery = Search.findAll({
1459
1508
  attributes: ["slug", [fn("COUNT", col("variant.id")), "slugCount"]],
1460
1509
  include: {
1461
1510
  association: "variant",
@@ -1469,6 +1518,17 @@ function ingestMembersFactory(db) {
1469
1518
  const count = item.getDataValue("slugCount");
1470
1519
  return [item.slug, Number.parseInt(`${count}`, 10)];
1471
1520
  })));
1521
+ const oldIngestedMembersQuery = Search.findAll({
1522
+ // attributes: ["id", "zvalue", "slug"],
1523
+ where: { variant_id: id }
1524
+ }).then((arr) => Object.fromEntries(arr.map((item) => {
1525
+ return [item.id, item.toJSON()];
1526
+ })));
1527
+ const [allSlugsFromOtherMembers, oldIngestedMembers] = await Promise.all([
1528
+ allSlugsFromOtherMembersQuery,
1529
+ oldIngestedMembersQuery
1530
+ ]);
1531
+ const oldIngestedSlugs = Object.values(oldIngestedMembers).map((m) => m.slug);
1472
1532
  const toIngestSlugs = [];
1473
1533
  let minValue = null;
1474
1534
  let maxValue = null;
@@ -1485,16 +1545,15 @@ function ingestMembersFactory(db) {
1485
1545
  }
1486
1546
  }
1487
1547
  }
1488
- const searchMembers = members.map((member) => {
1548
+ const toInsert = [];
1549
+ const toUpdate = [];
1550
+ const toUpdateContent = [];
1551
+ let toUpdateFlag = false;
1552
+ members.forEach((member) => {
1489
1553
  const memberId = member[idKey];
1490
1554
  const slug2 = slugify_default(member[labelKey]);
1491
- const hasDuplicateSlug = allSlugsFromOtherMembers[slug2] || toIngestSlugs.includes(slug2);
1492
- if (hasDuplicateSlug) {
1493
- console.log("Duplicate slug!", slug2, "replaced by", `${slug2}-${memberId}`);
1494
- }
1495
- const validateSlug = hasDuplicateSlug ? `${slug2}-${memberId}` : slug2;
1496
- toIngestSlugs.push(slug2);
1497
- let zvalue = Math.random();
1555
+ toUpdateFlag = false;
1556
+ let zvalue = parseFloat(Math.random().toPrecision(5));
1498
1557
  if (zValueKey && zValueKey !== "" && minValue && maxValue && member[zValueKey]) {
1499
1558
  let value;
1500
1559
  try {
@@ -1505,18 +1564,79 @@ function ingestMembersFactory(db) {
1505
1564
  const indexedValue = maxValue !== null && minValue !== null && maxValue !== minValue ? (value - minValue) / (maxValue - minValue) : 0;
1506
1565
  zvalue = maxValue === minValue ? 1 : parseFloat(indexedValue.toPrecision(5));
1507
1566
  }
1508
- return {
1509
- id: memberId,
1510
- slug: validateSlug,
1511
- variant_id: id,
1512
- dimension_id,
1513
- report_id,
1514
- zvalue
1515
- };
1567
+ if (oldIngestedMembers[memberId]) {
1568
+ if (overrideNames || regenerateSlugs || overrideRelevance || overrideAttributes) {
1569
+ const memberToBeUpdated = oldIngestedMembers[memberId];
1570
+ if (overrideNames || overrideAttributes) {
1571
+ toUpdateContent.push(memberToBeUpdated.content_id);
1572
+ }
1573
+ if (overrideNames) {
1574
+ if (regenerateSlugs) {
1575
+ const oldIngestedSlugsButNotCurrent = Object.values(oldIngestedMembers).filter((m) => m.id !== memberId).map((m) => m.slug);
1576
+ const hasDuplicateSlug = allSlugsFromOtherMembers[slug2] || oldIngestedSlugsButNotCurrent.includes[slug2] || toIngestSlugs.includes(slug2);
1577
+ if (hasDuplicateSlug) {
1578
+ console.log("Duplicate slug!", slug2, "replaced by", `${slug2}-${memberId}`);
1579
+ }
1580
+ const validateSlug = hasDuplicateSlug ? `${slug2}-${memberId}` : slug2;
1581
+ if (memberToBeUpdated.slug !== validateSlug) {
1582
+ memberToBeUpdated.slug = validateSlug;
1583
+ toIngestSlugs.push(slug2);
1584
+ toUpdateFlag = true;
1585
+ console.log("UPDATE SLUG", memberId, slug2);
1586
+ }
1587
+ }
1588
+ }
1589
+ if (zValueKey && zValueKey !== "" && overrideRelevance) {
1590
+ if (memberToBeUpdated.zvalue !== zvalue) {
1591
+ memberToBeUpdated.zvalue = zvalue;
1592
+ toUpdateFlag = true;
1593
+ console.log("UPDATE ZVALUE", memberId, zvalue);
1594
+ }
1595
+ }
1596
+ if (toUpdateFlag) {
1597
+ toUpdate.push(memberToBeUpdated);
1598
+ }
1599
+ }
1600
+ } else {
1601
+ console.log("INSERT ID", memberId);
1602
+ const hasDuplicateSlug = allSlugsFromOtherMembers[slug2] || oldIngestedSlugs.includes[slug2] || toIngestSlugs.includes(slug2);
1603
+ if (hasDuplicateSlug) {
1604
+ console.log("Duplicate slug!", slug2, "replaced by", `${slug2}-${memberId}`);
1605
+ }
1606
+ const validateSlug = hasDuplicateSlug ? `${slug2}-${memberId}` : slug2;
1607
+ toIngestSlugs.push(slug2);
1608
+ toInsert.push({
1609
+ id: memberId,
1610
+ slug: validateSlug,
1611
+ variant_id: id,
1612
+ dimension_id,
1613
+ report_id,
1614
+ zvalue
1615
+ });
1616
+ }
1516
1617
  });
1618
+ let toDelete = [];
1619
+ if (!keepOldMembers) {
1620
+ const newMembersIds = members.map((m) => m[idKey]);
1621
+ toDelete = Object.keys(oldIngestedMembers).filter((id2) => !newMembersIds.includes(id2));
1622
+ }
1517
1623
  try {
1518
- await Search.destroy({ where: { variant_id: id } });
1519
- await Search.bulkCreate(searchMembers);
1624
+ if (toInsert.length > 0 || toUpdate.length > 0) {
1625
+ await Search.bulkCreate([...toInsert, ...toUpdate], { updateOnDuplicate: ["slug", "zvalue"] });
1626
+ console.log("New members ingested:", toInsert.length);
1627
+ console.log("New members updated:", toUpdate.length);
1628
+ }
1629
+ if (toDelete.length > 0) {
1630
+ await Search.destroy({
1631
+ where: {
1632
+ id: {
1633
+ [Op.in]: toDelete
1634
+ }
1635
+ }
1636
+ });
1637
+ console.log("Old members deleted:", toDelete.length);
1638
+ }
1639
+ return toUpdateContent;
1520
1640
  } catch (error) {
1521
1641
  console.error(`[ERROR] Ingesting search members for ${locale}`, error);
1522
1642
  throw new Error(error);
@@ -2093,12 +2213,12 @@ function dbBlockFactory(db) {
2093
2213
  deleteBlock
2094
2214
  };
2095
2215
  async function createBlock(data) {
2096
- const { locales: locales9, ...blockData } = data;
2216
+ const { locales: locales10, ...blockData } = data;
2097
2217
  const entity = await Block.create({
2098
2218
  ...blockData,
2099
2219
  consumers: [],
2100
2220
  inputs: [],
2101
- contentByLocale: locales9.map((locale) => ({ locale }))
2221
+ contentByLocale: locales10.map((locale) => ({ locale }))
2102
2222
  }, {
2103
2223
  include: blockQuery.include
2104
2224
  });
@@ -2266,7 +2386,7 @@ function dbReportFactory(db) {
2266
2386
  async function readReport({
2267
2387
  id,
2268
2388
  include,
2269
- locales: locales9 = reportLocales
2389
+ locales: locales10 = reportLocales
2270
2390
  } = {}) {
2271
2391
  const allIdsList = id == null ? [] : [].concat(id);
2272
2392
  const idList = allIdsList.reduce((uniques, currentValue) => {
@@ -2290,7 +2410,7 @@ function dbReportFactory(db) {
2290
2410
  ...block,
2291
2411
  contentByLocale: Object.keys(block.contentByLocale).reduce((filteredContent, locale) => ({
2292
2412
  ...filteredContent,
2293
- ...[...locales9, "logic"].includes(locale) ? { [locale]: block.contentByLocale[locale] } : {}
2413
+ ...[...locales10, "logic"].includes(locale) ? { [locale]: block.contentByLocale[locale] } : {}
2294
2414
  }), {})
2295
2415
  }))
2296
2416
  }))
@@ -2410,9 +2530,14 @@ function dbVariantFactory(db, crud) {
2410
2530
  include: [{ association: "dimension" }],
2411
2531
  rejectOnEmpty: true
2412
2532
  });
2413
- entity.update(variantData);
2414
- await crud.ingestMembers(entity);
2415
- await search_default2(db, true);
2533
+ variantData.settings = getVariantSettingsDefaults(variantData.settings);
2534
+ const doIngest = variantData.settings.doIngest;
2535
+ variantData.settings.doIngest = false;
2536
+ await entity.update(variantData);
2537
+ if (doIngest) {
2538
+ await crud.ingestMembers(entity);
2539
+ await search_default2(db, true);
2540
+ }
2416
2541
  await entity.reload();
2417
2542
  return entity.toJSON();
2418
2543
  }
@@ -2508,12 +2633,16 @@ var uploadImage = async (db, id, imageData) => {
2508
2633
  { type: "thumb", res: thumbWidth }
2509
2634
  ];
2510
2635
  for (const config of configs) {
2511
- const buffer = await sharp(imageData).resize(config.res).toFormat("jpeg").jpeg({ force: true }).toBuffer().catch(catcher);
2636
+ const buffer = await sharp(imageData).resize(config.res).toFormat("webp").webp({ lossless: true }).toBuffer().catch(catcher);
2512
2637
  await db.image.update({ [config.type]: buffer }, { where: { id } }).catch(catcher);
2513
2638
  }
2514
2639
  };
2515
2640
  var uploadImage_default = uploadImage;
2516
2641
 
2642
+ // libs/consts.ts
2643
+ var apiSeparator = "|||";
2644
+ var imagesPageSize = 24;
2645
+
2517
2646
  // api/db/image/providers/flickr.ts
2518
2647
  var validLicenses = ["4", "5", "7", "8", "9", "10"];
2519
2648
  var validLicensesString = validLicenses.join();
@@ -2527,10 +2656,11 @@ if (process.env.FLICKR_API_KEY) {
2527
2656
  throw new Error(e.message);
2528
2657
  }
2529
2658
  }
2530
- async function searchFlickrProvider(db, params) {
2659
+ async function searchFlickrProvider(_db, params) {
2531
2660
  try {
2532
2661
  const searchParams = {
2533
- prompt: params.prompt || ""
2662
+ prompt: params.prompt || "",
2663
+ page: params.page || 1
2534
2664
  };
2535
2665
  if (!flickr) {
2536
2666
  console.log("Flickr is not initialized. Check the credentials");
@@ -2540,7 +2670,11 @@ async function searchFlickrProvider(db, params) {
2540
2670
  const result = await flickr.photos.search({
2541
2671
  text: q,
2542
2672
  license: validLicensesString,
2543
- sort: "relevance"
2673
+ sort: "relevance",
2674
+ per_page: imagesPageSize,
2675
+ page: searchParams.page,
2676
+ content_types: "0",
2677
+ orientation: "landscape"
2544
2678
  }).then((resp) => resp.body);
2545
2679
  const photos = result.photos.photo;
2546
2680
  const fetches = photos.reduce(
@@ -2560,7 +2694,8 @@ async function searchFlickrProvider(db, params) {
2560
2694
  }, []);
2561
2695
  return {
2562
2696
  meta: {
2563
- prompt: stripHTML(searchParams.prompt)
2697
+ prompt: stripHTML(searchParams.prompt),
2698
+ page: stripHTML(`${searchParams.page}`)
2564
2699
  },
2565
2700
  results: imagesResults
2566
2701
  };
@@ -2608,7 +2743,7 @@ async function saveFlickrProvider(db, params) {
2608
2743
  if (!image || !image.source) {
2609
2744
  throw new Error("Flickr Source Error, try another image.");
2610
2745
  }
2611
- const imageData = await axios5.get(image.source, { responseType: "arraybuffer" }).then((d) => d.data);
2746
+ const imageData = await axios6.get(image.source, { responseType: "arraybuffer" }).then((d) => d.data);
2612
2747
  const allLicenses = await flickr.photos.licenses.getInfo().then((resp) => resp.body.licenses.license);
2613
2748
  const currentPhotoLicense = allLicenses.find((l) => l.id === parseInt(info.photo.license, 10));
2614
2749
  const payload = {
@@ -2732,9 +2867,9 @@ function endpointMemberFactory(operations) {
2732
2867
  /*
2733
2868
  * Get image file itself
2734
2869
  * Example queries:
2735
- * /api/cms/member/image.png?member=1&format=thumb
2870
+ * /api/cms/member/image?member=1&format=thumb
2736
2871
  */
2737
- endpoint("GET", "member/image.png", (req) => {
2872
+ endpoint("GET", "member/image", (req) => {
2738
2873
  const size = normalizeList(req.query.size)[0];
2739
2874
  return readMemberImage({
2740
2875
  member: parseFiniteNumber(req.query.member),
@@ -2847,7 +2982,7 @@ async function searchLocalProvider(db, params) {
2847
2982
  const resultsFromProfiles = await dbSearchMember(searchParams);
2848
2983
  const imagesResults = resultsFromProfiles.results.filter((member) => member.image_id).map((member) => ({
2849
2984
  id: member.image_id,
2850
- source: `/api/cms/member/image.png?member=${member.content_id}&size=thumb`
2985
+ source: `/api/cms/member/image?member=${member.content_id}&size=thumb`
2851
2986
  }));
2852
2987
  return {
2853
2988
  meta: {
@@ -2895,10 +3030,11 @@ if (process.env.UNSPLASH_API_KEY) {
2895
3030
  throw new Error(e.message);
2896
3031
  }
2897
3032
  }
2898
- async function searchUnsplashProvider(db, params) {
3033
+ async function searchUnsplashProvider(_db, params) {
2899
3034
  try {
2900
3035
  const searchParams = {
2901
- prompt: params.prompt || ""
3036
+ prompt: params.prompt || "",
3037
+ page: params.page || 1
2902
3038
  };
2903
3039
  if (!unsplash) {
2904
3040
  throw new Error("Unsplash API Key not configured");
@@ -2906,8 +3042,9 @@ async function searchUnsplashProvider(db, params) {
2906
3042
  const q = searchParams.prompt;
2907
3043
  const result = await unsplash.search.getPhotos({
2908
3044
  query: q,
2909
- perPage: 30
2910
- // max
3045
+ perPage: imagesPageSize,
3046
+ page: searchParams.page,
3047
+ orientation: "landscape"
2911
3048
  }).then((resp) => resp.response.results);
2912
3049
  const imagesResults = result.map((image) => ({
2913
3050
  id: image.id,
@@ -2915,7 +3052,8 @@ async function searchUnsplashProvider(db, params) {
2915
3052
  }));
2916
3053
  return {
2917
3054
  meta: {
2918
- prompt: stripHTML(searchParams.prompt)
3055
+ prompt: stripHTML(searchParams.prompt),
3056
+ page: stripHTML(`${searchParams.page}`)
2919
3057
  },
2920
3058
  results: imagesResults
2921
3059
  };
@@ -2946,7 +3084,7 @@ async function saveUnsplashProvider(db, params) {
2946
3084
  if (imageRow) {
2947
3085
  await db.search.update({ image_id: imageRow.id }, { where: { content_id } });
2948
3086
  } else {
2949
- const imageData = await axios5.get(info.urls.full, { responseType: "arraybuffer" }).then((d) => d.data);
3087
+ const imageData = await axios6.get(info.urls.full, { responseType: "arraybuffer" }).then((d) => d.data);
2950
3088
  const payload = {
2951
3089
  url,
2952
3090
  author: info.user.name || info.user.username,
@@ -3033,13 +3171,156 @@ async function saveUploadProvider(db, params) {
3033
3171
  throw new Error("Error in save upload provider");
3034
3172
  }
3035
3173
  }
3174
+ var { locales: locales5 } = getLocales_default();
3175
+ var getHeaders = async (token) => {
3176
+ const baseHeaders = {
3177
+ "x-api-key": process.env.ADOBE_STOCK_API_KEY || "EMPTY_ADOBE_KEY",
3178
+ "X-Product": "BespokeApp/0.1"
3179
+ };
3180
+ if (token) {
3181
+ baseHeaders["Authorization"] = `Bearer ${token}`;
3182
+ }
3183
+ return baseHeaders;
3184
+ };
3185
+ var adobe;
3186
+ if (process.env.ADOBE_STOCK_API_KEY) {
3187
+ try {
3188
+ adobe = {
3189
+ search: async (terms, page) => await axios6.get("https://stock.adobe.io/Rest/Media/1/Search/Files", {
3190
+ headers: await getHeaders(false),
3191
+ params: {
3192
+ locale: "en_US",
3193
+ "search_parameters[limit]": imagesPageSize,
3194
+ "search_parameters[offset]": page * imagesPageSize,
3195
+ "search_parameters[words]": terms,
3196
+ "search_parameters[filters][content_type:photo]": "1",
3197
+ "search_parameters[filters][content_type:image]": "1",
3198
+ "search_parameters[filters][orientation]": "horizontal",
3199
+ result_columns: ["id", "stock_id", "thumbnail_url", "is_licensed"]
3200
+ }
3201
+ }).then((resp) => resp.data.files),
3202
+ get: async (imageId) => {
3203
+ return await axios6.get("https://stock.adobe.io/Rest/Media/1/Files", {
3204
+ headers: await getHeaders(false),
3205
+ params: {
3206
+ locale: "en_US",
3207
+ ids: imageId,
3208
+ result_columns: [
3209
+ "id",
3210
+ "thumbnail_url",
3211
+ "creator_name",
3212
+ "title",
3213
+ "thumbnail_1000_url",
3214
+ "details_url",
3215
+ "category"
3216
+ ]
3217
+ }
3218
+ }).then((resp) => resp.data.files[0]);
3219
+ }
3220
+ };
3221
+ } catch (e) {
3222
+ }
3223
+ }
3224
+ async function searchAdobeProvider(_db, params) {
3225
+ try {
3226
+ const searchParams = {
3227
+ prompt: params.prompt || "",
3228
+ page: params.page || 1
3229
+ };
3230
+ if (!adobe) {
3231
+ throw new Error("Adobe API Key not configured");
3232
+ }
3233
+ const result = await adobe.search(searchParams.prompt, searchParams.page);
3234
+ const imagesResults = result.map((image) => ({
3235
+ id: image.id,
3236
+ source: image.thumbnail_url
3237
+ }));
3238
+ return {
3239
+ meta: {
3240
+ prompt: stripHTML(searchParams.prompt),
3241
+ page: stripHTML(`${searchParams.page}`)
3242
+ },
3243
+ results: imagesResults
3244
+ };
3245
+ } catch (error) {
3246
+ console.log(error);
3247
+ throw new Error("Error in search Adobe provider");
3248
+ }
3249
+ }
3250
+ async function saveAdobeProvider(db, params) {
3251
+ try {
3252
+ const { content_id, image_id } = params;
3253
+ const saveParams = {
3254
+ content_id: stripHTML(`${content_id}`) || "",
3255
+ id: stripHTML(`${image_id}`) || ""
3256
+ };
3257
+ if (!adobe) {
3258
+ console.log("Adobe is not initialized. Check the credentials");
3259
+ throw new Error("Adobe is not initialized. Check the credentials");
3260
+ }
3261
+ const info = await adobe.get(image_id);
3262
+ let newRow;
3263
+ if (info) {
3264
+ if (true) {
3265
+ const searchRow = await db.search.findOne({ where: { content_id } });
3266
+ const url = info.details_url;
3267
+ const imageRow = await db.image.findOne({ where: { url } });
3268
+ if (searchRow) {
3269
+ if (imageRow) {
3270
+ await db.search.update({ image_id: imageRow.id }, { where: { content_id } });
3271
+ } else {
3272
+ const imageData = await axios6.get(info.thumbnail_1000_url, { responseType: "arraybuffer" }).then((d) => d.data);
3273
+ const payload = {
3274
+ url,
3275
+ author: info.creator_name,
3276
+ license: "ADOBE, TO-DO"
3277
+ // TO-DO add authorization to be able to filter by license and save the full picture with no watermark
3278
+ };
3279
+ const newImage = await db.image.create(payload);
3280
+ await db.image_content.destroy({ where: { id: newImage.id } });
3281
+ const contentPayload = locales5.map((locale) => ({
3282
+ id: newImage.id,
3283
+ locale,
3284
+ meta: info.title || info.description
3285
+ // TODO include tags
3286
+ }));
3287
+ await db.image_content.bulkCreate(contentPayload);
3288
+ await db.search.update({ image_id: newImage.id }, { where: { content_id } });
3289
+ await uploadImage_default(db, newImage.id, imageData);
3290
+ }
3291
+ const newRow2 = await db.search.findOne({
3292
+ where: { content_id },
3293
+ include: imageQueryThumbOnly
3294
+ });
3295
+ if (newRow2 && newRow2.image) {
3296
+ newRow2.image.thumb = Boolean(newRow2.image.thumb);
3297
+ }
3298
+ } else {
3299
+ throw new Error("Error updating Search");
3300
+ }
3301
+ }
3302
+ } else {
3303
+ throw new Error("Malformed URL");
3304
+ }
3305
+ return {
3306
+ meta: {
3307
+ ...saveParams
3308
+ },
3309
+ results: newRow
3310
+ };
3311
+ } catch (error) {
3312
+ console.log(error);
3313
+ throw new Error("Error in save adobe provider");
3314
+ }
3315
+ }
3036
3316
 
3037
3317
  // api/db/image/imageSave.ts
3038
3318
  var saveProviders = {
3039
3319
  local: saveLocalProvider,
3040
3320
  flickr: saveFlickrProvider,
3041
3321
  unsplash: saveUnsplashProvider,
3042
- upload: saveUploadProvider
3322
+ upload: saveUploadProvider,
3323
+ adobe: saveAdobeProvider
3043
3324
  };
3044
3325
  function dbImageSaveFactory(db, provider) {
3045
3326
  const saveProvider = saveProviders[provider];
@@ -3053,7 +3334,8 @@ function dbImageSaveFactory(db, provider) {
3053
3334
  var searchProviders = {
3054
3335
  local: searchLocalProvider,
3055
3336
  flickr: searchFlickrProvider,
3056
- unsplash: searchUnsplashProvider
3337
+ unsplash: searchUnsplashProvider,
3338
+ adobe: searchAdobeProvider
3057
3339
  };
3058
3340
  function dbImageSearchFactory(db, provider) {
3059
3341
  const searchProvider = searchProviders[provider];
@@ -3101,7 +3383,7 @@ function dbRegenerateSearchFactory(db) {
3101
3383
  }
3102
3384
 
3103
3385
  // api/db/searchReport.ts
3104
- var { locales: locales5, localeDefault: localeDefault4 } = getLocales_default();
3386
+ var { locales: locales6, localeDefault: localeDefault4 } = getLocales_default();
3105
3387
  var addProfilesData = (items, metadata) => {
3106
3388
  if (!items)
3107
3389
  return [];
@@ -3168,7 +3450,7 @@ function dbSearchReportFactory(db) {
3168
3450
  return dbSearchReport;
3169
3451
  async function dbSearchReport(params) {
3170
3452
  const format = params.format || "results";
3171
- const locale = locales5.includes(params.locale) ? params.locale : localeDefault4;
3453
+ const locale = locales6.includes(params.locale) ? params.locale : localeDefault4;
3172
3454
  const memberSearchResponse = await dbSearchMember({
3173
3455
  ...params,
3174
3456
  format: "plain",
@@ -3194,7 +3476,7 @@ function dbUrlProxyFactory() {
3194
3476
  return async (request) => {
3195
3477
  const config = typeof request === "string" ? { url: request } : request;
3196
3478
  try {
3197
- const response = await axios5.request(config);
3479
+ const response = await axios6.request(config);
3198
3480
  return {
3199
3481
  ok: true,
3200
3482
  status: response.status,
@@ -3396,10 +3678,12 @@ function apiFactory(dbModels) {
3396
3678
  imageFlickrSearch: dbImageSearchFactory(dbModels, "flickr"),
3397
3679
  imageLocalSearch: dbImageSearchFactory(dbModels, "local"),
3398
3680
  imageUnsplashSearch: dbImageSearchFactory(dbModels, "unsplash"),
3681
+ imageAdobeSearch: dbImageSearchFactory(dbModels, "adobe"),
3399
3682
  imageFlickrSave: dbImageSaveFactory(dbModels, "flickr"),
3400
3683
  imageLocalSave: dbImageSaveFactory(dbModels, "local"),
3401
3684
  imageUnsplashSave: dbImageSaveFactory(dbModels, "unsplash"),
3402
3685
  imageUploadSave: dbImageSaveFactory(dbModels, "upload"),
3686
+ imageAdobeSave: dbImageSaveFactory(dbModels, "adobe"),
3403
3687
  urlProxy: dbUrlProxyFactory(),
3404
3688
  searchRole: resultWrapper(dbSearchRole()),
3405
3689
  searchUser: resultWrapper(dbSearchUser()),
@@ -3498,7 +3782,7 @@ function endpointImageSearchFactory(operations, provider) {
3498
3782
  if (!prompt) {
3499
3783
  throw new BackendError(400, "Empty 'prompt' param.");
3500
3784
  }
3501
- return searchMethod({ prompt });
3785
+ return searchMethod({ prompt, page: parseFiniteNumber(req.query.page) });
3502
3786
  }, [CMS_ROLES.EDITOR]);
3503
3787
  }
3504
3788
 
@@ -3921,9 +4205,11 @@ function getEndpointMap(db) {
3921
4205
  endpointImageSaveFactory(api, "local"),
3922
4206
  endpointImageSaveFactory(api, "unsplash"),
3923
4207
  endpointImageSaveFactory(api, "upload"),
4208
+ endpointImageSaveFactory(api, "adobe"),
3924
4209
  endpointImageSearchFactory(api, "flickr"),
3925
4210
  endpointImageSearchFactory(api, "local"),
3926
4211
  endpointImageSearchFactory(api, "unsplash"),
4212
+ endpointImageSearchFactory(api, "adobe"),
3927
4213
  endpointUrlProxyFactory(api),
3928
4214
  endpointGetRolesFactory(api),
3929
4215
  endpointGetUsersFactory(api),
@@ -3968,15 +4254,23 @@ async function endpointNextJsHandlerFactory(req, res) {
3968
4254
  if (["POST", "DELETE"].includes(method)) {
3969
4255
  req.body = await parseBody(req);
3970
4256
  }
3971
- return Promise.resolve(req).then((req2) => handlerObj.handler(req2, res, session ? session : void 0)).then((result) => {
4257
+ return Promise.resolve(req).then((req2) => handlerObj.handler(req2, res, session ? session : void 0)).then(async (result) => {
3972
4258
  if (result && "error" in result) {
3973
4259
  throw new BackendError(result.status, result.error);
3974
4260
  }
3975
- if (result.ok && req.url) {
4261
+ if (result.ok) {
3976
4262
  if (result.data instanceof Buffer) {
3977
- const image = result.data;
3978
- res.writeHead(result.status, { "Content-Type": "image/png" }).end(image, "binary");
3979
- } else if (req.url.indexOf("/icon.svg?name=") > 0) {
4263
+ const type = await imageType(result.data);
4264
+ const contentLength = Buffer.byteLength(result.data);
4265
+ res.writeHead(
4266
+ result.status,
4267
+ {
4268
+ "Content-Type": type ? type.mime : "image/jpeg",
4269
+ // Default for legacy
4270
+ "Content-Length": contentLength.toString()
4271
+ }
4272
+ ).send(result.data);
4273
+ } else if (req.url && req.url.indexOf("/icon.svg?name=") > 0) {
3980
4274
  res.setHeader("Content-Type", "image/svg+xml");
3981
4275
  res.status(result.status).send(result.data);
3982
4276
  } else {
@@ -4041,8 +4335,8 @@ __export(actions_exports, {
4041
4335
  });
4042
4336
 
4043
4337
  // api/http/lib.ts
4044
- function http(axios6, config) {
4045
- return axios6.request(config).then((response) => {
4338
+ function http(axios7, config) {
4339
+ return axios7.request(config).then((response) => {
4046
4340
  const { status, data } = response;
4047
4341
  return "error" in data ? { ok: false, status, error: data.error } : { ok: true, status, data: data.data };
4048
4342
  }, (err) => {
@@ -4053,26 +4347,26 @@ function http(axios6, config) {
4053
4347
  return { ok: false, status: 500, error: err.message };
4054
4348
  });
4055
4349
  }
4056
- function httpGET(axios6, request, transformParams) {
4350
+ function httpGET(axios7, request, transformParams) {
4057
4351
  const config = typeof request === "string" ? { url: request } : request;
4058
- return (params) => http(axios6, {
4352
+ return (params) => http(axios7, {
4059
4353
  ...config,
4060
4354
  method: "GET",
4061
4355
  params: transformParams ? transformParams(params) : params
4062
4356
  });
4063
4357
  }
4064
- function httpPOST(axios6, request, transformPayload) {
4358
+ function httpPOST(axios7, request, transformPayload) {
4065
4359
  const config = typeof request === "string" ? { url: request } : request;
4066
- return (payload) => http(axios6, {
4360
+ return (payload) => http(axios7, {
4067
4361
  ...config,
4068
4362
  method: "POST",
4069
4363
  data: transformPayload ? transformPayload(payload) : payload
4070
4364
  });
4071
4365
  }
4072
- function httpDELETE(axios6, request, transformPayload) {
4366
+ function httpDELETE(axios7, request, transformPayload) {
4073
4367
  const config = typeof request === "string" ? { url: request } : request;
4074
4368
  return (payload) => {
4075
- return http(axios6, {
4369
+ return http(axios7, {
4076
4370
  ...config,
4077
4371
  method: "DELETE",
4078
4372
  params: transformPayload ? transformPayload(payload) : payload
@@ -4081,26 +4375,26 @@ function httpDELETE(axios6, request, transformPayload) {
4081
4375
  }
4082
4376
 
4083
4377
  // api/http/image/imageSave.ts
4084
- function httpImageSaveFactory(axios6, provider) {
4085
- return (params) => http(axios6, {
4086
- method: "GET",
4087
- url: `search/images/${provider}`,
4378
+ function httpImageSaveFactory(axios7, provider) {
4379
+ return (params) => http(axios7, {
4380
+ method: "POST",
4381
+ url: `images/save/${provider}`,
4088
4382
  params: { prompt: params.prompt, provider }
4089
4383
  });
4090
4384
  }
4091
4385
 
4092
4386
  // api/http/image/imageSearch.ts
4093
- function httpImageSearchFactory(axios6, provider) {
4094
- return (params) => http(axios6, {
4387
+ function httpImageSearchFactory(axios7, provider) {
4388
+ return (params) => http(axios7, {
4095
4389
  method: "GET",
4096
- url: `search/images/${provider}`,
4097
- params: { prompt: params.prompt, provider }
4390
+ url: `images/search/${provider}`,
4391
+ params: { prompt: params.prompt, page: params.page, provider }
4098
4392
  });
4099
4393
  }
4100
4394
 
4101
4395
  // api/http/icon/listIcons.ts
4102
- function httpListIconsFactory(axios6, provider) {
4103
- return () => http(axios6, {
4396
+ function httpListIconsFactory(axios7, provider) {
4397
+ return () => http(axios7, {
4104
4398
  method: "GET",
4105
4399
  url: `list/icons/${provider}`,
4106
4400
  params: { provider }
@@ -4108,8 +4402,8 @@ function httpListIconsFactory(axios6, provider) {
4108
4402
  }
4109
4403
 
4110
4404
  // api/http/icon/readIcon.ts
4111
- function httpReadIconFactory(axios6, provider) {
4112
- return (params) => http(axios6, {
4405
+ function httpReadIconFactory(axios7, provider) {
4406
+ return (params) => http(axios7, {
4113
4407
  method: "GET",
4114
4408
  url: `read/icons/${provider}/icon.svg`,
4115
4409
  params: { name: params.name }
@@ -4133,61 +4427,63 @@ var transformReadMembers = (params) => {
4133
4427
  return { ...params, [params.mode]: params[params.mode].join(",") };
4134
4428
  };
4135
4429
  function apiFactory2(baseURL) {
4136
- const axios6 = axios5.create({ baseURL });
4430
+ const axios7 = axios6.create({ baseURL });
4137
4431
  return {
4138
- createBlock: httpPOST(axios6, "create/block"),
4139
- createDimension: httpPOST(axios6, "create/dimension"),
4140
- createFormatter: httpPOST(axios6, "create/formatter"),
4141
- createReport: httpPOST(axios6, "create/report"),
4142
- createSection: httpPOST(axios6, "create/section"),
4143
- createVariant: httpPOST(axios6, "create/variant"),
4144
- deleteBlock: httpDELETE(axios6, "delete/block", transformDeletePayload),
4145
- deleteDimension: httpDELETE(axios6, "delete/dimension", transformDeletePayload),
4146
- deleteFormatter: httpDELETE(axios6, "delete/formatter", transformDeletePayload),
4147
- deleteReport: httpDELETE(axios6, "delete/report", transformDeletePayload),
4148
- deleteSection: httpDELETE(axios6, "delete/section", transformDeletePayload),
4149
- deleteVariant: httpDELETE(axios6, "delete/variant", transformDeletePayload),
4150
- readBlock: httpGET(axios6, "read/block"),
4151
- readDimension: httpGET(axios6, "read/dimension"),
4152
- readFormatter: httpGET(axios6, "read/formatter"),
4153
- readReport: httpGET(axios6, "read/report"),
4154
- readSection: httpGET(axios6, "read/section"),
4155
- readVariant: httpGET(axios6, "read/variant"),
4156
- updateBlock: httpPOST(axios6, "update/block"),
4157
- updateDimension: httpPOST(axios6, "update/dimension"),
4158
- updateFormatter: httpPOST(axios6, "update/formatter"),
4159
- updateReport: httpPOST(axios6, "update/report"),
4160
- updateSection: httpPOST(axios6, "update/section"),
4161
- updateVariant: httpPOST(axios6, "update/variant"),
4162
- searchReport: httpGET(axios6, "search/reports"),
4163
- validateVariantSlug: httpGET(axios6, "validate/variant"),
4164
- readMember: httpGET(axios6, "read/members", transformReadMembers),
4165
- readMemberImage: httpGET(axios6, {
4166
- url: "member/image.png",
4432
+ createBlock: httpPOST(axios7, "create/block"),
4433
+ createDimension: httpPOST(axios7, "create/dimension"),
4434
+ createFormatter: httpPOST(axios7, "create/formatter"),
4435
+ createReport: httpPOST(axios7, "create/report"),
4436
+ createSection: httpPOST(axios7, "create/section"),
4437
+ createVariant: httpPOST(axios7, "create/variant"),
4438
+ deleteBlock: httpDELETE(axios7, "delete/block", transformDeletePayload),
4439
+ deleteDimension: httpDELETE(axios7, "delete/dimension", transformDeletePayload),
4440
+ deleteFormatter: httpDELETE(axios7, "delete/formatter", transformDeletePayload),
4441
+ deleteReport: httpDELETE(axios7, "delete/report", transformDeletePayload),
4442
+ deleteSection: httpDELETE(axios7, "delete/section", transformDeletePayload),
4443
+ deleteVariant: httpDELETE(axios7, "delete/variant", transformDeletePayload),
4444
+ readBlock: httpGET(axios7, "read/block"),
4445
+ readDimension: httpGET(axios7, "read/dimension"),
4446
+ readFormatter: httpGET(axios7, "read/formatter"),
4447
+ readReport: httpGET(axios7, "read/report"),
4448
+ readSection: httpGET(axios7, "read/section"),
4449
+ readVariant: httpGET(axios7, "read/variant"),
4450
+ updateBlock: httpPOST(axios7, "update/block"),
4451
+ updateDimension: httpPOST(axios7, "update/dimension"),
4452
+ updateFormatter: httpPOST(axios7, "update/formatter"),
4453
+ updateReport: httpPOST(axios7, "update/report"),
4454
+ updateSection: httpPOST(axios7, "update/section"),
4455
+ updateVariant: httpPOST(axios7, "update/variant"),
4456
+ searchReport: httpGET(axios7, "search/reports"),
4457
+ validateVariantSlug: httpGET(axios7, "validate/variant"),
4458
+ readMember: httpGET(axios7, "read/members", transformReadMembers),
4459
+ readMemberImage: httpGET(axios7, {
4460
+ url: "member/image",
4167
4461
  responseType: "blob"
4168
4462
  }),
4169
- searchMember: httpGET(axios6, "search/members"),
4170
- updateMember: httpGET(axios6, "update/members"),
4171
- imageLocalSearch: httpImageSearchFactory(axios6, "local"),
4172
- imageLocalSave: httpImageSaveFactory(axios6, "local"),
4173
- imageFlickrSearch: httpImageSearchFactory(axios6, "flickr"),
4174
- imageFlickrSave: httpImageSaveFactory(axios6, "flickr"),
4175
- imageUnsplashSearch: httpImageSearchFactory(axios6, "unsplash"),
4176
- imageUnsplashSave: httpImageSaveFactory(axios6, "unsplash"),
4177
- imageUploadSave: httpImageSaveFactory(axios6, "upload"),
4178
- readMetadata: httpGET(axios6, "read/metadata"),
4179
- regenerateSearch: httpPOST(axios6, "search/regenerate"),
4180
- urlProxy: httpGET(axios6, "url/proxy"),
4181
- searchRole: httpGET(axios6, "auth/search/roles"),
4182
- searchUser: httpGET(axios6, "auth/search/users"),
4183
- readUser: httpGET(axios6, "auth/read/user"),
4184
- updateUser: httpPOST(axios6, "auth/update/user"),
4185
- addNewReportToCurrentUser: httpPOST(axios6, "auth/update/me"),
4186
- revalidateReport: httpGET(axios6, "revalidate/report"),
4187
- revalidateUrl: httpGET(axios6, "revalidate/url"),
4188
- readPrivateBlocks: httpPOST(axios6, "read/blocks/private"),
4189
- listTablerIcons: httpListIconsFactory(axios6, "tabler"),
4190
- readTablerIcon: httpReadIconFactory(axios6, "tabler")
4463
+ searchMember: httpGET(axios7, "search/members"),
4464
+ updateMember: httpGET(axios7, "update/members"),
4465
+ imageLocalSearch: httpImageSearchFactory(axios7, "local"),
4466
+ imageLocalSave: httpImageSaveFactory(axios7, "local"),
4467
+ imageFlickrSearch: httpImageSearchFactory(axios7, "flickr"),
4468
+ imageFlickrSave: httpImageSaveFactory(axios7, "flickr"),
4469
+ imageUnsplashSearch: httpImageSearchFactory(axios7, "unsplash"),
4470
+ imageUnsplashSave: httpImageSaveFactory(axios7, "unsplash"),
4471
+ imageUploadSave: httpImageSaveFactory(axios7, "upload"),
4472
+ imageAdobeSearch: httpImageSearchFactory(axios7, "adobe"),
4473
+ imageAdobeSave: httpImageSaveFactory(axios7, "adobe"),
4474
+ readMetadata: httpGET(axios7, "read/metadata"),
4475
+ regenerateSearch: httpPOST(axios7, "search/regenerate"),
4476
+ urlProxy: httpGET(axios7, "url/proxy"),
4477
+ searchRole: httpGET(axios7, "auth/search/roles"),
4478
+ searchUser: httpGET(axios7, "auth/search/users"),
4479
+ readUser: httpGET(axios7, "auth/read/user"),
4480
+ updateUser: httpPOST(axios7, "auth/update/user"),
4481
+ addNewReportToCurrentUser: httpPOST(axios7, "auth/update/me"),
4482
+ revalidateReport: httpGET(axios7, "revalidate/report"),
4483
+ revalidateUrl: httpGET(axios7, "revalidate/url"),
4484
+ readPrivateBlocks: httpPOST(axios7, "read/blocks/private"),
4485
+ listTablerIcons: httpListIconsFactory(axios7, "tabler"),
4486
+ readTablerIcon: httpReadIconFactory(axios7, "tabler")
4191
4487
  };
4192
4488
  }
4193
4489
 
@@ -4402,9 +4698,9 @@ var selectorQueryToVariable = (id, query, config) => {
4402
4698
  var selectorQueryToVariable_default = selectorQueryToVariable;
4403
4699
 
4404
4700
  // libs/blocks/getBlockContent.ts
4405
- var { localeDefault: localeDefault7, locales: locales6 } = getLocales_default();
4701
+ var { localeDefault: localeDefault7, locales: locales7 } = getLocales_default();
4406
4702
  var logicTypes = Object.values(BLOCK_LOGIC_TYPES);
4407
- var getLocaleDerived = (block, locale = localeDefault7) => block && logicTypes.includes(block.type) ? { locale: BLOCK_LOGIC_LOCALE, locales: [BLOCK_LOGIC_LOCALE] } : { locale, locales: locales6 };
4703
+ var getLocaleDerived = (block, locale = localeDefault7) => block && logicTypes.includes(block.type) ? { locale: BLOCK_LOGIC_LOCALE, locales: [BLOCK_LOGIC_LOCALE] } : { locale, locales: locales7 };
4408
4704
  var getBlockContent = (block, _locale = localeDefault7) => {
4409
4705
  if (!block)
4410
4706
  return {};
@@ -4425,12 +4721,9 @@ function getRootBlocksForSection(sid, blocks) {
4425
4721
  );
4426
4722
  }
4427
4723
  var getRootBlocksForSection_default = getRootBlocksForSection;
4428
-
4429
- // libs/consts.ts
4430
- var apiSeparator = "|||";
4431
4724
  var debug = yn2(process.env.NEXT_PUBLIC_REPORTS_DEBUG);
4432
4725
  var ORIGIN = process.env.REPORTS_ORIGIN || "";
4433
- axiosRetry(axios5, {
4726
+ axiosRetry(axios6, {
4434
4727
  retries: 3,
4435
4728
  retryDelay: axiosRetry.exponentialDelay,
4436
4729
  onRetry: (retryCount, error, requestConfig) => {
@@ -4439,11 +4732,11 @@ axiosRetry(axios5, {
4439
4732
  console.log(error.message);
4440
4733
  }
4441
4734
  });
4442
- axios5.interceptors.request.use((config) => ({
4735
+ axios6.interceptors.request.use((config) => ({
4443
4736
  ...config,
4444
4737
  requestStart: Date.now()
4445
4738
  }));
4446
- axios5.interceptors.response.use((d) => ({
4739
+ axios6.interceptors.response.use((d) => ({
4447
4740
  ...d,
4448
4741
  requestDuration: (/* @__PURE__ */ new Date()).getTime() - d.config.requestStart
4449
4742
  }), (e) => Promise.reject(e));
@@ -4482,7 +4775,7 @@ async function apiFetch(url, settings, readMemberFn, locale = "en") {
4482
4775
  }
4483
4776
  } else {
4484
4777
  try {
4485
- const response = await axios5({
4778
+ const response = await axios6({
4486
4779
  url: finalUrl,
4487
4780
  timeout: apiFetchTimeout
4488
4781
  });
@@ -5100,14 +5393,14 @@ var funcifyFormattersByLocale = (formatters = [], locale = localeDefault8) => fo
5100
5393
 
5101
5394
  // store/envvars.ts
5102
5395
  var localeDefault9 = process.env.NEXT_PUBLIC_REPORTS_LOCALE_DEFAULT || "en";
5103
- var locales7 = process.env.NEXT_PUBLIC_REPORTS_LOCALES?.split(",") || [localeDefault9];
5104
- if (!locales7.includes(localeDefault9))
5105
- locales7.push(localeDefault9);
5396
+ var locales8 = process.env.NEXT_PUBLIC_REPORTS_LOCALES?.split(",") || [localeDefault9];
5397
+ if (!locales8.includes(localeDefault9))
5398
+ locales8.push(localeDefault9);
5106
5399
 
5107
5400
  // store/statusSlice.ts
5108
5401
  var initialState = {
5109
5402
  localeDefault: localeDefault9,
5110
- locales: locales7,
5403
+ locales: locales8,
5111
5404
  currentLocale: localeDefault9,
5112
5405
  showToolbar: false,
5113
5406
  activeSection: null,
@@ -5896,10 +6189,10 @@ function parseReportId(value) {
5896
6189
  const [, reportId] = Array.isArray(value) ? value : [value];
5897
6190
  return Number.parseInt(reportId) || void 0;
5898
6191
  }
5899
- var { locales: locales8 } = getLocales_default();
6192
+ var { locales: locales9 } = getLocales_default();
5900
6193
  var initialContext = {
5901
6194
  pathSegment: "path",
5902
- formatterFunctions: locales8.reduce((acc, d) => ({ ...acc, [d]: {} }), {}),
6195
+ formatterFunctions: locales9.reduce((acc, d) => ({ ...acc, [d]: {} }), {}),
5903
6196
  profilePrefix: "path",
5904
6197
  siteProps: {}
5905
6198
  };
@@ -5925,11 +6218,11 @@ function BespokeRendererStaticPaths(options) {
5925
6218
  return async (context) => {
5926
6219
  const {
5927
6220
  defaultLocale = localeDefault9,
5928
- locales: locales9 = []
6221
+ locales: locales10 = []
5929
6222
  } = context;
5930
6223
  let paths = [];
5931
6224
  if (limit > 0) {
5932
- const locale = locales9.find((token) => token === defaultLocale);
6225
+ const locale = locales10.find((token) => token === defaultLocale);
5933
6226
  const { searchMember: searchMember2 } = await getDB().then(apiFactory);
5934
6227
  const req = await searchMember2({
5935
6228
  query: "",
@@ -5946,7 +6239,7 @@ function BespokeRendererStaticPaths(options) {
5946
6239
  });
5947
6240
  if (req.ok === true) {
5948
6241
  paths = req.data.results.map((item) => ({
5949
- locale: locales9.find((token) => token === item.locale),
6242
+ locale: locales10.find((token) => token === item.locale),
5950
6243
  params: {
5951
6244
  bespoke: [item.variant.slug, item.slug]
5952
6245
  // TODO: fix SearchResult definition