{"version":3,"file":"pushCronIdentifiersFromCsv-BPLwrNmv.mjs","names":[],"sources":["../src/lib/cron/markCronIdentifierCompleted.ts","../src/lib/cron/pushCronIdentifiersFromCsv.ts"],"sourcesContent":["import type { Got } from 'got';\nimport * as t from 'io-ts';\n\n/**\n * Minimal set required to mark as completed\n */\nexport const CronIdentifierPush = t.type({\n  nonce: t.string,\n  identifier: t.string,\n});\n\n/** Type override */\nexport type CronIdentifierPush = t.TypeOf<typeof CronIdentifierPush>;\n\n/**\n * Mark an identifier output by the cron job as completed.\n *\n * @see https://docs.transcend.io/docs/api-reference/PUT/v1/data-silo\n * @param sombra - Sombra instance configured to make requests\n * @param options - Additional options\n * @returns Successfully submitted request, false if not in a state to update\n */\nexport async function markCronIdentifierCompleted(\n  sombra: Got,\n  { nonce, identifier }: CronIdentifierPush,\n): Promise<boolean> {\n  try {\n    // Make the GraphQL request\n    await sombra.put('v1/data-silo', {\n      headers: {\n        'x-transcend-nonce': nonce,\n      },\n      json: {\n        profiles: [\n          {\n            profileId: identifier,\n          },\n        ],\n      },\n    });\n    return true;\n  } catch (err) {\n    // handle gracefully\n    if (err.response?.statusCode === 409) {\n      return false;\n    }\n    throw new Error(`Received an error from server: ${err?.response?.body || err?.message}`);\n  }\n}\n","import { createSombraGotInstance } from '@transcend-io/sdk';\nimport { map, mapSeries } from '@transcend-io/utils';\nimport cliProgress from 'cli-progress';\nimport colors from 'colors';\nimport { chunk } from 'lodash-es';\n\nimport { DEFAULT_TRANSCEND_API } from '../../constants.js';\nimport { logger } from '../../logger.js';\nimport { readCsv } from '../requests/index.js';\nimport { markCronIdentifierCompleted, CronIdentifierPush } from './markCronIdentifierCompleted.js';\n\n/**\n * Given a CSV of cron job outputs, mark all requests as completed in Transcend\n *\n * @param options - Options\n * @returns Number of items marked as completed\n */\nexport async function pushCronIdentifiersFromCsv({\n  file,\n  dataSiloId,\n  auth,\n  sombraAuth,\n  concurrency = 100,\n  transcendUrl = DEFAULT_TRANSCEND_API,\n  sleepSeconds = 10,\n}: {\n  /** CSV file path */\n  file: string;\n  /** Transcend API key authentication */\n  auth: string;\n  /** Data Silo ID to pull down jobs for */\n  dataSiloId: string;\n  /** Upload concurrency */\n  concurrency?: number;\n  /** API URL for Transcend backend */\n  transcendUrl?: string;\n  /** Sombra API key authentication */\n  sombraAuth?: string;\n  /** Sleep time in seconds between chunks of concurrent calls */\n  sleepSeconds?: number;\n}): Promise<number> {\n  // Create sombra instance to communicate with\n  const sombra = await createSombraGotInstance(transcendUrl, auth, {\n    logger,\n    sombraApiKey: sombraAuth,\n    sombraUrl: process.env.SOMBRA_URL,\n  });\n\n  // Read from CSV\n  logger.info(colors.magenta(`Reading \"${file}\" from disk`));\n  const activeResults = readCsv(file, CronIdentifierPush);\n\n  // Notify Transcend\n  logger.info(\n    colors.magenta(\n      `Notifying Transcend for data silo \"${dataSiloId}\" marking \"${activeResults.length}\" identifiers as completed.`,\n    ),\n  );\n\n  // Time duration\n  const t0 = new Date().getTime();\n  // create a new progress bar instance and use shades_classic theme\n  const progressBar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);\n\n  let successCount = 0;\n  let failureCount = 0;\n  let errorCount = 0;\n  progressBar.start(activeResults.length, 0);\n\n  // Process in chunks with sleep intervals\n  const chunks = chunk(activeResults, concurrency);\n  const totalChunks = chunks.length;\n  const processChunk = async (items: CronIdentifierPush[], chunkIndex: number): Promise<void> => {\n    logger.info(\n      colors.blue(`Processing chunk ${chunkIndex + 1}/${totalChunks} (${chunk.length} items)`),\n    );\n\n    // Process the items of the chunk concurrently\n    await map(items, async (identifier) => {\n      try {\n        const success = await markCronIdentifierCompleted(sombra, identifier);\n        if (success) {\n          successCount += 1;\n        } else {\n          failureCount += 1;\n        }\n      } catch (e) {\n        logger.error(\n          colors.red(\n            `Error notifying Transcend for identifier \"${identifier.identifier}\" - ${e?.message}`,\n          ),\n        );\n        errorCount += 1;\n      }\n      progressBar.update(successCount + failureCount);\n    });\n\n    // Sleep between chunks (except for the last chunk)\n    if (sleepSeconds > 0 && chunkIndex < totalChunks - 1) {\n      logger.info(colors.yellow(`Sleeping for ${sleepSeconds}s before next chunk...`));\n\n      await new Promise((resolve) => {\n        setTimeout(resolve, sleepSeconds * 1000);\n      });\n    }\n  };\n\n  // Process all chunks sequentially\n  await mapSeries(chunks, processChunk);\n\n  progressBar.stop();\n  const t1 = new Date().getTime();\n  const totalTime = t1 - t0;\n\n  logger.info(\n    colors.green(\n      `Successfully notified Transcend for ${successCount} identifiers in \"${\n        totalTime / 1000\n      }\" seconds!`,\n    ),\n  );\n  if (failureCount) {\n    logger.info(\n      colors.magenta(\n        `There were ${failureCount} identifiers that were not in a state to be updated.` +\n          'They likely have already been resolved.',\n      ),\n    );\n  }\n  if (errorCount) {\n    logger.error(\n      colors.red(\n        `There were ${errorCount} identifiers that failed to be updated. Please review the logs for more information.`,\n      ),\n    );\n    throw new Error('Failed to update all identifiers');\n  }\n  return activeResults.length;\n}\n"],"mappings":"8VAMA,MAAa,EAAqB,EAAE,KAAK,CACvC,MAAO,EAAE,OACT,WAAY,EAAE,OACf,CAAC,CAaF,eAAsB,EACpB,EACA,CAAE,QAAO,cACS,CAClB,GAAI,CAcF,OAZA,MAAM,EAAO,IAAI,eAAgB,CAC/B,QAAS,CACP,oBAAqB,EACtB,CACD,KAAM,CACJ,SAAU,CACR,CACE,UAAW,EACZ,CACF,CACF,CACF,CAAC,CACK,SACA,EAAK,CAEZ,GAAI,EAAI,UAAU,aAAe,IAC/B,MAAO,GAET,MAAU,MAAM,kCAAkC,GAAK,UAAU,MAAQ,GAAK,UAAU,EC7B5F,eAAsB,EAA2B,CAC/C,OACA,aACA,OACA,aACA,cAAc,IACd,eAAe,EACf,eAAe,IAgBG,CAElB,IAAM,EAAS,MAAM,EAAwB,EAAc,EAAM,CAC/D,SACA,aAAc,EACd,UAAW,QAAQ,IAAI,WACxB,CAAC,CAGF,EAAO,KAAK,EAAO,QAAQ,YAAY,EAAK,aAAa,CAAC,CAC1D,IAAM,EAAgB,EAAQ,EAAM,EAAmB,CAGvD,EAAO,KACL,EAAO,QACL,sCAAsC,EAAW,aAAa,EAAc,OAAO,6BACpF,CACF,CAGD,IAAM,EAAK,IAAI,MAAM,CAAC,SAAS,CAEzB,EAAc,IAAI,EAAY,UAAU,EAAE,CAAE,EAAY,QAAQ,eAAe,CAEjF,EAAe,EACf,EAAe,EACf,EAAa,EACjB,EAAY,MAAM,EAAc,OAAQ,EAAE,CAG1C,IAAM,EAAS,EAAM,EAAe,EAAY,CAC1C,EAAc,EAAO,OAqC3B,MAAM,EAAU,EAAQ,MApCI,EAA6B,IAAsC,CAC7F,EAAO,KACL,EAAO,KAAK,oBAAoB,EAAa,EAAE,GAAG,EAAY,IAAI,EAAM,OAAO,SAAS,CACzF,CAGD,MAAM,EAAI,EAAO,KAAO,IAAe,CACrC,GAAI,CAEE,MADkB,EAA4B,EAAQ,EAAW,CAEnE,GAAgB,EAEhB,GAAgB,QAEX,EAAG,CACV,EAAO,MACL,EAAO,IACL,6CAA6C,EAAW,WAAW,MAAM,GAAG,UAC7E,CACF,CACD,GAAc,EAEhB,EAAY,OAAO,EAAe,EAAa,EAC/C,CAGE,EAAe,GAAK,EAAa,EAAc,IACjD,EAAO,KAAK,EAAO,OAAO,gBAAgB,EAAa,wBAAwB,CAAC,CAEhF,MAAM,IAAI,QAAS,GAAY,CAC7B,WAAW,EAAS,EAAe,IAAK,EACxC,GAK+B,CAErC,EAAY,MAAM,CAElB,IAAM,EADK,IAAI,MAAM,CAAC,SACF,CAAG,EAiBvB,GAfA,EAAO,KACL,EAAO,MACL,uCAAuC,EAAa,mBAClD,EAAY,IACb,YACF,CACF,CACG,GACF,EAAO,KACL,EAAO,QACL,cAAc,EAAa,6FAE5B,CACF,CAEC,EAMF,MALA,EAAO,MACL,EAAO,IACL,cAAc,EAAW,sFAC1B,CACF,CACS,MAAM,mCAAmC,CAErD,OAAO,EAAc"}