@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/commands/deploy.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { AppArg } from \"../services/app/arg.js\";\nimport { REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION } from \"../services/app/edit-graphql.js\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport { type Command, type Usage } from \"../services/command/command.js\";\nimport { FileSync } from \"../services/filesync/filesync.js\";\nimport { isEqualHashes } from \"../services/filesync/hashes.js\";\nimport { select } from \"../services/output/prompt.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\nimport { isGraphQLErrors } from \"../services/util/is.js\";\n\nexport const usage: Usage = () => sprint`\n Deploy your Gadget application's development source code to production.\n\n {bold USAGE}\n ggt deploy [DIRECTORY] [--app=<name>]\n\n {bold ARGUMENTS}\n DIRECTORY The directory to sync files to and deploy (default: \".\")\n\n {bold FLAGS}\n -a, --app=<name> The Gadget application to deploy\n --force Deploy the Gadget application regardless of any issues it may have\n\n {bold DESCRIPTION}\n Deploy allows you to deploy your current Gadget application in development to production.\n \n It detects if local files are up to date with remote and if the Gadget application \n is in a deployable state. If there are any issues, it will display them and ask if \n you would like to deploy anyways. \n \n Note:\n • If local files are not up to date or have not recently been synced with remote ones,\n you will be prompted to run a one-time sync to ensure the files remain consistent with \n what is on the remote. \n • You may wish to keep ggt sync running in the background before trying to run ggt deploy\n \n {bold EXAMPLE} \n $ ggt deploy ~/gadget/example --app example\n \n App example\n Editor https://example.gadget.app/edit\n Playground https://example.gadget.app/api/graphql/playground\n Docs https://docs.gadget.dev/api/example\n\n Endpoints\n • https://example.gadget.app\n • https://example--development.gadget.app\n \n \n Building frontend assets ...\n ✔ DONE\n \n Setting up database ...\n ✔ DONE\n \n Copying development ...\n ✔ DONE\n \n Restarting app ...\n ✔ DONE\n \n Deploy completed. Good bye!\n`;\n\nexport const args = {\n \"--app\": {\n type: AppArg,\n alias: \"-a\",\n },\n \"--force\": Boolean,\n} satisfies ArgsSpec;\n\nexport enum Action {\n DEPLOY_ANYWAYS = \"Deploy anyways\",\n SYNC_ONCE = \"Sync once\",\n CANCEL = \"Cancel (Ctrl+C)\",\n}\n\nconst AppDeploymentStepsToAppDeployState = (step: string | undefined): string => {\n switch (step) {\n case \"NOT_STARTED\":\n return \"Deploy not started\";\n case \"STARTING\":\n case \"BUILDING_ASSETS\":\n case \"UPLOADING_ASSETS\":\n return \"Building frontend assets\";\n case \"CONVERGING_STORAGE\":\n return \"Setting up database\";\n case \"PUBLISHING_TREE\":\n return \"Copying development\";\n case \"RELOADING_SANDBOX\":\n return \"Restarting app\";\n case \"COMPLETED\":\n return \"Deploy completed\";\n default:\n return \"Unknown step\";\n }\n};\n\nenum AppDeploymentSteps {\n NOT_STARTED = \"NOT_STARTED\",\n STARTING = \"STARTING\",\n BUILDING_ASSETS = \"BUILDING_ASSETS\",\n UPLOADING_ASSETS = \"UPLOADING_ASSETS\",\n CONVERGING_STORAGE = \"CONVERGING_STORAGE\",\n PUBLISHING_TREE = \"PUBLISHING_TREE\",\n RELOADING_SANDBOX = \"RELOADING_SANDBOX\",\n COMPLETED = \"COMPLETED\",\n}\n\n/**\n * Runs the deploy process.\n */\n\nexport const command = (async (ctx, firstRun = true) => {\n const spinner = ora();\n let prevProgress: string | undefined = AppDeploymentStepsToAppDeployState(\"NOT_STARTED\");\n let action: Action;\n\n const filesync = await FileSync.init({\n user: await getUserOrLogin(),\n dir: ctx.args._[0],\n app: ctx.args[\"--app\"],\n });\n\n const log = filesync.log.extend(\"deploy\");\n\n if (firstRun) {\n log.printlns`App: ${filesync.app.slug}`;\n }\n\n const { localHashes, gadgetHashes } = await filesync._getHashes();\n\n const upToDate = isEqualHashes(localHashes, gadgetHashes);\n\n if (!upToDate) {\n log.printlns`\n Local files have diverged from remote. Run a sync once to converge your files or keep {italic ggt sync} running in the background.\n `;\n\n action = await select({\n message: \"How would you like to proceed?\",\n choices: [Action.CANCEL, Action.SYNC_ONCE],\n });\n\n switch (action) {\n case Action.SYNC_ONCE: {\n await filesync.sync();\n\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n // subscribes to the graphql subscription that will listen and send back the server contract status\n const unsubscribe = filesync.editGraphQL.subscribe({\n query: REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION,\n variables: () => ({ localFilesVersion: String(filesync.filesVersion), force: ctx.args[\"--force\"] }),\n onError: (error) => {\n if (isGraphQLErrors(error.cause)) {\n const message = error.cause[0]?.message;\n if (message && message.includes(\"GGT_PAYMENT_REQUIRED\")) {\n log.println(\"Production environment limit reached. Upgrade your plan to deploy\");\n } else {\n log.println(`${message}`);\n }\n }\n log.error(\"failed to deploy\", { error });\n },\n onData: async ({ publishStatus }): Promise<void> => {\n const { progress, issues } = publishStatus ?? {};\n\n const hasIssues = issues?.length;\n\n if (firstRun && hasIssues) {\n log.printlns`{underline Issues detected}`;\n\n for (const issue of issues) {\n const message = issue.message.replace(/\"/g, \"\");\n const nodeType = issue.node?.type;\n const nodeName = issue.node?.name;\n const nodeParent = issue.node?.parentApiIdentifier;\n\n log.printlns(\n `\n • ${message} \n ${nodeType ? `${nodeType}: ${chalk.cyan(nodeName)}` : \"\"} ${\n nodeParent ? `ParentResource: ${chalk.cyan(nodeParent)}` : \"\"\n }\n `.trim(),\n );\n }\n\n if (!ctx.args[\"--force\"]) {\n unsubscribe();\n\n action = await select({\n message: \"Detected some issues with your app. How would you like to proceed?\",\n choices: [Action.CANCEL, Action.DEPLOY_ANYWAYS],\n });\n\n switch (action) {\n case Action.DEPLOY_ANYWAYS: {\n ctx.args[\"--force\"] = true;\n await command(ctx, false);\n break;\n }\n case Action.CANCEL: {\n process.exit(0);\n }\n }\n }\n\n firstRun = false;\n } else {\n if (progress === AppDeploymentSteps.COMPLETED) {\n spinner.succeed(\"DONE\");\n log.printlns(\"Deploy completed. Good bye!\");\n unsubscribe();\n return;\n }\n\n const currentProgress = AppDeploymentStepsToAppDeployState(progress);\n\n if (progress && currentProgress !== prevProgress) {\n if ((progress as AppDeploymentSteps) !== AppDeploymentSteps.STARTING) {\n spinner.succeed(\"DONE\");\n }\n\n prevProgress = currentProgress;\n log.printlns(`${currentProgress} ...`);\n spinner.start(\"Working ...\");\n }\n }\n },\n });\n}) satisfies Command<typeof args>;\n"],"names":["chalk","ora","AppArg","REMOTE_SERVER_CONTRACT_STATUS_SUBSCRIPTION","FileSync","isEqualHashes","select","sprint","getUserOrLogin","isGraphQLErrors","usage","args","type","alias","Boolean","Action","AppDeploymentStepsToAppDeployState","step","AppDeploymentSteps","command","ctx","firstRun","spinner","prevProgress","action","filesync","init","user","dir","_","app","log","extend","printlns","slug","localHashes","gadgetHashes","_getHashes","upToDate","message","choices","sync","process","exit","unsubscribe","editGraphQL","subscribe","query","variables","localFilesVersion","String","filesVersion","force","onError","error","cause","includes","println","onData","publishStatus","progress","issues","hasIssues","length","issue","replace","nodeType","node","nodeName","name","nodeParent","parentApiIdentifier","cyan","trim","succeed","currentProgress","start"],"mappings":"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"}
@@ -1,38 +1,45 @@
1
- import _ from "lodash";
2
- import { getApps } from "../services/app.js";
3
- import { println, sprint } from "../services/output.js";
4
- import { getUserOrLogin } from "../services/user.js";
5
- export const usage = sprint`
1
+ import { getApps } from "../services/app/app.js";
2
+ import { createLogger } from "../services/output/log/logger.js";
3
+ import { sprint } from "../services/output/sprint.js";
4
+ import { getUserOrLogin } from "../services/user/user.js";
5
+ const log = createLogger({
6
+ name: "list"
7
+ });
8
+ export const usage = ()=>sprint`
6
9
  List the apps available to the currently logged in user.
7
10
 
8
11
  {bold USAGE}
9
- $ ggt list
12
+ ggt list
10
13
 
11
14
  {bold EXAMPLE}
12
- {gray $ ggt list}
13
- Slug Domain
14
- ─────── ──────────────────
15
- my-app my-app.gadget.app
16
- example example.gadget.app
17
- test test.gadget.app
15
+ $ ggt list
16
+ Slug Domain
17
+ ─────── ──────────────────
18
+ my-app my-app.gadget.app
19
+ example example.gadget.app
20
+ test test.gadget.app
18
21
  `;
19
- export const run = async ()=>{
22
+ export const command = async ()=>{
20
23
  const user = await getUserOrLogin();
21
24
  const apps = await getApps(user);
22
- if (!apps.length) {
23
- println`
25
+ if (apps.length === 0) {
26
+ log.println`
24
27
  It doesn't look like you have any applications.
25
28
 
26
29
  Visit https://gadget.new to create one!
27
30
  `;
28
31
  return;
29
32
  }
30
- const longestSlug = _.maxBy(apps, "slug.length")?.slug.length ?? 0;
31
- const longestDomain = _.maxBy(apps, "primaryDomain.length")?.primaryDomain.length ?? 0;
32
- println`{bold Slug}${_.repeat(" ", longestSlug - 4)} {bold Domain}`;
33
- println`${_.repeat("─", Math.max(longestSlug, 4))} ${_.repeat("─", Math.max(longestDomain, 6))}`;
34
- for (const app of _.sortBy(apps, "slug")){
35
- println`${app.slug}${_.repeat(" ", longestSlug - app.slug.length)} ${app.primaryDomain}`;
33
+ let longestSlug = 0;
34
+ let longestDomain = 0;
35
+ for (const app of apps){
36
+ longestSlug = Math.max(longestSlug, app.slug.length);
37
+ longestDomain = Math.max(longestDomain, app.primaryDomain.length);
38
+ }
39
+ log.println`{bold Slug}${" ".repeat(longestSlug - 4)} {bold Domain}`;
40
+ log.println`${"─".repeat(Math.max(longestSlug, 4))} ${"─".repeat(Math.max(longestDomain, 6))}`;
41
+ for (const app of apps.sort((a, b)=>a.slug.localeCompare(b.slug))){
42
+ log.println`${app.slug}${" ".repeat(longestSlug - app.slug.length)} ${app.primaryDomain}`;
36
43
  }
37
44
  };
38
45
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/list.ts"],"sourcesContent":["import _ from \"lodash\";\nimport { getApps } from \"../services/app.js\";\nimport { println, sprint } from \"../services/output.js\";\nimport { getUserOrLogin } from \"../services/user.js\";\n\nexport const usage = sprint`\n List the apps available to the currently logged in user.\n\n {bold USAGE}\n $ ggt list\n\n {bold EXAMPLE}\n {gray $ ggt list}\n Slug Domain\n ─────── ──────────────────\n my-app my-app.gadget.app\n example example.gadget.app\n test test.gadget.app\n`;\n\nexport const run = async () => {\n const user = await getUserOrLogin();\n\n const apps = await getApps(user);\n if (!apps.length) {\n println`\n It doesn't look like you have any applications.\n\n Visit https://gadget.new to create one!\n `;\n return;\n }\n\n const longestSlug = _.maxBy(apps, \"slug.length\")?.slug.length ?? 0;\n const longestDomain = _.maxBy(apps, \"primaryDomain.length\")?.primaryDomain.length ?? 0;\n\n println`{bold Slug}${_.repeat(\" \", longestSlug - 4)} {bold Domain}`;\n println`${_.repeat(\"─\", Math.max(longestSlug, 4))} ${_.repeat(\"─\", Math.max(longestDomain, 6))}`;\n for (const app of _.sortBy(apps, \"slug\")) {\n println`${app.slug}${_.repeat(\" \", longestSlug - app.slug.length)} ${app.primaryDomain}`;\n }\n};\n"],"names":["_","getApps","println","sprint","getUserOrLogin","usage","run","user","apps","length","longestSlug","maxBy","slug","longestDomain","primaryDomain","repeat","Math","max","app","sortBy"],"mappings":"AAAA,OAAOA,OAAO,SAAS;AACvB,SAASC,OAAO,QAAQ,qBAAqB;AAC7C,SAASC,OAAO,EAAEC,MAAM,QAAQ,wBAAwB;AACxD,SAASC,cAAc,QAAQ,sBAAsB;AAErD,OAAO,MAAMC,QAAQF,MAAM,CAAC;;;;;;;;;;;;;AAa5B,CAAC,CAAC;AAEF,OAAO,MAAMG,MAAM;IACjB,MAAMC,OAAO,MAAMH;IAEnB,MAAMI,OAAO,MAAMP,QAAQM;IAC3B,IAAI,CAACC,KAAKC,MAAM,EAAE;QAChBP,OAAO,CAAC;;;;IAIR,CAAC;QACD;IACF;IAEA,MAAMQ,cAAcV,EAAEW,KAAK,CAACH,MAAM,gBAAgBI,KAAKH,UAAU;IACjE,MAAMI,gBAAgBb,EAAEW,KAAK,CAACH,MAAM,yBAAyBM,cAAcL,UAAU;IAErFP,OAAO,CAAC,WAAW,EAAEF,EAAEe,MAAM,CAAC,KAAKL,cAAc,GAAG,cAAc,CAAC;IACnER,OAAO,CAAC,EAAEF,EAAEe,MAAM,CAAC,KAAKC,KAAKC,GAAG,CAACP,aAAa,IAAI,CAAC,EAAEV,EAAEe,MAAM,CAAC,KAAKC,KAAKC,GAAG,CAACJ,eAAe,IAAI,CAAC;IAChG,KAAK,MAAMK,OAAOlB,EAAEmB,MAAM,CAACX,MAAM,QAAS;QACxCN,OAAO,CAAC,EAAEgB,IAAIN,IAAI,CAAC,EAAEZ,EAAEe,MAAM,CAAC,KAAKL,cAAcQ,IAAIN,IAAI,CAACH,MAAM,EAAE,CAAC,EAAES,IAAIJ,aAAa,CAAC,CAAC;IAC1F;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/commands/list.ts"],"sourcesContent":["import { getApps } from \"../services/app/app.js\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { getUserOrLogin } from \"../services/user/user.js\";\n\nconst log = createLogger({ name: \"list\" });\n\nexport const usage: Usage = () => sprint`\n List the apps available to the currently logged in user.\n\n {bold USAGE}\n ggt list\n\n {bold EXAMPLE}\n $ ggt list\n Slug Domain\n ─────── ──────────────────\n my-app my-app.gadget.app\n example example.gadget.app\n test test.gadget.app\n`;\n\nexport const command: Command = async () => {\n const user = await getUserOrLogin();\n\n const apps = await getApps(user);\n if (apps.length === 0) {\n log.println`\n It doesn't look like you have any applications.\n\n Visit https://gadget.new to create one!\n `;\n return;\n }\n\n let longestSlug = 0;\n let longestDomain = 0;\n\n for (const app of apps) {\n longestSlug = Math.max(longestSlug, app.slug.length);\n longestDomain = Math.max(longestDomain, app.primaryDomain.length);\n }\n\n log.println`{bold Slug}${\" \".repeat(longestSlug - 4)} {bold Domain}`;\n log.println`${\"─\".repeat(Math.max(longestSlug, 4))} ${\"─\".repeat(Math.max(longestDomain, 6))}`;\n for (const app of apps.sort((a, b) => a.slug.localeCompare(b.slug))) {\n log.println`${app.slug}${\" \".repeat(longestSlug - app.slug.length)} ${app.primaryDomain}`;\n }\n};\n"],"names":["getApps","createLogger","sprint","getUserOrLogin","log","name","usage","command","user","apps","length","println","longestSlug","longestDomain","app","Math","max","slug","primaryDomain","repeat","sort","a","b","localeCompare"],"mappings":"AAAA,SAASA,OAAO,QAAQ,yBAAyB;AAEjD,SAASC,YAAY,QAAQ,mCAAmC;AAChE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,cAAc,QAAQ,2BAA2B;AAE1D,MAAMC,MAAMH,aAAa;IAAEI,MAAM;AAAO;AAExC,OAAO,MAAMC,QAAe,IAAMJ,MAAM,CAAC;;;;;;;;;;;;;AAazC,CAAC,CAAC;AAEF,OAAO,MAAMK,UAAmB;IAC9B,MAAMC,OAAO,MAAML;IAEnB,MAAMM,OAAO,MAAMT,QAAQQ;IAC3B,IAAIC,KAAKC,MAAM,KAAK,GAAG;QACrBN,IAAIO,OAAO,CAAC;;;;IAIZ,CAAC;QACD;IACF;IAEA,IAAIC,cAAc;IAClB,IAAIC,gBAAgB;IAEpB,KAAK,MAAMC,OAAOL,KAAM;QACtBG,cAAcG,KAAKC,GAAG,CAACJ,aAAaE,IAAIG,IAAI,CAACP,MAAM;QACnDG,gBAAgBE,KAAKC,GAAG,CAACH,eAAeC,IAAII,aAAa,CAACR,MAAM;IAClE;IAEAN,IAAIO,OAAO,CAAC,WAAW,EAAE,IAAIQ,MAAM,CAACP,cAAc,GAAG,cAAc,CAAC;IACpER,IAAIO,OAAO,CAAC,EAAE,IAAIQ,MAAM,CAACJ,KAAKC,GAAG,CAACJ,aAAa,IAAI,CAAC,EAAE,IAAIO,MAAM,CAACJ,KAAKC,GAAG,CAACH,eAAe,IAAI,CAAC;IAC9F,KAAK,MAAMC,OAAOL,KAAKW,IAAI,CAAC,CAACC,GAAGC,IAAMD,EAAEJ,IAAI,CAACM,aAAa,CAACD,EAAEL,IAAI,GAAI;QACnEb,IAAIO,OAAO,CAAC,EAAEG,IAAIG,IAAI,CAAC,EAAE,IAAIE,MAAM,CAACP,cAAcE,IAAIG,IAAI,CAACP,MAAM,EAAE,CAAC,EAAEI,IAAII,aAAa,CAAC,CAAC;IAC3F;AACF,EAAE"}
@@ -2,27 +2,29 @@ import getPort from "get-port";
2
2
  import assert from "node:assert";
3
3
  import http from "node:http";
4
4
  import open from "open";
5
- import { config } from "../services/config.js";
6
- import { createLogger } from "../services/log.js";
7
- import { println, sprint } from "../services/output.js";
8
- import { writeSession } from "../services/session.js";
9
- import { getUser } from "../services/user.js";
10
- export const usage = sprint`
5
+ import { config } from "../services/config/config.js";
6
+ import { createLogger } from "../services/output/log/logger.js";
7
+ import { sprint } from "../services/output/sprint.js";
8
+ import { writeSession } from "../services/user/session.js";
9
+ import { getUser } from "../services/user/user.js";
10
+ const log = createLogger({
11
+ name: "login"
12
+ });
13
+ export const usage = ()=>sprint`
11
14
  Log in to your account.
12
15
 
13
16
  {bold USAGE}
14
- $ ggt login
17
+ ggt login
15
18
 
16
19
  {bold EXAMPLES}
17
- {gray $ ggt login}
18
- We've opened Gadget's login page using your default browser.
20
+ $ ggt login
21
+ We've opened Gadget's login page using your default browser.
19
22
 
20
- Please log in and then return to this terminal.
23
+ Please log in and then return to this terminal.
21
24
 
22
- Hello, Jane Doe (jane@example.com)
25
+ Hello, Jane Doe (jane@example.com)
23
26
  `;
24
- const log = createLogger("login");
25
- export const run = async ()=>{
27
+ export const login = async ()=>{
26
28
  let server;
27
29
  try {
28
30
  const port = await getPort();
@@ -38,11 +40,10 @@ export const run = async ()=>{
38
40
  const user = await getUser();
39
41
  assert(user, "missing user after successful login");
40
42
  if (user.name) {
41
- println`Hello, ${user.name} {gray (${user.email})}`;
43
+ log.printlns`Hello, ${user.name} {gray (${user.email})}`;
42
44
  } else {
43
- println`Hello, ${user.email}`;
45
+ log.printlns`Hello, ${user.email}`;
44
46
  }
45
- println();
46
47
  landingPage.searchParams.set("success", "true");
47
48
  resolve();
48
49
  } catch (error) {
@@ -68,21 +69,21 @@ export const run = async ()=>{
68
69
  url.searchParams.set("returnTo", `https://${config.domains.services}/auth/cli/callback?port=${port}`);
69
70
  try {
70
71
  await open(url.toString());
71
- println`
72
+ log.printlns`
72
73
  We've opened Gadget's login page using your default browser.
73
74
 
74
- Please log in and then return to this terminal.\n
75
+ Please log in and then return to this terminal.
75
76
  `;
76
77
  } catch (error) {
77
78
  log.error("failed to open browser", {
78
79
  error
79
80
  });
80
- println`
81
+ log.printlns`
81
82
  Please open the following URL in your browser and log in:
82
83
 
83
84
  {gray ${url.toString()}}
84
85
 
85
- Once logged in, return to this terminal.\n
86
+ Once logged in, return to this terminal.
86
87
  `;
87
88
  }
88
89
  await receiveSession;
@@ -90,5 +91,6 @@ export const run = async ()=>{
90
91
  server?.close();
91
92
  }
92
93
  };
94
+ export const command = login;
93
95
 
94
96
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import getPort from \"get-port\";\nimport assert from \"node:assert\";\nimport http, { type Server } from \"node:http\";\nimport open from \"open\";\nimport { config } from \"../services/config.js\";\nimport { createLogger } from \"../services/log.js\";\nimport { println, sprint } from \"../services/output.js\";\nimport { writeSession } from \"../services/session.js\";\nimport { getUser } from \"../services/user.js\";\n\nexport const usage = sprint`\n Log in to your account.\n\n {bold USAGE}\n $ ggt login\n\n {bold EXAMPLES}\n {gray $ ggt login}\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n\n Hello, Jane Doe (jane@example.com)\n`;\n\nconst log = createLogger(\"login\");\n\nexport const run = async () => {\n let server: Server | undefined;\n\n try {\n const port = await getPort();\n const receiveSession = new Promise<void>((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server = http.createServer(async (req, res) => {\n const landingPage = new URL(`https://${config.domains.services}/auth/cli`);\n\n try {\n assert(req.url, \"missing url\");\n const session = new URL(req.url, `http://localhost:${port}`).searchParams.get(\"session\");\n assert(session, \"missing session\");\n\n writeSession(session);\n\n const user = await getUser();\n assert(user, \"missing user after successful login\");\n\n if (user.name) {\n println`Hello, ${user.name} {gray (${user.email})}`;\n } else {\n println`Hello, ${user.email}`;\n }\n println();\n\n landingPage.searchParams.set(\"success\", \"true\");\n resolve();\n } catch (error) {\n writeSession(undefined);\n landingPage.searchParams.set(\"success\", \"false\");\n reject(error);\n } finally {\n res.writeHead(303, { Location: landingPage.toString() });\n res.end();\n }\n });\n\n log.info(\"starting login server\", { port });\n server.listen(port);\n });\n\n // open the login page in the user's default browser have it\n // redirect to the cli callback route. The cli callback route will\n // send the session to the server we just started.\n const url = new URL(`https://${config.domains.services}/auth/login`);\n url.searchParams.set(\"returnTo\", `https://${config.domains.services}/auth/cli/callback?port=${port}`);\n\n try {\n await open(url.toString());\n println`\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\\n\n `;\n } catch (error) {\n log.error(\"failed to open browser\", { error });\n println`\n Please open the following URL in your browser and log in:\n\n {gray ${url.toString()}}\n\n Once logged in, return to this terminal.\\n\n `;\n }\n\n await receiveSession;\n } finally {\n server?.close();\n }\n};\n"],"names":["getPort","assert","http","open","config","createLogger","println","sprint","writeSession","getUser","usage","log","run","server","port","receiveSession","Promise","resolve","reject","createServer","req","res","landingPage","URL","domains","services","url","session","searchParams","get","user","name","email","set","error","undefined","writeHead","Location","toString","end","info","listen","close"],"mappings":"AAAA,OAAOA,aAAa,WAAW;AAC/B,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAA2B,YAAY;AAC9C,OAAOC,UAAU,OAAO;AACxB,SAASC,MAAM,QAAQ,wBAAwB;AAC/C,SAASC,YAAY,QAAQ,qBAAqB;AAClD,SAASC,OAAO,EAAEC,MAAM,QAAQ,wBAAwB;AACxD,SAASC,YAAY,QAAQ,yBAAyB;AACtD,SAASC,OAAO,QAAQ,sBAAsB;AAE9C,OAAO,MAAMC,QAAQH,MAAM,CAAC;;;;;;;;;;;;;AAa5B,CAAC,CAAC;AAEF,MAAMI,MAAMN,aAAa;AAEzB,OAAO,MAAMO,MAAM;IACjB,IAAIC;IAEJ,IAAI;QACF,MAAMC,OAAO,MAAMd;QACnB,MAAMe,iBAAiB,IAAIC,QAAc,CAACC,SAASC;YACjD,kEAAkE;YAClEL,SAASX,KAAKiB,YAAY,CAAC,OAAOC,KAAKC;gBACrC,MAAMC,cAAc,IAAIC,IAAI,CAAC,QAAQ,EAAEnB,OAAOoB,OAAO,CAACC,QAAQ,CAAC,SAAS,CAAC;gBAEzE,IAAI;oBACFxB,OAAOmB,IAAIM,GAAG,EAAE;oBAChB,MAAMC,UAAU,IAAIJ,IAAIH,IAAIM,GAAG,EAAE,CAAC,iBAAiB,EAAEZ,KAAK,CAAC,EAAEc,YAAY,CAACC,GAAG,CAAC;oBAC9E5B,OAAO0B,SAAS;oBAEhBnB,aAAamB;oBAEb,MAAMG,OAAO,MAAMrB;oBACnBR,OAAO6B,MAAM;oBAEb,IAAIA,KAAKC,IAAI,EAAE;wBACbzB,OAAO,CAAC,OAAO,EAAEwB,KAAKC,IAAI,CAAC,QAAQ,EAAED,KAAKE,KAAK,CAAC,EAAE,CAAC;oBACrD,OAAO;wBACL1B,OAAO,CAAC,OAAO,EAAEwB,KAAKE,KAAK,CAAC,CAAC;oBAC/B;oBACA1B;oBAEAgB,YAAYM,YAAY,CAACK,GAAG,CAAC,WAAW;oBACxChB;gBACF,EAAE,OAAOiB,OAAO;oBACd1B,aAAa2B;oBACbb,YAAYM,YAAY,CAACK,GAAG,CAAC,WAAW;oBACxCf,OAAOgB;gBACT,SAAU;oBACRb,IAAIe,SAAS,CAAC,KAAK;wBAAEC,UAAUf,YAAYgB,QAAQ;oBAAG;oBACtDjB,IAAIkB,GAAG;gBACT;YACF;YAEA5B,IAAI6B,IAAI,CAAC,yBAAyB;gBAAE1B;YAAK;YACzCD,OAAO4B,MAAM,CAAC3B;QAChB;QAEA,4DAA4D;QAC5D,kEAAkE;QAClE,kDAAkD;QAClD,MAAMY,MAAM,IAAIH,IAAI,CAAC,QAAQ,EAAEnB,OAAOoB,OAAO,CAACC,QAAQ,CAAC,WAAW,CAAC;QACnEC,IAAIE,YAAY,CAACK,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE7B,OAAOoB,OAAO,CAACC,QAAQ,CAAC,wBAAwB,EAAEX,KAAK,CAAC;QAEpG,IAAI;YACF,MAAMX,KAAKuB,IAAIY,QAAQ;YACvBhC,OAAO,CAAC;;;;IAIV,CAAC;QACD,EAAE,OAAO4B,OAAO;YACdvB,IAAIuB,KAAK,CAAC,0BAA0B;gBAAEA;YAAM;YAC5C5B,OAAO,CAAC;;;gBAGE,EAAEoB,IAAIY,QAAQ,GAAG;;;MAG3B,CAAC;QACH;QAEA,MAAMvB;IACR,SAAU;QACRF,QAAQ6B;IACV;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import getPort from \"get-port\";\nimport assert from \"node:assert\";\nimport http, { type Server } from \"node:http\";\nimport open from \"open\";\nimport type { Command, Usage } from \"../services/command/command.js\";\nimport { config } from \"../services/config/config.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { writeSession } from \"../services/user/session.js\";\nimport { getUser } from \"../services/user/user.js\";\n\nconst log = createLogger({ name: \"login\" });\n\nexport const usage: Usage = () => sprint`\n Log in to your account.\n\n {bold USAGE}\n ggt login\n\n {bold EXAMPLES}\n $ ggt login\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n\n Hello, Jane Doe (jane@example.com)\n`;\n\nexport const login = async (): Promise<void> => {\n let server: Server | undefined;\n\n try {\n const port = await getPort();\n const receiveSession = new Promise<void>((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server = http.createServer(async (req, res) => {\n const landingPage = new URL(`https://${config.domains.services}/auth/cli`);\n\n try {\n assert(req.url, \"missing url\");\n const session = new URL(req.url, `http://localhost:${port}`).searchParams.get(\"session\");\n assert(session, \"missing session\");\n\n writeSession(session);\n\n const user = await getUser();\n assert(user, \"missing user after successful login\");\n\n if (user.name) {\n log.printlns`Hello, ${user.name} {gray (${user.email})}`;\n } else {\n log.printlns`Hello, ${user.email}`;\n }\n\n landingPage.searchParams.set(\"success\", \"true\");\n resolve();\n } catch (error) {\n writeSession(undefined);\n landingPage.searchParams.set(\"success\", \"false\");\n reject(error);\n } finally {\n res.writeHead(303, { Location: landingPage.toString() });\n res.end();\n }\n });\n\n log.info(\"starting login server\", { port });\n server.listen(port);\n });\n\n // open the login page in the user's default browser have it\n // redirect to the cli callback route. The cli callback route will\n // send the session to the server we just started.\n const url = new URL(`https://${config.domains.services}/auth/login`);\n url.searchParams.set(\"returnTo\", `https://${config.domains.services}/auth/cli/callback?port=${port}`);\n\n try {\n await open(url.toString());\n log.printlns`\n We've opened Gadget's login page using your default browser.\n\n Please log in and then return to this terminal.\n `;\n } catch (error) {\n log.error(\"failed to open browser\", { error });\n log.printlns`\n Please open the following URL in your browser and log in:\n\n {gray ${url.toString()}}\n\n Once logged in, return to this terminal.\n `;\n }\n\n await receiveSession;\n } finally {\n server?.close();\n }\n};\n\nexport const command: Command = login;\n"],"names":["getPort","assert","http","open","config","createLogger","sprint","writeSession","getUser","log","name","usage","login","server","port","receiveSession","Promise","resolve","reject","createServer","req","res","landingPage","URL","domains","services","url","session","searchParams","get","user","printlns","email","set","error","undefined","writeHead","Location","toString","end","info","listen","close","command"],"mappings":"AAAA,OAAOA,aAAa,WAAW;AAC/B,OAAOC,YAAY,cAAc;AACjC,OAAOC,UAA2B,YAAY;AAC9C,OAAOC,UAAU,OAAO;AAExB,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,YAAY,QAAQ,mCAAmC;AAChE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,YAAY,QAAQ,8BAA8B;AAC3D,SAASC,OAAO,QAAQ,2BAA2B;AAEnD,MAAMC,MAAMJ,aAAa;IAAEK,MAAM;AAAQ;AAEzC,OAAO,MAAMC,QAAe,IAAML,MAAM,CAAC;;;;;;;;;;;;;AAazC,CAAC,CAAC;AAEF,OAAO,MAAMM,QAAQ;IACnB,IAAIC;IAEJ,IAAI;QACF,MAAMC,OAAO,MAAMd;QACnB,MAAMe,iBAAiB,IAAIC,QAAc,CAACC,SAASC;YACjD,kEAAkE;YAClEL,SAASX,KAAKiB,YAAY,CAAC,OAAOC,KAAKC;gBACrC,MAAMC,cAAc,IAAIC,IAAI,CAAC,QAAQ,EAAEnB,OAAOoB,OAAO,CAACC,QAAQ,CAAC,SAAS,CAAC;gBAEzE,IAAI;oBACFxB,OAAOmB,IAAIM,GAAG,EAAE;oBAChB,MAAMC,UAAU,IAAIJ,IAAIH,IAAIM,GAAG,EAAE,CAAC,iBAAiB,EAAEZ,KAAK,CAAC,EAAEc,YAAY,CAACC,GAAG,CAAC;oBAC9E5B,OAAO0B,SAAS;oBAEhBpB,aAAaoB;oBAEb,MAAMG,OAAO,MAAMtB;oBACnBP,OAAO6B,MAAM;oBAEb,IAAIA,KAAKpB,IAAI,EAAE;wBACbD,IAAIsB,QAAQ,CAAC,OAAO,EAAED,KAAKpB,IAAI,CAAC,QAAQ,EAAEoB,KAAKE,KAAK,CAAC,EAAE,CAAC;oBAC1D,OAAO;wBACLvB,IAAIsB,QAAQ,CAAC,OAAO,EAAED,KAAKE,KAAK,CAAC,CAAC;oBACpC;oBAEAV,YAAYM,YAAY,CAACK,GAAG,CAAC,WAAW;oBACxChB;gBACF,EAAE,OAAOiB,OAAO;oBACd3B,aAAa4B;oBACbb,YAAYM,YAAY,CAACK,GAAG,CAAC,WAAW;oBACxCf,OAAOgB;gBACT,SAAU;oBACRb,IAAIe,SAAS,CAAC,KAAK;wBAAEC,UAAUf,YAAYgB,QAAQ;oBAAG;oBACtDjB,IAAIkB,GAAG;gBACT;YACF;YAEA9B,IAAI+B,IAAI,CAAC,yBAAyB;gBAAE1B;YAAK;YACzCD,OAAO4B,MAAM,CAAC3B;QAChB;QAEA,4DAA4D;QAC5D,kEAAkE;QAClE,kDAAkD;QAClD,MAAMY,MAAM,IAAIH,IAAI,CAAC,QAAQ,EAAEnB,OAAOoB,OAAO,CAACC,QAAQ,CAAC,WAAW,CAAC;QACnEC,IAAIE,YAAY,CAACK,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE7B,OAAOoB,OAAO,CAACC,QAAQ,CAAC,wBAAwB,EAAEX,KAAK,CAAC;QAEpG,IAAI;YACF,MAAMX,KAAKuB,IAAIY,QAAQ;YACvB7B,IAAIsB,QAAQ,CAAC;;;;IAIf,CAAC;QACD,EAAE,OAAOG,OAAO;YACdzB,IAAIyB,KAAK,CAAC,0BAA0B;gBAAEA;YAAM;YAC5CzB,IAAIsB,QAAQ,CAAC;;;gBAGH,EAAEL,IAAIY,QAAQ,GAAG;;;MAG3B,CAAC;QACH;QAEA,MAAMvB;IACR,SAAU;QACRF,QAAQ6B;IACV;AACF,EAAE;AAEF,OAAO,MAAMC,UAAmB/B,MAAM"}
@@ -1,22 +1,26 @@
1
- import { println, sprint } from "../services/output.js";
2
- import { readSession, writeSession } from "../services/session.js";
3
- export const usage = sprint`
1
+ import { createLogger } from "../services/output/log/logger.js";
2
+ import { sprint } from "../services/output/sprint.js";
3
+ import { readSession, writeSession } from "../services/user/session.js";
4
+ const log = createLogger({
5
+ name: "logout"
6
+ });
7
+ export const usage = ()=>sprint`
4
8
  Log out of your account.
5
9
 
6
10
  {bold USAGE}
7
- $ ggt logout
11
+ ggt logout
8
12
 
9
13
  {bold EXAMPLES}
10
- {gray $ ggt logout}
11
- Goodbye
14
+ $ ggt logout
15
+ Goodbye
12
16
  `;
13
- export const run = ()=>{
17
+ export const command = ()=>{
14
18
  const token = readSession();
15
19
  if (token) {
16
20
  writeSession(undefined);
17
- println`Goodbye`;
21
+ log.println("Goodbye");
18
22
  } else {
19
- println`You are not logged in`;
23
+ log.println("You are not logged in");
20
24
  }
21
25
  };
22
26
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/logout.ts"],"sourcesContent":["import { println, sprint } from \"../services/output.js\";\nimport { readSession, writeSession } from \"../services/session.js\";\n\nexport const usage = sprint`\n Log out of your account.\n\n {bold USAGE}\n $ ggt logout\n\n {bold EXAMPLES}\n {gray $ ggt logout}\n Goodbye\n`;\n\nexport const run = () => {\n const token = readSession();\n if (token) {\n writeSession(undefined);\n println`Goodbye`;\n } else {\n println`You are not logged in`;\n }\n};\n"],"names":["println","sprint","readSession","writeSession","usage","run","token","undefined"],"mappings":"AAAA,SAASA,OAAO,EAAEC,MAAM,QAAQ,wBAAwB;AACxD,SAASC,WAAW,EAAEC,YAAY,QAAQ,yBAAyB;AAEnE,OAAO,MAAMC,QAAQH,MAAM,CAAC;;;;;;;;;AAS5B,CAAC,CAAC;AAEF,OAAO,MAAMI,MAAM;IACjB,MAAMC,QAAQJ;IACd,IAAII,OAAO;QACTH,aAAaI;QACbP,OAAO,CAAC,OAAO,CAAC;IAClB,OAAO;QACLA,OAAO,CAAC,qBAAqB,CAAC;IAChC;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/commands/logout.ts"],"sourcesContent":["import type { Command, Usage } from \"../services/command/command.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { readSession, writeSession } from \"../services/user/session.js\";\n\nconst log = createLogger({ name: \"logout\" });\n\nexport const usage: Usage = () => sprint`\n Log out of your account.\n\n {bold USAGE}\n ggt logout\n\n {bold EXAMPLES}\n $ ggt logout\n Goodbye\n`;\n\nexport const command: Command = () => {\n const token = readSession();\n if (token) {\n writeSession(undefined);\n log.println(\"Goodbye\");\n } else {\n log.println(\"You are not logged in\");\n }\n};\n"],"names":["createLogger","sprint","readSession","writeSession","log","name","usage","command","token","undefined","println"],"mappings":"AACA,SAASA,YAAY,QAAQ,mCAAmC;AAChE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,WAAW,EAAEC,YAAY,QAAQ,8BAA8B;AAExE,MAAMC,MAAMJ,aAAa;IAAEK,MAAM;AAAS;AAE1C,OAAO,MAAMC,QAAe,IAAML,MAAM,CAAC;;;;;;;;;AASzC,CAAC,CAAC;AAEF,OAAO,MAAMM,UAAmB;IAC9B,MAAMC,QAAQN;IACd,IAAIM,OAAO;QACTL,aAAaM;QACbL,IAAIM,OAAO,CAAC;IACd,OAAO;QACLN,IAAIM,OAAO,CAAC;IACd;AACF,EAAE"}
@@ -1,64 +1,76 @@
1
1
  import arg from "arg";
2
- import debug from "debug";
3
- import _ from "lodash";
4
- import { parseBoolean } from "../services/args.js";
5
- import { config } from "../services/config.js";
6
- import { CLIError } from "../services/errors.js";
7
- import { println, sortByLevenshtein, sprint } from "../services/output.js";
8
- import { warnIfUpdateAvailable } from "../services/version.js";
9
- import { availableCommands } from "./index.js";
10
- export const usage = sprint`
2
+ import ms from "ms";
3
+ import { AvailableCommands, importCommand, isAvailableCommand } from "../services/command/command.js";
4
+ import { Context } from "../services/command/context.js";
5
+ import { verbosityToLevel } from "../services/output/log/level.js";
6
+ import { createLogger } from "../services/output/log/logger.js";
7
+ import { reportErrorAndExit } from "../services/output/report.js";
8
+ import { sprint } from "../services/output/sprint.js";
9
+ import { warnIfUpdateAvailable } from "../services/output/update.js";
10
+ import { sortBySimilar } from "../services/util/collection.js";
11
+ import { isNil } from "../services/util/is.js";
12
+ const log = createLogger({
13
+ name: "root"
14
+ });
15
+ export const rootUsage = ()=>sprint`
11
16
  The command-line interface for Gadget
12
17
 
13
- {bold VERSION}
14
- ${config.versionFull}
15
-
16
18
  {bold USAGE}
17
- $ ggt [COMMAND]
19
+ ggt [COMMAND]
20
+
21
+ {bold COMMANDS}
22
+ sync Sync your Gadget application's source code
23
+ deploy Deploy your app to production
24
+ list List your apps
25
+ login Log in to your account
26
+ logout Log out of your account
27
+ whoami Print the currently logged in account
28
+ version Print the version of ggt
18
29
 
19
30
  {bold FLAGS}
20
- -h, --help {gray Print command's usage}
21
- -v, --version {gray Print version}
22
- --debug {gray Print debug output}
31
+ -h, --help Print command's usage
32
+ -v, --verbose Print verbose output
33
+ --json Print output as JSON
23
34
 
24
- {bold COMMANDS}
25
- sync Sync your Gadget application's source code to and
26
- from your local filesystem.
27
- list List your apps.
28
- login Log in to your account.
29
- logout Log out of your account.
30
- whoami Print the currently logged in account.
35
+ For more information on a specific command, use 'ggt [COMMAND] --help'
31
36
  `;
32
- export const rootArgsSpec = {
33
- "--help": Boolean,
34
- "-h": "--help",
35
- "--version": Boolean,
36
- "-v": "--version",
37
- "--debug": Boolean
37
+ export const rootArgs = {
38
+ "--help": {
39
+ type: Boolean,
40
+ alias: "-h"
41
+ },
42
+ "--verbose": {
43
+ type: arg.COUNT,
44
+ alias: [
45
+ "-v",
46
+ "--debug"
47
+ ]
48
+ },
49
+ "--json": {
50
+ type: Boolean
51
+ }
38
52
  };
39
- export const run = async ()=>{
40
- await warnIfUpdateAvailable();
41
- const rootArgs = arg(rootArgsSpec, {
53
+ export const command = async ()=>{
54
+ const ctx = new Context(rootArgs, {
42
55
  argv: process.argv.slice(2),
43
- permissive: true,
44
- stopAtPositional: false
56
+ permissive: true
45
57
  });
46
- if (rootArgs["--debug"] ?? parseBoolean(process.env["DEBUG"])) {
47
- debug.enable("ggt:*");
58
+ await warnIfUpdateAvailable();
59
+ if (ctx.args["--json"]) {
60
+ process.env["GGT_LOG_FORMAT"] = "json";
48
61
  }
49
- if (rootArgs["--version"]) {
50
- println(config.version);
51
- process.exit(0);
62
+ if (ctx.args["--verbose"]) {
63
+ process.env["GGT_LOG_LEVEL"] = verbosityToLevel(ctx.args["--verbose"]).toString();
52
64
  }
53
- const command = rootArgs._.shift();
54
- if (_.isNil(command)) {
55
- println(usage);
65
+ const cmd = ctx.args._.shift();
66
+ if (isNil(cmd)) {
67
+ log.println(rootUsage());
56
68
  process.exit(0);
57
69
  }
58
- if (!_.includes(availableCommands, command)) {
59
- const [closest] = sortByLevenshtein(command, availableCommands);
60
- println`
61
- Unknown command {yellow ${command}}
70
+ if (!isAvailableCommand(cmd)) {
71
+ const [closest] = sortBySimilar(cmd, AvailableCommands);
72
+ log.println`
73
+ Unknown command {yellow ${cmd}}
62
74
 
63
75
  Did you mean {blueBright ${closest}}?
64
76
 
@@ -66,19 +78,40 @@ export const run = async ()=>{
66
78
  `;
67
79
  process.exit(1);
68
80
  }
69
- const cmd = await import(`./${command}.js`);
70
- if (rootArgs["--help"]) {
71
- println(cmd.usage);
81
+ const { usage, command, args } = await importCommand(cmd);
82
+ if (ctx.args["--help"]) {
83
+ log.println(usage());
72
84
  process.exit(0);
73
85
  }
74
86
  try {
75
- await cmd.init?.(rootArgs);
76
- await cmd.run(rootArgs);
77
- } catch (cause) {
78
- const error = CLIError.from(cause);
79
- println(error.render());
80
- await error.capture();
81
- process.exit(1);
87
+ await command(ctx.extend({
88
+ args,
89
+ logName: cmd
90
+ }));
91
+ } catch (error) {
92
+ await reportErrorAndExit(error);
93
+ }
94
+ for (const signal of [
95
+ "SIGINT",
96
+ "SIGTERM"
97
+ ]){
98
+ process.once(signal, ()=>{
99
+ log.trace("received signal", {
100
+ signal
101
+ });
102
+ log.println` Stopping... {gray Press Ctrl+C again to force}`;
103
+ ctx.abort();
104
+ // when ggt is run via npx, and the user presses ctrl+c, npx
105
+ // sends sigint twice in quick succession. in order to prevent
106
+ // the second sigint from triggering the force exit listener,
107
+ // we wait a bit before registering it
108
+ setTimeout(()=>{
109
+ process.once(signal, ()=>{
110
+ log.println(" Exiting immediately");
111
+ process.exit(1);
112
+ });
113
+ }, ms("100ms")).unref();
114
+ });
82
115
  }
83
116
  };
84
117
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/root.ts"],"sourcesContent":["import arg from \"arg\";\nimport debug from \"debug\";\nimport _ from \"lodash\";\nimport { parseBoolean } from \"../services/args.js\";\nimport { config } from \"../services/config.js\";\nimport { CLIError } from \"../services/errors.js\";\nimport { println, sortByLevenshtein, sprint } from \"../services/output.js\";\nimport { warnIfUpdateAvailable } from \"../services/version.js\";\nimport { availableCommands, type Command } from \"./index.js\";\n\nexport const usage = sprint`\n The command-line interface for Gadget\n\n {bold VERSION}\n ${config.versionFull}\n\n {bold USAGE}\n $ ggt [COMMAND]\n\n {bold FLAGS}\n -h, --help {gray Print command's usage}\n -v, --version {gray Print version}\n --debug {gray Print debug output}\n\n {bold COMMANDS}\n sync Sync your Gadget application's source code to and\n from your local filesystem.\n list List your apps.\n login Log in to your account.\n logout Log out of your account.\n whoami Print the currently logged in account.\n`;\n\nexport const rootArgsSpec = {\n \"--help\": Boolean,\n \"-h\": \"--help\",\n \"--version\": Boolean,\n \"-v\": \"--version\",\n \"--debug\": Boolean,\n};\n\nexport type RootArgs = arg.Result<typeof rootArgsSpec>;\n\nexport const run = async () => {\n await warnIfUpdateAvailable();\n\n const rootArgs = arg(rootArgsSpec, {\n argv: process.argv.slice(2),\n permissive: true,\n stopAtPositional: false,\n });\n\n if (rootArgs[\"--debug\"] ?? parseBoolean(process.env[\"DEBUG\"])) {\n debug.enable(\"ggt:*\");\n }\n\n if (rootArgs[\"--version\"]) {\n println(config.version);\n process.exit(0);\n }\n\n const command = rootArgs._.shift();\n if (_.isNil(command)) {\n println(usage);\n process.exit(0);\n }\n\n if (!_.includes(availableCommands, command)) {\n const [closest] = sortByLevenshtein(command, availableCommands);\n println`\n Unknown command {yellow ${command}}\n\n Did you mean {blueBright ${closest}}?\n\n Run {gray ggt --help} for usage\n `;\n process.exit(1);\n }\n\n const cmd: Command = await import(`./${command}.js`);\n\n if (rootArgs[\"--help\"]) {\n println(cmd.usage);\n process.exit(0);\n }\n\n try {\n await cmd.init?.(rootArgs);\n await cmd.run(rootArgs);\n } catch (cause) {\n const error = CLIError.from(cause);\n println(error.render());\n await error.capture();\n process.exit(1);\n }\n};\n"],"names":["arg","debug","_","parseBoolean","config","CLIError","println","sortByLevenshtein","sprint","warnIfUpdateAvailable","availableCommands","usage","versionFull","rootArgsSpec","Boolean","run","rootArgs","argv","process","slice","permissive","stopAtPositional","env","enable","version","exit","command","shift","isNil","includes","closest","cmd","init","cause","error","from","render","capture"],"mappings":"AAAA,OAAOA,SAAS,MAAM;AACtB,OAAOC,WAAW,QAAQ;AAC1B,OAAOC,OAAO,SAAS;AACvB,SAASC,YAAY,QAAQ,sBAAsB;AACnD,SAASC,MAAM,QAAQ,wBAAwB;AAC/C,SAASC,QAAQ,QAAQ,wBAAwB;AACjD,SAASC,OAAO,EAAEC,iBAAiB,EAAEC,MAAM,QAAQ,wBAAwB;AAC3E,SAASC,qBAAqB,QAAQ,yBAAyB;AAC/D,SAASC,iBAAiB,QAAsB,aAAa;AAE7D,OAAO,MAAMC,QAAQH,MAAM,CAAC;;;;MAItB,EAAEJ,OAAOQ,WAAW,CAAC;;;;;;;;;;;;;;;;;AAiB3B,CAAC,CAAC;AAEF,OAAO,MAAMC,eAAe;IAC1B,UAAUC;IACV,MAAM;IACN,aAAaA;IACb,MAAM;IACN,WAAWA;AACb,EAAE;AAIF,OAAO,MAAMC,MAAM;IACjB,MAAMN;IAEN,MAAMO,WAAWhB,IAAIa,cAAc;QACjCI,MAAMC,QAAQD,IAAI,CAACE,KAAK,CAAC;QACzBC,YAAY;QACZC,kBAAkB;IACpB;IAEA,IAAIL,QAAQ,CAAC,UAAU,IAAIb,aAAae,QAAQI,GAAG,CAAC,QAAQ,GAAG;QAC7DrB,MAAMsB,MAAM,CAAC;IACf;IAEA,IAAIP,QAAQ,CAAC,YAAY,EAAE;QACzBV,QAAQF,OAAOoB,OAAO;QACtBN,QAAQO,IAAI,CAAC;IACf;IAEA,MAAMC,UAAUV,SAASd,CAAC,CAACyB,KAAK;IAChC,IAAIzB,EAAE0B,KAAK,CAACF,UAAU;QACpBpB,QAAQK;QACRO,QAAQO,IAAI,CAAC;IACf;IAEA,IAAI,CAACvB,EAAE2B,QAAQ,CAACnB,mBAAmBgB,UAAU;QAC3C,MAAM,CAACI,QAAQ,GAAGvB,kBAAkBmB,SAAShB;QAC7CJ,OAAO,CAAC;8BACkB,EAAEoB,QAAQ;;+BAET,EAAEI,QAAQ;;;IAGrC,CAAC;QACDZ,QAAQO,IAAI,CAAC;IACf;IAEA,MAAMM,MAAe,MAAM,MAAM,CAAC,CAAC,EAAE,EAAEL,QAAQ,GAAG,CAAC;IAEnD,IAAIV,QAAQ,CAAC,SAAS,EAAE;QACtBV,QAAQyB,IAAIpB,KAAK;QACjBO,QAAQO,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAMM,IAAIC,IAAI,GAAGhB;QACjB,MAAMe,IAAIhB,GAAG,CAACC;IAChB,EAAE,OAAOiB,OAAO;QACd,MAAMC,QAAQ7B,SAAS8B,IAAI,CAACF;QAC5B3B,QAAQ4B,MAAME,MAAM;QACpB,MAAMF,MAAMG,OAAO;QACnBnB,QAAQO,IAAI,CAAC;IACf;AACF,EAAE"}
1
+ {"version":3,"sources":["../../src/commands/root.ts"],"sourcesContent":["import arg from \"arg\";\nimport ms from \"ms\";\nimport type { ArgsSpec } from \"../services/command/arg.js\";\nimport { AvailableCommands, importCommand, isAvailableCommand, type Usage } from \"../services/command/command.js\";\nimport { Context } from \"../services/command/context.js\";\nimport { verbosityToLevel } from \"../services/output/log/level.js\";\nimport { createLogger } from \"../services/output/log/logger.js\";\nimport { reportErrorAndExit } from \"../services/output/report.js\";\nimport { sprint } from \"../services/output/sprint.js\";\nimport { warnIfUpdateAvailable } from \"../services/output/update.js\";\nimport { sortBySimilar } from \"../services/util/collection.js\";\nimport { isNil } from \"../services/util/is.js\";\n\nconst log = createLogger({ name: \"root\" });\n\nexport const rootUsage: Usage = () => sprint`\n The command-line interface for Gadget\n\n {bold USAGE}\n ggt [COMMAND]\n\n {bold COMMANDS}\n sync Sync your Gadget application's source code\n deploy Deploy your app to production\n list List your apps\n login Log in to your account\n logout Log out of your account\n whoami Print the currently logged in account\n version Print the version of ggt\n\n {bold FLAGS}\n -h, --help Print command's usage\n -v, --verbose Print verbose output\n --json Print output as JSON\n\n For more information on a specific command, use 'ggt [COMMAND] --help'\n`;\n\nexport const rootArgs = {\n \"--help\": {\n type: Boolean,\n alias: \"-h\",\n },\n \"--verbose\": {\n type: arg.COUNT,\n alias: [\"-v\", \"--debug\"],\n },\n \"--json\": {\n type: Boolean,\n },\n} satisfies ArgsSpec;\n\nexport const command = async (): Promise<void> => {\n const ctx = new Context(rootArgs, { argv: process.argv.slice(2), permissive: true });\n\n await warnIfUpdateAvailable();\n\n if (ctx.args[\"--json\"]) {\n process.env[\"GGT_LOG_FORMAT\"] = \"json\";\n }\n\n if (ctx.args[\"--verbose\"]) {\n process.env[\"GGT_LOG_LEVEL\"] = verbosityToLevel(ctx.args[\"--verbose\"]).toString();\n }\n\n const cmd = ctx.args._.shift();\n if (isNil(cmd)) {\n log.println(rootUsage());\n process.exit(0);\n }\n\n if (!isAvailableCommand(cmd)) {\n const [closest] = sortBySimilar(cmd, AvailableCommands);\n log.println`\n Unknown command {yellow ${cmd}}\n\n Did you mean {blueBright ${closest}}?\n\n Run {gray ggt --help} for usage\n `;\n process.exit(1);\n }\n\n const { usage, command, args } = await importCommand(cmd);\n\n if (ctx.args[\"--help\"]) {\n log.println(usage());\n process.exit(0);\n }\n\n try {\n await command(ctx.extend({ args, logName: cmd }));\n } catch (error) {\n await reportErrorAndExit(error);\n }\n\n for (const signal of [\"SIGINT\", \"SIGTERM\"] as const) {\n process.once(signal, () => {\n log.trace(\"received signal\", { signal });\n log.println` Stopping... {gray Press Ctrl+C again to force}`;\n ctx.abort();\n\n // when ggt is run via npx, and the user presses ctrl+c, npx\n // sends sigint twice in quick succession. in order to prevent\n // the second sigint from triggering the force exit listener,\n // we wait a bit before registering it\n setTimeout(() => {\n process.once(signal, () => {\n log.println(\" Exiting immediately\");\n process.exit(1);\n });\n }, ms(\"100ms\")).unref();\n });\n }\n};\n"],"names":["arg","ms","AvailableCommands","importCommand","isAvailableCommand","Context","verbosityToLevel","createLogger","reportErrorAndExit","sprint","warnIfUpdateAvailable","sortBySimilar","isNil","log","name","rootUsage","rootArgs","type","Boolean","alias","COUNT","command","ctx","argv","process","slice","permissive","args","env","toString","cmd","_","shift","println","exit","closest","usage","extend","logName","error","signal","once","trace","abort","setTimeout","unref"],"mappings":"AAAA,OAAOA,SAAS,MAAM;AACtB,OAAOC,QAAQ,KAAK;AAEpB,SAASC,iBAAiB,EAAEC,aAAa,EAAEC,kBAAkB,QAAoB,iCAAiC;AAClH,SAASC,OAAO,QAAQ,iCAAiC;AACzD,SAASC,gBAAgB,QAAQ,kCAAkC;AACnE,SAASC,YAAY,QAAQ,mCAAmC;AAChE,SAASC,kBAAkB,QAAQ,+BAA+B;AAClE,SAASC,MAAM,QAAQ,+BAA+B;AACtD,SAASC,qBAAqB,QAAQ,+BAA+B;AACrE,SAASC,aAAa,QAAQ,iCAAiC;AAC/D,SAASC,KAAK,QAAQ,yBAAyB;AAE/C,MAAMC,MAAMN,aAAa;IAAEO,MAAM;AAAO;AAExC,OAAO,MAAMC,YAAmB,IAAMN,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;AAqB7C,CAAC,CAAC;AAEF,OAAO,MAAMO,WAAW;IACtB,UAAU;QACRC,MAAMC;QACNC,OAAO;IACT;IACA,aAAa;QACXF,MAAMjB,IAAIoB,KAAK;QACfD,OAAO;YAAC;YAAM;SAAU;IAC1B;IACA,UAAU;QACRF,MAAMC;IACR;AACF,EAAqB;AAErB,OAAO,MAAMG,UAAU;IACrB,MAAMC,MAAM,IAAIjB,QAAQW,UAAU;QAAEO,MAAMC,QAAQD,IAAI,CAACE,KAAK,CAAC;QAAIC,YAAY;IAAK;IAElF,MAAMhB;IAEN,IAAIY,IAAIK,IAAI,CAAC,SAAS,EAAE;QACtBH,QAAQI,GAAG,CAAC,iBAAiB,GAAG;IAClC;IAEA,IAAIN,IAAIK,IAAI,CAAC,YAAY,EAAE;QACzBH,QAAQI,GAAG,CAAC,gBAAgB,GAAGtB,iBAAiBgB,IAAIK,IAAI,CAAC,YAAY,EAAEE,QAAQ;IACjF;IAEA,MAAMC,MAAMR,IAAIK,IAAI,CAACI,CAAC,CAACC,KAAK;IAC5B,IAAIpB,MAAMkB,MAAM;QACdjB,IAAIoB,OAAO,CAAClB;QACZS,QAAQU,IAAI,CAAC;IACf;IAEA,IAAI,CAAC9B,mBAAmB0B,MAAM;QAC5B,MAAM,CAACK,QAAQ,GAAGxB,cAAcmB,KAAK5B;QACrCW,IAAIoB,OAAO,CAAC;8BACc,EAAEH,IAAI;;+BAEL,EAAEK,QAAQ;;;IAGrC,CAAC;QACDX,QAAQU,IAAI,CAAC;IACf;IAEA,MAAM,EAAEE,KAAK,EAAEf,OAAO,EAAEM,IAAI,EAAE,GAAG,MAAMxB,cAAc2B;IAErD,IAAIR,IAAIK,IAAI,CAAC,SAAS,EAAE;QACtBd,IAAIoB,OAAO,CAACG;QACZZ,QAAQU,IAAI,CAAC;IACf;IAEA,IAAI;QACF,MAAMb,QAAQC,IAAIe,MAAM,CAAC;YAAEV;YAAMW,SAASR;QAAI;IAChD,EAAE,OAAOS,OAAO;QACd,MAAM/B,mBAAmB+B;IAC3B;IAEA,KAAK,MAAMC,UAAU;QAAC;QAAU;KAAU,CAAW;QACnDhB,QAAQiB,IAAI,CAACD,QAAQ;YACnB3B,IAAI6B,KAAK,CAAC,mBAAmB;gBAAEF;YAAO;YACtC3B,IAAIoB,OAAO,CAAC,+CAA+C,CAAC;YAC5DX,IAAIqB,KAAK;YAET,4DAA4D;YAC5D,8DAA8D;YAC9D,6DAA6D;YAC7D,sCAAsC;YACtCC,WAAW;gBACTpB,QAAQiB,IAAI,CAACD,QAAQ;oBACnB3B,IAAIoB,OAAO,CAAC;oBACZT,QAAQU,IAAI,CAAC;gBACf;YACF,GAAGjC,GAAG,UAAU4C,KAAK;QACvB;IACF;AACF,EAAE"}