@gadgetinc/ggt 0.4.10 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/README.md +165 -93
  2. package/lib/__generated__/graphql.js +66 -1
  3. package/lib/__generated__/graphql.js.map +1 -1
  4. package/lib/commands/deploy.js +328 -230
  5. package/lib/commands/deploy.js.map +1 -1
  6. package/lib/commands/dev.js +445 -0
  7. package/lib/commands/dev.js.map +1 -0
  8. package/lib/commands/list.js +27 -19
  9. package/lib/commands/list.js.map +1 -1
  10. package/lib/commands/login.js +15 -11
  11. package/lib/commands/login.js.map +1 -1
  12. package/lib/commands/logout.js +5 -5
  13. package/lib/commands/logout.js.map +1 -1
  14. package/lib/commands/open.js +200 -0
  15. package/lib/commands/open.js.map +1 -0
  16. package/lib/commands/pull.js +128 -0
  17. package/lib/commands/pull.js.map +1 -0
  18. package/lib/commands/push.js +126 -0
  19. package/lib/commands/push.js.map +1 -0
  20. package/lib/commands/root.js +46 -28
  21. package/lib/commands/root.js.map +1 -1
  22. package/lib/commands/status.js +61 -0
  23. package/lib/commands/status.js.map +1 -0
  24. package/lib/commands/version.js +6 -6
  25. package/lib/commands/version.js.map +1 -1
  26. package/lib/commands/whoami.js +6 -6
  27. package/lib/commands/whoami.js.map +1 -1
  28. package/lib/ggt.js +33 -8
  29. package/lib/ggt.js.map +1 -1
  30. package/lib/main.js +5 -0
  31. package/lib/main.js.map +1 -0
  32. package/lib/services/app/api/api.js +191 -0
  33. package/lib/services/app/api/api.js.map +1 -0
  34. package/lib/services/app/api/operation.js +12 -0
  35. package/lib/services/app/api/operation.js.map +1 -0
  36. package/lib/services/app/app.js +44 -10
  37. package/lib/services/app/app.js.map +1 -1
  38. package/lib/services/app/{edit/client.js → client.js} +29 -19
  39. package/lib/services/app/client.js.map +1 -0
  40. package/lib/services/app/edit/edit.js +67 -31
  41. package/lib/services/app/edit/edit.js.map +1 -1
  42. package/lib/services/app/edit/operation.js +4 -3
  43. package/lib/services/app/edit/operation.js.map +1 -1
  44. package/lib/services/app/{edit/error.js → error.js} +6 -6
  45. package/lib/services/app/error.js.map +1 -0
  46. package/lib/services/command/arg.js +4 -4
  47. package/lib/services/command/arg.js.map +1 -1
  48. package/lib/services/command/command.js +9 -7
  49. package/lib/services/command/command.js.map +1 -1
  50. package/lib/services/command/context.js +82 -20
  51. package/lib/services/command/context.js.map +1 -1
  52. package/lib/services/config/config.js +4 -7
  53. package/lib/services/config/config.js.map +1 -1
  54. package/lib/services/config/env.js +1 -1
  55. package/lib/services/config/env.js.map +1 -1
  56. package/lib/services/filesync/changes.js +76 -37
  57. package/lib/services/filesync/changes.js.map +1 -1
  58. package/lib/services/filesync/conflicts.js +10 -9
  59. package/lib/services/filesync/conflicts.js.map +1 -1
  60. package/lib/services/filesync/directory.js +16 -1
  61. package/lib/services/filesync/directory.js.map +1 -1
  62. package/lib/services/filesync/error.js +96 -27
  63. package/lib/services/filesync/error.js.map +1 -1
  64. package/lib/services/filesync/filesync.js +448 -490
  65. package/lib/services/filesync/filesync.js.map +1 -1
  66. package/lib/services/filesync/hashes.js +8 -5
  67. package/lib/services/filesync/hashes.js.map +1 -1
  68. package/lib/services/filesync/strategy.js +59 -0
  69. package/lib/services/filesync/strategy.js.map +1 -0
  70. package/lib/services/filesync/sync-json.js +475 -0
  71. package/lib/services/filesync/sync-json.js.map +1 -0
  72. package/lib/services/http/auth.js +30 -1
  73. package/lib/services/http/auth.js.map +1 -1
  74. package/lib/services/http/http.js +5 -0
  75. package/lib/services/http/http.js.map +1 -1
  76. package/lib/services/output/confirm.js +149 -0
  77. package/lib/services/output/confirm.js.map +1 -0
  78. package/lib/services/output/footer.js +22 -0
  79. package/lib/services/output/footer.js.map +1 -0
  80. package/lib/services/output/log/format/pretty.js +2 -1
  81. package/lib/services/output/log/format/pretty.js.map +1 -1
  82. package/lib/services/output/log/logger.js +13 -5
  83. package/lib/services/output/log/logger.js.map +1 -1
  84. package/lib/services/output/log/structured.js +2 -2
  85. package/lib/services/output/log/structured.js.map +1 -1
  86. package/lib/services/output/output.js +197 -0
  87. package/lib/services/output/output.js.map +1 -0
  88. package/lib/services/output/print.js +31 -0
  89. package/lib/services/output/print.js.map +1 -0
  90. package/lib/services/output/problems.js +84 -0
  91. package/lib/services/output/problems.js.map +1 -0
  92. package/lib/services/output/prompt.js +173 -40
  93. package/lib/services/output/prompt.js.map +1 -1
  94. package/lib/services/output/report.js +63 -19
  95. package/lib/services/output/report.js.map +1 -1
  96. package/lib/services/output/select.js +198 -0
  97. package/lib/services/output/select.js.map +1 -0
  98. package/lib/services/output/spinner.js +141 -0
  99. package/lib/services/output/spinner.js.map +1 -0
  100. package/lib/services/output/sprint.js +38 -15
  101. package/lib/services/output/sprint.js.map +1 -1
  102. package/lib/services/output/symbols.js +23 -0
  103. package/lib/services/output/symbols.js.map +1 -0
  104. package/lib/services/output/table.js +98 -0
  105. package/lib/services/output/table.js.map +1 -0
  106. package/lib/services/output/timestamp.js +12 -0
  107. package/lib/services/output/timestamp.js.map +1 -0
  108. package/lib/services/output/update.js +29 -9
  109. package/lib/services/output/update.js.map +1 -1
  110. package/lib/services/user/session.js +4 -0
  111. package/lib/services/user/session.js.map +1 -1
  112. package/lib/services/user/user.js +15 -10
  113. package/lib/services/user/user.js.map +1 -1
  114. package/lib/services/util/assert.js +11 -0
  115. package/lib/services/util/assert.js.map +1 -0
  116. package/lib/services/util/boolean.js +2 -2
  117. package/lib/services/util/boolean.js.map +1 -1
  118. package/lib/services/util/function.js +45 -7
  119. package/lib/services/util/function.js.map +1 -1
  120. package/lib/services/util/is.js +23 -2
  121. package/lib/services/util/is.js.map +1 -1
  122. package/lib/services/util/json.js +16 -13
  123. package/lib/services/util/json.js.map +1 -1
  124. package/lib/services/util/object.js +2 -2
  125. package/lib/services/util/object.js.map +1 -1
  126. package/lib/services/util/promise.js +5 -2
  127. package/lib/services/util/promise.js.map +1 -1
  128. package/lib/services/util/types.js.map +1 -1
  129. package/npm-shrinkwrap.json +3415 -2973
  130. package/package.json +47 -40
  131. package/bin/dev.cmd +0 -3
  132. package/bin/dev.js +0 -14
  133. package/bin/run.cmd +0 -3
  134. package/bin/run.js +0 -5
  135. package/lib/commands/sync.js +0 -284
  136. package/lib/commands/sync.js.map +0 -1
  137. package/lib/services/app/edit/client.js.map +0 -1
  138. package/lib/services/app/edit/error.js.map +0 -1
  139. package/lib/services/output/log/printer.js +0 -120
  140. package/lib/services/output/log/printer.js.map +0 -1
  141. package/lib/services/output/stream.js +0 -54
  142. package/lib/services/output/stream.js.map +0 -1
@@ -7,13 +7,16 @@ import path from "node:path";
7
7
  import semver from "semver";
8
8
  import { z } from "zod";
9
9
  import { config } from "../config/config.js";
10
+ import { packageJson } from "../config/package-json.js";
10
11
  import { http } from "../http/http.js";
12
+ import { println } from "./print.js";
11
13
  import { sprint } from "./sprint.js";
12
14
  const UPDATE_CHECK_FREQUENCY = ms("12 hours");
13
15
  const Registry = z.object({
14
16
  name: z.literal("ggt"),
15
17
  "dist-tags": z.object({
16
- latest: z.string()
18
+ latest: z.string(),
19
+ experimental: z.string()
17
20
  })
18
21
  });
19
22
  export const getDistTags = async (ctx)=>{
@@ -54,16 +57,33 @@ export const shouldCheckForUpdate = async ()=>{
54
57
  }
55
58
  await fs.outputFile(path.join(config.cacheDir, "last-update-check"), String(Date.now()));
56
59
  const tags = await getDistTags(ctx);
57
- if (semver.lt(config.version, tags.latest)) {
60
+ let latest;
61
+ let updateAvailable;
62
+ let updateMessage;
63
+ if (packageJson.version.includes("experimental")) {
64
+ // this is an experimental release
65
+ latest = tags.experimental;
66
+ updateAvailable = packageJson.version !== latest;
67
+ updateMessage = sprint`
68
+ Update available! {red ${packageJson.version}} → {green ${latest}}
69
+ Run "npm install -g ${packageJson.name}@experimental" to update.
70
+ `;
71
+ } else {
72
+ // this is a stable release
73
+ latest = tags.latest;
74
+ updateAvailable = semver.lt(packageJson.version, latest);
75
+ updateMessage = sprint`
76
+ Update available! {red ${packageJson.version}} → {green ${latest}}
77
+ Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${latest}
78
+ Run "npm install -g ${packageJson.name}" to update.
79
+ `;
80
+ }
81
+ if (updateAvailable) {
58
82
  ctx.log.info("update available", {
59
- current: config.version,
60
- latest: tags.latest
83
+ current: packageJson.version,
84
+ latest
61
85
  });
62
- ctx.log.println(boxen(sprint`
63
- Update available! {red ${config.version}} -> {green ${tags.latest}}.
64
- Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${tags.latest}
65
- Run "npm install -g ${config.name}" to update.
66
- `, {
86
+ println(boxen(updateMessage, {
67
87
  padding: 1,
68
88
  borderStyle: "round",
69
89
  textAlignment: "center"
@@ -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 { http } from \"../http/http.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 }),\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 if (semver.lt(config.version, tags.latest)) {\n ctx.log.info(\"update available\", { current: config.version, latest: tags.latest });\n ctx.log.println(\n boxen(\n sprint`\n Update available! {red ${config.version}} -> {green ${tags.latest}}.\n Changelog: https://github.com/gadget-inc/ggt/releases/tag/v${tags.latest}\n Run \"npm install -g ${config.name}\" to update.\n `,\n {\n padding: 1,\n borderStyle: \"round\",\n textAlignment: \"center\",\n },\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","http","sprint","UPDATE_CHECK_FREQUENCY","Registry","object","name","literal","latest","string","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","lt","version","log","info","current","println","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,IAAI,QAAQ,kBAAkB;AACvC,SAASC,MAAM,QAAQ,cAAc;AAErC,MAAMC,yBAAyBR,GAAG;AAElC,MAAMS,WAAWL,EAAEM,MAAM,CAAC;IACxBC,MAAMP,EAAEQ,OAAO,CAAC;IAChB,aAAaR,EAAEM,MAAM,CAAC;QACpBG,QAAQT,EAAEU,MAAM;IAClB;AACF;AAIA,OAAO,MAAMC,cAAc,OAAOC;IAChC,MAAMC,OAAO,MAAMX,KAAK;QACtBY,SAAS;YAAEF;QAAI;QACfG,QAAQ;QACRC,KAAK;QACLC,cAAc;QACdC,iBAAiB;QACjBC,SAAS;YACPC,SAASxB,GAAG;QACd;IACF;IAEA,OAAOS,SAASgB,KAAK,CAACR,KAAK,CAAC,YAAY;AAC1C,EAAE;AAEF,OAAO,MAAMS,uBAAuB;IAClC,IAAI;QACF,MAAMC,YAAYC,OAAO,MAAM7B,GAAG8B,QAAQ,CAAC3B,KAAK4B,IAAI,CAACzB,OAAO0B,QAAQ,EAAE,sBAAsB;QAC5F9B,OAAO,CAAC2B,OAAOI,KAAK,CAACL;QACrB,OAAO7B,QAAQmC,OAAO,CAACN,YAAYnB;IACrC,EAAE,OAAO0B,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,MAAMrC,GAAGsC,UAAU,CAACnC,KAAK4B,IAAI,CAACzB,OAAO0B,QAAQ,EAAE,sBAAsBO,OAAOC,KAAKC,GAAG;QAEpF,MAAMC,OAAO,MAAM1B,YAAYC;QAE/B,IAAIb,OAAOuC,EAAE,CAACrC,OAAOsC,OAAO,EAAEF,KAAK5B,MAAM,GAAG;YAC1CG,IAAI4B,GAAG,CAACC,IAAI,CAAC,oBAAoB;gBAAEC,SAASzC,OAAOsC,OAAO;gBAAE9B,QAAQ4B,KAAK5B,MAAM;YAAC;YAChFG,IAAI4B,GAAG,CAACG,OAAO,CACblD,MACEU,MAAM,CAAC;mCACkB,EAAEF,OAAOsC,OAAO,CAAC,YAAY,EAAEF,KAAK5B,MAAM,CAAC;uEACP,EAAE4B,KAAK5B,MAAM,CAAC;gCACrD,EAAER,OAAOM,IAAI,CAAC;UACpC,CAAC,EACD;gBACEqC,SAAS;gBACTC,aAAa;gBACbC,eAAe;YACjB;QAGN;IACF,EAAE,OAAOhB,OAAO;QACdlB,IAAI4B,GAAG,CAACV,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"],"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"}
@@ -46,5 +46,9 @@ const log = createLogger({
46
46
  fs.removeSync(configPath("session.txt"));
47
47
  }
48
48
  };
49
+ export const readToken = ()=>{
50
+ log.debug("reading token from env");
51
+ return process.env["GGT_TOKEN"];
52
+ };
49
53
 
50
54
  //# sourceMappingURL=session.js.map
@@ -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"],"names":["fs","configPath","swallowEnoent","createLogger","memo","log","name","readSession","process","env","debug","readFileSync","error","undefined","writeSession","session","clear","Boolean","path","outputFileSync","removeSync"],"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"}
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"}
@@ -2,9 +2,10 @@ import assert from "node:assert";
2
2
  import z from "zod";
3
3
  import { login } from "../../commands/login.js";
4
4
  import { config } from "../config/config.js";
5
- import { loadCookie, swallowUnauthorized } from "../http/auth.js";
5
+ import { loadAuthHeaders, swallowUnauthorized } from "../http/auth.js";
6
6
  import { http } from "../http/http.js";
7
- import { confirm } from "../output/prompt.js";
7
+ import { confirm } from "../output/confirm.js";
8
+ import { println } from "../output/print.js";
8
9
  const User = z.object({
9
10
  id: z.union([
10
11
  z.string(),
@@ -22,8 +23,8 @@ const User = z.object({
22
23
  if (ctx.user) {
23
24
  return ctx.user;
24
25
  }
25
- const cookie = loadCookie();
26
- if (!cookie) {
26
+ const headers = loadAuthHeaders();
27
+ if (!headers) {
27
28
  return undefined;
28
29
  }
29
30
  try {
@@ -33,7 +34,7 @@ const User = z.object({
33
34
  },
34
35
  url: `https://${config.domains.services}/auth/api/current-user`,
35
36
  headers: {
36
- cookie
37
+ ...headers
37
38
  },
38
39
  responseType: "json",
39
40
  resolveBodyOnly: true
@@ -51,17 +52,21 @@ const User = z.object({
51
52
  * already logged in.
52
53
  *
53
54
  * @param ctx - The current context.
54
- * @param message - The message to display when prompting the user to log in.
55
55
  * @returns A Promise that resolves to the current user.
56
- */ export const getUserOrLogin = async (ctx, message = "You must be logged in to use this command. Would you like to log in?")=>{
56
+ */ export const getUserOrLogin = async (ctx)=>{
57
57
  let user = await getUser(ctx);
58
58
  if (user) {
59
59
  return user;
60
60
  }
61
61
  ctx.log.info("prompting user to log in");
62
- await confirm(ctx, {
63
- message
64
- });
62
+ println({
63
+ ensureEmptyLineAbove: true
64
+ })`
65
+ You must be logged in to use "ggt ${ctx.command}".
66
+ `;
67
+ await confirm({
68
+ ensureEmptyLineAbove: true
69
+ })("Would you like to log in?");
65
70
  await login(ctx);
66
71
  user = await getUser(ctx);
67
72
  assert(user, "missing user after successful login");
@@ -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 { loadCookie, swallowUnauthorized } from \"../http/auth.js\";\nimport { http } from \"../http/http.js\";\nimport { confirm } from \"../output/prompt.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 cookie = loadCookie();\n if (!cookie) {\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: { cookie },\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 * @param message - The message to display when prompting the user to log in.\n * @returns A Promise that resolves to the current user.\n */\nexport const getUserOrLogin = async (\n ctx: Context,\n message = \"You must be logged in to use this command. Would you like to log in?\",\n): 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 await confirm(ctx, { message });\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","loadCookie","swallowUnauthorized","http","confirm","User","object","id","union","string","number","transform","Number","name","nullish","email","getUser","ctx","user","cookie","undefined","json","context","url","domains","services","headers","responseType","resolveBodyOnly","parse","log","info","error","getUserOrLogin","message"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,OAAOC,OAAO,MAAM;AACpB,SAASC,KAAK,QAAQ,0BAA0B;AAEhD,SAASC,MAAM,QAAQ,sBAAsB;AAC7C,SAASC,UAAU,EAAEC,mBAAmB,QAAQ,kBAAkB;AAClE,SAASC,IAAI,QAAQ,kBAAkB;AACvC,SAASC,OAAO,QAAQ,sBAAsB;AAE9C,MAAMC,OAAOP,EAAEQ,MAAM,CAAC;IACpBC,IAAIT,EAAEU,KAAK,CAAC;QAACV,EAAEW,MAAM;QAAIX,EAAEY,MAAM;KAAG,EAAEC,SAAS,CAACC;IAChDC,MAAMf,EAAEW,MAAM,GAAGK,OAAO;IACxBC,OAAOjB,EAAEW,MAAM;AACjB;AAIA;;;;;CAKC,GACD,OAAO,MAAMO,UAAU,OAAOC;IAC5B,IAAIA,IAAIC,IAAI,EAAE;QACZ,OAAOD,IAAIC,IAAI;IACjB;IAEA,MAAMC,SAASlB;IACf,IAAI,CAACkB,QAAQ;QACX,OAAOC;IACT;IAEA,IAAI;QACF,MAAMC,OAAO,MAAMlB,KAAK;YACtBmB,SAAS;gBAAEL;YAAI;YACfM,KAAK,CAAC,QAAQ,EAAEvB,OAAOwB,OAAO,CAACC,QAAQ,CAAC,sBAAsB,CAAC;YAC/DC,SAAS;gBAAEP;YAAO;YAClBQ,cAAc;YACdC,iBAAiB;QACnB;QAEAX,IAAIC,IAAI,GAAGb,KAAKwB,KAAK,CAACR;QACtBJ,IAAIa,GAAG,CAACC,IAAI,CAAC;QAEb,OAAOd,IAAIC,IAAI;IACjB,EAAE,OAAOc,OAAO;QACd9B,oBAAoBe,KAAKe;QACzB,OAAOZ;IACT;AACF,EAAE;AAEF;;;;;;;CAOC,GACD,OAAO,MAAMa,iBAAiB,OAC5BhB,KACAiB,UAAU,sEAAsE;IAEhF,IAAIhB,OAAO,MAAMF,QAAQC;IACzB,IAAIC,MAAM;QACR,OAAOA;IACT;IAEAD,IAAIa,GAAG,CAACC,IAAI,CAAC;IACb,MAAM3B,QAAQa,KAAK;QAAEiB;IAAQ;IAE7B,MAAMnC,MAAMkB;IAEZC,OAAO,MAAMF,QAAQC;IACrBpB,OAAOqB,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"],"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"}
@@ -0,0 +1,11 @@
1
+ /* eslint-disable func-style */ /**
2
+ * Throws an error indicating that the code should be unreachable.
3
+ *
4
+ * @param expr - An optional expression to include in the error message.
5
+ * @throws - Always throws an error with the message "Unreachable code: {expr}".
6
+ */ export function unreachable(expr) {
7
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
8
+ throw new Error(`Unreachable code: ${expr}`);
9
+ }
10
+
11
+ //# sourceMappingURL=assert.js.map
@@ -0,0 +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,10 +1,10 @@
1
- import { memo } from "./function.js";
1
+ import { MemoFirstArg, memo } from "./function.js";
2
2
  /**
3
3
  * Parses a string value and returns a boolean value.
4
4
  *
5
5
  * @param value - The string value to parse.
6
6
  * @returns A boolean value representing the parsed value.
7
- */ export const parseBoolean = memo((value)=>{
7
+ */ export const parseBoolean = memo(MemoFirstArg, (value)=>{
8
8
  value ??= "";
9
9
  return [
10
10
  "true",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/boolean.ts"],"sourcesContent":["import { 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((value: string | null | undefined): boolean => {\n value ??= \"\";\n return [\"true\", \"1\"].includes(value.trim().toLowerCase());\n});\n"],"names":["memo","parseBoolean","value","includes","trim","toLowerCase"],"mappings":"AAAA,SAASA,IAAI,QAAQ,gBAAgB;AAErC;;;;;CAKC,GACD,OAAO,MAAMC,eAAeD,KAAK,CAACE;IAChCA,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"],"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,11 +1,14 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable func-style */ import mimicFunction from "mimic-fn";
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable func-style */ import mimicFunction from "mimic-function";
2
2
  import assert from "node:assert";
3
3
  import { isFunction } from "./is.js";
4
4
  const memoizedFns = new Set();
5
5
  /**
6
- * A function that returns the first argument as a string.
6
+ * A function that returns an empty string.
7
7
  *
8
8
  * Used as the default key function for {@linkcode memo}.
9
+ */ export const MemoFirstCall = ()=>"";
10
+ /**
11
+ * A function that returns the first argument as a string.
9
12
  */ export const MemoFirstArg = (...args)=>String(args[0]);
10
13
  /**
11
14
  * A function that returns all arguments as a string.
@@ -73,6 +76,41 @@ export function memo(fnOrKeyFn, fn) {
73
76
  mimicFunction(debounced, fn);
74
77
  return debounced;
75
78
  };
79
+ /**
80
+ * Creates a debounced function that delays invoking the provided
81
+ * function until after `delayMS` milliseconds have elapsed since the
82
+ * last time it was invoked.
83
+ *
84
+ * @param delayMS - The number of milliseconds to delay.
85
+ * @param fn - The function to be debounced.
86
+ * @returns A debounced version of the provided function.
87
+ */ export const debounceAsync = (delayMS, fn)=>{
88
+ let timerId;
89
+ let nextCall;
90
+ let pendingPromise;
91
+ const debouncedAsync = (...args)=>{
92
+ nextCall = ()=>{
93
+ nextCall = undefined;
94
+ timerId = undefined;
95
+ if (pendingPromise) {
96
+ pendingPromise = pendingPromise.then(()=>fn(...args)).catch(noop).finally(()=>pendingPromise = undefined);
97
+ } else {
98
+ pendingPromise = fn(...args).catch(noop).finally(()=>pendingPromise = undefined);
99
+ }
100
+ return pendingPromise;
101
+ };
102
+ clearTimeout(timerId);
103
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
104
+ timerId = setTimeout(nextCall, delayMS);
105
+ };
106
+ debouncedAsync.flush = async ()=>{
107
+ if (nextCall) {
108
+ await nextCall();
109
+ }
110
+ };
111
+ mimicFunction(debouncedAsync, fn);
112
+ return debouncedAsync;
113
+ };
76
114
  /**
77
115
  * Wraps a value in a thunk (a function that returns a value). If the
78
116
  * value is already a function, it is returned as is.
@@ -89,13 +127,13 @@ export function memo(fnOrKeyFn, fn) {
89
127
  * Unwraps a value from a thunk (a function that returns a value). If the
90
128
  * value is not a function, it is returned as is.
91
129
  *
92
- * @param val - The value or thunk to unwrap.
130
+ * @param value - The value or thunk to unwrap.
93
131
  * @returns The unwrapped value.
94
- */ export const unthunk = (val)=>{
95
- if (isFunction(val)) {
96
- return val();
132
+ */ export const unthunk = (value, ...args)=>{
133
+ if (isFunction(value)) {
134
+ return value(...args);
97
135
  }
98
- return val;
136
+ return value;
99
137
  };
100
138
  /**
101
139
  * A function that does nothing and returns nothing.
@@ -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-fn\";\nimport assert from \"node:assert\";\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 the first argument as a string.\n *\n * Used as the default key function for {@linkcode memo}.\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 results of previous calls and\n * returns the cached result when the first argument matches a previous\n * call. Subsequent arguments are ignored.\n *\n * @param fn - The function to memoize.\n * @see MemoFirstArg\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) => {\n const key = keyFn(...(args as Parameters<Fn>));\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 * Either a value or a function that returns a value.\n */\nexport type Thunk<T> = T | (() => 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 val - The value or thunk to unwrap.\n * @returns The unwrapped value.\n */\nexport const unthunk = <T>(val: T | (() => T)): T => {\n if (isFunction(val)) {\n return val();\n }\n return val;\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","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","thunk","val","unthunk","noop","_args","noopThis","noopNoop"],"mappings":"AAAA,qDAAqD,GACrD,6BAA6B,GAC7B,OAAOA,mBAAmB,WAAW;AACrC,OAAOC,YAAY,cAAc;AACjC,SAASC,UAAU,QAAQ,UAAU;AAGrC,MAAMC,cAAc,IAAIC;AAYxB;;;;CAIC,GACD,OAAO,MAAMC,eAAe,CAAC,GAAGC,OAAwBC,OAAOD,IAAI,CAAC,EAAE,EAAE;AAExE;;;;;CAKC,GACD,OAAO,MAAME,cAAc,CAAC,GAAGF,OAAwBA,KAAKG,GAAG,CAACF,QAAQG,IAAI,CAAC,KAAK;AA0BlF,+CAA+C;AAC/C,OAAO,SAASC,KACdC,SAAqB,EACrBC,EAAO;IAEP,IAAIC;IACJ,IAAID,IAAI;QACNC,QAAQF;IACV,OAAO;QACLC,KAAKD;QACLE,QAAQT;IACV;IAEA,MAAMU,QAAQ,IAAIC;IAElB,MAAMC,WAAY,CAAC,GAAGX;QACpB,MAAMY,MAAMJ,SAAUR;QACtB,IAAIS,MAAMI,GAAG,CAACD,MAAM;YAClB,OAAOH,MAAMK,GAAG,CAACF;QACnB;QAEAjB,OAAOY,IAAI;QACX,MAAMQ,SAASR,MAAMP;QACrBS,MAAMO,GAAG,CAACJ,KAAKG;QAEf,OAAOA;IACT;IAEAJ,SAASM,KAAK,GAAGR,MAAMQ,KAAK,CAACC,IAAI,CAACT;IAElCZ,YAAYsB,GAAG,CAACR;IAEhBjB,cAAciB,UAAUJ;IAExB,OAAOI;AACT;AAEA;;CAEC,GACD,OAAO,MAAMS,gBAAgB;IAC3B,KAAK,MAAMT,YAAYd,YAAa;QAClCc,SAASM,KAAK;IAChB;AACF,EAAE;AAYF;;;;;;;;CAQC,GACD,OAAO,MAAMI,WAAW,CAAyCC,SAAiBf;IAChF,IAAIgB;IACJ,IAAIC;IAEJ,MAAMC,YAAa,CAAC,GAAGzB;QACrBwB,eAAe;YACbA,eAAeE;YACfH,UAAUG;YACVnB,MAAMP;QACR;QAEA2B,aAAaJ;QACbA,UAAUK,WAAWJ,cAAcF;IACrC;IAEAG,UAAUI,KAAK,GAAG;QAChB,IAAIL,cAAc;YAChBA;QACF;IACF;IAEA9B,cAAc+B,WAAWlB;IAEzB,OAAOkB;AACT,EAAE;AAOF;;;;;;CAMC,GACD,OAAO,MAAMK,QAAQ,CAAIC;IACvB,IAAInC,WAAWmC,MAAM;QACnB,OAAOA;IACT;IACA,OAAO,IAAMA;AACf,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAMC,UAAU,CAAID;IACzB,IAAInC,WAAWmC,MAAM;QACnB,OAAOA;IACT;IACA,OAAOA;AACT,EAAE;AAEF;;CAEC,GACD,gEAAgE;AAChE,OAAO,MAAME,OAAO,CAAC,GAAGC,SAAwB,EAAE;AAElD;;CAEC,GACD,OAAO,MAAMC,WAAW,SAAsB,GAAGD,KAAY;IAC3D,OAAO,IAAI;AACb,EAAE;AAEF;;CAEC,GACD,OAAO,MAAME,WAAW,CAAC,GAAGF;IAC1B,OAAOD;AACT,EAAE"}
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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"}
@@ -8,6 +8,7 @@ export const isString = (val)=>{
8
8
  export const isObject = (val)=>{
9
9
  return typeof val === "object" && val !== null;
10
10
  };
11
+ export const isArray = Array.isArray;
11
12
  // eslint-disable-next-line @typescript-eslint/ban-types
12
13
  export const isFunction = (val)=>{
13
14
  return typeof val === "function";
@@ -50,8 +51,9 @@ export const isGraphQLResult = (val)=>{
50
51
  };
51
52
  export const isGraphQLErrors = (e)=>{
52
53
  return z.array(z.object({
53
- message: z.string()
54
- })).safeParse(e).success;
54
+ message: z.string(),
55
+ extensions: z.record(z.unknown()).nullish().transform((ext)=>ext ?? {})
56
+ })).min(1).safeParse(e).success;
55
57
  };
56
58
  export const isNever = (value)=>{
57
59
  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
@@ -60,5 +62,24 @@ export const isNever = (value)=>{
60
62
  export const isAbortError = (error)=>{
61
63
  return error instanceof Error && error.name === "AbortError" || error instanceof Event && error.type === "abort";
62
64
  };
65
+ export const isJavaScriptFile = (filepath)=>{
66
+ return [
67
+ ".js",
68
+ ".jsx",
69
+ ".cjs",
70
+ ".mjs"
71
+ ].some((ext)=>filepath.endsWith(ext));
72
+ };
73
+ export const isTypeScriptFile = (filepath)=>{
74
+ return [
75
+ ".ts",
76
+ ".tsx",
77
+ ".cts",
78
+ ".mts"
79
+ ].some((ext)=>filepath.endsWith(ext) && !filepath.endsWith(".d.ts"));
80
+ };
81
+ export const isGellyFile = (filepath)=>{
82
+ return filepath.endsWith(".gelly");
83
+ };
63
84
 
64
85
  //# sourceMappingURL=is.js.map
@@ -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\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.array(z.object({ message: z.string() })).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"],"names":["z","isNil","val","undefined","isString","isObject","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","isNever","value","isAbortError","name","Event"],"mappings":"AAGA,SAASA,CAAC,QAAQ,MAAM;AAExB,OAAO,MAAMC,QAAQ,CAACC;IACpB,OAAOA,QAAQ,QAAQA,QAAQC;AACjC,EAAE;AAEF,OAAO,MAAMC,WAAW,CAACF;IACvB,OAAO,OAAOA,QAAQ;AACxB,EAAE;AAEF,OAAO,MAAMG,WAAW,CAACH;IACvB,OAAO,OAAOA,QAAQ,YAAYA,QAAQ;AAC5C,EAAE;AAEF,wDAAwD;AACxD,OAAO,MAAMI,aAAa,CAACJ;IACzB,OAAO,OAAOA,QAAQ;AACxB,EAAE;AAEF,OAAO,MAAMK,UAAU,CAACL;IACtB,OAAOA,eAAeM;AACxB,EAAE;AAEF,OAAO,MAAMC,eAAe,CAACC;IAC3B,OAAOV,EAAEW,MAAM,CAAC;QAAEC,MAAMZ,EAAEa,MAAM;QAAIC,MAAMd,EAAEe,MAAM;QAAIC,QAAQhB,EAAEa,MAAM;QAAII,UAAUjB,EAAEkB,OAAO;IAAG,GAAGC,SAAS,CAACT,GAAGU,OAAO;AACzH,EAAE;AAEF,OAAO,MAAMC,eAAe,CAACX;IAC3B,OAAOV,EAAEW,MAAM,CAAC;QAAEC,MAAMZ,EAAEa,MAAM;QAAIS,SAAStB,EAAEa,MAAM;QAAIU,OAAOvB,EAAEwB,GAAG;IAAG,GAAGL,SAAS,CAACT,GAAGU,OAAO;AACjG,EAAE;AAEF,OAAO,MAAMK,kBAAkB,CAACvB;IAC9B,OAAOF,EACJ0B,KAAK,CAAC;QACL1B,EAAEW,MAAM,CAAC;YAAEgB,MAAM3B,EAAE4B,MAAM,CAAC5B,EAAE6B,OAAO;QAAI;QACvC7B,EAAEW,MAAM,CAAC;YAAEmB,QAAQ9B,EAAE+B,KAAK,CAAC/B,EAAEW,MAAM,CAAC;gBAAEW,SAAStB,EAAEa,MAAM;YAAG;QAAI;QAC9Db,EAAEW,MAAM,CAAC;YACPgB,MAAM3B,EAAE4B,MAAM,CAAC5B,EAAE6B,OAAO;YACxBC,QAAQ9B,EAAE+B,KAAK,CAAC/B,EAAEW,MAAM,CAAC;gBAAEW,SAAStB,EAAEa,MAAM;YAAG;QACjD;KACD,EACAM,SAAS,CAACjB,KAAKkB,OAAO;AAC3B,EAAE;AAEF,OAAO,MAAMY,kBAAkB,CAACtB;IAC9B,OAAOV,EAAE+B,KAAK,CAAC/B,EAAEW,MAAM,CAAC;QAAEW,SAAStB,EAAEa,MAAM;IAAG,IAAIM,SAAS,CAACT,GAAGU,OAAO;AACxE,EAAE;AAEF,OAAO,MAAMa,UAAU,CAACC;IACtB,4EAA4E;IAC5E,MAAM,IAAI1B,MAAM,CAAC,kBAAkB,EAAE0B,MAAM,CAAC;AAC9C,EAAE;AAEF,OAAO,MAAMC,eAAe,CAACZ;IAC3B,OAAO,AAACA,iBAAiBf,SAASe,MAAMa,IAAI,KAAK,gBAAkBb,iBAAiBc,SAASd,MAAMX,IAAI,KAAK;AAC9G,EAAE"}
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 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","isJavaScriptFile","filepath","some","endsWith","isTypeScriptFile","isGellyFile"],"mappings":"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"}
@@ -1,28 +1,31 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ export const installJsonExtensions = ()=>{
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ const bigintToJSON = function() {
2
+ return String(this);
3
+ };
4
+ const mapToJSON = function() {
5
+ return Object.fromEntries(this);
6
+ };
7
+ const setToJSON = function() {
8
+ return Array.from(this);
9
+ };
10
+ export const installJsonExtensions = ()=>{
2
11
  if (!Object.prototype.hasOwnProperty.call(BigInt, "toJSON")) {
3
- BigInt.prototype.toJSON = function() {
4
- return String(this);
5
- };
12
+ BigInt.prototype.toJSON = bigintToJSON;
6
13
  }
7
14
  if (!Object.prototype.hasOwnProperty.call(Map, "toJSON")) {
8
- Map.prototype.toJSON = function() {
9
- return Object.fromEntries(this);
10
- };
15
+ Map.prototype.toJSON = mapToJSON;
11
16
  }
12
17
  if (!Object.prototype.hasOwnProperty.call(Set, "toJSON")) {
13
- Set.prototype.toJSON = function() {
14
- return Array.from(this);
15
- };
18
+ Set.prototype.toJSON = setToJSON;
16
19
  }
17
20
  };
18
21
  export const uninstallJsonExtensions = ()=>{
19
- if (Object.prototype.hasOwnProperty.call(BigInt, "toJSON")) {
22
+ if (BigInt.prototype.toJSON === bigintToJSON) {
20
23
  delete BigInt.prototype.toJSON;
21
24
  }
22
- if (Object.prototype.hasOwnProperty.call(Map, "toJSON")) {
25
+ if (Map.prototype.toJSON === mapToJSON) {
23
26
  delete Map.prototype.toJSON;
24
27
  }
25
- if (Object.prototype.hasOwnProperty.call(Set, "toJSON")) {
28
+ if (Set.prototype.toJSON === setToJSON) {
26
29
  delete Set.prototype.toJSON;
27
30
  }
28
31
  };
@@ -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\nexport const installJsonExtensions = (): void => {\n if (!Object.prototype.hasOwnProperty.call(BigInt, \"toJSON\")) {\n BigInt.prototype.toJSON = function () {\n return String(this);\n };\n }\n\n if (!Object.prototype.hasOwnProperty.call(Map, \"toJSON\")) {\n Map.prototype.toJSON = function () {\n return Object.fromEntries(this);\n };\n }\n\n if (!Object.prototype.hasOwnProperty.call(Set, \"toJSON\")) {\n Set.prototype.toJSON = function () {\n return Array.from(this);\n };\n }\n};\n\nexport const uninstallJsonExtensions = (): void => {\n if (Object.prototype.hasOwnProperty.call(BigInt, \"toJSON\")) {\n delete BigInt.prototype.toJSON;\n }\n\n if (Object.prototype.hasOwnProperty.call(Map, \"toJSON\")) {\n delete Map.prototype.toJSON;\n }\n\n if (Object.prototype.hasOwnProperty.call(Set, \"toJSON\")) {\n delete Set.prototype.toJSON;\n }\n};\n"],"names":["installJsonExtensions","Object","prototype","hasOwnProperty","call","BigInt","toJSON","String","Map","fromEntries","Set","Array","from","uninstallJsonExtensions"],"mappings":"AAAA,oDAAoD,GACpD,sDAAsD,GACtD,iEAAiE,GAcjE,OAAO,MAAMA,wBAAwB;IACnC,IAAI,CAACC,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACC,QAAQ,WAAW;QAC3DA,OAAOH,SAAS,CAACI,MAAM,GAAG;YACxB,OAAOC,OAAO,IAAI;QACpB;IACF;IAEA,IAAI,CAACN,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACI,KAAK,WAAW;QACxDA,IAAIN,SAAS,CAACI,MAAM,GAAG;YACrB,OAAOL,OAAOQ,WAAW,CAAC,IAAI;QAChC;IACF;IAEA,IAAI,CAACR,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACM,KAAK,WAAW;QACxDA,IAAIR,SAAS,CAACI,MAAM,GAAG;YACrB,OAAOK,MAAMC,IAAI,CAAC,IAAI;QACxB;IACF;AACF,EAAE;AAEF,OAAO,MAAMC,0BAA0B;IACrC,IAAIZ,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACC,QAAQ,WAAW;QAC1D,OAAOA,OAAOH,SAAS,CAACI,MAAM;IAChC;IAEA,IAAIL,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACI,KAAK,WAAW;QACvD,OAAOA,IAAIN,SAAS,CAACI,MAAM;IAC7B;IAEA,IAAIL,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACM,KAAK,WAAW;QACvD,OAAOA,IAAIR,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"],"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"}
@@ -75,10 +75,10 @@ import { workspaceRoot } from "./paths.js";
75
75
  * Wraps `serialize-error` with some handy stuff, like special support
76
76
  * for Got HTTP errors
77
77
  */ export const serializeError = (error)=>{
78
- if (Array.isArray(error) && error.length === 1) {
78
+ if (Array.isArray(error)) {
79
79
  error = error[0];
80
80
  }
81
- let serialized = baseSerializeError(Array.isArray(error) ? new AggregateError(error) : error);
81
+ let serialized = baseSerializeError(error);
82
82
  if (typeof serialized == "string") {
83
83
  serialized = {
84
84
  message: serialized
@@ -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) && error.length === 1) {\n error = error[0];\n }\n\n let serialized = baseSerializeError(Array.isArray(error) ? new AggregateError(error) : 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","length","serialized","AggregateError","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,UAAUA,MAAMG,MAAM,KAAK,GAAG;QAC9CH,QAAQA,KAAK,CAAC,EAAE;IAClB;IAEA,IAAII,aAAatB,mBAAmBmB,MAAMC,OAAO,CAACF,SAAS,IAAIK,eAAeL,SAASA;IACvF,IAAI,OAAOI,cAAc,UAAU;QACjCA,aAAa;YAAEE,SAASF;QAAW;IACrC;IAEA,IAAIA,WAAWG,KAAK,EAAE;QACpBH,WAAWG,KAAK,GAAG7B,WAAW0B,WAAWG,KAAK,EAAE;YAAEC,QAAQ;YAAMC,UAAU1B;QAAc,GAAG2B,UAAU,CAAC,gBAAgB;IACxH;IAEA,IAAIV,iBAAiBrB,cAAc;QACjCyB,UAAU,CAAC,UAAU,GAAGO;QACxBP,UAAU,CAAC,UAAU,GAAG;YACtBQ,QAAQZ,MAAMa,OAAO,CAACD,MAAM;YAC5BE,KAAKd,MAAMa,OAAO,CAACC,GAAG,YAAYC,MAAMf,MAAMa,OAAO,CAACC,GAAG,CAACE,MAAM,KAAKhB,MAAMa,OAAO,CAACC,GAAG;QACxF;QACAV,UAAU,CAAC,eAAe,GAAGxB,QAAQoB,MAAMiB,QAAQ,EAAEC;IACvD;IAEA,OAAOd;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"],"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,11 +1,14 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import ms from "ms";
3
+ import { setTimeout } from "node:timers/promises";
4
+ export const delay = (duration, options)=>setTimeout(ms(duration), undefined, options);
1
5
  /**
2
6
  * Long lived references to Promises stress the garbage collector in JS.
3
7
  *
4
8
  * Instead of caching resolved Promises, we cache these little data
5
9
  * objects instead which reference the resolution or rejection of the
6
10
  * Promise, allowing the Promise object to be free'd.
7
- */ import { _ as _define_property } from "@swc/helpers/_/_define_property";
8
- export class PromiseWrapper {
11
+ */ export class PromiseWrapper {
9
12
  async unwrap() {
10
13
  if (this.pendingPromise) {
11
14
  return await this.pendingPromise;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/util/promise.ts"],"sourcesContent":["/**\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":["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;;;;;;CAMC;AACD,OAAO,MAAMA;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"],"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"}