@lizard-build/cli 0.1.0 → 0.3.29
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/.github/workflows/release.yml +90 -0
- package/README.md +41 -0
- package/dist/commands/add.js +318 -45
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +68 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/docs.d.ts +2 -0
- package/dist/commands/docs.js +13 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/domain.d.ts +9 -0
- package/dist/commands/domain.js +195 -0
- package/dist/commands/domain.js.map +1 -0
- package/dist/commands/git.js +175 -36
- package/dist/commands/git.js.map +1 -1
- package/dist/commands/init.d.ts +24 -0
- package/dist/commands/init.js +128 -86
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/link.d.ts +7 -0
- package/dist/commands/link.js +104 -33
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/login.js +4 -3
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logs.js +223 -30
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/open.js +3 -2
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/port.d.ts +7 -0
- package/dist/commands/port.js +49 -0
- package/dist/commands/port.js.map +1 -0
- package/dist/commands/projects.js +36 -6
- package/dist/commands/projects.js.map +1 -1
- package/dist/commands/ps.js +32 -39
- package/dist/commands/ps.js.map +1 -1
- package/dist/commands/redeploy.js +48 -8
- package/dist/commands/redeploy.js.map +1 -1
- package/dist/commands/regions.js +2 -5
- package/dist/commands/regions.js.map +1 -1
- package/dist/commands/restart.js +84 -10
- package/dist/commands/restart.js.map +1 -1
- package/dist/commands/run.d.ts +9 -0
- package/dist/commands/run.js +61 -22
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/scale.d.ts +10 -0
- package/dist/commands/scale.js +166 -0
- package/dist/commands/scale.js.map +1 -0
- package/dist/commands/secrets.js +200 -89
- package/dist/commands/secrets.js.map +1 -1
- package/dist/commands/service-set.d.ts +49 -0
- package/dist/commands/service-set.js +552 -0
- package/dist/commands/service-set.js.map +1 -0
- package/dist/commands/service-show.d.ts +11 -0
- package/dist/commands/service-show.js +44 -0
- package/dist/commands/service-show.js.map +1 -0
- package/dist/commands/service.d.ts +8 -0
- package/dist/commands/service.js +262 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/ssh.d.ts +2 -0
- package/dist/commands/ssh.js +161 -0
- package/dist/commands/ssh.js.map +1 -0
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +49 -38
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/unlink.d.ts +5 -0
- package/dist/commands/unlink.js +18 -0
- package/dist/commands/unlink.js.map +1 -0
- package/dist/commands/up.d.ts +9 -0
- package/dist/commands/up.js +417 -0
- package/dist/commands/up.js.map +1 -0
- package/dist/commands/upgrade.d.ts +2 -0
- package/dist/commands/upgrade.js +79 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/whoami.js +26 -6
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/workspace.d.ts +8 -0
- package/dist/commands/workspace.js +36 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/index.js +204 -82
- package/dist/index.js.map +1 -1
- package/dist/lib/api.d.ts +17 -2
- package/dist/lib/api.js +85 -51
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/auth.d.ts +3 -11
- package/dist/lib/auth.js +16 -36
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config.d.ts +36 -15
- package/dist/lib/config.js +71 -58
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/format.d.ts +1 -0
- package/dist/lib/format.js +17 -4
- package/dist/lib/format.js.map +1 -1
- package/dist/lib/name.d.ts +11 -0
- package/dist/lib/name.js +26 -0
- package/dist/lib/name.js.map +1 -0
- package/dist/lib/picker.d.ts +32 -0
- package/dist/lib/picker.js +91 -0
- package/dist/lib/picker.js.map +1 -0
- package/dist/lib/resolve.d.ts +85 -0
- package/dist/lib/resolve.js +203 -0
- package/dist/lib/resolve.js.map +1 -0
- package/dist/lib/updater.d.ts +16 -0
- package/dist/lib/updater.js +102 -0
- package/dist/lib/updater.js.map +1 -0
- package/lizard-wrapper.sh +2 -0
- package/package.json +11 -3
- package/src/commands/add.ts +388 -56
- package/src/commands/config.ts +80 -0
- package/src/commands/docs.ts +15 -0
- package/src/commands/domain.ts +248 -0
- package/src/commands/git.ts +201 -40
- package/src/commands/init.ts +149 -100
- package/src/commands/link.ts +127 -35
- package/src/commands/login.ts +4 -3
- package/src/commands/logs.ts +283 -27
- package/src/commands/open.ts +3 -2
- package/src/commands/port.ts +57 -0
- package/src/commands/projects.ts +43 -6
- package/src/commands/ps.ts +39 -60
- package/src/commands/redeploy.ts +51 -10
- package/src/commands/regions.ts +2 -6
- package/src/commands/restart.ts +84 -10
- package/src/commands/run.ts +68 -24
- package/src/commands/scale.ts +216 -0
- package/src/commands/secrets.ts +277 -100
- package/src/commands/service-set.ts +669 -0
- package/src/commands/service-show.ts +52 -0
- package/src/commands/service.ts +298 -0
- package/src/commands/ssh.ts +176 -0
- package/src/commands/status.ts +51 -46
- package/src/commands/unlink.ts +17 -0
- package/src/commands/up.ts +461 -0
- package/src/commands/upgrade.ts +87 -0
- package/src/commands/whoami.ts +34 -6
- package/src/commands/workspace.ts +44 -0
- package/src/index.ts +214 -85
- package/src/lib/api.ts +114 -51
- package/src/lib/auth.ts +22 -46
- package/src/lib/config.ts +100 -65
- package/src/lib/format.ts +18 -4
- package/src/lib/name.ts +27 -0
- package/src/lib/picker.ts +133 -0
- package/src/lib/resolve.ts +285 -0
- package/src/lib/updater.ts +106 -0
- package/test/cli.test.ts +491 -0
- package/test/fixtures/hello-app/Dockerfile +5 -0
- package/test/fixtures/hello-app/index.js +5 -0
- package/test/unit/api.test.ts +66 -0
- package/test/unit/config.test.ts +94 -0
- package/test/unit/init.test.ts +211 -0
- package/test/unit/json.test.ts +208 -0
- package/test/unit/picker.test.ts +161 -0
- package/test/unit/resolve.test.ts +124 -0
- package/test/unit/service-set.test.ts +355 -0
- package/vitest.config.ts +10 -0
- package/dist/commands/connect.d.ts +0 -2
- package/dist/commands/connect.js +0 -117
- package/dist/commands/connect.js.map +0 -1
- package/dist/commands/context.d.ts +0 -2
- package/dist/commands/context.js +0 -71
- package/dist/commands/context.js.map +0 -1
- package/dist/commands/deploy.d.ts +0 -2
- package/dist/commands/deploy.js +0 -120
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/destroy.d.ts +0 -2
- package/dist/commands/destroy.js +0 -51
- package/dist/commands/destroy.js.map +0 -1
- package/dist/commands/update.d.ts +0 -2
- package/dist/commands/update.js +0 -41
- package/dist/commands/update.js.map +0 -1
- package/dist/commands/version.d.ts +0 -2
- package/dist/commands/version.js +0 -37
- package/dist/commands/version.js.map +0 -1
- package/src/commands/connect.ts +0 -145
- package/src/commands/context.ts +0 -93
- package/src/commands/deploy.ts +0 -153
- package/src/commands/destroy.ts +0 -51
- package/src/commands/update.ts +0 -44
- package/src/commands/version.ts +0 -37
package/dist/lib/auth.d.ts
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
expiresAt?: string;
|
|
5
|
-
userId: string;
|
|
6
|
-
username: string;
|
|
7
|
-
email?: string;
|
|
8
|
-
avatarUrl?: string;
|
|
9
|
-
}
|
|
10
|
-
export declare function setTokenOverride(token: string): void;
|
|
11
|
-
/** Get the active token in priority order: override → env → file */
|
|
1
|
+
import { type Credentials } from "./config.js";
|
|
2
|
+
export type { Credentials } from "./config.js";
|
|
3
|
+
/** Get the active token in priority order: env → file */
|
|
12
4
|
export declare function getToken(): string | null;
|
|
13
5
|
export declare function loadCredentials(): Credentials | null;
|
|
14
6
|
export declare function saveCredentials(creds: Credentials): void;
|
package/dist/lib/auth.js
CHANGED
|
@@ -1,42 +1,23 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import os from "node:os";
|
|
4
1
|
import open from "open";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let tokenOverride = null;
|
|
8
|
-
export function setTokenOverride(token) {
|
|
9
|
-
tokenOverride = token;
|
|
10
|
-
}
|
|
11
|
-
/** Get the active token in priority order: override → env → file */
|
|
2
|
+
import { loadConfig, saveConfig, } from "./config.js";
|
|
3
|
+
/** Get the active token in priority order: env → file */
|
|
12
4
|
export function getToken() {
|
|
13
|
-
if (tokenOverride)
|
|
14
|
-
return tokenOverride;
|
|
15
5
|
if (process.env.LIZARD_TOKEN)
|
|
16
6
|
return process.env.LIZARD_TOKEN;
|
|
17
|
-
|
|
18
|
-
return creds?.accessToken ?? null;
|
|
7
|
+
return loadCredentials()?.accessToken ?? null;
|
|
19
8
|
}
|
|
20
9
|
export function loadCredentials() {
|
|
21
|
-
|
|
22
|
-
const data = fs.readFileSync(CREDENTIALS_FILE, "utf-8");
|
|
23
|
-
return JSON.parse(data);
|
|
24
|
-
}
|
|
25
|
-
catch {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
10
|
+
return loadConfig().credentials ?? null;
|
|
28
11
|
}
|
|
29
12
|
export function saveCredentials(creds) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
config.credentials = creds;
|
|
15
|
+
saveConfig(config);
|
|
34
16
|
}
|
|
35
17
|
export function clearCredentials() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
catch { }
|
|
18
|
+
const config = loadConfig();
|
|
19
|
+
delete config.credentials;
|
|
20
|
+
saveConfig(config);
|
|
40
21
|
}
|
|
41
22
|
export function isLoggedIn() {
|
|
42
23
|
return getToken() !== null;
|
|
@@ -49,10 +30,9 @@ function isTTY() {
|
|
|
49
30
|
* Returns credentials or throws.
|
|
50
31
|
*/
|
|
51
32
|
export async function requireAuth() {
|
|
52
|
-
|
|
53
|
-
if (tokenOverride || process.env.LIZARD_TOKEN) {
|
|
33
|
+
if (process.env.LIZARD_TOKEN) {
|
|
54
34
|
return {
|
|
55
|
-
accessToken:
|
|
35
|
+
accessToken: process.env.LIZARD_TOKEN,
|
|
56
36
|
userId: "",
|
|
57
37
|
username: "",
|
|
58
38
|
};
|
|
@@ -60,11 +40,11 @@ export async function requireAuth() {
|
|
|
60
40
|
const creds = loadCredentials();
|
|
61
41
|
if (creds)
|
|
62
42
|
return creds;
|
|
63
|
-
// Not logged in
|
|
64
43
|
if (!isTTY()) {
|
|
65
|
-
|
|
44
|
+
const err = new Error("Not authenticated. Set LIZARD_TOKEN or run `lizard login` first.");
|
|
45
|
+
err.code = "NOT_AUTHENTICATED";
|
|
46
|
+
throw err;
|
|
66
47
|
}
|
|
67
|
-
// Auto-login
|
|
68
48
|
const { performLogin } = await import("../commands/login.js");
|
|
69
49
|
return performLogin();
|
|
70
50
|
}
|
|
@@ -76,7 +56,7 @@ export async function openURL(url) {
|
|
|
76
56
|
!process.env.DISPLAY &&
|
|
77
57
|
!process.env.WAYLAND_DISPLAY;
|
|
78
58
|
if (isSSH || isCI || noDisplay) {
|
|
79
|
-
return false;
|
|
59
|
+
return false;
|
|
80
60
|
}
|
|
81
61
|
try {
|
|
82
62
|
await open(url);
|
package/dist/lib/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,UAAU,EACV,UAAU,GAEX,MAAM,aAAa,CAAC;AAIrB,yDAAyD;AACzD,MAAM,UAAU,QAAQ;IACtB,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC9D,OAAO,eAAe,EAAE,EAAE,WAAW,IAAI,IAAI,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,UAAU,EAAE,CAAC,WAAW,IAAI,IAAI,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,OAAO,MAAM,CAAC,WAAW,CAAC;IAC1B,UAAU,CAAC,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,EAAE,KAAK,IAAI,CAAC;AAC7B,CAAC;AAED,SAAS,KAAK;IACZ,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO;YACL,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;YACrC,MAAM,EAAE,EAAE;YACV,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,kEAAkE,CACvC,CAAC;QAC9B,GAAG,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAC/B,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAC9D,OAAO,YAAY,EAAE,CAAC;AACxB,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,MAAM,KAAK,GAAG,OAAO,CACnB,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAC5E,CAAC;IACF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrC,MAAM,SAAS,GACb,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC5B,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO;QACpB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAE/B,IAAI,KAAK,IAAI,IAAI,IAAI,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,23 +1,44 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export declare const DEFAULT_REGION = "us-east-1";
|
|
2
|
+
export interface Credentials {
|
|
3
|
+
accessToken: string;
|
|
4
|
+
refreshToken?: string;
|
|
5
|
+
expiresAt?: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
username: string;
|
|
8
|
+
email?: string;
|
|
9
|
+
avatarUrl?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ProjectLink {
|
|
3
12
|
projectId: string;
|
|
4
13
|
projectName?: string;
|
|
5
|
-
|
|
14
|
+
/** Workspace the project belongs to. Lazy-filled for legacy links. */
|
|
15
|
+
workspaceId?: string;
|
|
16
|
+
workspaceName?: string;
|
|
17
|
+
/** Active service for this cwd. `appId/appName` are kept as aliases for backwards compat. */
|
|
18
|
+
serviceId?: string;
|
|
19
|
+
serviceName?: string;
|
|
20
|
+
/** @deprecated use serviceId */
|
|
21
|
+
appId?: string;
|
|
22
|
+
/** @deprecated use serviceName */
|
|
23
|
+
appName?: string;
|
|
6
24
|
}
|
|
7
|
-
export interface
|
|
8
|
-
|
|
25
|
+
export interface Config {
|
|
26
|
+
credentials?: Credentials;
|
|
27
|
+
projects?: Record<string, ProjectLink>;
|
|
9
28
|
}
|
|
10
|
-
|
|
11
|
-
export declare function
|
|
12
|
-
/** Save project config in cwd */
|
|
13
|
-
export declare function saveProjectConfig(config: ProjectConfig): void;
|
|
14
|
-
export declare function loadGlobalSettings(): GlobalSettings;
|
|
15
|
-
export declare function saveGlobalSettings(settings: GlobalSettings): void;
|
|
29
|
+
export declare function loadConfig(): Config;
|
|
30
|
+
export declare function saveConfig(config: Config): void;
|
|
16
31
|
/**
|
|
17
|
-
*
|
|
32
|
+
* Read the link for a directory. Normalises legacy `appId/appName` into
|
|
33
|
+
* `serviceId/serviceName` so callers only have to look at one pair.
|
|
18
34
|
*/
|
|
19
|
-
export declare function
|
|
35
|
+
export declare function getProjectLink(cwd?: string): ProjectLink | null;
|
|
36
|
+
export declare function setProjectLink(link: ProjectLink, cwd?: string): void;
|
|
37
|
+
export declare function updateProjectLink(patch: Partial<ProjectLink>, cwd?: string): void;
|
|
38
|
+
export declare function clearProjectLink(cwd?: string): void;
|
|
20
39
|
/**
|
|
21
|
-
* Resolve
|
|
40
|
+
* Resolve a project flag (name, slug, or ID) to an actual project ID.
|
|
41
|
+
* When no flag is given, falls back to the linked cwd. Hits the API only
|
|
42
|
+
* when a flag is provided so name/slug lookups work as advertised.
|
|
22
43
|
*/
|
|
23
|
-
export declare function
|
|
44
|
+
export declare function resolveProjectId(flagValue?: string): Promise<string>;
|
package/dist/lib/config.js
CHANGED
|
@@ -1,77 +1,90 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import os from "node:os";
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (fs.existsSync(configPath)) {
|
|
13
|
-
try {
|
|
14
|
-
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
const parent = path.dirname(dir);
|
|
21
|
-
if (parent === dir)
|
|
22
|
-
break;
|
|
23
|
-
dir = parent;
|
|
24
|
-
}
|
|
25
|
-
return null;
|
|
4
|
+
export const DEFAULT_REGION = "us-east-1";
|
|
5
|
+
// Resolve at every call so tests (and exotic shells that mutate HOME) get a
|
|
6
|
+
// fresh path. Cost is negligible — we hit disk anyway. LIZARD_HOME lets tests
|
|
7
|
+
// (and power users) point the config dir somewhere other than ~/.lizard.
|
|
8
|
+
function configDir() {
|
|
9
|
+
return process.env.LIZARD_HOME
|
|
10
|
+
? path.join(process.env.LIZARD_HOME, ".lizard")
|
|
11
|
+
: path.join(os.homedir(), ".lizard");
|
|
26
12
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const dir = path.join(process.cwd(), CONFIG_DIR);
|
|
30
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
31
|
-
fs.writeFileSync(path.join(dir, CONFIG_FILE), JSON.stringify(config, null, 2));
|
|
32
|
-
// Add .lizard/ to .gitignore if not already there
|
|
33
|
-
const gitignorePath = path.join(process.cwd(), ".gitignore");
|
|
34
|
-
try {
|
|
35
|
-
const existing = fs.existsSync(gitignorePath)
|
|
36
|
-
? fs.readFileSync(gitignorePath, "utf-8")
|
|
37
|
-
: "";
|
|
38
|
-
if (!existing.includes(".lizard/")) {
|
|
39
|
-
fs.appendFileSync(gitignorePath, (existing.endsWith("\n") ? "" : "\n") + ".lizard/\n");
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
catch { }
|
|
13
|
+
function configFile() {
|
|
14
|
+
return path.join(configDir(), "config.json");
|
|
43
15
|
}
|
|
44
|
-
export function
|
|
16
|
+
export function loadConfig() {
|
|
45
17
|
try {
|
|
46
|
-
return JSON.parse(fs.readFileSync(
|
|
18
|
+
return JSON.parse(fs.readFileSync(configFile(), "utf-8"));
|
|
47
19
|
}
|
|
48
20
|
catch {
|
|
49
21
|
return {};
|
|
50
22
|
}
|
|
51
23
|
}
|
|
52
|
-
export function
|
|
53
|
-
|
|
54
|
-
fs.
|
|
55
|
-
|
|
24
|
+
export function saveConfig(config) {
|
|
25
|
+
fs.mkdirSync(configDir(), { recursive: true });
|
|
26
|
+
fs.writeFileSync(configFile(), JSON.stringify(config, null, 2), {
|
|
27
|
+
mode: 0o600,
|
|
28
|
+
});
|
|
56
29
|
}
|
|
57
30
|
/**
|
|
58
|
-
*
|
|
31
|
+
* Read the link for a directory. Normalises legacy `appId/appName` into
|
|
32
|
+
* `serviceId/serviceName` so callers only have to look at one pair.
|
|
59
33
|
*/
|
|
60
|
-
export function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
34
|
+
export function getProjectLink(cwd = process.cwd()) {
|
|
35
|
+
const raw = loadConfig().projects?.[cwd];
|
|
36
|
+
if (!raw)
|
|
37
|
+
return null;
|
|
38
|
+
return {
|
|
39
|
+
...raw,
|
|
40
|
+
serviceId: raw.serviceId ?? raw.appId,
|
|
41
|
+
serviceName: raw.serviceName ?? raw.appName,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function setProjectLink(link, cwd = process.cwd()) {
|
|
45
|
+
const config = loadConfig();
|
|
46
|
+
config.projects ??= {};
|
|
47
|
+
// Mirror service↔app for older readers.
|
|
48
|
+
const normalised = {
|
|
49
|
+
...link,
|
|
50
|
+
appId: link.serviceId ?? link.appId,
|
|
51
|
+
appName: link.serviceName ?? link.appName,
|
|
52
|
+
serviceId: link.serviceId ?? link.appId,
|
|
53
|
+
serviceName: link.serviceName ?? link.appName,
|
|
54
|
+
};
|
|
55
|
+
config.projects[cwd] = normalised;
|
|
56
|
+
saveConfig(config);
|
|
57
|
+
}
|
|
58
|
+
export function updateProjectLink(patch, cwd = process.cwd()) {
|
|
59
|
+
const existing = getProjectLink(cwd);
|
|
60
|
+
if (!existing)
|
|
61
|
+
return;
|
|
62
|
+
setProjectLink({ ...existing, ...patch }, cwd);
|
|
63
|
+
}
|
|
64
|
+
export function clearProjectLink(cwd = process.cwd()) {
|
|
65
|
+
const config = loadConfig();
|
|
66
|
+
if (config.projects) {
|
|
67
|
+
delete config.projects[cwd];
|
|
68
|
+
saveConfig(config);
|
|
69
|
+
}
|
|
67
70
|
}
|
|
68
71
|
/**
|
|
69
|
-
* Resolve
|
|
72
|
+
* Resolve a project flag (name, slug, or ID) to an actual project ID.
|
|
73
|
+
* When no flag is given, falls back to the linked cwd. Hits the API only
|
|
74
|
+
* when a flag is provided so name/slug lookups work as advertised.
|
|
70
75
|
*/
|
|
71
|
-
export function
|
|
72
|
-
if (flagValue)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
export async function resolveProjectId(flagValue) {
|
|
77
|
+
if (!flagValue) {
|
|
78
|
+
const link = getProjectLink();
|
|
79
|
+
if (link?.projectId)
|
|
80
|
+
return link.projectId;
|
|
81
|
+
throw new Error("No project linked. Run `lizard init` or pass --project <id>.");
|
|
82
|
+
}
|
|
83
|
+
const { api } = await import("./api.js");
|
|
84
|
+
const projects = await api.get("/api/projects");
|
|
85
|
+
const match = projects.find((p) => p.id === flagValue || p.slug === flagValue || p.name === flagValue);
|
|
86
|
+
if (!match)
|
|
87
|
+
throw new Error(`Project "${flagValue}" not found.`);
|
|
88
|
+
return match.id;
|
|
76
89
|
}
|
|
77
90
|
//# sourceMappingURL=config.js.map
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/format.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare function success(msg: string): void;
|
|
|
6
6
|
export declare function error(msg: string): void;
|
|
7
7
|
export declare function warn(msg: string): void;
|
|
8
8
|
export declare function info(msg: string): void;
|
|
9
|
+
export declare function link(url: string, text?: string): string;
|
|
9
10
|
export declare function table(headers: string[], rows: string[][]): void;
|
|
10
11
|
export declare function statusColor(status: string): string;
|
|
11
12
|
export declare function timeAgo(ts: number | string): string;
|
package/dist/lib/format.js
CHANGED
|
@@ -28,24 +28,37 @@ export function info(msg) {
|
|
|
28
28
|
return;
|
|
29
29
|
process.stderr.write(msg + "\n");
|
|
30
30
|
}
|
|
31
|
+
export function link(url, text) {
|
|
32
|
+
const label = text ?? url;
|
|
33
|
+
if (!isTTY())
|
|
34
|
+
return label;
|
|
35
|
+
return `\x1b]8;;${url}\x1b\\${label}\x1b]8;;\x1b\\`;
|
|
36
|
+
}
|
|
37
|
+
const ANSI_RE = /\x1b\[[0-9;]*m/g;
|
|
38
|
+
function visibleLength(s) {
|
|
39
|
+
return s.replace(ANSI_RE, "").length;
|
|
40
|
+
}
|
|
41
|
+
function padVisible(s, width) {
|
|
42
|
+
return s + " ".repeat(Math.max(0, width - visibleLength(s)));
|
|
43
|
+
}
|
|
31
44
|
export function table(headers, rows) {
|
|
32
45
|
if (rows.length === 0)
|
|
33
46
|
return;
|
|
34
|
-
const widths = headers.map((h) => h
|
|
47
|
+
const widths = headers.map((h) => visibleLength(h));
|
|
35
48
|
for (const row of rows) {
|
|
36
49
|
for (let i = 0; i < row.length; i++) {
|
|
37
50
|
if (i < widths.length) {
|
|
38
|
-
widths[i] = Math.max(widths[i], (row[i] || "")
|
|
51
|
+
widths[i] = Math.max(widths[i], visibleLength(row[i] || ""));
|
|
39
52
|
}
|
|
40
53
|
}
|
|
41
54
|
}
|
|
42
55
|
const header = headers
|
|
43
|
-
.map((h, i) => h.toUpperCase()
|
|
56
|
+
.map((h, i) => padVisible(h.toUpperCase(), widths[i]))
|
|
44
57
|
.join(" ");
|
|
45
58
|
console.log(chalk.dim(header));
|
|
46
59
|
for (const row of rows) {
|
|
47
60
|
const line = headers
|
|
48
|
-
.map((_, i) => (row[i] || ""
|
|
61
|
+
.map((_, i) => padVisible(row[i] || "", widths[i]))
|
|
49
62
|
.join(" ");
|
|
50
63
|
console.log(line);
|
|
51
64
|
}
|
package/dist/lib/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,UAAU,KAAK;IACnB,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,MAAM,UAAU,WAAW,CAAC,EAAW;IACrC,QAAQ,GAAG,EAAE,CAAC;AAChB,CAAC;AACD,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAa;IACrC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,QAAQ;QAAE,OAAO;IACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,IAAI,QAAQ;QAAE,OAAO;IACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,KAAK,CACnB,OAAiB,EACjB,IAAgB;IAEhB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE9B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const NAME_REGEX: RegExp;
|
|
2
|
+
export declare const NAME_VALIDATION_HINT = "1\u201340 chars, lowercase a\u2013z, digits, hyphens; can't start or end with a hyphen";
|
|
3
|
+
export declare function validateName(name: string): string | null;
|
|
4
|
+
/** Mirrors `slugifyName` in lizard-client/src/lib/api.ts. */
|
|
5
|
+
export declare function slugifyName(name: string): string;
|
|
6
|
+
/** Mirrors `addonRefName` in lizard-client — what users type inside ${{...}}. */
|
|
7
|
+
export declare function addonRefName(addon: {
|
|
8
|
+
name?: string | null;
|
|
9
|
+
type?: string;
|
|
10
|
+
addonType?: string;
|
|
11
|
+
}): string;
|
package/dist/lib/name.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Shared name validator. Mirrors server/src/services/var-transform.ts.
|
|
2
|
+
// LIZARD-55: 1–40 chars, [a-z0-9-], must start and end with [a-z0-9].
|
|
3
|
+
export const NAME_REGEX = /^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/;
|
|
4
|
+
export const NAME_VALIDATION_HINT = "1–40 chars, lowercase a–z, digits, hyphens; can't start or end with a hyphen";
|
|
5
|
+
export function validateName(name) {
|
|
6
|
+
if (!name)
|
|
7
|
+
return "name is required";
|
|
8
|
+
if (name.length > 40)
|
|
9
|
+
return "name must be 40 characters or fewer";
|
|
10
|
+
if (!NAME_REGEX.test(name))
|
|
11
|
+
return `invalid name (${NAME_VALIDATION_HINT})`;
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
/** Mirrors `slugifyName` in lizard-client/src/lib/api.ts. */
|
|
15
|
+
export function slugifyName(name) {
|
|
16
|
+
return name
|
|
17
|
+
.toLowerCase()
|
|
18
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
19
|
+
.replace(/^-+|-+$/g, "");
|
|
20
|
+
}
|
|
21
|
+
/** Mirrors `addonRefName` in lizard-client — what users type inside ${{...}}. */
|
|
22
|
+
export function addonRefName(addon) {
|
|
23
|
+
const display = addon.name || addon.type || addon.addonType || "";
|
|
24
|
+
return slugifyName(display) || display;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name.js","sourceRoot":"","sources":["../../src/lib/name.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,sEAAsE;AAEtE,MAAM,CAAC,MAAM,UAAU,GAAG,sCAAsC,CAAC;AACjE,MAAM,CAAC,MAAM,oBAAoB,GAC/B,8EAA8E,CAAC;AAEjF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI;QAAE,OAAO,kBAAkB,CAAC;IACrC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,qCAAqC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,iBAAiB,oBAAoB,GAAG,CAAC;IAC5E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC;SAC7B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC7B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,KAAkE;IAC7F,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC;IAClE,OAAO,WAAW,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type Workspace } from "./api.js";
|
|
2
|
+
export declare function fetchWorkspaces(): Promise<Workspace[]>;
|
|
3
|
+
export declare function matchWorkspace(workspaces: Workspace[], idOrSlugOrName: string): Workspace | undefined;
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a workspace by flag value. Fetches the list once; throws with the
|
|
6
|
+
* available names when the value doesn't match anything the user belongs to.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveWorkspace(flagValue: string): Promise<Workspace>;
|
|
9
|
+
/**
|
|
10
|
+
* Pick a workspace for project creation / linking.
|
|
11
|
+
*
|
|
12
|
+
* 1. --workspace flag wins.
|
|
13
|
+
* 2. If only one workspace exists, auto-select it.
|
|
14
|
+
* 3. Non-TTY → prefer personal, else first.
|
|
15
|
+
* 4. TTY → prompt.
|
|
16
|
+
*
|
|
17
|
+
* `projectNameHint` lets the caller short-circuit when --name X uniquely
|
|
18
|
+
* identifies a workspace (see init flow case 5).
|
|
19
|
+
*/
|
|
20
|
+
export declare function pickWorkspace(opts: {
|
|
21
|
+
flag?: string;
|
|
22
|
+
projectNameHint?: string;
|
|
23
|
+
workspaces?: Workspace[];
|
|
24
|
+
}): Promise<Workspace>;
|
|
25
|
+
interface ProjectLite {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
slug: string;
|
|
29
|
+
workspaceId?: string | null;
|
|
30
|
+
}
|
|
31
|
+
export declare function listProjectsInWorkspace(workspaceId: string): Promise<ProjectLite[]>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import { api, withQuery } from "./api.js";
|
|
3
|
+
import { isTTY } from "./format.js";
|
|
4
|
+
export async function fetchWorkspaces() {
|
|
5
|
+
return api.get("/api/workspaces");
|
|
6
|
+
}
|
|
7
|
+
export function matchWorkspace(workspaces, idOrSlugOrName) {
|
|
8
|
+
const lower = idOrSlugOrName.toLowerCase();
|
|
9
|
+
return workspaces.find((w) => w.id.toLowerCase() === lower ||
|
|
10
|
+
w.slug.toLowerCase() === lower ||
|
|
11
|
+
w.name.toLowerCase() === lower);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a workspace by flag value. Fetches the list once; throws with the
|
|
15
|
+
* available names when the value doesn't match anything the user belongs to.
|
|
16
|
+
*/
|
|
17
|
+
export async function resolveWorkspace(flagValue) {
|
|
18
|
+
const workspaces = await fetchWorkspaces();
|
|
19
|
+
const match = matchWorkspace(workspaces, flagValue);
|
|
20
|
+
if (!match) {
|
|
21
|
+
throw new Error(`Workspace "${flagValue}" not found. Available: ${workspaces.map((w) => w.name).join(", ") || "(none)"}`);
|
|
22
|
+
}
|
|
23
|
+
return match;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pick a workspace for project creation / linking.
|
|
27
|
+
*
|
|
28
|
+
* 1. --workspace flag wins.
|
|
29
|
+
* 2. If only one workspace exists, auto-select it.
|
|
30
|
+
* 3. Non-TTY → prefer personal, else first.
|
|
31
|
+
* 4. TTY → prompt.
|
|
32
|
+
*
|
|
33
|
+
* `projectNameHint` lets the caller short-circuit when --name X uniquely
|
|
34
|
+
* identifies a workspace (see init flow case 5).
|
|
35
|
+
*/
|
|
36
|
+
export async function pickWorkspace(opts) {
|
|
37
|
+
if (opts.flag)
|
|
38
|
+
return resolveWorkspace(opts.flag);
|
|
39
|
+
const list = opts.workspaces ?? (await fetchWorkspaces());
|
|
40
|
+
if (list.length === 0) {
|
|
41
|
+
throw new Error("No workspaces available. The backend should always return a personal workspace — please report this.");
|
|
42
|
+
}
|
|
43
|
+
if (list.length === 1)
|
|
44
|
+
return list[0];
|
|
45
|
+
// Hint-based auto-pick: a --name match that is unique across workspaces.
|
|
46
|
+
if (opts.projectNameHint) {
|
|
47
|
+
const matches = await findWorkspacesContainingProject(list, opts.projectNameHint);
|
|
48
|
+
if (matches.length === 1)
|
|
49
|
+
return matches[0].workspace;
|
|
50
|
+
if (matches.length > 1) {
|
|
51
|
+
const detail = matches
|
|
52
|
+
.map((m) => ` • ${m.project.name} in ${m.workspace.name} (--workspace ${m.workspace.slug})`)
|
|
53
|
+
.join("\n");
|
|
54
|
+
throw new Error(`Multiple projects named "${opts.projectNameHint}" found:\n${detail}\nPass --workspace, or run \`lizard init\` without --name to choose interactively.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!isTTY()) {
|
|
58
|
+
// Non-TTY fallback: personal first, else first ws.
|
|
59
|
+
const personal = list.find((w) => w.isPersonal);
|
|
60
|
+
return personal ?? list[0];
|
|
61
|
+
}
|
|
62
|
+
const sel = await p.select({
|
|
63
|
+
message: "Workspace",
|
|
64
|
+
options: list.map((w) => ({
|
|
65
|
+
value: w.id,
|
|
66
|
+
label: w.name,
|
|
67
|
+
hint: `${w.role}${w.isPersonal ? " · personal" : ""} · ${w.projectCount ?? 0} project${(w.projectCount ?? 0) === 1 ? "" : "s"}`,
|
|
68
|
+
})),
|
|
69
|
+
});
|
|
70
|
+
if (p.isCancel(sel))
|
|
71
|
+
process.exit(5);
|
|
72
|
+
return list.find((w) => w.id === sel);
|
|
73
|
+
}
|
|
74
|
+
async function findWorkspacesContainingProject(workspaces, nameOrSlugOrId) {
|
|
75
|
+
const all = await api.get("/api/projects");
|
|
76
|
+
const lower = nameOrSlugOrId.toLowerCase();
|
|
77
|
+
const matches = [];
|
|
78
|
+
for (const w of workspaces) {
|
|
79
|
+
const inWs = all.find((pr) => pr.workspaceId === w.id &&
|
|
80
|
+
(pr.id.toLowerCase() === lower ||
|
|
81
|
+
pr.slug.toLowerCase() === lower ||
|
|
82
|
+
pr.name.toLowerCase() === lower));
|
|
83
|
+
if (inWs)
|
|
84
|
+
matches.push({ workspace: w, project: inWs });
|
|
85
|
+
}
|
|
86
|
+
return matches;
|
|
87
|
+
}
|
|
88
|
+
export async function listProjectsInWorkspace(workspaceId) {
|
|
89
|
+
return api.get(withQuery("/api/projects", { workspaceId }));
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"picker.js","sourceRoot":"","sources":["../../src/lib/picker.ts"],"names":[],"mappings":"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"}
|