@saplo/cli 0.1.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 (96) hide show
  1. package/README.md +112 -0
  2. package/bin/dev.js +5 -0
  3. package/bin/run.js +5 -0
  4. package/dist/commands/deploy.d.ts +13 -0
  5. package/dist/commands/deploy.d.ts.map +1 -0
  6. package/dist/commands/deploy.js +206 -0
  7. package/dist/commands/deploy.js.map +1 -0
  8. package/dist/commands/domain/add.d.ts +13 -0
  9. package/dist/commands/domain/add.d.ts.map +1 -0
  10. package/dist/commands/domain/add.js +44 -0
  11. package/dist/commands/domain/add.js.map +1 -0
  12. package/dist/commands/domain/ls.d.ts +10 -0
  13. package/dist/commands/domain/ls.d.ts.map +1 -0
  14. package/dist/commands/domain/ls.js +32 -0
  15. package/dist/commands/domain/ls.js.map +1 -0
  16. package/dist/commands/domain/rm.d.ts +13 -0
  17. package/dist/commands/domain/rm.d.ts.map +1 -0
  18. package/dist/commands/domain/rm.js +29 -0
  19. package/dist/commands/domain/rm.js.map +1 -0
  20. package/dist/commands/env/index.d.ts +10 -0
  21. package/dist/commands/env/index.d.ts.map +1 -0
  22. package/dist/commands/env/index.js +34 -0
  23. package/dist/commands/env/index.js.map +1 -0
  24. package/dist/commands/env/pull.d.ts +12 -0
  25. package/dist/commands/env/pull.d.ts.map +1 -0
  26. package/dist/commands/env/pull.js +62 -0
  27. package/dist/commands/env/pull.js.map +1 -0
  28. package/dist/commands/env/rm.d.ts +14 -0
  29. package/dist/commands/env/rm.d.ts.map +1 -0
  30. package/dist/commands/env/rm.js +36 -0
  31. package/dist/commands/env/rm.js.map +1 -0
  32. package/dist/commands/env/set.d.ts +14 -0
  33. package/dist/commands/env/set.d.ts.map +1 -0
  34. package/dist/commands/env/set.js +47 -0
  35. package/dist/commands/env/set.js.map +1 -0
  36. package/dist/commands/init.d.ts +13 -0
  37. package/dist/commands/init.d.ts.map +1 -0
  38. package/dist/commands/init.js +144 -0
  39. package/dist/commands/init.js.map +1 -0
  40. package/dist/commands/link.d.ts +10 -0
  41. package/dist/commands/link.d.ts.map +1 -0
  42. package/dist/commands/link.js +86 -0
  43. package/dist/commands/link.js.map +1 -0
  44. package/dist/commands/login.d.ts +12 -0
  45. package/dist/commands/login.d.ts.map +1 -0
  46. package/dist/commands/login.js +83 -0
  47. package/dist/commands/login.js.map +1 -0
  48. package/dist/commands/logs.d.ts +13 -0
  49. package/dist/commands/logs.d.ts.map +1 -0
  50. package/dist/commands/logs.js +63 -0
  51. package/dist/commands/logs.js.map +1 -0
  52. package/dist/commands/open.d.ts +10 -0
  53. package/dist/commands/open.d.ts.map +1 -0
  54. package/dist/commands/open.js +42 -0
  55. package/dist/commands/open.js.map +1 -0
  56. package/dist/commands/rollback.d.ts +16 -0
  57. package/dist/commands/rollback.d.ts.map +1 -0
  58. package/dist/commands/rollback.js +51 -0
  59. package/dist/commands/rollback.js.map +1 -0
  60. package/dist/commands/status.d.ts +10 -0
  61. package/dist/commands/status.d.ts.map +1 -0
  62. package/dist/commands/status.js +63 -0
  63. package/dist/commands/status.js.map +1 -0
  64. package/dist/commands/whoami.d.ts +7 -0
  65. package/dist/commands/whoami.d.ts.map +1 -0
  66. package/dist/commands/whoami.js +26 -0
  67. package/dist/commands/whoami.js.map +1 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +2 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/lib/api.d.ts +68 -0
  73. package/dist/lib/api.d.ts.map +1 -0
  74. package/dist/lib/api.js +117 -0
  75. package/dist/lib/api.js.map +1 -0
  76. package/dist/lib/config.d.ts +16 -0
  77. package/dist/lib/config.d.ts.map +1 -0
  78. package/dist/lib/config.js +74 -0
  79. package/dist/lib/config.js.map +1 -0
  80. package/dist/lib/detect.d.ts +9 -0
  81. package/dist/lib/detect.d.ts.map +1 -0
  82. package/dist/lib/detect.js +293 -0
  83. package/dist/lib/detect.js.map +1 -0
  84. package/dist/lib/packager.d.ts +18 -0
  85. package/dist/lib/packager.d.ts.map +1 -0
  86. package/dist/lib/packager.js +139 -0
  87. package/dist/lib/packager.js.map +1 -0
  88. package/dist/lib/saplo-config.d.ts +50 -0
  89. package/dist/lib/saplo-config.d.ts.map +1 -0
  90. package/dist/lib/saplo-config.js +203 -0
  91. package/dist/lib/saplo-config.js.map +1 -0
  92. package/dist/lib/ws-logs.d.ts +6 -0
  93. package/dist/lib/ws-logs.d.ts.map +1 -0
  94. package/dist/lib/ws-logs.js +112 -0
  95. package/dist/lib/ws-logs.js.map +1 -0
  96. package/package.json +80 -0
@@ -0,0 +1,63 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { api } from '../lib/api.js';
4
+ import { requireToken, requireProjectConfig } from '../lib/config.js';
5
+ import { pollLogsHttp, defaultLogHandler } from '../lib/ws-logs.js';
6
+ export default class Logs extends Command {
7
+ static description = 'Show logs for the current application deployment';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %>',
10
+ '<%= config.bin %> <%= command.id %> --follow',
11
+ '<%= config.bin %> <%= command.id %> --deployment 42',
12
+ ];
13
+ static flags = {
14
+ follow: Flags.boolean({
15
+ char: 'f',
16
+ description: 'Follow log output (poll for new lines)',
17
+ default: false,
18
+ }),
19
+ deployment: Flags.integer({
20
+ char: 'd',
21
+ description: 'Specific deployment ID',
22
+ }),
23
+ 'app-id': Flags.integer({
24
+ char: 'a',
25
+ description: 'Application ID (overrides .saplo/project.json)',
26
+ }),
27
+ tail: Flags.integer({
28
+ char: 'n',
29
+ description: 'Number of recent lines to show',
30
+ default: 100,
31
+ }),
32
+ };
33
+ async run() {
34
+ const { flags } = await this.parse(Logs);
35
+ requireToken();
36
+ let deploymentId = flags.deployment;
37
+ if (!deploymentId) {
38
+ const appId = flags['app-id'] ?? requireProjectConfig().app_id;
39
+ const deployments = await api.listDeployments(appId);
40
+ const current = deployments.find((d) => d.is_current) ?? deployments[0];
41
+ if (!current) {
42
+ this.error('No deployments found for this application.');
43
+ }
44
+ deploymentId = current.id;
45
+ }
46
+ const deployment = await api.getDeployment(deploymentId);
47
+ this.log(chalk.dim(`Showing logs for deployment #${deploymentId} (${deployment.status})`));
48
+ this.log('');
49
+ if (flags.follow) {
50
+ this.log(chalk.dim('Following logs... Press Ctrl+C to stop.'));
51
+ await pollLogsHttp(deploymentId, defaultLogHandler, 2000);
52
+ }
53
+ else {
54
+ const lines = await api.getLogs(deploymentId);
55
+ const tail = flags.tail;
56
+ const slice = tail > 0 ? lines.slice(-tail) : lines;
57
+ for (const entry of slice) {
58
+ defaultLogHandler(entry.line, entry.stream);
59
+ }
60
+ }
61
+ }
62
+ }
63
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,YAAY,EAAE,oBAAoB,EAAC,MAAM,kBAAkB,CAAA;AACnE,OAAO,EAAC,YAAY,EAAE,iBAAiB,EAAC,MAAM,mBAAmB,CAAA;AAEjE,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAU,WAAW,GAAG,kDAAkD,CAAA;IAEhF,MAAM,CAAU,QAAQ,GAAG;QACzB,qCAAqC;QACrC,8CAA8C;QAC9C,qDAAqD;KACtD,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC;YACpB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,wCAAwC;YACrD,OAAO,EAAE,KAAK;SACf,CAAC;QACF,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;YACxB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,wBAAwB;SACtC,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,gDAAgD;SAC9D,CAAC;QACF,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC;YAClB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,gCAAgC;YAC7C,OAAO,EAAE,GAAG;SACb,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACtC,YAAY,EAAE,CAAA;QAEd,IAAI,YAAY,GAAG,KAAK,CAAC,UAAU,CAAA;QAEnC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,MAAM,CAAA;YAC9D,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;YACpD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAA;YACvE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAA;YAC1D,CAAC;YACD,YAAY,GAAG,OAAO,CAAC,EAAE,CAAA;QAC3B,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,CAAA;QACxD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gCAAgC,YAAY,KAAK,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC1F,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAEZ,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAA;YAC9D,MAAM,YAAY,CAAC,YAAY,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAA;QAC3D,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;YAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;YACvB,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;YACnD,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;gBAC1B,iBAAiB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAA6B,CAAC,CAAA;YACpE,CAAC;QACH,CAAC;IACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Open extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'app-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAQ,MAAM,aAAa,CAAA;AAmB1C,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,OAAgB,WAAW,SAA6C;IAExE,OAAgB,QAAQ,WAA0C;IAElE,OAAgB,KAAK;;MAKpB;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAe3B"}
@@ -0,0 +1,42 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { exec } from 'node:child_process';
3
+ import chalk from 'chalk';
4
+ import { api } from '../lib/api.js';
5
+ import { requireToken, requireProjectConfig } from '../lib/config.js';
6
+ function openUrl(url) {
7
+ const platform = process.platform;
8
+ let cmd;
9
+ if (platform === 'darwin') {
10
+ cmd = `open "${url}"`;
11
+ }
12
+ else if (platform === 'win32') {
13
+ cmd = `start "" "${url}"`;
14
+ }
15
+ else {
16
+ cmd = `xdg-open "${url}"`;
17
+ }
18
+ exec(cmd);
19
+ }
20
+ export default class Open extends Command {
21
+ static description = 'Open the application URL in your browser';
22
+ static examples = ['<%= config.bin %> <%= command.id %>'];
23
+ static flags = {
24
+ 'app-id': Flags.integer({
25
+ char: 'a',
26
+ description: 'Application ID (overrides .saplo/project.json)',
27
+ }),
28
+ };
29
+ async run() {
30
+ const { flags } = await this.parse(Open);
31
+ requireToken();
32
+ const appId = flags['app-id'] ?? requireProjectConfig().app_id;
33
+ const app = await api.getApplication(appId);
34
+ const url = app.url;
35
+ if (!url) {
36
+ this.error('No URL found for this application. It may not be running yet.');
37
+ }
38
+ this.log(`Opening ${chalk.cyan(url)}`);
39
+ openUrl(url);
40
+ }
41
+ }
42
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAC,IAAI,EAAC,MAAM,oBAAoB,CAAA;AACvC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,YAAY,EAAE,oBAAoB,EAAC,MAAM,kBAAkB,CAAA;AAEnE,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,IAAI,GAAW,CAAA;IACf,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,GAAG,GAAG,SAAS,GAAG,GAAG,CAAA;IACvB,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChC,GAAG,GAAG,aAAa,GAAG,GAAG,CAAA;IAC3B,CAAC;SAAM,CAAC;QACN,GAAG,GAAG,aAAa,GAAG,GAAG,CAAA;IAC3B,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAA;AACX,CAAC;AAED,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAU,WAAW,GAAG,0CAA0C,CAAA;IAExE,MAAM,CAAU,QAAQ,GAAG,CAAC,qCAAqC,CAAC,CAAA;IAElE,MAAM,CAAU,KAAK,GAAG;QACtB,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,gDAAgD;SAC9D,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACtC,YAAY,EAAE,CAAA;QAEd,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,MAAM,CAAA;QAC9D,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;QAE3C,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAA;QACnB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAA;QAC7E,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACtC,OAAO,CAAC,GAAG,CAAC,CAAA;IACd,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Rollback extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ deployment_id: import("@oclif/core/lib/interfaces/parser.js").Arg<number | undefined, {
7
+ max?: number | undefined;
8
+ min?: number | undefined;
9
+ }>;
10
+ };
11
+ static flags: {
12
+ 'app-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
16
+ //# sourceMappingURL=rollback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback.d.ts","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAc,MAAM,aAAa,CAAA;AAMhD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,OAAgB,WAAW,SAA6E;IAExG,OAAgB,QAAQ,WAGvB;IAED,OAAgB,IAAI;;;;;MAKnB;IAED,OAAgB,KAAK;;MAKpB;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA6B3B"}
@@ -0,0 +1,51 @@
1
+ import { Command, Args, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { api } from '../lib/api.js';
5
+ import { requireToken, requireProjectConfig } from '../lib/config.js';
6
+ export default class Rollback extends Command {
7
+ static description = 'Roll back to a previous deployment (default: previous successful deploy)';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %>',
10
+ '<%= config.bin %> <%= command.id %> 42',
11
+ ];
12
+ static args = {
13
+ deployment_id: Args.integer({
14
+ description: 'Deployment ID to roll back to (default: previous successful)',
15
+ required: false,
16
+ }),
17
+ };
18
+ static flags = {
19
+ 'app-id': Flags.integer({
20
+ char: 'a',
21
+ description: 'Application ID (overrides .saplo/project.json)',
22
+ }),
23
+ };
24
+ async run() {
25
+ const { args, flags } = await this.parse(Rollback);
26
+ requireToken();
27
+ const appId = flags['app-id'] ?? requireProjectConfig().app_id;
28
+ let targetId = args.deployment_id;
29
+ if (!targetId) {
30
+ // Find previous successful deployment
31
+ const deployments = await api.listDeployments(appId);
32
+ const currentIdx = deployments.findIndex((d) => d.is_current);
33
+ const previous = currentIdx !== -1 ? deployments[currentIdx + 1] : deployments[1];
34
+ if (!previous) {
35
+ this.error('No previous deployment found to roll back to.');
36
+ }
37
+ targetId = previous.id;
38
+ this.log(chalk.dim(`Rolling back to deployment #${targetId}`));
39
+ }
40
+ const spinner = ora('Rolling back...').start();
41
+ try {
42
+ const result = await api.rollback(appId, targetId);
43
+ spinner.succeed(chalk.green(`Rolled back successfully! Now live: deployment #${result.now_live}`));
44
+ }
45
+ catch (err) {
46
+ spinner.fail('Rollback failed');
47
+ this.error(err.message);
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=rollback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollback.js","sourceRoot":"","sources":["../../src/commands/rollback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAChD,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,YAAY,EAAE,oBAAoB,EAAC,MAAM,kBAAkB,CAAA;AAEnE,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,OAAO;IAC3C,MAAM,CAAU,WAAW,GAAG,0EAA0E,CAAA;IAExG,MAAM,CAAU,QAAQ,GAAG;QACzB,qCAAqC;QACrC,wCAAwC;KACzC,CAAA;IAED,MAAM,CAAU,IAAI,GAAG;QACrB,aAAa,EAAE,IAAI,CAAC,OAAO,CAAC;YAC1B,WAAW,EAAE,8DAA8D;YAC3E,QAAQ,EAAE,KAAK;SAChB,CAAC;KACH,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;YACtB,IAAI,EAAE,GAAG;YACT,WAAW,EAAE,gDAAgD;SAC9D,CAAC;KACH,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,IAAI,EAAE,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAChD,YAAY,EAAE,CAAA;QAEd,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,oBAAoB,EAAE,CAAC,MAAM,CAAA;QAE9D,IAAI,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAA;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,sCAAsC;YACtC,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAA;YACpD,MAAM,UAAU,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;YAC7D,MAAM,QAAQ,GAAG,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;YAEjF,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAA;YAC7D,CAAC;YACD,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAA;YACtB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,+BAA+B,QAAQ,EAAE,CAAC,CAAC,CAAA;QAChE,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,CAAA;QAC9C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YAClD,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,mDAAmD,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QACpG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;YAC/B,IAAI,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAA;QACpC,CAAC;IACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Status extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ 'app-id': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAQ,MAAM,aAAa,CAAA;AAe1C,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,OAAgB,WAAW,SAAoE;IAE/F,OAAgB,QAAQ,WAA0C;IAElE,OAAgB,KAAK;;MAKpB;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA2C3B"}
@@ -0,0 +1,63 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { api } from '../lib/api.js';
4
+ import { requireToken, requireProjectConfig } from '../lib/config.js';
5
+ function colorStatus(status) {
6
+ switch (status) {
7
+ case 'running': return chalk.green(status);
8
+ case 'building': return chalk.yellow(status);
9
+ case 'failed': return chalk.red(status);
10
+ case 'stopped': return chalk.dim(status);
11
+ default: return chalk.dim(status);
12
+ }
13
+ }
14
+ export default class Status extends Command {
15
+ static description = 'Show the current status and live deployment of your application';
16
+ static examples = ['<%= config.bin %> <%= command.id %>'];
17
+ static flags = {
18
+ 'app-id': Flags.integer({
19
+ char: 'a',
20
+ description: 'Application ID (overrides .saplo/project.json)',
21
+ }),
22
+ };
23
+ async run() {
24
+ const { flags } = await this.parse(Status);
25
+ requireToken();
26
+ const appId = flags['app-id'] ?? requireProjectConfig().app_id;
27
+ const [app, deployments] = await Promise.all([
28
+ api.getApplication(appId),
29
+ api.listDeployments(appId),
30
+ ]);
31
+ const current = deployments.find((d) => d.is_current);
32
+ this.log('');
33
+ this.log(chalk.bold(`${app.name}`) + chalk.dim(` (#${app.id})`));
34
+ this.log(` Stack: ${app.stack}`);
35
+ this.log(` Status: ${colorStatus(app.status)}`);
36
+ if (app.url)
37
+ this.log(` URL: ${chalk.cyan(app.url)}`);
38
+ if (app.domains && app.domains.length > 0) {
39
+ this.log(` Domains: ${app.domains.join(', ')}`);
40
+ }
41
+ if (current) {
42
+ this.log('');
43
+ this.log(chalk.bold('Current deployment:'));
44
+ this.log(` ID: #${current.id}`);
45
+ this.log(` Status: ${colorStatus(current.status)}`);
46
+ if (current.commit)
47
+ this.log(` Commit: ${current.commit.slice(0, 8)}`);
48
+ if (current.duration_ms)
49
+ this.log(` Duration: ${(current.duration_ms / 1000).toFixed(1)}s`);
50
+ }
51
+ if (deployments.length > 1) {
52
+ this.log('');
53
+ this.log(chalk.bold(`Recent deployments (${deployments.length}):`));
54
+ deployments.slice(0, 5).forEach((d) => {
55
+ const marker = d.is_current ? chalk.green(' * ') : ' ';
56
+ const dur = d.duration_ms ? ` (${(d.duration_ms / 1000).toFixed(1)}s)` : '';
57
+ this.log(`${marker}#${d.id} ${colorStatus(d.status)}${dur}`);
58
+ });
59
+ }
60
+ this.log('');
61
+ }
62
+ }
63
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Whoami extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=whoami.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AAKnC,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,OAAgB,WAAW,SAA0C;IAErE,OAAgB,QAAQ,WAA0C;IAE5D,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAiB3B"}
@@ -0,0 +1,26 @@
1
+ import { Command } from '@oclif/core';
2
+ import chalk from 'chalk';
3
+ import { api } from '../lib/api.js';
4
+ import { requireToken, getGlobalConfig } from '../lib/config.js';
5
+ export default class Whoami extends Command {
6
+ static description = 'Show the currently authenticated user';
7
+ static examples = ['<%= config.bin %> <%= command.id %>'];
8
+ async run() {
9
+ requireToken();
10
+ const config = getGlobalConfig();
11
+ try {
12
+ const whoami = await api.whoami();
13
+ this.log('');
14
+ this.log(chalk.bold('Authenticated as:'));
15
+ this.log(` User: ${chalk.cyan(whoami.user)}`);
16
+ this.log(` Token: ${whoami.token_name}`);
17
+ this.log(` Scopes: ${whoami.scopes.join(', ')}`);
18
+ this.log(` API URL: ${config.api_url}`);
19
+ this.log('');
20
+ }
21
+ catch (err) {
22
+ this.error(err.message);
23
+ }
24
+ }
25
+ }
26
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,YAAY,EAAE,eAAe,EAAC,MAAM,kBAAkB,CAAA;AAE9D,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,MAAM,CAAU,WAAW,GAAG,uCAAuC,CAAA;IAErE,MAAM,CAAU,QAAQ,GAAG,CAAC,qCAAqC,CAAC,CAAA;IAElE,KAAK,CAAC,GAAG;QACP,YAAY,EAAE,CAAA;QACd,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;QAEhC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAA;YACjC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACZ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAA;YACzC,IAAI,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACjD,IAAI,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;YAC3C,IAAI,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAClD,IAAI,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;YACxC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAA;QACpC,CAAC;IACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { run } from '@oclif/core';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { run } from '@oclif/core';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAC,MAAM,aAAa,CAAA"}
@@ -0,0 +1,68 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import type FormData from 'form-data';
3
+ export interface WhoamiResponse {
4
+ user: string;
5
+ scopes: string[];
6
+ token_name: string;
7
+ }
8
+ export interface Application {
9
+ id: number;
10
+ name: string;
11
+ stack: string;
12
+ status: string;
13
+ url?: string;
14
+ domains?: string[];
15
+ }
16
+ export interface Deployment {
17
+ id: number;
18
+ status: string;
19
+ commit?: string;
20
+ duration_ms?: number;
21
+ error?: string;
22
+ is_current?: boolean;
23
+ created_at?: string;
24
+ }
25
+ export interface DeploymentCreateResponse {
26
+ deployment_id: number;
27
+ logs_ws: string;
28
+ }
29
+ export interface EnvVar {
30
+ key: string;
31
+ value?: string;
32
+ is_secret: boolean;
33
+ target: string;
34
+ }
35
+ export interface LogLine {
36
+ ts: string;
37
+ stream: string;
38
+ line: string;
39
+ }
40
+ export declare function createApiClient(token?: string): AxiosInstance;
41
+ export declare function getClient(): AxiosInstance;
42
+ export declare const api: {
43
+ whoami(token?: string): Promise<WhoamiResponse>;
44
+ listApplications(): Promise<Application[]>;
45
+ getApplication(id: number): Promise<Application>;
46
+ createApplication(data: {
47
+ name: string;
48
+ stack: string;
49
+ izolbox_id?: number;
50
+ }): Promise<Application>;
51
+ createDeployment(appId: number, formData: FormData, extraHeaders?: Record<string, string>): Promise<DeploymentCreateResponse>;
52
+ listDeployments(appId: number): Promise<Deployment[]>;
53
+ getDeployment(id: number): Promise<Deployment>;
54
+ getLogs(id: number, since?: string): Promise<LogLine[]>;
55
+ cancelDeployment(id: number): Promise<void>;
56
+ getEnvVars(appId: number): Promise<EnvVar[]>;
57
+ setEnvVars(appId: number, vars: Record<string, string>): Promise<EnvVar[]>;
58
+ deleteEnvVar(appId: number, key: string): Promise<void>;
59
+ listDomains(appId: number): Promise<string[]>;
60
+ addDomain(appId: number, domain: string): Promise<{
61
+ dns_instructions: string;
62
+ }>;
63
+ removeDomain(appId: number, domain: string): Promise<void>;
64
+ rollback(appId: number, deploymentId?: number): Promise<{
65
+ now_live: number;
66
+ }>;
67
+ };
68
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAc,EAAC,aAAa,EAAa,MAAM,OAAO,CAAA;AACtD,OAAO,KAAK,QAAQ,MAAM,WAAW,CAAA;AAGrC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,OAAO,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACb;AAID,wBAAgB,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,CAqD7D;AAED,wBAAgB,SAAS,IAAI,aAAa,CAKzC;AAED,eAAO,MAAM,GAAG;mBACC,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;wBAK3B,OAAO,CAAC,WAAW,EAAE,CAAC;uBAIvB,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;4BAIxB;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,WAAW,CAAC;4BAIzE,MAAM,YAAY,QAAQ,iBAAiB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,wBAAwB,CAAC;2BAWtG,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;sBAInC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;gBAIlC,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;yBAKlC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;sBAIzB,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;sBAI1B,MAAM,QAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;wBAItD,MAAM,OAAO,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;uBAIpC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;qBAI5B,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAC,CAAC;wBAIzD,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;oBAI1C,MAAM,iBAAiB,MAAM,GAAG,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAC,CAAC;CAI5E,CAAA"}
@@ -0,0 +1,117 @@
1
+ import axios from 'axios';
2
+ import { getGlobalConfig } from './config.js';
3
+ let _client = null;
4
+ export function createApiClient(token) {
5
+ const config = getGlobalConfig();
6
+ const baseURL = config.api_url;
7
+ const authToken = token ?? config.token;
8
+ const client = axios.create({
9
+ baseURL,
10
+ timeout: 60_000,
11
+ headers: {
12
+ 'Content-Type': 'application/json',
13
+ 'User-Agent': '@saplo/cli',
14
+ },
15
+ });
16
+ client.interceptors.request.use((req) => {
17
+ if (authToken) {
18
+ req.headers['Authorization'] = `Token ${authToken}`;
19
+ }
20
+ return req;
21
+ });
22
+ client.interceptors.response.use((res) => res, (err) => {
23
+ const status = err.response?.status;
24
+ if (status === 401) {
25
+ const e = new Error('Authentication failed. Check your token or run: saplo login');
26
+ e.code = 'EAUTH';
27
+ throw e;
28
+ }
29
+ if (status === 403) {
30
+ const e = new Error('Permission denied. Your token may not have the required scope.');
31
+ e.code = 'EPERM';
32
+ throw e;
33
+ }
34
+ if (status === 404) {
35
+ const e = new Error('Resource not found. Check your app_id.');
36
+ e.code = 'ENOTFOUND';
37
+ throw e;
38
+ }
39
+ if (status === 413) {
40
+ const e = new Error('Request entity too large (413)');
41
+ e.code = 'EPAYLOAD';
42
+ throw e;
43
+ }
44
+ const msg = err.response?.data?.detail
45
+ ?? err.response?.data?.error
46
+ ?? err.message;
47
+ throw new Error(String(msg));
48
+ });
49
+ return client;
50
+ }
51
+ export function getClient() {
52
+ if (!_client) {
53
+ _client = createApiClient();
54
+ }
55
+ return _client;
56
+ }
57
+ export const api = {
58
+ whoami(token) {
59
+ const client = token ? createApiClient(token) : getClient();
60
+ return client.get('/api/v1/auth/whoami').then((r) => r.data);
61
+ },
62
+ listApplications() {
63
+ return getClient().get('/api/v1/applications/').then((r) => r.data);
64
+ },
65
+ getApplication(id) {
66
+ return getClient().get(`/api/v1/applications/${id}/`).then((r) => r.data);
67
+ },
68
+ createApplication(data) {
69
+ return getClient().post('/api/v1/applications/', data).then((r) => r.data);
70
+ },
71
+ createDeployment(appId, formData, extraHeaders) {
72
+ return getClient()
73
+ .post(`/api/v1/applications/${appId}/deployments/`, formData, {
74
+ headers: { 'Content-Type': 'multipart/form-data', ...extraHeaders },
75
+ timeout: 300_000,
76
+ maxBodyLength: Infinity,
77
+ maxContentLength: Infinity,
78
+ })
79
+ .then((r) => r.data);
80
+ },
81
+ listDeployments(appId) {
82
+ return getClient().get(`/api/v1/applications/${appId}/deployments/`).then((r) => r.data);
83
+ },
84
+ getDeployment(id) {
85
+ return getClient().get(`/api/v1/deployments/${id}/`).then((r) => r.data);
86
+ },
87
+ getLogs(id, since) {
88
+ const params = since ? { since } : {};
89
+ return getClient().get(`/api/v1/deployments/${id}/logs`, { params }).then((r) => r.data);
90
+ },
91
+ cancelDeployment(id) {
92
+ return getClient().post(`/api/v1/deployments/${id}/cancel`).then(() => undefined);
93
+ },
94
+ getEnvVars(appId) {
95
+ return getClient().get(`/api/v1/applications/${appId}/env/`).then((r) => r.data);
96
+ },
97
+ setEnvVars(appId, vars) {
98
+ return getClient().put(`/api/v1/applications/${appId}/env/`, { vars }).then((r) => r.data);
99
+ },
100
+ deleteEnvVar(appId, key) {
101
+ return getClient().delete(`/api/v1/applications/${appId}/env/`, { data: { key } }).then(() => undefined);
102
+ },
103
+ listDomains(appId) {
104
+ return getClient().get(`/api/v1/applications/${appId}/domains/`).then((r) => r.data);
105
+ },
106
+ addDomain(appId, domain) {
107
+ return getClient().post(`/api/v1/applications/${appId}/domains/`, { domain }).then((r) => r.data);
108
+ },
109
+ removeDomain(appId, domain) {
110
+ return getClient().delete(`/api/v1/applications/${appId}/domains/`, { data: { domain } }).then(() => undefined);
111
+ },
112
+ rollback(appId, deploymentId) {
113
+ const data = deploymentId ? { deployment_id: deploymentId } : {};
114
+ return getClient().post(`/api/v1/applications/${appId}/rollback/`, data).then((r) => r.data);
115
+ },
116
+ };
117
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export interface GlobalConfig {
2
+ token?: string;
3
+ api_url: string;
4
+ }
5
+ export interface ProjectConfig {
6
+ app_id: number;
7
+ app_name?: string;
8
+ }
9
+ export declare function getGlobalConfig(): GlobalConfig;
10
+ export declare function saveGlobalConfig(config: Partial<GlobalConfig>): void;
11
+ export declare function clearToken(): void;
12
+ export declare function getProjectConfig(cwd?: string): ProjectConfig | null;
13
+ export declare function saveProjectConfig(config: ProjectConfig, cwd?: string): void;
14
+ export declare function requireToken(): string;
15
+ export declare function requireProjectConfig(cwd?: string): ProjectConfig;
16
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAQD,wBAAgB,eAAe,IAAI,YAAY,CAe9C;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAQpE;AAED,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAsB,GAAG,aAAa,GAAG,IAAI,CASlF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,GAAE,MAAsB,GAAG,IAAI,CAO1F;AAED,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,GAAE,MAAsB,GAAG,aAAa,CAM/E"}