@gasboost/console 0.2.0 → 0.3.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.
- package/dist/appsScript/AppsScriptProjectRepository.d.ts +21 -0
- package/dist/appsScript/AppsScriptProjectRepository.d.ts.map +1 -0
- package/dist/appsScript/AppsScriptProjectRepository.js +75 -0
- package/dist/appsScript/AppsScriptProjectRepository.js.map +1 -0
- package/dist/appsScript/appsScriptOperations.d.ts +4 -1
- package/dist/appsScript/appsScriptOperations.d.ts.map +1 -1
- package/dist/appsScript/appsScriptOperations.js +146 -37
- package/dist/appsScript/appsScriptOperations.js.map +1 -1
- package/dist/env/EnvFileRepository.d.ts +13 -0
- package/dist/env/EnvFileRepository.d.ts.map +1 -0
- package/dist/env/EnvFileRepository.js +67 -0
- package/dist/env/EnvFileRepository.js.map +1 -0
- package/dist/firebase/FirebaseProjectRepository.d.ts +17 -0
- package/dist/firebase/FirebaseProjectRepository.d.ts.map +1 -0
- package/dist/firebase/FirebaseProjectRepository.js +82 -0
- package/dist/firebase/FirebaseProjectRepository.js.map +1 -0
- package/dist/firebase/FirebaseRunner.d.ts +10 -0
- package/dist/firebase/FirebaseRunner.d.ts.map +1 -0
- package/dist/firebase/FirebaseRunner.js +54 -0
- package/dist/firebase/FirebaseRunner.js.map +1 -0
- package/dist/firebase/firebaseOperations.d.ts +20 -0
- package/dist/firebase/firebaseOperations.d.ts.map +1 -0
- package/dist/firebase/firebaseOperations.js +96 -0
- package/dist/firebase/firebaseOperations.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/startGasboostConsole.d.ts +3 -1
- package/dist/startGasboostConsole.d.ts.map +1 -1
- package/dist/startGasboostConsole.js +15 -9
- package/dist/startGasboostConsole.js.map +1 -1
- package/dist/ui/assets/index-ClzuMWwT.css +1 -0
- package/dist/ui/assets/index-DSY49jCs.js +6 -0
- package/dist/ui/index.html +154 -11
- package/package.json +1 -1
- package/dist/ui/assets/index-B2QLlRZv.css +0 -1
- package/dist/ui/assets/index-Bv7Miq39.js +0 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FirebaseRunner.d.ts","sourceRoot":"","sources":["../../src/firebase/FirebaseRunner.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,GAAG,EAAE,CACZ,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,KAC9B,OAAO,CAAC,cAAc,CAAC,CAAC;CAC9B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAgCxE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export function createFirebaseRunner(projectRoot) {
|
|
3
|
+
return {
|
|
4
|
+
run: (args, onOutput) => new Promise((resolve, reject) => {
|
|
5
|
+
const child = spawn("pnpm", ["exec", "firebase", ...args], {
|
|
6
|
+
cwd: projectRoot,
|
|
7
|
+
env: { ...process.env, NO_COLOR: "1" },
|
|
8
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
9
|
+
});
|
|
10
|
+
let stdout = "";
|
|
11
|
+
let stderr = "";
|
|
12
|
+
const stdoutLines = createLineEmitter(onOutput);
|
|
13
|
+
const stderrLines = createLineEmitter(onOutput);
|
|
14
|
+
child.stdout.setEncoding("utf8");
|
|
15
|
+
child.stderr.setEncoding("utf8");
|
|
16
|
+
child.stdout.on("data", (chunk) => {
|
|
17
|
+
stdout += chunk;
|
|
18
|
+
stdoutLines.write(chunk);
|
|
19
|
+
});
|
|
20
|
+
child.stderr.on("data", (chunk) => {
|
|
21
|
+
stderr += chunk;
|
|
22
|
+
stderrLines.write(chunk);
|
|
23
|
+
});
|
|
24
|
+
child.once("error", reject);
|
|
25
|
+
child.once("close", (exitCode) => {
|
|
26
|
+
stdoutLines.flush();
|
|
27
|
+
stderrLines.flush();
|
|
28
|
+
resolve({ exitCode: exitCode ?? 1, stdout, stderr });
|
|
29
|
+
});
|
|
30
|
+
}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function createLineEmitter(onOutput) {
|
|
34
|
+
let buffer = "";
|
|
35
|
+
const emit = (line) => {
|
|
36
|
+
const message = line.trim();
|
|
37
|
+
if (message.length > 0)
|
|
38
|
+
onOutput?.(message);
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
write(chunk) {
|
|
42
|
+
buffer += chunk;
|
|
43
|
+
const lines = buffer.split(/\r?\n/);
|
|
44
|
+
buffer = lines.pop() ?? "";
|
|
45
|
+
for (const line of lines)
|
|
46
|
+
emit(line);
|
|
47
|
+
},
|
|
48
|
+
flush() {
|
|
49
|
+
emit(buffer);
|
|
50
|
+
buffer = "";
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=FirebaseRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FirebaseRunner.js","sourceRoot":"","sources":["../../src/firebase/FirebaseRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAe3C,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,OAAO;QACL,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,CACtB,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9C,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE;gBACzD,GAAG,EAAE,WAAW;gBAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE;gBACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,MAAM,WAAW,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,WAAW,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAEhD,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACxC,MAAM,IAAI,KAAK,CAAC;gBAChB,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACxC,MAAM,IAAI,KAAK,CAAC;gBAChB,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC/B,WAAW,CAAC,KAAK,EAAE,CAAC;gBACpB,WAAW,CAAC,KAAK,EAAE,CAAC;gBACpB,OAAO,CAAC,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;KACL,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,QAA8C;IAE9C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,IAAI,GAAG,CAAC,IAAY,EAAQ,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC;IAC9C,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,CAAC,KAAK;YACT,MAAM,IAAI,KAAK,CAAC;YAChB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpC,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAC3B,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,KAAK;YACH,IAAI,CAAC,MAAM,CAAC,CAAC;YACb,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { NormalizedGasboostConfig } from "@gasboost/config";
|
|
2
|
+
import type { OperationDefinition } from "@gasboost/console-runtime";
|
|
3
|
+
import type { FirebaseRunner } from "./FirebaseRunner.js";
|
|
4
|
+
export type FirebaseStatus = {
|
|
5
|
+
readonly enabled: boolean;
|
|
6
|
+
readonly configured: boolean;
|
|
7
|
+
readonly authenticated: boolean;
|
|
8
|
+
readonly projectId?: string;
|
|
9
|
+
readonly realtimeDatabaseDesired: boolean;
|
|
10
|
+
readonly firebaseJson: boolean;
|
|
11
|
+
readonly firebaserc: boolean;
|
|
12
|
+
};
|
|
13
|
+
type FirebaseOperation = OperationDefinition<any, unknown>;
|
|
14
|
+
export declare function createFirebaseOperations({ projectRoot, config, firebase, }: {
|
|
15
|
+
readonly projectRoot: string;
|
|
16
|
+
readonly config: NormalizedGasboostConfig;
|
|
17
|
+
readonly firebase: FirebaseRunner;
|
|
18
|
+
}): readonly FirebaseOperation[];
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=firebaseOperations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firebaseOperations.d.ts","sourceRoot":"","sources":["../../src/firebase/firebaseOperations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAIrE,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1E,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,KAAK,iBAAiB,GAAG,mBAAmB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAO3D,wBAAgB,wBAAwB,CAAC,EACvC,WAAW,EACX,MAAM,EACN,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC,GAAG,SAAS,iBAAiB,EAAE,CAkE/B"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { EnvFileRepository } from "../env/EnvFileRepository.js";
|
|
3
|
+
import { FirebaseProjectRepository } from "./FirebaseProjectRepository.js";
|
|
4
|
+
const emptyInput = z.object({}).strict();
|
|
5
|
+
const projectInput = z
|
|
6
|
+
.object({ projectId: z.string().trim().min(3).max(80) })
|
|
7
|
+
.strict();
|
|
8
|
+
export function createFirebaseOperations({ projectRoot, config, firebase, }) {
|
|
9
|
+
const projectRepository = new FirebaseProjectRepository(projectRoot);
|
|
10
|
+
const envRepository = new EnvFileRepository(projectRoot);
|
|
11
|
+
const status = async () => getFirebaseStatus({ config, projectRepository, envRepository, firebase });
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
id: "firebase.status",
|
|
15
|
+
input: emptyInput,
|
|
16
|
+
async handler(_input, context) {
|
|
17
|
+
context.progress({ message: "Checking Firebase", percentage: 25 });
|
|
18
|
+
const result = await status();
|
|
19
|
+
context.progress({ message: "Firebase status ready", percentage: 100 });
|
|
20
|
+
return result;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "firebase.enable",
|
|
25
|
+
input: emptyInput,
|
|
26
|
+
async handler(_input, context) {
|
|
27
|
+
context.progress({ message: "Creating Firebase local configuration" });
|
|
28
|
+
await projectRepository.enable();
|
|
29
|
+
return status();
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: "firebase.login",
|
|
34
|
+
input: emptyInput,
|
|
35
|
+
async handler(_input, context) {
|
|
36
|
+
const result = await firebase.run(["login"], context.log);
|
|
37
|
+
assertFirebaseSuccess("Firebase login", result);
|
|
38
|
+
return status();
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "firebase.connect",
|
|
43
|
+
input: projectInput,
|
|
44
|
+
async handler(input, context) {
|
|
45
|
+
context.progress({ message: "Connecting Firebase project", percentage: 30 });
|
|
46
|
+
await projectRepository.connect(input.projectId);
|
|
47
|
+
await envRepository.update({ FIREBASE_PROJECT_ID: input.projectId });
|
|
48
|
+
context.progress({ message: "Firebase project connected", percentage: 100 });
|
|
49
|
+
return status();
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "firebase.rules.deploy",
|
|
54
|
+
input: emptyInput,
|
|
55
|
+
async handler(_input, context) {
|
|
56
|
+
const env = await envRepository.read();
|
|
57
|
+
const current = await projectRepository.read();
|
|
58
|
+
const projectId = env.FIREBASE_PROJECT_ID ?? current.projectId;
|
|
59
|
+
if (projectId === undefined) {
|
|
60
|
+
throw new Error("Connect a Firebase project before deploying rules.");
|
|
61
|
+
}
|
|
62
|
+
const result = await firebase.run(["deploy", "--only", "database", "--project", projectId], context.log);
|
|
63
|
+
assertFirebaseSuccess("Firebase RTDB rules deploy", result);
|
|
64
|
+
await envRepository.update({ FIREBASE_PROJECT_ID: projectId });
|
|
65
|
+
return { deployed: true, projectId };
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
async function getFirebaseStatus({ config, projectRepository, envRepository, firebase, }) {
|
|
71
|
+
const [project, env, login] = await Promise.all([
|
|
72
|
+
projectRepository.read(),
|
|
73
|
+
envRepository.read(),
|
|
74
|
+
firebase.run(["login:list", "--json"]),
|
|
75
|
+
]);
|
|
76
|
+
const projectId = project.projectId ?? env.FIREBASE_PROJECT_ID;
|
|
77
|
+
if (projectId !== undefined) {
|
|
78
|
+
await envRepository.update({ FIREBASE_PROJECT_ID: projectId });
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
enabled: project.enabled || config.firebase !== undefined,
|
|
82
|
+
configured: projectId !== undefined,
|
|
83
|
+
authenticated: login.exitCode === 0,
|
|
84
|
+
...(projectId === undefined ? {} : { projectId }),
|
|
85
|
+
realtimeDatabaseDesired: config.firebase?.realtimeDatabase !== undefined,
|
|
86
|
+
firebaseJson: project.firebaseJson,
|
|
87
|
+
firebaserc: project.firebaserc,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function assertFirebaseSuccess(action, result) {
|
|
91
|
+
if (result.exitCode === 0)
|
|
92
|
+
return;
|
|
93
|
+
const diagnostic = result.stderr.trim() || result.stdout.trim();
|
|
94
|
+
throw new Error(diagnostic.length === 0 ? `${action} failed.` : `${action} failed: ${diagnostic}`);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=firebaseOperations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firebaseOperations.js","sourceRoot":"","sources":["../../src/firebase/firebaseOperations.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export { createProjectInspectOperation, type ProjectState, } from "./projectInsp
|
|
|
2
2
|
export { startGasboostConsole } from "./startGasboostConsole.js";
|
|
3
3
|
export { createAppsScriptOperations, type AppsScriptStatus, } from "./appsScript/appsScriptOperations.js";
|
|
4
4
|
export { createClaspRunner, type ClaspResult, type ClaspRunner, } from "./appsScript/ClaspRunner.js";
|
|
5
|
+
export { createFirebaseRunner, type FirebaseResult, type FirebaseRunner, } from "./firebase/FirebaseRunner.js";
|
|
6
|
+
export { createFirebaseOperations, type FirebaseStatus, } from "./firebase/firebaseOperations.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,KAAK,YAAY,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,0BAA0B,EAC1B,KAAK,gBAAgB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,KAAK,YAAY,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,0BAA0B,EAC1B,KAAK,gBAAgB,GACtB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,iBAAiB,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,wBAAwB,EACxB,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,4 +2,6 @@ export { createProjectInspectOperation, } from "./projectInspectOperation.js";
|
|
|
2
2
|
export { startGasboostConsole } from "./startGasboostConsole.js";
|
|
3
3
|
export { createAppsScriptOperations, } from "./appsScript/appsScriptOperations.js";
|
|
4
4
|
export { createClaspRunner, } from "./appsScript/ClaspRunner.js";
|
|
5
|
+
export { createFirebaseRunner, } from "./firebase/FirebaseRunner.js";
|
|
6
|
+
export { createFirebaseOperations, } from "./firebase/firebaseOperations.js";
|
|
5
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,GAE9B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,0BAA0B,GAE3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,iBAAiB,GAGlB,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,GAE9B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,0BAA0B,GAE3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,iBAAiB,GAGlB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,GAGrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,wBAAwB,GAEzB,MAAM,kCAAkC,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type ConsoleRuntime } from "@gasboost/console-runtime";
|
|
2
2
|
import type { ClaspRunner } from "./appsScript/ClaspRunner.js";
|
|
3
|
-
|
|
3
|
+
import type { FirebaseRunner } from "./firebase/FirebaseRunner.js";
|
|
4
|
+
export declare function startGasboostConsole({ projectRoot, openBrowser, clasp, firebase, }: {
|
|
4
5
|
readonly projectRoot: string;
|
|
5
6
|
readonly openBrowser?: boolean;
|
|
6
7
|
readonly clasp?: ClaspRunner;
|
|
8
|
+
readonly firebase?: FirebaseRunner;
|
|
7
9
|
}): Promise<ConsoleRuntime>;
|
|
8
10
|
//# sourceMappingURL=startGasboostConsole.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startGasboostConsole.d.ts","sourceRoot":"","sources":["../src/startGasboostConsole.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG/D,wBAAsB,oBAAoB,CAAC,EACzC,WAAW,EACX,WAAkB,EAClB,KAAsC,
|
|
1
|
+
{"version":3,"file":"startGasboostConsole.d.ts","sourceRoot":"","sources":["../src/startGasboostConsole.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,wBAAsB,oBAAoB,CAAC,EACzC,WAAW,EACX,WAAkB,EAClB,KAAsC,EACtC,QAA4C,GAC7C,EAAE;IACD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;CACpC,GAAG,OAAO,CAAC,cAAc,CAAC,CAsB1B"}
|
|
@@ -2,24 +2,30 @@ import { startConsoleRuntime, } from "@gasboost/console-runtime";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { createAppsScriptOperations } from "./appsScript/appsScriptOperations.js";
|
|
4
4
|
import { createClaspRunner } from "./appsScript/ClaspRunner.js";
|
|
5
|
+
import { createFirebaseOperations } from "./firebase/firebaseOperations.js";
|
|
6
|
+
import { createFirebaseRunner } from "./firebase/FirebaseRunner.js";
|
|
5
7
|
import { createProjectInspectOperation } from "./projectInspectOperation.js";
|
|
6
|
-
|
|
8
|
+
import { loadGasboostConfig } from "@gasboost/config";
|
|
9
|
+
export async function startGasboostConsole({ projectRoot, openBrowser = true, clasp = createClaspRunner(projectRoot), firebase = createFirebaseRunner(projectRoot), }) {
|
|
7
10
|
const config = await loadGasboostConfig({ projectRoot });
|
|
8
|
-
const appsScriptOperations =
|
|
9
|
-
|
|
10
|
-
:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const appsScriptOperations = createAppsScriptOperations({
|
|
12
|
+
projectRoot,
|
|
13
|
+
...(config.appsScript === undefined ? {} : { config: config.appsScript }),
|
|
14
|
+
clasp,
|
|
15
|
+
});
|
|
16
|
+
const firebaseOperations = createFirebaseOperations({
|
|
17
|
+
projectRoot,
|
|
18
|
+
config,
|
|
19
|
+
firebase,
|
|
20
|
+
});
|
|
15
21
|
return startConsoleRuntime({
|
|
16
22
|
uiDirectory: fileURLToPath(new URL("./ui", import.meta.url)),
|
|
17
23
|
operations: [
|
|
18
24
|
createProjectInspectOperation(projectRoot),
|
|
19
25
|
...appsScriptOperations,
|
|
26
|
+
...firebaseOperations,
|
|
20
27
|
],
|
|
21
28
|
openBrowser,
|
|
22
29
|
});
|
|
23
30
|
}
|
|
24
|
-
import { loadGasboostConfig } from "@gasboost/config";
|
|
25
31
|
//# sourceMappingURL=startGasboostConsole.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"startGasboostConsole.js","sourceRoot":"","sources":["../src/startGasboostConsole.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"startGasboostConsole.js","sourceRoot":"","sources":["../src/startGasboostConsole.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,GAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EACzC,WAAW,EACX,WAAW,GAAG,IAAI,EAClB,KAAK,GAAG,iBAAiB,CAAC,WAAW,CAAC,EACtC,QAAQ,GAAG,oBAAoB,CAAC,WAAW,CAAC,GAM7C;IACC,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IACzD,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;QACtD,WAAW;QACX,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QACzE,KAAK;KACN,CAAC,CAAC;IACH,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;QAClD,WAAW;QACX,MAAM;QACN,QAAQ;KACT,CAAC,CAAC;IAEH,OAAO,mBAAmB,CAAC;QACzB,WAAW,EAAE,aAAa,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,UAAU,EAAE;YACV,6BAA6B,CAAC,WAAW,CAAC;YAC1C,GAAG,oBAAoB;YACvB,GAAG,kBAAkB;SACtB;QACD,WAAW;KACZ,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{color:#17211b;font-synthesis:none;background:#f4f6f4;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}*{box-sizing:border-box}[hidden]{display:none!important}body{min-width:320px;min-height:100vh;margin:0}button,input,textarea{font:inherit}.topbar{color:#fff;background:#15271e;border-bottom:1px solid #294235;align-items:center;gap:12px;height:64px;padding:0 24px;display:flex}.brand-mark{color:#15271e;background:#e8ff6a;border-radius:6px;place-items:center;width:34px;height:34px;font-weight:800;display:grid}.product-name{font-size:14px;font-weight:700}.project-path{text-overflow:ellipsis;white-space:nowrap;color:#aabbb1;max-width:min(60vw,680px);font:12px ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.icon-button{color:#fff;cursor:pointer;background:0 0;border:1px solid #496052;border-radius:6px;place-items:center;width:36px;height:36px;margin-left:auto;display:grid}.icon-button:hover{background:#294235}.icon-button:disabled{opacity:.5;cursor:wait}.icon-button svg{width:17px;height:17px}.icon-button.light{color:#26352c;background:#fff;border-color:#cbd5ce;margin-left:0}.icon-button.light:hover{background:#edf2ee}.status-band{background:#fff;border-bottom:1px solid #dce2de;justify-content:space-between;align-items:center;gap:24px;min-height:112px;padding:24px clamp(24px,5vw,72px);display:flex}.eyebrow{color:#668071;font-size:11px;font-weight:800}h1,h2,h3,p{letter-spacing:0;margin:0}h1{margin-top:5px;font-size:28px;line-height:1.2}.runtime-status{color:#526158;align-items:center;font-size:13px;font-weight:650;display:flex}.runtime-status span{background:#e0a526;border-radius:50%;width:8px;height:8px}.runtime-status.ready span{background:#28a264}.runtime-status.error span{background:#d54c4c}.workspace{grid-template-columns:220px minmax(0,1fr);min-height:calc(100vh - 176px);display:grid}.sidebar{background:#e9eeea;border-right:1px solid #d5ddd7;padding:18px 12px}.nav-item{color:#46554c;text-align:left;background:0 0;border:0;border-radius:5px;align-items:center;gap:10px;width:100%;height:40px;padding:0 12px;display:flex}.nav-item svg{width:17px;height:17px}.nav-item.active{color:#17211b;background:#fff;font-weight:700;box-shadow:0 1px 2px #11231914}.nav-item:disabled{opacity:.55}.content{width:min(960px,100%);padding:32px clamp(24px,5vw,64px) 56px}.section-heading{justify-content:space-between;align-items:end;margin-bottom:18px;display:flex}h2{margin-top:4px;font-size:20px;line-height:1.3}.capability-list,.status-list{background:#fff;border:1px solid #d8dfda;border-radius:7px;overflow:hidden}.capability-row,.status-row{border-bottom:1px solid #e4e9e5;grid-template-columns:42px minmax(0,1fr) auto;align-items:center;gap:15px;min-height:82px;padding:16px 18px;display:grid}.capability-row:last-child,.status-row:last-child{border-bottom:0}.capability-icon{border-radius:6px;place-items:center;width:40px;height:40px;display:grid}.capability-icon svg{width:19px;height:19px}.capability-icon.apps{color:#2659a8;background:#e7f0ff}.capability-icon.firebase{color:#9a5c00;background:#fff1d6}.capability-icon.account{color:#16705c;background:#e3f5ef}h3{font-size:14px}.capability-row p{color:#6c7971;margin-top:4px;font-size:12px}.badge{color:#66736b;text-align:center;background:#f6f8f6;border:1px solid #d7ded9;border-radius:4px;min-width:94px;padding:5px 8px;font-size:11px;font-weight:700}.badge.configured{color:#137145;background:#e9f8f0;border-color:#a9dbc1}.badge.inactive{color:#68736c}.mono-detail{text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.action-bar{flex-wrap:wrap;gap:8px;margin-top:18px;display:flex}.command-button,.secondary-button{color:#26352c;cursor:pointer;background:#fff;border:1px solid #c9d3cc;border-radius:5px;justify-content:center;align-items:center;gap:7px;min-height:36px;padding:0 13px;font-size:12px;font-weight:700;display:inline-flex}.button{cursor:pointer;border:0;border-radius:5px;justify-content:center;align-items:center;gap:7px;min-height:39px;padding:0 17px;font-size:12px;font-weight:700;display:inline-flex}.button svg{width:15px;height:15px}.button--primary{color:#17211b;background:#e8ff6a}.button--primary:hover:not(:disabled){background:#efff91}.button:disabled{opacity:.4;cursor:not-allowed}.command-button svg,.secondary-button svg{width:15px;height:15px}.command-button:hover,.secondary-button:hover{background:#edf2ee}.command-button.primary{color:#17211b;background:#e8ff6a;border-color:#d0e54d}.command-button.danger{color:#fff;background:#bd4141;border-color:#ae3737}.command-button:disabled{opacity:.45;cursor:not-allowed}.setup-mode{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin-top:22px;display:grid}.setup-mode__button{color:#17211b;text-align:left;cursor:pointer;background:#fff;border:1px solid #d8dfda;border-radius:7px;flex-direction:column;gap:7px;min-height:96px;padding:16px;display:flex}.setup-mode__button:hover{background:#f8faf8}.setup-mode__button--active{background:#f8ffe5;border-color:#adc238;box-shadow:0 0 0 1px #adc23829}.setup-mode__button strong{font-size:13px}.setup-mode__button span{color:#6c7971;font-size:11px;line-height:1.55}.panel{background:#fff;border:1px solid #d8dfda;border-radius:7px;flex-direction:column;gap:14px;margin-top:14px;padding:16px;display:flex}.info-box{color:#5d6b62;background:#f7faf8;border:1px solid #d8dfda;border-radius:7px;align-items:flex-start;gap:11px;padding:14px;font-size:12px;line-height:1.6;display:flex}.info-box__icon{color:#3c7c9d;border:1px solid #3c7c9d;border-radius:999px;flex:none;place-items:center;width:18px;height:18px;font-family:serif;font-size:12px;font-weight:700;display:grid}.field{flex-direction:column;gap:8px;margin-top:18px;display:flex}.panel .field{margin-top:0}.field__label{color:#526158;font-size:12px;font-weight:700}.field input{color:#17211b;background:#fff;border:1px solid #bfcac2;border-radius:5px;width:100%;height:40px;padding:0 11px;font:13px ui-monospace,SFMono-Regular,Menlo,monospace}.field input:focus{outline-offset:1px;outline:2px solid #bdd43f}.field__help{color:#6c7971;margin:0;font-size:11px;line-height:1.55}.required{color:#bd4141}.activity{margin-top:30px}.activity-heading{justify-content:space-between;align-items:center;margin-bottom:12px;display:flex}.text-button{color:#446052;cursor:pointer;background:0 0;border:0;font-size:12px;font-weight:700}.log{color:#dce8e0;background:#18241d;border-radius:6px;height:180px;padding:8px 0;font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;overflow:auto}.log-row{grid-template-columns:84px 1fr;gap:10px;padding:4px 14px;display:grid}.log-row time{color:#789083}.log-row.progress span{color:#e8ff6a}.log-row.error span{color:#ff9b9b}dialog{color:#17211b;border:1px solid #ccd6cf;border-radius:7px;width:min(440px,100vw - 32px);padding:0;box-shadow:0 20px 60px #12221938}dialog::backdrop{background:#0f1c147a}dialog form{padding:20px}.dialog-heading{justify-content:space-between;align-items:center;margin-bottom:20px;display:flex}.dialog-close{color:#536158;cursor:pointer;background:0 0;border:0;place-items:center;width:32px;height:32px;display:grid}.dialog-close svg{width:18px;height:18px}dialog label{color:#526158;margin-bottom:7px;font-size:12px;font-weight:700;display:block}dialog input{color:#17211b;width:100%;height:40px;font:inherit;border:1px solid #bfcac2;border-radius:5px;padding:0 11px}dialog input:focus{outline-offset:1px;outline:2px solid #bdd43f}.dialog-copy{color:#5d6b62;font-size:13px;line-height:1.6}.dialog-actions{justify-content:flex-end;gap:8px;margin-top:24px;display:flex}@media (width<=700px){.topbar{padding:0 16px}.status-band{min-height:104px;padding:20px}h1{font-size:23px}.workspace{grid-template-columns:1fr}.sidebar{border-bottom:1px solid #d5ddd7;border-right:0;padding:8px;display:flex;overflow-x:auto}.nav-item{width:auto;min-width:max-content}.content{padding:24px 16px 40px}.capability-row,.status-row{grid-template-columns:40px minmax(0,1fr)}.badge{grid-column:2;justify-self:start}.action-bar{grid-template-columns:1fr 1fr;display:grid}}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`,"stroke-linejoin":`round`},t=([e,n,r])=>{let i=document.createElementNS(`http://www.w3.org/2000/svg`,e);return Object.keys(n).forEach(e=>{i.setAttribute(e,String(n[e]))}),r?.length&&r.forEach(e=>{let n=t(e);i.appendChild(n)}),i},n=(n,r={})=>t([`svg`,{...e,...r},n]),r=e=>Array.from(e.attributes).reduce((e,t)=>(e[t.name]=t.value,e),{}),i=e=>typeof e==`string`?e:!e||!e.class?``:e.class&&typeof e.class==`string`?e.class.split(` `):e.class&&Array.isArray(e.class)?e.class:``,a=e=>e.flatMap(i).map(e=>e.trim()).filter(Boolean).filter((e,t,n)=>n.indexOf(e)===t).join(` `),ee=e=>e.replace(/(\w)(\w*)(_|-|\s*)/g,(e,t,n)=>t.toUpperCase()+n.toLowerCase()),o=(t,{nameAttr:i,icons:o,attrs:s})=>{let c=t.getAttribute(i);if(c==null)return;let l=o[ee(c)];if(!l)return console.warn(`${t.outerHTML} icon name was not found in the provided icons object.`);let u=r(t),d={...e,"data-lucide":c,...s,...u},f=a([`lucide`,`lucide-${c}`,u,s]);f&&Object.assign(d,{class:f});let te=n(l,d);return t.parentNode?.replaceChild(te,t)},s=[[`path`,{d:`m18 16 4-4-4-4`}],[`path`,{d:`m6 8-4 4 4 4`}],[`path`,{d:`m14.5 4-5 16`}]],c=[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`}]],l=[[`path`,{d:`M15 3h6v6`}],[`path`,{d:`M10 14 21 3`}],[`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`}]],u=[[`path`,{d:`M4 22h14a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v4`}],[`path`,{d:`M14 2v4a2 2 0 0 0 2 2h4`}],[`path`,{d:`m5 12-3 3 3 3`}],[`path`,{d:`m9 18 3-3-3-3`}]],d=[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`}]],f=[[`rect`,{width:`7`,height:`9`,x:`3`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`14`,y:`3`,rx:`1`}],[`rect`,{width:`7`,height:`9`,x:`14`,y:`12`,rx:`1`}],[`rect`,{width:`7`,height:`5`,x:`3`,y:`16`,rx:`1`}]],te=[[`path`,{d:`m10 17 5-5-5-5`}],[`path`,{d:`M15 12H3`}],[`path`,{d:`M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4`}]],ne=[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`}]],re=[[`path`,{d:`M5 12h14`}],[`path`,{d:`M12 5v14`}]],ie=[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`}],[`path`,{d:`M21 3v5h-5`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`}],[`path`,{d:`M8 16H3v5`}]],ae=[[`path`,{d:`M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z`}],[`path`,{d:`m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z`}],[`path`,{d:`M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0`}],[`path`,{d:`M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5`}]],oe=[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`}]],se=[[`path`,{d:`M12 3v12`}],[`path`,{d:`m17 8-5-5-5 5`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`}]],ce=[[`circle`,{cx:`12`,cy:`8`,r:`5`}],[`path`,{d:`M20 21a8 8 0 0 0-16 0`}]],le=[[`path`,{d:`M18 6 6 18`}],[`path`,{d:`m6 6 12 12`}]],ue=({icons:e={},nameAttr:t=`data-lucide`,attrs:n={},root:r=document}={})=>{if(!Object.values(e).length)throw Error(`Please provide an icons object.
|
|
2
|
+
If you want to use all the icons you can import it like:
|
|
3
|
+
\`import { createIcons, icons } from 'lucide';
|
|
4
|
+
lucide.createIcons({icons});\``);if(r===void 0)throw Error("`createIcons()` only works in a browser environment.");let i=r.querySelectorAll(`[${t}]`);if(Array.from(i).forEach(r=>o(r,{nameAttr:t,icons:e,attrs:n})),t===`data-lucide`){let t=r.querySelectorAll(`[icon-name]`);t.length>0&&(console.warn(`[Lucide] Some icons were found with the now deprecated icon-name attribute. These will still be replaced for backwards compatibility, but will no longer be supported in v1.0 and you should switch to data-lucide`),Array.from(t).forEach(t=>o(t,{nameAttr:`icon-name`,icons:e,attrs:n})))}},de=xe(),p,m,h,g=`existing`;ue({icons:{Code2:s,Database:c,ExternalLink:l,FileCode2:u,KeyRound:d,LayoutDashboard:f,LogIn:te,Play:ne,Plus:re,RefreshCw:ie,Rocket:ae,Square:oe,Upload:se,UserRound:ce,X:le}});var _=$(`refresh`),v=$(`log`),y=$(`apps-log`),b=$(`deployment-log`),x=$(`firebase-log`),fe=$(`development-log`),S={overview:$(`overview-nav`),development:$(`development-nav`),"apps-script":$(`apps-script-nav`),deployment:$(`deployment-nav`),firebase:$(`firebase-nav`)},C=$(`apps-login`),w=$(`apps-create`),T=$(`apps-connect`),pe=$(`apps-user-settings`),E=$(`apps-open`),D=$(`apps-push`),O=$(`apps-pull`),k=$(`credential-service-account`),A=$(`credential-script-properties`),j=$(`deployment-list`),M=$(`deployment-create`),N=$(`deployment-update`),P=$(`deployment-open`),F=$(`firebase-enable`),I=$(`firebase-login`),L=$(`firebase-connect`),R=$(`firebase-rules-deploy`),z=$(`firebase-open`);_.addEventListener(`click`,()=>void B()),$(`clear-log`).addEventListener(`click`,()=>v.replaceChildren()),$(`apps-clear-log`).addEventListener(`click`,()=>y.replaceChildren()),$(`deployment-clear-log`).addEventListener(`click`,()=>b.replaceChildren()),$(`firebase-clear-log`).addEventListener(`click`,()=>x.replaceChildren()),$(`development-clear-log`).addEventListener(`click`,()=>fe.replaceChildren());for(let[e,t]of Object.entries(S))t.addEventListener(`click`,()=>{ve(e),e===`apps-script`&&V(),e===`deployment`&&V(),e===`firebase`&&H()});$(`apps-refresh`).addEventListener(`click`,()=>void V()),$(`deployment-refresh`).addEventListener(`click`,()=>void V()),$(`firebase-refresh`).addEventListener(`click`,()=>void H());for(let e of document.querySelectorAll(`[data-setup-mode]`))e.addEventListener(`click`,()=>{g=e.dataset.setupMode===`new`?`new`:`existing`,_e()});C.addEventListener(`click`,()=>void U(`apps.login`,{},y,K)),pe.addEventListener(`click`,()=>window.open(`https://script.google.com/home/usersettings`,`_blank`,`noopener`)),w.addEventListener(`click`,()=>{let e=$(`script-title`);e.value=p?.name??``,$(`create-dialog`).showModal(),e.focus()}),T.addEventListener(`click`,()=>{U(`apps.connect`,{scriptId:$(`script-id`).value.trim()},y,K)}),E.addEventListener(`click`,()=>void U(`apps.open`,{},y,()=>void 0)),D.addEventListener(`click`,()=>$(`push-dialog`).showModal()),O.addEventListener(`click`,()=>Z(y,`Pull is reserved for a follow-up operation.`,`info`)),k.addEventListener(`click`,()=>{let e=h?.projectId;e!==void 0&&window.open(`https://console.firebase.google.com/project/${encodeURIComponent(e)}/settings/serviceaccounts/adminsdk`,`_blank`,`noopener`)}),A.addEventListener(`click`,()=>{let e=m?.scriptId;e!==void 0&&window.open(`https://script.google.com/home/projects/${encodeURIComponent(e)}/settings`,`_blank`,`noopener`)}),j.addEventListener(`click`,()=>void U(`apps.deployments`,{},b,e=>{Z(b,e.deployments.length===0?`No deployments returned`:e.deployments.map(e=>`${e.deploymentId}${e.description===void 0?``:` (${e.description})`}`).join(`, `),`info`)})),M.addEventListener(`click`,()=>$(`deployment-dialog`).showModal()),N.addEventListener(`click`,()=>void U(`apps.deployment.update`,{deploymentId:$(`deployment-id`).value.trim()||void 0},b,()=>void V())),P.addEventListener(`click`,()=>{let e=m?.deploymentId??$(`deployment-id`).value.trim();e.length>0&&window.open(`https://script.google.com/macros/s/${e}/exec`,`_blank`,`noopener`)}),F.addEventListener(`click`,()=>void U(`firebase.enable`,{},x,q)),I.addEventListener(`click`,()=>void U(`firebase.login`,{},x,q)),L.addEventListener(`click`,()=>{U(`firebase.connect`,{projectId:$(`firebase-project-id`).value.trim()},x,q)}),R.addEventListener(`click`,()=>void U(`firebase.rules.deploy`,{},x,()=>void H())),z.addEventListener(`click`,()=>window.open(`https://console.firebase.google.com/`,`_blank`,`noopener`)),$(`create-form`).addEventListener(`submit`,e=>{e.preventDefault();let t=$(`create-dialog`),n=$(`script-title`).value;t.close(),U(`apps.create`,{title:n},y,K)}),$(`push-form`).addEventListener(`submit`,e=>{e.preventDefault(),$(`push-dialog`).close(),U(`apps.push`,{confirmed:!0},y,()=>void V())}),$(`deployment-form`).addEventListener(`submit`,e=>{e.preventDefault(),$(`deployment-dialog`).close(),U(`apps.deployment.create`,{description:$(`deployment-description`).value.trim()||void 0},b,()=>void V())});for(let e of document.querySelectorAll(`[data-close-dialog]`))e.addEventListener(`click`,()=>{let t=e.dataset.closeDialog;t!==void 0&&$(t).close()});B();async function B(){await me(),await Promise.all([V(),H()])}async function me(){_.disabled=!0,X(`running`,`Inspecting`),Z(v,`Inspecting project definition`,`info`);try{await G(`project.inspect`,{},W(v,e=>{p=e,ge(e)})),X(`ready`,`Ready`)}catch(e){X(`error`,`Error`),Q(v,e)}finally{_.disabled=!1}}async function V(){await U(`apps.status`,{},y,K)}async function H(){await U(`firebase.status`,{},x,q)}async function U(e,t,n,r){ye(!0),X(`running`,`Working`);try{await G(e,t,W(n,r)),X(`ready`,`Ready`)}catch(e){X(`error`,`Error`),Q(n,e)}finally{ye(!1)}}function W(e,t){return{log:t=>Z(e,t,`info`),progress:(t,n)=>Z(e,n===void 0?t:`${t} (${n}%)`,`progress`),result:t}}async function G(e,t,n){let r=await fetch(`/api/operations/${encodeURIComponent(e)}`,{method:`POST`,headers:{"Content-Type":`application/json`,"X-Gasboost-Session":de},body:JSON.stringify(t)});if(!r.ok||r.body===null){let e=await r.json().catch(()=>null);throw Error(e?.error??`Operation failed with status ${r.status}`)}let i=r.body.pipeThrough(new TextDecoderStream).getReader(),a=``;for(;;){let{done:e,value:t}=await i.read();a+=t??``;let r=a.split(`
|
|
5
|
+
|
|
6
|
+
`);a=r.pop()??``;for(let e of r)he(e,n);if(e)break}}function he(e,t){let n=/^event: (.+)$/m.exec(e)?.[1],r=/^data: (.+)$/m.exec(e)?.[1];if(n===void 0||r===void 0)return;let i=JSON.parse(r);if(n===`log`&&typeof i.message==`string`)t.log(i.message);else if(n===`progress`&&typeof i.message==`string`)t.progress(i.message,typeof i.percentage==`number`?i.percentage:void 0);else if(n===`result`)t.result(i);else if(n===`error`)throw Error(typeof i.message==`string`?i.message:`Operation failed`)}function ge(e){$(`project-title`).textContent=e.name,$(`project-path`).textContent=e.root,be(`apps-script-status`,e.capabilities.appsScript),be(`firebase-status`,e.capabilities.firebaseRealtimeDatabase)}function K(e){m=e,Y(`apps-auth-status`,e.authenticated,`Authorized`,`Sign in required`),Y(`apps-project-status`,e.configured,`Connected`,`Not initialized`),Y(`apps-manifest-status`,e.manifestExists,`Found`,`Missing`),Y(`deployment-project-status`,e.configured,`Ready`,`Prerequisite`),$(`apps-account-detail`).textContent=e.authenticated?`clasp authorization available`:`No clasp authorization found`,$(`apps-project-detail`).textContent=e.configured?`${e.scriptId??`Connected`} · ${e.rootDir}`:`Local source: ${e.rootDir}`,$(`apps-manifest-detail`).textContent=e.manifestExists?`appsscript.json exists in project root`:`Manifest was not detected at project root`,$(`deployment-project-detail`).textContent=e.configured?`Script ID: ${e.scriptId??`connected`}`:`Create or connect an Apps Script project first`,$(`deployment-id`).value=e.deploymentId??``,Y(`deployment-id-status`,e.deploymentId!==void 0,`Selected`,`Not selected`),$(`deployment-id-detail`).textContent=e.deploymentId===void 0?`No deployment synced to .env`:e.deploymentId,_e(),J()}function q(e){h=e,Y(`firebase-enabled-status`,e.enabled,`Enabled`,`Not enabled`),Y(`firebase-auth-status`,e.authenticated,`Authorized`,`Sign in required`),Y(`firebase-project-status`,e.configured,`Connected`,`Not connected`),$(`firebase-enabled-detail`).textContent=e.enabled?`Local Firebase configuration detected`:`Enable Firebase to create local configuration`,$(`firebase-auth-detail`).textContent=e.authenticated?`Firebase CLI authorization available`:`No Firebase CLI authorization found`,$(`firebase-project-detail`).textContent=e.projectId===void 0?`No project ID synced to .env`:e.projectId,$(`firebase-project-id`).value=e.projectId??``,J()}function _e(){for(let e of document.querySelectorAll(`[data-setup-mode]`))e.classList.toggle(`setup-mode__button--active`,e.dataset.setupMode===g);$(`apps-create-panel`).hidden=g!==`new`,$(`apps-connect-panel`).hidden=g!==`existing`}function ve(e){for(let t of Object.keys(S))$(`${t}-view`).hidden=t!==e,S[t].classList.toggle(`active`,t===e)}function ye(e){if(e)for(let e of document.querySelectorAll(`button`))e.classList.contains(`nav-item`)||(e.disabled=!0);else J()}function J(){let e=m?.authenticated===!0,t=m?.configured===!0;C.disabled=e,w.disabled=!e||t,T.disabled=!e||t,E.disabled=!e||!t,D.disabled=!e||!t,O.disabled=!e||!t,k.disabled=h?.projectId===void 0,A.disabled=m?.scriptId===void 0,j.disabled=!e||!t,M.disabled=!e||!t,N.disabled=!e||!t,P.disabled=(m?.deploymentId??$(`deployment-id`).value).length===0,I.disabled=h?.authenticated===!0,F.disabled=h?.enabled===!0,L.disabled=!1,R.disabled=h?.configured!==!0,z.disabled=!1,_.disabled=!1;for(let e of Object.values(S))e.disabled=!1}function be(e,t){Y(e,t,`Configured`,`Not configured`)}function Y(e,t,n,r){let i=$(e);i.textContent=t?n:r,i.className=`badge ${t?`configured`:`inactive`}`}function X(e,t){let n=$(`runtime-status`);n.className=`runtime-status ${e}`,n.innerHTML=``;let r=document.createElement(`span`);n.append(r,document.createTextNode(` ${t}`))}function Z(e,t,n){let r=document.createElement(`div`);r.className=`log-row ${n}`;let i=document.createElement(`time`);i.textContent=new Date().toLocaleTimeString();let a=document.createElement(`span`);a.textContent=t,r.append(i,a),e.append(r),e.scrollTop=e.scrollHeight}function Q(e,t){Z(e,t instanceof Error?t.message:`Operation failed`,`error`)}function $(e){let t=document.getElementById(e);if(t===null)throw Error(`Missing UI element: ${e}`);return t}function xe(){let e=document.querySelector(`meta[name="gasboost-session"]`)?.content;if(e===void 0||e.length===0)throw Error(`Console session was not initialized`);return e}
|
package/dist/ui/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<meta name="gasboost-session" content="__GASBOOST_SESSION_TOKEN__" />
|
|
7
7
|
<title>Gasboost Console</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DSY49jCs.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="/assets/index-ClzuMWwT.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<header class="topbar">
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
<main>
|
|
24
24
|
<section class="status-band" aria-labelledby="project-title">
|
|
25
25
|
<div>
|
|
26
|
-
<div class="eyebrow">PROJECT</div>
|
|
26
|
+
<div class="eyebrow">PROJECT LIFECYCLE</div>
|
|
27
27
|
<h1 id="project-title">Loading...</h1>
|
|
28
28
|
</div>
|
|
29
29
|
<div class="runtime-status" id="runtime-status"><span></span> Connecting</div>
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
<section class="workspace" aria-label="Project lifecycle">
|
|
33
33
|
<nav class="sidebar" aria-label="Console sections">
|
|
34
34
|
<button class="nav-item active" id="overview-nav" type="button"><i data-lucide="layout-dashboard"></i>Overview</button>
|
|
35
|
-
<button class="nav-item" type="button"
|
|
36
|
-
<button class="nav-item" id="apps-script-nav" type="button"
|
|
37
|
-
<button class="nav-item" type="button"
|
|
38
|
-
<button class="nav-item" type="button"
|
|
35
|
+
<button class="nav-item" id="development-nav" type="button"><i data-lucide="code-2"></i>Development</button>
|
|
36
|
+
<button class="nav-item" id="apps-script-nav" type="button"><i data-lucide="file-code-2"></i>Apps Script</button>
|
|
37
|
+
<button class="nav-item" id="deployment-nav" type="button"><i data-lucide="rocket"></i>Deployment</button>
|
|
38
|
+
<button class="nav-item" id="firebase-nav" type="button"><i data-lucide="database"></i>Firebase</button>
|
|
39
39
|
</nav>
|
|
40
40
|
|
|
41
41
|
<div class="content" id="overview-view">
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
<div class="capability-list">
|
|
50
50
|
<article class="capability-row">
|
|
51
51
|
<div class="capability-icon apps"><i data-lucide="file-code-2"></i></div>
|
|
52
|
-
<div><h3>Apps Script</h3><p>
|
|
52
|
+
<div><h3>Apps Script</h3><p>Desired capability from gasboost.config.ts. Lifecycle controls stay available either way.</p></div>
|
|
53
53
|
<div class="badge" id="apps-script-status">Checking</div>
|
|
54
54
|
</article>
|
|
55
55
|
<article class="capability-row">
|
|
56
56
|
<div class="capability-icon firebase"><i data-lucide="database"></i></div>
|
|
57
|
-
<div><h3>Firebase Realtime Database</h3><p>Rules generation and deployment
|
|
57
|
+
<div><h3>Firebase Realtime Database</h3><p>Rules generation and deployment capability.</p></div>
|
|
58
58
|
<div class="badge" id="firebase-status">Checking</div>
|
|
59
59
|
</article>
|
|
60
60
|
</div>
|
|
@@ -65,6 +65,23 @@
|
|
|
65
65
|
</section>
|
|
66
66
|
</div>
|
|
67
67
|
|
|
68
|
+
<div class="content" id="development-view" hidden>
|
|
69
|
+
<div class="section-heading">
|
|
70
|
+
<div><div class="eyebrow">DEVELOPMENT</div><h2>Local application</h2></div>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="info-box"><span class="info-box__icon">i</span><div>Dev server operations are intentionally separated from arbitrary package script execution. Start/stop wiring can be added as registered operations without opening a shell launcher.</div></div>
|
|
73
|
+
<div class="action-bar">
|
|
74
|
+
<button class="command-button" type="button" disabled><i data-lucide="play"></i>Start</button>
|
|
75
|
+
<button class="command-button" type="button" disabled><i data-lucide="square"></i>Stop</button>
|
|
76
|
+
<button class="command-button" type="button" disabled><i data-lucide="refresh-cw"></i>Restart</button>
|
|
77
|
+
<button class="command-button" type="button" disabled><i data-lucide="external-link"></i>Open local app</button>
|
|
78
|
+
</div>
|
|
79
|
+
<section class="activity" aria-labelledby="development-activity-title">
|
|
80
|
+
<div class="activity-heading"><h2 id="development-activity-title">Activity</h2><button id="development-clear-log" class="text-button" type="button">Clear</button></div>
|
|
81
|
+
<div class="log" id="development-log" role="log" aria-live="polite"></div>
|
|
82
|
+
</section>
|
|
83
|
+
</div>
|
|
84
|
+
|
|
68
85
|
<div class="content" id="apps-script-view" hidden>
|
|
69
86
|
<div class="section-heading">
|
|
70
87
|
<div><div class="eyebrow">APPS SCRIPT</div><h2>Project lifecycle</h2></div>
|
|
@@ -82,13 +99,55 @@
|
|
|
82
99
|
<div><h3>Script project</h3><p class="mono-detail" id="apps-project-detail">Checking project</p></div>
|
|
83
100
|
<div class="badge" id="apps-project-status">Checking</div>
|
|
84
101
|
</div>
|
|
102
|
+
<div class="status-row">
|
|
103
|
+
<div class="capability-icon apps"><i data-lucide="file-code-2"></i></div>
|
|
104
|
+
<div><h3>Manifest</h3><p class="mono-detail" id="apps-manifest-detail">Checking appsscript.json</p></div>
|
|
105
|
+
<div class="badge" id="apps-manifest-status">Checking</div>
|
|
106
|
+
</div>
|
|
85
107
|
</div>
|
|
86
108
|
|
|
87
109
|
<div class="action-bar" aria-label="Apps Script actions">
|
|
88
110
|
<button class="command-button" id="apps-login" type="button"><i data-lucide="log-in"></i>Sign in</button>
|
|
89
|
-
<button class="command-button" id="apps-
|
|
111
|
+
<button class="command-button" id="apps-user-settings" type="button"><i data-lucide="external-link"></i>User Settings</button>
|
|
90
112
|
<button class="command-button" id="apps-open" type="button"><i data-lucide="external-link"></i>Open editor</button>
|
|
91
|
-
<button class="command-button primary" id="apps-push" type="button"><i data-lucide="upload"></i>Push
|
|
113
|
+
<button class="command-button primary" id="apps-push" type="button"><i data-lucide="upload"></i>Push</button>
|
|
114
|
+
<button class="command-button" id="apps-pull" type="button"><i data-lucide="refresh-cw"></i>Pull</button>
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<div class="setup-mode">
|
|
118
|
+
<button type="button" class="setup-mode__button setup-mode__button--active" data-setup-mode="existing">
|
|
119
|
+
<strong>Connect existing project</strong>
|
|
120
|
+
<span>Store the Script ID in .clasp.json and sync GAS_SCRIPT_ID to .env.</span>
|
|
121
|
+
</button>
|
|
122
|
+
<button type="button" class="setup-mode__button" data-setup-mode="new">
|
|
123
|
+
<strong>Create new</strong>
|
|
124
|
+
<span>Create a new Apps Script project through the registered clasp operation.</span>
|
|
125
|
+
</button>
|
|
126
|
+
</div>
|
|
127
|
+
|
|
128
|
+
<div class="panel" id="apps-connect-panel">
|
|
129
|
+
<div class="field">
|
|
130
|
+
<label for="script-id" class="field__label">Apps Script Script ID <span class="required">*</span></label>
|
|
131
|
+
<input id="script-id" placeholder="1BxImVS0XRA5nFMdKvBdBZjgmlUqptlbs..." />
|
|
132
|
+
<p class="field__help">Console writes .clasp.json and .env; no command copy is required.</p>
|
|
133
|
+
</div>
|
|
134
|
+
<button class="button button--primary" id="apps-connect" type="button"><i data-lucide="plus"></i>Connect project</button>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<div class="panel" id="apps-create-panel" hidden>
|
|
138
|
+
<div class="info-box"><span class="info-box__icon">i</span><div>This runs the fixed Apps Script project creation operation and refreshes state afterward.</div></div>
|
|
139
|
+
<button class="button button--primary" id="apps-create" type="button"><i data-lucide="plus"></i>Create project</button>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div class="panel">
|
|
143
|
+
<div>
|
|
144
|
+
<h3>Firebase credentials</h3>
|
|
145
|
+
<p class="field__help">Create a service account key in Firebase, then add its values to Script Properties in Apps Script. Credentials stay in those provider interfaces and never pass through Console.</p>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="action-bar">
|
|
148
|
+
<button class="command-button" id="credential-service-account" type="button"><i data-lucide="key-round"></i>1. Open Service Accounts</button>
|
|
149
|
+
<button class="command-button" id="credential-script-properties" type="button"><i data-lucide="external-link"></i>2. Open Script Properties</button>
|
|
150
|
+
</div>
|
|
92
151
|
</div>
|
|
93
152
|
|
|
94
153
|
<section class="activity" aria-labelledby="apps-activity-title">
|
|
@@ -96,6 +155,80 @@
|
|
|
96
155
|
<div class="log" id="apps-log" role="log" aria-live="polite"></div>
|
|
97
156
|
</section>
|
|
98
157
|
</div>
|
|
158
|
+
|
|
159
|
+
<div class="content" id="deployment-view" hidden>
|
|
160
|
+
<div class="section-heading">
|
|
161
|
+
<div><div class="eyebrow">DEPLOYMENT</div><h2>Apps Script deployment</h2></div>
|
|
162
|
+
<button class="icon-button light" id="deployment-refresh" type="button" title="Refresh deployment status" aria-label="Refresh deployment status"><i data-lucide="refresh-cw"></i></button>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="status-list">
|
|
165
|
+
<div class="status-row">
|
|
166
|
+
<div class="capability-icon apps"><i data-lucide="file-code-2"></i></div>
|
|
167
|
+
<div><h3>Apps Script project</h3><p class="mono-detail" id="deployment-project-detail">Checking prerequisite</p></div>
|
|
168
|
+
<div class="badge" id="deployment-project-status">Checking</div>
|
|
169
|
+
</div>
|
|
170
|
+
<div class="status-row">
|
|
171
|
+
<div class="capability-icon apps"><i data-lucide="rocket"></i></div>
|
|
172
|
+
<div><h3>Deployment ID</h3><p class="mono-detail" id="deployment-id-detail">Checking .env</p></div>
|
|
173
|
+
<div class="badge" id="deployment-id-status">Checking</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
<div class="field">
|
|
177
|
+
<label for="deployment-id" class="field__label">Deployment ID</label>
|
|
178
|
+
<input id="deployment-id" placeholder="AKfycb..." />
|
|
179
|
+
<p class="field__help">Create or update syncs DEPLOYMENT_ID to .env.</p>
|
|
180
|
+
</div>
|
|
181
|
+
<div class="action-bar">
|
|
182
|
+
<button class="command-button" id="deployment-list" type="button"><i data-lucide="refresh-cw"></i>List</button>
|
|
183
|
+
<button class="command-button primary" id="deployment-create" type="button"><i data-lucide="plus"></i>Create</button>
|
|
184
|
+
<button class="command-button" id="deployment-update" type="button"><i data-lucide="upload"></i>Update</button>
|
|
185
|
+
<button class="command-button" id="deployment-open" type="button"><i data-lucide="external-link"></i>Open deployed app</button>
|
|
186
|
+
</div>
|
|
187
|
+
<section class="activity" aria-labelledby="deployment-activity-title">
|
|
188
|
+
<div class="activity-heading"><h2 id="deployment-activity-title">Activity</h2><button id="deployment-clear-log" class="text-button" type="button">Clear</button></div>
|
|
189
|
+
<div class="log" id="deployment-log" role="log" aria-live="polite"></div>
|
|
190
|
+
</section>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div class="content" id="firebase-view" hidden>
|
|
194
|
+
<div class="section-heading">
|
|
195
|
+
<div><div class="eyebrow">FIREBASE</div><h2>Realtime Database lifecycle</h2></div>
|
|
196
|
+
<button class="icon-button light" id="firebase-refresh" type="button" title="Refresh Firebase status" aria-label="Refresh Firebase status"><i data-lucide="refresh-cw"></i></button>
|
|
197
|
+
</div>
|
|
198
|
+
<div class="status-list">
|
|
199
|
+
<div class="status-row">
|
|
200
|
+
<div class="capability-icon firebase"><i data-lucide="database"></i></div>
|
|
201
|
+
<div><h3>Firebase</h3><p id="firebase-enabled-detail">Checking local configuration</p></div>
|
|
202
|
+
<div class="badge" id="firebase-enabled-status">Checking</div>
|
|
203
|
+
</div>
|
|
204
|
+
<div class="status-row">
|
|
205
|
+
<div class="capability-icon account"><i data-lucide="user-round"></i></div>
|
|
206
|
+
<div><h3>Firebase account</h3><p id="firebase-auth-detail">Checking authorization</p></div>
|
|
207
|
+
<div class="badge" id="firebase-auth-status">Checking</div>
|
|
208
|
+
</div>
|
|
209
|
+
<div class="status-row">
|
|
210
|
+
<div class="capability-icon firebase"><i data-lucide="database"></i></div>
|
|
211
|
+
<div><h3>Firebase project</h3><p class="mono-detail" id="firebase-project-detail">Checking project ID</p></div>
|
|
212
|
+
<div class="badge" id="firebase-project-status">Checking</div>
|
|
213
|
+
</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="field">
|
|
216
|
+
<label for="firebase-project-id" class="field__label">Firebase Project ID <span class="required">*</span></label>
|
|
217
|
+
<input id="firebase-project-id" placeholder="my-firebase-project" />
|
|
218
|
+
<p class="field__help">Connect syncs FIREBASE_PROJECT_ID to .env and .firebaserc.</p>
|
|
219
|
+
</div>
|
|
220
|
+
<div class="action-bar">
|
|
221
|
+
<button class="command-button primary" id="firebase-enable" type="button"><i data-lucide="plus"></i>Enable Firebase</button>
|
|
222
|
+
<button class="command-button" id="firebase-login" type="button"><i data-lucide="log-in"></i>Firebase login</button>
|
|
223
|
+
<button class="command-button" id="firebase-connect" type="button"><i data-lucide="database"></i>Connect project</button>
|
|
224
|
+
<button class="command-button" id="firebase-rules-deploy" type="button"><i data-lucide="upload"></i>Deploy rules</button>
|
|
225
|
+
<button class="command-button" id="firebase-open" type="button"><i data-lucide="external-link"></i>Open console</button>
|
|
226
|
+
</div>
|
|
227
|
+
<section class="activity" aria-labelledby="firebase-activity-title">
|
|
228
|
+
<div class="activity-heading"><h2 id="firebase-activity-title">Activity</h2><button id="firebase-clear-log" class="text-button" type="button">Clear</button></div>
|
|
229
|
+
<div class="log" id="firebase-log" role="log" aria-live="polite"></div>
|
|
230
|
+
</section>
|
|
231
|
+
</div>
|
|
99
232
|
</section>
|
|
100
233
|
</main>
|
|
101
234
|
|
|
@@ -115,5 +248,15 @@
|
|
|
115
248
|
<div class="dialog-actions"><button class="secondary-button" type="button" data-close-dialog="push-dialog">Cancel</button><button class="command-button danger" type="submit"><i data-lucide="upload"></i>Push and replace</button></div>
|
|
116
249
|
</form>
|
|
117
250
|
</dialog>
|
|
251
|
+
|
|
252
|
+
<dialog id="deployment-dialog">
|
|
253
|
+
<form id="deployment-form">
|
|
254
|
+
<div class="dialog-heading"><h2>Create deployment</h2><button class="dialog-close" type="button" data-close-dialog="deployment-dialog" aria-label="Close"><i data-lucide="x"></i></button></div>
|
|
255
|
+
<label for="deployment-description">Description</label>
|
|
256
|
+
<input id="deployment-description" maxlength="120" placeholder="Initial deployment" />
|
|
257
|
+
<div class="dialog-actions"><button class="secondary-button" type="button" data-close-dialog="deployment-dialog">Cancel</button><button class="command-button primary" type="submit"><i data-lucide="rocket"></i>Create</button></div>
|
|
258
|
+
</form>
|
|
259
|
+
</dialog>
|
|
260
|
+
|
|
118
261
|
</body>
|
|
119
262
|
</html>
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{color:#17211b;font-synthesis:none;background:#f4f6f4;font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}*{box-sizing:border-box}[hidden]{display:none!important}body{min-width:320px;min-height:100vh;margin:0}button{font:inherit}.topbar{color:#fff;background:#15271e;border-bottom:1px solid #294235;align-items:center;gap:12px;height:64px;padding:0 24px;display:flex}.brand-mark{color:#15271e;background:#e8ff6a;border-radius:6px;place-items:center;width:34px;height:34px;font-weight:800;display:grid}.product-name{font-size:14px;font-weight:700}.project-path{text-overflow:ellipsis;white-space:nowrap;color:#aabbb1;max-width:min(60vw,680px);font:12px ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.icon-button{color:#fff;cursor:pointer;background:0 0;border:1px solid #496052;border-radius:6px;place-items:center;width:36px;height:36px;margin-left:auto;display:grid}.icon-button:hover{background:#294235}.icon-button:disabled{opacity:.5;cursor:wait}.icon-button svg{width:17px;height:17px}.icon-button.light{color:#26352c;background:#fff;border-color:#cbd5ce;margin-left:0}.icon-button.light:hover{background:#edf2ee}.status-band{background:#fff;border-bottom:1px solid #dce2de;justify-content:space-between;align-items:center;gap:24px;min-height:112px;padding:24px clamp(24px,5vw,72px);display:flex}.eyebrow{color:#668071;font-size:11px;font-weight:800}h1,h2,h3,p{letter-spacing:0;margin:0}h1{margin-top:5px;font-size:28px;line-height:1.2}.runtime-status{color:#526158;align-items:center;font-size:13px;font-weight:650;display:flex}.runtime-status span{background:#e0a526;border-radius:50%;width:8px;height:8px}.runtime-status.ready span{background:#28a264}.runtime-status.error span{background:#d54c4c}.workspace{grid-template-columns:220px minmax(0,1fr);min-height:calc(100vh - 176px);display:grid}.sidebar{background:#e9eeea;border-right:1px solid #d5ddd7;padding:18px 12px}.nav-item{color:#46554c;text-align:left;background:0 0;border:0;border-radius:5px;align-items:center;gap:10px;width:100%;height:40px;padding:0 12px;display:flex}.nav-item svg{width:17px;height:17px}.nav-item.active{color:#17211b;background:#fff;font-weight:700;box-shadow:0 1px 2px #11231914}.nav-item:disabled{opacity:.55}.content{width:min(960px,100%);padding:32px clamp(24px,5vw,64px) 56px}.section-heading{justify-content:space-between;align-items:end;margin-bottom:18px;display:flex}h2{margin-top:4px;font-size:20px;line-height:1.3}.capability-list,.status-list{background:#fff;border:1px solid #d8dfda;border-radius:7px;overflow:hidden}.capability-row,.status-row{border-bottom:1px solid #e4e9e5;grid-template-columns:42px minmax(0,1fr) auto;align-items:center;gap:15px;min-height:82px;padding:16px 18px;display:grid}.capability-row:last-child,.status-row:last-child{border-bottom:0}.capability-icon{border-radius:6px;place-items:center;width:40px;height:40px;display:grid}.capability-icon svg{width:19px;height:19px}.capability-icon.apps{color:#2659a8;background:#e7f0ff}.capability-icon.firebase{color:#9a5c00;background:#fff1d6}.capability-icon.account{color:#16705c;background:#e3f5ef}h3{font-size:14px}.capability-row p{color:#6c7971;margin-top:4px;font-size:12px}.badge{color:#66736b;text-align:center;background:#f6f8f6;border:1px solid #d7ded9;border-radius:4px;min-width:94px;padding:5px 8px;font-size:11px;font-weight:700}.badge.configured{color:#137145;background:#e9f8f0;border-color:#a9dbc1}.badge.inactive{color:#68736c}.mono-detail{text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.action-bar{flex-wrap:wrap;gap:8px;margin-top:18px;display:flex}.command-button,.secondary-button{color:#26352c;cursor:pointer;background:#fff;border:1px solid #c9d3cc;border-radius:5px;justify-content:center;align-items:center;gap:7px;min-height:36px;padding:0 13px;font-size:12px;font-weight:700;display:inline-flex}.command-button svg,.secondary-button svg{width:15px;height:15px}.command-button:hover,.secondary-button:hover{background:#edf2ee}.command-button.primary{color:#17211b;background:#e8ff6a;border-color:#d0e54d}.command-button.danger{color:#fff;background:#bd4141;border-color:#ae3737}.command-button:disabled{opacity:.45;cursor:not-allowed}.activity{margin-top:30px}.activity-heading{justify-content:space-between;align-items:center;margin-bottom:12px;display:flex}.text-button{color:#446052;cursor:pointer;background:0 0;border:0;font-size:12px;font-weight:700}.log{color:#dce8e0;background:#18241d;border-radius:6px;height:180px;padding:8px 0;font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace;overflow:auto}.log-row{grid-template-columns:84px 1fr;gap:10px;padding:4px 14px;display:grid}.log-row time{color:#789083}.log-row.progress span{color:#e8ff6a}.log-row.error span{color:#ff9b9b}dialog{color:#17211b;border:1px solid #ccd6cf;border-radius:7px;width:min(440px,100vw - 32px);padding:0;box-shadow:0 20px 60px #12221938}dialog::backdrop{background:#0f1c147a}dialog form{padding:20px}.dialog-heading{justify-content:space-between;align-items:center;margin-bottom:20px;display:flex}.dialog-close{color:#536158;cursor:pointer;background:0 0;border:0;place-items:center;width:32px;height:32px;display:grid}.dialog-close svg{width:18px;height:18px}dialog label{color:#526158;margin-bottom:7px;font-size:12px;font-weight:700;display:block}dialog input{color:#17211b;width:100%;height:40px;font:inherit;border:1px solid #bfcac2;border-radius:5px;padding:0 11px}dialog input:focus{outline-offset:1px;outline:2px solid #bdd43f}.dialog-copy{color:#5d6b62;font-size:13px;line-height:1.6}.dialog-actions{justify-content:flex-end;gap:8px;margin-top:24px;display:flex}@media (width<=700px){.topbar{padding:0 16px}.status-band{min-height:104px;padding:20px}h1{font-size:23px}.workspace{grid-template-columns:1fr}.sidebar{border-bottom:1px solid #d5ddd7;border-right:0;padding:8px;display:flex;overflow-x:auto}.nav-item{width:auto;min-width:max-content}.content{padding:24px 16px 40px}.capability-row,.status-row{grid-template-columns:40px minmax(0,1fr)}.badge{grid-column:2;justify-self:start}.action-bar{grid-template-columns:1fr 1fr;display:grid}}
|