@gadgetinc/ggt 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +192 -128
  2. package/lib/__generated__/graphql.js.map +1 -1
  3. package/lib/commands/add.js +385 -0
  4. package/lib/commands/add.js.map +1 -0
  5. package/lib/commands/deploy.js +20 -102
  6. package/lib/commands/deploy.js.map +1 -1
  7. package/lib/commands/dev.js +43 -114
  8. package/lib/commands/dev.js.map +1 -1
  9. package/lib/commands/list.js +3 -6
  10. package/lib/commands/list.js.map +1 -1
  11. package/lib/commands/login.js +2 -5
  12. package/lib/commands/login.js.map +1 -1
  13. package/lib/commands/logout.js +2 -5
  14. package/lib/commands/logout.js.map +1 -1
  15. package/lib/commands/open.js +45 -86
  16. package/lib/commands/open.js.map +1 -1
  17. package/lib/commands/pull.js +19 -76
  18. package/lib/commands/pull.js.map +1 -1
  19. package/lib/commands/push.js +19 -76
  20. package/lib/commands/push.js.map +1 -1
  21. package/lib/commands/root.js +4 -3
  22. package/lib/commands/root.js.map +1 -1
  23. package/lib/commands/status.js +3 -8
  24. package/lib/commands/status.js.map +1 -1
  25. package/lib/commands/version.js +6 -5
  26. package/lib/commands/version.js.map +1 -1
  27. package/lib/commands/whoami.js +2 -5
  28. package/lib/commands/whoami.js.map +1 -1
  29. package/lib/ggt.js.map +1 -1
  30. package/lib/main.js.map +1 -1
  31. package/lib/services/app/api/api.js.map +1 -1
  32. package/lib/services/app/api/operation.js +11 -0
  33. package/lib/services/app/api/operation.js.map +1 -1
  34. package/lib/services/app/app.js +21 -2
  35. package/lib/services/app/app.js.map +1 -1
  36. package/lib/services/app/arg.js.map +1 -1
  37. package/lib/services/app/client.js +1 -5
  38. package/lib/services/app/client.js.map +1 -1
  39. package/lib/services/app/edit/edit.js.map +1 -1
  40. package/lib/services/app/edit/operation.js +52 -0
  41. package/lib/services/app/edit/operation.js.map +1 -1
  42. package/lib/services/app/error.js.map +1 -1
  43. package/lib/services/command/arg.js +3 -1
  44. package/lib/services/command/arg.js.map +1 -1
  45. package/lib/services/command/command.js +1 -0
  46. package/lib/services/command/command.js.map +1 -1
  47. package/lib/services/command/context.js.map +1 -1
  48. package/lib/services/config/config.js.map +1 -1
  49. package/lib/services/config/env.js.map +1 -1
  50. package/lib/services/config/package-json.js.map +1 -1
  51. package/lib/services/filesync/changes.js.map +1 -1
  52. package/lib/services/filesync/conflicts.js.map +1 -1
  53. package/lib/services/filesync/directory.js.map +1 -1
  54. package/lib/services/filesync/error.js +1 -0
  55. package/lib/services/filesync/error.js.map +1 -1
  56. package/lib/services/filesync/file.js.map +1 -1
  57. package/lib/services/filesync/filesync.js +179 -174
  58. package/lib/services/filesync/filesync.js.map +1 -1
  59. package/lib/services/filesync/hashes.js.map +1 -1
  60. package/lib/services/filesync/strategy.js.map +1 -1
  61. package/lib/services/filesync/sync-json.js.map +1 -1
  62. package/lib/services/http/auth.js.map +1 -1
  63. package/lib/services/http/http.js.map +1 -1
  64. package/lib/services/output/confirm.js.map +1 -1
  65. package/lib/services/output/footer.js.map +1 -1
  66. package/lib/services/output/log/field.js.map +1 -1
  67. package/lib/services/output/log/format/format.js.map +1 -1
  68. package/lib/services/output/log/format/json.js.map +1 -1
  69. package/lib/services/output/log/format/pretty.js.map +1 -1
  70. package/lib/services/output/log/level.js.map +1 -1
  71. package/lib/services/output/log/logger.js.map +1 -1
  72. package/lib/services/output/log/structured.js.map +1 -1
  73. package/lib/services/output/notify.js.map +1 -1
  74. package/lib/services/output/output.js.map +1 -1
  75. package/lib/services/output/print.js.map +1 -1
  76. package/lib/services/output/problems.js.map +1 -1
  77. package/lib/services/output/prompt.js.map +1 -1
  78. package/lib/services/output/report.js.map +1 -1
  79. package/lib/services/output/select.js.map +1 -1
  80. package/lib/services/output/spinner.js.map +1 -1
  81. package/lib/services/output/sprint.js.map +1 -1
  82. package/lib/services/output/symbols.js.map +1 -1
  83. package/lib/services/output/table.js.map +1 -1
  84. package/lib/services/output/timestamp.js.map +1 -1
  85. package/lib/services/output/update.js.map +1 -1
  86. package/lib/services/user/session.js.map +1 -1
  87. package/lib/services/user/user.js.map +1 -1
  88. package/lib/services/util/assert.js.map +1 -1
  89. package/lib/services/util/boolean.js.map +1 -1
  90. package/lib/services/util/collection.js.map +1 -1
  91. package/lib/services/util/function.js.map +1 -1
  92. package/lib/services/util/is.js.map +1 -1
  93. package/lib/services/util/json.js.map +1 -1
  94. package/lib/services/util/number.js.map +1 -1
  95. package/lib/services/util/object.js.map +1 -1
  96. package/lib/services/util/paths.js.map +1 -1
  97. package/lib/services/util/promise.js.map +1 -1
  98. package/lib/services/util/types.js.map +1 -1
  99. package/npm-shrinkwrap.json +2071 -1684
  100. package/package.json +30 -30
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/confirm.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport process from \"node:process\";\nimport type { Promisable } from \"type-fest\";\nimport { isString } from \"../util/is.js\";\nimport { defaults } from \"../util/object.js\";\nimport { output } from \"./output.js\";\nimport { println } from \"./print.js\";\nimport { Prompt, type StdinKey } from \"./prompt.js\";\nimport { isSprintOptions, sprint, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type ConfirmOptions = SprintOptions & {\n /**\n * If `true`, ggt will exit if the user selects \"No\".\n *\n * @default true\n */\n exitWhenNo?: boolean;\n\n /**\n * What to do if ggt is not running in an interactive terminal.\n *\n * @default ```\n * println(options)(text);\n * println({ ensureEmptyLineAbove: true })`\n * Aborting because ggt is not running in an interactive terminal.\n * `;\n * process.exit(1);\n * ```\n */\n whenNotInteractive?: () => Promisable<void>;\n};\n\nexport type confirm = {\n (str: string): Promise<void>;\n (template: TemplateStringsArray, ...values: unknown[]): Promise<void>;\n (options: ConfirmOptions): confirm;\n};\n\n// TODO: i regret this api... don't make it the same as println... just make it take ctx and options\nconst createConfirm = (options: ConfirmOptions): confirm => {\n options = defaults(options, {\n ensureEmptyLineAbove: true,\n exitWhenNo: true,\n });\n\n return ((templateOrOptions: ConfirmOptions | string | TemplateStringsArray, ...values: unknown[]): confirm | Promise<void> => {\n if (isSprintOptions(templateOrOptions)) {\n return createConfirm({ ...options, ...templateOrOptions });\n }\n\n let text = templateOrOptions as string;\n if (!isString(text)) {\n text = sprint(templateOrOptions as TemplateStringsArray, ...values);\n }\n\n const whenNotInteractive =\n options.whenNotInteractive ??\n (() => {\n // TODO: log an error here\n println(options)(text);\n println({ ensureEmptyLineAbove: true })`\n Aborting because ggt is not running in an interactive terminal.\n `;\n process.exit(1);\n });\n\n if (!output.isInteractive) {\n return Promise.resolve(whenNotInteractive());\n }\n\n return new Promise((resolve) => {\n const conf = new Confirm(text, options);\n conf.on(\"submit\", resolve);\n conf.on(\"exit\", () => process.exit(0));\n conf.on(\"abort\", () => process.exit(1));\n });\n }) as confirm;\n};\n\nexport const confirm = createConfirm({});\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/confirm.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nexport class Confirm extends Prompt {\n override value: boolean | undefined = undefined;\n defaultValue = false;\n options;\n\n constructor(\n readonly text: string,\n options: Partial<ConfirmOptions>,\n ) {\n super();\n\n this.options = defaults(options, {\n exitWhenNo: true,\n ensureEmptyLineAbove: true,\n });\n\n if (this.options.ensureEmptyLineAbove) {\n this.text = \"\\n\" + this.text;\n }\n\n this.render();\n }\n\n reset(): void {\n this.value = this.defaultValue;\n this.fire();\n this.render();\n }\n\n exit(): void {\n this.abort();\n }\n\n abort(): void {\n this.value = false;\n this.done = this.aborted = true;\n this.fire();\n this.render(false);\n this.close();\n\n if (this.options.exitWhenNo) {\n process.exit(0);\n }\n }\n\n submit(): void {\n this.value = this.value ?? false;\n this.done = true;\n this.aborted = false;\n this.fire();\n this.render();\n this.close();\n\n if (this.options.exitWhenNo && !this.value) {\n process.exit(0);\n }\n }\n\n override _(char: string, _key: StdinKey): void {\n if (char.toLowerCase() === \"y\") {\n this.value = true;\n this.submit();\n return;\n }\n\n if (char.toLowerCase() === \"n\") {\n this.value = false;\n this.submit();\n return;\n }\n\n this.bell();\n }\n\n override render(value = this.value): void {\n super.render();\n\n if (this.done) {\n output.persistPrompt(sprintln`\n ${this.text} ${value ? chalk.bold.greenBright(\"Yes.\") : chalk.bold.redBright(\"No.\")}\n `);\n return;\n }\n\n output.updatePrompt(sprintln`\n ${this.text} ${this.defaultValue ? \"[Y/n] \" : \"[y/N] \"}\n `);\n }\n}\n"],"names":["chalk","process","isString","defaults","output","println","Prompt","isSprintOptions","sprint","sprintln","createConfirm","options","ensureEmptyLineAbove","exitWhenNo","templateOrOptions","values","text","whenNotInteractive","exit","isInteractive","Promise","resolve","conf","Confirm","on","confirm","reset","value","defaultValue","fire","render","abort","done","aborted","close","submit","_","char","_key","toLowerCase","bell","persistPrompt","bold","greenBright","redBright","updatePrompt","constructor","undefined"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/output/confirm.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport process from \"node:process\";\nimport type { Promisable } from \"type-fest\";\nimport { isString } from \"../util/is.js\";\nimport { defaults } from \"../util/object.js\";\nimport { output } from \"./output.js\";\nimport { println } from \"./print.js\";\nimport { Prompt, type StdinKey } from \"./prompt.js\";\nimport { isSprintOptions, sprint, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type ConfirmOptions = SprintOptions & {\n /**\n * If `true`, ggt will exit if the user selects \"No\".\n *\n * @default true\n */\n exitWhenNo?: boolean;\n\n /**\n * What to do if ggt is not running in an interactive terminal.\n *\n * @default ```\n * println(options)(text);\n * println({ ensureEmptyLineAbove: true })`\n * Aborting because ggt is not running in an interactive terminal.\n * `;\n * process.exit(1);\n * ```\n */\n whenNotInteractive?: () => Promisable<void>;\n};\n\nexport type confirm = {\n (str: string): Promise<void>;\n (template: TemplateStringsArray, ...values: unknown[]): Promise<void>;\n (options: ConfirmOptions): confirm;\n};\n\n// TODO: i regret this api... don't make it the same as println... just make it take ctx and options\nconst createConfirm = (options: ConfirmOptions): confirm => {\n options = defaults(options, {\n ensureEmptyLineAbove: true,\n exitWhenNo: true,\n });\n\n return ((templateOrOptions: ConfirmOptions | string | TemplateStringsArray, ...values: unknown[]): confirm | Promise<void> => {\n if (isSprintOptions(templateOrOptions)) {\n return createConfirm({ ...options, ...templateOrOptions });\n }\n\n let text = templateOrOptions as string;\n if (!isString(text)) {\n text = sprint(templateOrOptions as TemplateStringsArray, ...values);\n }\n\n const whenNotInteractive =\n options.whenNotInteractive ??\n (() => {\n // TODO: log an error here\n println(options)(text);\n println({ ensureEmptyLineAbove: true })`\n Aborting because ggt is not running in an interactive terminal.\n `;\n process.exit(1);\n });\n\n if (!output.isInteractive) {\n return Promise.resolve(whenNotInteractive());\n }\n\n return new Promise((resolve) => {\n const conf = new Confirm(text, options);\n conf.on(\"submit\", resolve);\n conf.on(\"exit\", () => process.exit(0));\n conf.on(\"abort\", () => process.exit(1));\n });\n }) as confirm;\n};\n\nexport const confirm = createConfirm({});\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/confirm.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nexport class Confirm extends Prompt {\n override value: boolean | undefined = undefined;\n defaultValue = false;\n options;\n\n constructor(\n readonly text: string,\n options: Partial<ConfirmOptions>,\n ) {\n super();\n\n this.options = defaults(options, {\n exitWhenNo: true,\n ensureEmptyLineAbove: true,\n });\n\n if (this.options.ensureEmptyLineAbove) {\n this.text = \"\\n\" + this.text;\n }\n\n this.render();\n }\n\n reset(): void {\n this.value = this.defaultValue;\n this.fire();\n this.render();\n }\n\n exit(): void {\n this.abort();\n }\n\n abort(): void {\n this.value = false;\n this.done = this.aborted = true;\n this.fire();\n this.render(false);\n this.close();\n\n if (this.options.exitWhenNo) {\n process.exit(0);\n }\n }\n\n submit(): void {\n this.value = this.value ?? false;\n this.done = true;\n this.aborted = false;\n this.fire();\n this.render();\n this.close();\n\n if (this.options.exitWhenNo && !this.value) {\n process.exit(0);\n }\n }\n\n override _(char: string, _key: StdinKey): void {\n if (char.toLowerCase() === \"y\") {\n this.value = true;\n this.submit();\n return;\n }\n\n if (char.toLowerCase() === \"n\") {\n this.value = false;\n this.submit();\n return;\n }\n\n this.bell();\n }\n\n override render(value = this.value): void {\n super.render();\n\n if (this.done) {\n output.persistPrompt(sprintln`\n ${this.text} ${value ? chalk.bold.greenBright(\"Yes.\") : chalk.bold.redBright(\"No.\")}\n `);\n return;\n }\n\n output.updatePrompt(sprintln`\n ${this.text} ${this.defaultValue ? \"[Y/n] \" : \"[y/N] \"}\n `);\n }\n}\n"],"names":["chalk","process","isString","defaults","output","println","Prompt","isSprintOptions","sprint","sprintln","createConfirm","options","ensureEmptyLineAbove","exitWhenNo","templateOrOptions","values","text","whenNotInteractive","exit","isInteractive","Promise","resolve","conf","Confirm","on","confirm","reset","value","defaultValue","fire","render","abort","done","aborted","close","submit","_","char","_key","toLowerCase","bell","persistPrompt","bold","greenBright","redBright","updatePrompt","constructor","undefined"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/footer.ts"],"sourcesContent":["import { output } from \"./output.js\";\nimport { isSprintOptions, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type footer = {\n (str: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n (options: SprintOptions): footer;\n};\n\nconst createFooter = (options: SprintOptions): footer => {\n return ((optionsOrString: SprintOptions | string | TemplateStringsArray, ...values: unknown[]): footer | undefined => {\n if (isSprintOptions(optionsOrString)) {\n return createFooter({ ...options, ...optionsOrString });\n }\n\n const str = sprintln(options)(optionsOrString as TemplateStringsArray, ...values);\n\n if (output.isInteractive) {\n output.updateFooter(str);\n } else {\n output.writeStdout(str);\n }\n\n return;\n }) as footer;\n};\n\nexport const footer = createFooter({});\n"],"names":["output","isSprintOptions","sprintln","createFooter","options","optionsOrString","values","str","isInteractive","updateFooter","writeStdout","footer"],"mappings":"AAAA,SAASA,MAAM,QAAQ,cAAc;AACrC,SAASC,eAAe,EAAEC,QAAQ,QAA4B,cAAc;AAQ5E,MAAMC,eAAe,CAACC;IACpB,OAAQ,CAACC,iBAAgE,GAAGC;QAC1E,IAAIL,gBAAgBI,kBAAkB;YACpC,OAAOF,aAAa;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,eAAe;YAAC;QACvD;QAEA,MAAME,MAAML,SAASE,SAASC,oBAA4CC;QAE1E,IAAIN,OAAOQ,aAAa,EAAE;YACxBR,OAAOS,YAAY,CAACF;QACtB,OAAO;YACLP,OAAOU,WAAW,CAACH;QACrB;QAEA;IACF;AACF;AAEA,OAAO,MAAMI,SAASR,aAAa,CAAC,GAAG"}
1
+ {"version":3,"sources":["../../../src/services/output/footer.ts"],"sourcesContent":["import { output } from \"./output.js\";\nimport { isSprintOptions, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type footer = {\n (str: string): void;\n (template: TemplateStringsArray, ...values: unknown[]): void;\n (options: SprintOptions): footer;\n};\n\nconst createFooter = (options: SprintOptions): footer => {\n return ((optionsOrString: SprintOptions | string | TemplateStringsArray, ...values: unknown[]): footer | undefined => {\n if (isSprintOptions(optionsOrString)) {\n return createFooter({ ...options, ...optionsOrString });\n }\n\n const str = sprintln(options)(optionsOrString as TemplateStringsArray, ...values);\n\n if (output.isInteractive) {\n output.updateFooter(str);\n } else {\n output.writeStdout(str);\n }\n\n return;\n }) as footer;\n};\n\nexport const footer = createFooter({});\n"],"names":["output","isSprintOptions","sprintln","createFooter","options","optionsOrString","values","str","isInteractive","updateFooter","writeStdout","footer"],"rangeMappings":";;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,MAAM,QAAQ,cAAc;AACrC,SAASC,eAAe,EAAEC,QAAQ,QAA4B,cAAc;AAQ5E,MAAMC,eAAe,CAACC;IACpB,OAAQ,CAACC,iBAAgE,GAAGC;QAC1E,IAAIL,gBAAgBI,kBAAkB;YACpC,OAAOF,aAAa;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,eAAe;YAAC;QACvD;QAEA,MAAME,MAAML,SAASE,SAASC,oBAA4CC;QAE1E,IAAIN,OAAOQ,aAAa,EAAE;YACxBR,OAAOS,YAAY,CAACF;QACtB,OAAO;YACLP,OAAOU,WAAW,CAACH;QACrB;QAEA;IACF;AACF;AAEA,OAAO,MAAMI,SAASR,aAAa,CAAC,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/services/output/log/field.ts"],"sourcesContent":["import { type JsonObject, type JsonPrimitive } from \"type-fest\";\n\nexport type Fields = Record<string, Field> | { error: unknown } | { reason: unknown };\n\nexport type Field = FieldPrimitive | FieldObject | FieldArray;\n\nexport type FieldPrimitive = JsonPrimitive | bigint | undefined;\n\nexport type FieldObject = JsonObject | { [key in string]: Field } | Map<FieldPrimitive, Field>;\n\nexport type FieldArray = Field[] | Set<Field>;\n"],"names":[],"mappings":"AAUA,WAA8C"}
1
+ {"version":3,"sources":["../../../../src/services/output/log/field.ts"],"sourcesContent":["import { type JsonObject, type JsonPrimitive } from \"type-fest\";\n\nexport type Fields = Record<string, Field> | { error: unknown } | { reason: unknown };\n\nexport type Field = FieldPrimitive | FieldObject | FieldArray;\n\nexport type FieldPrimitive = JsonPrimitive | bigint | undefined;\n\nexport type FieldObject = JsonObject | { [key in string]: Field } | Map<FieldPrimitive, Field>;\n\nexport type FieldArray = Field[] | Set<Field>;\n"],"names":[],"rangeMappings":"","mappings":"AAUA,WAA8C"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/services/output/log/format/format.ts"],"sourcesContent":["import type { Fields } from \"../field.js\";\nimport type { Level } from \"../level.js\";\nimport { formatJson } from \"./json.js\";\nimport { formatPretty } from \"./pretty.js\";\n\nexport type Formatter = (level: Level, name: string, msg: string, fields: Fields) => string;\n\nexport const formatters = {\n pretty: formatPretty,\n json: formatJson,\n} as const;\n"],"names":["formatJson","formatPretty","formatters","pretty","json"],"mappings":"AAEA,SAASA,UAAU,QAAQ,YAAY;AACvC,SAASC,YAAY,QAAQ,cAAc;AAI3C,OAAO,MAAMC,aAAa;IACxBC,QAAQF;IACRG,MAAMJ;AACR,EAAW"}
1
+ {"version":3,"sources":["../../../../../src/services/output/log/format/format.ts"],"sourcesContent":["import type { Fields } from \"../field.js\";\nimport type { Level } from \"../level.js\";\nimport { formatJson } from \"./json.js\";\nimport { formatPretty } from \"./pretty.js\";\n\nexport type Formatter = (level: Level, name: string, msg: string, fields: Fields) => string;\n\nexport const formatters = {\n pretty: formatPretty,\n json: formatJson,\n} as const;\n"],"names":["formatJson","formatPretty","formatters","pretty","json"],"rangeMappings":";;;;;","mappings":"AAEA,SAASA,UAAU,QAAQ,YAAY;AACvC,SAASC,YAAY,QAAQ,cAAc;AAI3C,OAAO,MAAMC,aAAa;IACxBC,QAAQF;IACRG,MAAMJ;AACR,EAAW"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/services/output/log/format/json.ts"],"sourcesContent":["import stripAnsi from \"strip-ansi\";\nimport { isObject, isString } from \"../../../util/is.js\";\nimport type { Formatter } from \"./format.js\";\n\nexport const formatJson: Formatter = (level, name, msg, fields) => {\n return JSON.stringify({ level, name, msg: stripAnsi(msg).trim(), fields: serializeFields(fields) }) + \"\\n\";\n};\n\nconst serializeFields = (fields: Record<string, unknown>): Record<string, unknown> => {\n const result = {} as Record<string, unknown>;\n for (const [key, value] of Object.entries(fields)) {\n result[key] = serializeValue(value);\n }\n return result;\n};\n\nconst serializeValue = (value: unknown): unknown => {\n if (value instanceof Set) {\n value = Array.from(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(serializeValue);\n }\n\n if (value instanceof Map) {\n value = Object.fromEntries(value.entries());\n }\n\n if (isObject(value)) {\n return serializeFields(value as Record<string, unknown>);\n }\n\n if (isString(value)) {\n return stripAnsi(value).trim();\n }\n\n return value;\n};\n"],"names":["stripAnsi","isObject","isString","formatJson","level","name","msg","fields","JSON","stringify","trim","serializeFields","result","key","value","Object","entries","serializeValue","Set","Array","from","isArray","map","Map","fromEntries"],"mappings":"AAAA,OAAOA,eAAe,aAAa;AACnC,SAASC,QAAQ,EAAEC,QAAQ,QAAQ,sBAAsB;AAGzD,OAAO,MAAMC,aAAwB,CAACC,OAAOC,MAAMC,KAAKC;IACtD,OAAOC,KAAKC,SAAS,CAAC;QAAEL;QAAOC;QAAMC,KAAKN,UAAUM,KAAKI,IAAI;QAAIH,QAAQI,gBAAgBJ;IAAQ,KAAK;AACxG,EAAE;AAEF,MAAMI,kBAAkB,CAACJ;IACvB,MAAMK,SAAS,CAAC;IAChB,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACT,QAAS;QACjDK,MAAM,CAACC,IAAI,GAAGI,eAAeH;IAC/B;IACA,OAAOF;AACT;AAEA,MAAMK,iBAAiB,CAACH;IACtB,IAAIA,iBAAiBI,KAAK;QACxBJ,QAAQK,MAAMC,IAAI,CAACN;IACrB;IAEA,IAAIK,MAAME,OAAO,CAACP,QAAQ;QACxB,OAAOA,MAAMQ,GAAG,CAACL;IACnB;IAEA,IAAIH,iBAAiBS,KAAK;QACxBT,QAAQC,OAAOS,WAAW,CAACV,MAAME,OAAO;IAC1C;IAEA,IAAIf,SAASa,QAAQ;QACnB,OAAOH,gBAAgBG;IACzB;IAEA,IAAIZ,SAASY,QAAQ;QACnB,OAAOd,UAAUc,OAAOJ,IAAI;IAC9B;IAEA,OAAOI;AACT"}
1
+ {"version":3,"sources":["../../../../../src/services/output/log/format/json.ts"],"sourcesContent":["import stripAnsi from \"strip-ansi\";\nimport { isObject, isString } from \"../../../util/is.js\";\nimport type { Formatter } from \"./format.js\";\n\nexport const formatJson: Formatter = (level, name, msg, fields) => {\n return JSON.stringify({ level, name, msg: stripAnsi(msg).trim(), fields: serializeFields(fields) }) + \"\\n\";\n};\n\nconst serializeFields = (fields: Record<string, unknown>): Record<string, unknown> => {\n const result = {} as Record<string, unknown>;\n for (const [key, value] of Object.entries(fields)) {\n result[key] = serializeValue(value);\n }\n return result;\n};\n\nconst serializeValue = (value: unknown): unknown => {\n if (value instanceof Set) {\n value = Array.from(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(serializeValue);\n }\n\n if (value instanceof Map) {\n value = Object.fromEntries(value.entries());\n }\n\n if (isObject(value)) {\n return serializeFields(value as Record<string, unknown>);\n }\n\n if (isString(value)) {\n return stripAnsi(value).trim();\n }\n\n return value;\n};\n"],"names":["stripAnsi","isObject","isString","formatJson","level","name","msg","fields","JSON","stringify","trim","serializeFields","result","key","value","Object","entries","serializeValue","Set","Array","from","isArray","map","Map","fromEntries"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,eAAe,aAAa;AACnC,SAASC,QAAQ,EAAEC,QAAQ,QAAQ,sBAAsB;AAGzD,OAAO,MAAMC,aAAwB,CAACC,OAAOC,MAAMC,KAAKC;IACtD,OAAOC,KAAKC,SAAS,CAAC;QAAEL;QAAOC;QAAMC,KAAKN,UAAUM,KAAKI,IAAI;QAAIH,QAAQI,gBAAgBJ;IAAQ,KAAK;AACxG,EAAE;AAEF,MAAMI,kBAAkB,CAACJ;IACvB,MAAMK,SAAS,CAAC;IAChB,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACT,QAAS;QACjDK,MAAM,CAACC,IAAI,GAAGI,eAAeH;IAC/B;IACA,OAAOF;AACT;AAEA,MAAMK,iBAAiB,CAACH;IACtB,IAAIA,iBAAiBI,KAAK;QACxBJ,QAAQK,MAAMC,IAAI,CAACN;IACrB;IAEA,IAAIK,MAAME,OAAO,CAACP,QAAQ;QACxB,OAAOA,MAAMQ,GAAG,CAACL;IACnB;IAEA,IAAIH,iBAAiBS,KAAK;QACxBT,QAAQC,OAAOS,WAAW,CAACV,MAAME,OAAO;IAC1C;IAEA,IAAIf,SAASa,QAAQ;QACnB,OAAOH,gBAAgBG;IACzB;IAEA,IAAIZ,SAASY,QAAQ;QACnB,OAAOd,UAAUc,OAAOJ,IAAI;IAC9B;IAEA,OAAOI;AACT"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/services/output/log/format/pretty.ts"],"sourcesContent":["import chalk, { Chalk } from \"chalk\";\nimport dayjs from \"dayjs\";\nimport assert from \"node:assert\";\nimport { config } from \"../../../config/config.js\";\nimport { env } from \"../../../config/env.js\";\nimport { isObject } from \"../../../util/is.js\";\nimport { symbol } from \"../../symbols.js\";\nimport { Level } from \"../level.js\";\nimport type { Formatter } from \"./format.js\";\n\nexport const formatPretty: Formatter = (level, name, msg, fields) => {\n return `${formatTimestamp()} ${formatLevel(level)} ${formatName(name)}:${formatMessage(msg)}${formatFields(fields)}${NEW_LINE}`;\n};\n\nconst color = new Chalk({\n // we always turn off colors in tests (FORCE_COLOR=0) so that we get\n // predictable output, but if we're running with logs enabled\n // (GGT_LOG_LEVEL=info), we still want to see colors in our logs\n level: env.testLike && config.logLevel < Level.PRINT ? 3 : chalk.level,\n});\n\nconst blue = color.hex(\"#86B5F7\");\nconst blueLight = color.hex(\"#B2D0FA\");\nconst gray = color.hex(\"#D6D6D6\");\nconst grayDark = color.hex(\"#C2C2C2\");\nconst green = color.hex(\"#9DE6A4\");\nconst greenLight = color.hex(\"#BEEEC3\");\nconst orange = color.hex(\"#EEAC78\");\nconst orangeLight = color.hex(\"#F4C7A4\");\nconst pink = color.hex(\"#FAACB5\");\nconst red = color.hex(\"#A64E4E\");\nconst white = color.hex(\"#FFFFFF\");\n\nconst EMPTY = \"\";\nconst SPACE = \" \";\nconst NEW_LINE = \"\\n\";\nconst COLON = \":\";\nconst QUOTE = \"'\";\n\nconst formatKey = (key: string, indent: number): string => {\n const color = key === \"error\" ? red : gray;\n\n const buf: string[] = [];\n buf.push(NEW_LINE);\n for (let i = 0; i < indent; i++) {\n buf.push(SPACE);\n }\n buf.push(color(key));\n buf.push(COLON);\n\n return buf.join(\"\");\n};\n\nconst formatValue = (value: string, color: (s: string) => string, indent: number): string => {\n const lines = value.split(NEW_LINE);\n if (lines.length === 0) {\n return EMPTY;\n }\n\n const buf: string[] = [];\n const firstLine = lines.shift();\n assert(firstLine);\n buf.push(color(firstLine));\n\n // color the rest of the lines\n for (const line of lines) {\n if (!line) {\n continue;\n }\n\n buf.push(NEW_LINE);\n for (let i = 0; i < indent; i++) {\n buf.push(SPACE);\n }\n\n buf.push(color(line));\n }\n\n return buf.join(EMPTY);\n};\n\nconst formatFields = (fields: Record<string, unknown>, indent = 2): string => {\n if (Object.keys(fields).length === 0) {\n return EMPTY;\n }\n\n const buf: string[] = [];\n for (let [key, value] of Object.entries(fields)) {\n buf.push(formatKey(key, indent));\n\n if (value instanceof Set) {\n value = Array.from(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n buf.push(formatValue(\" []\", gray, indent));\n continue;\n }\n\n value = Object.fromEntries(value.entries());\n }\n\n if (value instanceof Map) {\n value = Object.fromEntries(value);\n }\n\n if (isObject(value)) {\n const entries = Object.entries(value);\n if (entries.length === 0) {\n buf.push(formatValue(\" {}\", gray, indent));\n continue;\n }\n\n if (entries.length > 10 && config.logLevel > Level.TRACE) {\n // truncate objects to 10 keys when not tracing\n value = Object.fromEntries([...entries.slice(0, 10), [symbol.ellipsis, `${entries.length - 10} more`]]);\n }\n\n buf.push(formatFields(value as Record<string, unknown>, indent + 2));\n continue;\n }\n\n buf.push(SPACE);\n\n switch (typeof value) {\n case \"string\":\n buf.push(formatValue(QUOTE + value.replaceAll(NEW_LINE, NEW_LINE + SPACE.repeat(indent + key.length)) + QUOTE, blueLight, indent));\n break;\n case \"number\":\n buf.push(formatValue(String(value), orangeLight, indent));\n break;\n case \"bigint\":\n buf.push(formatValue(String(value) + \"n\", orangeLight, indent));\n break;\n case \"boolean\":\n buf.push(formatValue(String(value), greenLight, indent));\n break;\n default:\n buf.push(formatValue(String(value), white, indent));\n break;\n }\n }\n\n return buf.join(EMPTY);\n};\n\nconst formatTimestamp = (): string => {\n const ts = dayjs().format(\"hh:mm:ss\");\n return grayDark(ts);\n};\n\nconst formatLevel = (level: Level): string => {\n switch (level) {\n case Level.PRINT:\n return gray(\"PRINT\");\n case Level.TRACE:\n return blue(\"TRACE\");\n case Level.DEBUG:\n return orange(\"DEBUG\");\n case Level.INFO:\n return green(\"INFO\");\n case Level.WARN:\n return pink(\"WARN\");\n case Level.ERROR:\n return red(\"ERROR\");\n // case \"fatal\":\n // return red(colors.bold(level));\n }\n};\n\nconst formatName = (name: string): string => {\n return white(name);\n};\n\nconst formatMessage = (msg: string): string => {\n const lines = msg.split(NEW_LINE);\n if (lines.length === 1) {\n return SPACE + white(msg);\n }\n return NEW_LINE + lines.map((line) => SPACE + SPACE + line).join(NEW_LINE);\n};\n"],"names":["chalk","Chalk","dayjs","assert","config","env","isObject","symbol","Level","formatPretty","level","name","msg","fields","formatTimestamp","formatLevel","formatName","formatMessage","formatFields","NEW_LINE","color","testLike","logLevel","PRINT","blue","hex","blueLight","gray","grayDark","green","greenLight","orange","orangeLight","pink","red","white","EMPTY","SPACE","COLON","QUOTE","formatKey","key","indent","buf","push","i","join","formatValue","value","lines","split","length","firstLine","shift","line","Object","keys","entries","Set","Array","from","isArray","fromEntries","Map","TRACE","slice","ellipsis","replaceAll","repeat","String","ts","format","DEBUG","INFO","WARN","ERROR","map"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/services/output/log/format/pretty.ts"],"sourcesContent":["import chalk, { Chalk } from \"chalk\";\nimport dayjs from \"dayjs\";\nimport assert from \"node:assert\";\nimport { config } from \"../../../config/config.js\";\nimport { env } from \"../../../config/env.js\";\nimport { isObject } from \"../../../util/is.js\";\nimport { symbol } from \"../../symbols.js\";\nimport { Level } from \"../level.js\";\nimport type { Formatter } from \"./format.js\";\n\nexport const formatPretty: Formatter = (level, name, msg, fields) => {\n return `${formatTimestamp()} ${formatLevel(level)} ${formatName(name)}:${formatMessage(msg)}${formatFields(fields)}${NEW_LINE}`;\n};\n\nconst color = new Chalk({\n // we always turn off colors in tests (FORCE_COLOR=0) so that we get\n // predictable output, but if we're running with logs enabled\n // (GGT_LOG_LEVEL=info), we still want to see colors in our logs\n level: env.testLike && config.logLevel < Level.PRINT ? 3 : chalk.level,\n});\n\nconst blue = color.hex(\"#86B5F7\");\nconst blueLight = color.hex(\"#B2D0FA\");\nconst gray = color.hex(\"#D6D6D6\");\nconst grayDark = color.hex(\"#C2C2C2\");\nconst green = color.hex(\"#9DE6A4\");\nconst greenLight = color.hex(\"#BEEEC3\");\nconst orange = color.hex(\"#EEAC78\");\nconst orangeLight = color.hex(\"#F4C7A4\");\nconst pink = color.hex(\"#FAACB5\");\nconst red = color.hex(\"#A64E4E\");\nconst white = color.hex(\"#FFFFFF\");\n\nconst EMPTY = \"\";\nconst SPACE = \" \";\nconst NEW_LINE = \"\\n\";\nconst COLON = \":\";\nconst QUOTE = \"'\";\n\nconst formatKey = (key: string, indent: number): string => {\n const color = key === \"error\" ? red : gray;\n\n const buf: string[] = [];\n buf.push(NEW_LINE);\n for (let i = 0; i < indent; i++) {\n buf.push(SPACE);\n }\n buf.push(color(key));\n buf.push(COLON);\n\n return buf.join(\"\");\n};\n\nconst formatValue = (value: string, color: (s: string) => string, indent: number): string => {\n const lines = value.split(NEW_LINE);\n if (lines.length === 0) {\n return EMPTY;\n }\n\n const buf: string[] = [];\n const firstLine = lines.shift();\n assert(firstLine);\n buf.push(color(firstLine));\n\n // color the rest of the lines\n for (const line of lines) {\n if (!line) {\n continue;\n }\n\n buf.push(NEW_LINE);\n for (let i = 0; i < indent; i++) {\n buf.push(SPACE);\n }\n\n buf.push(color(line));\n }\n\n return buf.join(EMPTY);\n};\n\nconst formatFields = (fields: Record<string, unknown>, indent = 2): string => {\n if (Object.keys(fields).length === 0) {\n return EMPTY;\n }\n\n const buf: string[] = [];\n for (let [key, value] of Object.entries(fields)) {\n buf.push(formatKey(key, indent));\n\n if (value instanceof Set) {\n value = Array.from(value);\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n buf.push(formatValue(\" []\", gray, indent));\n continue;\n }\n\n value = Object.fromEntries(value.entries());\n }\n\n if (value instanceof Map) {\n value = Object.fromEntries(value);\n }\n\n if (isObject(value)) {\n const entries = Object.entries(value);\n if (entries.length === 0) {\n buf.push(formatValue(\" {}\", gray, indent));\n continue;\n }\n\n if (entries.length > 10 && config.logLevel > Level.TRACE) {\n // truncate objects to 10 keys when not tracing\n value = Object.fromEntries([...entries.slice(0, 10), [symbol.ellipsis, `${entries.length - 10} more`]]);\n }\n\n buf.push(formatFields(value as Record<string, unknown>, indent + 2));\n continue;\n }\n\n buf.push(SPACE);\n\n switch (typeof value) {\n case \"string\":\n buf.push(formatValue(QUOTE + value.replaceAll(NEW_LINE, NEW_LINE + SPACE.repeat(indent + key.length)) + QUOTE, blueLight, indent));\n break;\n case \"number\":\n buf.push(formatValue(String(value), orangeLight, indent));\n break;\n case \"bigint\":\n buf.push(formatValue(String(value) + \"n\", orangeLight, indent));\n break;\n case \"boolean\":\n buf.push(formatValue(String(value), greenLight, indent));\n break;\n default:\n buf.push(formatValue(String(value), white, indent));\n break;\n }\n }\n\n return buf.join(EMPTY);\n};\n\nconst formatTimestamp = (): string => {\n const ts = dayjs().format(\"hh:mm:ss\");\n return grayDark(ts);\n};\n\nconst formatLevel = (level: Level): string => {\n switch (level) {\n case Level.PRINT:\n return gray(\"PRINT\");\n case Level.TRACE:\n return blue(\"TRACE\");\n case Level.DEBUG:\n return orange(\"DEBUG\");\n case Level.INFO:\n return green(\"INFO\");\n case Level.WARN:\n return pink(\"WARN\");\n case Level.ERROR:\n return red(\"ERROR\");\n // case \"fatal\":\n // return red(colors.bold(level));\n }\n};\n\nconst formatName = (name: string): string => {\n return white(name);\n};\n\nconst formatMessage = (msg: string): string => {\n const lines = msg.split(NEW_LINE);\n if (lines.length === 1) {\n return SPACE + white(msg);\n }\n return NEW_LINE + lines.map((line) => SPACE + SPACE + line).join(NEW_LINE);\n};\n"],"names":["chalk","Chalk","dayjs","assert","config","env","isObject","symbol","Level","formatPretty","level","name","msg","fields","formatTimestamp","formatLevel","formatName","formatMessage","formatFields","NEW_LINE","color","testLike","logLevel","PRINT","blue","hex","blueLight","gray","grayDark","green","greenLight","orange","orangeLight","pink","red","white","EMPTY","SPACE","COLON","QUOTE","formatKey","key","indent","buf","push","i","join","formatValue","value","lines","split","length","firstLine","shift","line","Object","keys","entries","Set","Array","from","isArray","fromEntries","Map","TRACE","slice","ellipsis","replaceAll","repeat","String","ts","format","DEBUG","INFO","WARN","ERROR","map"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/services/output/log/level.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport { z } from \"zod\";\nimport { MemoAllArgs, memo } from \"../../util/function.js\";\nimport { clamp } from \"../../util/number.js\";\n\nexport type Level = (typeof Level)[keyof typeof Level];\n\nexport const Level = {\n TRACE: 1,\n DEBUG: 2,\n INFO: 3,\n WARN: 4,\n ERROR: 5,\n PRINT: 6,\n} as const;\n\nexport const parseLevel = memo(MemoAllArgs, (value: unknown, defaultValue: Level): Level => {\n let parsed = z\n .enum([\"TRACE\", \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\"])\n .transform((str) => Level[str])\n .safeParse(String(value).toUpperCase());\n\n if (!parsed.success) {\n parsed = z.number().min(Level.TRACE).max(Level.ERROR).safeParse(Number(value)) as typeof parsed;\n }\n\n return parsed.success ? parsed.data : defaultValue;\n});\n\n/**\n * Converts a numeric verbosity value to a log level.\n *\n * @param verbosity - The verbosity value\n * @returns The log level\n * @example\n * verbosityToLevel(1) // => Level.INFO\n * verbosityToLevel(2) // => Level.DEBUG\n * verbosityToLevel(3) // => Level.TRACE\n * verbosityToLevel(Infinity) // => Level.TRACE\n */\nexport const verbosityToLevel = (verbosity: number): Level => {\n assert(verbosity > 0, \"verbosity must be greater than 0\");\n return clamp(Level.INFO + 1 - verbosity, Level.TRACE, Level.INFO) as Level;\n};\n"],"names":["assert","z","MemoAllArgs","memo","clamp","Level","TRACE","DEBUG","INFO","WARN","ERROR","PRINT","parseLevel","value","defaultValue","parsed","enum","transform","str","safeParse","String","toUpperCase","success","number","min","max","Number","data","verbosityToLevel","verbosity"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,WAAW,EAAEC,IAAI,QAAQ,yBAAyB;AAC3D,SAASC,KAAK,QAAQ,uBAAuB;AAI7C,OAAO,MAAMC,QAAQ;IACnBC,OAAO;IACPC,OAAO;IACPC,MAAM;IACNC,MAAM;IACNC,OAAO;IACPC,OAAO;AACT,EAAW;AAEX,OAAO,MAAMC,aAAaT,KAAKD,aAAa,CAACW,OAAgBC;IAC3D,IAAIC,SAASd,EACVe,IAAI,CAAC;QAAC;QAAS;QAAS;QAAQ;QAAQ;KAAQ,EAChDC,SAAS,CAAC,CAACC,MAAQb,KAAK,CAACa,IAAI,EAC7BC,SAAS,CAACC,OAAOP,OAAOQ,WAAW;IAEtC,IAAI,CAACN,OAAOO,OAAO,EAAE;QACnBP,SAASd,EAAEsB,MAAM,GAAGC,GAAG,CAACnB,MAAMC,KAAK,EAAEmB,GAAG,CAACpB,MAAMK,KAAK,EAAES,SAAS,CAACO,OAAOb;IACzE;IAEA,OAAOE,OAAOO,OAAO,GAAGP,OAAOY,IAAI,GAAGb;AACxC,GAAG;AAEH;;;;;;;;;;CAUC,GACD,OAAO,MAAMc,mBAAmB,CAACC;IAC/B7B,OAAO6B,YAAY,GAAG;IACtB,OAAOzB,MAAMC,MAAMG,IAAI,GAAG,IAAIqB,WAAWxB,MAAMC,KAAK,EAAED,MAAMG,IAAI;AAClE,EAAE"}
1
+ {"version":3,"sources":["../../../../src/services/output/log/level.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport { z } from \"zod\";\nimport { MemoAllArgs, memo } from \"../../util/function.js\";\nimport { clamp } from \"../../util/number.js\";\n\nexport type Level = (typeof Level)[keyof typeof Level];\n\nexport const Level = {\n TRACE: 1,\n DEBUG: 2,\n INFO: 3,\n WARN: 4,\n ERROR: 5,\n PRINT: 6,\n} as const;\n\nexport const parseLevel = memo(MemoAllArgs, (value: unknown, defaultValue: Level): Level => {\n let parsed = z\n .enum([\"TRACE\", \"DEBUG\", \"INFO\", \"WARN\", \"ERROR\"])\n .transform((str) => Level[str])\n .safeParse(String(value).toUpperCase());\n\n if (!parsed.success) {\n parsed = z.number().min(Level.TRACE).max(Level.ERROR).safeParse(Number(value)) as typeof parsed;\n }\n\n return parsed.success ? parsed.data : defaultValue;\n});\n\n/**\n * Converts a numeric verbosity value to a log level.\n *\n * @param verbosity - The verbosity value\n * @returns The log level\n * @example\n * verbosityToLevel(1) // => Level.INFO\n * verbosityToLevel(2) // => Level.DEBUG\n * verbosityToLevel(3) // => Level.TRACE\n * verbosityToLevel(Infinity) // => Level.TRACE\n */\nexport const verbosityToLevel = (verbosity: number): Level => {\n assert(verbosity > 0, \"verbosity must be greater than 0\");\n return clamp(Level.INFO + 1 - verbosity, Level.TRACE, Level.INFO) as Level;\n};\n"],"names":["assert","z","MemoAllArgs","memo","clamp","Level","TRACE","DEBUG","INFO","WARN","ERROR","PRINT","parseLevel","value","defaultValue","parsed","enum","transform","str","safeParse","String","toUpperCase","success","number","min","max","Number","data","verbosityToLevel","verbosity"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,WAAW,EAAEC,IAAI,QAAQ,yBAAyB;AAC3D,SAASC,KAAK,QAAQ,uBAAuB;AAI7C,OAAO,MAAMC,QAAQ;IACnBC,OAAO;IACPC,OAAO;IACPC,MAAM;IACNC,MAAM;IACNC,OAAO;IACPC,OAAO;AACT,EAAW;AAEX,OAAO,MAAMC,aAAaT,KAAKD,aAAa,CAACW,OAAgBC;IAC3D,IAAIC,SAASd,EACVe,IAAI,CAAC;QAAC;QAAS;QAAS;QAAQ;QAAQ;KAAQ,EAChDC,SAAS,CAAC,CAACC,MAAQb,KAAK,CAACa,IAAI,EAC7BC,SAAS,CAACC,OAAOP,OAAOQ,WAAW;IAEtC,IAAI,CAACN,OAAOO,OAAO,EAAE;QACnBP,SAASd,EAAEsB,MAAM,GAAGC,GAAG,CAACnB,MAAMC,KAAK,EAAEmB,GAAG,CAACpB,MAAMK,KAAK,EAAES,SAAS,CAACO,OAAOb;IACzE;IAEA,OAAOE,OAAOO,OAAO,GAAGP,OAAOY,IAAI,GAAGb;AACxC,GAAG;AAEH;;;;;;;;;;CAUC,GACD,OAAO,MAAMc,mBAAmB,CAACC;IAC/B7B,OAAO6B,YAAY,GAAG;IACtB,OAAOzB,MAAMC,MAAMG,IAAI,GAAG,IAAIqB,WAAWxB,MAAMC,KAAK,EAAED,MAAMG,IAAI;AAClE,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/services/output/log/logger.ts"],"sourcesContent":["import { unthunk } from \"../../util/function.js\";\nimport { createStructuredLogger, type StructuredLogger, type StructuredLoggerOptions } from \"./structured.js\";\n\nexport type Logger = StructuredLogger & {\n /**\n * Creates a child logger with the given options. The child logger\n * inherits the name and fields of the parent logger.\n *\n * @param options\n */\n child(options: Partial<StructuredLoggerOptions>): Logger;\n};\n\n/**\n * Creates a {@linkcode Logger} with the given name and fields.\n *\n * Use the {@linkcode Printer} methods to print messages to stdout for\n * end users to read.\n *\n * Use the {@linkcode StructuredLogger} methods to print structured\n * messages to stderr for developers to read. These messages are only\n * printed when the `GGT_LOG_LEVEL` is greater than or equal to the\n * level of the message.\n *\n * @example\n * const logger = createLogger({ name: \"my-logger\" });\n * logger.info(\"printing hello world\", { foo: \"bar\" });\n * // stderr\n * // 12:00:00 INFO my-logger: printing hello world\n * // foo: \"bar\"\n * //\n * // stderr w/ --json\n * // {\"level\":3,\"name\":\"my-logger\",\"msg\":\"printing hello world\",\"fields\":{\"foo\":\"bar\"}}\n *\n * logger.println(\"Hello, world!\");\n * // stdout\n * // Hello, world!\n * //\n * // stdout w/ --json\n * // {\"level\":6,\"name\":\"my-logger\",\"msg\":\"Hello, world!\"}\n */\nexport const createLogger = ({ name, fields: loggerFields, devFields: loggerDevFields }: StructuredLoggerOptions): Logger => {\n return {\n ...createStructuredLogger({ name, fields: loggerFields, devFields: loggerDevFields }),\n child: ({ name: childName, fields: childFields, devFields: childDevFields }) => {\n return createLogger({\n name: childName || name,\n fields: () => ({ ...unthunk(loggerFields), ...unthunk(childFields) }),\n devFields: { ...unthunk(loggerDevFields), ...unthunk(childDevFields) },\n });\n },\n };\n};\n"],"names":["unthunk","createStructuredLogger","createLogger","name","fields","loggerFields","devFields","loggerDevFields","child","childName","childFields","childDevFields"],"mappings":"AAAA,SAASA,OAAO,QAAQ,yBAAyB;AACjD,SAASC,sBAAsB,QAA6D,kBAAkB;AAY9G;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,MAAMC,eAAe,CAAC,EAAEC,IAAI,EAAEC,QAAQC,YAAY,EAAEC,WAAWC,eAAe,EAA2B;IAC9G,OAAO;QACL,GAAGN,uBAAuB;YAAEE;YAAMC,QAAQC;YAAcC,WAAWC;QAAgB,EAAE;QACrFC,OAAO,CAAC,EAAEL,MAAMM,SAAS,EAAEL,QAAQM,WAAW,EAAEJ,WAAWK,cAAc,EAAE;YACzE,OAAOT,aAAa;gBAClBC,MAAMM,aAAaN;gBACnBC,QAAQ,IAAO,CAAA;wBAAE,GAAGJ,QAAQK,aAAa;wBAAE,GAAGL,QAAQU,YAAY;oBAAC,CAAA;gBACnEJ,WAAW;oBAAE,GAAGN,QAAQO,gBAAgB;oBAAE,GAAGP,QAAQW,eAAe;gBAAC;YACvE;QACF;IACF;AACF,EAAE"}
1
+ {"version":3,"sources":["../../../../src/services/output/log/logger.ts"],"sourcesContent":["import { unthunk } from \"../../util/function.js\";\nimport { createStructuredLogger, type StructuredLogger, type StructuredLoggerOptions } from \"./structured.js\";\n\nexport type Logger = StructuredLogger & {\n /**\n * Creates a child logger with the given options. The child logger\n * inherits the name and fields of the parent logger.\n *\n * @param options\n */\n child(options: Partial<StructuredLoggerOptions>): Logger;\n};\n\n/**\n * Creates a {@linkcode Logger} with the given name and fields.\n *\n * Use the {@linkcode Printer} methods to print messages to stdout for\n * end users to read.\n *\n * Use the {@linkcode StructuredLogger} methods to print structured\n * messages to stderr for developers to read. These messages are only\n * printed when the `GGT_LOG_LEVEL` is greater than or equal to the\n * level of the message.\n *\n * @example\n * const logger = createLogger({ name: \"my-logger\" });\n * logger.info(\"printing hello world\", { foo: \"bar\" });\n * // stderr\n * // 12:00:00 INFO my-logger: printing hello world\n * // foo: \"bar\"\n * //\n * // stderr w/ --json\n * // {\"level\":3,\"name\":\"my-logger\",\"msg\":\"printing hello world\",\"fields\":{\"foo\":\"bar\"}}\n *\n * logger.println(\"Hello, world!\");\n * // stdout\n * // Hello, world!\n * //\n * // stdout w/ --json\n * // {\"level\":6,\"name\":\"my-logger\",\"msg\":\"Hello, world!\"}\n */\nexport const createLogger = ({ name, fields: loggerFields, devFields: loggerDevFields }: StructuredLoggerOptions): Logger => {\n return {\n ...createStructuredLogger({ name, fields: loggerFields, devFields: loggerDevFields }),\n child: ({ name: childName, fields: childFields, devFields: childDevFields }) => {\n return createLogger({\n name: childName || name,\n fields: () => ({ ...unthunk(loggerFields), ...unthunk(childFields) }),\n devFields: { ...unthunk(loggerDevFields), ...unthunk(childDevFields) },\n });\n },\n };\n};\n"],"names":["unthunk","createStructuredLogger","createLogger","name","fields","loggerFields","devFields","loggerDevFields","child","childName","childFields","childDevFields"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,OAAO,QAAQ,yBAAyB;AACjD,SAASC,sBAAsB,QAA6D,kBAAkB;AAY9G;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,GACD,OAAO,MAAMC,eAAe,CAAC,EAAEC,IAAI,EAAEC,QAAQC,YAAY,EAAEC,WAAWC,eAAe,EAA2B;IAC9G,OAAO;QACL,GAAGN,uBAAuB;YAAEE;YAAMC,QAAQC;YAAcC,WAAWC;QAAgB,EAAE;QACrFC,OAAO,CAAC,EAAEL,MAAMM,SAAS,EAAEL,QAAQM,WAAW,EAAEJ,WAAWK,cAAc,EAAE;YACzE,OAAOT,aAAa;gBAClBC,MAAMM,aAAaN;gBACnBC,QAAQ,IAAO,CAAA;wBAAE,GAAGJ,QAAQK,aAAa;wBAAE,GAAGL,QAAQU,YAAY;oBAAC,CAAA;gBACnEJ,WAAW;oBAAE,GAAGN,QAAQO,gBAAgB;oBAAE,GAAGP,QAAQW,eAAe;gBAAC;YACvE;QACF;IACF;AACF,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/services/output/log/structured.ts"],"sourcesContent":["import { addBreadcrumb as addSentryBreadcrumb } from \"@sentry/node\";\nimport { config } from \"../../config/config.js\";\nimport { env } from \"../../config/env.js\";\nimport { unthunk, type Thunk } from \"../../util/function.js\";\nimport { serializeError } from \"../../util/object.js\";\nimport { output } from \"../output.js\";\nimport type { Fields } from \"./field.js\";\nimport { formatters } from \"./format/format.js\";\nimport { Level } from \"./level.js\";\n\ntype StructuredLog = (msg: Lowercase<string>, fields?: Fields, devFields?: Fields) => void;\n\nexport type StructuredLogger = {\n trace: StructuredLog;\n debug: StructuredLog;\n info: StructuredLog;\n warn: StructuredLog;\n error: StructuredLog;\n};\n\nexport type StructuredLoggerOptions = {\n /**\n * The name of logger.\n */\n name: string;\n\n /**\n * Fields to add to every message logged by the logger.\n */\n fields?: Thunk<Fields>;\n\n /**\n * Fields to add to every message logged by the logger only in\n * development or test environments.\n */\n devFields?: Thunk<Fields>;\n};\n\nexport const createStructuredLogger = ({\n name,\n fields: loggerFields = {},\n devFields: devLoggerFields = {},\n}: StructuredLoggerOptions): StructuredLogger => {\n const createStructuredLog = (level: Level): StructuredLog => {\n return (msg, messageFields, devMessageFields) => {\n const shouldLog = level >= config.logLevel;\n const shouldSendToSentry = level >= Level.INFO;\n if (!shouldLog && !shouldSendToSentry) {\n return;\n }\n\n const fields = { ...unthunk(loggerFields), ...messageFields };\n if (env.developmentOrTestLike) {\n Object.assign(fields, unthunk(devLoggerFields), devMessageFields);\n }\n\n if (\"error\" in fields) {\n fields.error = serializeError(fields.error);\n }\n\n if (\"reason\" in fields) {\n fields.reason = serializeError(fields.reason);\n }\n\n if (shouldLog) {\n const format = formatters[config.logFormat];\n output.writeStderr(format(level, name, msg, fields));\n }\n\n if (shouldSendToSentry) {\n addSentryBreadcrumb({ level: \"log\", message: msg, data: fields });\n }\n };\n };\n\n return {\n trace: createStructuredLog(Level.TRACE),\n debug: createStructuredLog(Level.DEBUG),\n info: createStructuredLog(Level.INFO),\n warn: createStructuredLog(Level.WARN),\n error: createStructuredLog(Level.ERROR),\n };\n};\n"],"names":["addBreadcrumb","addSentryBreadcrumb","config","env","unthunk","serializeError","output","formatters","Level","createStructuredLogger","name","fields","loggerFields","devFields","devLoggerFields","createStructuredLog","level","msg","messageFields","devMessageFields","shouldLog","logLevel","shouldSendToSentry","INFO","developmentOrTestLike","Object","assign","error","reason","format","logFormat","writeStderr","message","data","trace","TRACE","debug","DEBUG","info","warn","WARN","ERROR"],"mappings":"AAAA,SAASA,iBAAiBC,mBAAmB,QAAQ,eAAe;AACpE,SAASC,MAAM,QAAQ,yBAAyB;AAChD,SAASC,GAAG,QAAQ,sBAAsB;AAC1C,SAASC,OAAO,QAAoB,yBAAyB;AAC7D,SAASC,cAAc,QAAQ,uBAAuB;AACtD,SAASC,MAAM,QAAQ,eAAe;AAEtC,SAASC,UAAU,QAAQ,qBAAqB;AAChD,SAASC,KAAK,QAAQ,aAAa;AA8BnC,OAAO,MAAMC,yBAAyB,CAAC,EACrCC,IAAI,EACJC,QAAQC,eAAe,CAAC,CAAC,EACzBC,WAAWC,kBAAkB,CAAC,CAAC,EACP;IACxB,MAAMC,sBAAsB,CAACC;QAC3B,OAAO,CAACC,KAAKC,eAAeC;YAC1B,MAAMC,YAAYJ,SAASd,OAAOmB,QAAQ;YAC1C,MAAMC,qBAAqBN,SAASR,MAAMe,IAAI;YAC9C,IAAI,CAACH,aAAa,CAACE,oBAAoB;gBACrC;YACF;YAEA,MAAMX,SAAS;gBAAE,GAAGP,QAAQQ,aAAa;gBAAE,GAAGM,aAAa;YAAC;YAC5D,IAAIf,IAAIqB,qBAAqB,EAAE;gBAC7BC,OAAOC,MAAM,CAACf,QAAQP,QAAQU,kBAAkBK;YAClD;YAEA,IAAI,WAAWR,QAAQ;gBACrBA,OAAOgB,KAAK,GAAGtB,eAAeM,OAAOgB,KAAK;YAC5C;YAEA,IAAI,YAAYhB,QAAQ;gBACtBA,OAAOiB,MAAM,GAAGvB,eAAeM,OAAOiB,MAAM;YAC9C;YAEA,IAAIR,WAAW;gBACb,MAAMS,SAAStB,UAAU,CAACL,OAAO4B,SAAS,CAAC;gBAC3CxB,OAAOyB,WAAW,CAACF,OAAOb,OAAON,MAAMO,KAAKN;YAC9C;YAEA,IAAIW,oBAAoB;gBACtBrB,oBAAoB;oBAAEe,OAAO;oBAAOgB,SAASf;oBAAKgB,MAAMtB;gBAAO;YACjE;QACF;IACF;IAEA,OAAO;QACLuB,OAAOnB,oBAAoBP,MAAM2B,KAAK;QACtCC,OAAOrB,oBAAoBP,MAAM6B,KAAK;QACtCC,MAAMvB,oBAAoBP,MAAMe,IAAI;QACpCgB,MAAMxB,oBAAoBP,MAAMgC,IAAI;QACpCb,OAAOZ,oBAAoBP,MAAMiC,KAAK;IACxC;AACF,EAAE"}
1
+ {"version":3,"sources":["../../../../src/services/output/log/structured.ts"],"sourcesContent":["import { addBreadcrumb as addSentryBreadcrumb } from \"@sentry/node\";\nimport { config } from \"../../config/config.js\";\nimport { env } from \"../../config/env.js\";\nimport { unthunk, type Thunk } from \"../../util/function.js\";\nimport { serializeError } from \"../../util/object.js\";\nimport { output } from \"../output.js\";\nimport type { Fields } from \"./field.js\";\nimport { formatters } from \"./format/format.js\";\nimport { Level } from \"./level.js\";\n\ntype StructuredLog = (msg: Lowercase<string>, fields?: Fields, devFields?: Fields) => void;\n\nexport type StructuredLogger = {\n trace: StructuredLog;\n debug: StructuredLog;\n info: StructuredLog;\n warn: StructuredLog;\n error: StructuredLog;\n};\n\nexport type StructuredLoggerOptions = {\n /**\n * The name of logger.\n */\n name: string;\n\n /**\n * Fields to add to every message logged by the logger.\n */\n fields?: Thunk<Fields>;\n\n /**\n * Fields to add to every message logged by the logger only in\n * development or test environments.\n */\n devFields?: Thunk<Fields>;\n};\n\nexport const createStructuredLogger = ({\n name,\n fields: loggerFields = {},\n devFields: devLoggerFields = {},\n}: StructuredLoggerOptions): StructuredLogger => {\n const createStructuredLog = (level: Level): StructuredLog => {\n return (msg, messageFields, devMessageFields) => {\n const shouldLog = level >= config.logLevel;\n const shouldSendToSentry = level >= Level.INFO;\n if (!shouldLog && !shouldSendToSentry) {\n return;\n }\n\n const fields = { ...unthunk(loggerFields), ...messageFields };\n if (env.developmentOrTestLike) {\n Object.assign(fields, unthunk(devLoggerFields), devMessageFields);\n }\n\n if (\"error\" in fields) {\n fields.error = serializeError(fields.error);\n }\n\n if (\"reason\" in fields) {\n fields.reason = serializeError(fields.reason);\n }\n\n if (shouldLog) {\n const format = formatters[config.logFormat];\n output.writeStderr(format(level, name, msg, fields));\n }\n\n if (shouldSendToSentry) {\n addSentryBreadcrumb({ level: \"log\", message: msg, data: fields });\n }\n };\n };\n\n return {\n trace: createStructuredLog(Level.TRACE),\n debug: createStructuredLog(Level.DEBUG),\n info: createStructuredLog(Level.INFO),\n warn: createStructuredLog(Level.WARN),\n error: createStructuredLog(Level.ERROR),\n };\n};\n"],"names":["addBreadcrumb","addSentryBreadcrumb","config","env","unthunk","serializeError","output","formatters","Level","createStructuredLogger","name","fields","loggerFields","devFields","devLoggerFields","createStructuredLog","level","msg","messageFields","devMessageFields","shouldLog","logLevel","shouldSendToSentry","INFO","developmentOrTestLike","Object","assign","error","reason","format","logFormat","writeStderr","message","data","trace","TRACE","debug","DEBUG","info","warn","WARN","ERROR"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,iBAAiBC,mBAAmB,QAAQ,eAAe;AACpE,SAASC,MAAM,QAAQ,yBAAyB;AAChD,SAASC,GAAG,QAAQ,sBAAsB;AAC1C,SAASC,OAAO,QAAoB,yBAAyB;AAC7D,SAASC,cAAc,QAAQ,uBAAuB;AACtD,SAASC,MAAM,QAAQ,eAAe;AAEtC,SAASC,UAAU,QAAQ,qBAAqB;AAChD,SAASC,KAAK,QAAQ,aAAa;AA8BnC,OAAO,MAAMC,yBAAyB,CAAC,EACrCC,IAAI,EACJC,QAAQC,eAAe,CAAC,CAAC,EACzBC,WAAWC,kBAAkB,CAAC,CAAC,EACP;IACxB,MAAMC,sBAAsB,CAACC;QAC3B,OAAO,CAACC,KAAKC,eAAeC;YAC1B,MAAMC,YAAYJ,SAASd,OAAOmB,QAAQ;YAC1C,MAAMC,qBAAqBN,SAASR,MAAMe,IAAI;YAC9C,IAAI,CAACH,aAAa,CAACE,oBAAoB;gBACrC;YACF;YAEA,MAAMX,SAAS;gBAAE,GAAGP,QAAQQ,aAAa;gBAAE,GAAGM,aAAa;YAAC;YAC5D,IAAIf,IAAIqB,qBAAqB,EAAE;gBAC7BC,OAAOC,MAAM,CAACf,QAAQP,QAAQU,kBAAkBK;YAClD;YAEA,IAAI,WAAWR,QAAQ;gBACrBA,OAAOgB,KAAK,GAAGtB,eAAeM,OAAOgB,KAAK;YAC5C;YAEA,IAAI,YAAYhB,QAAQ;gBACtBA,OAAOiB,MAAM,GAAGvB,eAAeM,OAAOiB,MAAM;YAC9C;YAEA,IAAIR,WAAW;gBACb,MAAMS,SAAStB,UAAU,CAACL,OAAO4B,SAAS,CAAC;gBAC3CxB,OAAOyB,WAAW,CAACF,OAAOb,OAAON,MAAMO,KAAKN;YAC9C;YAEA,IAAIW,oBAAoB;gBACtBrB,oBAAoB;oBAAEe,OAAO;oBAAOgB,SAASf;oBAAKgB,MAAMtB;gBAAO;YACjE;QACF;IACF;IAEA,OAAO;QACLuB,OAAOnB,oBAAoBP,MAAM2B,KAAK;QACtCC,OAAOrB,oBAAoBP,MAAM6B,KAAK;QACtCC,MAAMvB,oBAAoBP,MAAMe,IAAI;QACpCgB,MAAMxB,oBAAoBP,MAAMgC,IAAI;QACpCb,OAAOZ,oBAAoBP,MAAMiC,KAAK;IACxC;AACF,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/notify.ts"],"sourcesContent":["import notifier, { type Notification } from \"node-notifier\";\nimport type WindowsBalloon from \"node-notifier/notifiers/balloon.js\";\nimport type Growl from \"node-notifier/notifiers/growl.js\";\nimport type NotificationCenter from \"node-notifier/notifiers/notificationcenter.js\";\nimport type NotifySend from \"node-notifier/notifiers/notifysend.js\";\nimport type WindowsToaster from \"node-notifier/notifiers/toaster.js\";\nimport type { Context } from \"../command/context.js\";\nimport { assetsPath } from \"../util/paths.js\";\nimport type { Field } from \"./log/field.js\";\n\n/**\n * Sends a native OS notification to the user.\n *\n * @see {@link https://www.npmjs.com/package/node-notifier node-notifier}\n */\nexport const notify = (\n ctx: Context,\n notification:\n | Notification\n | NotificationCenter.Notification\n | NotifySend.Notification\n | WindowsToaster.Notification\n | WindowsBalloon.Notification\n | Growl.Notification,\n): void => {\n ctx.log.info(\"notifying user\", { notification: notification as Field });\n\n notifier.notify(\n {\n title: \"Gadget\",\n contentImage: assetsPath(\"favicon-128@4x.png\"),\n icon: assetsPath(\"favicon-128@4x.png\"),\n sound: true,\n timeout: false,\n ...notification,\n },\n (error) => {\n if (error) {\n ctx.log.warn(\"error notifying user\", { notification: notification as Field });\n }\n },\n );\n};\n"],"names":["notifier","assetsPath","notify","ctx","notification","log","info","title","contentImage","icon","sound","timeout","error","warn"],"mappings":"AAAA,OAAOA,cAAqC,gBAAgB;AAO5D,SAASC,UAAU,QAAQ,mBAAmB;AAG9C;;;;CAIC,GACD,OAAO,MAAMC,SAAS,CACpBC,KACAC;IAQAD,IAAIE,GAAG,CAACC,IAAI,CAAC,kBAAkB;QAAEF,cAAcA;IAAsB;IAErEJ,SAASE,MAAM,CACb;QACEK,OAAO;QACPC,cAAcP,WAAW;QACzBQ,MAAMR,WAAW;QACjBS,OAAO;QACPC,SAAS;QACT,GAAGP,YAAY;IACjB,GACA,CAACQ;QACC,IAAIA,OAAO;YACTT,IAAIE,GAAG,CAACQ,IAAI,CAAC,wBAAwB;gBAAET,cAAcA;YAAsB;QAC7E;IACF;AAEJ,EAAE"}
1
+ {"version":3,"sources":["../../../src/services/output/notify.ts"],"sourcesContent":["import notifier, { type Notification } from \"node-notifier\";\nimport type WindowsBalloon from \"node-notifier/notifiers/balloon.js\";\nimport type Growl from \"node-notifier/notifiers/growl.js\";\nimport type NotificationCenter from \"node-notifier/notifiers/notificationcenter.js\";\nimport type NotifySend from \"node-notifier/notifiers/notifysend.js\";\nimport type WindowsToaster from \"node-notifier/notifiers/toaster.js\";\nimport type { Context } from \"../command/context.js\";\nimport { assetsPath } from \"../util/paths.js\";\nimport type { Field } from \"./log/field.js\";\n\n/**\n * Sends a native OS notification to the user.\n *\n * @see {@link https://www.npmjs.com/package/node-notifier node-notifier}\n */\nexport const notify = (\n ctx: Context,\n notification:\n | Notification\n | NotificationCenter.Notification\n | NotifySend.Notification\n | WindowsToaster.Notification\n | WindowsBalloon.Notification\n | Growl.Notification,\n): void => {\n ctx.log.info(\"notifying user\", { notification: notification as Field });\n\n notifier.notify(\n {\n title: \"Gadget\",\n contentImage: assetsPath(\"favicon-128@4x.png\"),\n icon: assetsPath(\"favicon-128@4x.png\"),\n sound: true,\n timeout: false,\n ...notification,\n },\n (error) => {\n if (error) {\n ctx.log.warn(\"error notifying user\", { notification: notification as Field });\n }\n },\n );\n};\n"],"names":["notifier","assetsPath","notify","ctx","notification","log","info","title","contentImage","icon","sound","timeout","error","warn"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,OAAOA,cAAqC,gBAAgB;AAO5D,SAASC,UAAU,QAAQ,mBAAmB;AAG9C;;;;CAIC,GACD,OAAO,MAAMC,SAAS,CACpBC,KACAC;IAQAD,IAAIE,GAAG,CAACC,IAAI,CAAC,kBAAkB;QAAEF,cAAcA;IAAsB;IAErEJ,SAASE,MAAM,CACb;QACEK,OAAO;QACPC,cAAcP,WAAW;QACzBQ,MAAMR,WAAW;QACjBS,OAAO;QACPC,SAAS;QACT,GAAGP,YAAY;IACjB,GACA,CAACQ;QACC,IAAIA,OAAO;YACTT,IAAIE,GAAG,CAACQ,IAAI,CAAC,wBAAwB;gBAAET,cAAcA;YAAsB;QAC7E;IACF;AAEJ,EAAE"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/output.ts"],"sourcesContent":["import cliCursor from \"cli-cursor\";\nimport isInteractive from \"is-interactive\";\nimport assert from \"node:assert\";\nimport process from \"node:process\";\nimport stdinDiscarder from \"stdin-discarder\";\nimport stringWidth from \"string-width\";\nimport stripAnsi from \"strip-ansi\";\nimport { env } from \"../config/env.js\";\nimport { unthunk } from \"../util/function.js\";\nimport { isObject } from \"../util/is.js\";\n\nlet cursorIsHidden = false;\n\n/**\n * Stderr\n * Prompt\n * Spinner\n * Footer\n */\nexport class Output {\n /**\n * Indicates whether the last line that was written to the stream was\n * empty (i.e. \"\\n\"). This is useful for preventing duplicate empty\n * lines from being printed.\n *\n * This is automatically calculated by the {@linkcode writeStdout}\n * method, so you only need to set this property manually when you\n * know something else wrote to the stream directly.\n */\n lastPrintedLineWasEmpty = true;\n\n lastStickyLineWasEmpty = true;\n\n private _promptText = \"\";\n\n private _spinnerText = \"\";\n\n private _footerText = \"\";\n\n private _stickyTextLinesToClear = 0;\n\n constructor() {\n process.stdout.on(\"error\", (err: unknown) => {\n if (isObject(err) && \"code\" in err && err.code === \"EPIPE\") {\n return;\n }\n throw err;\n });\n\n process.stderr.on(\"error\", (err: unknown) => {\n if (isObject(err) && \"code\" in err && err.code === \"EPIPE\") {\n return;\n }\n throw err;\n });\n }\n\n get isInteractive(): boolean {\n return !env.testLike && isInteractive({ stream: process.stdout });\n }\n\n writeStdout(text: string): void {\n this._clearStickyText();\n\n text = this._stripUnnecessaryNewLines(text, this.lastPrintedLineWasEmpty);\n this._writeStdout(text);\n this.lastPrintedLineWasEmpty = text === \"\\n\" || text.endsWith(\"\\n\\n\");\n this.lastStickyLineWasEmpty = this.lastPrintedLineWasEmpty;\n\n this._writeStickyText();\n }\n\n writeStderr(text: string): void {\n this._clearStickyText();\n\n text = this._stripUnnecessaryNewLines(text, this.lastPrintedLineWasEmpty);\n this._writeStderr(text);\n this.lastPrintedLineWasEmpty = text === \"\\n\" || text.endsWith(\"\\n\\n\");\n this.lastStickyLineWasEmpty = this.lastPrintedLineWasEmpty;\n\n this._writeStickyText();\n }\n\n updatePrompt(promptTextThunk: string | ((currentPromptText: string) => string)): void {\n assert(this.isInteractive, \"cannot update prompt in non-interactive mode\");\n this._promptText = unthunk(promptTextThunk, this._promptText);\n this._writeStickyText();\n }\n\n persistPrompt(finalPromptText = this._promptText): void {\n this._promptText = \"\";\n this.writeStdout(finalPromptText);\n }\n\n updateSpinner(spinnerTextThunk: string | ((currentSpinnerText: string) => string)): void {\n assert(this.isInteractive, \"cannot update spinner in non-interactive mode\");\n this._spinnerText = unthunk(spinnerTextThunk, this._spinnerText);\n this._writeStickyText();\n }\n\n persistSpinner(finalSpinnerText = this._spinnerText): void {\n this._spinnerText = \"\";\n this.writeStdout(finalSpinnerText);\n }\n\n updateFooter(footerTextThunk: string | ((currentFooterText: string) => string)): void {\n assert(this.isInteractive, \"cannot update footer in non-interactive mode\");\n this._footerText = unthunk(footerTextThunk, this._footerText);\n this._writeStickyText();\n }\n\n persistFooter(finalFooterText = this._footerText): void {\n this._footerText = \"\";\n this.writeStdout(finalFooterText);\n }\n\n private _writeStdout(text: string): void {\n if (text === \"\") {\n return;\n }\n\n if (!env.testLike) {\n process.stdout.write(text);\n return;\n }\n\n // we use console.log/error in tests since vitest doesn't display\n // process.stdout/stderr correctly, so we need to remove the\n // trailing newline because console.log/error adds one\n if (text.endsWith(\"\\n\")) {\n text = text.slice(0, -1);\n }\n\n console.log(text);\n }\n\n private _writeStderr(text: string): void {\n if (text === \"\") {\n return;\n }\n\n if (!env.testLike) {\n process.stderr.write(text);\n return;\n }\n\n // we use console.log/error in tests since vitest doesn't display\n // process.stdout/stderr correctly, so we need to remove the\n // trailing newline because console.log/error adds one\n if (text.endsWith(\"\\n\")) {\n text = text.slice(0, -1);\n }\n\n console.error(text);\n }\n\n private _clearStickyText(): void {\n this.lastStickyLineWasEmpty = this.lastPrintedLineWasEmpty;\n if (this._stickyTextLinesToClear === 0) {\n return;\n }\n\n process.stderr.cursorTo(0);\n for (let i = 0; i < this._stickyTextLinesToClear; i++) {\n if (i > 0) {\n process.stderr.moveCursor(0, -1);\n }\n process.stderr.clearLine(1);\n }\n\n this._stickyTextLinesToClear = 0;\n }\n\n private _writeStickyText(): void {\n if (!this.isInteractive) {\n return;\n }\n\n this._clearStickyText();\n\n let formattedStickyText = \"\";\n if (this._promptText) {\n formattedStickyText += this._stripUnnecessaryNewLines(this._promptText, this.lastStickyLineWasEmpty);\n this.lastStickyLineWasEmpty = formattedStickyText === \"\\n\" || formattedStickyText.endsWith(\"\\n\\n\");\n }\n\n if (this._spinnerText) {\n formattedStickyText += this._stripUnnecessaryNewLines(this._spinnerText, this.lastStickyLineWasEmpty);\n this.lastStickyLineWasEmpty = formattedStickyText === \"\\n\" || formattedStickyText.endsWith(\"\\n\\n\");\n }\n\n if (this._footerText) {\n formattedStickyText += this._stripUnnecessaryNewLines(this._footerText, this.lastStickyLineWasEmpty);\n this.lastStickyLineWasEmpty = formattedStickyText === \"\\n\" || formattedStickyText.endsWith(\"\\n\\n\");\n }\n\n this._writeStderr(formattedStickyText);\n this._updateStickyTextLinesToClear(formattedStickyText);\n\n if (cursorIsHidden && !formattedStickyText) {\n cliCursor.show(process.stderr);\n stdinDiscarder.stop();\n cursorIsHidden = false;\n } else if (!cursorIsHidden && formattedStickyText) {\n cliCursor.hide(process.stderr);\n stdinDiscarder.start();\n cursorIsHidden = true;\n }\n }\n\n private _updateStickyTextLinesToClear(lastWrittenStickyText: string): void {\n for (const line of stripAnsi(lastWrittenStickyText).split(/\\r?\\n/)) {\n const numCharacters = stringWidth(line, { countAnsiEscapeCodes: true });\n const numLines = Math.ceil(numCharacters / process.stderr.columns);\n this._stickyTextLinesToClear += Math.max(1, numLines);\n }\n }\n\n private _stripUnnecessaryNewLines(text: string, lastLineWasEmpty: boolean): string {\n // remove duplicate empty lines\n let index = -1;\n while ((index = text.indexOf(\"\\n\\n\\n\")) !== -1) {\n text = text.slice(0, index) + text.slice(index + 1);\n }\n\n if (lastLineWasEmpty) {\n // we just printed an empty line, so don't print another one\n while (text.startsWith(\"\\n\")) {\n text = text.slice(1);\n }\n }\n\n return text;\n }\n}\n\nexport const output = new Output();\n"],"names":["cliCursor","isInteractive","assert","process","stdinDiscarder","stringWidth","stripAnsi","env","unthunk","isObject","cursorIsHidden","Output","testLike","stream","stdout","writeStdout","text","_clearStickyText","_stripUnnecessaryNewLines","lastPrintedLineWasEmpty","_writeStdout","endsWith","lastStickyLineWasEmpty","_writeStickyText","writeStderr","_writeStderr","updatePrompt","promptTextThunk","_promptText","persistPrompt","finalPromptText","updateSpinner","spinnerTextThunk","_spinnerText","persistSpinner","finalSpinnerText","updateFooter","footerTextThunk","_footerText","persistFooter","finalFooterText","write","slice","console","log","stderr","error","_stickyTextLinesToClear","cursorTo","i","moveCursor","clearLine","formattedStickyText","_updateStickyTextLinesToClear","show","stop","hide","start","lastWrittenStickyText","line","split","numCharacters","countAnsiEscapeCodes","numLines","Math","ceil","columns","max","lastLineWasEmpty","index","indexOf","startsWith","constructor","on","err","code","output"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/output/output.ts"],"sourcesContent":["import cliCursor from \"cli-cursor\";\nimport isInteractive from \"is-interactive\";\nimport assert from \"node:assert\";\nimport process from \"node:process\";\nimport stdinDiscarder from \"stdin-discarder\";\nimport stringWidth from \"string-width\";\nimport stripAnsi from \"strip-ansi\";\nimport { env } from \"../config/env.js\";\nimport { unthunk } from \"../util/function.js\";\nimport { isObject } from \"../util/is.js\";\n\nlet cursorIsHidden = false;\n\n/**\n * Stderr\n * Prompt\n * Spinner\n * Footer\n */\nexport class Output {\n /**\n * Indicates whether the last line that was written to the stream was\n * empty (i.e. \"\\n\"). This is useful for preventing duplicate empty\n * lines from being printed.\n *\n * This is automatically calculated by the {@linkcode writeStdout}\n * method, so you only need to set this property manually when you\n * know something else wrote to the stream directly.\n */\n lastPrintedLineWasEmpty = true;\n\n lastStickyLineWasEmpty = true;\n\n private _promptText = \"\";\n\n private _spinnerText = \"\";\n\n private _footerText = \"\";\n\n private _stickyTextLinesToClear = 0;\n\n constructor() {\n process.stdout.on(\"error\", (err: unknown) => {\n if (isObject(err) && \"code\" in err && err.code === \"EPIPE\") {\n return;\n }\n throw err;\n });\n\n process.stderr.on(\"error\", (err: unknown) => {\n if (isObject(err) && \"code\" in err && err.code === \"EPIPE\") {\n return;\n }\n throw err;\n });\n }\n\n get isInteractive(): boolean {\n return !env.testLike && isInteractive({ stream: process.stdout });\n }\n\n writeStdout(text: string): void {\n this._clearStickyText();\n\n text = this._stripUnnecessaryNewLines(text, this.lastPrintedLineWasEmpty);\n this._writeStdout(text);\n this.lastPrintedLineWasEmpty = text === \"\\n\" || text.endsWith(\"\\n\\n\");\n this.lastStickyLineWasEmpty = this.lastPrintedLineWasEmpty;\n\n this._writeStickyText();\n }\n\n writeStderr(text: string): void {\n this._clearStickyText();\n\n text = this._stripUnnecessaryNewLines(text, this.lastPrintedLineWasEmpty);\n this._writeStderr(text);\n this.lastPrintedLineWasEmpty = text === \"\\n\" || text.endsWith(\"\\n\\n\");\n this.lastStickyLineWasEmpty = this.lastPrintedLineWasEmpty;\n\n this._writeStickyText();\n }\n\n updatePrompt(promptTextThunk: string | ((currentPromptText: string) => string)): void {\n assert(this.isInteractive, \"cannot update prompt in non-interactive mode\");\n this._promptText = unthunk(promptTextThunk, this._promptText);\n this._writeStickyText();\n }\n\n persistPrompt(finalPromptText = this._promptText): void {\n this._promptText = \"\";\n this.writeStdout(finalPromptText);\n }\n\n updateSpinner(spinnerTextThunk: string | ((currentSpinnerText: string) => string)): void {\n assert(this.isInteractive, \"cannot update spinner in non-interactive mode\");\n this._spinnerText = unthunk(spinnerTextThunk, this._spinnerText);\n this._writeStickyText();\n }\n\n persistSpinner(finalSpinnerText = this._spinnerText): void {\n this._spinnerText = \"\";\n this.writeStdout(finalSpinnerText);\n }\n\n updateFooter(footerTextThunk: string | ((currentFooterText: string) => string)): void {\n assert(this.isInteractive, \"cannot update footer in non-interactive mode\");\n this._footerText = unthunk(footerTextThunk, this._footerText);\n this._writeStickyText();\n }\n\n persistFooter(finalFooterText = this._footerText): void {\n this._footerText = \"\";\n this.writeStdout(finalFooterText);\n }\n\n private _writeStdout(text: string): void {\n if (text === \"\") {\n return;\n }\n\n if (!env.testLike) {\n process.stdout.write(text);\n return;\n }\n\n // we use console.log/error in tests since vitest doesn't display\n // process.stdout/stderr correctly, so we need to remove the\n // trailing newline because console.log/error adds one\n if (text.endsWith(\"\\n\")) {\n text = text.slice(0, -1);\n }\n\n console.log(text);\n }\n\n private _writeStderr(text: string): void {\n if (text === \"\") {\n return;\n }\n\n if (!env.testLike) {\n process.stderr.write(text);\n return;\n }\n\n // we use console.log/error in tests since vitest doesn't display\n // process.stdout/stderr correctly, so we need to remove the\n // trailing newline because console.log/error adds one\n if (text.endsWith(\"\\n\")) {\n text = text.slice(0, -1);\n }\n\n console.error(text);\n }\n\n private _clearStickyText(): void {\n this.lastStickyLineWasEmpty = this.lastPrintedLineWasEmpty;\n if (this._stickyTextLinesToClear === 0) {\n return;\n }\n\n process.stderr.cursorTo(0);\n for (let i = 0; i < this._stickyTextLinesToClear; i++) {\n if (i > 0) {\n process.stderr.moveCursor(0, -1);\n }\n process.stderr.clearLine(1);\n }\n\n this._stickyTextLinesToClear = 0;\n }\n\n private _writeStickyText(): void {\n if (!this.isInteractive) {\n return;\n }\n\n this._clearStickyText();\n\n let formattedStickyText = \"\";\n if (this._promptText) {\n formattedStickyText += this._stripUnnecessaryNewLines(this._promptText, this.lastStickyLineWasEmpty);\n this.lastStickyLineWasEmpty = formattedStickyText === \"\\n\" || formattedStickyText.endsWith(\"\\n\\n\");\n }\n\n if (this._spinnerText) {\n formattedStickyText += this._stripUnnecessaryNewLines(this._spinnerText, this.lastStickyLineWasEmpty);\n this.lastStickyLineWasEmpty = formattedStickyText === \"\\n\" || formattedStickyText.endsWith(\"\\n\\n\");\n }\n\n if (this._footerText) {\n formattedStickyText += this._stripUnnecessaryNewLines(this._footerText, this.lastStickyLineWasEmpty);\n this.lastStickyLineWasEmpty = formattedStickyText === \"\\n\" || formattedStickyText.endsWith(\"\\n\\n\");\n }\n\n this._writeStderr(formattedStickyText);\n this._updateStickyTextLinesToClear(formattedStickyText);\n\n if (cursorIsHidden && !formattedStickyText) {\n cliCursor.show(process.stderr);\n stdinDiscarder.stop();\n cursorIsHidden = false;\n } else if (!cursorIsHidden && formattedStickyText) {\n cliCursor.hide(process.stderr);\n stdinDiscarder.start();\n cursorIsHidden = true;\n }\n }\n\n private _updateStickyTextLinesToClear(lastWrittenStickyText: string): void {\n for (const line of stripAnsi(lastWrittenStickyText).split(/\\r?\\n/)) {\n const numCharacters = stringWidth(line, { countAnsiEscapeCodes: true });\n const numLines = Math.ceil(numCharacters / process.stderr.columns);\n this._stickyTextLinesToClear += Math.max(1, numLines);\n }\n }\n\n private _stripUnnecessaryNewLines(text: string, lastLineWasEmpty: boolean): string {\n // remove duplicate empty lines\n let index = -1;\n while ((index = text.indexOf(\"\\n\\n\\n\")) !== -1) {\n text = text.slice(0, index) + text.slice(index + 1);\n }\n\n if (lastLineWasEmpty) {\n // we just printed an empty line, so don't print another one\n while (text.startsWith(\"\\n\")) {\n text = text.slice(1);\n }\n }\n\n return text;\n }\n}\n\nexport const output = new Output();\n"],"names":["cliCursor","isInteractive","assert","process","stdinDiscarder","stringWidth","stripAnsi","env","unthunk","isObject","cursorIsHidden","Output","testLike","stream","stdout","writeStdout","text","_clearStickyText","_stripUnnecessaryNewLines","lastPrintedLineWasEmpty","_writeStdout","endsWith","lastStickyLineWasEmpty","_writeStickyText","writeStderr","_writeStderr","updatePrompt","promptTextThunk","_promptText","persistPrompt","finalPromptText","updateSpinner","spinnerTextThunk","_spinnerText","persistSpinner","finalSpinnerText","updateFooter","footerTextThunk","_footerText","persistFooter","finalFooterText","write","slice","console","log","stderr","error","_stickyTextLinesToClear","cursorTo","i","moveCursor","clearLine","formattedStickyText","_updateStickyTextLinesToClear","show","stop","hide","start","lastWrittenStickyText","line","split","numCharacters","countAnsiEscapeCodes","numLines","Math","ceil","columns","max","lastLineWasEmpty","index","indexOf","startsWith","constructor","on","err","code","output"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/print.ts"],"sourcesContent":["import { config } from \"../config/config.js\";\nimport type { Field } from \"./log/field.js\";\nimport { output } from \"./output.js\";\nimport { isSprintOptions, sprint, type SprintOptions } from \"./sprint.js\";\n\nexport type PrintOptions = SprintOptions & {\n /**\n * What to print if --json was passed.\n *\n * @default undefined (print nothing)\n */\n json?: Field;\n};\n\nexport type print = {\n /**\n * Prints the given string as is.\n *\n * @param str - The string to print.\n * @example\n * print(\"Hello, world!\");\n * // => \"Hello, world!\"\n *\n * print(`\n * Hello, world!\n *\n * How are you?\n * `);\n * // => \"\\n Hello, world!\\n\\n How are you?\\n\"\n */\n (str: string): void;\n\n /**\n * Prints the given template string with dedent and chalk-template.\n *\n * @param template - The template string to format.\n * @param values - The values to interpolate into the template.\n * @example\n * ```\n * let name = \"Jane\";\n *\n * print`Hello, ${name}!`;\n * // => \"Hello, Jane!\"\n *\n * print`Hello, {red ${name}}!`;\n * // => \"Hello, \\u001b[31mJane\\u001b[39m!\"\n *\n * print`\n * Hello, {red ${name}}!\n *\n * How are you?\n * `;\n * // => \"Hello, \\u001b[31mJane\\u001b[39m!\\n\\nHow are you?\"\n * ```\n * @see dedent https://github.com/tamino-martinius/node-ts-dedent\n * @see chalk-template https://github.com/chalk/chalk-template\n */\n (template: TemplateStringsArray, ...values: unknown[]): void;\n\n /**\n * Configures print with options before printing the given template\n * string with dedent and chalk-template.\n *\n * @example\n * ```\n * let name = \"Jane\";\n * print({ ensureEmptyLineAbove: true })`Hello, ${name}!`;\n * // => \"\\nHello, Jane!\"\n *\n * print({ ensureEmptyLineAbove: true })`Hello, {red ${name}}!`;\n * // => \"\\nHello, \\u001b[31mJane\\u001b[39m!\"\n *\n * print({ ensureEmptyLineAbove: true })`\n * Hello, {red ${name}}!\n *\n * How are you?\n * `;\n * // => \"\\nHello, \\u001b[31mJane\\u001b[39m!\\n\\nHow are you?\"\n * ```\n * @see PrintOptions\n */\n (options: PrintOptions): print;\n};\n\nconst createPrint = (options: PrintOptions): print => {\n return ((templateOrOptions: PrintOptions | string | TemplateStringsArray, ...values: unknown[]): print | undefined => {\n if (isSprintOptions(templateOrOptions)) {\n return createPrint({ ...options, ...templateOrOptions });\n }\n\n const { json, ...sprintOptions } = options;\n\n if (config.logFormat === \"json\") {\n if (json) {\n output.writeStdout(JSON.stringify(json) + \"\\n\");\n }\n return;\n }\n\n const text = sprint(sprintOptions)(templateOrOptions as TemplateStringsArray, ...values);\n output.writeStdout(text);\n return;\n }) as print;\n};\n\nexport const print = createPrint({ ensureNewLine: false });\nexport const println = createPrint({ ensureNewLine: true });\n"],"names":["config","output","isSprintOptions","sprint","createPrint","options","templateOrOptions","values","json","sprintOptions","logFormat","writeStdout","JSON","stringify","text","print","ensureNewLine","println"],"mappings":"AAAA,SAASA,MAAM,QAAQ,sBAAsB;AAE7C,SAASC,MAAM,QAAQ,cAAc;AACrC,SAASC,eAAe,EAAEC,MAAM,QAA4B,cAAc;AAiF1E,MAAMC,cAAc,CAACC;IACnB,OAAQ,CAACC,mBAAiE,GAAGC;QAC3E,IAAIL,gBAAgBI,oBAAoB;YACtC,OAAOF,YAAY;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,iBAAiB;YAAC;QACxD;QAEA,MAAM,EAAEE,IAAI,EAAE,GAAGC,eAAe,GAAGJ;QAEnC,IAAIL,OAAOU,SAAS,KAAK,QAAQ;YAC/B,IAAIF,MAAM;gBACRP,OAAOU,WAAW,CAACC,KAAKC,SAAS,CAACL,QAAQ;YAC5C;YACA;QACF;QAEA,MAAMM,OAAOX,OAAOM,eAAeH,sBAA8CC;QACjFN,OAAOU,WAAW,CAACG;QACnB;IACF;AACF;AAEA,OAAO,MAAMC,QAAQX,YAAY;IAAEY,eAAe;AAAM,GAAG;AAC3D,OAAO,MAAMC,UAAUb,YAAY;IAAEY,eAAe;AAAK,GAAG"}
1
+ {"version":3,"sources":["../../../src/services/output/print.ts"],"sourcesContent":["import { config } from \"../config/config.js\";\nimport type { Field } from \"./log/field.js\";\nimport { output } from \"./output.js\";\nimport { isSprintOptions, sprint, type SprintOptions } from \"./sprint.js\";\n\nexport type PrintOptions = SprintOptions & {\n /**\n * What to print if --json was passed.\n *\n * @default undefined (print nothing)\n */\n json?: Field;\n};\n\nexport type print = {\n /**\n * Prints the given string as is.\n *\n * @param str - The string to print.\n * @example\n * print(\"Hello, world!\");\n * // => \"Hello, world!\"\n *\n * print(`\n * Hello, world!\n *\n * How are you?\n * `);\n * // => \"\\n Hello, world!\\n\\n How are you?\\n\"\n */\n (str: string): void;\n\n /**\n * Prints the given template string with dedent and chalk-template.\n *\n * @param template - The template string to format.\n * @param values - The values to interpolate into the template.\n * @example\n * ```\n * let name = \"Jane\";\n *\n * print`Hello, ${name}!`;\n * // => \"Hello, Jane!\"\n *\n * print`Hello, {red ${name}}!`;\n * // => \"Hello, \\u001b[31mJane\\u001b[39m!\"\n *\n * print`\n * Hello, {red ${name}}!\n *\n * How are you?\n * `;\n * // => \"Hello, \\u001b[31mJane\\u001b[39m!\\n\\nHow are you?\"\n * ```\n * @see dedent https://github.com/tamino-martinius/node-ts-dedent\n * @see chalk-template https://github.com/chalk/chalk-template\n */\n (template: TemplateStringsArray, ...values: unknown[]): void;\n\n /**\n * Configures print with options before printing the given template\n * string with dedent and chalk-template.\n *\n * @example\n * ```\n * let name = \"Jane\";\n * print({ ensureEmptyLineAbove: true })`Hello, ${name}!`;\n * // => \"\\nHello, Jane!\"\n *\n * print({ ensureEmptyLineAbove: true })`Hello, {red ${name}}!`;\n * // => \"\\nHello, \\u001b[31mJane\\u001b[39m!\"\n *\n * print({ ensureEmptyLineAbove: true })`\n * Hello, {red ${name}}!\n *\n * How are you?\n * `;\n * // => \"\\nHello, \\u001b[31mJane\\u001b[39m!\\n\\nHow are you?\"\n * ```\n * @see PrintOptions\n */\n (options: PrintOptions): print;\n};\n\nconst createPrint = (options: PrintOptions): print => {\n return ((templateOrOptions: PrintOptions | string | TemplateStringsArray, ...values: unknown[]): print | undefined => {\n if (isSprintOptions(templateOrOptions)) {\n return createPrint({ ...options, ...templateOrOptions });\n }\n\n const { json, ...sprintOptions } = options;\n\n if (config.logFormat === \"json\") {\n if (json) {\n output.writeStdout(JSON.stringify(json) + \"\\n\");\n }\n return;\n }\n\n const text = sprint(sprintOptions)(templateOrOptions as TemplateStringsArray, ...values);\n output.writeStdout(text);\n return;\n }) as print;\n};\n\nexport const print = createPrint({ ensureNewLine: false });\nexport const println = createPrint({ ensureNewLine: true });\n"],"names":["config","output","isSprintOptions","sprint","createPrint","options","templateOrOptions","values","json","sprintOptions","logFormat","writeStdout","JSON","stringify","text","print","ensureNewLine","println"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"AAAA,SAASA,MAAM,QAAQ,sBAAsB;AAE7C,SAASC,MAAM,QAAQ,cAAc;AACrC,SAASC,eAAe,EAAEC,MAAM,QAA4B,cAAc;AAiF1E,MAAMC,cAAc,CAACC;IACnB,OAAQ,CAACC,mBAAiE,GAAGC;QAC3E,IAAIL,gBAAgBI,oBAAoB;YACtC,OAAOF,YAAY;gBAAE,GAAGC,OAAO;gBAAE,GAAGC,iBAAiB;YAAC;QACxD;QAEA,MAAM,EAAEE,IAAI,EAAE,GAAGC,eAAe,GAAGJ;QAEnC,IAAIL,OAAOU,SAAS,KAAK,QAAQ;YAC/B,IAAIF,MAAM;gBACRP,OAAOU,WAAW,CAACC,KAAKC,SAAS,CAACL,QAAQ;YAC5C;YACA;QACF;QAEA,MAAMM,OAAOX,OAAOM,eAAeH,sBAA8CC;QACjFN,OAAOU,WAAW,CAACG;QACnB;IACF;AACF;AAEA,OAAO,MAAMC,QAAQX,YAAY;IAAEY,eAAe;AAAM,GAAG;AAC3D,OAAO,MAAMC,UAAUb,YAAY;IAAEY,eAAe;AAAK,GAAG"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/problems.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport pluralize from \"pluralize\";\nimport type { Problem as FileSyncProblem, PublishIssue } from \"../../__generated__/graphql.js\";\nimport { compact } from \"../util/collection.js\";\nimport { isGellyFile, isJavaScriptFile, isTypeScriptFile } from \"../util/is.js\";\nimport { println } from \"./print.js\";\nimport { sprint, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type Problems = Record<string, Problem[]>;\n\nexport type Problem = {\n type: string;\n severity: ProblemSeverity;\n message: string;\n labels: string[];\n};\n\nexport const ProblemSeverity = Object.freeze({\n Fatal: \"Fatal\",\n Error: \"Error\",\n Warning: \"Warning\",\n Info: \"Info\",\n});\n\nexport type ProblemSeverity = keyof typeof ProblemSeverity;\n\nexport type PrintProblemsOptions = SprintOptions & {\n /**\n * The problems to print.\n */\n problems: Problems;\n\n /**\n * Whether to show the file type in the output.\n *\n * @default problem.type === \"SourceFile\"\n */\n showFileTypes?: boolean;\n};\n\nexport const sprintProblems = ({ problems: groupedProblems, showFileTypes, ...sprintOptions }: PrintProblemsOptions): string => {\n let output = \"\";\n\n for (const [name, problems] of Object.entries(groupedProblems)) {\n output += sprintln(\"\");\n output += sprintln`• {cyan ${name}} {redBright ${pluralize(\"problem\", problems.length, true)}}`;\n for (const problem of problems) {\n const [message, ...lines] = problem.message.split(\"\\n\") as [string, ...string[]];\n\n output += sprint` {red ✖} `;\n if (showFileTypes ?? problem.type === \"SourceFile\") {\n output += sprint`${filetype(name)} `;\n }\n output += sprint(message);\n\n for (const line of lines) {\n output += sprintln(\"\");\n output += sprint` ${line}`;\n }\n\n for (const label of problem.labels) {\n output += sprint` {dim ${label}}`;\n }\n\n output += sprintln(\"\");\n }\n }\n\n return sprintln(sprintOptions)(output);\n};\n\nexport const printProblems = (options: PrintProblemsOptions): void => {\n println(sprintProblems(options));\n};\n\nexport const filetype = (filename: string): string => {\n switch (true) {\n case isJavaScriptFile(filename):\n return chalk.yellowBright(\"JavaScript\");\n case isTypeScriptFile(filename):\n return chalk.blue(\"TypeScript\");\n case isGellyFile(filename):\n return chalk.magenta(\"Gelly\");\n default:\n return chalk.gray(\"File\");\n }\n};\n\nexport const publishIssuesToProblems = (issues: PublishIssue[]): Problems => {\n const problems: Problems = {};\n for (const issue of issues) {\n const name = issue.node?.apiIdentifier ?? issue.node?.name ?? \"Other\";\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n problems[name] ??= [];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n problems[name]!.push({\n type: issue.node?.type ?? \"Unknown\",\n severity: issue.severity as ProblemSeverity,\n message: issue.message,\n labels: compact(issue.nodeLabels?.map((label) => label?.identifier) ?? []),\n });\n }\n return problems;\n};\n\nexport const filesyncProblemsToProblems = (filesyncProblems: FileSyncProblem[]): Problems => {\n const problems: Problems = {};\n for (const filesyncProblem of filesyncProblems) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n problems[filesyncProblem.path] ??= [];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n problems[filesyncProblem.path]!.push({\n type: filesyncProblem.type,\n severity: filesyncProblem.level as ProblemSeverity,\n message: filesyncProblem.message,\n labels: [],\n });\n }\n return problems;\n};\n"],"names":["chalk","pluralize","compact","isGellyFile","isJavaScriptFile","isTypeScriptFile","println","sprint","sprintln","ProblemSeverity","Object","freeze","Fatal","Error","Warning","Info","sprintProblems","problems","groupedProblems","showFileTypes","sprintOptions","output","name","entries","length","problem","message","lines","split","type","filetype","line","label","labels","printProblems","options","filename","yellowBright","blue","magenta","gray","publishIssuesToProblems","issues","issue","node","apiIdentifier","push","severity","nodeLabels","map","identifier","filesyncProblemsToProblems","filesyncProblems","filesyncProblem","path","level"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/output/problems.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport pluralize from \"pluralize\";\nimport type { Problem as FileSyncProblem, PublishIssue } from \"../../__generated__/graphql.js\";\nimport { compact } from \"../util/collection.js\";\nimport { isGellyFile, isJavaScriptFile, isTypeScriptFile } from \"../util/is.js\";\nimport { println } from \"./print.js\";\nimport { sprint, sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport type Problems = Record<string, Problem[]>;\n\nexport type Problem = {\n type: string;\n severity: ProblemSeverity;\n message: string;\n labels: string[];\n};\n\nexport const ProblemSeverity = Object.freeze({\n Fatal: \"Fatal\",\n Error: \"Error\",\n Warning: \"Warning\",\n Info: \"Info\",\n});\n\nexport type ProblemSeverity = keyof typeof ProblemSeverity;\n\nexport type PrintProblemsOptions = SprintOptions & {\n /**\n * The problems to print.\n */\n problems: Problems;\n\n /**\n * Whether to show the file type in the output.\n *\n * @default problem.type === \"SourceFile\"\n */\n showFileTypes?: boolean;\n};\n\nexport const sprintProblems = ({ problems: groupedProblems, showFileTypes, ...sprintOptions }: PrintProblemsOptions): string => {\n let output = \"\";\n\n for (const [name, problems] of Object.entries(groupedProblems)) {\n output += sprintln(\"\");\n output += sprintln`• {cyan ${name}} {redBright ${pluralize(\"problem\", problems.length, true)}}`;\n for (const problem of problems) {\n const [message, ...lines] = problem.message.split(\"\\n\") as [string, ...string[]];\n\n output += sprint` {red ✖} `;\n if (showFileTypes ?? problem.type === \"SourceFile\") {\n output += sprint`${filetype(name)} `;\n }\n output += sprint(message);\n\n for (const line of lines) {\n output += sprintln(\"\");\n output += sprint` ${line}`;\n }\n\n for (const label of problem.labels) {\n output += sprint` {dim ${label}}`;\n }\n\n output += sprintln(\"\");\n }\n }\n\n return sprintln(sprintOptions)(output);\n};\n\nexport const printProblems = (options: PrintProblemsOptions): void => {\n println(sprintProblems(options));\n};\n\nexport const filetype = (filename: string): string => {\n switch (true) {\n case isJavaScriptFile(filename):\n return chalk.yellowBright(\"JavaScript\");\n case isTypeScriptFile(filename):\n return chalk.blue(\"TypeScript\");\n case isGellyFile(filename):\n return chalk.magenta(\"Gelly\");\n default:\n return chalk.gray(\"File\");\n }\n};\n\nexport const publishIssuesToProblems = (issues: PublishIssue[]): Problems => {\n const problems: Problems = {};\n for (const issue of issues) {\n const name = issue.node?.apiIdentifier ?? issue.node?.name ?? \"Other\";\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n problems[name] ??= [];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n problems[name]!.push({\n type: issue.node?.type ?? \"Unknown\",\n severity: issue.severity as ProblemSeverity,\n message: issue.message,\n labels: compact(issue.nodeLabels?.map((label) => label?.identifier) ?? []),\n });\n }\n return problems;\n};\n\nexport const filesyncProblemsToProblems = (filesyncProblems: FileSyncProblem[]): Problems => {\n const problems: Problems = {};\n for (const filesyncProblem of filesyncProblems) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n problems[filesyncProblem.path] ??= [];\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n problems[filesyncProblem.path]!.push({\n type: filesyncProblem.type,\n severity: filesyncProblem.level as ProblemSeverity,\n message: filesyncProblem.message,\n labels: [],\n });\n }\n return problems;\n};\n"],"names":["chalk","pluralize","compact","isGellyFile","isJavaScriptFile","isTypeScriptFile","println","sprint","sprintln","ProblemSeverity","Object","freeze","Fatal","Error","Warning","Info","sprintProblems","problems","groupedProblems","showFileTypes","sprintOptions","output","name","entries","length","problem","message","lines","split","type","filetype","line","label","labels","printProblems","options","filename","yellowBright","blue","magenta","gray","publishIssuesToProblems","issues","issue","node","apiIdentifier","push","severity","nodeLabels","map","identifier","filesyncProblemsToProblems","filesyncProblems","filesyncProblem","path","level"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/prompt.ts"],"sourcesContent":["import ansiEscapes from \"ansi-escapes\";\nimport assert from \"node:assert\";\nimport EventEmitter from \"node:events\";\nimport process from \"node:process\";\nimport readline from \"node:readline\";\nimport { output } from \"./output.js\";\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/prompt.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nexport class Prompt extends EventEmitter {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [action: string]: any; // (key: StdinKey) => void;\n\n static active = false;\n\n // state\n value: unknown = undefined;\n firstRender = true;\n done = false;\n closed = false;\n aborted = false;\n exited = false;\n\n // methods that rely on constructor closure\n close: () => void;\n\n constructor() {\n super();\n assert(!Prompt.active, \"only one prompt can be active at a time\");\n Prompt.active = true;\n\n const rl = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });\n readline.emitKeypressEvents(process.stdin, rl);\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n\n const isSelect = [\"SelectPrompt\"].includes(this.constructor.name);\n const keypress = (str: string, key: StdinKey): void => {\n const action = getPromptAction(key, isSelect);\n if (action === false) {\n this._(str, key);\n } else if (action && typeof this[action] === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n this[action](key);\n } else {\n this.bell();\n }\n };\n\n this.close = () => {\n process.stdin.removeListener(\"keypress\", keypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n\n rl.close();\n this.emit(this.aborted ? \"abort\" : this.exited ? \"exit\" : \"submit\", this.value);\n this.closed = true;\n Prompt.active = false;\n };\n\n process.stdin.on(\"keypress\", keypress);\n }\n\n _(_str: string, _key: StdinKey): void {\n // noop\n }\n\n onRender(): void {\n // noop\n }\n\n fire(): void {\n this.emit(\"state\", {\n value: this.value,\n aborted: this.aborted,\n exited: this.exited,\n });\n }\n\n bell(): void {\n output.writeStdout(ansiEscapes.beep);\n }\n\n render(): void {\n this.onRender();\n if (this.firstRender) {\n this.firstRender = false;\n }\n }\n}\n\nexport type PromptAction =\n | \"abort\"\n | \"exit\"\n | \"submit\"\n | \"next\"\n | \"nextPage\"\n | \"prevPage\"\n | \"home\"\n | \"end\"\n | \"up\"\n | \"down\"\n | \"right\"\n | \"left\"\n | \"reset\"\n | \"delete\"\n | \"deleteForward\"\n | \"first\"\n | \"last\";\n\nexport type StdinKey = {\n name: string;\n ctrl: boolean;\n meta: boolean;\n};\n\nconst getPromptAction = (key: StdinKey, isSelect: boolean): PromptAction | false | undefined => {\n if (key.meta && key.name !== \"escape\") {\n return;\n }\n\n if (key.ctrl) {\n switch (key.name) {\n case \"a\":\n return \"first\";\n case \"c\":\n case \"d\":\n return \"abort\";\n case \"e\":\n return \"last\";\n case \"g\":\n return \"reset\";\n }\n }\n\n if (isSelect) {\n if (key.name === \"j\") {\n return \"down\";\n }\n if (key.name === \"k\") {\n return \"up\";\n }\n }\n\n switch (key.name) {\n case \"return\":\n case \"enter\":\n return \"submit\";\n case \"backspace\":\n return \"delete\";\n case \"delete\":\n return \"deleteForward\";\n case \"abort\":\n return \"abort\";\n case \"escape\":\n return \"exit\";\n case \"tab\":\n return \"next\";\n case \"pagedown\":\n return \"nextPage\";\n case \"pageup\":\n return \"prevPage\";\n case \"home\":\n return \"home\";\n case \"end\":\n return \"end\";\n case \"up\":\n return \"up\";\n case \"down\":\n return \"down\";\n case \"right\":\n return \"right\";\n case \"left\":\n return \"left\";\n default:\n return false;\n }\n};\n\n/**\n * Determine what entries should be displayed on the screen, based on the\n * currently selected index and the maximum visible. Used in list-based\n * prompts like `select` and `multiselect`.\n *\n * @param cursor - the currently selected entry\n * @param total - the total entries available to display\n * @param [maxVisible] - the number of entries that can be displayed\n */\nexport const entriesToDisplay = (cursor: number, total: number, maxVisible: number): { startIndex: number; endIndex: number } => {\n maxVisible = maxVisible || total;\n\n let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));\n if (startIndex < 0) {\n startIndex = 0;\n }\n\n const endIndex = Math.min(startIndex + maxVisible, total);\n\n return { startIndex, endIndex };\n};\n"],"names":["ansiEscapes","assert","EventEmitter","process","readline","output","Prompt","_","_str","_key","onRender","fire","emit","value","aborted","exited","bell","writeStdout","beep","render","firstRender","constructor","undefined","done","closed","close","active","rl","createInterface","input","stdin","escapeCodeTimeout","emitKeypressEvents","isTTY","setRawMode","isSelect","includes","name","keypress","str","key","action","getPromptAction","removeListener","on","meta","ctrl","entriesToDisplay","cursor","total","maxVisible","startIndex","Math","min","floor","endIndex"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/output/prompt.ts"],"sourcesContent":["import ansiEscapes from \"ansi-escapes\";\nimport assert from \"node:assert\";\nimport EventEmitter from \"node:events\";\nimport process from \"node:process\";\nimport readline from \"node:readline\";\nimport { output } from \"./output.js\";\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/prompt.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nexport class Prompt extends EventEmitter {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [action: string]: any; // (key: StdinKey) => void;\n\n static active = false;\n\n // state\n value: unknown = undefined;\n firstRender = true;\n done = false;\n closed = false;\n aborted = false;\n exited = false;\n\n // methods that rely on constructor closure\n close: () => void;\n\n constructor() {\n super();\n assert(!Prompt.active, \"only one prompt can be active at a time\");\n Prompt.active = true;\n\n const rl = readline.createInterface({ input: process.stdin, escapeCodeTimeout: 50 });\n readline.emitKeypressEvents(process.stdin, rl);\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n }\n\n const isSelect = [\"SelectPrompt\"].includes(this.constructor.name);\n const keypress = (str: string, key: StdinKey): void => {\n const action = getPromptAction(key, isSelect);\n if (action === false) {\n this._(str, key);\n } else if (action && typeof this[action] === \"function\") {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n this[action](key);\n } else {\n this.bell();\n }\n };\n\n this.close = () => {\n process.stdin.removeListener(\"keypress\", keypress);\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n }\n\n rl.close();\n this.emit(this.aborted ? \"abort\" : this.exited ? \"exit\" : \"submit\", this.value);\n this.closed = true;\n Prompt.active = false;\n };\n\n process.stdin.on(\"keypress\", keypress);\n }\n\n _(_str: string, _key: StdinKey): void {\n // noop\n }\n\n onRender(): void {\n // noop\n }\n\n fire(): void {\n this.emit(\"state\", {\n value: this.value,\n aborted: this.aborted,\n exited: this.exited,\n });\n }\n\n bell(): void {\n output.writeStdout(ansiEscapes.beep);\n }\n\n render(): void {\n this.onRender();\n if (this.firstRender) {\n this.firstRender = false;\n }\n }\n}\n\nexport type PromptAction =\n | \"abort\"\n | \"exit\"\n | \"submit\"\n | \"next\"\n | \"nextPage\"\n | \"prevPage\"\n | \"home\"\n | \"end\"\n | \"up\"\n | \"down\"\n | \"right\"\n | \"left\"\n | \"reset\"\n | \"delete\"\n | \"deleteForward\"\n | \"first\"\n | \"last\";\n\nexport type StdinKey = {\n name: string;\n ctrl: boolean;\n meta: boolean;\n};\n\nconst getPromptAction = (key: StdinKey, isSelect: boolean): PromptAction | false | undefined => {\n if (key.meta && key.name !== \"escape\") {\n return;\n }\n\n if (key.ctrl) {\n switch (key.name) {\n case \"a\":\n return \"first\";\n case \"c\":\n case \"d\":\n return \"abort\";\n case \"e\":\n return \"last\";\n case \"g\":\n return \"reset\";\n }\n }\n\n if (isSelect) {\n if (key.name === \"j\") {\n return \"down\";\n }\n if (key.name === \"k\") {\n return \"up\";\n }\n }\n\n switch (key.name) {\n case \"return\":\n case \"enter\":\n return \"submit\";\n case \"backspace\":\n return \"delete\";\n case \"delete\":\n return \"deleteForward\";\n case \"abort\":\n return \"abort\";\n case \"escape\":\n return \"exit\";\n case \"tab\":\n return \"next\";\n case \"pagedown\":\n return \"nextPage\";\n case \"pageup\":\n return \"prevPage\";\n case \"home\":\n return \"home\";\n case \"end\":\n return \"end\";\n case \"up\":\n return \"up\";\n case \"down\":\n return \"down\";\n case \"right\":\n return \"right\";\n case \"left\":\n return \"left\";\n default:\n return false;\n }\n};\n\n/**\n * Determine what entries should be displayed on the screen, based on the\n * currently selected index and the maximum visible. Used in list-based\n * prompts like `select` and `multiselect`.\n *\n * @param cursor - the currently selected entry\n * @param total - the total entries available to display\n * @param [maxVisible] - the number of entries that can be displayed\n */\nexport const entriesToDisplay = (cursor: number, total: number, maxVisible: number): { startIndex: number; endIndex: number } => {\n maxVisible = maxVisible || total;\n\n let startIndex = Math.min(total - maxVisible, cursor - Math.floor(maxVisible / 2));\n if (startIndex < 0) {\n startIndex = 0;\n }\n\n const endIndex = Math.min(startIndex + maxVisible, total);\n\n return { startIndex, endIndex };\n};\n"],"names":["ansiEscapes","assert","EventEmitter","process","readline","output","Prompt","_","_str","_key","onRender","fire","emit","value","aborted","exited","bell","writeStdout","beep","render","firstRender","constructor","undefined","done","closed","close","active","rl","createInterface","input","stdin","escapeCodeTimeout","emitKeypressEvents","isTTY","setRawMode","isSelect","includes","name","keypress","str","key","action","getPromptAction","removeListener","on","meta","ctrl","entriesToDisplay","cursor","total","maxVisible","startIndex","Math","min","floor","endIndex"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/report.ts"],"sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport cleanStack from \"clean-stack\";\nimport ms from \"ms\";\nimport { randomUUID } from \"node:crypto\";\nimport os from \"node:os\";\nimport terminalLink from \"terminal-link\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\nimport { packageJson } from \"../config/package-json.js\";\nimport { isAbortError } from \"../util/is.js\";\nimport { serializeError } from \"../util/object.js\";\nimport { workspaceRoot } from \"../util/paths.js\";\nimport { println } from \"./print.js\";\nimport { sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport const reportErrorAndExit = async (ctx: Context, cause: unknown): Promise<never> => {\n if (isAbortError(cause)) {\n ctx.log.debug(\"aborting without reporting error\", { error: cause });\n return process.exit(1);\n }\n\n ctx.log.error(\"reporting error and exiting\", { error: cause });\n\n try {\n const error = GGTError.from(cause);\n error.print();\n\n if (error.isBug === IsBug.NO) {\n return undefined as never;\n }\n\n Sentry.captureException(error, {\n event_id: error.id,\n captureContext: {\n user: ctx.user && {\n id: String(ctx.user.id),\n email: ctx.user.email,\n username: ctx.user.name ?? undefined,\n },\n tags: {\n application_id: ctx.app?.id,\n arch: config.arch,\n bug: error.isBug,\n environment: env.value,\n platform: config.platform,\n shell: config.shell,\n version: packageJson.version,\n },\n contexts: {\n ctx: {\n argv: process.argv,\n args: ctx.args,\n },\n cause: error.cause ? serializeError(error.cause) : undefined,\n app: {\n app_name: packageJson.name,\n app_version: packageJson.version,\n },\n device: {\n name: os.hostname(),\n family: os.type(),\n arch: os.arch(),\n },\n runtime: {\n name: process.release.name,\n version: process.version,\n },\n },\n },\n });\n\n await Sentry.flush(ms(\"2s\"));\n } finally {\n process.exit(1);\n }\n};\n\nexport const installErrorHandlers = (ctx: Context): void => {\n ctx.log.debug(\"installing error handlers\");\n\n Sentry.init({\n dsn: \"https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266\",\n enabled: env.productionLike && (ctx.args[\"--telemetry\"] ?? false),\n release: packageJson.version,\n environment: packageJson.version.includes(\"experimental\") ? \"experimental\" : \"production\",\n });\n\n const handleError = (error: unknown) => void reportErrorAndExit(ctx, error);\n process.once(\"uncaughtException\", handleError);\n process.once(\"unhandledRejection\", handleError);\n};\n\nexport const IsBug = Object.freeze({\n YES: \"yes\",\n NO: \"no\",\n MAYBE: \"maybe\",\n});\n\nexport type IsBug = (typeof IsBug)[keyof typeof IsBug];\n\n/**\n * Base class for all errors.\n */\nexport abstract class GGTError extends Error {\n /**\n * The ID for this error.\n */\n id = env.testLike ? \"00000000-0000-0000-0000-000000000000\" : randomUUID();\n\n /**\n * The underlying *thing* that caused this error.\n */\n cause?: unknown;\n\n /**\n * Assume the stack trace exists.\n */\n override stack!: string;\n\n /**\n * Indicates whether this error is considered a bug or not.\n */\n abstract isBug: IsBug;\n\n constructor(message: string) {\n super(message);\n Error.captureStackTrace(this, this.constructor);\n this.stack = cleanStack(this.stack, { pretty: true, basePath: workspaceRoot });\n }\n\n /**\n * Constructs a GGTError from an unknown cause.\n *\n * @param cause - The cause of the error.\n */\n static from(cause: unknown): GGTError {\n if (cause instanceof GGTError) {\n return cause;\n }\n return new UnexpectedError(cause);\n }\n\n sprint(): string {\n let rendered = this.render();\n\n if (this.isBug !== IsBug.NO) {\n // ensure the rendered message ends with a newline\n rendered = sprintln(rendered);\n\n const thisIsABug = this.isBug === IsBug.YES ? \"This is a bug\" : \"If you think this is a bug\";\n const issueLink = `https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}`;\n\n if (terminalLink.isSupported) {\n rendered += sprintln({ ensureEmptyLineAbove: true })`\n ${thisIsABug}, ${terminalLink(\"click here\", issueLink)} to create an issue on GitHub.\n `;\n } else {\n rendered += sprintln({ ensureEmptyLineAbove: true })`\n ${thisIsABug}, use the link below to create an issue on GitHub.\n\n ${issueLink}\n `;\n }\n }\n\n return rendered;\n }\n\n print(options?: SprintOptions): void {\n println({ ensureEmptyLineAbove: true, ...options })(this.sprint());\n }\n\n /**\n * Turns this error into a user-friendly message that explains what\n * went wrong and how to fix it. A good write up of what an error\n * should look like can be found here:\n * {@link https://clig.dev/#errors}\n */\n protected abstract render(): string;\n}\n\n/**\n * Our \"catch all\" error.\n *\n * If this error is thrown, we almost certainly have a bug, and should\n * either fix it or add a more specific error so that we can provide\n * more useful information.\n */\nexport class UnexpectedError extends GGTError {\n isBug = IsBug.YES;\n\n constructor(override cause: unknown) {\n super(\"An unexpected error occurred\");\n }\n\n protected render(): string {\n const serialized = serializeError(this.cause);\n const body = serialized.stack || serialized.message || this.stack;\n return this.message + \".\\n\\n\" + body;\n }\n}\n\n/**\n * An error that is expected to happen sometimes.\n */\nexport class EdgeCaseError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(\n message: string,\n override cause?: unknown,\n ) {\n super(message);\n }\n\n protected render(): string {\n return this.message;\n }\n}\n"],"names":["Sentry","cleanStack","ms","randomUUID","os","terminalLink","config","env","packageJson","isAbortError","serializeError","workspaceRoot","println","sprintln","reportErrorAndExit","ctx","cause","log","debug","error","process","exit","GGTError","from","print","isBug","IsBug","NO","undefined","captureException","event_id","id","captureContext","user","String","email","username","name","tags","application_id","app","arch","bug","environment","value","platform","shell","version","contexts","argv","args","app_name","app_version","device","hostname","family","type","runtime","release","flush","installErrorHandlers","init","dsn","enabled","productionLike","includes","handleError","once","Object","freeze","YES","MAYBE","Error","UnexpectedError","sprint","rendered","render","thisIsABug","issueLink","isSupported","ensureEmptyLineAbove","options","constructor","message","testLike","stack","captureStackTrace","pretty","basePath","serialized","body","EdgeCaseError"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/output/report.ts"],"sourcesContent":["import * as Sentry from \"@sentry/node\";\nimport cleanStack from \"clean-stack\";\nimport ms from \"ms\";\nimport { randomUUID } from \"node:crypto\";\nimport os from \"node:os\";\nimport terminalLink from \"terminal-link\";\nimport type { Context } from \"../command/context.js\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\nimport { packageJson } from \"../config/package-json.js\";\nimport { isAbortError } from \"../util/is.js\";\nimport { serializeError } from \"../util/object.js\";\nimport { workspaceRoot } from \"../util/paths.js\";\nimport { println } from \"./print.js\";\nimport { sprintln, type SprintOptions } from \"./sprint.js\";\n\nexport const reportErrorAndExit = async (ctx: Context, cause: unknown): Promise<never> => {\n if (isAbortError(cause)) {\n ctx.log.debug(\"aborting without reporting error\", { error: cause });\n return process.exit(1);\n }\n\n ctx.log.error(\"reporting error and exiting\", { error: cause });\n\n try {\n const error = GGTError.from(cause);\n error.print();\n\n if (error.isBug === IsBug.NO) {\n return undefined as never;\n }\n\n Sentry.captureException(error, {\n event_id: error.id,\n captureContext: {\n user: ctx.user && {\n id: String(ctx.user.id),\n email: ctx.user.email,\n username: ctx.user.name ?? undefined,\n },\n tags: {\n application_id: ctx.app?.id,\n arch: config.arch,\n bug: error.isBug,\n environment: env.value,\n platform: config.platform,\n shell: config.shell,\n version: packageJson.version,\n },\n contexts: {\n ctx: {\n argv: process.argv,\n args: ctx.args,\n },\n cause: error.cause ? serializeError(error.cause) : undefined,\n app: {\n app_name: packageJson.name,\n app_version: packageJson.version,\n },\n device: {\n name: os.hostname(),\n family: os.type(),\n arch: os.arch(),\n },\n runtime: {\n name: process.release.name,\n version: process.version,\n },\n },\n },\n });\n\n await Sentry.flush(ms(\"2s\"));\n } finally {\n process.exit(1);\n }\n};\n\nexport const installErrorHandlers = (ctx: Context): void => {\n ctx.log.debug(\"installing error handlers\");\n\n Sentry.init({\n dsn: \"https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266\",\n enabled: env.productionLike && (ctx.args[\"--telemetry\"] ?? false),\n release: packageJson.version,\n environment: packageJson.version.includes(\"experimental\") ? \"experimental\" : \"production\",\n });\n\n const handleError = (error: unknown) => void reportErrorAndExit(ctx, error);\n process.once(\"uncaughtException\", handleError);\n process.once(\"unhandledRejection\", handleError);\n};\n\nexport const IsBug = Object.freeze({\n YES: \"yes\",\n NO: \"no\",\n MAYBE: \"maybe\",\n});\n\nexport type IsBug = (typeof IsBug)[keyof typeof IsBug];\n\n/**\n * Base class for all errors.\n */\nexport abstract class GGTError extends Error {\n /**\n * The ID for this error.\n */\n id = env.testLike ? \"00000000-0000-0000-0000-000000000000\" : randomUUID();\n\n /**\n * The underlying *thing* that caused this error.\n */\n cause?: unknown;\n\n /**\n * Assume the stack trace exists.\n */\n override stack!: string;\n\n /**\n * Indicates whether this error is considered a bug or not.\n */\n abstract isBug: IsBug;\n\n constructor(message: string) {\n super(message);\n Error.captureStackTrace(this, this.constructor);\n this.stack = cleanStack(this.stack, { pretty: true, basePath: workspaceRoot });\n }\n\n /**\n * Constructs a GGTError from an unknown cause.\n *\n * @param cause - The cause of the error.\n */\n static from(cause: unknown): GGTError {\n if (cause instanceof GGTError) {\n return cause;\n }\n return new UnexpectedError(cause);\n }\n\n sprint(): string {\n let rendered = this.render();\n\n if (this.isBug !== IsBug.NO) {\n // ensure the rendered message ends with a newline\n rendered = sprintln(rendered);\n\n const thisIsABug = this.isBug === IsBug.YES ? \"This is a bug\" : \"If you think this is a bug\";\n const issueLink = `https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}`;\n\n if (terminalLink.isSupported) {\n rendered += sprintln({ ensureEmptyLineAbove: true })`\n ${thisIsABug}, ${terminalLink(\"click here\", issueLink)} to create an issue on GitHub.\n `;\n } else {\n rendered += sprintln({ ensureEmptyLineAbove: true })`\n ${thisIsABug}, use the link below to create an issue on GitHub.\n\n ${issueLink}\n `;\n }\n }\n\n return rendered;\n }\n\n print(options?: SprintOptions): void {\n println({ ensureEmptyLineAbove: true, ...options })(this.sprint());\n }\n\n /**\n * Turns this error into a user-friendly message that explains what\n * went wrong and how to fix it. A good write up of what an error\n * should look like can be found here:\n * {@link https://clig.dev/#errors}\n */\n protected abstract render(): string;\n}\n\n/**\n * Our \"catch all\" error.\n *\n * If this error is thrown, we almost certainly have a bug, and should\n * either fix it or add a more specific error so that we can provide\n * more useful information.\n */\nexport class UnexpectedError extends GGTError {\n isBug = IsBug.YES;\n\n constructor(override cause: unknown) {\n super(\"An unexpected error occurred\");\n }\n\n protected render(): string {\n const serialized = serializeError(this.cause);\n const body = serialized.stack || serialized.message || this.stack;\n return this.message + \".\\n\\n\" + body;\n }\n}\n\n/**\n * An error that is expected to happen sometimes.\n */\nexport class EdgeCaseError extends GGTError {\n isBug = IsBug.MAYBE;\n\n constructor(\n message: string,\n override cause?: unknown,\n ) {\n super(message);\n }\n\n protected render(): string {\n return this.message;\n }\n}\n"],"names":["Sentry","cleanStack","ms","randomUUID","os","terminalLink","config","env","packageJson","isAbortError","serializeError","workspaceRoot","println","sprintln","reportErrorAndExit","ctx","cause","log","debug","error","process","exit","GGTError","from","print","isBug","IsBug","NO","undefined","captureException","event_id","id","captureContext","user","String","email","username","name","tags","application_id","app","arch","bug","environment","value","platform","shell","version","contexts","argv","args","app_name","app_version","device","hostname","family","type","runtime","release","flush","installErrorHandlers","init","dsn","enabled","productionLike","includes","handleError","once","Object","freeze","YES","MAYBE","Error","UnexpectedError","sprint","rendered","render","thisIsABug","issueLink","isSupported","ensureEmptyLineAbove","options","constructor","message","testLike","stack","captureStackTrace","pretty","basePath","serialized","body","EdgeCaseError"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/services/output/select.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport indentString from \"indent-string\";\nimport assert from \"node:assert\";\nimport process from \"node:process\";\nimport { isString } from \"../util/is.js\";\nimport { defaults } from \"../util/object.js\";\nimport { output } from \"./output.js\";\nimport { println } from \"./print.js\";\nimport { entriesToDisplay, Prompt, type StdinKey } from \"./prompt.js\";\nimport { sprint, sprintln, type SprintOptions } from \"./sprint.js\";\nimport { symbol } from \"./symbols.js\";\n\nexport type SelectOptions<Choice extends string> = SprintOptions & {\n choices: Choice[];\n formatChoice?: (choice: Choice) => string;\n formatSelection?: (choice: Choice) => string;\n};\n\nexport type select<Choice extends string> = (options: SelectOptions<Choice>) => selectWithChoices<Choice>;\n\nexport type selectWithChoices<Choice extends string> = {\n (str: string): Promise<Choice>;\n (template: TemplateStringsArray, ...values: unknown[]): Promise<Choice>;\n};\n\n// TODO: i regret this api... don't make it the same as println... just make it take ctx and options\nexport const select = <Choice extends string>(options: SelectOptions<Choice>): selectWithChoices<Choice> => {\n options = defaults(options, {\n ensureEmptyLineAbove: true,\n });\n\n return ((template: string | TemplateStringsArray, ...values: unknown[]): Promise<Choice> => {\n let text = template as string;\n if (!isString(text)) {\n text = sprint(template as TemplateStringsArray, ...values);\n }\n\n if (!output.isInteractive) {\n // TODO: log an error here\n println(options)(text);\n println({ ensureEmptyLineAbove: true })`\n Aborting because ggt is not running in an interactive terminal.\n `;\n process.exit(1);\n }\n\n return new Promise((resolve) => {\n const sel = new Select(text, {\n formatChoice: (choice) => choice,\n formatSelection: (choice) => choice,\n ...options,\n });\n sel.on(\"submit\", resolve);\n sel.on(\"exit\", () => process.exit(0));\n sel.on(\"abort\", () => process.exit(0));\n });\n }) as selectWithChoices<Choice>;\n};\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/select.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n// TODO: implement autocomplete https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/autocomplete.js\nclass Select<Choice extends string> extends Prompt {\n cursor = 0;\n optionsPerPage = 10;\n options;\n\n constructor(\n readonly text: string,\n options: SelectOptions<Choice>,\n ) {\n super();\n\n this.options = defaults(options, {\n formatChoice: (choice) => choice,\n formatSelection: (choice) => choice,\n ...options,\n });\n\n if (this.options.ensureEmptyLineAbove) {\n this.text = \"\\n\" + this.text;\n }\n\n this.render();\n }\n\n get selection(): Choice {\n const choice = this.options.choices[this.cursor];\n assert(choice, `choices[${this.cursor}] is not defined`);\n return choice;\n }\n\n moveCursor(n: number): void {\n this.cursor = n;\n this.fire();\n }\n\n reset(): void {\n this.moveCursor(0);\n this.fire();\n this.render();\n }\n\n exit(): void {\n this.abort();\n }\n\n abort(): void {\n this.done = this.aborted = true;\n this.fire();\n this.render(\"Cancel (Ctrl+C)\" as Choice);\n this.close();\n }\n\n submit(): void {\n this.done = true;\n this.aborted = false;\n this.value = this.selection;\n this.fire();\n this.render();\n this.close();\n }\n\n first(): void {\n this.moveCursor(0);\n this.render();\n }\n\n last(): void {\n this.moveCursor(this.options.choices.length - 1);\n this.render();\n }\n\n up(): void {\n if (this.cursor === 0) {\n this.moveCursor(this.options.choices.length - 1);\n } else {\n this.moveCursor(this.cursor - 1);\n }\n this.render();\n }\n\n down(): void {\n if (this.cursor === this.options.choices.length - 1) {\n this.moveCursor(0);\n } else {\n this.moveCursor(this.cursor + 1);\n }\n this.render();\n }\n\n next(): void {\n this.moveCursor((this.cursor + 1) % this.options.choices.length);\n this.render();\n }\n\n override _(char: string, _key: StdinKey): void {\n if (char === \" \") {\n this.submit();\n return;\n }\n }\n\n override render(selection?: Choice): void {\n if (this.closed) {\n return;\n }\n\n super.render();\n\n let question = this.text;\n if (this.done) {\n output.persistPrompt(sprintln`\n ${question.trimEnd()} ${this.options.formatChoice(selection ?? this.selection)}\n `);\n return;\n }\n\n question += ` ${chalk.gray(\"Use arrow keys to move\")}\\n\\n`;\n\n let choices = \"\";\n const { startIndex, endIndex } = entriesToDisplay(this.cursor, this.options.choices.length, this.optionsPerPage);\n for (let index = startIndex; index < endIndex; index++) {\n // determine whether to display \"more choices\" indicators\n let prefix: string;\n if (this.cursor === index) {\n prefix = `${symbol.arrowRight} `;\n } else if (index === startIndex && startIndex > 0) {\n prefix = `${symbol.arrowUp} `;\n } else if (index === endIndex - 1 && endIndex < this.options.choices.length) {\n prefix = `${symbol.arrowDown} `;\n } else {\n prefix = \" \";\n }\n\n const choice_ = this.options.choices[index];\n assert(choice_, `choices[${index}] is not defined`);\n\n let choice = this.options.formatChoice(choice_);\n if (this.cursor === index) {\n choice = chalk.blue.underline(choice);\n }\n\n choices += `${prefix}${choice}\\n`;\n }\n\n if (this.options.indent) {\n choices = indentString(choices, this.options.indent);\n }\n\n output.updatePrompt(question + choices);\n }\n}\n"],"names":["chalk","indentString","assert","process","isString","defaults","output","println","entriesToDisplay","Prompt","sprint","sprintln","symbol","select","options","ensureEmptyLineAbove","template","values","text","isInteractive","exit","Promise","resolve","sel","Select","formatChoice","choice","formatSelection","on","selection","choices","cursor","moveCursor","n","fire","reset","render","abort","done","aborted","close","submit","value","first","last","length","up","down","next","_","char","_key","closed","question","persistPrompt","trimEnd","gray","startIndex","endIndex","optionsPerPage","index","prefix","arrowRight","arrowUp","arrowDown","choice_","blue","underline","indent","updatePrompt","constructor"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/services/output/select.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport indentString from \"indent-string\";\nimport assert from \"node:assert\";\nimport process from \"node:process\";\nimport { isString } from \"../util/is.js\";\nimport { defaults } from \"../util/object.js\";\nimport { output } from \"./output.js\";\nimport { println } from \"./print.js\";\nimport { entriesToDisplay, Prompt, type StdinKey } from \"./prompt.js\";\nimport { sprint, sprintln, type SprintOptions } from \"./sprint.js\";\nimport { symbol } from \"./symbols.js\";\n\nexport type SelectOptions<Choice extends string> = SprintOptions & {\n choices: Choice[];\n formatChoice?: (choice: Choice) => string;\n formatSelection?: (choice: Choice) => string;\n};\n\nexport type select<Choice extends string> = (options: SelectOptions<Choice>) => selectWithChoices<Choice>;\n\nexport type selectWithChoices<Choice extends string> = {\n (str: string): Promise<Choice>;\n (template: TemplateStringsArray, ...values: unknown[]): Promise<Choice>;\n};\n\n// TODO: i regret this api... don't make it the same as println... just make it take ctx and options\nexport const select = <Choice extends string>(options: SelectOptions<Choice>): selectWithChoices<Choice> => {\n options = defaults(options, {\n ensureEmptyLineAbove: true,\n });\n\n return ((template: string | TemplateStringsArray, ...values: unknown[]): Promise<Choice> => {\n let text = template as string;\n if (!isString(text)) {\n text = sprint(template as TemplateStringsArray, ...values);\n }\n\n if (!output.isInteractive) {\n // TODO: log an error here\n println(options)(text);\n println({ ensureEmptyLineAbove: true })`\n Aborting because ggt is not running in an interactive terminal.\n `;\n process.exit(1);\n }\n\n return new Promise((resolve) => {\n const sel = new Select(text, {\n formatChoice: (choice) => choice,\n formatSelection: (choice) => choice,\n ...options,\n });\n sel.on(\"submit\", resolve);\n sel.on(\"exit\", () => process.exit(0));\n sel.on(\"abort\", () => process.exit(0));\n });\n }) as selectWithChoices<Choice>;\n};\n\n/**\n * Inspired by `prompts`:\n * https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/select.js\n *\n * MIT License\n *\n * Copyright (c) 2018 Terkel Gjervig Nielsen\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n// TODO: implement autocomplete https://github.com/terkelg/prompts/blob/e0519913ec4fcc6746bb3d97d8cd0960c3f3ffde/lib/elements/autocomplete.js\nclass Select<Choice extends string> extends Prompt {\n cursor = 0;\n optionsPerPage = 10;\n options;\n\n constructor(\n readonly text: string,\n options: SelectOptions<Choice>,\n ) {\n super();\n\n this.options = defaults(options, {\n formatChoice: (choice) => choice,\n formatSelection: (choice) => choice,\n ...options,\n });\n\n if (this.options.ensureEmptyLineAbove) {\n this.text = \"\\n\" + this.text;\n }\n\n this.render();\n }\n\n get selection(): Choice {\n const choice = this.options.choices[this.cursor];\n assert(choice, `choices[${this.cursor}] is not defined`);\n return choice;\n }\n\n moveCursor(n: number): void {\n this.cursor = n;\n this.fire();\n }\n\n reset(): void {\n this.moveCursor(0);\n this.fire();\n this.render();\n }\n\n exit(): void {\n this.abort();\n }\n\n abort(): void {\n this.done = this.aborted = true;\n this.fire();\n this.render(\"Cancel (Ctrl+C)\" as Choice);\n this.close();\n }\n\n submit(): void {\n this.done = true;\n this.aborted = false;\n this.value = this.selection;\n this.fire();\n this.render();\n this.close();\n }\n\n first(): void {\n this.moveCursor(0);\n this.render();\n }\n\n last(): void {\n this.moveCursor(this.options.choices.length - 1);\n this.render();\n }\n\n up(): void {\n if (this.cursor === 0) {\n this.moveCursor(this.options.choices.length - 1);\n } else {\n this.moveCursor(this.cursor - 1);\n }\n this.render();\n }\n\n down(): void {\n if (this.cursor === this.options.choices.length - 1) {\n this.moveCursor(0);\n } else {\n this.moveCursor(this.cursor + 1);\n }\n this.render();\n }\n\n next(): void {\n this.moveCursor((this.cursor + 1) % this.options.choices.length);\n this.render();\n }\n\n override _(char: string, _key: StdinKey): void {\n if (char === \" \") {\n this.submit();\n return;\n }\n }\n\n override render(selection?: Choice): void {\n if (this.closed) {\n return;\n }\n\n super.render();\n\n let question = this.text;\n if (this.done) {\n output.persistPrompt(sprintln`\n ${question.trimEnd()} ${this.options.formatChoice(selection ?? this.selection)}\n `);\n return;\n }\n\n question += ` ${chalk.gray(\"Use arrow keys to move\")}\\n\\n`;\n\n let choices = \"\";\n const { startIndex, endIndex } = entriesToDisplay(this.cursor, this.options.choices.length, this.optionsPerPage);\n for (let index = startIndex; index < endIndex; index++) {\n // determine whether to display \"more choices\" indicators\n let prefix: string;\n if (this.cursor === index) {\n prefix = `${symbol.arrowRight} `;\n } else if (index === startIndex && startIndex > 0) {\n prefix = `${symbol.arrowUp} `;\n } else if (index === endIndex - 1 && endIndex < this.options.choices.length) {\n prefix = `${symbol.arrowDown} `;\n } else {\n prefix = \" \";\n }\n\n const choice_ = this.options.choices[index];\n assert(choice_, `choices[${index}] is not defined`);\n\n let choice = this.options.formatChoice(choice_);\n if (this.cursor === index) {\n choice = chalk.blue.underline(choice);\n }\n\n choices += `${prefix}${choice}\\n`;\n }\n\n if (this.options.indent) {\n choices = indentString(choices, this.options.indent);\n }\n\n output.updatePrompt(question + choices);\n }\n}\n"],"names":["chalk","indentString","assert","process","isString","defaults","output","println","entriesToDisplay","Prompt","sprint","sprintln","symbol","select","options","ensureEmptyLineAbove","template","values","text","isInteractive","exit","Promise","resolve","sel","Select","formatChoice","choice","formatSelection","on","selection","choices","cursor","moveCursor","n","fire","reset","render","abort","done","aborted","close","submit","value","first","last","length","up","down","next","_","char","_key","closed","question","persistPrompt","trimEnd","gray","startIndex","endIndex","optionsPerPage","index","prefix","arrowRight","arrowUp","arrowDown","choice_","blue","underline","indent","updatePrompt","constructor"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":";AAAA,OAAOA,WAAW,QAAQ;AAC1B,OAAOC,kBAAkB,gBAAgB;AACzC,OAAOC,YAAY,cAAc;AACjC,OAAOC,aAAa,eAAe;AACnC,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,SAASC,QAAQ,QAAQ,oBAAoB;AAC7C,SAASC,MAAM,QAAQ,cAAc;AACrC,SAASC,OAAO,QAAQ,aAAa;AACrC,SAASC,gBAAgB,EAAEC,MAAM,QAAuB,cAAc;AACtE,SAASC,MAAM,EAAEC,QAAQ,QAA4B,cAAc;AACnE,SAASC,MAAM,QAAQ,eAAe;AAetC,oGAAoG;AACpG,OAAO,MAAMC,SAAS,CAAwBC;IAC5CA,UAAUT,SAASS,SAAS;QAC1BC,sBAAsB;IACxB;IAEA,OAAQ,CAACC,UAAyC,GAAGC;QACnD,IAAIC,OAAOF;QACX,IAAI,CAACZ,SAASc,OAAO;YACnBA,OAAOR,OAAOM,aAAqCC;QACrD;QAEA,IAAI,CAACX,OAAOa,aAAa,EAAE;YACzB,0BAA0B;YAC1BZ,QAAQO,SAASI;YACjBX,QAAQ;gBAAEQ,sBAAsB;YAAK,EAAE,CAAC;;MAExC,CAAC;YACDZ,QAAQiB,IAAI,CAAC;QACf;QAEA,OAAO,IAAIC,QAAQ,CAACC;YAClB,MAAMC,MAAM,IAAIC,OAAON,MAAM;gBAC3BO,cAAc,CAACC,SAAWA;gBAC1BC,iBAAiB,CAACD,SAAWA;gBAC7B,GAAGZ,OAAO;YACZ;YACAS,IAAIK,EAAE,CAAC,UAAUN;YACjBC,IAAIK,EAAE,CAAC,QAAQ,IAAMzB,QAAQiB,IAAI,CAAC;YAClCG,IAAIK,EAAE,CAAC,SAAS,IAAMzB,QAAQiB,IAAI,CAAC;QACrC;IACF;AACF,EAAE;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,6IAA6I;AAC7I,MAAMI,eAAsCf;IAwB1C,IAAIoB,YAAoB;QACtB,MAAMH,SAAS,IAAI,CAACZ,OAAO,CAACgB,OAAO,CAAC,IAAI,CAACC,MAAM,CAAC;QAChD7B,OAAOwB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAACK,MAAM,CAAC,gBAAgB,CAAC;QACvD,OAAOL;IACT;IAEAM,WAAWC,CAAS,EAAQ;QAC1B,IAAI,CAACF,MAAM,GAAGE;QACd,IAAI,CAACC,IAAI;IACX;IAEAC,QAAc;QACZ,IAAI,CAACH,UAAU,CAAC;QAChB,IAAI,CAACE,IAAI;QACT,IAAI,CAACE,MAAM;IACb;IAEAhB,OAAa;QACX,IAAI,CAACiB,KAAK;IACZ;IAEAA,QAAc;QACZ,IAAI,CAACC,IAAI,GAAG,IAAI,CAACC,OAAO,GAAG;QAC3B,IAAI,CAACL,IAAI;QACT,IAAI,CAACE,MAAM,CAAC;QACZ,IAAI,CAACI,KAAK;IACZ;IAEAC,SAAe;QACb,IAAI,CAACH,IAAI,GAAG;QACZ,IAAI,CAACC,OAAO,GAAG;QACf,IAAI,CAACG,KAAK,GAAG,IAAI,CAACb,SAAS;QAC3B,IAAI,CAACK,IAAI;QACT,IAAI,CAACE,MAAM;QACX,IAAI,CAACI,KAAK;IACZ;IAEAG,QAAc;QACZ,IAAI,CAACX,UAAU,CAAC;QAChB,IAAI,CAACI,MAAM;IACb;IAEAQ,OAAa;QACX,IAAI,CAACZ,UAAU,CAAC,IAAI,CAAClB,OAAO,CAACgB,OAAO,CAACe,MAAM,GAAG;QAC9C,IAAI,CAACT,MAAM;IACb;IAEAU,KAAW;QACT,IAAI,IAAI,CAACf,MAAM,KAAK,GAAG;YACrB,IAAI,CAACC,UAAU,CAAC,IAAI,CAAClB,OAAO,CAACgB,OAAO,CAACe,MAAM,GAAG;QAChD,OAAO;YACL,IAAI,CAACb,UAAU,CAAC,IAAI,CAACD,MAAM,GAAG;QAChC;QACA,IAAI,CAACK,MAAM;IACb;IAEAW,OAAa;QACX,IAAI,IAAI,CAAChB,MAAM,KAAK,IAAI,CAACjB,OAAO,CAACgB,OAAO,CAACe,MAAM,GAAG,GAAG;YACnD,IAAI,CAACb,UAAU,CAAC;QAClB,OAAO;YACL,IAAI,CAACA,UAAU,CAAC,IAAI,CAACD,MAAM,GAAG;QAChC;QACA,IAAI,CAACK,MAAM;IACb;IAEAY,OAAa;QACX,IAAI,CAAChB,UAAU,CAAC,AAAC,CAAA,IAAI,CAACD,MAAM,GAAG,CAAA,IAAK,IAAI,CAACjB,OAAO,CAACgB,OAAO,CAACe,MAAM;QAC/D,IAAI,CAACT,MAAM;IACb;IAESa,EAAEC,IAAY,EAAEC,IAAc,EAAQ;QAC7C,IAAID,SAAS,KAAK;YAChB,IAAI,CAACT,MAAM;YACX;QACF;IACF;IAESL,OAAOP,SAAkB,EAAQ;QACxC,IAAI,IAAI,CAACuB,MAAM,EAAE;YACf;QACF;QAEA,KAAK,CAAChB;QAEN,IAAIiB,WAAW,IAAI,CAACnC,IAAI;QACxB,IAAI,IAAI,CAACoB,IAAI,EAAE;YACbhC,OAAOgD,aAAa,CAAC3C,QAAQ,CAAC;QAC5B,EAAE0C,SAASE,OAAO,GAAG,CAAC,EAAE,IAAI,CAACzC,OAAO,CAACW,YAAY,CAACI,aAAa,IAAI,CAACA,SAAS,EAAE;MACjF,CAAC;YACD;QACF;QAEAwB,YAAY,CAAC,CAAC,EAAErD,MAAMwD,IAAI,CAAC,0BAA0B,IAAI,CAAC;QAE1D,IAAI1B,UAAU;QACd,MAAM,EAAE2B,UAAU,EAAEC,QAAQ,EAAE,GAAGlD,iBAAiB,IAAI,CAACuB,MAAM,EAAE,IAAI,CAACjB,OAAO,CAACgB,OAAO,CAACe,MAAM,EAAE,IAAI,CAACc,cAAc;QAC/G,IAAK,IAAIC,QAAQH,YAAYG,QAAQF,UAAUE,QAAS;YACtD,yDAAyD;YACzD,IAAIC;YACJ,IAAI,IAAI,CAAC9B,MAAM,KAAK6B,OAAO;gBACzBC,SAAS,CAAC,EAAEjD,OAAOkD,UAAU,CAAC,CAAC,CAAC;YAClC,OAAO,IAAIF,UAAUH,cAAcA,aAAa,GAAG;gBACjDI,SAAS,CAAC,EAAEjD,OAAOmD,OAAO,CAAC,CAAC,CAAC;YAC/B,OAAO,IAAIH,UAAUF,WAAW,KAAKA,WAAW,IAAI,CAAC5C,OAAO,CAACgB,OAAO,CAACe,MAAM,EAAE;gBAC3EgB,SAAS,CAAC,EAAEjD,OAAOoD,SAAS,CAAC,CAAC,CAAC;YACjC,OAAO;gBACLH,SAAS;YACX;YAEA,MAAMI,UAAU,IAAI,CAACnD,OAAO,CAACgB,OAAO,CAAC8B,MAAM;YAC3C1D,OAAO+D,SAAS,CAAC,QAAQ,EAAEL,MAAM,gBAAgB,CAAC;YAElD,IAAIlC,SAAS,IAAI,CAACZ,OAAO,CAACW,YAAY,CAACwC;YACvC,IAAI,IAAI,CAAClC,MAAM,KAAK6B,OAAO;gBACzBlC,SAAS1B,MAAMkE,IAAI,CAACC,SAAS,CAACzC;YAChC;YAEAI,WAAW,CAAC,EAAE+B,OAAO,EAAEnC,OAAO,EAAE,CAAC;QACnC;QAEA,IAAI,IAAI,CAACZ,OAAO,CAACsD,MAAM,EAAE;YACvBtC,UAAU7B,aAAa6B,SAAS,IAAI,CAAChB,OAAO,CAACsD,MAAM;QACrD;QAEA9D,OAAO+D,YAAY,CAAChB,WAAWvB;IACjC;IAhJAwC,YACE,AAASpD,IAAY,EACrBJ,OAA8B,CAC9B;QACA,KAAK;;QARPiB,uBAAAA,UAAAA,KAAAA;QACA4B,uBAAAA,kBAAAA,KAAAA;QACA7C,uBAAAA,WAAAA,KAAAA;aAGWI,OAAAA;aALXa,SAAS;aACT4B,iBAAiB;QASf,IAAI,CAAC7C,OAAO,GAAGT,SAASS,SAAS;YAC/BW,cAAc,CAACC,SAAWA;YAC1BC,iBAAiB,CAACD,SAAWA;YAC7B,GAAGZ,OAAO;QACZ;QAEA,IAAI,IAAI,CAACA,OAAO,CAACC,oBAAoB,EAAE;YACrC,IAAI,CAACG,IAAI,GAAG,OAAO,IAAI,CAACA,IAAI;QAC9B;QAEA,IAAI,CAACkB,MAAM;IACb;AAgIF"}