@gadgetinc/ggt 1.0.2 → 1.0.3

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.
Files changed (99) hide show
  1. package/README.md +192 -128
  2. package/lib/__generated__/graphql.js.map +1 -1
  3. package/lib/commands/add.js +385 -0
  4. package/lib/commands/add.js.map +1 -0
  5. package/lib/commands/deploy.js +20 -102
  6. package/lib/commands/deploy.js.map +1 -1
  7. package/lib/commands/dev.js +43 -114
  8. package/lib/commands/dev.js.map +1 -1
  9. package/lib/commands/list.js +3 -6
  10. package/lib/commands/list.js.map +1 -1
  11. package/lib/commands/login.js +2 -5
  12. package/lib/commands/login.js.map +1 -1
  13. package/lib/commands/logout.js +2 -5
  14. package/lib/commands/logout.js.map +1 -1
  15. package/lib/commands/open.js +45 -86
  16. package/lib/commands/open.js.map +1 -1
  17. package/lib/commands/pull.js +19 -76
  18. package/lib/commands/pull.js.map +1 -1
  19. package/lib/commands/push.js +19 -76
  20. package/lib/commands/push.js.map +1 -1
  21. package/lib/commands/root.js +4 -3
  22. package/lib/commands/root.js.map +1 -1
  23. package/lib/commands/status.js +3 -8
  24. package/lib/commands/status.js.map +1 -1
  25. package/lib/commands/version.js +6 -5
  26. package/lib/commands/version.js.map +1 -1
  27. package/lib/commands/whoami.js +2 -5
  28. package/lib/commands/whoami.js.map +1 -1
  29. package/lib/ggt.js.map +1 -1
  30. package/lib/main.js.map +1 -1
  31. package/lib/services/app/api/api.js.map +1 -1
  32. package/lib/services/app/api/operation.js +11 -0
  33. package/lib/services/app/api/operation.js.map +1 -1
  34. package/lib/services/app/app.js +21 -2
  35. package/lib/services/app/app.js.map +1 -1
  36. package/lib/services/app/arg.js.map +1 -1
  37. package/lib/services/app/client.js.map +1 -1
  38. package/lib/services/app/edit/edit.js.map +1 -1
  39. package/lib/services/app/edit/operation.js +52 -0
  40. package/lib/services/app/edit/operation.js.map +1 -1
  41. package/lib/services/app/error.js.map +1 -1
  42. package/lib/services/command/arg.js +3 -1
  43. package/lib/services/command/arg.js.map +1 -1
  44. package/lib/services/command/command.js +1 -0
  45. package/lib/services/command/command.js.map +1 -1
  46. package/lib/services/command/context.js.map +1 -1
  47. package/lib/services/config/config.js.map +1 -1
  48. package/lib/services/config/env.js.map +1 -1
  49. package/lib/services/config/package-json.js.map +1 -1
  50. package/lib/services/filesync/changes.js.map +1 -1
  51. package/lib/services/filesync/conflicts.js.map +1 -1
  52. package/lib/services/filesync/directory.js.map +1 -1
  53. package/lib/services/filesync/error.js +1 -0
  54. package/lib/services/filesync/error.js.map +1 -1
  55. package/lib/services/filesync/file.js.map +1 -1
  56. package/lib/services/filesync/filesync.js +179 -174
  57. package/lib/services/filesync/filesync.js.map +1 -1
  58. package/lib/services/filesync/hashes.js.map +1 -1
  59. package/lib/services/filesync/strategy.js.map +1 -1
  60. package/lib/services/filesync/sync-json.js.map +1 -1
  61. package/lib/services/http/auth.js.map +1 -1
  62. package/lib/services/http/http.js.map +1 -1
  63. package/lib/services/output/confirm.js.map +1 -1
  64. package/lib/services/output/footer.js.map +1 -1
  65. package/lib/services/output/log/field.js.map +1 -1
  66. package/lib/services/output/log/format/format.js.map +1 -1
  67. package/lib/services/output/log/format/json.js.map +1 -1
  68. package/lib/services/output/log/format/pretty.js.map +1 -1
  69. package/lib/services/output/log/level.js.map +1 -1
  70. package/lib/services/output/log/logger.js.map +1 -1
  71. package/lib/services/output/log/structured.js.map +1 -1
  72. package/lib/services/output/notify.js.map +1 -1
  73. package/lib/services/output/output.js.map +1 -1
  74. package/lib/services/output/print.js.map +1 -1
  75. package/lib/services/output/problems.js.map +1 -1
  76. package/lib/services/output/prompt.js.map +1 -1
  77. package/lib/services/output/report.js.map +1 -1
  78. package/lib/services/output/select.js.map +1 -1
  79. package/lib/services/output/spinner.js.map +1 -1
  80. package/lib/services/output/sprint.js.map +1 -1
  81. package/lib/services/output/symbols.js.map +1 -1
  82. package/lib/services/output/table.js.map +1 -1
  83. package/lib/services/output/timestamp.js.map +1 -1
  84. package/lib/services/output/update.js.map +1 -1
  85. package/lib/services/user/session.js.map +1 -1
  86. package/lib/services/user/user.js.map +1 -1
  87. package/lib/services/util/assert.js.map +1 -1
  88. package/lib/services/util/boolean.js.map +1 -1
  89. package/lib/services/util/collection.js.map +1 -1
  90. package/lib/services/util/function.js.map +1 -1
  91. package/lib/services/util/is.js.map +1 -1
  92. package/lib/services/util/json.js.map +1 -1
  93. package/lib/services/util/number.js.map +1 -1
  94. package/lib/services/util/object.js.map +1 -1
  95. package/lib/services/util/paths.js.map +1 -1
  96. package/lib/services/util/promise.js.map +1 -1
  97. package/lib/services/util/types.js.map +1 -1
  98. package/npm-shrinkwrap.json +2071 -1684
  99. package/package.json +30 -30
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/spinner.ts"],"sourcesContent":["import type { ColorName } from \"chalk\";\nimport chalk from \"chalk\";\nimport chalkTemplate from \"chalk-template\";\nimport type { SpinnerName } from \"cli-spinners\";\nimport cliSpinners from \"cli-spinners\";\nimport assert from \"node:assert\";\nimport os from \"node:os\";\nimport { dedent } from \"ts-dedent\";\nimport { isString } from \"../util/is.js\";\nimport { output } from \"./output.js\";\nimport { isSprintOptions, sprintln } from \"./sprint.js\";\nimport { symbol } from \"./symbols.js\";\n\nexport type SpinnerOptions = {\n /**\n * Whether to ensure a new line is after the text.\n *\n * @default false\n */\n ensureNewLine?: boolean;\n\n /**\n * Whether to ensure an empty line is above the spinner.\n *\n * @default false\n */\n ensureEmptyLineAbove?: boolean;\n\n /**\n * The name of the spinner to use.\n *\n * @default \"dots\"\n * @see https://github.com/sindresorhus/cli-spinners\n */\n kind?: SpinnerName;\n\n /**\n * The color of the spinner.\n *\n * @default \"cyan\"\n * @see https://github.com/chalk/chalk\n */\n color?: ColorName;\n\n /**\n * The symbol to display when the spinner succeeds.\n *\n * @default \"✔\"\n */\n successSymbol?: string;\n\n /**\n * The symbol to display when the spinner fails.\n *\n * @default \"✖\"\n */\n failSymbol?: string;\n};\n\nexport type spin = {\n (str: string): spinner;\n (template: TemplateStringsArray, ...values: unknown[]): spinner;\n (options: Omit<SpinnerOptions, \"str\">): spin;\n};\n\nexport type spinner = {\n text: string;\n clear: () => void;\n succeed: {\n (str?: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n };\n fail: {\n (str?: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n };\n};\n\nexport let activeSpinner: spinner | undefined;\n\nexport const createSpin = (options: SpinnerOptions): spin => {\n return ((optionsOrString: SpinnerOptions | string | TemplateStringsArray, ...values: unknown[]): spin | spinner => {\n if (isSprintOptions(optionsOrString)) {\n return createSpin({ ...options, ...optionsOrString });\n }\n\n assert(!activeSpinner, \"a spinner is already active\");\n\n let str = optionsOrString as string;\n if (!isString(str)) {\n str = sprintln(str, ...values);\n }\n\n const {\n ensureNewLine = true,\n ensureEmptyLineAbove = false,\n kind = \"dots\",\n color = \"white\",\n successSymbol = chalk.green(symbol.tick),\n failSymbol = chalk.red(symbol.cross),\n } = options;\n\n let frameIndex = 0;\n const frames = cliSpinners[kind].frames;\n const interval = cliSpinners[kind].interval;\n\n type RenderOptions = { symbol?: string; message: string; final?: boolean };\n let firstRender = true;\n\n const render = ({ symbol, message, final: finalRender = false }: RenderOptions): void => {\n // strip leading and trailing newlines so we can add them back in\n // the right place\n while (message.startsWith(\"\\n\")) {\n message = message.slice(1);\n }\n\n while (message.endsWith(\"\\n\")) {\n message = message.slice(0, -1);\n }\n\n // if no symbol is provided, use the next frame\n if (symbol === undefined) {\n frameIndex = ++frameIndex % frames.length;\n symbol = chalk[color](frames[frameIndex]);\n }\n\n if (message) {\n // we have a message to display\n if (symbol) {\n // add the spinner symbol to the first line of the message\n const lines = message.split(/\\r?\\n/);\n lines[0] = `${symbol} ${lines[0]}`;\n message = lines.join(os.EOL);\n }\n\n if (ensureEmptyLineAbove && !message.startsWith(\"\\n\")) {\n // add an empty line before the symbol\n message = \"\\n\" + message;\n }\n\n if (ensureNewLine && !message.endsWith(\"\\n\")) {\n // add a newline after the message\n message += \"\\n\";\n }\n }\n\n if (finalRender) {\n if (!output.isInteractive && ensureEmptyLineAbove) {\n // we're in a non-interactive terminal, therefor\n // ensureEmptyLineAbove only applies to the first render.\n // strip it so that the final render of the spinner is right\n // below the first render of the spinner\n message = message.slice(1);\n }\n\n // this is the final render, so persist the spinner\n output.persistSpinner(message);\n activeSpinner = undefined;\n return;\n }\n\n // this is not the final render, so we need to update the spinner\n if (output.isInteractive) {\n // we're in an interactive terminal, so update the spinner\n output.updateSpinner(message);\n } else if (firstRender) {\n // we're not in an interactive terminal, and this is the first\n // render, so just write the first render to stdout\n output.writeStdout(message);\n firstRender = false;\n }\n };\n\n // render the first frame\n render({ message: str });\n\n let spinnerInterval: NodeJS.Timeout | undefined;\n if (output.isInteractive) {\n // we are in an interactive terminal, so keep rendering the spinner\n spinnerInterval = setInterval(() => render({ message: str }), interval);\n }\n\n // setup the last render\n const finalRender = (renderOptions: Omit<RenderOptions, \"final\">): void => {\n render({ ...renderOptions, final: true });\n clearInterval(spinnerInterval);\n };\n\n activeSpinner = {\n text: str,\n clear(): void {\n this.text = \"\";\n finalRender({ symbol: \"\", message: \"\" });\n },\n succeed(finalStr?: string | TemplateStringsArray, ...values: unknown[]): void {\n finalStr ??= str;\n if (!isString(finalStr)) {\n finalStr = dedent(chalkTemplate(finalStr, ...values));\n }\n this.text = finalStr;\n finalRender({ message: finalStr, symbol: successSymbol });\n },\n fail(finalStr?: string | TemplateStringsArray, ...values: unknown[]): void {\n finalStr ??= str;\n if (!isString(finalStr)) {\n finalStr = dedent(chalkTemplate(finalStr, ...values));\n }\n this.text = finalStr;\n finalRender({ message: finalStr, symbol: failSymbol });\n },\n };\n\n return activeSpinner;\n }) as spin;\n};\n\nexport const spin = createSpin({});\n"],"names":["chalk","chalkTemplate","cliSpinners","assert","os","dedent","isString","output","isSprintOptions","sprintln","symbol","activeSpinner","createSpin","options","optionsOrString","values","str","ensureNewLine","ensureEmptyLineAbove","kind","color","successSymbol","green","tick","failSymbol","red","cross","frameIndex","frames","interval","firstRender","render","message","final","finalRender","startsWith","slice","endsWith","undefined","length","lines","split","join","EOL","isInteractive","persistSpinner","updateSpinner","writeStdout","spinnerInterval","setInterval","renderOptions","clearInterval","text","clear","succeed","finalStr","fail","spin"],"mappings":"AACA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,mBAAmB,iBAAiB;AAE3C,OAAOC,iBAAiB,eAAe;AACvC,OAAOC,YAAY,cAAc;AACjC,OAAOC,QAAQ,UAAU;AACzB,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,SAASC,MAAM,QAAQ,cAAc;AACrC,SAASC,eAAe,EAAEC,QAAQ,QAAQ,cAAc;AACxD,SAASC,MAAM,QAAQ,eAAe;AAmEtC,OAAO,IAAIC,cAAmC;AAE9C,OAAO,MAAMC,aAAa,CAACC;IACzB,OAAQ,CAACC,iBAAiE,GAAGC;QAC3E,IAAIP,gBAAgBM,kBAAkB;YACpC,OAAOF,WAAW;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,eAAe;YAAC;QACrD;QAEAX,OAAO,CAACQ,eAAe;QAEvB,IAAIK,MAAMF;QACV,IAAI,CAACR,SAASU,MAAM;YAClBA,MAAMP,SAASO,QAAQD;QACzB;QAEA,MAAM,EACJE,gBAAgB,IAAI,EACpBC,uBAAuB,KAAK,EAC5BC,OAAO,MAAM,EACbC,QAAQ,OAAO,EACfC,gBAAgBrB,MAAMsB,KAAK,CAACZ,OAAOa,IAAI,CAAC,EACxCC,aAAaxB,MAAMyB,GAAG,CAACf,OAAOgB,KAAK,CAAC,EACrC,GAAGb;QAEJ,IAAIc,aAAa;QACjB,MAAMC,SAAS1B,WAAW,CAACiB,KAAK,CAACS,MAAM;QACvC,MAAMC,WAAW3B,WAAW,CAACiB,KAAK,CAACU,QAAQ;QAG3C,IAAIC,cAAc;QAElB,MAAMC,SAAS,CAAC,EAAErB,MAAM,EAAEsB,OAAO,EAAEC,OAAOC,cAAc,KAAK,EAAiB;YAC5E,iEAAiE;YACjE,kBAAkB;YAClB,MAAOF,QAAQG,UAAU,CAAC,MAAO;gBAC/BH,UAAUA,QAAQI,KAAK,CAAC;YAC1B;YAEA,MAAOJ,QAAQK,QAAQ,CAAC,MAAO;gBAC7BL,UAAUA,QAAQI,KAAK,CAAC,GAAG,CAAC;YAC9B;YAEA,+CAA+C;YAC/C,IAAI1B,WAAW4B,WAAW;gBACxBX,aAAa,EAAEA,aAAaC,OAAOW,MAAM;gBACzC7B,SAASV,KAAK,CAACoB,MAAM,CAACQ,MAAM,CAACD,WAAW;YAC1C;YAEA,IAAIK,SAAS;gBACX,+BAA+B;gBAC/B,IAAItB,QAAQ;oBACV,0DAA0D;oBAC1D,MAAM8B,QAAQR,QAAQS,KAAK,CAAC;oBAC5BD,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE9B,OAAO,CAAC,EAAE8B,KAAK,CAAC,EAAE,CAAC,CAAC;oBAClCR,UAAUQ,MAAME,IAAI,CAACtC,GAAGuC,GAAG;gBAC7B;gBAEA,IAAIzB,wBAAwB,CAACc,QAAQG,UAAU,CAAC,OAAO;oBACrD,sCAAsC;oBACtCH,UAAU,OAAOA;gBACnB;gBAEA,IAAIf,iBAAiB,CAACe,QAAQK,QAAQ,CAAC,OAAO;oBAC5C,kCAAkC;oBAClCL,WAAW;gBACb;YACF;YAEA,IAAIE,aAAa;gBACf,IAAI,CAAC3B,OAAOqC,aAAa,IAAI1B,sBAAsB;oBACjD,gDAAgD;oBAChD,yDAAyD;oBACzD,4DAA4D;oBAC5D,wCAAwC;oBACxCc,UAAUA,QAAQI,KAAK,CAAC;gBAC1B;gBAEA,mDAAmD;gBACnD7B,OAAOsC,cAAc,CAACb;gBACtBrB,gBAAgB2B;gBAChB;YACF;YAEA,iEAAiE;YACjE,IAAI/B,OAAOqC,aAAa,EAAE;gBACxB,0DAA0D;gBAC1DrC,OAAOuC,aAAa,CAACd;YACvB,OAAO,IAAIF,aAAa;gBACtB,8DAA8D;gBAC9D,mDAAmD;gBACnDvB,OAAOwC,WAAW,CAACf;gBACnBF,cAAc;YAChB;QACF;QAEA,yBAAyB;QACzBC,OAAO;YAAEC,SAAShB;QAAI;QAEtB,IAAIgC;QACJ,IAAIzC,OAAOqC,aAAa,EAAE;YACxB,mEAAmE;YACnEI,kBAAkBC,YAAY,IAAMlB,OAAO;oBAAEC,SAAShB;gBAAI,IAAIa;QAChE;QAEA,wBAAwB;QACxB,MAAMK,cAAc,CAACgB;YACnBnB,OAAO;gBAAE,GAAGmB,aAAa;gBAAEjB,OAAO;YAAK;YACvCkB,cAAcH;QAChB;QAEArC,gBAAgB;YACdyC,MAAMpC;YACNqC;gBACE,IAAI,CAACD,IAAI,GAAG;gBACZlB,YAAY;oBAAExB,QAAQ;oBAAIsB,SAAS;gBAAG;YACxC;YACAsB,SAAQC,QAAwC,EAAE,GAAGxC,MAAiB;gBACpEwC,aAAavC;gBACb,IAAI,CAACV,SAASiD,WAAW;oBACvBA,WAAWlD,OAAOJ,cAAcsD,aAAaxC;gBAC/C;gBACA,IAAI,CAACqC,IAAI,GAAGG;gBACZrB,YAAY;oBAAEF,SAASuB;oBAAU7C,QAAQW;gBAAc;YACzD;YACAmC,MAAKD,QAAwC,EAAE,GAAGxC,MAAiB;gBACjEwC,aAAavC;gBACb,IAAI,CAACV,SAASiD,WAAW;oBACvBA,WAAWlD,OAAOJ,cAAcsD,aAAaxC;gBAC/C;gBACA,IAAI,CAACqC,IAAI,GAAGG;gBACZrB,YAAY;oBAAEF,SAASuB;oBAAU7C,QAAQc;gBAAW;YACtD;QACF;QAEA,OAAOb;IACT;AACF,EAAE;AAEF,OAAO,MAAM8C,OAAO7C,WAAW,CAAC,GAAG"}
1
+ {"version":3,"sources":["../../../src/services/output/spinner.ts"],"sourcesContent":["import type { ColorName } from \"chalk\";\nimport chalk from \"chalk\";\nimport chalkTemplate from \"chalk-template\";\nimport type { SpinnerName } from \"cli-spinners\";\nimport cliSpinners from \"cli-spinners\";\nimport assert from \"node:assert\";\nimport os from \"node:os\";\nimport { dedent } from \"ts-dedent\";\nimport { isString } from \"../util/is.js\";\nimport { output } from \"./output.js\";\nimport { isSprintOptions, sprintln } from \"./sprint.js\";\nimport { symbol } from \"./symbols.js\";\n\nexport type SpinnerOptions = {\n /**\n * Whether to ensure a new line is after the text.\n *\n * @default false\n */\n ensureNewLine?: boolean;\n\n /**\n * Whether to ensure an empty line is above the spinner.\n *\n * @default false\n */\n ensureEmptyLineAbove?: boolean;\n\n /**\n * The name of the spinner to use.\n *\n * @default \"dots\"\n * @see https://github.com/sindresorhus/cli-spinners\n */\n kind?: SpinnerName;\n\n /**\n * The color of the spinner.\n *\n * @default \"cyan\"\n * @see https://github.com/chalk/chalk\n */\n color?: ColorName;\n\n /**\n * The symbol to display when the spinner succeeds.\n *\n * @default \"✔\"\n */\n successSymbol?: string;\n\n /**\n * The symbol to display when the spinner fails.\n *\n * @default \"✖\"\n */\n failSymbol?: string;\n};\n\nexport type spin = {\n (str: string): spinner;\n (template: TemplateStringsArray, ...values: unknown[]): spinner;\n (options: Omit<SpinnerOptions, \"str\">): spin;\n};\n\nexport type spinner = {\n text: string;\n clear: () => void;\n succeed: {\n (str?: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n };\n fail: {\n (str?: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n };\n};\n\nexport let activeSpinner: spinner | undefined;\n\nexport const createSpin = (options: SpinnerOptions): spin => {\n return ((optionsOrString: SpinnerOptions | string | TemplateStringsArray, ...values: unknown[]): spin | spinner => {\n if (isSprintOptions(optionsOrString)) {\n return createSpin({ ...options, ...optionsOrString });\n }\n\n assert(!activeSpinner, \"a spinner is already active\");\n\n let str = optionsOrString as string;\n if (!isString(str)) {\n str = sprintln(str, ...values);\n }\n\n const {\n ensureNewLine = true,\n ensureEmptyLineAbove = false,\n kind = \"dots\",\n color = \"white\",\n successSymbol = chalk.green(symbol.tick),\n failSymbol = chalk.red(symbol.cross),\n } = options;\n\n let frameIndex = 0;\n const frames = cliSpinners[kind].frames;\n const interval = cliSpinners[kind].interval;\n\n type RenderOptions = { symbol?: string; message: string; final?: boolean };\n let firstRender = true;\n\n const render = ({ symbol, message, final: finalRender = false }: RenderOptions): void => {\n // strip leading and trailing newlines so we can add them back in\n // the right place\n while (message.startsWith(\"\\n\")) {\n message = message.slice(1);\n }\n\n while (message.endsWith(\"\\n\")) {\n message = message.slice(0, -1);\n }\n\n // if no symbol is provided, use the next frame\n if (symbol === undefined) {\n frameIndex = ++frameIndex % frames.length;\n symbol = chalk[color](frames[frameIndex]);\n }\n\n if (message) {\n // we have a message to display\n if (symbol) {\n // add the spinner symbol to the first line of the message\n const lines = message.split(/\\r?\\n/);\n lines[0] = `${symbol} ${lines[0]}`;\n message = lines.join(os.EOL);\n }\n\n if (ensureEmptyLineAbove && !message.startsWith(\"\\n\")) {\n // add an empty line before the symbol\n message = \"\\n\" + message;\n }\n\n if (ensureNewLine && !message.endsWith(\"\\n\")) {\n // add a newline after the message\n message += \"\\n\";\n }\n }\n\n if (finalRender) {\n if (!output.isInteractive && ensureEmptyLineAbove) {\n // we're in a non-interactive terminal, therefor\n // ensureEmptyLineAbove only applies to the first render.\n // strip it so that the final render of the spinner is right\n // below the first render of the spinner\n message = message.slice(1);\n }\n\n // this is the final render, so persist the spinner\n output.persistSpinner(message);\n activeSpinner = undefined;\n return;\n }\n\n // this is not the final render, so we need to update the spinner\n if (output.isInteractive) {\n // we're in an interactive terminal, so update the spinner\n output.updateSpinner(message);\n } else if (firstRender) {\n // we're not in an interactive terminal, and this is the first\n // render, so just write the first render to stdout\n output.writeStdout(message);\n firstRender = false;\n }\n };\n\n // render the first frame\n render({ message: str });\n\n let spinnerInterval: NodeJS.Timeout | undefined;\n if (output.isInteractive) {\n // we are in an interactive terminal, so keep rendering the spinner\n spinnerInterval = setInterval(() => render({ message: str }), interval);\n }\n\n // setup the last render\n const finalRender = (renderOptions: Omit<RenderOptions, \"final\">): void => {\n render({ ...renderOptions, final: true });\n clearInterval(spinnerInterval);\n };\n\n activeSpinner = {\n text: str,\n clear(): void {\n this.text = \"\";\n finalRender({ symbol: \"\", message: \"\" });\n },\n succeed(finalStr?: string | TemplateStringsArray, ...values: unknown[]): void {\n finalStr ??= str;\n if (!isString(finalStr)) {\n finalStr = dedent(chalkTemplate(finalStr, ...values));\n }\n this.text = finalStr;\n finalRender({ message: finalStr, symbol: successSymbol });\n },\n fail(finalStr?: string | TemplateStringsArray, ...values: unknown[]): void {\n finalStr ??= str;\n if (!isString(finalStr)) {\n finalStr = dedent(chalkTemplate(finalStr, ...values));\n }\n this.text = finalStr;\n finalRender({ message: finalStr, symbol: failSymbol });\n },\n };\n\n return activeSpinner;\n }) as spin;\n};\n\nexport const spin = createSpin({});\n"],"names":["chalk","chalkTemplate","cliSpinners","assert","os","dedent","isString","output","isSprintOptions","sprintln","symbol","activeSpinner","createSpin","options","optionsOrString","values","str","ensureNewLine","ensureEmptyLineAbove","kind","color","successSymbol","green","tick","failSymbol","red","cross","frameIndex","frames","interval","firstRender","render","message","final","finalRender","startsWith","slice","endsWith","undefined","length","lines","split","join","EOL","isInteractive","persistSpinner","updateSpinner","writeStdout","spinnerInterval","setInterval","renderOptions","clearInterval","text","clear","succeed","finalStr","fail","spin"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/sprint.ts"],"sourcesContent":["import type { Options as BoxenOptions } from \"boxen\";\nimport boxen from \"boxen\";\nimport chalkTemplate from \"chalk-template\";\nimport indentString from \"indent-string\";\nimport { dedent } from \"ts-dedent\";\nimport { isArray, isString } from \"../util/is.js\";\n\nexport type SprintOptions = {\n /**\n * Whether to ensure a new line is after the content.\n *\n * @default true\n */\n ensureNewLine?: boolean;\n\n /**\n * Whether to ensure an empty line is above the content.\n *\n * @default false\n */\n ensureEmptyLineAbove?: boolean;\n\n /**\n * The number of spaces to indent the text.\n *\n * @default 0\n */\n indent?: number;\n\n /**\n * Whether to wrap the text in a box.\n *\n * @default undefined (no box)\n */\n boxen?: BoxenOptions;\n};\n\nexport type sprint = {\n (str: string): string;\n (template: TemplateStringsArray, ...values: unknown[]): string;\n (options: SprintOptions): sprint;\n};\n\nexport const isSprintOptions = <const T extends SprintOptions>(value: string | TemplateStringsArray | SprintOptions): value is T => {\n return !isString(value) && !isArray(value);\n};\n\nconst createSprint = (options: SprintOptions): sprint => {\n return ((optionsOrString: SprintOptions | string | TemplateStringsArray, ...values: unknown[]): sprint | string => {\n if (isSprintOptions(optionsOrString)) {\n return createSprint({ ...options, ...optionsOrString });\n }\n\n const { ensureNewLine = false, ensureEmptyLineAbove = false, indent = 0, boxen: boxenOptions } = options;\n\n let str = optionsOrString as string;\n if (!isString(str)) {\n str = dedent(chalkTemplate(str, ...values));\n }\n\n if (ensureEmptyLineAbove && !str.startsWith(\"\\n\")) {\n str = \"\\n\" + str;\n }\n\n if (ensureNewLine && !str.endsWith(\"\\n\")) {\n str += \"\\n\";\n }\n\n if (boxenOptions) {\n str = boxen(str, boxenOptions);\n }\n\n if (indent > 0) {\n str = indentString(str, indent);\n }\n\n return str;\n }) as sprint;\n};\n\nexport const sprint = createSprint({ ensureNewLine: false });\nexport const sprintln = createSprint({ ensureNewLine: true });\n"],"names":["boxen","chalkTemplate","indentString","dedent","isArray","isString","isSprintOptions","value","createSprint","options","optionsOrString","values","ensureNewLine","ensureEmptyLineAbove","indent","boxenOptions","str","startsWith","endsWith","sprint","sprintln"],"mappings":"AACA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,mBAAmB,iBAAiB;AAC3C,OAAOC,kBAAkB,gBAAgB;AACzC,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,OAAO,EAAEC,QAAQ,QAAQ,gBAAgB;AAsClD,OAAO,MAAMC,kBAAkB,CAAgCC;IAC7D,OAAO,CAACF,SAASE,UAAU,CAACH,QAAQG;AACtC,EAAE;AAEF,MAAMC,eAAe,CAACC;IACpB,OAAQ,CAACC,iBAAgE,GAAGC;QAC1E,IAAIL,gBAAgBI,kBAAkB;YACpC,OAAOF,aAAa;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,eAAe;YAAC;QACvD;QAEA,MAAM,EAAEE,gBAAgB,KAAK,EAAEC,uBAAuB,KAAK,EAAEC,SAAS,CAAC,EAAEd,OAAOe,YAAY,EAAE,GAAGN;QAEjG,IAAIO,MAAMN;QACV,IAAI,CAACL,SAASW,MAAM;YAClBA,MAAMb,OAAOF,cAAce,QAAQL;QACrC;QAEA,IAAIE,wBAAwB,CAACG,IAAIC,UAAU,CAAC,OAAO;YACjDD,MAAM,OAAOA;QACf;QAEA,IAAIJ,iBAAiB,CAACI,IAAIE,QAAQ,CAAC,OAAO;YACxCF,OAAO;QACT;QAEA,IAAID,cAAc;YAChBC,MAAMhB,MAAMgB,KAAKD;QACnB;QAEA,IAAID,SAAS,GAAG;YACdE,MAAMd,aAAac,KAAKF;QAC1B;QAEA,OAAOE;IACT;AACF;AAEA,OAAO,MAAMG,SAASX,aAAa;IAAEI,eAAe;AAAM,GAAG;AAC7D,OAAO,MAAMQ,WAAWZ,aAAa;IAAEI,eAAe;AAAK,GAAG"}
1
+ {"version":3,"sources":["../../../src/services/output/sprint.ts"],"sourcesContent":["import type { Options as BoxenOptions } from \"boxen\";\nimport boxen from \"boxen\";\nimport chalkTemplate from \"chalk-template\";\nimport indentString from \"indent-string\";\nimport { dedent } from \"ts-dedent\";\nimport { isArray, isString } from \"../util/is.js\";\n\nexport type SprintOptions = {\n /**\n * Whether to ensure a new line is after the content.\n *\n * @default true\n */\n ensureNewLine?: boolean;\n\n /**\n * Whether to ensure an empty line is above the content.\n *\n * @default false\n */\n ensureEmptyLineAbove?: boolean;\n\n /**\n * The number of spaces to indent the text.\n *\n * @default 0\n */\n indent?: number;\n\n /**\n * Whether to wrap the text in a box.\n *\n * @default undefined (no box)\n */\n boxen?: BoxenOptions;\n};\n\nexport type sprint = {\n (str: string): string;\n (template: TemplateStringsArray, ...values: unknown[]): string;\n (options: SprintOptions): sprint;\n};\n\nexport const isSprintOptions = <const T extends SprintOptions>(value: string | TemplateStringsArray | SprintOptions): value is T => {\n return !isString(value) && !isArray(value);\n};\n\nconst createSprint = (options: SprintOptions): sprint => {\n return ((optionsOrString: SprintOptions | string | TemplateStringsArray, ...values: unknown[]): sprint | string => {\n if (isSprintOptions(optionsOrString)) {\n return createSprint({ ...options, ...optionsOrString });\n }\n\n const { ensureNewLine = false, ensureEmptyLineAbove = false, indent = 0, boxen: boxenOptions } = options;\n\n let str = optionsOrString as string;\n if (!isString(str)) {\n str = dedent(chalkTemplate(str, ...values));\n }\n\n if (ensureEmptyLineAbove && !str.startsWith(\"\\n\")) {\n str = \"\\n\" + str;\n }\n\n if (ensureNewLine && !str.endsWith(\"\\n\")) {\n str += \"\\n\";\n }\n\n if (boxenOptions) {\n str = boxen(str, boxenOptions);\n }\n\n if (indent > 0) {\n str = indentString(str, indent);\n }\n\n return str;\n }) as sprint;\n};\n\nexport const sprint = createSprint({ ensureNewLine: false });\nexport const sprintln = createSprint({ ensureNewLine: true });\n"],"names":["boxen","chalkTemplate","indentString","dedent","isArray","isString","isSprintOptions","value","createSprint","options","optionsOrString","values","ensureNewLine","ensureEmptyLineAbove","indent","boxenOptions","str","startsWith","endsWith","sprint","sprintln"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AACA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,mBAAmB,iBAAiB;AAC3C,OAAOC,kBAAkB,gBAAgB;AACzC,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,OAAO,EAAEC,QAAQ,QAAQ,gBAAgB;AAsClD,OAAO,MAAMC,kBAAkB,CAAgCC;IAC7D,OAAO,CAACF,SAASE,UAAU,CAACH,QAAQG;AACtC,EAAE;AAEF,MAAMC,eAAe,CAACC;IACpB,OAAQ,CAACC,iBAAgE,GAAGC;QAC1E,IAAIL,gBAAgBI,kBAAkB;YACpC,OAAOF,aAAa;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,eAAe;YAAC;QACvD;QAEA,MAAM,EAAEE,gBAAgB,KAAK,EAAEC,uBAAuB,KAAK,EAAEC,SAAS,CAAC,EAAEd,OAAOe,YAAY,EAAE,GAAGN;QAEjG,IAAIO,MAAMN;QACV,IAAI,CAACL,SAASW,MAAM;YAClBA,MAAMb,OAAOF,cAAce,QAAQL;QACrC;QAEA,IAAIE,wBAAwB,CAACG,IAAIC,UAAU,CAAC,OAAO;YACjDD,MAAM,OAAOA;QACf;QAEA,IAAIJ,iBAAiB,CAACI,IAAIE,QAAQ,CAAC,OAAO;YACxCF,OAAO;QACT;QAEA,IAAID,cAAc;YAChBC,MAAMhB,MAAMgB,KAAKD;QACnB;QAEA,IAAID,SAAS,GAAG;YACdE,MAAMd,aAAac,KAAKF;QAC1B;QAEA,OAAOE;IACT;AACF;AAEA,OAAO,MAAMG,SAASX,aAAa;IAAEI,eAAe;AAAM,GAAG;AAC7D,OAAO,MAAMQ,WAAWZ,aAAa;IAAEI,eAAe;AAAK,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/symbols.ts"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports -- this is the only place we're allowed to import figures\nimport figures, { mainSymbols } from \"figures\";\nimport isUnicodeSupported from \"is-unicode-supported\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\n\n// we always use main symbols in tests rather than figures so that our\n// tests are consistent across platforms (particularly Windows)\nexport const symbol = { ...(env.testLike ? mainSymbols : figures) };\n\nif (isUnicodeSupported() && config.windowsOrWsl) {\n // when unicode is supported and we're on windows or wsl, these\n // symbols end up rendering over two cells while only taking up one,\n // so we add an extra space to each of them to make them take up two\n for (const name of [\"tick\", \"cross\"] as const) {\n symbol[name] += \" \";\n }\n}\n"],"names":["figures","mainSymbols","isUnicodeSupported","config","env","symbol","testLike","windowsOrWsl","name"],"mappings":"AAAA,2GAA2G;AAC3G,OAAOA,WAAWC,WAAW,QAAQ,UAAU;AAC/C,OAAOC,wBAAwB,uBAAuB;AACtD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,GAAG,QAAQ,mBAAmB;AAEvC,sEAAsE;AACtE,+DAA+D;AAC/D,OAAO,MAAMC,SAAS;IAAE,GAAID,IAAIE,QAAQ,GAAGL,cAAcD,OAAO;AAAE,EAAE;AAEpE,IAAIE,wBAAwBC,OAAOI,YAAY,EAAE;IAC/C,+DAA+D;IAC/D,oEAAoE;IACpE,oEAAoE;IACpE,KAAK,MAAMC,QAAQ;QAAC;QAAQ;KAAQ,CAAW;QAC7CH,MAAM,CAACG,KAAK,IAAI;IAClB;AACF"}
1
+ {"version":3,"sources":["../../../src/services/output/symbols.ts"],"sourcesContent":["// eslint-disable-next-line no-restricted-imports -- this is the only place we're allowed to import figures\nimport figures, { mainSymbols } from \"figures\";\nimport isUnicodeSupported from \"is-unicode-supported\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\n\n// we always use main symbols in tests rather than figures so that our\n// tests are consistent across platforms (particularly Windows)\nexport const symbol = { ...(env.testLike ? mainSymbols : figures) };\n\nif (isUnicodeSupported() && config.windowsOrWsl) {\n // when unicode is supported and we're on windows or wsl, these\n // symbols end up rendering over two cells while only taking up one,\n // so we add an extra space to each of them to make them take up two\n for (const name of [\"tick\", \"cross\"] as const) {\n symbol[name] += \" \";\n }\n}\n"],"names":["figures","mainSymbols","isUnicodeSupported","config","env","symbol","testLike","windowsOrWsl","name"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,2GAA2G;AAC3G,OAAOA,WAAWC,WAAW,QAAQ,UAAU;AAC/C,OAAOC,wBAAwB,uBAAuB;AACtD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,GAAG,QAAQ,mBAAmB;AAEvC,sEAAsE;AACtE,+DAA+D;AAC/D,OAAO,MAAMC,SAAS;IAAE,GAAID,IAAIE,QAAQ,GAAGL,cAAcD,OAAO;AAAE,EAAE;AAEpE,IAAIE,wBAAwBC,OAAOI,YAAY,EAAE;IAC/C,+DAA+D;IAC/D,oEAAoE;IACpE,oEAAoE;IACpE,KAAK,MAAMC,QAAQ;QAAC;QAAQ;KAAQ,CAAW;QAC7CH,MAAM,CAACG,KAAK,IAAI;IAClB;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/table.ts"],"sourcesContent":["import CliTable3 from \"cli-table3\";\nimport indentString from \"indent-string\";\nimport { dedent } from \"ts-dedent\";\nimport { println, type PrintOptions } from \"./print.js\";\nimport { sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type SprintTableOptions = SprintOptions & {\n /**\n * The text to print above the table.\n */\n title?: string;\n\n /**\n * The headers of the table.\n */\n headers?: string[];\n\n /**\n * The rows of the table.\n */\n rows: string[][];\n\n /**\n * The text to print below the table.\n */\n footer?: string;\n\n /**\n * Whether to add an empty line above the body of the table.\n *\n * @default false\n */\n ensureEmptyLineAboveBody?: boolean;\n\n /**\n * Whether to add an empty line above the footer of the table.\n *\n * @default false\n */\n ensureEmptyLineAboveFooter?: boolean;\n\n /**\n * The type of borders to use.\n *\n * @default \"none\"\n */\n borders?: \"none\" | \"thin\" | \"thick\";\n\n /**\n * The alignment of the content in each column.\n *\n * @default [] (left-aligned)\n */\n colAligns?: (\"left\" | \"center\" | \"right\")[];\n\n /**\n * The width of each column.\n *\n * @default [] (auto-sized)\n */\n colWidths?: number[];\n};\n\nexport const sprintTable = ({\n title,\n headers,\n rows,\n footer,\n ensureEmptyLineAboveBody = false,\n ensureEmptyLineAboveFooter = false,\n borders: borderType = \"none\",\n colAligns = [],\n colWidths = [],\n indent,\n ...printOptions\n}: SprintTableOptions): string => {\n const table = new CliTable3({\n chars: borders[borderType],\n colAligns,\n colWidths,\n head: headers,\n style: { head: [], border: [] },\n });\n\n table.push(...rows);\n\n let text = table.toString() + \"\\n\";\n if (borderType === \"none\") {\n // remove the left padding\n text = dedent(text).slice(1);\n }\n\n // remove the right padding\n text = text\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\");\n\n if (indent) {\n text = indentString(text, indent);\n }\n\n if (title) {\n text = sprintln(title) + sprintln({ ensureEmptyLineAbove: ensureEmptyLineAboveBody })(text);\n }\n\n if (footer) {\n text = sprintln(text) + sprintln({ ensureEmptyLineAbove: ensureEmptyLineAboveFooter })(footer);\n }\n\n return sprintln(printOptions)(text);\n};\n\nexport type PrintTableOptions = PrintOptions & SprintTableOptions;\n\nexport const printTable = (options: PrintTableOptions): void => {\n println(options)(sprintTable(options));\n};\n\n// prettier-ignore\nconst borders = {\n none: {\n \"top-left\": \"\", top: \"\", \"top-mid\": \"\", \"top-right\": \"\",\n \"left-mid\": \"\", mid: \"\", \"mid-mid\": \"\", \"right-mid\": \"\",\n left: \"\", middle: \"\", right: \"\",\n \"bottom-left\": \"\", bottom: \"\", \"bottom-mid\": \"\", \"bottom-right\": \"\",\n },\n thin: {\n \"top-left\": \"┌\", top: \"─\", \"top-mid\": \"┬\", \"top-right\": \"┐\",\n \"left-mid\": \"├\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"┤\",\n left: \"│\", middle: \"│\", right: \"│\",\n \"bottom-left\": \"└\", bottom: \"─\", \"bottom-mid\": \"┴\", \"bottom-right\": \"┘\",\n },\n thick: {\n \"top-left\": \"╔\", top: \"═\", \"top-mid\": \"╤\", \"top-right\": \"╗\",\n left: \"║\", middle: \"│\", right: \"║\",\n \"left-mid\": \"╟\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"╢\",\n \"bottom-left\": \"╚\", bottom: \"═\", \"bottom-mid\": \"╧\", \"bottom-right\": \"╝\",\n },\n };\n"],"names":["CliTable3","indentString","dedent","println","sprintln","sprintTable","title","headers","rows","footer","ensureEmptyLineAboveBody","ensureEmptyLineAboveFooter","borders","borderType","colAligns","colWidths","indent","printOptions","table","chars","head","style","border","push","text","toString","slice","split","map","line","trimEnd","join","ensureEmptyLineAbove","printTable","options","none","top","mid","left","middle","right","bottom","thin","thick"],"mappings":"AAAA,OAAOA,eAAe,aAAa;AACnC,OAAOC,kBAAkB,gBAAgB;AACzC,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,OAAO,QAA2B,aAAa;AACxD,SAASC,QAAQ,QAA4B,cAAc;AA2D3D,OAAO,MAAMC,cAAc,CAAC,EAC1BC,KAAK,EACLC,OAAO,EACPC,IAAI,EACJC,MAAM,EACNC,2BAA2B,KAAK,EAChCC,6BAA6B,KAAK,EAClCC,SAASC,aAAa,MAAM,EAC5BC,YAAY,EAAE,EACdC,YAAY,EAAE,EACdC,MAAM,EACN,GAAGC,cACgB;IACnB,MAAMC,QAAQ,IAAIlB,UAAU;QAC1BmB,OAAOP,OAAO,CAACC,WAAW;QAC1BC;QACAC;QACAK,MAAMb;QACNc,OAAO;YAAED,MAAM,EAAE;YAAEE,QAAQ,EAAE;QAAC;IAChC;IAEAJ,MAAMK,IAAI,IAAIf;IAEd,IAAIgB,OAAON,MAAMO,QAAQ,KAAK;IAC9B,IAAIZ,eAAe,QAAQ;QACzB,0BAA0B;QAC1BW,OAAOtB,OAAOsB,MAAME,KAAK,CAAC;IAC5B;IAEA,2BAA2B;IAC3BF,OAAOA,KACJG,KAAK,CAAC,MACNC,GAAG,CAAC,CAACC,OAASA,KAAKC,OAAO,IAC1BC,IAAI,CAAC;IAER,IAAIf,QAAQ;QACVQ,OAAOvB,aAAauB,MAAMR;IAC5B;IAEA,IAAIV,OAAO;QACTkB,OAAOpB,SAASE,SAASF,SAAS;YAAE4B,sBAAsBtB;QAAyB,GAAGc;IACxF;IAEA,IAAIf,QAAQ;QACVe,OAAOpB,SAASoB,QAAQpB,SAAS;YAAE4B,sBAAsBrB;QAA2B,GAAGF;IACzF;IAEA,OAAOL,SAASa,cAAcO;AAChC,EAAE;AAIF,OAAO,MAAMS,aAAa,CAACC;IACzB/B,QAAQ+B,SAAS7B,YAAY6B;AAC/B,EAAE;AAEF,kBAAkB;AAClB,MAAMtB,UAAU;IACZuB,MAAM;QACJ,YAAY;QAAIC,KAAK;QAAI,WAAW;QAAI,aAAa;QACrD,YAAY;QAAIC,KAAK;QAAI,WAAW;QAAI,aAAa;QACrDC,MAAM;QAAIC,QAAQ;QAAIC,OAAO;QAC7B,eAAe;QAAIC,QAAQ;QAAI,cAAc;QAAI,gBAAgB;IACnE;IACAC,MAAM;QACJ,YAAY;QAAKN,KAAK;QAAK,WAAW;QAAK,aAAa;QACxD,YAAY;QAAKC,KAAK;QAAK,WAAW;QAAK,aAAa;QACxDC,MAAM;QAAKC,QAAQ;QAAKC,OAAO;QAC/B,eAAe;QAAKC,QAAQ;QAAK,cAAc;QAAK,gBAAgB;IACtE;IACAE,OAAO;QACL,YAAY;QAAKP,KAAK;QAAK,WAAW;QAAK,aAAa;QACxDE,MAAM;QAAKC,QAAQ;QAAKC,OAAO;QAC/B,YAAY;QAAKH,KAAK;QAAK,WAAW;QAAK,aAAa;QACxD,eAAe;QAAKI,QAAQ;QAAK,cAAc;QAAK,gBAAgB;IACtE;AACF"}
1
+ {"version":3,"sources":["../../../src/services/output/table.ts"],"sourcesContent":["import CliTable3 from \"cli-table3\";\nimport indentString from \"indent-string\";\nimport { dedent } from \"ts-dedent\";\nimport { println, type PrintOptions } from \"./print.js\";\nimport { sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type SprintTableOptions = SprintOptions & {\n /**\n * The text to print above the table.\n */\n title?: string;\n\n /**\n * The headers of the table.\n */\n headers?: string[];\n\n /**\n * The rows of the table.\n */\n rows: string[][];\n\n /**\n * The text to print below the table.\n */\n footer?: string;\n\n /**\n * Whether to add an empty line above the body of the table.\n *\n * @default false\n */\n ensureEmptyLineAboveBody?: boolean;\n\n /**\n * Whether to add an empty line above the footer of the table.\n *\n * @default false\n */\n ensureEmptyLineAboveFooter?: boolean;\n\n /**\n * The type of borders to use.\n *\n * @default \"none\"\n */\n borders?: \"none\" | \"thin\" | \"thick\";\n\n /**\n * The alignment of the content in each column.\n *\n * @default [] (left-aligned)\n */\n colAligns?: (\"left\" | \"center\" | \"right\")[];\n\n /**\n * The width of each column.\n *\n * @default [] (auto-sized)\n */\n colWidths?: number[];\n};\n\nexport const sprintTable = ({\n title,\n headers,\n rows,\n footer,\n ensureEmptyLineAboveBody = false,\n ensureEmptyLineAboveFooter = false,\n borders: borderType = \"none\",\n colAligns = [],\n colWidths = [],\n indent,\n ...printOptions\n}: SprintTableOptions): string => {\n const table = new CliTable3({\n chars: borders[borderType],\n colAligns,\n colWidths,\n head: headers,\n style: { head: [], border: [] },\n });\n\n table.push(...rows);\n\n let text = table.toString() + \"\\n\";\n if (borderType === \"none\") {\n // remove the left padding\n text = dedent(text).slice(1);\n }\n\n // remove the right padding\n text = text\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .join(\"\\n\");\n\n if (indent) {\n text = indentString(text, indent);\n }\n\n if (title) {\n text = sprintln(title) + sprintln({ ensureEmptyLineAbove: ensureEmptyLineAboveBody })(text);\n }\n\n if (footer) {\n text = sprintln(text) + sprintln({ ensureEmptyLineAbove: ensureEmptyLineAboveFooter })(footer);\n }\n\n return sprintln(printOptions)(text);\n};\n\nexport type PrintTableOptions = PrintOptions & SprintTableOptions;\n\nexport const printTable = (options: PrintTableOptions): void => {\n println(options)(sprintTable(options));\n};\n\n// prettier-ignore\nconst borders = {\n none: {\n \"top-left\": \"\", top: \"\", \"top-mid\": \"\", \"top-right\": \"\",\n \"left-mid\": \"\", mid: \"\", \"mid-mid\": \"\", \"right-mid\": \"\",\n left: \"\", middle: \"\", right: \"\",\n \"bottom-left\": \"\", bottom: \"\", \"bottom-mid\": \"\", \"bottom-right\": \"\",\n },\n thin: {\n \"top-left\": \"┌\", top: \"─\", \"top-mid\": \"┬\", \"top-right\": \"┐\",\n \"left-mid\": \"├\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"┤\",\n left: \"│\", middle: \"│\", right: \"│\",\n \"bottom-left\": \"└\", bottom: \"─\", \"bottom-mid\": \"┴\", \"bottom-right\": \"┘\",\n },\n thick: {\n \"top-left\": \"╔\", top: \"═\", \"top-mid\": \"╤\", \"top-right\": \"╗\",\n left: \"║\", middle: \"│\", right: \"║\",\n \"left-mid\": \"╟\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"╢\",\n \"bottom-left\": \"╚\", bottom: \"═\", \"bottom-mid\": \"╧\", \"bottom-right\": \"╝\",\n },\n };\n"],"names":["CliTable3","indentString","dedent","println","sprintln","sprintTable","title","headers","rows","footer","ensureEmptyLineAboveBody","ensureEmptyLineAboveFooter","borders","borderType","colAligns","colWidths","indent","printOptions","table","chars","head","style","border","push","text","toString","slice","split","map","line","trimEnd","join","ensureEmptyLineAbove","printTable","options","none","top","mid","left","middle","right","bottom","thin","thick"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,eAAe,aAAa;AACnC,OAAOC,kBAAkB,gBAAgB;AACzC,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,OAAO,QAA2B,aAAa;AACxD,SAASC,QAAQ,QAA4B,cAAc;AA2D3D,OAAO,MAAMC,cAAc,CAAC,EAC1BC,KAAK,EACLC,OAAO,EACPC,IAAI,EACJC,MAAM,EACNC,2BAA2B,KAAK,EAChCC,6BAA6B,KAAK,EAClCC,SAASC,aAAa,MAAM,EAC5BC,YAAY,EAAE,EACdC,YAAY,EAAE,EACdC,MAAM,EACN,GAAGC,cACgB;IACnB,MAAMC,QAAQ,IAAIlB,UAAU;QAC1BmB,OAAOP,OAAO,CAACC,WAAW;QAC1BC;QACAC;QACAK,MAAMb;QACNc,OAAO;YAAED,MAAM,EAAE;YAAEE,QAAQ,EAAE;QAAC;IAChC;IAEAJ,MAAMK,IAAI,IAAIf;IAEd,IAAIgB,OAAON,MAAMO,QAAQ,KAAK;IAC9B,IAAIZ,eAAe,QAAQ;QACzB,0BAA0B;QAC1BW,OAAOtB,OAAOsB,MAAME,KAAK,CAAC;IAC5B;IAEA,2BAA2B;IAC3BF,OAAOA,KACJG,KAAK,CAAC,MACNC,GAAG,CAAC,CAACC,OAASA,KAAKC,OAAO,IAC1BC,IAAI,CAAC;IAER,IAAIf,QAAQ;QACVQ,OAAOvB,aAAauB,MAAMR;IAC5B;IAEA,IAAIV,OAAO;QACTkB,OAAOpB,SAASE,SAASF,SAAS;YAAE4B,sBAAsBtB;QAAyB,GAAGc;IACxF;IAEA,IAAIf,QAAQ;QACVe,OAAOpB,SAASoB,QAAQpB,SAAS;YAAE4B,sBAAsBrB;QAA2B,GAAGF;IACzF;IAEA,OAAOL,SAASa,cAAcO;AAChC,EAAE;AAIF,OAAO,MAAMS,aAAa,CAACC;IACzB/B,QAAQ+B,SAAS7B,YAAY6B;AAC/B,EAAE;AAEF,kBAAkB;AAClB,MAAMtB,UAAU;IACZuB,MAAM;QACJ,YAAY;QAAIC,KAAK;QAAI,WAAW;QAAI,aAAa;QACrD,YAAY;QAAIC,KAAK;QAAI,WAAW;QAAI,aAAa;QACrDC,MAAM;QAAIC,QAAQ;QAAIC,OAAO;QAC7B,eAAe;QAAIC,QAAQ;QAAI,cAAc;QAAI,gBAAgB;IACnE;IACAC,MAAM;QACJ,YAAY;QAAKN,KAAK;QAAK,WAAW;QAAK,aAAa;QACxD,YAAY;QAAKC,KAAK;QAAK,WAAW;QAAK,aAAa;QACxDC,MAAM;QAAKC,QAAQ;QAAKC,OAAO;QAC/B,eAAe;QAAKC,QAAQ;QAAK,cAAc;QAAK,gBAAgB;IACtE;IACAE,OAAO;QACL,YAAY;QAAKP,KAAK;QAAK,WAAW;QAAK,aAAa;QACxDE,MAAM;QAAKC,QAAQ;QAAKC,OAAO;QAC/B,YAAY;QAAKH,KAAK;QAAK,WAAW;QAAK,aAAa;QACxD,eAAe;QAAKI,QAAQ;QAAK,cAAc;QAAK,gBAAgB;IACtE;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/timestamp.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport dayjs from \"dayjs\";\nimport { env } from \"../config/env.js\";\nimport { parseBoolean } from \"../util/boolean.js\";\n\nexport const ts = (): string => {\n if (!env.testLike && parseBoolean(process.env[\"CI\"])) {\n return new Date().toISOString();\n }\n return chalk.gray(dayjs().format(\"hh:mm:ss A\"));\n};\n"],"names":["chalk","dayjs","env","parseBoolean","ts","testLike","process","Date","toISOString","gray","format"],"mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,SAASC,GAAG,QAAQ,mBAAmB;AACvC,SAASC,YAAY,QAAQ,qBAAqB;AAElD,OAAO,MAAMC,KAAK;IAChB,IAAI,CAACF,IAAIG,QAAQ,IAAIF,aAAaG,QAAQJ,GAAG,CAAC,KAAK,GAAG;QACpD,OAAO,IAAIK,OAAOC,WAAW;IAC/B;IACA,OAAOR,MAAMS,IAAI,CAACR,QAAQS,MAAM,CAAC;AACnC,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/output/timestamp.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport dayjs from \"dayjs\";\nimport { env } from \"../config/env.js\";\nimport { parseBoolean } from \"../util/boolean.js\";\n\nexport const ts = (): string => {\n if (!env.testLike && parseBoolean(process.env[\"CI\"])) {\n return new Date().toISOString();\n }\n return chalk.gray(dayjs().format(\"hh:mm:ss A\"));\n};\n"],"names":["chalk","dayjs","env","parseBoolean","ts","testLike","process","Date","toISOString","gray","format"],"rangeMappings":";;;;;;;;;","mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,SAASC,GAAG,QAAQ,mBAAmB;AACvC,SAASC,YAAY,QAAQ,qBAAqB;AAElD,OAAO,MAAMC,KAAK;IAChB,IAAI,CAACF,IAAIG,QAAQ,IAAIF,aAAaG,QAAQJ,GAAG,CAAC,KAAK,GAAG;QACpD,OAAO,IAAIK,OAAOC,WAAW;IAC/B;IACA,OAAOR,MAAMS,IAAI,CAACR,QAAQS,MAAM,CAAC;AACnC,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/update.ts"],"sourcesContent":["import boxen from \"boxen\";\nimport dayjs from \"dayjs\";\nimport fs from \"fs-extra\";\nimport ms from \"ms\";\nimport assert from \"node:assert\";\nimport path from \"node:path\";\nimport semver from \"semver\";\nimport { z } from \"zod\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { packageJson } from \"../config/package-json.js\";\nimport { http } from \"../http/http.js\";\nimport { println } from \"./print.js\";\nimport { sprint } from \"./sprint.js\";\n\nconst UPDATE_CHECK_FREQUENCY = ms(\"12 hours\");\n\nconst Registry = z.object({\n name: z.literal(\"ggt\"),\n \"dist-tags\": z.object({\n latest: z.string(),\n experimental: z.string(),\n }),\n});\n\ntype Registry = z.infer<typeof Registry>;\n\nexport const getDistTags = async (ctx: Context): Promise<Registry[\"dist-tags\"]> => {\n const json = await http({\n context: { ctx },\n method: \"GET\",\n url: \"https://registry.npmjs.org/ggt\",\n responseType: \"json\",\n resolveBodyOnly: true,\n timeout: {\n request: ms(\"5s\"),\n },\n });\n\n return Registry.parse(json)[\"dist-tags\"];\n};\n\nexport const shouldCheckForUpdate = async (): Promise<boolean> => {\n try {\n const lastCheck = Number(await fs.readFile(path.join(config.cacheDir, \"last-update-check\"), \"utf8\"));\n assert(!Number.isNaN(lastCheck));\n return dayjs().isAfter(lastCheck + UPDATE_CHECK_FREQUENCY);\n } catch (error) {\n return true;\n }\n};\n\n/**\n * Checks for updates to the `ggt` npm package and logs a warning\n * message if an update is available.\n *\n * @returns A Promise that resolves with void when the check is\n * complete.\n */\nexport const warnIfUpdateAvailable = async (ctx: Context): Promise<void> => {\n try {\n const shouldCheck = await shouldCheckForUpdate();\n if (!shouldCheck) {\n return;\n }\n\n await fs.outputFile(path.join(config.cacheDir, \"last-update-check\"), String(Date.now()));\n\n const tags = await getDistTags(ctx);\n\n let latest: string;\n let updateAvailable: boolean;\n let updateMessage: string;\n\n if (packageJson.version.includes(\"experimental\")) {\n // this is an experimental release\n latest = tags.experimental;\n updateAvailable = packageJson.version !== latest;\n updateMessage = sprint`\n Update available! {red ${packageJson.version}} → {green ${latest}}\n Run \"npm install -g ${packageJson.name}@experimental\" to update.\n `;\n } else {\n // this is a stable release\n latest = tags.latest;\n updateAvailable = semver.lt(packageJson.version, latest);\n updateMessage = sprint`\n Update available! {red ${packageJson.version}} → {green ${latest}}\n Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${latest}\n Run \"npm install -g ${packageJson.name}\" to update.\n `;\n }\n\n if (updateAvailable) {\n ctx.log.info(\"update available\", { current: packageJson.version, latest });\n println(\n boxen(updateMessage, {\n padding: 1,\n borderStyle: \"round\",\n textAlignment: \"center\",\n }),\n );\n }\n } catch (error) {\n ctx.log.error(\"failed to check for updates\", { error });\n }\n};\n"],"names":["boxen","dayjs","fs","ms","assert","path","semver","z","config","packageJson","http","println","sprint","UPDATE_CHECK_FREQUENCY","Registry","object","name","literal","latest","string","experimental","getDistTags","ctx","json","context","method","url","responseType","resolveBodyOnly","timeout","request","parse","shouldCheckForUpdate","lastCheck","Number","readFile","join","cacheDir","isNaN","isAfter","error","warnIfUpdateAvailable","shouldCheck","outputFile","String","Date","now","tags","updateAvailable","updateMessage","version","includes","lt","log","info","current","padding","borderStyle","textAlignment"],"mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAAU,YAAY;AAC7B,OAAOC,YAAY,SAAS;AAC5B,SAASC,CAAC,QAAQ,MAAM;AAExB,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,WAAW,QAAQ,4BAA4B;AACxD,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,OAAO,QAAQ,aAAa;AACrC,SAASC,MAAM,QAAQ,cAAc;AAErC,MAAMC,yBAAyBV,GAAG;AAElC,MAAMW,WAAWP,EAAEQ,MAAM,CAAC;IACxBC,MAAMT,EAAEU,OAAO,CAAC;IAChB,aAAaV,EAAEQ,MAAM,CAAC;QACpBG,QAAQX,EAAEY,MAAM;QAChBC,cAAcb,EAAEY,MAAM;IACxB;AACF;AAIA,OAAO,MAAME,cAAc,OAAOC;IAChC,MAAMC,OAAO,MAAMb,KAAK;QACtBc,SAAS;YAAEF;QAAI;QACfG,QAAQ;QACRC,KAAK;QACLC,cAAc;QACdC,iBAAiB;QACjBC,SAAS;YACPC,SAAS3B,GAAG;QACd;IACF;IAEA,OAAOW,SAASiB,KAAK,CAACR,KAAK,CAAC,YAAY;AAC1C,EAAE;AAEF,OAAO,MAAMS,uBAAuB;IAClC,IAAI;QACF,MAAMC,YAAYC,OAAO,MAAMhC,GAAGiC,QAAQ,CAAC9B,KAAK+B,IAAI,CAAC5B,OAAO6B,QAAQ,EAAE,sBAAsB;QAC5FjC,OAAO,CAAC8B,OAAOI,KAAK,CAACL;QACrB,OAAOhC,QAAQsC,OAAO,CAACN,YAAYpB;IACrC,EAAE,OAAO2B,OAAO;QACd,OAAO;IACT;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMC,wBAAwB,OAAOnB;IAC1C,IAAI;QACF,MAAMoB,cAAc,MAAMV;QAC1B,IAAI,CAACU,aAAa;YAChB;QACF;QAEA,MAAMxC,GAAGyC,UAAU,CAACtC,KAAK+B,IAAI,CAAC5B,OAAO6B,QAAQ,EAAE,sBAAsBO,OAAOC,KAAKC,GAAG;QAEpF,MAAMC,OAAO,MAAM1B,YAAYC;QAE/B,IAAIJ;QACJ,IAAI8B;QACJ,IAAIC;QAEJ,IAAIxC,YAAYyC,OAAO,CAACC,QAAQ,CAAC,iBAAiB;YAChD,kCAAkC;YAClCjC,SAAS6B,KAAK3B,YAAY;YAC1B4B,kBAAkBvC,YAAYyC,OAAO,KAAKhC;YAC1C+B,gBAAgBrC,MAAM,CAAC;+BACE,EAAEH,YAAYyC,OAAO,CAAC,WAAW,EAAEhC,OAAO;4BAC7C,EAAET,YAAYO,IAAI,CAAC;MACzC,CAAC;QACH,OAAO;YACL,2BAA2B;YAC3BE,SAAS6B,KAAK7B,MAAM;YACpB8B,kBAAkB1C,OAAO8C,EAAE,CAAC3C,YAAYyC,OAAO,EAAEhC;YACjD+B,gBAAgBrC,MAAM,CAAC;+BACE,EAAEH,YAAYyC,OAAO,CAAC,WAAW,EAAEhC,OAAO;mEACN,EAAEA,OAAO;4BAChD,EAAET,YAAYO,IAAI,CAAC;MACzC,CAAC;QACH;QAEA,IAAIgC,iBAAiB;YACnB1B,IAAI+B,GAAG,CAACC,IAAI,CAAC,oBAAoB;gBAAEC,SAAS9C,YAAYyC,OAAO;gBAAEhC;YAAO;YACxEP,QACEX,MAAMiD,eAAe;gBACnBO,SAAS;gBACTC,aAAa;gBACbC,eAAe;YACjB;QAEJ;IACF,EAAE,OAAOlB,OAAO;QACdlB,IAAI+B,GAAG,CAACb,KAAK,CAAC,+BAA+B;YAAEA;QAAM;IACvD;AACF,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/output/update.ts"],"sourcesContent":["import boxen from \"boxen\";\nimport dayjs from \"dayjs\";\nimport fs from \"fs-extra\";\nimport ms from \"ms\";\nimport assert from \"node:assert\";\nimport path from \"node:path\";\nimport semver from \"semver\";\nimport { z } from \"zod\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { packageJson } from \"../config/package-json.js\";\nimport { http } from \"../http/http.js\";\nimport { println } from \"./print.js\";\nimport { sprint } from \"./sprint.js\";\n\nconst UPDATE_CHECK_FREQUENCY = ms(\"12 hours\");\n\nconst Registry = z.object({\n name: z.literal(\"ggt\"),\n \"dist-tags\": z.object({\n latest: z.string(),\n experimental: z.string(),\n }),\n});\n\ntype Registry = z.infer<typeof Registry>;\n\nexport const getDistTags = async (ctx: Context): Promise<Registry[\"dist-tags\"]> => {\n const json = await http({\n context: { ctx },\n method: \"GET\",\n url: \"https://registry.npmjs.org/ggt\",\n responseType: \"json\",\n resolveBodyOnly: true,\n timeout: {\n request: ms(\"5s\"),\n },\n });\n\n return Registry.parse(json)[\"dist-tags\"];\n};\n\nexport const shouldCheckForUpdate = async (): Promise<boolean> => {\n try {\n const lastCheck = Number(await fs.readFile(path.join(config.cacheDir, \"last-update-check\"), \"utf8\"));\n assert(!Number.isNaN(lastCheck));\n return dayjs().isAfter(lastCheck + UPDATE_CHECK_FREQUENCY);\n } catch (error) {\n return true;\n }\n};\n\n/**\n * Checks for updates to the `ggt` npm package and logs a warning\n * message if an update is available.\n *\n * @returns A Promise that resolves with void when the check is\n * complete.\n */\nexport const warnIfUpdateAvailable = async (ctx: Context): Promise<void> => {\n try {\n const shouldCheck = await shouldCheckForUpdate();\n if (!shouldCheck) {\n return;\n }\n\n await fs.outputFile(path.join(config.cacheDir, \"last-update-check\"), String(Date.now()));\n\n const tags = await getDistTags(ctx);\n\n let latest: string;\n let updateAvailable: boolean;\n let updateMessage: string;\n\n if (packageJson.version.includes(\"experimental\")) {\n // this is an experimental release\n latest = tags.experimental;\n updateAvailable = packageJson.version !== latest;\n updateMessage = sprint`\n Update available! {red ${packageJson.version}} → {green ${latest}}\n Run \"npm install -g ${packageJson.name}@experimental\" to update.\n `;\n } else {\n // this is a stable release\n latest = tags.latest;\n updateAvailable = semver.lt(packageJson.version, latest);\n updateMessage = sprint`\n Update available! {red ${packageJson.version}} → {green ${latest}}\n Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${latest}\n Run \"npm install -g ${packageJson.name}\" to update.\n `;\n }\n\n if (updateAvailable) {\n ctx.log.info(\"update available\", { current: packageJson.version, latest });\n println(\n boxen(updateMessage, {\n padding: 1,\n borderStyle: \"round\",\n textAlignment: \"center\",\n }),\n );\n }\n } catch (error) {\n ctx.log.error(\"failed to check for updates\", { error });\n }\n};\n"],"names":["boxen","dayjs","fs","ms","assert","path","semver","z","config","packageJson","http","println","sprint","UPDATE_CHECK_FREQUENCY","Registry","object","name","literal","latest","string","experimental","getDistTags","ctx","json","context","method","url","responseType","resolveBodyOnly","timeout","request","parse","shouldCheckForUpdate","lastCheck","Number","readFile","join","cacheDir","isNaN","isAfter","error","warnIfUpdateAvailable","shouldCheck","outputFile","String","Date","now","tags","updateAvailable","updateMessage","version","includes","lt","log","info","current","padding","borderStyle","textAlignment"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,WAAW,QAAQ;AAC1B,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,QAAQ,KAAK;AACpB,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAAU,YAAY;AAC7B,OAAOC,YAAY,SAAS;AAC5B,SAASC,CAAC,QAAQ,MAAM;AAExB,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,WAAW,QAAQ,4BAA4B;AACxD,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,OAAO,QAAQ,aAAa;AACrC,SAASC,MAAM,QAAQ,cAAc;AAErC,MAAMC,yBAAyBV,GAAG;AAElC,MAAMW,WAAWP,EAAEQ,MAAM,CAAC;IACxBC,MAAMT,EAAEU,OAAO,CAAC;IAChB,aAAaV,EAAEQ,MAAM,CAAC;QACpBG,QAAQX,EAAEY,MAAM;QAChBC,cAAcb,EAAEY,MAAM;IACxB;AACF;AAIA,OAAO,MAAME,cAAc,OAAOC;IAChC,MAAMC,OAAO,MAAMb,KAAK;QACtBc,SAAS;YAAEF;QAAI;QACfG,QAAQ;QACRC,KAAK;QACLC,cAAc;QACdC,iBAAiB;QACjBC,SAAS;YACPC,SAAS3B,GAAG;QACd;IACF;IAEA,OAAOW,SAASiB,KAAK,CAACR,KAAK,CAAC,YAAY;AAC1C,EAAE;AAEF,OAAO,MAAMS,uBAAuB;IAClC,IAAI;QACF,MAAMC,YAAYC,OAAO,MAAMhC,GAAGiC,QAAQ,CAAC9B,KAAK+B,IAAI,CAAC5B,OAAO6B,QAAQ,EAAE,sBAAsB;QAC5FjC,OAAO,CAAC8B,OAAOI,KAAK,CAACL;QACrB,OAAOhC,QAAQsC,OAAO,CAACN,YAAYpB;IACrC,EAAE,OAAO2B,OAAO;QACd,OAAO;IACT;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMC,wBAAwB,OAAOnB;IAC1C,IAAI;QACF,MAAMoB,cAAc,MAAMV;QAC1B,IAAI,CAACU,aAAa;YAChB;QACF;QAEA,MAAMxC,GAAGyC,UAAU,CAACtC,KAAK+B,IAAI,CAAC5B,OAAO6B,QAAQ,EAAE,sBAAsBO,OAAOC,KAAKC,GAAG;QAEpF,MAAMC,OAAO,MAAM1B,YAAYC;QAE/B,IAAIJ;QACJ,IAAI8B;QACJ,IAAIC;QAEJ,IAAIxC,YAAYyC,OAAO,CAACC,QAAQ,CAAC,iBAAiB;YAChD,kCAAkC;YAClCjC,SAAS6B,KAAK3B,YAAY;YAC1B4B,kBAAkBvC,YAAYyC,OAAO,KAAKhC;YAC1C+B,gBAAgBrC,MAAM,CAAC;+BACE,EAAEH,YAAYyC,OAAO,CAAC,WAAW,EAAEhC,OAAO;4BAC7C,EAAET,YAAYO,IAAI,CAAC;MACzC,CAAC;QACH,OAAO;YACL,2BAA2B;YAC3BE,SAAS6B,KAAK7B,MAAM;YACpB8B,kBAAkB1C,OAAO8C,EAAE,CAAC3C,YAAYyC,OAAO,EAAEhC;YACjD+B,gBAAgBrC,MAAM,CAAC;+BACE,EAAEH,YAAYyC,OAAO,CAAC,WAAW,EAAEhC,OAAO;mEACN,EAAEA,OAAO;4BAChD,EAAET,YAAYO,IAAI,CAAC;MACzC,CAAC;QACH;QAEA,IAAIgC,iBAAiB;YACnB1B,IAAI+B,GAAG,CAACC,IAAI,CAAC,oBAAoB;gBAAEC,SAAS9C,YAAYyC,OAAO;gBAAEhC;YAAO;YACxEP,QACEX,MAAMiD,eAAe;gBACnBO,SAAS;gBACTC,aAAa;gBACbC,eAAe;YACjB;QAEJ;IACF,EAAE,OAAOlB,OAAO;QACdlB,IAAI+B,GAAG,CAACb,KAAK,CAAC,+BAA+B;YAAEA;QAAM;IACvD;AACF,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/user/session.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport { configPath } from \"../config/config.js\";\nimport { swallowEnoent } from \"../filesync/directory.js\";\nimport { createLogger } from \"../output/log/logger.js\";\nimport { memo } from \"../util/function.js\";\n\nconst log = createLogger({ name: \"session\" });\n\n/**\n * Reads the session from either the environment variable `GGT_SESSION`\n * or from the `session.txt` file in the config directory.\n *\n * @returns The session string if found, otherwise undefined.\n */\nexport const readSession = memo((): string | undefined => {\n if (process.env[\"GGT_SESSION\"]) {\n log.debug(\"reading session from env\");\n return process.env[\"GGT_SESSION\"];\n }\n\n try {\n log.debug(\"reading session from disk\");\n return fs.readFileSync(configPath(\"session.txt\"), \"utf8\");\n } catch (error) {\n swallowEnoent(error);\n return undefined;\n }\n});\n\n/**\n * Writes the session to disk in the `session.txt` file in the config.\n *\n * @param session - The session to write to disk.\n */\nexport const writeSession = (session: string | undefined): void => {\n readSession.clear();\n\n if (process.env[\"GGT_SESSION\"]) {\n log.debug(\"writing session to env\", { session: Boolean(session) });\n process.env[\"GGT_SESSION\"] = session;\n }\n\n log.debug(\"writing session to disk\", { session: Boolean(session), path: configPath(\"session.txt\") });\n\n if (session) {\n fs.outputFileSync(configPath(\"session.txt\"), session);\n } else {\n fs.removeSync(configPath(\"session.txt\"));\n }\n};\n\nexport const readToken = (): string | undefined => {\n log.debug(\"reading token from env\");\n return process.env[\"GGT_TOKEN\"];\n};\n"],"names":["fs","configPath","swallowEnoent","createLogger","memo","log","name","readSession","process","env","debug","readFileSync","error","undefined","writeSession","session","clear","Boolean","path","outputFileSync","removeSync","readToken"],"mappings":"AAAA,OAAOA,QAAQ,WAAW;AAC1B,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,aAAa,QAAQ,2BAA2B;AACzD,SAASC,YAAY,QAAQ,0BAA0B;AACvD,SAASC,IAAI,QAAQ,sBAAsB;AAE3C,MAAMC,MAAMF,aAAa;IAAEG,MAAM;AAAU;AAE3C;;;;;CAKC,GACD,OAAO,MAAMC,cAAcH,KAAK;IAC9B,IAAII,QAAQC,GAAG,CAAC,cAAc,EAAE;QAC9BJ,IAAIK,KAAK,CAAC;QACV,OAAOF,QAAQC,GAAG,CAAC,cAAc;IACnC;IAEA,IAAI;QACFJ,IAAIK,KAAK,CAAC;QACV,OAAOV,GAAGW,YAAY,CAACV,WAAW,gBAAgB;IACpD,EAAE,OAAOW,OAAO;QACdV,cAAcU;QACd,OAAOC;IACT;AACF,GAAG;AAEH;;;;CAIC,GACD,OAAO,MAAMC,eAAe,CAACC;IAC3BR,YAAYS,KAAK;IAEjB,IAAIR,QAAQC,GAAG,CAAC,cAAc,EAAE;QAC9BJ,IAAIK,KAAK,CAAC,0BAA0B;YAAEK,SAASE,QAAQF;QAAS;QAChEP,QAAQC,GAAG,CAAC,cAAc,GAAGM;IAC/B;IAEAV,IAAIK,KAAK,CAAC,2BAA2B;QAAEK,SAASE,QAAQF;QAAUG,MAAMjB,WAAW;IAAe;IAElG,IAAIc,SAAS;QACXf,GAAGmB,cAAc,CAAClB,WAAW,gBAAgBc;IAC/C,OAAO;QACLf,GAAGoB,UAAU,CAACnB,WAAW;IAC3B;AACF,EAAE;AAEF,OAAO,MAAMoB,YAAY;IACvBhB,IAAIK,KAAK,CAAC;IACV,OAAOF,QAAQC,GAAG,CAAC,YAAY;AACjC,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/user/session.ts"],"sourcesContent":["import fs from \"fs-extra\";\nimport { configPath } from \"../config/config.js\";\nimport { swallowEnoent } from \"../filesync/directory.js\";\nimport { createLogger } from \"../output/log/logger.js\";\nimport { memo } from \"../util/function.js\";\n\nconst log = createLogger({ name: \"session\" });\n\n/**\n * Reads the session from either the environment variable `GGT_SESSION`\n * or from the `session.txt` file in the config directory.\n *\n * @returns The session string if found, otherwise undefined.\n */\nexport const readSession = memo((): string | undefined => {\n if (process.env[\"GGT_SESSION\"]) {\n log.debug(\"reading session from env\");\n return process.env[\"GGT_SESSION\"];\n }\n\n try {\n log.debug(\"reading session from disk\");\n return fs.readFileSync(configPath(\"session.txt\"), \"utf8\");\n } catch (error) {\n swallowEnoent(error);\n return undefined;\n }\n});\n\n/**\n * Writes the session to disk in the `session.txt` file in the config.\n *\n * @param session - The session to write to disk.\n */\nexport const writeSession = (session: string | undefined): void => {\n readSession.clear();\n\n if (process.env[\"GGT_SESSION\"]) {\n log.debug(\"writing session to env\", { session: Boolean(session) });\n process.env[\"GGT_SESSION\"] = session;\n }\n\n log.debug(\"writing session to disk\", { session: Boolean(session), path: configPath(\"session.txt\") });\n\n if (session) {\n fs.outputFileSync(configPath(\"session.txt\"), session);\n } else {\n fs.removeSync(configPath(\"session.txt\"));\n }\n};\n\nexport const readToken = (): string | undefined => {\n log.debug(\"reading token from env\");\n return process.env[\"GGT_TOKEN\"];\n};\n"],"names":["fs","configPath","swallowEnoent","createLogger","memo","log","name","readSession","process","env","debug","readFileSync","error","undefined","writeSession","session","clear","Boolean","path","outputFileSync","removeSync","readToken"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,QAAQ,WAAW;AAC1B,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,aAAa,QAAQ,2BAA2B;AACzD,SAASC,YAAY,QAAQ,0BAA0B;AACvD,SAASC,IAAI,QAAQ,sBAAsB;AAE3C,MAAMC,MAAMF,aAAa;IAAEG,MAAM;AAAU;AAE3C;;;;;CAKC,GACD,OAAO,MAAMC,cAAcH,KAAK;IAC9B,IAAII,QAAQC,GAAG,CAAC,cAAc,EAAE;QAC9BJ,IAAIK,KAAK,CAAC;QACV,OAAOF,QAAQC,GAAG,CAAC,cAAc;IACnC;IAEA,IAAI;QACFJ,IAAIK,KAAK,CAAC;QACV,OAAOV,GAAGW,YAAY,CAACV,WAAW,gBAAgB;IACpD,EAAE,OAAOW,OAAO;QACdV,cAAcU;QACd,OAAOC;IACT;AACF,GAAG;AAEH;;;;CAIC,GACD,OAAO,MAAMC,eAAe,CAACC;IAC3BR,YAAYS,KAAK;IAEjB,IAAIR,QAAQC,GAAG,CAAC,cAAc,EAAE;QAC9BJ,IAAIK,KAAK,CAAC,0BAA0B;YAAEK,SAASE,QAAQF;QAAS;QAChEP,QAAQC,GAAG,CAAC,cAAc,GAAGM;IAC/B;IAEAV,IAAIK,KAAK,CAAC,2BAA2B;QAAEK,SAASE,QAAQF;QAAUG,MAAMjB,WAAW;IAAe;IAElG,IAAIc,SAAS;QACXf,GAAGmB,cAAc,CAAClB,WAAW,gBAAgBc;IAC/C,OAAO;QACLf,GAAGoB,UAAU,CAACnB,WAAW;IAC3B;AACF,EAAE;AAEF,OAAO,MAAMoB,YAAY;IACvBhB,IAAIK,KAAK,CAAC;IACV,OAAOF,QAAQC,GAAG,CAAC,YAAY;AACjC,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/user/user.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport z from \"zod\";\nimport { login } from \"../../commands/login.js\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { loadAuthHeaders, swallowUnauthorized } from \"../http/auth.js\";\nimport { http } from \"../http/http.js\";\nimport { confirm } from \"../output/confirm.js\";\nimport { println } from \"../output/print.js\";\n\nconst User = z.object({\n id: z.union([z.string(), z.number()]).transform(Number),\n name: z.string().nullish(),\n email: z.string(),\n});\n\nexport type User = z.infer<typeof User>;\n\n/**\n * Retrieves the currently logged in user from Gadgets API.\n *\n * @returns A Promise that resolves to a User object representing the\n * current user, or undefined if the user is not authenticated.\n */\nexport const getUser = async (ctx: Context): Promise<User | undefined> => {\n if (ctx.user) {\n return ctx.user;\n }\n\n const headers = loadAuthHeaders();\n\n if (!headers) {\n return undefined;\n }\n\n try {\n const json = await http({\n context: { ctx },\n url: `https://${config.domains.services}/auth/api/current-user`,\n headers: { ...headers },\n responseType: \"json\",\n resolveBodyOnly: true,\n });\n\n ctx.user = User.parse(json);\n ctx.log.info(\"loaded user\");\n\n return ctx.user;\n } catch (error) {\n swallowUnauthorized(ctx, error);\n return undefined;\n }\n};\n\n/**\n * Retrieves the current user or prompts the user to log in if not\n * already logged in.\n *\n * @param ctx - The current context.\n * @returns A Promise that resolves to the current user.\n */\nexport const getUserOrLogin = async (ctx: Context): Promise<User> => {\n let user = await getUser(ctx);\n if (user) {\n return user;\n }\n\n ctx.log.info(\"prompting user to log in\");\n\n println({ ensureEmptyLineAbove: true })`\n You must be logged in to use \"ggt ${ctx.command}\".\n `;\n\n await confirm({ ensureEmptyLineAbove: true })(\"Would you like to log in?\");\n\n await login(ctx);\n\n user = await getUser(ctx);\n assert(user, \"missing user after successful login\");\n\n return user;\n};\n"],"names":["assert","z","login","config","loadAuthHeaders","swallowUnauthorized","http","confirm","println","User","object","id","union","string","number","transform","Number","name","nullish","email","getUser","ctx","user","headers","undefined","json","context","url","domains","services","responseType","resolveBodyOnly","parse","log","info","error","getUserOrLogin","ensureEmptyLineAbove","command"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,OAAOC,OAAO,MAAM;AACpB,SAASC,KAAK,QAAQ,0BAA0B;AAEhD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,eAAe,EAAEC,mBAAmB,QAAQ,kBAAkB;AACvE,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,OAAO,QAAQ,uBAAuB;AAC/C,SAASC,OAAO,QAAQ,qBAAqB;AAE7C,MAAMC,OAAOR,EAAES,MAAM,CAAC;IACpBC,IAAIV,EAAEW,KAAK,CAAC;QAACX,EAAEY,MAAM;QAAIZ,EAAEa,MAAM;KAAG,EAAEC,SAAS,CAACC;IAChDC,MAAMhB,EAAEY,MAAM,GAAGK,OAAO;IACxBC,OAAOlB,EAAEY,MAAM;AACjB;AAIA;;;;;CAKC,GACD,OAAO,MAAMO,UAAU,OAAOC;IAC5B,IAAIA,IAAIC,IAAI,EAAE;QACZ,OAAOD,IAAIC,IAAI;IACjB;IAEA,MAAMC,UAAUnB;IAEhB,IAAI,CAACmB,SAAS;QACZ,OAAOC;IACT;IAEA,IAAI;QACF,MAAMC,OAAO,MAAMnB,KAAK;YACtBoB,SAAS;gBAAEL;YAAI;YACfM,KAAK,CAAC,QAAQ,EAAExB,OAAOyB,OAAO,CAACC,QAAQ,CAAC,sBAAsB,CAAC;YAC/DN,SAAS;gBAAE,GAAGA,OAAO;YAAC;YACtBO,cAAc;YACdC,iBAAiB;QACnB;QAEAV,IAAIC,IAAI,GAAGb,KAAKuB,KAAK,CAACP;QACtBJ,IAAIY,GAAG,CAACC,IAAI,CAAC;QAEb,OAAOb,IAAIC,IAAI;IACjB,EAAE,OAAOa,OAAO;QACd9B,oBAAoBgB,KAAKc;QACzB,OAAOX;IACT;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMY,iBAAiB,OAAOf;IACnC,IAAIC,OAAO,MAAMF,QAAQC;IACzB,IAAIC,MAAM;QACR,OAAOA;IACT;IAEAD,IAAIY,GAAG,CAACC,IAAI,CAAC;IAEb1B,QAAQ;QAAE6B,sBAAsB;IAAK,EAAE,CAAC;sCACJ,EAAEhB,IAAIiB,OAAO,CAAC;EAClD,CAAC;IAED,MAAM/B,QAAQ;QAAE8B,sBAAsB;IAAK,GAAG;IAE9C,MAAMnC,MAAMmB;IAEZC,OAAO,MAAMF,QAAQC;IACrBrB,OAAOsB,MAAM;IAEb,OAAOA;AACT,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/user/user.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport z from \"zod\";\nimport { login } from \"../../commands/login.js\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { loadAuthHeaders, swallowUnauthorized } from \"../http/auth.js\";\nimport { http } from \"../http/http.js\";\nimport { confirm } from \"../output/confirm.js\";\nimport { println } from \"../output/print.js\";\n\nconst User = z.object({\n id: z.union([z.string(), z.number()]).transform(Number),\n name: z.string().nullish(),\n email: z.string(),\n});\n\nexport type User = z.infer<typeof User>;\n\n/**\n * Retrieves the currently logged in user from Gadgets API.\n *\n * @returns A Promise that resolves to a User object representing the\n * current user, or undefined if the user is not authenticated.\n */\nexport const getUser = async (ctx: Context): Promise<User | undefined> => {\n if (ctx.user) {\n return ctx.user;\n }\n\n const headers = loadAuthHeaders();\n\n if (!headers) {\n return undefined;\n }\n\n try {\n const json = await http({\n context: { ctx },\n url: `https://${config.domains.services}/auth/api/current-user`,\n headers: { ...headers },\n responseType: \"json\",\n resolveBodyOnly: true,\n });\n\n ctx.user = User.parse(json);\n ctx.log.info(\"loaded user\");\n\n return ctx.user;\n } catch (error) {\n swallowUnauthorized(ctx, error);\n return undefined;\n }\n};\n\n/**\n * Retrieves the current user or prompts the user to log in if not\n * already logged in.\n *\n * @param ctx - The current context.\n * @returns A Promise that resolves to the current user.\n */\nexport const getUserOrLogin = async (ctx: Context): Promise<User> => {\n let user = await getUser(ctx);\n if (user) {\n return user;\n }\n\n ctx.log.info(\"prompting user to log in\");\n\n println({ ensureEmptyLineAbove: true })`\n You must be logged in to use \"ggt ${ctx.command}\".\n `;\n\n await confirm({ ensureEmptyLineAbove: true })(\"Would you like to log in?\");\n\n await login(ctx);\n\n user = await getUser(ctx);\n assert(user, \"missing user after successful login\");\n\n return user;\n};\n"],"names":["assert","z","login","config","loadAuthHeaders","swallowUnauthorized","http","confirm","println","User","object","id","union","string","number","transform","Number","name","nullish","email","getUser","ctx","user","headers","undefined","json","context","url","domains","services","responseType","resolveBodyOnly","parse","log","info","error","getUserOrLogin","ensureEmptyLineAbove","command"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,OAAOC,OAAO,MAAM;AACpB,SAASC,KAAK,QAAQ,0BAA0B;AAEhD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,eAAe,EAAEC,mBAAmB,QAAQ,kBAAkB;AACvE,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,OAAO,QAAQ,uBAAuB;AAC/C,SAASC,OAAO,QAAQ,qBAAqB;AAE7C,MAAMC,OAAOR,EAAES,MAAM,CAAC;IACpBC,IAAIV,EAAEW,KAAK,CAAC;QAACX,EAAEY,MAAM;QAAIZ,EAAEa,MAAM;KAAG,EAAEC,SAAS,CAACC;IAChDC,MAAMhB,EAAEY,MAAM,GAAGK,OAAO;IACxBC,OAAOlB,EAAEY,MAAM;AACjB;AAIA;;;;;CAKC,GACD,OAAO,MAAMO,UAAU,OAAOC;IAC5B,IAAIA,IAAIC,IAAI,EAAE;QACZ,OAAOD,IAAIC,IAAI;IACjB;IAEA,MAAMC,UAAUnB;IAEhB,IAAI,CAACmB,SAAS;QACZ,OAAOC;IACT;IAEA,IAAI;QACF,MAAMC,OAAO,MAAMnB,KAAK;YACtBoB,SAAS;gBAAEL;YAAI;YACfM,KAAK,CAAC,QAAQ,EAAExB,OAAOyB,OAAO,CAACC,QAAQ,CAAC,sBAAsB,CAAC;YAC/DN,SAAS;gBAAE,GAAGA,OAAO;YAAC;YACtBO,cAAc;YACdC,iBAAiB;QACnB;QAEAV,IAAIC,IAAI,GAAGb,KAAKuB,KAAK,CAACP;QACtBJ,IAAIY,GAAG,CAACC,IAAI,CAAC;QAEb,OAAOb,IAAIC,IAAI;IACjB,EAAE,OAAOa,OAAO;QACd9B,oBAAoBgB,KAAKc;QACzB,OAAOX;IACT;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMY,iBAAiB,OAAOf;IACnC,IAAIC,OAAO,MAAMF,QAAQC;IACzB,IAAIC,MAAM;QACR,OAAOA;IACT;IAEAD,IAAIY,GAAG,CAACC,IAAI,CAAC;IAEb1B,QAAQ;QAAE6B,sBAAsB;IAAK,EAAE,CAAC;sCACJ,EAAEhB,IAAIiB,OAAO,CAAC;EAClD,CAAC;IAED,MAAM/B,QAAQ;QAAE8B,sBAAsB;IAAK,GAAG;IAE9C,MAAMnC,MAAMmB;IAEZC,OAAO,MAAMF,QAAQC;IACrBrB,OAAOsB,MAAM;IAEb,OAAOA;AACT,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/assert.ts"],"sourcesContent":["/* eslint-disable func-style */\n\n/**\n * Throws an error indicating that the code should be unreachable.\n *\n * @param expr - An optional expression to include in the error message.\n * @throws - Always throws an error with the message \"Unreachable code: {expr}\".\n */\nexport function unreachable(expr?: unknown): never {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unreachable code: ${expr}`);\n}\n"],"names":["unreachable","expr","Error"],"mappings":"AAAA,6BAA6B,GAE7B;;;;;CAKC,GACD,OAAO,SAASA,YAAYC,IAAc;IACxC,4EAA4E;IAC5E,MAAM,IAAIC,MAAM,CAAC,kBAAkB,EAAED,KAAK,CAAC;AAC7C"}
1
+ {"version":3,"sources":["../../../src/services/util/assert.ts"],"sourcesContent":["/* eslint-disable func-style */\n\n/**\n * Throws an error indicating that the code should be unreachable.\n *\n * @param expr - An optional expression to include in the error message.\n * @throws - Always throws an error with the message \"Unreachable code: {expr}\".\n */\nexport function unreachable(expr?: unknown): never {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unreachable code: ${expr}`);\n}\n"],"names":["unreachable","expr","Error"],"rangeMappings":";;;;;;;;","mappings":"AAAA,6BAA6B,GAE7B;;;;;CAKC,GACD,OAAO,SAASA,YAAYC,IAAc;IACxC,4EAA4E;IAC5E,MAAM,IAAIC,MAAM,CAAC,kBAAkB,EAAED,KAAK,CAAC;AAC7C"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/boolean.ts"],"sourcesContent":["import { MemoFirstArg, memo } from \"./function.js\";\n\n/**\n * Parses a string value and returns a boolean value.\n *\n * @param value - The string value to parse.\n * @returns A boolean value representing the parsed value.\n */\nexport const parseBoolean = memo(MemoFirstArg, (value: string | null | undefined): boolean => {\n value ??= \"\";\n return [\"true\", \"1\"].includes(value.trim().toLowerCase());\n});\n"],"names":["MemoFirstArg","memo","parseBoolean","value","includes","trim","toLowerCase"],"mappings":"AAAA,SAASA,YAAY,EAAEC,IAAI,QAAQ,gBAAgB;AAEnD;;;;;CAKC,GACD,OAAO,MAAMC,eAAeD,KAAKD,cAAc,CAACG;IAC9CA,UAAU;IACV,OAAO;QAAC;QAAQ;KAAI,CAACC,QAAQ,CAACD,MAAME,IAAI,GAAGC,WAAW;AACxD,GAAG"}
1
+ {"version":3,"sources":["../../../src/services/util/boolean.ts"],"sourcesContent":["import { MemoFirstArg, memo } from \"./function.js\";\n\n/**\n * Parses a string value and returns a boolean value.\n *\n * @param value - The string value to parse.\n * @returns A boolean value representing the parsed value.\n */\nexport const parseBoolean = memo(MemoFirstArg, (value: string | null | undefined): boolean => {\n value ??= \"\";\n return [\"true\", \"1\"].includes(value.trim().toLowerCase());\n});\n"],"names":["MemoFirstArg","memo","parseBoolean","value","includes","trim","toLowerCase"],"rangeMappings":";;;;;;;;;;;;","mappings":"AAAA,SAASA,YAAY,EAAEC,IAAI,QAAQ,gBAAgB;AAEnD;;;;;CAKC,GACD,OAAO,MAAMC,eAAeD,KAAKD,cAAc,CAACG;IAC9CA,UAAU;IACV,OAAO;QAAC;QAAQ;KAAI,CAACC,QAAQ,CAACD,MAAME,IAAI,GAAGC,WAAW;AACxD,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/collection.ts"],"sourcesContent":["import levenshtein from \"fast-levenshtein\";\nimport assert from \"node:assert\";\n\n/**\n * Returns a new array with all falsy values removed. The values\n * `false`, `null`, `0`, `\"\"`, `undefined`, and `NaN` are falsy.\n *\n * @param array - The array to compact.\n * @returns A new array with all falsy values removed.\n */\nexport const compact = <T>(array: T[]): NonNullable<T>[] => {\n return array.filter((value): value is NonNullable<T> => Boolean(value));\n};\n\n/**\n * Returns a new array with all duplicate elements removed.\n *\n * @param array - The array to remove duplicates from.\n * @returns A new array with all duplicate elements removed.\n */\nexport const uniq = <T>(array: T[]): T[] => {\n return [...new Set(array)];\n};\n\n/**\n * Sorts an array of strings based on their similarity to a given input\n * string. The closest match is returned as the first element, followed\n * by the sorted array.\n *\n * @param input - The input string to compare against.\n * @param options - The array of strings to be sorted.\n * @returns An array with the closest match as the first element,\n * followed by the sorted array.\n */\nexport const sortBySimilar = (input: string, options: readonly string[]): [closest: string, ...sorted: string[]] => {\n assert(options.length > 0, \"options must not be empty\");\n return [...options].sort((a, b) => levenshtein.get(a, input) - levenshtein.get(b, input)) as [string, ...string[]];\n};\n"],"names":["levenshtein","assert","compact","array","filter","value","Boolean","uniq","Set","sortBySimilar","input","options","length","sort","a","b","get"],"mappings":"AAAA,OAAOA,iBAAiB,mBAAmB;AAC3C,OAAOC,YAAY,cAAc;AAEjC;;;;;;CAMC,GACD,OAAO,MAAMC,UAAU,CAAIC;IACzB,OAAOA,MAAMC,MAAM,CAAC,CAACC,QAAmCC,QAAQD;AAClE,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAME,OAAO,CAAIJ;IACtB,OAAO;WAAI,IAAIK,IAAIL;KAAO;AAC5B,EAAE;AAEF;;;;;;;;;CASC,GACD,OAAO,MAAMM,gBAAgB,CAACC,OAAeC;IAC3CV,OAAOU,QAAQC,MAAM,GAAG,GAAG;IAC3B,OAAO;WAAID;KAAQ,CAACE,IAAI,CAAC,CAACC,GAAGC,IAAMf,YAAYgB,GAAG,CAACF,GAAGJ,SAASV,YAAYgB,GAAG,CAACD,GAAGL;AACpF,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/util/collection.ts"],"sourcesContent":["import levenshtein from \"fast-levenshtein\";\nimport assert from \"node:assert\";\n\n/**\n * Returns a new array with all falsy values removed. The values\n * `false`, `null`, `0`, `\"\"`, `undefined`, and `NaN` are falsy.\n *\n * @param array - The array to compact.\n * @returns A new array with all falsy values removed.\n */\nexport const compact = <T>(array: T[]): NonNullable<T>[] => {\n return array.filter((value): value is NonNullable<T> => Boolean(value));\n};\n\n/**\n * Returns a new array with all duplicate elements removed.\n *\n * @param array - The array to remove duplicates from.\n * @returns A new array with all duplicate elements removed.\n */\nexport const uniq = <T>(array: T[]): T[] => {\n return [...new Set(array)];\n};\n\n/**\n * Sorts an array of strings based on their similarity to a given input\n * string. The closest match is returned as the first element, followed\n * by the sorted array.\n *\n * @param input - The input string to compare against.\n * @param options - The array of strings to be sorted.\n * @returns An array with the closest match as the first element,\n * followed by the sorted array.\n */\nexport const sortBySimilar = (input: string, options: readonly string[]): [closest: string, ...sorted: string[]] => {\n assert(options.length > 0, \"options must not be empty\");\n return [...options].sort((a, b) => levenshtein.get(a, input) - levenshtein.get(b, input)) as [string, ...string[]];\n};\n"],"names":["levenshtein","assert","compact","array","filter","value","Boolean","uniq","Set","sortBySimilar","input","options","length","sort","a","b","get"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,iBAAiB,mBAAmB;AAC3C,OAAOC,YAAY,cAAc;AAEjC;;;;;;CAMC,GACD,OAAO,MAAMC,UAAU,CAAIC;IACzB,OAAOA,MAAMC,MAAM,CAAC,CAACC,QAAmCC,QAAQD;AAClE,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAME,OAAO,CAAIJ;IACtB,OAAO;WAAI,IAAIK,IAAIL;KAAO;AAC5B,EAAE;AAEF;;;;;;;;;CASC,GACD,OAAO,MAAMM,gBAAgB,CAACC,OAAeC;IAC3CV,OAAOU,QAAQC,MAAM,GAAG,GAAG;IAC3B,OAAO;WAAID;KAAQ,CAACE,IAAI,CAAC,CAACC,GAAGC,IAAMf,YAAYgB,GAAG,CAACF,GAAGJ,SAASV,YAAYgB,GAAG,CAACD,GAAGL;AACpF,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/function.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable func-style */\nimport mimicFunction from \"mimic-function\";\nimport assert from \"node:assert\";\nimport type { SetReturnType } from \"type-fest\";\nimport { isFunction } from \"./is.js\";\nimport { type AnyFunction } from \"./types.js\";\n\nconst memoizedFns = new Set<MemoizedFn>();\n\n/**\n * A function that has been wrapped by {@linkcode memo}.\n */\nexport type MemoizedFn<Fn extends AnyFunction = AnyFunction> = Fn & {\n /**\n * Clears the cache of the memoized function.\n */\n clear: () => void;\n};\n\n/**\n * A function that returns an empty string.\n *\n * Used as the default key function for {@linkcode memo}.\n */\nexport const MemoFirstCall = (): string => \"\";\n\n/**\n * A function that returns the first argument as a string.\n */\nexport const MemoFirstArg = (...args: any[]): string => String(args[0]);\n\n/**\n * A function that returns all arguments as a string.\n *\n * Useful for memoizing functions that accept a variable number of\n * arguments.\n */\nexport const MemoAllArgs = (...args: any[]): string => args.map(String).join(\":\");\n\n/**\n * Creates a memoized version of the provided function.\n *\n * The memoized function caches the result of the first call and returns\n * the cached result for all subsequent calls.\n *\n * @param fn - The function to memoize.\n * @see MemoFirstCall\n */\nexport function memo<Fn extends AnyFunction>(fn: Fn): MemoizedFn<Fn>;\n\n/**\n * Creates a memoized version of the provided function.\n *\n * The memoized function caches the results of previous calls and\n * returns the cached result when the key returned by `keyFn` matches\n * a previous call.\n *\n * @param keyFn - A function that returns a key for the arguments.\n * @param fn - The function to memoize.\n */\nexport function memo<Fn extends AnyFunction, KeyFn extends (...args: Parameters<Fn>) => string>(keyFn: KeyFn, fn: Fn): MemoizedFn<Fn>;\n\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function memo<Fn extends AnyFunction, KeyFn extends (...args: Parameters<Fn>) => string>(\n fnOrKeyFn: Fn | KeyFn,\n fn?: Fn,\n): MemoizedFn<Fn> {\n let keyFn: KeyFn;\n if (fn) {\n keyFn = fnOrKeyFn as KeyFn;\n } else {\n fn = fnOrKeyFn as Fn;\n keyFn = MemoFirstArg as unknown as KeyFn;\n }\n\n const cache = new Map<string, unknown>();\n\n const memoized = ((...args: Parameters<Fn>) => {\n const key = keyFn(...args);\n if (cache.has(key)) {\n return cache.get(key);\n }\n\n assert(fn, \"fn shouldn't be undefined\");\n const result = fn(...args);\n cache.set(key, result);\n\n return result;\n }) as MemoizedFn<Fn>;\n\n memoized.clear = cache.clear.bind(cache);\n\n memoizedFns.add(memoized);\n\n mimicFunction(memoized, fn);\n\n return memoized;\n}\n\n/**\n * Clears the cache of all memoized functions.\n */\nexport const clearMemoized = (): void => {\n for (const memoized of memoizedFns) {\n memoized.clear();\n }\n};\n\n/**\n * A function that has been wrapped by {@linkcode debounce}.\n */\nexport type DebouncedFunc<Fn extends (...args: unknown[]) => void> = Fn & {\n /**\n * Invokes the function if it is waiting to stop being called.\n */\n flush: () => void;\n};\n\n/**\n * Creates a debounced function that delays invoking the provided\n * function until after `delayMS` milliseconds have elapsed since the\n * last time it was invoked.\n *\n * @param delayMS - The number of milliseconds to delay.\n * @param fn - The function to be debounced.\n * @returns A debounced version of the provided function.\n */\nexport const debounce = <F extends (...args: unknown[]) => void>(delayMS: number, fn: F): DebouncedFunc<F> => {\n let timerId: NodeJS.Timeout | undefined;\n let upcomingCall: (() => void) | undefined;\n\n const debounced = ((...args) => {\n upcomingCall = () => {\n upcomingCall = undefined;\n timerId = undefined;\n fn(...args);\n };\n\n clearTimeout(timerId);\n timerId = setTimeout(upcomingCall, delayMS);\n }) as DebouncedFunc<F>;\n\n debounced.flush = () => {\n if (upcomingCall) {\n upcomingCall();\n }\n };\n\n mimicFunction(debounced, fn);\n\n return debounced;\n};\n\n/**\n * A function that has been wrapped by {@linkcode debounce}.\n */\nexport type DebouncedAsyncFunc<Fn extends (...args: unknown[]) => Promise<void>> = SetReturnType<Fn, void> & {\n /**\n * Invokes the function if it is waiting to stop being called.\n */\n flush: () => Promise<void>;\n};\n\n/**\n * Creates a debounced function that delays invoking the provided\n * function until after `delayMS` milliseconds have elapsed since the\n * last time it was invoked.\n *\n * @param delayMS - The number of milliseconds to delay.\n * @param fn - The function to be debounced.\n * @returns A debounced version of the provided function.\n */\nexport const debounceAsync = <F extends (...args: unknown[]) => Promise<void>>(delayMS: number, fn: F): DebouncedAsyncFunc<F> => {\n let timerId: NodeJS.Timeout | undefined;\n let nextCall: (() => Promise<void>) | undefined;\n let pendingPromise: Promise<void> | undefined;\n\n const debouncedAsync = ((...args) => {\n nextCall = () => {\n nextCall = undefined;\n timerId = undefined;\n\n if (pendingPromise) {\n pendingPromise = pendingPromise\n .then(() => fn(...args))\n .catch(noop)\n .finally(() => (pendingPromise = undefined));\n } else {\n pendingPromise = fn(...args)\n .catch(noop)\n .finally(() => (pendingPromise = undefined));\n }\n\n return pendingPromise;\n };\n\n clearTimeout(timerId);\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n timerId = setTimeout(nextCall, delayMS);\n }) as DebouncedAsyncFunc<F>;\n\n debouncedAsync.flush = async () => {\n if (nextCall) {\n await nextCall();\n }\n };\n\n mimicFunction(debouncedAsync, fn);\n\n return debouncedAsync;\n};\n\n/**\n * Either a value or a function that returns a value.\n */\nexport type Thunk<T, Args extends any[] = []> = T | ((...args: Args) => T);\n\n/**\n * Wraps a value in a thunk (a function that returns a value). If the\n * value is already a function, it is returned as is.\n *\n * @param val - The value or function to wrap.\n * @returns A function that returns the value.\n */\nexport const thunk = <T>(val: T | (() => T)): (() => T) => {\n if (isFunction(val)) {\n return val;\n }\n return () => val;\n};\n\n/**\n * Unwraps a value from a thunk (a function that returns a value). If the\n * value is not a function, it is returned as is.\n *\n * @param value - The value or thunk to unwrap.\n * @returns The unwrapped value.\n */\nexport const unthunk = <T, Args extends any[]>(value: Thunk<T, Args>, ...args: Args): T => {\n if (isFunction(value)) {\n return value(...args);\n }\n return value;\n};\n\n/**\n * A function that does nothing and returns nothing.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport const noop = (..._args: any[]): void => {};\n\n/**\n * A function that does nothing and returns `this`.\n */\nexport const noopThis = function <T>(this: T, ..._args: any[]): T {\n return this;\n};\n\n/**\n * A function that does nothing and returns a function that does nothing.\n */\nexport const noopNoop = (..._args: any[]): typeof noop => {\n return noop;\n};\n"],"names":["mimicFunction","assert","isFunction","memoizedFns","Set","MemoFirstCall","MemoFirstArg","args","String","MemoAllArgs","map","join","memo","fnOrKeyFn","fn","keyFn","cache","Map","memoized","key","has","get","result","set","clear","bind","add","clearMemoized","debounce","delayMS","timerId","upcomingCall","debounced","undefined","clearTimeout","setTimeout","flush","debounceAsync","nextCall","pendingPromise","debouncedAsync","then","catch","noop","finally","thunk","val","unthunk","value","_args","noopThis","noopNoop"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/util/function.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable func-style */\nimport mimicFunction from \"mimic-function\";\nimport assert from \"node:assert\";\nimport type { SetReturnType } from \"type-fest\";\nimport { isFunction } from \"./is.js\";\nimport { type AnyFunction } from \"./types.js\";\n\nconst memoizedFns = new Set<MemoizedFn>();\n\n/**\n * A function that has been wrapped by {@linkcode memo}.\n */\nexport type MemoizedFn<Fn extends AnyFunction = AnyFunction> = Fn & {\n /**\n * Clears the cache of the memoized function.\n */\n clear: () => void;\n};\n\n/**\n * A function that returns an empty string.\n *\n * Used as the default key function for {@linkcode memo}.\n */\nexport const MemoFirstCall = (): string => \"\";\n\n/**\n * A function that returns the first argument as a string.\n */\nexport const MemoFirstArg = (...args: any[]): string => String(args[0]);\n\n/**\n * A function that returns all arguments as a string.\n *\n * Useful for memoizing functions that accept a variable number of\n * arguments.\n */\nexport const MemoAllArgs = (...args: any[]): string => args.map(String).join(\":\");\n\n/**\n * Creates a memoized version of the provided function.\n *\n * The memoized function caches the result of the first call and returns\n * the cached result for all subsequent calls.\n *\n * @param fn - The function to memoize.\n * @see MemoFirstCall\n */\nexport function memo<Fn extends AnyFunction>(fn: Fn): MemoizedFn<Fn>;\n\n/**\n * Creates a memoized version of the provided function.\n *\n * The memoized function caches the results of previous calls and\n * returns the cached result when the key returned by `keyFn` matches\n * a previous call.\n *\n * @param keyFn - A function that returns a key for the arguments.\n * @param fn - The function to memoize.\n */\nexport function memo<Fn extends AnyFunction, KeyFn extends (...args: Parameters<Fn>) => string>(keyFn: KeyFn, fn: Fn): MemoizedFn<Fn>;\n\n// eslint-disable-next-line jsdoc/require-jsdoc\nexport function memo<Fn extends AnyFunction, KeyFn extends (...args: Parameters<Fn>) => string>(\n fnOrKeyFn: Fn | KeyFn,\n fn?: Fn,\n): MemoizedFn<Fn> {\n let keyFn: KeyFn;\n if (fn) {\n keyFn = fnOrKeyFn as KeyFn;\n } else {\n fn = fnOrKeyFn as Fn;\n keyFn = MemoFirstArg as unknown as KeyFn;\n }\n\n const cache = new Map<string, unknown>();\n\n const memoized = ((...args: Parameters<Fn>) => {\n const key = keyFn(...args);\n if (cache.has(key)) {\n return cache.get(key);\n }\n\n assert(fn, \"fn shouldn't be undefined\");\n const result = fn(...args);\n cache.set(key, result);\n\n return result;\n }) as MemoizedFn<Fn>;\n\n memoized.clear = cache.clear.bind(cache);\n\n memoizedFns.add(memoized);\n\n mimicFunction(memoized, fn);\n\n return memoized;\n}\n\n/**\n * Clears the cache of all memoized functions.\n */\nexport const clearMemoized = (): void => {\n for (const memoized of memoizedFns) {\n memoized.clear();\n }\n};\n\n/**\n * A function that has been wrapped by {@linkcode debounce}.\n */\nexport type DebouncedFunc<Fn extends (...args: unknown[]) => void> = Fn & {\n /**\n * Invokes the function if it is waiting to stop being called.\n */\n flush: () => void;\n};\n\n/**\n * Creates a debounced function that delays invoking the provided\n * function until after `delayMS` milliseconds have elapsed since the\n * last time it was invoked.\n *\n * @param delayMS - The number of milliseconds to delay.\n * @param fn - The function to be debounced.\n * @returns A debounced version of the provided function.\n */\nexport const debounce = <F extends (...args: unknown[]) => void>(delayMS: number, fn: F): DebouncedFunc<F> => {\n let timerId: NodeJS.Timeout | undefined;\n let upcomingCall: (() => void) | undefined;\n\n const debounced = ((...args) => {\n upcomingCall = () => {\n upcomingCall = undefined;\n timerId = undefined;\n fn(...args);\n };\n\n clearTimeout(timerId);\n timerId = setTimeout(upcomingCall, delayMS);\n }) as DebouncedFunc<F>;\n\n debounced.flush = () => {\n if (upcomingCall) {\n upcomingCall();\n }\n };\n\n mimicFunction(debounced, fn);\n\n return debounced;\n};\n\n/**\n * A function that has been wrapped by {@linkcode debounce}.\n */\nexport type DebouncedAsyncFunc<Fn extends (...args: unknown[]) => Promise<void>> = SetReturnType<Fn, void> & {\n /**\n * Invokes the function if it is waiting to stop being called.\n */\n flush: () => Promise<void>;\n};\n\n/**\n * Creates a debounced function that delays invoking the provided\n * function until after `delayMS` milliseconds have elapsed since the\n * last time it was invoked.\n *\n * @param delayMS - The number of milliseconds to delay.\n * @param fn - The function to be debounced.\n * @returns A debounced version of the provided function.\n */\nexport const debounceAsync = <F extends (...args: unknown[]) => Promise<void>>(delayMS: number, fn: F): DebouncedAsyncFunc<F> => {\n let timerId: NodeJS.Timeout | undefined;\n let nextCall: (() => Promise<void>) | undefined;\n let pendingPromise: Promise<void> | undefined;\n\n const debouncedAsync = ((...args) => {\n nextCall = () => {\n nextCall = undefined;\n timerId = undefined;\n\n if (pendingPromise) {\n pendingPromise = pendingPromise\n .then(() => fn(...args))\n .catch(noop)\n .finally(() => (pendingPromise = undefined));\n } else {\n pendingPromise = fn(...args)\n .catch(noop)\n .finally(() => (pendingPromise = undefined));\n }\n\n return pendingPromise;\n };\n\n clearTimeout(timerId);\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n timerId = setTimeout(nextCall, delayMS);\n }) as DebouncedAsyncFunc<F>;\n\n debouncedAsync.flush = async () => {\n if (nextCall) {\n await nextCall();\n }\n };\n\n mimicFunction(debouncedAsync, fn);\n\n return debouncedAsync;\n};\n\n/**\n * Either a value or a function that returns a value.\n */\nexport type Thunk<T, Args extends any[] = []> = T | ((...args: Args) => T);\n\n/**\n * Wraps a value in a thunk (a function that returns a value). If the\n * value is already a function, it is returned as is.\n *\n * @param val - The value or function to wrap.\n * @returns A function that returns the value.\n */\nexport const thunk = <T>(val: T | (() => T)): (() => T) => {\n if (isFunction(val)) {\n return val;\n }\n return () => val;\n};\n\n/**\n * Unwraps a value from a thunk (a function that returns a value). If the\n * value is not a function, it is returned as is.\n *\n * @param value - The value or thunk to unwrap.\n * @returns The unwrapped value.\n */\nexport const unthunk = <T, Args extends any[]>(value: Thunk<T, Args>, ...args: Args): T => {\n if (isFunction(value)) {\n return value(...args);\n }\n return value;\n};\n\n/**\n * A function that does nothing and returns nothing.\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport const noop = (..._args: any[]): void => {};\n\n/**\n * A function that does nothing and returns `this`.\n */\nexport const noopThis = function <T>(this: T, ..._args: any[]): T {\n return this;\n};\n\n/**\n * A function that does nothing and returns a function that does nothing.\n */\nexport const noopNoop = (..._args: any[]): typeof noop => {\n return noop;\n};\n"],"names":["mimicFunction","assert","isFunction","memoizedFns","Set","MemoFirstCall","MemoFirstArg","args","String","MemoAllArgs","map","join","memo","fnOrKeyFn","fn","keyFn","cache","Map","memoized","key","has","get","result","set","clear","bind","add","clearMemoized","debounce","delayMS","timerId","upcomingCall","debounced","undefined","clearTimeout","setTimeout","flush","debounceAsync","nextCall","pendingPromise","debouncedAsync","then","catch","noop","finally","thunk","val","unthunk","value","_args","noopThis","noopNoop"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/is.ts"],"sourcesContent":["import type { ExecutionResult, GraphQLError } from \"graphql\";\nimport type { SetOptional } from \"type-fest\";\nimport type { CloseEvent, ErrorEvent } from \"ws\";\nimport { z } from \"zod\";\n\nexport const isNil = (val: unknown): val is null | undefined => {\n return val === null || val === undefined;\n};\n\nexport const isString = (val: unknown): val is string => {\n return typeof val === \"string\";\n};\n\nexport const isObject = (val: unknown): val is object => {\n return typeof val === \"object\" && val !== null;\n};\n\nexport const isArray = Array.isArray;\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const isFunction = (val: unknown): val is Function => {\n return typeof val === \"function\";\n};\n\nexport const isError = (val: unknown): val is Error => {\n return val instanceof Error;\n};\n\nexport const isCloseEvent = (e: unknown): e is SetOptional<CloseEvent, \"target\"> => {\n return z.object({ type: z.string(), code: z.number(), reason: z.string(), wasClean: z.boolean() }).safeParse(e).success;\n};\n\nexport const isErrorEvent = (e: unknown): e is SetOptional<ErrorEvent, \"target\"> => {\n return z.object({ type: z.string(), message: z.string(), error: z.any() }).safeParse(e).success;\n};\n\nexport const isGraphQLResult = (val: unknown): val is ExecutionResult => {\n return z\n .union([\n z.object({ data: z.record(z.unknown()) }),\n z.object({ errors: z.array(z.object({ message: z.string() })) }),\n z.object({\n data: z.record(z.unknown()),\n errors: z.array(z.object({ message: z.string() })),\n }),\n ])\n .safeParse(val).success;\n};\n\nexport const isGraphQLErrors = (e: unknown): e is readonly GraphQLError[] => {\n return z\n .array(\n z.object({\n message: z.string(),\n extensions: z\n .record(z.unknown())\n .nullish()\n .transform((ext) => ext ?? {}),\n }),\n )\n .min(1)\n .safeParse(e).success;\n};\n\nexport const isNever = (value: never): never => {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unexpected value: ${value}`);\n};\n\nexport const isAbortError = (error: unknown): error is Error | Event => {\n return (error instanceof Error && error.name === \"AbortError\") || (error instanceof Event && error.type === \"abort\");\n};\n\nexport const isENOENTError = (error: unknown): error is { code: \"ENOENT\" } => {\n return isObject(error) && \"code\" in error && error.code === \"ENOENT\";\n};\n\nexport const isENOTEMPTYError = (error: unknown): error is { code: \"ENOTEMPTY\" } => {\n return isObject(error) && \"code\" in error && error.code === \"ENOTEMPTY\";\n};\n\nexport const isENOTDIRError = (error: unknown): error is { code: \"ENOTDIR\" } => {\n return isObject(error) && \"code\" in error && error.code === \"ENOTDIR\";\n};\n\nexport const isEEXISTError = (error: unknown): error is { code: \"EEXIST\" } => {\n return isObject(error) && \"code\" in error && error.code === \"EEXIST\";\n};\n\nexport const isJavaScriptFile = (filepath: string): boolean => {\n return [\".js\", \".jsx\", \".cjs\", \".mjs\"].some((ext) => filepath.endsWith(ext));\n};\n\nexport const isTypeScriptFile = (filepath: string): boolean => {\n return [\".ts\", \".tsx\", \".cts\", \".mts\"].some((ext) => filepath.endsWith(ext) && !filepath.endsWith(\".d.ts\"));\n};\n\nexport const isGellyFile = (filepath: string): boolean => {\n return filepath.endsWith(\".gelly\");\n};\n"],"names":["z","isNil","val","undefined","isString","isObject","isArray","Array","isFunction","isError","Error","isCloseEvent","e","object","type","string","code","number","reason","wasClean","boolean","safeParse","success","isErrorEvent","message","error","any","isGraphQLResult","union","data","record","unknown","errors","array","isGraphQLErrors","extensions","nullish","transform","ext","min","isNever","value","isAbortError","name","Event","isENOENTError","isENOTEMPTYError","isENOTDIRError","isEEXISTError","isJavaScriptFile","filepath","some","endsWith","isTypeScriptFile","isGellyFile"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/util/is.ts"],"sourcesContent":["import type { ExecutionResult, GraphQLError } from \"graphql\";\nimport type { SetOptional } from \"type-fest\";\nimport type { CloseEvent, ErrorEvent } from \"ws\";\nimport { z } from \"zod\";\n\nexport const isNil = (val: unknown): val is null | undefined => {\n return val === null || val === undefined;\n};\n\nexport const isString = (val: unknown): val is string => {\n return typeof val === \"string\";\n};\n\nexport const isObject = (val: unknown): val is object => {\n return typeof val === \"object\" && val !== null;\n};\n\nexport const isArray = Array.isArray;\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nexport const isFunction = (val: unknown): val is Function => {\n return typeof val === \"function\";\n};\n\nexport const isError = (val: unknown): val is Error => {\n return val instanceof Error;\n};\n\nexport const isCloseEvent = (e: unknown): e is SetOptional<CloseEvent, \"target\"> => {\n return z.object({ type: z.string(), code: z.number(), reason: z.string(), wasClean: z.boolean() }).safeParse(e).success;\n};\n\nexport const isErrorEvent = (e: unknown): e is SetOptional<ErrorEvent, \"target\"> => {\n return z.object({ type: z.string(), message: z.string(), error: z.any() }).safeParse(e).success;\n};\n\nexport const isGraphQLResult = (val: unknown): val is ExecutionResult => {\n return z\n .union([\n z.object({ data: z.record(z.unknown()) }),\n z.object({ errors: z.array(z.object({ message: z.string() })) }),\n z.object({\n data: z.record(z.unknown()),\n errors: z.array(z.object({ message: z.string() })),\n }),\n ])\n .safeParse(val).success;\n};\n\nexport const isGraphQLErrors = (e: unknown): e is readonly GraphQLError[] => {\n return z\n .array(\n z.object({\n message: z.string(),\n extensions: z\n .record(z.unknown())\n .nullish()\n .transform((ext) => ext ?? {}),\n }),\n )\n .min(1)\n .safeParse(e).success;\n};\n\nexport const isNever = (value: never): never => {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n throw new Error(`Unexpected value: ${value}`);\n};\n\nexport const isAbortError = (error: unknown): error is Error | Event => {\n return (error instanceof Error && error.name === \"AbortError\") || (error instanceof Event && error.type === \"abort\");\n};\n\nexport const isENOENTError = (error: unknown): error is { code: \"ENOENT\" } => {\n return isObject(error) && \"code\" in error && error.code === \"ENOENT\";\n};\n\nexport const isENOTEMPTYError = (error: unknown): error is { code: \"ENOTEMPTY\" } => {\n return isObject(error) && \"code\" in error && error.code === \"ENOTEMPTY\";\n};\n\nexport const isENOTDIRError = (error: unknown): error is { code: \"ENOTDIR\" } => {\n return isObject(error) && \"code\" in error && error.code === \"ENOTDIR\";\n};\n\nexport const isEEXISTError = (error: unknown): error is { code: \"EEXIST\" } => {\n return isObject(error) && \"code\" in error && error.code === \"EEXIST\";\n};\n\nexport const isJavaScriptFile = (filepath: string): boolean => {\n return [\".js\", \".jsx\", \".cjs\", \".mjs\"].some((ext) => filepath.endsWith(ext));\n};\n\nexport const isTypeScriptFile = (filepath: string): boolean => {\n return [\".ts\", \".tsx\", \".cts\", \".mts\"].some((ext) => filepath.endsWith(ext) && !filepath.endsWith(\".d.ts\"));\n};\n\nexport const isGellyFile = (filepath: string): boolean => {\n return filepath.endsWith(\".gelly\");\n};\n"],"names":["z","isNil","val","undefined","isString","isObject","isArray","Array","isFunction","isError","Error","isCloseEvent","e","object","type","string","code","number","reason","wasClean","boolean","safeParse","success","isErrorEvent","message","error","any","isGraphQLResult","union","data","record","unknown","errors","array","isGraphQLErrors","extensions","nullish","transform","ext","min","isNever","value","isAbortError","name","Event","isENOENTError","isENOTEMPTYError","isENOTDIRError","isEEXISTError","isJavaScriptFile","filepath","some","endsWith","isTypeScriptFile","isGellyFile"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/json.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/consistent-type-definitions */\n\ndeclare global {\n interface BigInt {\n toJSON?(): string;\n }\n interface Map<K, V> {\n toJSON?(): Record<string, V>;\n }\n interface Set<T> {\n toJSON?(): T[];\n }\n}\n\nconst bigintToJSON = function (this: bigint): string {\n return String(this);\n};\n\nconst mapToJSON = function <K, V>(this: Map<K, V>): Record<string, V> {\n return Object.fromEntries(this);\n};\n\nconst setToJSON = function <T>(this: Set<T>): T[] {\n return Array.from(this);\n};\n\nexport const installJsonExtensions = (): void => {\n if (!Object.prototype.hasOwnProperty.call(BigInt, \"toJSON\")) {\n BigInt.prototype.toJSON = bigintToJSON;\n }\n\n if (!Object.prototype.hasOwnProperty.call(Map, \"toJSON\")) {\n Map.prototype.toJSON = mapToJSON;\n }\n\n if (!Object.prototype.hasOwnProperty.call(Set, \"toJSON\")) {\n Set.prototype.toJSON = setToJSON;\n }\n};\n\nexport const uninstallJsonExtensions = (): void => {\n if (BigInt.prototype.toJSON === bigintToJSON) {\n delete BigInt.prototype.toJSON;\n }\n\n if (Map.prototype.toJSON === mapToJSON) {\n delete Map.prototype.toJSON;\n }\n\n if (Set.prototype.toJSON === setToJSON) {\n delete Set.prototype.toJSON;\n }\n};\n"],"names":["bigintToJSON","String","mapToJSON","Object","fromEntries","setToJSON","Array","from","installJsonExtensions","prototype","hasOwnProperty","call","BigInt","toJSON","Map","Set","uninstallJsonExtensions"],"mappings":"AAAA,oDAAoD,GACpD,sDAAsD,GACtD,iEAAiE,GAcjE,MAAMA,eAAe;IACnB,OAAOC,OAAO,IAAI;AACpB;AAEA,MAAMC,YAAY;IAChB,OAAOC,OAAOC,WAAW,CAAC,IAAI;AAChC;AAEA,MAAMC,YAAY;IAChB,OAAOC,MAAMC,IAAI,CAAC,IAAI;AACxB;AAEA,OAAO,MAAMC,wBAAwB;IACnC,IAAI,CAACL,OAAOM,SAAS,CAACC,cAAc,CAACC,IAAI,CAACC,QAAQ,WAAW;QAC3DA,OAAOH,SAAS,CAACI,MAAM,GAAGb;IAC5B;IAEA,IAAI,CAACG,OAAOM,SAAS,CAACC,cAAc,CAACC,IAAI,CAACG,KAAK,WAAW;QACxDA,IAAIL,SAAS,CAACI,MAAM,GAAGX;IACzB;IAEA,IAAI,CAACC,OAAOM,SAAS,CAACC,cAAc,CAACC,IAAI,CAACI,KAAK,WAAW;QACxDA,IAAIN,SAAS,CAACI,MAAM,GAAGR;IACzB;AACF,EAAE;AAEF,OAAO,MAAMW,0BAA0B;IACrC,IAAIJ,OAAOH,SAAS,CAACI,MAAM,KAAKb,cAAc;QAC5C,OAAOY,OAAOH,SAAS,CAACI,MAAM;IAChC;IAEA,IAAIC,IAAIL,SAAS,CAACI,MAAM,KAAKX,WAAW;QACtC,OAAOY,IAAIL,SAAS,CAACI,MAAM;IAC7B;IAEA,IAAIE,IAAIN,SAAS,CAACI,MAAM,KAAKR,WAAW;QACtC,OAAOU,IAAIN,SAAS,CAACI,MAAM;IAC7B;AACF,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/util/json.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-unsafe-return */\n/* eslint-disable @typescript-eslint/consistent-type-definitions */\n\ndeclare global {\n interface BigInt {\n toJSON?(): string;\n }\n interface Map<K, V> {\n toJSON?(): Record<string, V>;\n }\n interface Set<T> {\n toJSON?(): T[];\n }\n}\n\nconst bigintToJSON = function (this: bigint): string {\n return String(this);\n};\n\nconst mapToJSON = function <K, V>(this: Map<K, V>): Record<string, V> {\n return Object.fromEntries(this);\n};\n\nconst setToJSON = function <T>(this: Set<T>): T[] {\n return Array.from(this);\n};\n\nexport const installJsonExtensions = (): void => {\n if (!Object.prototype.hasOwnProperty.call(BigInt, \"toJSON\")) {\n BigInt.prototype.toJSON = bigintToJSON;\n }\n\n if (!Object.prototype.hasOwnProperty.call(Map, \"toJSON\")) {\n Map.prototype.toJSON = mapToJSON;\n }\n\n if (!Object.prototype.hasOwnProperty.call(Set, \"toJSON\")) {\n Set.prototype.toJSON = setToJSON;\n }\n};\n\nexport const uninstallJsonExtensions = (): void => {\n if (BigInt.prototype.toJSON === bigintToJSON) {\n delete BigInt.prototype.toJSON;\n }\n\n if (Map.prototype.toJSON === mapToJSON) {\n delete Map.prototype.toJSON;\n }\n\n if (Set.prototype.toJSON === setToJSON) {\n delete Set.prototype.toJSON;\n }\n};\n"],"names":["bigintToJSON","String","mapToJSON","Object","fromEntries","setToJSON","Array","from","installJsonExtensions","prototype","hasOwnProperty","call","BigInt","toJSON","Map","Set","uninstallJsonExtensions"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,oDAAoD,GACpD,sDAAsD,GACtD,iEAAiE,GAcjE,MAAMA,eAAe;IACnB,OAAOC,OAAO,IAAI;AACpB;AAEA,MAAMC,YAAY;IAChB,OAAOC,OAAOC,WAAW,CAAC,IAAI;AAChC;AAEA,MAAMC,YAAY;IAChB,OAAOC,MAAMC,IAAI,CAAC,IAAI;AACxB;AAEA,OAAO,MAAMC,wBAAwB;IACnC,IAAI,CAACL,OAAOM,SAAS,CAACC,cAAc,CAACC,IAAI,CAACC,QAAQ,WAAW;QAC3DA,OAAOH,SAAS,CAACI,MAAM,GAAGb;IAC5B;IAEA,IAAI,CAACG,OAAOM,SAAS,CAACC,cAAc,CAACC,IAAI,CAACG,KAAK,WAAW;QACxDA,IAAIL,SAAS,CAACI,MAAM,GAAGX;IACzB;IAEA,IAAI,CAACC,OAAOM,SAAS,CAACC,cAAc,CAACC,IAAI,CAACI,KAAK,WAAW;QACxDA,IAAIN,SAAS,CAACI,MAAM,GAAGR;IACzB;AACF,EAAE;AAEF,OAAO,MAAMW,0BAA0B;IACrC,IAAIJ,OAAOH,SAAS,CAACI,MAAM,KAAKb,cAAc;QAC5C,OAAOY,OAAOH,SAAS,CAACI,MAAM;IAChC;IAEA,IAAIC,IAAIL,SAAS,CAACI,MAAM,KAAKX,WAAW;QACtC,OAAOY,IAAIL,SAAS,CAACI,MAAM;IAC7B;IAEA,IAAIE,IAAIN,SAAS,CAACI,MAAM,KAAKR,WAAW;QACtC,OAAOU,IAAIN,SAAS,CAACI,MAAM;IAC7B;AACF,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/number.ts"],"sourcesContent":["/**\n * Parses a string value into a number. If the value is an invalid\n * number it returns {@linkcode defaultValue}.\n *\n * @param value - The string value to parse.\n * @returns The parsed number.\n */\nexport const parseNumber = (value: string | null | undefined, defaultValue = 0): number => {\n value ??= \"\";\n const parsed = Number.parseFloat(value);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n};\n\n/**\n * Ensures that a number is within a given range.\n *\n * If the number is less than the minimum value, the minimum value is returned.\n * If the number is greater than the maximum value, the maximum value is returned.\n * Otherwise, the number is returned as is.\n *\n * @param value - The value to be clamped.\n * @param min - The minimum value of the range.\n * @param max - The maximum value of the range.\n * @returns The clamped value.\n */\nexport const clamp = (value: number, min: number, max: number): number => {\n return Math.max(min, Math.min(max, value));\n};\n"],"names":["parseNumber","value","defaultValue","parsed","Number","parseFloat","isNaN","clamp","min","max","Math"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,MAAMA,cAAc,CAACC,OAAkCC,eAAe,CAAC;IAC5ED,UAAU;IACV,MAAME,SAASC,OAAOC,UAAU,CAACJ;IACjC,OAAOG,OAAOE,KAAK,CAACH,UAAUD,eAAeC;AAC/C,EAAE;AAEF;;;;;;;;;;;CAWC,GACD,OAAO,MAAMI,QAAQ,CAACN,OAAeO,KAAaC;IAChD,OAAOC,KAAKD,GAAG,CAACD,KAAKE,KAAKF,GAAG,CAACC,KAAKR;AACrC,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/util/number.ts"],"sourcesContent":["/**\n * Parses a string value into a number. If the value is an invalid\n * number it returns {@linkcode defaultValue}.\n *\n * @param value - The string value to parse.\n * @returns The parsed number.\n */\nexport const parseNumber = (value: string | null | undefined, defaultValue = 0): number => {\n value ??= \"\";\n const parsed = Number.parseFloat(value);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n};\n\n/**\n * Ensures that a number is within a given range.\n *\n * If the number is less than the minimum value, the minimum value is returned.\n * If the number is greater than the maximum value, the maximum value is returned.\n * Otherwise, the number is returned as is.\n *\n * @param value - The value to be clamped.\n * @param min - The minimum value of the range.\n * @param max - The maximum value of the range.\n * @returns The clamped value.\n */\nexport const clamp = (value: number, min: number, max: number): number => {\n return Math.max(min, Math.min(max, value));\n};\n"],"names":["parseNumber","value","defaultValue","parsed","Number","parseFloat","isNaN","clamp","min","max","Math"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA;;;;;;CAMC,GACD,OAAO,MAAMA,cAAc,CAACC,OAAkCC,eAAe,CAAC;IAC5ED,UAAU;IACV,MAAME,SAASC,OAAOC,UAAU,CAACJ;IACjC,OAAOG,OAAOE,KAAK,CAACH,UAAUD,eAAeC;AAC/C,EAAE;AAEF;;;;;;;;;;;CAWC,GACD,OAAO,MAAMI,QAAQ,CAACN,OAAeO,KAAaC;IAChD,OAAOC,KAAKD,GAAG,CAACD,KAAKE,KAAKF,GAAG,CAACC,KAAKR;AACrC,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/object.ts"],"sourcesContent":["import cleanStack from \"clean-stack\";\nimport { RequestError } from \"got\";\nimport { inspect } from \"node:util\";\nimport { serializeError as baseSerializeError, type ErrorObject } from \"serialize-error\";\nimport type { Simplify } from \"type-fest\";\nimport { workspaceRoot } from \"./paths.js\";\n\n/**\n * Returns a new object with the properties of the input object merged\n * with the properties of the defaults object. If a property exists in\n * both objects, the property of the input object will be used.\n *\n * @param input - The input object to merge with the defaults object.\n * @param defaults - The defaults object to merge with the input object.\n * @returns A new object with the properties of the input object merged\n * with the properties of the defaults object.\n */\nexport const defaults = <Input extends Record<string, unknown>, Defaults extends Partial<Input>>(\n input: Input | null | undefined,\n defaults: Defaults,\n): Simplify<Defaults & Input> => {\n const result = { ...input };\n for (const [key, defaultValue] of Object.entries(defaults)) {\n if (!result[key]) {\n result[key] = defaultValue;\n }\n }\n return result as Simplify<Defaults & Input>;\n};\n\n/**\n * Creates a new object with only the specified properties of the\n * original object.\n *\n * @param object - The original object to pick properties from.\n * @param keys - The keys of the properties to pick.\n * @returns A new object with only the specified properties of the\n * original object.\n */\nexport const pick = <T extends Record<string, unknown>, K extends keyof T>(object: T, keys: readonly K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n result[key] = object[key];\n }\n return result;\n};\n\n/**\n * Returns a new object with the specified keys omitted.\n *\n * @param record - The input object.\n * @param keys - The keys to omit.\n * @returns A new object with the specified keys omitted.\n */\nexport const omit = <T extends Record<string, unknown>, K extends keyof T>(record: T, keys: readonly K[]): Omit<T, K> => {\n const result = { ...record };\n for (const key of keys) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[key];\n }\n return result;\n};\n\n/**\n * Maps the values of an object to a new set of values using the\n * provided function.\n *\n * @param obj - The input object to map.\n * @param fn - The function to apply to each value in the input object.\n * @returns A new object with the same keys as the input object, but\n * with the values mapped to new values using the provided function.\n */\nexport const mapValues = <Key extends string | number | symbol, Value, MappedValue>(\n obj: Record<Key, Value>,\n fn: (value: Value) => MappedValue,\n): Record<Key, MappedValue> => {\n const result = {} as Record<Key, MappedValue>;\n for (const [key, value] of Object.entries(obj)) {\n result[key as Key] = fn(value as Value);\n }\n return result;\n};\n\n/**\n * Universal Error object to json blob serializer.\n *\n * Wraps `serialize-error` with some handy stuff, like special support\n * for Got HTTP errors\n */\nexport const serializeError = (error: unknown): ErrorObject => {\n if (Array.isArray(error)) {\n error = error[0];\n }\n\n let serialized = baseSerializeError(error);\n if (typeof serialized == \"string\") {\n serialized = { message: serialized };\n }\n\n if (serialized.stack) {\n serialized.stack = cleanStack(serialized.stack, { pretty: true, basePath: workspaceRoot }).replaceAll(/file:\\/\\/\\//g, \"\");\n }\n\n if (error instanceof RequestError) {\n serialized[\"timings\"] = undefined;\n serialized[\"options\"] = {\n method: error.options.method,\n url: error.options.url instanceof URL ? error.options.url.toJSON() : error.options.url,\n };\n serialized[\"responseBody\"] = inspect(error.response?.body);\n }\n\n return serialized;\n};\n"],"names":["cleanStack","RequestError","inspect","serializeError","baseSerializeError","workspaceRoot","defaults","input","result","key","defaultValue","Object","entries","pick","object","keys","omit","record","mapValues","obj","fn","value","error","Array","isArray","serialized","message","stack","pretty","basePath","replaceAll","undefined","method","options","url","URL","toJSON","response","body"],"mappings":"AAAA,OAAOA,gBAAgB,cAAc;AACrC,SAASC,YAAY,QAAQ,MAAM;AACnC,SAASC,OAAO,QAAQ,YAAY;AACpC,SAASC,kBAAkBC,kBAAkB,QAA0B,kBAAkB;AAEzF,SAASC,aAAa,QAAQ,aAAa;AAE3C;;;;;;;;;CASC,GACD,OAAO,MAAMC,WAAW,CACtBC,OACAD;IAEA,MAAME,SAAS;QAAE,GAAGD,KAAK;IAAC;IAC1B,KAAK,MAAM,CAACE,KAAKC,aAAa,IAAIC,OAAOC,OAAO,CAACN,UAAW;QAC1D,IAAI,CAACE,MAAM,CAACC,IAAI,EAAE;YAChBD,MAAM,CAACC,IAAI,GAAGC;QAChB;IACF;IACA,OAAOF;AACT,EAAE;AAEF;;;;;;;;CAQC,GACD,OAAO,MAAMK,OAAO,CAAuDC,QAAWC;IACpF,MAAMP,SAAS,CAAC;IAChB,KAAK,MAAMC,OAAOM,KAAM;QACtBP,MAAM,CAACC,IAAI,GAAGK,MAAM,CAACL,IAAI;IAC3B;IACA,OAAOD;AACT,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMQ,OAAO,CAAuDC,QAAWF;IACpF,MAAMP,SAAS;QAAE,GAAGS,MAAM;IAAC;IAC3B,KAAK,MAAMR,OAAOM,KAAM;QACtB,gEAAgE;QAChE,OAAOP,MAAM,CAACC,IAAI;IACpB;IACA,OAAOD;AACT,EAAE;AAEF;;;;;;;;CAQC,GACD,OAAO,MAAMU,YAAY,CACvBC,KACAC;IAEA,MAAMZ,SAAS,CAAC;IAChB,KAAK,MAAM,CAACC,KAAKY,MAAM,IAAIV,OAAOC,OAAO,CAACO,KAAM;QAC9CX,MAAM,CAACC,IAAW,GAAGW,GAAGC;IAC1B;IACA,OAAOb;AACT,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAML,iBAAiB,CAACmB;IAC7B,IAAIC,MAAMC,OAAO,CAACF,QAAQ;QACxBA,QAAQA,KAAK,CAAC,EAAE;IAClB;IAEA,IAAIG,aAAarB,mBAAmBkB;IACpC,IAAI,OAAOG,cAAc,UAAU;QACjCA,aAAa;YAAEC,SAASD;QAAW;IACrC;IAEA,IAAIA,WAAWE,KAAK,EAAE;QACpBF,WAAWE,KAAK,GAAG3B,WAAWyB,WAAWE,KAAK,EAAE;YAAEC,QAAQ;YAAMC,UAAUxB;QAAc,GAAGyB,UAAU,CAAC,gBAAgB;IACxH;IAEA,IAAIR,iBAAiBrB,cAAc;QACjCwB,UAAU,CAAC,UAAU,GAAGM;QACxBN,UAAU,CAAC,UAAU,GAAG;YACtBO,QAAQV,MAAMW,OAAO,CAACD,MAAM;YAC5BE,KAAKZ,MAAMW,OAAO,CAACC,GAAG,YAAYC,MAAMb,MAAMW,OAAO,CAACC,GAAG,CAACE,MAAM,KAAKd,MAAMW,OAAO,CAACC,GAAG;QACxF;QACAT,UAAU,CAAC,eAAe,GAAGvB,QAAQoB,MAAMe,QAAQ,EAAEC;IACvD;IAEA,OAAOb;AACT,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/util/object.ts"],"sourcesContent":["import cleanStack from \"clean-stack\";\nimport { RequestError } from \"got\";\nimport { inspect } from \"node:util\";\nimport { serializeError as baseSerializeError, type ErrorObject } from \"serialize-error\";\nimport type { Simplify } from \"type-fest\";\nimport { workspaceRoot } from \"./paths.js\";\n\n/**\n * Returns a new object with the properties of the input object merged\n * with the properties of the defaults object. If a property exists in\n * both objects, the property of the input object will be used.\n *\n * @param input - The input object to merge with the defaults object.\n * @param defaults - The defaults object to merge with the input object.\n * @returns A new object with the properties of the input object merged\n * with the properties of the defaults object.\n */\nexport const defaults = <Input extends Record<string, unknown>, Defaults extends Partial<Input>>(\n input: Input | null | undefined,\n defaults: Defaults,\n): Simplify<Defaults & Input> => {\n const result = { ...input };\n for (const [key, defaultValue] of Object.entries(defaults)) {\n if (!result[key]) {\n result[key] = defaultValue;\n }\n }\n return result as Simplify<Defaults & Input>;\n};\n\n/**\n * Creates a new object with only the specified properties of the\n * original object.\n *\n * @param object - The original object to pick properties from.\n * @param keys - The keys of the properties to pick.\n * @returns A new object with only the specified properties of the\n * original object.\n */\nexport const pick = <T extends Record<string, unknown>, K extends keyof T>(object: T, keys: readonly K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n result[key] = object[key];\n }\n return result;\n};\n\n/**\n * Returns a new object with the specified keys omitted.\n *\n * @param record - The input object.\n * @param keys - The keys to omit.\n * @returns A new object with the specified keys omitted.\n */\nexport const omit = <T extends Record<string, unknown>, K extends keyof T>(record: T, keys: readonly K[]): Omit<T, K> => {\n const result = { ...record };\n for (const key of keys) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete result[key];\n }\n return result;\n};\n\n/**\n * Maps the values of an object to a new set of values using the\n * provided function.\n *\n * @param obj - The input object to map.\n * @param fn - The function to apply to each value in the input object.\n * @returns A new object with the same keys as the input object, but\n * with the values mapped to new values using the provided function.\n */\nexport const mapValues = <Key extends string | number | symbol, Value, MappedValue>(\n obj: Record<Key, Value>,\n fn: (value: Value) => MappedValue,\n): Record<Key, MappedValue> => {\n const result = {} as Record<Key, MappedValue>;\n for (const [key, value] of Object.entries(obj)) {\n result[key as Key] = fn(value as Value);\n }\n return result;\n};\n\n/**\n * Universal Error object to json blob serializer.\n *\n * Wraps `serialize-error` with some handy stuff, like special support\n * for Got HTTP errors\n */\nexport const serializeError = (error: unknown): ErrorObject => {\n if (Array.isArray(error)) {\n error = error[0];\n }\n\n let serialized = baseSerializeError(error);\n if (typeof serialized == \"string\") {\n serialized = { message: serialized };\n }\n\n if (serialized.stack) {\n serialized.stack = cleanStack(serialized.stack, { pretty: true, basePath: workspaceRoot }).replaceAll(/file:\\/\\/\\//g, \"\");\n }\n\n if (error instanceof RequestError) {\n serialized[\"timings\"] = undefined;\n serialized[\"options\"] = {\n method: error.options.method,\n url: error.options.url instanceof URL ? error.options.url.toJSON() : error.options.url,\n };\n serialized[\"responseBody\"] = inspect(error.response?.body);\n }\n\n return serialized;\n};\n"],"names":["cleanStack","RequestError","inspect","serializeError","baseSerializeError","workspaceRoot","defaults","input","result","key","defaultValue","Object","entries","pick","object","keys","omit","record","mapValues","obj","fn","value","error","Array","isArray","serialized","message","stack","pretty","basePath","replaceAll","undefined","method","options","url","URL","toJSON","response","body"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,gBAAgB,cAAc;AACrC,SAASC,YAAY,QAAQ,MAAM;AACnC,SAASC,OAAO,QAAQ,YAAY;AACpC,SAASC,kBAAkBC,kBAAkB,QAA0B,kBAAkB;AAEzF,SAASC,aAAa,QAAQ,aAAa;AAE3C;;;;;;;;;CASC,GACD,OAAO,MAAMC,WAAW,CACtBC,OACAD;IAEA,MAAME,SAAS;QAAE,GAAGD,KAAK;IAAC;IAC1B,KAAK,MAAM,CAACE,KAAKC,aAAa,IAAIC,OAAOC,OAAO,CAACN,UAAW;QAC1D,IAAI,CAACE,MAAM,CAACC,IAAI,EAAE;YAChBD,MAAM,CAACC,IAAI,GAAGC;QAChB;IACF;IACA,OAAOF;AACT,EAAE;AAEF;;;;;;;;CAQC,GACD,OAAO,MAAMK,OAAO,CAAuDC,QAAWC;IACpF,MAAMP,SAAS,CAAC;IAChB,KAAK,MAAMC,OAAOM,KAAM;QACtBP,MAAM,CAACC,IAAI,GAAGK,MAAM,CAACL,IAAI;IAC3B;IACA,OAAOD;AACT,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMQ,OAAO,CAAuDC,QAAWF;IACpF,MAAMP,SAAS;QAAE,GAAGS,MAAM;IAAC;IAC3B,KAAK,MAAMR,OAAOM,KAAM;QACtB,gEAAgE;QAChE,OAAOP,MAAM,CAACC,IAAI;IACpB;IACA,OAAOD;AACT,EAAE;AAEF;;;;;;;;CAQC,GACD,OAAO,MAAMU,YAAY,CACvBC,KACAC;IAEA,MAAMZ,SAAS,CAAC;IAChB,KAAK,MAAM,CAACC,KAAKY,MAAM,IAAIV,OAAOC,OAAO,CAACO,KAAM;QAC9CX,MAAM,CAACC,IAAW,GAAGW,GAAGC;IAC1B;IACA,OAAOb;AACT,EAAE;AAEF;;;;;CAKC,GACD,OAAO,MAAML,iBAAiB,CAACmB;IAC7B,IAAIC,MAAMC,OAAO,CAACF,QAAQ;QACxBA,QAAQA,KAAK,CAAC,EAAE;IAClB;IAEA,IAAIG,aAAarB,mBAAmBkB;IACpC,IAAI,OAAOG,cAAc,UAAU;QACjCA,aAAa;YAAEC,SAASD;QAAW;IACrC;IAEA,IAAIA,WAAWE,KAAK,EAAE;QACpBF,WAAWE,KAAK,GAAG3B,WAAWyB,WAAWE,KAAK,EAAE;YAAEC,QAAQ;YAAMC,UAAUxB;QAAc,GAAGyB,UAAU,CAAC,gBAAgB;IACxH;IAEA,IAAIR,iBAAiBrB,cAAc;QACjCwB,UAAU,CAAC,UAAU,GAAGM;QACxBN,UAAU,CAAC,UAAU,GAAG;YACtBO,QAAQV,MAAMW,OAAO,CAACD,MAAM;YAC5BE,KAAKZ,MAAMW,OAAO,CAACC,GAAG,YAAYC,MAAMb,MAAMW,OAAO,CAACC,GAAG,CAACE,MAAM,KAAKd,MAAMW,OAAO,CAACC,GAAG;QACxF;QACAT,UAAU,CAAC,eAAe,GAAGvB,QAAQoB,MAAMe,QAAQ,EAAEC;IACvD;IAEA,OAAOb;AACT,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/paths.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Returns the filename of the current module.\n *\n * @returns The filename of the current module.\n */\nexport const thisFilename = (): string => fileURLToPath(import.meta.url);\n\n/**\n * Returns the directory name of the current module.\n *\n * @returns The directory name of the current module.\n */\nexport const thisDirname = (): string => path.dirname(thisFilename());\n\n/**\n * Returns a path relative to the current module.\n *\n * @param segments - The segments of the path.\n * @returns The path relative to the current module.\n */\nexport const relativeToThisFile = (...segments: string[]): string => path.join(thisDirname(), ...segments);\n\n/**\n * The root directory of the ggt package.\n */\nexport const workspaceRoot = relativeToThisFile(\"../../../\");\n\n/**\n * Returns an absolute path within the ggt package.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const workspacePath = (...segments: string[]): string => path.join(workspaceRoot, ...segments);\n\n/**\n * Returns an absolute path within the `assets` directory of the ggt\n * package.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const assetsPath = (...segments: string[]): string => workspacePath(\"assets\", ...segments);\n"],"names":["path","fileURLToPath","thisFilename","url","thisDirname","dirname","relativeToThisFile","segments","join","workspaceRoot","workspacePath","assetsPath"],"mappings":"AAAA,OAAOA,UAAU,YAAY;AAC7B,SAASC,aAAa,QAAQ,WAAW;AAEzC;;;;CAIC,GACD,OAAO,MAAMC,eAAe,IAAcD,cAAc,YAAYE,GAAG,EAAE;AAEzE;;;;CAIC,GACD,OAAO,MAAMC,cAAc,IAAcJ,KAAKK,OAAO,CAACH,gBAAgB;AAEtE;;;;;CAKC,GACD,OAAO,MAAMI,qBAAqB,CAAC,GAAGC,WAA+BP,KAAKQ,IAAI,CAACJ,kBAAkBG,UAAU;AAE3G;;CAEC,GACD,OAAO,MAAME,gBAAgBH,mBAAmB,aAAa;AAE7D;;;;;CAKC,GACD,OAAO,MAAMI,gBAAgB,CAAC,GAAGH,WAA+BP,KAAKQ,IAAI,CAACC,kBAAkBF,UAAU;AAEtG;;;;;;CAMC,GACD,OAAO,MAAMI,aAAa,CAAC,GAAGJ,WAA+BG,cAAc,aAAaH,UAAU"}
1
+ {"version":3,"sources":["../../../src/services/util/paths.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Returns the filename of the current module.\n *\n * @returns The filename of the current module.\n */\nexport const thisFilename = (): string => fileURLToPath(import.meta.url);\n\n/**\n * Returns the directory name of the current module.\n *\n * @returns The directory name of the current module.\n */\nexport const thisDirname = (): string => path.dirname(thisFilename());\n\n/**\n * Returns a path relative to the current module.\n *\n * @param segments - The segments of the path.\n * @returns The path relative to the current module.\n */\nexport const relativeToThisFile = (...segments: string[]): string => path.join(thisDirname(), ...segments);\n\n/**\n * The root directory of the ggt package.\n */\nexport const workspaceRoot = relativeToThisFile(\"../../../\");\n\n/**\n * Returns an absolute path within the ggt package.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const workspacePath = (...segments: string[]): string => path.join(workspaceRoot, ...segments);\n\n/**\n * Returns an absolute path within the `assets` directory of the ggt\n * package.\n *\n * @param segments - The segments of the path to join.\n * @returns The absolute path to the file or directory.\n */\nexport const assetsPath = (...segments: string[]): string => workspacePath(\"assets\", ...segments);\n"],"names":["path","fileURLToPath","thisFilename","url","thisDirname","dirname","relativeToThisFile","segments","join","workspaceRoot","workspacePath","assetsPath"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,UAAU,YAAY;AAC7B,SAASC,aAAa,QAAQ,WAAW;AAEzC;;;;CAIC,GACD,OAAO,MAAMC,eAAe,IAAcD,cAAc,YAAYE,GAAG,EAAE;AAEzE;;;;CAIC,GACD,OAAO,MAAMC,cAAc,IAAcJ,KAAKK,OAAO,CAACH,gBAAgB;AAEtE;;;;;CAKC,GACD,OAAO,MAAMI,qBAAqB,CAAC,GAAGC,WAA+BP,KAAKQ,IAAI,CAACJ,kBAAkBG,UAAU;AAE3G;;CAEC,GACD,OAAO,MAAME,gBAAgBH,mBAAmB,aAAa;AAE7D;;;;;CAKC,GACD,OAAO,MAAMI,gBAAgB,CAAC,GAAGH,WAA+BP,KAAKQ,IAAI,CAACC,kBAAkBF,UAAU;AAEtG;;;;;;CAMC,GACD,OAAO,MAAMI,aAAa,CAAC,GAAGJ,WAA+BG,cAAc,aAAaH,UAAU"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/promise.ts"],"sourcesContent":["import ms from \"ms\";\nimport type { TimerOptions } from \"node:timers\";\nimport { setTimeout } from \"node:timers/promises\";\n\nexport const delay = (duration: string, options?: TimerOptions): Promise<void> => setTimeout(ms(duration), undefined, options);\n\n/**\n * Long lived references to Promises stress the garbage collector in JS.\n *\n * Instead of caching resolved Promises, we cache these little data\n * objects instead which reference the resolution or rejection of the\n * Promise, allowing the Promise object to be free'd.\n */\nexport class PromiseWrapper<T> {\n resolution?: T;\n rejection?: unknown;\n pendingPromise?: Promise<T>;\n\n constructor(promise: Promise<T>) {\n this.pendingPromise = promise;\n\n promise\n .then((res) => {\n this.resolution = res;\n return res;\n })\n .catch((err) => {\n this.rejection = err;\n })\n .finally(() => {\n delete this.pendingPromise;\n });\n }\n\n async unwrap(): Promise<T> {\n if (this.pendingPromise) {\n return await this.pendingPromise;\n } else if (this.rejection) {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw this.rejection;\n } else {\n return this.resolution as T;\n }\n }\n}\n\n/**\n * A promise that can be resolved or rejected from outside its callback.\n *\n * This is typically used when you want to await a promise that is\n * resolved or rejected from outside the current scope, such as from an\n * event handler.\n *\n * @example\n * const signal = new PromiseSignal();\n * process.on(\"SIGINT\", () => {\n * signal.resolve();\n * });\n * await signal;\n */\nexport class PromiseSignal<T = void> implements Promise<T> {\n readonly [Symbol.toStringTag]!: string;\n\n resolve!: (value: T | PromiseLike<T>) => void;\n reject!: (reason?: unknown) => void;\n\n private _promise: PromiseWrapper<T>;\n\n constructor() {\n this._promise = new PromiseWrapper<T>(\n new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n }),\n );\n\n this[Symbol.toStringTag] = String(this._promise.pendingPromise);\n }\n\n then<R = T, E = never>(\n onfulfilled?: (value: T) => R | PromiseLike<R>,\n onrejected?: (reason: unknown) => E | PromiseLike<E>,\n ): Promise<R | E> {\n return this._promise.unwrap().then(onfulfilled, onrejected);\n }\n\n catch<E = never>(onrejected?: (reason: unknown) => E | PromiseLike<E>): Promise<T | E> {\n return this._promise.unwrap().catch(onrejected);\n }\n\n finally(onfinally?: () => void): Promise<T> {\n return this._promise.unwrap().finally(onfinally);\n }\n}\n"],"names":["ms","setTimeout","delay","duration","options","undefined","PromiseWrapper","unwrap","pendingPromise","rejection","resolution","constructor","promise","then","res","catch","err","finally","Symbol","toStringTag","PromiseSignal","onfulfilled","onrejected","_promise","onfinally","resolve","reject","Promise","String"],"mappings":";AAAA,OAAOA,QAAQ,KAAK;AAEpB,SAASC,UAAU,QAAQ,uBAAuB;AAElD,OAAO,MAAMC,QAAQ,CAACC,UAAkBC,UAA0CH,WAAWD,GAAGG,WAAWE,WAAWD,SAAS;AAE/H;;;;;;CAMC,GACD,OAAO,MAAME;IAqBX,MAAMC,SAAqB;QACzB,IAAI,IAAI,CAACC,cAAc,EAAE;YACvB,OAAO,MAAM,IAAI,CAACA,cAAc;QAClC,OAAO,IAAI,IAAI,CAACC,SAAS,EAAE;YACzB,+DAA+D;YAC/D,MAAM,IAAI,CAACA,SAAS;QACtB,OAAO;YACL,OAAO,IAAI,CAACC,UAAU;QACxB;IACF;IAzBAC,YAAYC,OAAmB,CAAE;QAJjCF,uBAAAA,cAAAA,KAAAA;QACAD,uBAAAA,aAAAA,KAAAA;QACAD,uBAAAA,kBAAAA,KAAAA;QAGE,IAAI,CAACA,cAAc,GAAGI;QAEtBA,QACGC,IAAI,CAAC,CAACC;YACL,IAAI,CAACJ,UAAU,GAAGI;YAClB,OAAOA;QACT,GACCC,KAAK,CAAC,CAACC;YACN,IAAI,CAACP,SAAS,GAAGO;QACnB,GACCC,OAAO,CAAC;YACP,OAAO,IAAI,CAACT,cAAc;QAC5B;IACJ;AAYF;IAiBYU,sBAAAA,OAAOC,WAAW;AAf9B;;;;;;;;;;;;;CAaC,GACD,OAAO,MAAMC;IAmBXP,KACEQ,WAA8C,EAC9CC,UAAoD,EACpC;QAChB,OAAO,IAAI,CAACC,QAAQ,CAAChB,MAAM,GAAGM,IAAI,CAACQ,aAAaC;IAClD;IAEAP,MAAiBO,UAAoD,EAAkB;QACrF,OAAO,IAAI,CAACC,QAAQ,CAAChB,MAAM,GAAGQ,KAAK,CAACO;IACtC;IAEAL,QAAQO,SAAsB,EAAc;QAC1C,OAAO,IAAI,CAACD,QAAQ,CAAChB,MAAM,GAAGU,OAAO,CAACO;IACxC;IAxBAb,aAAc;QAPd,uBAAUO,qBAAV,KAAA;QAEAO,uBAAAA,WAAAA,KAAAA;QACAC,uBAAAA,UAAAA,KAAAA;QAEA,uBAAQH,YAAR,KAAA;QAGE,IAAI,CAACA,QAAQ,GAAG,IAAIjB,eAClB,IAAIqB,QAAQ,CAACF,SAASC;YACpB,IAAI,CAACD,OAAO,GAAGA;YACf,IAAI,CAACC,MAAM,GAAGA;QAChB;QAGF,IAAI,CAACR,OAAOC,WAAW,CAAC,GAAGS,OAAO,IAAI,CAACL,QAAQ,CAACf,cAAc;IAChE;AAgBF"}
1
+ {"version":3,"sources":["../../../src/services/util/promise.ts"],"sourcesContent":["import ms from \"ms\";\nimport type { TimerOptions } from \"node:timers\";\nimport { setTimeout } from \"node:timers/promises\";\n\nexport const delay = (duration: string, options?: TimerOptions): Promise<void> => setTimeout(ms(duration), undefined, options);\n\n/**\n * Long lived references to Promises stress the garbage collector in JS.\n *\n * Instead of caching resolved Promises, we cache these little data\n * objects instead which reference the resolution or rejection of the\n * Promise, allowing the Promise object to be free'd.\n */\nexport class PromiseWrapper<T> {\n resolution?: T;\n rejection?: unknown;\n pendingPromise?: Promise<T>;\n\n constructor(promise: Promise<T>) {\n this.pendingPromise = promise;\n\n promise\n .then((res) => {\n this.resolution = res;\n return res;\n })\n .catch((err) => {\n this.rejection = err;\n })\n .finally(() => {\n delete this.pendingPromise;\n });\n }\n\n async unwrap(): Promise<T> {\n if (this.pendingPromise) {\n return await this.pendingPromise;\n } else if (this.rejection) {\n // eslint-disable-next-line @typescript-eslint/no-throw-literal\n throw this.rejection;\n } else {\n return this.resolution as T;\n }\n }\n}\n\n/**\n * A promise that can be resolved or rejected from outside its callback.\n *\n * This is typically used when you want to await a promise that is\n * resolved or rejected from outside the current scope, such as from an\n * event handler.\n *\n * @example\n * const signal = new PromiseSignal();\n * process.on(\"SIGINT\", () => {\n * signal.resolve();\n * });\n * await signal;\n */\nexport class PromiseSignal<T = void> implements Promise<T> {\n readonly [Symbol.toStringTag]!: string;\n\n resolve!: (value: T | PromiseLike<T>) => void;\n reject!: (reason?: unknown) => void;\n\n private _promise: PromiseWrapper<T>;\n\n constructor() {\n this._promise = new PromiseWrapper<T>(\n new Promise((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n }),\n );\n\n this[Symbol.toStringTag] = String(this._promise.pendingPromise);\n }\n\n then<R = T, E = never>(\n onfulfilled?: (value: T) => R | PromiseLike<R>,\n onrejected?: (reason: unknown) => E | PromiseLike<E>,\n ): Promise<R | E> {\n return this._promise.unwrap().then(onfulfilled, onrejected);\n }\n\n catch<E = never>(onrejected?: (reason: unknown) => E | PromiseLike<E>): Promise<T | E> {\n return this._promise.unwrap().catch(onrejected);\n }\n\n finally(onfinally?: () => void): Promise<T> {\n return this._promise.unwrap().finally(onfinally);\n }\n}\n"],"names":["ms","setTimeout","delay","duration","options","undefined","PromiseWrapper","unwrap","pendingPromise","rejection","resolution","constructor","promise","then","res","catch","err","finally","Symbol","toStringTag","PromiseSignal","onfulfilled","onrejected","_promise","onfinally","resolve","reject","Promise","String"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AAAA,OAAOA,QAAQ,KAAK;AAEpB,SAASC,UAAU,QAAQ,uBAAuB;AAElD,OAAO,MAAMC,QAAQ,CAACC,UAAkBC,UAA0CH,WAAWD,GAAGG,WAAWE,WAAWD,SAAS;AAE/H;;;;;;CAMC,GACD,OAAO,MAAME;IAqBX,MAAMC,SAAqB;QACzB,IAAI,IAAI,CAACC,cAAc,EAAE;YACvB,OAAO,MAAM,IAAI,CAACA,cAAc;QAClC,OAAO,IAAI,IAAI,CAACC,SAAS,EAAE;YACzB,+DAA+D;YAC/D,MAAM,IAAI,CAACA,SAAS;QACtB,OAAO;YACL,OAAO,IAAI,CAACC,UAAU;QACxB;IACF;IAzBAC,YAAYC,OAAmB,CAAE;QAJjCF,uBAAAA,cAAAA,KAAAA;QACAD,uBAAAA,aAAAA,KAAAA;QACAD,uBAAAA,kBAAAA,KAAAA;QAGE,IAAI,CAACA,cAAc,GAAGI;QAEtBA,QACGC,IAAI,CAAC,CAACC;YACL,IAAI,CAACJ,UAAU,GAAGI;YAClB,OAAOA;QACT,GACCC,KAAK,CAAC,CAACC;YACN,IAAI,CAACP,SAAS,GAAGO;QACnB,GACCC,OAAO,CAAC;YACP,OAAO,IAAI,CAACT,cAAc;QAC5B;IACJ;AAYF;IAiBYU,sBAAAA,OAAOC,WAAW;AAf9B;;;;;;;;;;;;;CAaC,GACD,OAAO,MAAMC;IAmBXP,KACEQ,WAA8C,EAC9CC,UAAoD,EACpC;QAChB,OAAO,IAAI,CAACC,QAAQ,CAAChB,MAAM,GAAGM,IAAI,CAACQ,aAAaC;IAClD;IAEAP,MAAiBO,UAAoD,EAAkB;QACrF,OAAO,IAAI,CAACC,QAAQ,CAAChB,MAAM,GAAGQ,KAAK,CAACO;IACtC;IAEAL,QAAQO,SAAsB,EAAc;QAC1C,OAAO,IAAI,CAACD,QAAQ,CAAChB,MAAM,GAAGU,OAAO,CAACO;IACxC;IAxBAb,aAAc;QAPd,uBAAUO,qBAAV,KAAA;QAEAO,uBAAAA,WAAAA,KAAAA;QACAC,uBAAAA,UAAAA,KAAAA;QAEA,uBAAQH,YAAR,KAAA;QAGE,IAAI,CAACA,QAAQ,GAAG,IAAIjB,eAClB,IAAIqB,QAAQ,CAACF,SAASC;YACpB,IAAI,CAACD,OAAO,GAAGA;YACf,IAAI,CAACC,MAAM,GAAGA;QAChB;QAGF,IAAI,CAACR,OAAOC,WAAW,CAAC,GAAGS,OAAO,IAAI,CAACL,QAAQ,CAACf,cAAc;IAChE;AAgBF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { Promisable, Simplify } from \"type-fest\";\n\n/**\n * Makes all properties of an object optional, except for the specified\n * properties.\n */\nexport type PartialExcept<T, K extends keyof T> = Simplify<Partial<T> & Pick<T, K>>;\n\n/**\n * Represents a function that can accept any number of arguments\n * and returns any value.\n */\nexport type AnyFunction = (...args: any[]) => unknown;\n\n/**\n * Represents void or Promise<void>.\n */\nexport type AnyVoid = Promisable<void>;\n\n/**\n * Returns all property names of an object whose values are functions.\n */\nexport type FunctionPropertyNames<T> = {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;\n}[keyof T];\n\n/**\n * Returns the arguments of a function.\n */\nexport type ArgsType<T> = T extends (...args: infer A) => any ? A : never;\n"],"names":[],"mappings":"AAAA,qDAAqD,GA2BrD;;CAEC,GACD,WAA0E"}
1
+ {"version":3,"sources":["../../../src/services/util/types.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { Promisable, Simplify } from \"type-fest\";\n\n/**\n * Makes all properties of an object optional, except for the specified\n * properties.\n */\nexport type PartialExcept<T, K extends keyof T> = Simplify<Partial<T> & Pick<T, K>>;\n\n/**\n * Represents a function that can accept any number of arguments\n * and returns any value.\n */\nexport type AnyFunction = (...args: any[]) => unknown;\n\n/**\n * Represents void or Promise<void>.\n */\nexport type AnyVoid = Promisable<void>;\n\n/**\n * Returns all property names of an object whose values are functions.\n */\nexport type FunctionPropertyNames<T> = {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never;\n}[keyof T];\n\n/**\n * Returns the arguments of a function.\n */\nexport type ArgsType<T> = T extends (...args: infer A) => any ? A : never;\n"],"names":[],"rangeMappings":";;","mappings":"AAAA,qDAAqD,GA2BrD;;CAEC,GACD,WAA0E"}