@gadgetinc/ggt 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +139 -76
  2. package/bin/dev.js +4 -7
  3. package/lib/__generated__/graphql.js.map +1 -1
  4. package/lib/commands/deploy.js +227 -0
  5. package/lib/commands/deploy.js.map +1 -0
  6. package/lib/commands/list.js +28 -21
  7. package/lib/commands/list.js.map +1 -1
  8. package/lib/commands/login.js +22 -20
  9. package/lib/commands/login.js.map +1 -1
  10. package/lib/commands/logout.js +13 -9
  11. package/lib/commands/logout.js.map +1 -1
  12. package/lib/commands/root.js +89 -56
  13. package/lib/commands/root.js.map +1 -1
  14. package/lib/commands/sync.js +256 -499
  15. package/lib/commands/sync.js.map +1 -1
  16. package/lib/commands/version.js +21 -0
  17. package/lib/commands/version.js.map +1 -0
  18. package/lib/commands/whoami.js +15 -11
  19. package/lib/commands/whoami.js.map +1 -1
  20. package/lib/main.js +4 -10
  21. package/lib/main.js.map +1 -1
  22. package/lib/services/{app.js → app/app.js} +9 -5
  23. package/lib/services/app/app.js.map +1 -0
  24. package/lib/services/app/arg.js +28 -0
  25. package/lib/services/app/arg.js.map +1 -0
  26. package/lib/services/app/edit-graphql.js +389 -0
  27. package/lib/services/app/edit-graphql.js.map +1 -0
  28. package/lib/services/command/arg.js +53 -0
  29. package/lib/services/command/arg.js.map +1 -0
  30. package/lib/services/command/command.js +27 -0
  31. package/lib/services/command/command.js.map +1 -0
  32. package/lib/services/command/context.js +60 -0
  33. package/lib/services/command/context.js.map +1 -0
  34. package/lib/services/{config.js → config/config.js} +32 -35
  35. package/lib/services/config/config.js.map +1 -0
  36. package/lib/services/config/env.js +22 -0
  37. package/lib/services/config/env.js.map +1 -0
  38. package/lib/services/config/package-json.js +9 -0
  39. package/lib/services/config/package-json.js.map +1 -0
  40. package/lib/services/filesync/changes.js +97 -0
  41. package/lib/services/filesync/changes.js.map +1 -0
  42. package/lib/services/filesync/conflicts.js +137 -0
  43. package/lib/services/filesync/conflicts.js.map +1 -0
  44. package/lib/services/filesync/directory.js +253 -0
  45. package/lib/services/filesync/directory.js.map +1 -0
  46. package/lib/services/filesync/error.js +67 -0
  47. package/lib/services/filesync/error.js.map +1 -0
  48. package/lib/services/filesync/file.js +3 -0
  49. package/lib/services/filesync/file.js.map +1 -0
  50. package/lib/services/filesync/filesync.js +675 -0
  51. package/lib/services/filesync/filesync.js.map +1 -0
  52. package/lib/services/filesync/hashes.js +150 -0
  53. package/lib/services/filesync/hashes.js.map +1 -0
  54. package/lib/services/http/auth.js +41 -0
  55. package/lib/services/http/auth.js.map +1 -0
  56. package/lib/services/http/http.js +64 -0
  57. package/lib/services/http/http.js.map +1 -0
  58. package/lib/services/output/log/field.js +3 -0
  59. package/lib/services/output/log/field.js.map +1 -0
  60. package/lib/services/output/log/format/format.js +8 -0
  61. package/lib/services/output/log/format/format.js.map +1 -0
  62. package/lib/services/output/log/format/json.js +45 -0
  63. package/lib/services/output/log/format/json.js.map +1 -0
  64. package/lib/services/output/log/format/pretty.js +147 -0
  65. package/lib/services/output/log/format/pretty.js.map +1 -0
  66. package/lib/services/output/log/level.js +41 -0
  67. package/lib/services/output/log/level.js.map +1 -0
  68. package/lib/services/output/log/logger.js +40 -0
  69. package/lib/services/output/log/logger.js.map +1 -0
  70. package/lib/services/output/log/printer.js +120 -0
  71. package/lib/services/output/log/printer.js.map +1 -0
  72. package/lib/services/output/log/structured.js +52 -0
  73. package/lib/services/output/log/structured.js.map +1 -0
  74. package/lib/services/{notify.js → output/notify.js} +7 -6
  75. package/lib/services/output/notify.js.map +1 -0
  76. package/lib/services/output/prompt.js +52 -0
  77. package/lib/services/output/prompt.js.map +1 -0
  78. package/lib/services/output/report.js +162 -0
  79. package/lib/services/output/report.js.map +1 -0
  80. package/lib/services/output/sprint.js +21 -0
  81. package/lib/services/output/sprint.js.map +1 -0
  82. package/lib/services/{output.js → output/stream.js} +18 -23
  83. package/lib/services/output/stream.js.map +1 -0
  84. package/lib/services/{version.js → output/update.js} +26 -18
  85. package/lib/services/output/update.js.map +1 -0
  86. package/lib/services/user/session.js +50 -0
  87. package/lib/services/user/session.js.map +1 -0
  88. package/lib/services/{user.js → user/user.js} +24 -17
  89. package/lib/services/user/user.js.map +1 -0
  90. package/lib/services/util/boolean.js +15 -0
  91. package/lib/services/util/boolean.js.map +1 -0
  92. package/lib/services/util/collection.js +38 -0
  93. package/lib/services/util/collection.js.map +1 -0
  94. package/lib/services/util/function.js +97 -0
  95. package/lib/services/util/function.js.map +1 -0
  96. package/lib/services/util/is.js +46 -0
  97. package/lib/services/util/is.js.map +1 -0
  98. package/lib/services/util/number.js +27 -0
  99. package/lib/services/util/number.js.map +1 -0
  100. package/lib/services/util/object.js +101 -0
  101. package/lib/services/util/object.js.map +1 -0
  102. package/lib/services/util/paths.js +36 -0
  103. package/lib/services/util/paths.js.map +1 -0
  104. package/lib/services/{promise.js → util/promise.js} +4 -4
  105. package/lib/services/util/promise.js.map +1 -0
  106. package/npm-shrinkwrap.json +2416 -1547
  107. package/package.json +52 -46
  108. package/lib/commands/index.js +0 -9
  109. package/lib/commands/index.js.map +0 -1
  110. package/lib/services/app.js.map +0 -1
  111. package/lib/services/args.js +0 -28
  112. package/lib/services/args.js.map +0 -1
  113. package/lib/services/config.js.map +0 -1
  114. package/lib/services/edit-graphql.js +0 -193
  115. package/lib/services/edit-graphql.js.map +0 -1
  116. package/lib/services/errors.js +0 -274
  117. package/lib/services/errors.js.map +0 -1
  118. package/lib/services/filesync.js +0 -404
  119. package/lib/services/filesync.js.map +0 -1
  120. package/lib/services/fs-utils.js +0 -33
  121. package/lib/services/fs-utils.js.map +0 -1
  122. package/lib/services/http.js +0 -53
  123. package/lib/services/http.js.map +0 -1
  124. package/lib/services/log.js +0 -45
  125. package/lib/services/log.js.map +0 -1
  126. package/lib/services/notify.js.map +0 -1
  127. package/lib/services/output.js.map +0 -1
  128. package/lib/services/promise.js.map +0 -1
  129. package/lib/services/session.js +0 -27
  130. package/lib/services/session.js.map +0 -1
  131. package/lib/services/sleep.js +0 -19
  132. package/lib/services/sleep.js.map +0 -1
  133. package/lib/services/timeout.js +0 -8
  134. package/lib/services/timeout.js.map +0 -1
  135. package/lib/services/user.js.map +0 -1
  136. package/lib/services/version.js.map +0 -1
@@ -0,0 +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 { 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 if (value.length > 10 && config.logLevel > Level.TRACE) {\n // truncate arrays to 10 elements when not tracing\n value = value.slice(0, 10);\n assert(Array.isArray(value));\n }\n\n value = Object.fromEntries(value.entries());\n }\n\n if (value instanceof Map) {\n value = Object.fromEntries(value.entries());\n }\n\n if (isObject(value)) {\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","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","TRACE","slice","fromEntries","Map","replaceAll","repeat","String","ts","format","DEBUG","INFO","WARN","ERROR","map"],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import assert from "node:assert";
2
+ import { z } from "zod";
3
+ import { MemoAllArgs, memo } from "../../util/function.js";
4
+ import { clamp } from "../../util/number.js";
5
+ export const Level = {
6
+ TRACE: 1,
7
+ DEBUG: 2,
8
+ INFO: 3,
9
+ WARN: 4,
10
+ ERROR: 5,
11
+ PRINT: 6
12
+ };
13
+ export const parseLevel = memo(MemoAllArgs, (value, defaultValue)=>{
14
+ let parsed = z.enum([
15
+ "TRACE",
16
+ "DEBUG",
17
+ "INFO",
18
+ "WARN",
19
+ "ERROR"
20
+ ]).transform((str)=>Level[str]).safeParse(String(value).toUpperCase());
21
+ if (!parsed.success) {
22
+ parsed = z.number().min(Level.TRACE).max(Level.ERROR).safeParse(Number(value));
23
+ }
24
+ return parsed.success ? parsed.data : defaultValue;
25
+ });
26
+ /**
27
+ * Converts a numeric verbosity value to a log level.
28
+ *
29
+ * @param verbosity - The verbosity value
30
+ * @returns The log level
31
+ * @example
32
+ * verbosityToLevel(1) // => Level.INFO
33
+ * verbosityToLevel(2) // => Level.DEBUG
34
+ * verbosityToLevel(3) // => Level.TRACE
35
+ * verbosityToLevel(Infinity) // => Level.TRACE
36
+ */ export const verbosityToLevel = (verbosity)=>{
37
+ assert(verbosity > 0, "verbosity must be greater than 0");
38
+ return clamp(Level.INFO + 1 - verbosity, Level.TRACE, Level.INFO);
39
+ };
40
+
41
+ //# sourceMappingURL=level.js.map
@@ -0,0 +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"}
@@ -0,0 +1,40 @@
1
+ import { unthunk } from "../../util/function.js";
2
+ import { createPrinter } from "./printer.js";
3
+ import { createStructuredLogger } from "./structured.js";
4
+ /**
5
+ * Creates a {@linkcode Logger} with the given name and fields.
6
+ *
7
+ * Use the {@linkcode Printer} methods to print messages to stdout for
8
+ * end users to read.
9
+ *
10
+ * Use the {@linkcode StructuredLogger} methods to print structured
11
+ * messages to stderr for developers to read. These messages are only
12
+ * printed when the `GGT_LOG_LEVEL` is greater than or equal to the
13
+ * level of the message.
14
+ *
15
+ * @example
16
+ * const logger = createLogger({ name: "my-logger" });
17
+ * logger.info("printing hello world", { foo: "bar" });
18
+ * logger.print("Hello, world!");
19
+ */ export const createLogger = ({ name, fields: loggerFields = {} })=>{
20
+ return {
21
+ ...createPrinter({
22
+ name
23
+ }),
24
+ ...createStructuredLogger({
25
+ name,
26
+ fields: loggerFields
27
+ }),
28
+ extend: (name, extendedLoggerFields)=>{
29
+ return createLogger({
30
+ name,
31
+ fields: ()=>({
32
+ ...unthunk(loggerFields),
33
+ ...unthunk(extendedLoggerFields)
34
+ })
35
+ });
36
+ }
37
+ };
38
+ };
39
+
40
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/services/output/log/logger.ts"],"sourcesContent":["import { unthunk, type Thunk } from \"../../util/function.js\";\nimport type { Fields } from \"./field.js\";\nimport { createPrinter, type Printer } from \"./printer.js\";\nimport { createStructuredLogger, type StructuredLogger } from \"./structured.js\";\n\nexport type Logger = StructuredLogger &\n Printer & {\n extend(name: string, fields?: Thunk<Fields>): 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 * logger.print(\"Hello, world!\");\n */\nexport const createLogger = ({ name, fields: loggerFields = {} }: { name: string; fields?: Thunk<Fields> }): Logger => {\n return {\n ...createPrinter({ name }),\n ...createStructuredLogger({ name, fields: loggerFields }),\n extend: (name, extendedLoggerFields?: Thunk<Fields>) => {\n return createLogger({ name, fields: () => ({ ...unthunk(loggerFields), ...unthunk(extendedLoggerFields) }) });\n },\n };\n};\n"],"names":["unthunk","createPrinter","createStructuredLogger","createLogger","name","fields","loggerFields","extend","extendedLoggerFields"],"mappings":"AAAA,SAASA,OAAO,QAAoB,yBAAyB;AAE7D,SAASC,aAAa,QAAsB,eAAe;AAC3D,SAASC,sBAAsB,QAA+B,kBAAkB;AAOhF;;;;;;;;;;;;;;;CAeC,GACD,OAAO,MAAMC,eAAe,CAAC,EAAEC,IAAI,EAAEC,QAAQC,eAAe,CAAC,CAAC,EAA4C;IACxG,OAAO;QACL,GAAGL,cAAc;YAAEG;QAAK,EAAE;QAC1B,GAAGF,uBAAuB;YAAEE;YAAMC,QAAQC;QAAa,EAAE;QACzDC,QAAQ,CAACH,MAAMI;YACb,OAAOL,aAAa;gBAAEC;gBAAMC,QAAQ,IAAO,CAAA;wBAAE,GAAGL,QAAQM,aAAa;wBAAE,GAAGN,QAAQQ,qBAAqB;oBAAC,CAAA;YAAG;QAC7G;IACF;AACF,EAAE"}
@@ -0,0 +1,120 @@
1
+ import boxen from "boxen";
2
+ import CliTable3 from "cli-table3";
3
+ import { dedent } from "ts-dedent";
4
+ import { config } from "../../config/config.js";
5
+ import { sprint, sprintln, sprintln2, sprintlns } from "../sprint.js";
6
+ import { stdout } from "../stream.js";
7
+ import { formatters } from "./format/format.js";
8
+ import { Level } from "./level.js";
9
+ export const createPrinter = ({ name })=>{
10
+ const createPrint = (sprinter)=>{
11
+ return (template, ...values)=>{
12
+ let msg = sprinter(template, ...values);
13
+ if (config.logLevel < Level.PRINT || config.logFormat === "json") {
14
+ msg = formatters[config.logFormat](Level.PRINT, name, msg, {});
15
+ }
16
+ stdout.write(msg);
17
+ };
18
+ };
19
+ return {
20
+ print: createPrint(sprint),
21
+ println: createPrint(sprintln),
22
+ println2: createPrint(sprintln2),
23
+ printlns: createPrint(sprintlns),
24
+ printTable ({ message, headers, rows, footer, borders: borderType = "none", spaceY = 0, colAligns = [], colWidths = [], boxen: boxenOptions }) {
25
+ if (config.logFormat === "json") {
26
+ stdout.write(formatters.json(Level.PRINT, name, message || boxenOptions?.title || "table", {
27
+ headers,
28
+ rows,
29
+ footer
30
+ }));
31
+ return;
32
+ }
33
+ const table = new CliTable3({
34
+ chars: borders[borderType],
35
+ colAligns,
36
+ colWidths,
37
+ head: headers,
38
+ style: {
39
+ head: [],
40
+ border: []
41
+ }
42
+ });
43
+ table.push(...rows);
44
+ const padding = "\n".repeat(spaceY + 1);
45
+ let output = "";
46
+ if (message) {
47
+ output += message + padding;
48
+ }
49
+ if (borderType === "none") {
50
+ // remove the left padding
51
+ output += dedent(table.toString()).slice(1);
52
+ } else {
53
+ output += table.toString();
54
+ }
55
+ if (footer) {
56
+ output += padding + footer;
57
+ }
58
+ if (boxenOptions) {
59
+ output = boxen(output, boxenOptions);
60
+ }
61
+ this.println2(output);
62
+ }
63
+ };
64
+ };
65
+ // prettier-ignore
66
+ const borders = {
67
+ none: {
68
+ "top-left": "",
69
+ top: "",
70
+ "top-mid": "",
71
+ "top-right": "",
72
+ "left-mid": "",
73
+ mid: "",
74
+ "mid-mid": "",
75
+ "right-mid": "",
76
+ left: "",
77
+ middle: "",
78
+ right: "",
79
+ "bottom-left": "",
80
+ bottom: "",
81
+ "bottom-mid": "",
82
+ "bottom-right": ""
83
+ },
84
+ thin: {
85
+ "top-left": "┌",
86
+ top: "─",
87
+ "top-mid": "┬",
88
+ "top-right": "┐",
89
+ "left-mid": "├",
90
+ mid: "─",
91
+ "mid-mid": "┼",
92
+ "right-mid": "┤",
93
+ left: "│",
94
+ middle: "│",
95
+ right: "│",
96
+ "bottom-left": "└",
97
+ bottom: "─",
98
+ "bottom-mid": "┴",
99
+ "bottom-right": "┘"
100
+ },
101
+ thick: {
102
+ "top-left": "╔",
103
+ top: "═",
104
+ "top-mid": "╤",
105
+ "top-right": "╗",
106
+ left: "║",
107
+ middle: "│",
108
+ right: "║",
109
+ "left-mid": "╟",
110
+ mid: "─",
111
+ "mid-mid": "┼",
112
+ "right-mid": "╢",
113
+ "bottom-left": "╚",
114
+ bottom: "═",
115
+ "bottom-mid": "╧",
116
+ "bottom-right": "╝"
117
+ }
118
+ };
119
+
120
+ //# sourceMappingURL=printer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/services/output/log/printer.ts"],"sourcesContent":["import type { Options as BoxenOptions } from \"boxen\";\nimport boxen from \"boxen\";\nimport CliTable3 from \"cli-table3\";\nimport { dedent } from \"ts-dedent\";\nimport { config } from \"../../config/config.js\";\nimport { sprint, sprintln, sprintln2, sprintlns, type Sprint } from \"../sprint.js\";\nimport { stdout } from \"../stream.js\";\nimport { formatters } from \"./format/format.js\";\nimport { Level } from \"./level.js\";\n\ntype Print = (template: TemplateStringsArray | string, ...values: unknown[]) => void;\n\nexport type Printer = {\n /**\n * Prints a message to stdout.\n *\n * @example\n * logger.print(\"Hello, world!\");\n * // Hello, world!\n */\n print: Print;\n\n /**\n * Prints a message to stdout followed by a newline.\n *\n * @example\n * logger.println(\"Hello, world!\");\n * // Hello, world!\\n\n */\n println: Print;\n\n /**\n * Prints a message to stdout followed by two newlines.\n *\n * @example\n * logger.println2(\"Hello, world!\");\n * // Hello, world!\\n\n * // \\n\n */\n println2: Print;\n\n /**\n * Prints a message to stdout surrounded by newlines.\n *\n * @example\n * logger.printlns(\"Hello, world!\");\n * // \\n\n * // Hello, world!\\n\n */\n printlns: Print;\n\n /**\n * Prints a table to stdout.\n */\n printTable: (options: PrintTableOptions) => void;\n};\n\nexport type PrintTableOptions = {\n /**\n * The message to print above the table.\n */\n message?: string;\n\n /**\n * The headers of the table.\n */\n headers?: string[];\n\n /**\n * The rows of the table.\n */\n rows: string[][];\n\n /**\n * The message to print below the table.\n */\n footer?: string;\n\n /**\n * The type of borders to use.\n * @default \"none\"\n */\n borders?: \"none\" | \"thin\" | \"thick\";\n\n /**\n * The amount of empty lines to print between the message, table,\n * and footer.\n * @default 0\n */\n spaceY?: number;\n\n /**\n * The alignment of the content in each column.\n * @default [] (left-aligned)\n */\n colAligns?: (\"left\" | \"center\" | \"right\")[];\n\n /**\n * The width of each column.\n * @default [] (auto-sized)\n */\n colWidths?: number[];\n\n /**\n * The options to pass to `boxen`.\n * @default undefined (no box)\n */\n boxen?: BoxenOptions;\n};\n\nexport const createPrinter = ({ name }: { name: string }): Printer => {\n const createPrint = (sprinter: Sprint): Print => {\n return (template, ...values) => {\n let msg = sprinter(template, ...values);\n if (config.logLevel < Level.PRINT || config.logFormat === \"json\") {\n msg = formatters[config.logFormat](Level.PRINT, name, msg, {});\n }\n stdout.write(msg);\n };\n };\n\n return {\n print: createPrint(sprint),\n println: createPrint(sprintln),\n println2: createPrint(sprintln2),\n printlns: createPrint(sprintlns),\n printTable({\n message,\n headers,\n rows,\n footer,\n borders: borderType = \"none\",\n spaceY = 0,\n colAligns = [],\n colWidths = [],\n boxen: boxenOptions,\n }) {\n if (config.logFormat === \"json\") {\n stdout.write(formatters.json(Level.PRINT, name, message || boxenOptions?.title || \"table\", { headers, rows, footer }));\n return;\n }\n\n const table = new CliTable3({\n chars: borders[borderType],\n colAligns,\n colWidths,\n head: headers,\n style: { head: [], border: [] },\n });\n\n table.push(...rows);\n\n const padding = \"\\n\".repeat(spaceY + 1);\n\n let output = \"\";\n if (message) {\n output += message + padding;\n }\n\n if (borderType === \"none\") {\n // remove the left padding\n output += dedent(table.toString()).slice(1);\n } else {\n output += table.toString();\n }\n\n if (footer) {\n output += padding + footer;\n }\n\n if (boxenOptions) {\n output = boxen(output, boxenOptions);\n }\n\n this.println2(output);\n },\n };\n};\n\n// prettier-ignore\nconst borders = {\n none: {\n \"top-left\": \"\", top: \"\", \"top-mid\": \"\", \"top-right\": \"\",\n \"left-mid\": \"\", mid: \"\", \"mid-mid\": \"\", \"right-mid\": \"\",\n left: \"\", middle: \"\", right: \"\",\n \"bottom-left\": \"\", bottom: \"\", \"bottom-mid\": \"\", \"bottom-right\": \"\",\n },\n thin: {\n \"top-left\": \"┌\", top: \"─\", \"top-mid\": \"┬\", \"top-right\": \"┐\",\n \"left-mid\": \"├\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"┤\",\n left: \"│\", middle: \"│\", right: \"│\",\n \"bottom-left\": \"└\", bottom: \"─\", \"bottom-mid\": \"┴\", \"bottom-right\": \"┘\",\n },\n thick: {\n \"top-left\": \"╔\", top: \"═\", \"top-mid\": \"╤\", \"top-right\": \"╗\",\n left: \"║\", middle: \"│\", right: \"║\",\n \"left-mid\": \"╟\", mid: \"─\", \"mid-mid\": \"┼\", \"right-mid\": \"╢\",\n \"bottom-left\": \"╚\", bottom: \"═\", \"bottom-mid\": \"╧\", \"bottom-right\": \"╝\",\n },\n};\n"],"names":["boxen","CliTable3","dedent","config","sprint","sprintln","sprintln2","sprintlns","stdout","formatters","Level","createPrinter","name","createPrint","sprinter","template","values","msg","logLevel","PRINT","logFormat","write","print","println","println2","printlns","printTable","message","headers","rows","footer","borders","borderType","spaceY","colAligns","colWidths","boxenOptions","json","title","table","chars","head","style","border","push","padding","repeat","output","toString","slice","none","top","mid","left","middle","right","bottom","thin","thick"],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { addBreadcrumb as addSentryBreadcrumb } from "@sentry/node";
2
+ import { config } from "../../config/config.js";
3
+ import { env } from "../../config/env.js";
4
+ import { unthunk } from "../../util/function.js";
5
+ import { serializeError } from "../../util/object.js";
6
+ import { stderr } from "../stream.js";
7
+ import { formatters } from "./format/format.js";
8
+ import { Level } from "./level.js";
9
+ export const createStructuredLogger = ({ name, fields: loggerFields = {} })=>{
10
+ const createStructuredLog = (level)=>{
11
+ return (msg, messageFields, devMessageFields)=>{
12
+ const shouldLog = level >= config.logLevel;
13
+ const shouldSendToSentry = level >= Level.INFO;
14
+ if (!shouldLog && !shouldSendToSentry) {
15
+ return;
16
+ }
17
+ const fields = {
18
+ ...unthunk(loggerFields),
19
+ ...messageFields
20
+ };
21
+ if (env.developmentOrTestLike) {
22
+ Object.assign(fields, devMessageFields);
23
+ }
24
+ if ("error" in fields) {
25
+ fields.error = serializeError(fields.error);
26
+ }
27
+ if ("reason" in fields) {
28
+ fields.reason = serializeError(fields.reason);
29
+ }
30
+ if (shouldLog) {
31
+ const format = formatters[config.logFormat];
32
+ stderr.write(format(level, name, msg, fields));
33
+ }
34
+ if (shouldSendToSentry) {
35
+ addSentryBreadcrumb({
36
+ level: "log",
37
+ message: msg,
38
+ data: fields
39
+ });
40
+ }
41
+ };
42
+ };
43
+ return {
44
+ trace: createStructuredLog(Level.TRACE),
45
+ debug: createStructuredLog(Level.DEBUG),
46
+ info: createStructuredLog(Level.INFO),
47
+ warn: createStructuredLog(Level.WARN),
48
+ error: createStructuredLog(Level.ERROR)
49
+ };
50
+ };
51
+
52
+ //# sourceMappingURL=structured.js.map
@@ -0,0 +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 { stderr } from \"../stream.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 const createStructuredLogger = ({ name, fields: loggerFields = {} }: { name: string; fields?: Thunk<Fields> }): 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, 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 stderr.write(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","stderr","formatters","Level","createStructuredLogger","name","fields","loggerFields","createStructuredLog","level","msg","messageFields","devMessageFields","shouldLog","logLevel","shouldSendToSentry","INFO","developmentOrTestLike","Object","assign","error","reason","format","logFormat","write","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;AAYnC,OAAO,MAAMC,yBAAyB,CAAC,EAAEC,IAAI,EAAEC,QAAQC,eAAe,CAAC,CAAC,EAA4C;IAClH,MAAMC,sBAAsB,CAACC;QAC3B,OAAO,CAACC,KAAKC,eAAeC;YAC1B,MAAMC,YAAYJ,SAASZ,OAAOiB,QAAQ;YAC1C,MAAMC,qBAAqBN,SAASN,MAAMa,IAAI;YAC9C,IAAI,CAACH,aAAa,CAACE,oBAAoB;gBACrC;YACF;YAEA,MAAMT,SAAS;gBAAE,GAAGP,QAAQQ,aAAa;gBAAE,GAAGI,aAAa;YAAC;YAC5D,IAAIb,IAAImB,qBAAqB,EAAE;gBAC7BC,OAAOC,MAAM,CAACb,QAAQM;YACxB;YAEA,IAAI,WAAWN,QAAQ;gBACrBA,OAAOc,KAAK,GAAGpB,eAAeM,OAAOc,KAAK;YAC5C;YAEA,IAAI,YAAYd,QAAQ;gBACtBA,OAAOe,MAAM,GAAGrB,eAAeM,OAAOe,MAAM;YAC9C;YAEA,IAAIR,WAAW;gBACb,MAAMS,SAASpB,UAAU,CAACL,OAAO0B,SAAS,CAAC;gBAC3CtB,OAAOuB,KAAK,CAACF,OAAOb,OAAOJ,MAAMK,KAAKJ;YACxC;YAEA,IAAIS,oBAAoB;gBACtBnB,oBAAoB;oBAAEa,OAAO;oBAAOgB,SAASf;oBAAKgB,MAAMpB;gBAAO;YACjE;QACF;IACF;IAEA,OAAO;QACLqB,OAAOnB,oBAAoBL,MAAMyB,KAAK;QACtCC,OAAOrB,oBAAoBL,MAAM2B,KAAK;QACtCC,MAAMvB,oBAAoBL,MAAMa,IAAI;QACpCgB,MAAMxB,oBAAoBL,MAAM8B,IAAI;QACpCb,OAAOZ,oBAAoBL,MAAM+B,KAAK;IACxC;AACF,EAAE"}
@@ -1,8 +1,9 @@
1
1
  import notifier from "node-notifier";
2
- import path from "node:path";
3
- import { workspaceRoot } from "./config.js";
4
- import { createLogger } from "./log.js";
5
- const log = createLogger("notify");
2
+ import { assetsPath } from "../util/paths.js";
3
+ import { createLogger } from "./log/logger.js";
4
+ const log = createLogger({
5
+ name: "notify"
6
+ });
6
7
  /**
7
8
  * Sends a native OS notification to the user.
8
9
  *
@@ -13,8 +14,8 @@ const log = createLogger("notify");
13
14
  });
14
15
  notifier.notify({
15
16
  title: "Gadget",
16
- contentImage: path.join(workspaceRoot, "assets/favicon-128@4x.png"),
17
- icon: path.join(workspaceRoot, "assets/favicon-128@4x.png"),
17
+ contentImage: assetsPath("favicon-128@4x.png"),
18
+ icon: assetsPath("favicon-128@4x.png"),
18
19
  sound: true,
19
20
  timeout: false,
20
21
  ...notification
@@ -0,0 +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 { assetsPath } from \"../util/paths.js\";\nimport type { Field } from \"./log/field.js\";\nimport { createLogger } from \"./log/logger.js\";\n\nconst log = createLogger({ name: \"notify\" });\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 notification:\n | Notification\n | NotificationCenter.Notification\n | NotifySend.Notification\n | WindowsToaster.Notification\n | WindowsBalloon.Notification\n | Growl.Notification,\n): void => {\n 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 log.warn(\"error notifying user\", { notification: notification as Field });\n }\n },\n );\n};\n"],"names":["notifier","assetsPath","createLogger","log","name","notify","notification","info","title","contentImage","icon","sound","timeout","error","warn"],"mappings":"AAAA,OAAOA,cAAqC,gBAAgB;AAM5D,SAASC,UAAU,QAAQ,mBAAmB;AAE9C,SAASC,YAAY,QAAQ,kBAAkB;AAE/C,MAAMC,MAAMD,aAAa;IAAEE,MAAM;AAAS;AAE1C;;;;CAIC,GACD,OAAO,MAAMC,SAAS,CACpBC;IAQAH,IAAII,IAAI,CAAC,kBAAkB;QAAED,cAAcA;IAAsB;IAEjEN,SAASK,MAAM,CACb;QACEG,OAAO;QACPC,cAAcR,WAAW;QACzBS,MAAMT,WAAW;QACjBU,OAAO;QACPC,SAAS;QACT,GAAGN,YAAY;IACjB,GACA,CAACO;QACC,IAAIA,OAAO;YACTV,IAAIW,IAAI,CAAC,wBAAwB;gBAAER,cAAcA;YAAsB;QACzE;IACF;AAEJ,EAAE"}
@@ -0,0 +1,52 @@
1
+ import prompts from "prompts";
2
+ import { createLogger } from "./log/logger.js";
3
+ const log = createLogger({
4
+ name: "prompt"
5
+ });
6
+ /**
7
+ * Prompts the user to select an option from a list of choices.
8
+ *
9
+ * @param message - The message to display to the user.
10
+ * @param choices - The list of choices for the user to select from.
11
+ * @returns A promise that resolves to the selected option.
12
+ */ export const select = async ({ message, choices })=>{
13
+ log.println("");
14
+ try {
15
+ const response = await prompts({
16
+ name: "value",
17
+ type: "autocomplete",
18
+ message,
19
+ choices: choices.map((value)=>({
20
+ title: value,
21
+ value
22
+ }))
23
+ });
24
+ if (!response.value) {
25
+ // The user pressed Ctrl+C
26
+ process.exit(0);
27
+ }
28
+ return response.value;
29
+ } catch (error) {
30
+ process.exit(0);
31
+ }
32
+ };
33
+ /**
34
+ * Displays a confirmation prompt with the specified message. If the
35
+ * user confirms, the function resolves, otherwise it exits the process.
36
+ *
37
+ * @param message - The message to display in the confirmation prompt.
38
+ * @returns A Promise that resolves when the user confirms the prompt.
39
+ */ export const confirm = async ({ message })=>{
40
+ log.println("");
41
+ const response = await prompts({
42
+ name: "value",
43
+ type: "confirm",
44
+ message
45
+ });
46
+ if (!response.value) {
47
+ // The user pressed Ctrl+C
48
+ process.exit(0);
49
+ }
50
+ };
51
+
52
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/services/output/prompt.ts"],"sourcesContent":["import prompts from \"prompts\";\nimport { createLogger } from \"./log/logger.js\";\n\nconst log = createLogger({ name: \"prompt\" });\n\n/**\n * Prompts the user to select an option from a list of choices.\n *\n * @param message - The message to display to the user.\n * @param choices - The list of choices for the user to select from.\n * @returns A promise that resolves to the selected option.\n */\nexport const select = async <T extends string>({ message, choices }: { message: string; choices: T[] }): Promise<T> => {\n log.println(\"\");\n\n try {\n const response = await prompts({\n name: \"value\",\n type: \"autocomplete\",\n message,\n choices: choices.map((value) => ({ title: value, value })),\n });\n\n if (!response.value) {\n // The user pressed Ctrl+C\n process.exit(0);\n }\n\n return response.value as T;\n } catch (error) {\n process.exit(0);\n }\n};\n\n/**\n * Displays a confirmation prompt with the specified message. If the\n * user confirms, the function resolves, otherwise it exits the process.\n *\n * @param message - The message to display in the confirmation prompt.\n * @returns A Promise that resolves when the user confirms the prompt.\n */\nexport const confirm = async ({ message }: { message: string }): Promise<void> => {\n log.println(\"\");\n\n const response = await prompts({\n name: \"value\",\n type: \"confirm\",\n message,\n });\n\n if (!response.value) {\n // The user pressed Ctrl+C\n process.exit(0);\n }\n};\n"],"names":["prompts","createLogger","log","name","select","message","choices","println","response","type","map","value","title","process","exit","error","confirm"],"mappings":"AAAA,OAAOA,aAAa,UAAU;AAC9B,SAASC,YAAY,QAAQ,kBAAkB;AAE/C,MAAMC,MAAMD,aAAa;IAAEE,MAAM;AAAS;AAE1C;;;;;;CAMC,GACD,OAAO,MAAMC,SAAS,OAAyB,EAAEC,OAAO,EAAEC,OAAO,EAAqC;IACpGJ,IAAIK,OAAO,CAAC;IAEZ,IAAI;QACF,MAAMC,WAAW,MAAMR,QAAQ;YAC7BG,MAAM;YACNM,MAAM;YACNJ;YACAC,SAASA,QAAQI,GAAG,CAAC,CAACC,QAAW,CAAA;oBAAEC,OAAOD;oBAAOA;gBAAM,CAAA;QACzD;QAEA,IAAI,CAACH,SAASG,KAAK,EAAE;YACnB,0BAA0B;YAC1BE,QAAQC,IAAI,CAAC;QACf;QAEA,OAAON,SAASG,KAAK;IACvB,EAAE,OAAOI,OAAO;QACdF,QAAQC,IAAI,CAAC;IACf;AACF,EAAE;AAEF;;;;;;CAMC,GACD,OAAO,MAAME,UAAU,OAAO,EAAEX,OAAO,EAAuB;IAC5DH,IAAIK,OAAO,CAAC;IAEZ,MAAMC,WAAW,MAAMR,QAAQ;QAC7BG,MAAM;QACNM,MAAM;QACNJ;IACF;IAEA,IAAI,CAACG,SAASG,KAAK,EAAE;QACnB,0BAA0B;QAC1BE,QAAQC,IAAI,CAAC;IACf;AACF,EAAE"}
@@ -0,0 +1,162 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import * as Sentry from "@sentry/node";
3
+ import cleanStack from "clean-stack";
4
+ import ms from "ms";
5
+ import { randomUUID } from "node:crypto";
6
+ import os from "node:os";
7
+ import { config } from "../config/config.js";
8
+ import { env } from "../config/env.js";
9
+ import { parseBoolean } from "../util/boolean.js";
10
+ import { serializeError } from "../util/object.js";
11
+ import { workspaceRoot } from "../util/paths.js";
12
+ import { createLogger } from "./log/logger.js";
13
+ import { sprint } from "./sprint.js";
14
+ const log = createLogger({
15
+ name: "report"
16
+ });
17
+ let user;
18
+ export const setUser = (newUser)=>{
19
+ log.trace("set user", {
20
+ user: newUser
21
+ });
22
+ user = newUser;
23
+ // eslint-disable-next-line unicorn/no-null
24
+ Sentry.setUser(newUser ?? null);
25
+ };
26
+ let app;
27
+ export const setApp = (newApp)=>{
28
+ log.trace("set app", {
29
+ app: newApp
30
+ });
31
+ app = newApp;
32
+ };
33
+ export const reportErrorAndExit = async (cause)=>{
34
+ log.error("reporting error and exiting", {
35
+ error: cause
36
+ });
37
+ try {
38
+ const error = CLIError.from(cause);
39
+ log.println(error.toString());
40
+ if (error.isBug !== IsBug.NO) {
41
+ Sentry.getCurrentHub().captureException(error, {
42
+ event_id: error.id,
43
+ captureContext: {
44
+ user: user ? {
45
+ id: String(user.id),
46
+ email: user.email,
47
+ username: user.name ?? undefined
48
+ } : undefined,
49
+ tags: {
50
+ applicationId: app ? app.id : undefined,
51
+ arch: config.arch,
52
+ bug: error.isBug,
53
+ environment: env.value,
54
+ platform: config.platform,
55
+ shell: config.shell,
56
+ version: config.version
57
+ },
58
+ contexts: {
59
+ cause: error.cause ? serializeError(error.cause) : undefined,
60
+ app: {
61
+ command: `ggt ${process.argv.slice(2).join(" ")}`,
62
+ argv: process.argv
63
+ },
64
+ device: {
65
+ name: os.hostname(),
66
+ family: os.type(),
67
+ arch: os.arch()
68
+ },
69
+ runtime: {
70
+ name: process.release.name,
71
+ version: process.version
72
+ }
73
+ }
74
+ }
75
+ });
76
+ await Sentry.flush(ms("2s"));
77
+ }
78
+ } finally{
79
+ process.exit(1);
80
+ }
81
+ };
82
+ export const installErrorHandlers = ()=>{
83
+ log.debug("installing error handlers");
84
+ Sentry.init({
85
+ dsn: "https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266",
86
+ release: config.version,
87
+ enabled: env.productionLike && parseBoolean(process.env["GGT_SENTRY_ENABLED"] ?? "true")
88
+ });
89
+ process.once("uncaughtException", (error)=>{
90
+ void reportErrorAndExit(error);
91
+ });
92
+ process.once("unhandledRejection", (error)=>{
93
+ void reportErrorAndExit(error);
94
+ });
95
+ };
96
+ export const IsBug = Object.freeze({
97
+ YES: "yes",
98
+ NO: "no",
99
+ MAYBE: "maybe"
100
+ });
101
+ /**
102
+ * Base class for all errors.
103
+ */ export class CLIError extends Error {
104
+ /**
105
+ * Constructs a CLIError from a cause.
106
+ */ static from(cause) {
107
+ if (cause instanceof CLIError) {
108
+ return cause;
109
+ }
110
+ return new UnexpectedError(cause);
111
+ }
112
+ toString() {
113
+ let rendered = this.render();
114
+ if (this.isBug !== IsBug.NO) {
115
+ rendered += "\n\n" + sprint`
116
+ ${this.isBug === IsBug.YES ? "This is a bug" : "If you think this is a bug"}, please submit an issue using the link below.
117
+
118
+ https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}
119
+ `;
120
+ }
121
+ return rendered;
122
+ }
123
+ constructor(message){
124
+ super(message);
125
+ /**
126
+ * The ID for this error.
127
+ */ _define_property(this, "id", env.testLike ? "00000000-0000-0000-0000-000000000000" : randomUUID());
128
+ /**
129
+ * The underlying *thing* that caused this error.
130
+ */ _define_property(this, "cause", void 0);
131
+ /**
132
+ * Assume the stack trace exists.
133
+ */ _define_property(this, "stack", void 0);
134
+ Error.captureStackTrace(this, this.constructor);
135
+ this.stack = cleanStack(this.stack, {
136
+ pretty: true,
137
+ basePath: workspaceRoot
138
+ });
139
+ }
140
+ }
141
+ /**
142
+ * Our "catch all" error.
143
+ *
144
+ * If this error is thrown, we almost certainly have a bug, and should
145
+ * either fix it or add a more specific error so that we can provide
146
+ * more useful information.
147
+ */ export class UnexpectedError extends CLIError {
148
+ render() {
149
+ const serialized = serializeError(this.cause);
150
+ const body = serialized.stack || serialized.message || this.stack;
151
+ return this.message + "\n\n" + body;
152
+ }
153
+ constructor(cause){
154
+ super("An unexpected error occurred");
155
+ _define_property(this, "cause", void 0);
156
+ _define_property(this, "isBug", void 0);
157
+ this.cause = cause;
158
+ this.isBug = IsBug.YES;
159
+ }
160
+ }
161
+
162
+ //# sourceMappingURL=report.js.map
@@ -0,0 +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 type { App } from \"../app/app.js\";\nimport { config } from \"../config/config.js\";\nimport { env } from \"../config/env.js\";\nimport type { User } from \"../user/user.js\";\nimport { parseBoolean } from \"../util/boolean.js\";\nimport { serializeError } from \"../util/object.js\";\nimport { workspaceRoot } from \"../util/paths.js\";\nimport { createLogger } from \"./log/logger.js\";\nimport { sprint } from \"./sprint.js\";\n\nconst log = createLogger({ name: \"report\" });\n\nlet user: User | undefined;\nexport const setUser = (newUser: typeof user): void => {\n log.trace(\"set user\", { user: newUser });\n user = newUser;\n // eslint-disable-next-line unicorn/no-null\n Sentry.setUser(newUser ?? null);\n};\n\nlet app: App | undefined;\nexport const setApp = (newApp: typeof app): void => {\n log.trace(\"set app\", { app: newApp });\n app = newApp;\n};\n\nexport const reportErrorAndExit = async (cause: unknown): Promise<never> => {\n log.error(\"reporting error and exiting\", { error: cause });\n\n try {\n const error = CLIError.from(cause);\n log.println(error.toString());\n\n if (error.isBug !== IsBug.NO) {\n Sentry.getCurrentHub().captureException(error, {\n event_id: error.id,\n captureContext: {\n user: user ? { id: String(user.id), email: user.email, username: user.name ?? undefined } : undefined,\n tags: {\n applicationId: app ? app.id : undefined,\n arch: config.arch,\n bug: error.isBug,\n environment: env.value,\n platform: config.platform,\n shell: config.shell,\n version: config.version,\n },\n contexts: {\n cause: error.cause ? serializeError(error.cause) : undefined,\n app: {\n command: `ggt ${process.argv.slice(2).join(\" \")}`,\n argv: process.argv,\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 }\n } finally {\n process.exit(1);\n }\n};\n\nexport const installErrorHandlers = (): void => {\n log.debug(\"installing error handlers\");\n\n Sentry.init({\n dsn: \"https://0c26e0d8afd94e77a88ee1c3aa9e7065@o250689.ingest.sentry.io/6703266\",\n release: config.version,\n enabled: env.productionLike && parseBoolean(process.env[\"GGT_SENTRY_ENABLED\"] ?? \"true\"),\n });\n\n process.once(\"uncaughtException\", (error) => {\n void reportErrorAndExit(error);\n });\n\n process.once(\"unhandledRejection\", (error) => {\n void reportErrorAndExit(error);\n });\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 CLIError 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 CLIError from a cause.\n */\n static from(cause: unknown): CLIError {\n if (cause instanceof CLIError) {\n return cause;\n }\n return new UnexpectedError(cause);\n }\n\n override toString(): string {\n let rendered = this.render();\n\n if (this.isBug !== IsBug.NO) {\n rendered +=\n \"\\n\\n\" +\n sprint`\n ${this.isBug === IsBug.YES ? \"This is a bug\" : \"If you think this is a bug\"}, please submit an issue using the link below.\n\n https://github.com/gadget-inc/ggt/issues/new?template=bug_report.yml&error-id=${this.id}\n `;\n }\n\n return rendered;\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 CLIError {\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"],"names":["Sentry","cleanStack","ms","randomUUID","os","config","env","parseBoolean","serializeError","workspaceRoot","createLogger","sprint","log","name","user","setUser","newUser","trace","app","setApp","newApp","reportErrorAndExit","cause","error","CLIError","from","println","toString","isBug","IsBug","NO","getCurrentHub","captureException","event_id","id","captureContext","String","email","username","undefined","tags","applicationId","arch","bug","environment","value","platform","shell","version","contexts","command","process","argv","slice","join","device","hostname","family","type","runtime","release","flush","exit","installErrorHandlers","debug","init","dsn","enabled","productionLike","once","Object","freeze","YES","MAYBE","Error","UnexpectedError","rendered","render","constructor","message","testLike","stack","captureStackTrace","pretty","basePath","serialized","body"],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import chalkTemplate from "chalk-template";
2
+ import { dedent } from "ts-dedent";
3
+ import { isString } from "../util/is.js";
4
+ export const sprint = (template, ...values)=>{
5
+ let content = template;
6
+ if (!isString(content)) {
7
+ content = chalkTemplate(content, ...values);
8
+ }
9
+ return dedent(content);
10
+ };
11
+ export const sprintln = (template, ...values)=>{
12
+ return sprint(template, ...values) + "\n";
13
+ };
14
+ export const sprintln2 = (template, ...values)=>{
15
+ return sprintln(template, ...values) + "\n";
16
+ };
17
+ export const sprintlns = (template, ...values)=>{
18
+ return "\n" + sprintln(template, ...values);
19
+ };
20
+
21
+ //# sourceMappingURL=sprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/services/output/sprint.ts"],"sourcesContent":["import chalkTemplate from \"chalk-template\";\nimport { dedent } from \"ts-dedent\";\nimport { isString } from \"../util/is.js\";\n\nexport type Sprint = (template: TemplateStringsArray | string, ...values: unknown[]) => string;\n\nexport const sprint: Sprint = (template, ...values) => {\n let content = template;\n if (!isString(content)) {\n content = chalkTemplate(content, ...values);\n }\n return dedent(content);\n};\n\nexport const sprintln: Sprint = (template, ...values) => {\n return sprint(template, ...values) + \"\\n\";\n};\n\nexport const sprintln2: Sprint = (template, ...values) => {\n return sprintln(template, ...values) + \"\\n\";\n};\n\nexport const sprintlns: Sprint = (template, ...values) => {\n return \"\\n\" + sprintln(template, ...values);\n};\n"],"names":["chalkTemplate","dedent","isString","sprint","template","values","content","sprintln","sprintln2","sprintlns"],"mappings":"AAAA,OAAOA,mBAAmB,iBAAiB;AAC3C,SAASC,MAAM,QAAQ,YAAY;AACnC,SAASC,QAAQ,QAAQ,gBAAgB;AAIzC,OAAO,MAAMC,SAAiB,CAACC,UAAU,GAAGC;IAC1C,IAAIC,UAAUF;IACd,IAAI,CAACF,SAASI,UAAU;QACtBA,UAAUN,cAAcM,YAAYD;IACtC;IACA,OAAOJ,OAAOK;AAChB,EAAE;AAEF,OAAO,MAAMC,WAAmB,CAACH,UAAU,GAAGC;IAC5C,OAAOF,OAAOC,aAAaC,UAAU;AACvC,EAAE;AAEF,OAAO,MAAMG,YAAoB,CAACJ,UAAU,GAAGC;IAC7C,OAAOE,SAASH,aAAaC,UAAU;AACzC,EAAE;AAEF,OAAO,MAAMI,YAAoB,CAACL,UAAU,GAAGC;IAC7C,OAAO,OAAOE,SAASH,aAAaC;AACtC,EAAE"}