slickenv 0.0.1
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.
- package/bin/run.js +4 -0
- package/dist/base-command.d.ts +24 -0
- package/dist/base-command.d.ts.map +1 -0
- package/dist/base-command.js +74 -0
- package/dist/base-command.js.map +1 -0
- package/dist/commands/diff.d.ts +22 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +52 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/export.d.ts +13 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +61 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/init.d.ts +17 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +90 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +16 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +83 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +14 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +24 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/pull.d.ts +15 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +100 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/push.d.ts +17 -0
- package/dist/commands/push.d.ts.map +1 -0
- package/dist/commands/push.js +136 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/rollback.d.ts +19 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +51 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/share.d.ts +14 -0
- package/dist/commands/share.d.ts.map +1 -0
- package/dist/commands/share.js +79 -0
- package/dist/commands/share.js.map +1 -0
- package/dist/commands/status.d.ts +12 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +93 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/versions.d.ts +13 -0
- package/dist/commands/versions.d.ts.map +1 -0
- package/dist/commands/versions.js +42 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/lib/api.d.ts +11 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +32 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +24 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +91 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +22 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +71 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/crypto.d.ts +30 -0
- package/dist/lib/crypto.d.ts.map +1 -0
- package/dist/lib/crypto.js +56 -0
- package/dist/lib/crypto.js.map +1 -0
- package/dist/lib/errors.d.ts +17 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +33 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/keychain.d.ts +14 -0
- package/dist/lib/keychain.d.ts.map +1 -0
- package/dist/lib/keychain.js +85 -0
- package/dist/lib/keychain.js.map +1 -0
- package/dist/lib/output.d.ts +29 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +69 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/parser.d.ts +13 -0
- package/dist/lib/parser.d.ts.map +1 -0
- package/dist/lib/parser.js +150 -0
- package/dist/lib/parser.js.map +1 -0
- package/oclif.manifest.json +594 -0
- package/package.json +69 -0
package/bin/run.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import type { SlickEnvConfig } from "@slickenv/types";
|
|
3
|
+
export declare abstract class BaseCommand extends Command {
|
|
4
|
+
/** Override to false in commands that don't need a .slickenv config (login, init) */
|
|
5
|
+
protected requiresConfig: boolean;
|
|
6
|
+
/** Override to false in commands that don't need auth (login) */
|
|
7
|
+
protected requiresAuth: boolean;
|
|
8
|
+
protected slickenvConfig: SlickEnvConfig;
|
|
9
|
+
protected authToken: string;
|
|
10
|
+
static baseFlags: {
|
|
11
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
};
|
|
15
|
+
init(): Promise<void>;
|
|
16
|
+
protected success(msg: string): void;
|
|
17
|
+
protected info(msg: string): void;
|
|
18
|
+
protected warning(msg: string): void;
|
|
19
|
+
protected fail(msg: string): never;
|
|
20
|
+
protected catch(error: Error & {
|
|
21
|
+
exitCode?: number;
|
|
22
|
+
}): Promise<unknown>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=base-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.d.ts","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAMtD,8BAAsB,WAAY,SAAQ,OAAO;IAC/C,qFAAqF;IACrF,SAAS,CAAC,cAAc,UAAQ;IAEhC,iEAAiE;IACjE,SAAS,CAAC,YAAY,UAAQ;IAE9B,SAAS,CAAC,cAAc,EAAG,cAAc,CAAC;IAC1C,SAAS,CAAC,SAAS,EAAG,MAAM,CAAC;IAE7B,MAAM,CAAC,SAAS;;;;MAad;IAEI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA4B3B,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIpC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIjC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIpC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK;IAOlC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAMxE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Command, Flags } from "@oclif/core";
|
|
2
|
+
import { loadConfig } from "./lib/config.js";
|
|
3
|
+
import { getValidToken } from "./lib/auth.js";
|
|
4
|
+
import { colors, symbols } from "./lib/output.js";
|
|
5
|
+
import { ConfigError, AuthError } from "./lib/errors.js";
|
|
6
|
+
export class BaseCommand extends Command {
|
|
7
|
+
/** Override to false in commands that don't need a .slickenv config (login, init) */
|
|
8
|
+
requiresConfig = true;
|
|
9
|
+
/** Override to false in commands that don't need auth (login) */
|
|
10
|
+
requiresAuth = true;
|
|
11
|
+
slickenvConfig;
|
|
12
|
+
authToken;
|
|
13
|
+
static baseFlags = {
|
|
14
|
+
json: Flags.boolean({
|
|
15
|
+
description: "Output as JSON",
|
|
16
|
+
default: false,
|
|
17
|
+
}),
|
|
18
|
+
"no-color": Flags.boolean({
|
|
19
|
+
description: "Disable colour output",
|
|
20
|
+
default: false,
|
|
21
|
+
}),
|
|
22
|
+
verbose: Flags.boolean({
|
|
23
|
+
description: "Show additional debug information",
|
|
24
|
+
default: false,
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
async init() {
|
|
28
|
+
await super.init();
|
|
29
|
+
if (this.requiresConfig) {
|
|
30
|
+
try {
|
|
31
|
+
this.slickenvConfig = await loadConfig();
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (error instanceof ConfigError) {
|
|
35
|
+
this.fail(error.message);
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (this.requiresAuth) {
|
|
41
|
+
try {
|
|
42
|
+
this.authToken = await getValidToken();
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof AuthError) {
|
|
46
|
+
this.fail(error.message);
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ── Output Helpers ───────────────────────────────────────────────
|
|
53
|
+
success(msg) {
|
|
54
|
+
this.log(`${colors.success(symbols.success)} ${msg}`);
|
|
55
|
+
}
|
|
56
|
+
info(msg) {
|
|
57
|
+
this.log(`${colors.info(symbols.info)} ${msg}`);
|
|
58
|
+
}
|
|
59
|
+
warning(msg) {
|
|
60
|
+
this.log(`${colors.warning(symbols.warning)} ${msg}`);
|
|
61
|
+
}
|
|
62
|
+
fail(msg) {
|
|
63
|
+
this.log(`${colors.error(symbols.error)} ${msg}`);
|
|
64
|
+
this.exit(1);
|
|
65
|
+
}
|
|
66
|
+
// ── Error Handling ─────────────────────────────────────────────
|
|
67
|
+
catch(error) {
|
|
68
|
+
if (error instanceof ConfigError || error instanceof AuthError) {
|
|
69
|
+
this.fail(error.message);
|
|
70
|
+
}
|
|
71
|
+
return super.catch(error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=base-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.js","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
export default class Diff extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
"version-a": import("@oclif/core/interfaces").Arg<number, {
|
|
7
|
+
max?: number;
|
|
8
|
+
min?: number;
|
|
9
|
+
}>;
|
|
10
|
+
"version-b": import("@oclif/core/interfaces").Arg<number, {
|
|
11
|
+
max?: number;
|
|
12
|
+
min?: number;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
static flags: {
|
|
16
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
};
|
|
20
|
+
run(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,OAAgB,WAAW,SAAiD;IAE5E,OAAgB,QAAQ,WAEtB;IAEF,OAAgB,IAAI;;;;;;;;;MASlB;IAEF,OAAgB,KAAK;;;;MAEnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAkC3B"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Args } from "@oclif/core";
|
|
2
|
+
import { BaseCommand } from "../base-command.js";
|
|
3
|
+
import { createApiClient } from "../lib/api.js";
|
|
4
|
+
import { colors, symbols } from "../lib/output.js";
|
|
5
|
+
export default class Diff extends BaseCommand {
|
|
6
|
+
static description = "Show the diff between two specific versions";
|
|
7
|
+
static examples = [
|
|
8
|
+
"slickenv diff 3 5",
|
|
9
|
+
];
|
|
10
|
+
static args = {
|
|
11
|
+
"version-a": Args.integer({
|
|
12
|
+
description: "First version to compare",
|
|
13
|
+
required: true,
|
|
14
|
+
}),
|
|
15
|
+
"version-b": Args.integer({
|
|
16
|
+
description: "Second version to compare",
|
|
17
|
+
required: true,
|
|
18
|
+
}),
|
|
19
|
+
};
|
|
20
|
+
static flags = {
|
|
21
|
+
...BaseCommand.baseFlags,
|
|
22
|
+
};
|
|
23
|
+
async run() {
|
|
24
|
+
const { args } = await this.parse(Diff);
|
|
25
|
+
const client = createApiClient(this.slickenvConfig.apiUrl, this.authToken);
|
|
26
|
+
const result = await client.query("versions:diff", {
|
|
27
|
+
projectId: this.slickenvConfig.projectId,
|
|
28
|
+
label: this.slickenvConfig.defaultEnvironment,
|
|
29
|
+
versionA: args["version-a"],
|
|
30
|
+
versionB: args["version-b"],
|
|
31
|
+
});
|
|
32
|
+
this.log("");
|
|
33
|
+
this.log(` ${colors.key(this.slickenvConfig.projectName)} / ${this.slickenvConfig.defaultEnvironment}`);
|
|
34
|
+
this.log(` Comparing v${result.versionA} ... v${result.versionB}`);
|
|
35
|
+
this.log("");
|
|
36
|
+
for (const d of result.diffs) {
|
|
37
|
+
if (d.status === "unchanged")
|
|
38
|
+
continue;
|
|
39
|
+
const sym = d.status === "added" ? symbols.added
|
|
40
|
+
: d.status === "removed" ? symbols.removed
|
|
41
|
+
: symbols.modified;
|
|
42
|
+
const color = d.status === "added" ? colors.success
|
|
43
|
+
: d.status === "removed" ? colors.error
|
|
44
|
+
: colors.warning;
|
|
45
|
+
this.log(` ${color(sym)} ${d.key}`);
|
|
46
|
+
}
|
|
47
|
+
this.log("");
|
|
48
|
+
this.log(` ${colors.success(`+${result.summary.added}`)} added ${colors.error(`-${result.summary.removed}`)} removed ${colors.warning(`~${result.summary.modified}`)} modified ${colors.info(`${result.summary.unchanged} unchanged`)}`);
|
|
49
|
+
this.log("");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
export default class Export extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
out: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAAkC;IAE7D,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;;;MAMnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA6C3B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import { Flags } from "@oclif/core";
|
|
3
|
+
import { BaseCommand } from "../base-command.js";
|
|
4
|
+
import { createApiClient } from "../lib/api.js";
|
|
5
|
+
export default class Export extends BaseCommand {
|
|
6
|
+
static description = "Generate a .env.example file";
|
|
7
|
+
static examples = [
|
|
8
|
+
"slickenv export",
|
|
9
|
+
"slickenv export --out ./docs/.env.example",
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
...BaseCommand.baseFlags,
|
|
13
|
+
out: Flags.string({
|
|
14
|
+
description: "Output file path",
|
|
15
|
+
default: ".env.example",
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
async run() {
|
|
19
|
+
const { flags } = await this.parse(Export);
|
|
20
|
+
const client = createApiClient(this.slickenvConfig.apiUrl, this.authToken);
|
|
21
|
+
const snapshot = await client.query("sharing:createSnapshot", {
|
|
22
|
+
projectId: this.slickenvConfig.projectId,
|
|
23
|
+
label: this.slickenvConfig.defaultEnvironment,
|
|
24
|
+
publicOnly: false,
|
|
25
|
+
});
|
|
26
|
+
// Build .env.example content
|
|
27
|
+
const lines = [
|
|
28
|
+
`# .env.example`,
|
|
29
|
+
`# Generated by SlickEnv (v${snapshot.version})`,
|
|
30
|
+
`# ${snapshot.project.name} / ${snapshot.label}`,
|
|
31
|
+
``,
|
|
32
|
+
];
|
|
33
|
+
for (const v of snapshot.variables) {
|
|
34
|
+
// Add metadata comment
|
|
35
|
+
const meta = [];
|
|
36
|
+
if (v.visibility)
|
|
37
|
+
meta.push(`@visibility=${v.visibility}`);
|
|
38
|
+
if (v.required)
|
|
39
|
+
meta.push(`@required=true`);
|
|
40
|
+
if (v.type && v.type !== "string")
|
|
41
|
+
meta.push(`@type=${v.type}`);
|
|
42
|
+
if (v.example)
|
|
43
|
+
meta.push(`@example=${v.example}`);
|
|
44
|
+
if (meta.length > 0) {
|
|
45
|
+
lines.push(`# ${meta.join(" ")}`);
|
|
46
|
+
}
|
|
47
|
+
// Public vars: show value. Private: show example or empty
|
|
48
|
+
if (v.visibility === "public") {
|
|
49
|
+
lines.push(`${v.key}=${v.value}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
lines.push(`${v.key}=${v.example ?? ""}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
lines.push("");
|
|
56
|
+
const content = lines.join("\n");
|
|
57
|
+
await writeFile(flags.out, content, "utf8");
|
|
58
|
+
this.success(`Exported ${snapshot.variables.length} variable${snapshot.variables.length === 1 ? "" : "s"} to ${flags.out}.`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
export default class Init extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
env: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
protected requiresConfig: boolean;
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
private prompt;
|
|
15
|
+
private ensureGitignore;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMjD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,OAAgB,WAAW,SAA4D;IAEvF,OAAgB,QAAQ,WAGtB;IAEF,OAAgB,KAAK;;;;;;MASnB;IAEF,UAAmB,cAAc,UAAS;IAEpC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAkDZ,MAAM;YAUN,eAAe;CAY9B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { readFile, writeFile, access } from "node:fs/promises";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { createInterface } from "node:readline";
|
|
4
|
+
import { Flags } from "@oclif/core";
|
|
5
|
+
import { BaseCommand } from "../base-command.js";
|
|
6
|
+
import { findConfigDir, writeConfig, CONFIG_FILENAME } from "../lib/config.js";
|
|
7
|
+
import { createApiClient } from "../lib/api.js";
|
|
8
|
+
import { isTTY } from "../lib/output.js";
|
|
9
|
+
export default class Init extends BaseCommand {
|
|
10
|
+
static description = "Initialise a SlickEnv project in the current directory";
|
|
11
|
+
static examples = [
|
|
12
|
+
"slickenv init",
|
|
13
|
+
"slickenv init --name my-app --env production",
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
...BaseCommand.baseFlags,
|
|
17
|
+
name: Flags.string({
|
|
18
|
+
description: "Project name",
|
|
19
|
+
}),
|
|
20
|
+
env: Flags.string({
|
|
21
|
+
description: "Environment label (e.g. production, staging)",
|
|
22
|
+
default: "production",
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
requiresConfig = false;
|
|
26
|
+
async run() {
|
|
27
|
+
const { flags } = await this.parse(Init);
|
|
28
|
+
// Check if already initialised
|
|
29
|
+
const existingDir = await findConfigDir();
|
|
30
|
+
if (existingDir) {
|
|
31
|
+
this.warning(`Project already initialised (found ${CONFIG_FILENAME} in ${existingDir}).`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Resolve project name
|
|
35
|
+
let projectName = flags.name;
|
|
36
|
+
if (!projectName) {
|
|
37
|
+
projectName = isTTY ? await this.prompt("Project name", basename(process.cwd())) : basename(process.cwd());
|
|
38
|
+
}
|
|
39
|
+
const envLabel = flags.env ?? "production";
|
|
40
|
+
// Create project via Convex
|
|
41
|
+
const client = createApiClient(undefined, this.authToken);
|
|
42
|
+
let result;
|
|
43
|
+
try {
|
|
44
|
+
result = await client.mutation("projects:create", {
|
|
45
|
+
name: projectName,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
const msg = error?.data?.message ?? error?.message ?? "Failed to create project.";
|
|
50
|
+
this.fail(msg);
|
|
51
|
+
}
|
|
52
|
+
// Write .slickenv config
|
|
53
|
+
const config = {
|
|
54
|
+
version: 1,
|
|
55
|
+
projectId: result.projectId,
|
|
56
|
+
projectName,
|
|
57
|
+
defaultEnvironment: envLabel,
|
|
58
|
+
apiUrl: process.env.SLICKENV_API_URL ?? "https://apienv.slickspender.com",
|
|
59
|
+
};
|
|
60
|
+
await writeConfig(config, process.cwd());
|
|
61
|
+
// Add .env to .gitignore if not already there
|
|
62
|
+
await this.ensureGitignore();
|
|
63
|
+
this.success(`Project "${projectName}" initialised (${result.slug}).`);
|
|
64
|
+
this.info(`Environment: ${envLabel}`);
|
|
65
|
+
this.info(`Config written to ${CONFIG_FILENAME}`);
|
|
66
|
+
}
|
|
67
|
+
async prompt(message, defaultValue) {
|
|
68
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
69
|
+
return new Promise((resolve) => {
|
|
70
|
+
rl.question(` ${message} (${defaultValue}): `, (answer) => {
|
|
71
|
+
rl.close();
|
|
72
|
+
resolve(answer.trim() || defaultValue);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async ensureGitignore() {
|
|
77
|
+
const gitignorePath = join(process.cwd(), ".gitignore");
|
|
78
|
+
try {
|
|
79
|
+
await access(gitignorePath);
|
|
80
|
+
const content = await readFile(gitignorePath, "utf8");
|
|
81
|
+
if (!content.includes(".env")) {
|
|
82
|
+
await writeFile(gitignorePath, content.trimEnd() + "\n.env\n", "utf8");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
await writeFile(gitignorePath, ".env\n", "utf8");
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
export default class Login extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
protected requiresConfig: boolean;
|
|
11
|
+
protected requiresAuth: boolean;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
private waitForAuthCallback;
|
|
14
|
+
private openBrowser;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AASjD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,WAAW;IAC5C,OAAgB,WAAW,SAAoC;IAE/D,OAAgB,QAAQ,WAEtB;IAEF,OAAgB,KAAK;;;;MAEnB;IAEF,UAAmB,cAAc,UAAS;IAC1C,UAAmB,YAAY,UAAS;IAElC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAqBZ,mBAAmB;IAyCjC,OAAO,CAAC,WAAW;CAMpB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { exec } from "node:child_process";
|
|
3
|
+
import { BaseCommand } from "../base-command.js";
|
|
4
|
+
import { resolveToken } from "../lib/auth.js";
|
|
5
|
+
import { storeToken } from "../lib/keychain.js";
|
|
6
|
+
import { createApiClient } from "../lib/api.js";
|
|
7
|
+
import { colors } from "../lib/output.js";
|
|
8
|
+
const CALLBACK_PORT = 9876;
|
|
9
|
+
const AUTH_TIMEOUT_MS = 120_000;
|
|
10
|
+
export default class Login extends BaseCommand {
|
|
11
|
+
static description = "Authenticate via browser OAuth";
|
|
12
|
+
static examples = [
|
|
13
|
+
"slickenv login",
|
|
14
|
+
];
|
|
15
|
+
static flags = {
|
|
16
|
+
...BaseCommand.baseFlags,
|
|
17
|
+
};
|
|
18
|
+
requiresConfig = false;
|
|
19
|
+
requiresAuth = false;
|
|
20
|
+
async run() {
|
|
21
|
+
const existingToken = await resolveToken();
|
|
22
|
+
if (existingToken) {
|
|
23
|
+
this.success("Already authenticated.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.log(`\n ${colors.info("Opening browser for authentication...")}\n`);
|
|
27
|
+
const token = await this.waitForAuthCallback();
|
|
28
|
+
await storeToken(token);
|
|
29
|
+
try {
|
|
30
|
+
const client = createApiClient(undefined, token);
|
|
31
|
+
await client.mutation("users:ensureUser");
|
|
32
|
+
this.success("Logged in successfully.");
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
this.success("Token saved. Could not sync user record — will retry on next command.");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async waitForAuthCallback() {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const timeout = setTimeout(() => {
|
|
41
|
+
server.close();
|
|
42
|
+
reject(new Error("Authentication timed out. Please try again."));
|
|
43
|
+
}, AUTH_TIMEOUT_MS);
|
|
44
|
+
const server = createServer((req, res) => {
|
|
45
|
+
const url = new URL(req.url ?? "/", `http://localhost:${CALLBACK_PORT}`);
|
|
46
|
+
if (url.pathname === "/callback") {
|
|
47
|
+
const token = url.searchParams.get("token");
|
|
48
|
+
if (token) {
|
|
49
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
50
|
+
res.end("<html><body style=\"font-family:system-ui;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#0a0a0a;color:#fafafa\"><div style=\"text-align:center\"><h1>Authenticated</h1><p>You can close this window and return to your terminal.</p></div></body></html>");
|
|
51
|
+
clearTimeout(timeout);
|
|
52
|
+
server.close();
|
|
53
|
+
resolve(token);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
57
|
+
res.end("Missing token parameter.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
res.writeHead(404);
|
|
62
|
+
res.end();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
server.listen(CALLBACK_PORT, () => {
|
|
66
|
+
const authBase = process.env.SLICKENV_AUTH_URL ?? "https://env.slickspender.com";
|
|
67
|
+
const authUrl = `${authBase}/login?callback=http://localhost:${CALLBACK_PORT}/callback`;
|
|
68
|
+
this.openBrowser(authUrl);
|
|
69
|
+
});
|
|
70
|
+
server.on("error", (err) => {
|
|
71
|
+
clearTimeout(timeout);
|
|
72
|
+
reject(new Error(`Could not start auth server on port ${CALLBACK_PORT}: ${err.message}`));
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
openBrowser(url) {
|
|
77
|
+
const { platform } = process;
|
|
78
|
+
const cmd = platform === "darwin" ? "open" : platform === "win32" ? "start" : "xdg-open";
|
|
79
|
+
exec(`${cmd} "${url}"`);
|
|
80
|
+
this.log(` If the browser doesn't open, visit:\n ${colors.info(url)}\n`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
export default class Logout extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
};
|
|
10
|
+
protected requiresConfig: boolean;
|
|
11
|
+
protected requiresAuth: boolean;
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=logout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,OAAgB,WAAW,SAAuC;IAElE,OAAgB,QAAQ,WAEtB;IAEF,OAAgB,KAAK;;;;MAEnB;IAEF,UAAmB,cAAc,UAAS;IAC1C,UAAmB,YAAY,UAAS;IAElC,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAU3B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
import { deleteToken } from "../lib/keychain.js";
|
|
3
|
+
import { resolveToken } from "../lib/auth.js";
|
|
4
|
+
export default class Logout extends BaseCommand {
|
|
5
|
+
static description = "Revoke token and clear local auth";
|
|
6
|
+
static examples = [
|
|
7
|
+
"slickenv logout",
|
|
8
|
+
];
|
|
9
|
+
static flags = {
|
|
10
|
+
...BaseCommand.baseFlags,
|
|
11
|
+
};
|
|
12
|
+
requiresConfig = false;
|
|
13
|
+
requiresAuth = false;
|
|
14
|
+
async run() {
|
|
15
|
+
const token = await resolveToken();
|
|
16
|
+
if (!token) {
|
|
17
|
+
this.info("Not currently authenticated.");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await deleteToken();
|
|
21
|
+
this.success("Logged out. Token cleared from local storage.");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,WAAW;IAC7C,MAAM,CAAU,WAAW,GAAG,mCAAmC,CAAC;IAElE,MAAM,CAAU,QAAQ,GAAG;QACzB,iBAAiB;KAClB,CAAC;IAEF,MAAM,CAAU,KAAK,GAAG;QACtB,GAAG,WAAW,CAAC,SAAS;KACzB,CAAC;IAEiB,cAAc,GAAG,KAAK,CAAC;IACvB,YAAY,GAAG,KAAK,CAAC;IAExC,KAAK,CAAC,GAAG;QACP,MAAM,KAAK,GAAG,MAAM,YAAY,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,WAAW,EAAE,CAAC;QACpB,IAAI,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;IAChE,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseCommand } from "../base-command.js";
|
|
2
|
+
export default class Pull extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static flags: {
|
|
6
|
+
version: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
|
+
"dry-run": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
"no-color": import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=pull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,WAAW;IAC3C,OAAgB,WAAW,SAAyD;IAEpF,OAAgB,QAAQ,WAItB;IAEF,OAAgB,KAAK;;;;;;;MAcnB;IAEI,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAgF3B"}
|