hikoutei 0.5.11 → 0.5.12
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/README.md +6 -0
- package/dist/cli/args.d.ts +50 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +139 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/confirm.d.ts +31 -0
- package/dist/cli/confirm.d.ts.map +1 -0
- package/dist/cli/confirm.js +29 -0
- package/dist/cli/confirm.js.map +1 -0
- package/dist/cli/errors.d.ts +47 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +42 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/gcloudRunner.d.ts +35 -0
- package/dist/cli/gcloudRunner.d.ts.map +1 -0
- package/dist/cli/gcloudRunner.js +40 -0
- package/dist/cli/gcloudRunner.js.map +1 -0
- package/dist/cli/setup.d.ts +13 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +74 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/setupFlow.d.ts +137 -0
- package/dist/cli/setupFlow.d.ts.map +1 -0
- package/dist/cli/setupFlow.js +443 -0
- package/dist/cli/setupFlow.js.map +1 -0
- package/dist/cli/sheetsFactory.d.ts +49 -0
- package/dist/cli/sheetsFactory.d.ts.map +1 -0
- package/dist/cli/sheetsFactory.js +71 -0
- package/dist/cli/sheetsFactory.js.map +1 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -125,6 +125,12 @@ an operation for each write. The sync runtime uses one Google Sheets API
|
|
|
125
125
|
provider (the internal `googleSheetsApi` bootstrap option) with a service
|
|
126
126
|
account — no Apps Script deployment.
|
|
127
127
|
|
|
128
|
+
**Fastest path:** install the gcloud CLI, run `gcloud auth login`, then
|
|
129
|
+
`npx hikoutei setup` — it creates the project, service account, key, and a
|
|
130
|
+
spreadsheet owned by that service account, and writes
|
|
131
|
+
`GOOGLE_APPLICATION_CREDENTIALS` plus `HIKOUTEI_SYNC_SPREADSHEET_URL` into
|
|
132
|
+
your `.env`. The manual steps below remain available for advanced setups.
|
|
133
|
+
|
|
128
134
|
### Env-driven sync auto-start
|
|
129
135
|
|
|
130
136
|
Set the spreadsheet URL in the environment and `createTypedSheets()` starts
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure command-line parsing for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* This module owns flag syntax and defaults only; it never touches gcloud,
|
|
5
|
+
* the filesystem, or the network. The result is an explicit union so the CLI
|
|
6
|
+
* entry can branch on help / valid / invalid without inspecting message text.
|
|
7
|
+
*/
|
|
8
|
+
import { type SetupFailure } from "./errors.js";
|
|
9
|
+
/** Default service-account name when `--sa-name` is not given. */
|
|
10
|
+
export declare const DEFAULT_SA_NAME = "hikoutei-sa";
|
|
11
|
+
/** Default output file name (resolved against the current directory by main). */
|
|
12
|
+
export declare const DEFAULT_OUTPUT_FILE_NAME = ".env";
|
|
13
|
+
/** Parsed and defaulted setup options handed to the setup flow. */
|
|
14
|
+
export interface SetupOptions {
|
|
15
|
+
/** Existing Google Cloud project id; when absent the flow creates one. */
|
|
16
|
+
readonly projectId?: string;
|
|
17
|
+
/** Service-account name within the project. */
|
|
18
|
+
readonly saName: string;
|
|
19
|
+
/** Spreadsheet title; when absent the flow derives `hikoutei-sync-<project>`. */
|
|
20
|
+
readonly spreadsheetTitle?: string;
|
|
21
|
+
/** Output .env path (relative to the current directory). */
|
|
22
|
+
readonly output: string;
|
|
23
|
+
/** Skip interactive confirmation. */
|
|
24
|
+
readonly yes: boolean;
|
|
25
|
+
/** Print the planned command sequence without executing anything. */
|
|
26
|
+
readonly dryRun: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** Discriminated result of `parseSetupArgs`. */
|
|
29
|
+
export type SetupArgsParseResult = {
|
|
30
|
+
readonly status: "help";
|
|
31
|
+
readonly helpText: string;
|
|
32
|
+
} | {
|
|
33
|
+
readonly status: "valid";
|
|
34
|
+
readonly options: SetupOptions;
|
|
35
|
+
} | {
|
|
36
|
+
readonly status: "invalid";
|
|
37
|
+
readonly failure: SetupFailure;
|
|
38
|
+
};
|
|
39
|
+
export declare const SETUP_HELP_TEXT: string;
|
|
40
|
+
/**
|
|
41
|
+
* Parses raw argv (without node/script) into setup options.
|
|
42
|
+
*
|
|
43
|
+
* `--flag value` and `--flag=value` are both accepted. A leading `setup`
|
|
44
|
+
* token is ignored so the npm bin works both as `hikoutei setup ...` and as
|
|
45
|
+
* `node dist/cli/setup.js ...`. Unknown flags, missing values, boolean flags
|
|
46
|
+
* given a value, and other positional arguments are rejected with
|
|
47
|
+
* `invalid_args`. `--help` short-circuits with the help text.
|
|
48
|
+
*/
|
|
49
|
+
export declare function parseSetupArgs(argv: readonly string[]): SetupArgsParseResult;
|
|
50
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAmC,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEjF,kEAAkE;AAClE,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAE/C,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAED,gDAAgD;AAChD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,CAAC;AAanE,eAAO,MAAM,eAAe,QAyBhB,CAAC;AAUb;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,oBAAoB,CA6E5E"}
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure command-line parsing for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* This module owns flag syntax and defaults only; it never touches gcloud,
|
|
5
|
+
* the filesystem, or the network. The result is an explicit union so the CLI
|
|
6
|
+
* entry can branch on help / valid / invalid without inspecting message text.
|
|
7
|
+
*/
|
|
8
|
+
import { SETUP_ERROR_CODES, setupFailure } from "./errors.js";
|
|
9
|
+
/** Default service-account name when `--sa-name` is not given. */
|
|
10
|
+
export const DEFAULT_SA_NAME = "hikoutei-sa";
|
|
11
|
+
/** Default output file name (resolved against the current directory by main). */
|
|
12
|
+
export const DEFAULT_OUTPUT_FILE_NAME = ".env";
|
|
13
|
+
const SETUP_FLAGS = {
|
|
14
|
+
HELP: "--help",
|
|
15
|
+
HELP_SHORT: "-h",
|
|
16
|
+
PROJECT: "--project",
|
|
17
|
+
SA_NAME: "--sa-name",
|
|
18
|
+
SPREADSHEET_TITLE: "--spreadsheet-title",
|
|
19
|
+
OUTPUT: "--output",
|
|
20
|
+
YES: "--yes",
|
|
21
|
+
DRY_RUN: "--dry-run",
|
|
22
|
+
};
|
|
23
|
+
export const SETUP_HELP_TEXT = [
|
|
24
|
+
"hikoutei setup - bootstrap a Google Cloud project, service account, key, and",
|
|
25
|
+
"spreadsheet for Hikoutei sync, then write a ready-to-use .env file.",
|
|
26
|
+
"",
|
|
27
|
+
"Prerequisites: the gcloud CLI is installed and `gcloud auth login` has been",
|
|
28
|
+
"run once (an active account is required).",
|
|
29
|
+
"",
|
|
30
|
+
"Usage:",
|
|
31
|
+
" hikoutei setup [options]",
|
|
32
|
+
"",
|
|
33
|
+
"Options:",
|
|
34
|
+
" --project <id> Use an existing Google Cloud project instead of",
|
|
35
|
+
" creating one (verified with `gcloud projects",
|
|
36
|
+
" describe`).",
|
|
37
|
+
" --sa-name <name> Service-account name (default: hikoutei-sa).",
|
|
38
|
+
" --spreadsheet-title <title> Title of the spreadsheet to create (default:",
|
|
39
|
+
" hikoutei-sync-<project>).",
|
|
40
|
+
" --output <path> .env file to write or update (default: .env in",
|
|
41
|
+
" the current directory).",
|
|
42
|
+
" --yes Skip interactive confirmation (non-interactive",
|
|
43
|
+
" mode).",
|
|
44
|
+
" --dry-run Print the exact gcloud command sequence and",
|
|
45
|
+
" simulated outcomes without executing anything.",
|
|
46
|
+
" -h, --help Show this help and exit.",
|
|
47
|
+
"",
|
|
48
|
+
].join("\n");
|
|
49
|
+
/** True when the flag is a value flag; used to accept `--flag value` and `--flag=value`. */
|
|
50
|
+
const VALUE_FLAGS = [
|
|
51
|
+
SETUP_FLAGS.PROJECT,
|
|
52
|
+
SETUP_FLAGS.SA_NAME,
|
|
53
|
+
SETUP_FLAGS.SPREADSHEET_TITLE,
|
|
54
|
+
SETUP_FLAGS.OUTPUT,
|
|
55
|
+
];
|
|
56
|
+
/**
|
|
57
|
+
* Parses raw argv (without node/script) into setup options.
|
|
58
|
+
*
|
|
59
|
+
* `--flag value` and `--flag=value` are both accepted. A leading `setup`
|
|
60
|
+
* token is ignored so the npm bin works both as `hikoutei setup ...` and as
|
|
61
|
+
* `node dist/cli/setup.js ...`. Unknown flags, missing values, boolean flags
|
|
62
|
+
* given a value, and other positional arguments are rejected with
|
|
63
|
+
* `invalid_args`. `--help` short-circuits with the help text.
|
|
64
|
+
*/
|
|
65
|
+
export function parseSetupArgs(argv) {
|
|
66
|
+
// `npx hikoutei setup ...` invokes the bin with `setup` as the first arg.
|
|
67
|
+
const args = argv.length > 0 && argv[0] === "setup" ? argv.slice(1) : argv;
|
|
68
|
+
let projectId;
|
|
69
|
+
let saName = DEFAULT_SA_NAME;
|
|
70
|
+
let spreadsheetTitle;
|
|
71
|
+
let output = DEFAULT_OUTPUT_FILE_NAME;
|
|
72
|
+
let yes = false;
|
|
73
|
+
let dryRun = false;
|
|
74
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
75
|
+
const arg = args[index];
|
|
76
|
+
if (arg === SETUP_FLAGS.HELP || arg === SETUP_FLAGS.HELP_SHORT) {
|
|
77
|
+
return { status: "help", helpText: SETUP_HELP_TEXT };
|
|
78
|
+
}
|
|
79
|
+
if (arg === SETUP_FLAGS.YES) {
|
|
80
|
+
yes = true;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (arg === SETUP_FLAGS.DRY_RUN) {
|
|
84
|
+
dryRun = true;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const equalsIndex = arg.indexOf("=");
|
|
88
|
+
const flagName = equalsIndex === -1 ? arg : arg.slice(0, equalsIndex);
|
|
89
|
+
if (VALUE_FLAGS.includes(flagName)) {
|
|
90
|
+
const value = equalsIndex === -1 ? args[index + 1] : arg.slice(equalsIndex + 1);
|
|
91
|
+
if (value === undefined || value === "" || (equalsIndex === -1 && value.startsWith("-"))) {
|
|
92
|
+
return {
|
|
93
|
+
status: "invalid",
|
|
94
|
+
failure: setupFailure(SETUP_ERROR_CODES.INVALID_ARGS, `${flagName} requires a value`),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
switch (flagName) {
|
|
98
|
+
case SETUP_FLAGS.PROJECT:
|
|
99
|
+
projectId = value;
|
|
100
|
+
break;
|
|
101
|
+
case SETUP_FLAGS.SA_NAME:
|
|
102
|
+
saName = value;
|
|
103
|
+
break;
|
|
104
|
+
case SETUP_FLAGS.SPREADSHEET_TITLE:
|
|
105
|
+
spreadsheetTitle = value;
|
|
106
|
+
break;
|
|
107
|
+
case SETUP_FLAGS.OUTPUT:
|
|
108
|
+
output = value;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
if (equalsIndex === -1) {
|
|
112
|
+
index += 1;
|
|
113
|
+
}
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (arg.startsWith("-")) {
|
|
117
|
+
return {
|
|
118
|
+
status: "invalid",
|
|
119
|
+
failure: setupFailure(SETUP_ERROR_CODES.INVALID_ARGS, `unknown flag: ${arg}`),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
status: "invalid",
|
|
124
|
+
failure: setupFailure(SETUP_ERROR_CODES.INVALID_ARGS, `unexpected argument: ${arg}`),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
status: "valid",
|
|
129
|
+
options: {
|
|
130
|
+
...(projectId !== undefined ? { projectId } : {}),
|
|
131
|
+
...(spreadsheetTitle !== undefined ? { spreadsheetTitle } : {}),
|
|
132
|
+
saName,
|
|
133
|
+
output,
|
|
134
|
+
yes,
|
|
135
|
+
dryRun,
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive confirmation for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* The setup flow creates real Google Cloud resources, so the CLI asks for a
|
|
5
|
+
* y/N confirmation before running unless `--yes` (non-interactive mode) or
|
|
6
|
+
* `--dry-run` is given. The input and output sinks are injected so tests can
|
|
7
|
+
* exercise the prompt without a TTY.
|
|
8
|
+
*/
|
|
9
|
+
export interface ConfirmSetupOptions {
|
|
10
|
+
readonly yes: boolean;
|
|
11
|
+
readonly dryRun: boolean;
|
|
12
|
+
/** Line/chunk source; `process.stdin` in the real CLI. */
|
|
13
|
+
readonly input: AsyncIterable<string>;
|
|
14
|
+
readonly output: {
|
|
15
|
+
readonly write: (text: string) => void;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export type ConfirmSetupResult = {
|
|
19
|
+
readonly status: "confirmed";
|
|
20
|
+
} | {
|
|
21
|
+
readonly status: "declined";
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Asks for confirmation unless `--yes` or `--dry-run` was given.
|
|
25
|
+
*
|
|
26
|
+
* Reads a single input chunk; `y`/`yes` (case-insensitive) confirms, anything
|
|
27
|
+
* else or end-of-input declines. Buffers are decoded as UTF-8 so the function
|
|
28
|
+
* works with both string and Buffer stdin streams.
|
|
29
|
+
*/
|
|
30
|
+
export declare function confirmSetup(options: ConfirmSetupOptions): Promise<ConfirmSetupResult>;
|
|
31
|
+
//# sourceMappingURL=confirm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC7D;AAED,MAAM,MAAM,kBAAkB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAKpG;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAW5F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive confirmation for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* The setup flow creates real Google Cloud resources, so the CLI asks for a
|
|
5
|
+
* y/N confirmation before running unless `--yes` (non-interactive mode) or
|
|
6
|
+
* `--dry-run` is given. The input and output sinks are injected so tests can
|
|
7
|
+
* exercise the prompt without a TTY.
|
|
8
|
+
*/
|
|
9
|
+
const CONFIRMATION_PROMPT = "This will create Google Cloud resources (project, service account, key, spreadsheet). Continue? [y/N] ";
|
|
10
|
+
/**
|
|
11
|
+
* Asks for confirmation unless `--yes` or `--dry-run` was given.
|
|
12
|
+
*
|
|
13
|
+
* Reads a single input chunk; `y`/`yes` (case-insensitive) confirms, anything
|
|
14
|
+
* else or end-of-input declines. Buffers are decoded as UTF-8 so the function
|
|
15
|
+
* works with both string and Buffer stdin streams.
|
|
16
|
+
*/
|
|
17
|
+
export async function confirmSetup(options) {
|
|
18
|
+
if (options.yes || options.dryRun) {
|
|
19
|
+
return { status: "confirmed" };
|
|
20
|
+
}
|
|
21
|
+
options.output.write(CONFIRMATION_PROMPT);
|
|
22
|
+
for await (const chunk of options.input) {
|
|
23
|
+
const text = typeof chunk === "string" ? chunk : String(chunk);
|
|
24
|
+
const answer = text.trim().toLowerCase();
|
|
25
|
+
return answer === "y" || answer === "yes" ? { status: "confirmed" } : { status: "declined" };
|
|
26
|
+
}
|
|
27
|
+
return { status: "declined" };
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=confirm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/cli/confirm.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAYH,MAAM,mBAAmB,GACvB,wGAAwG,CAAC;AAE3G;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA4B;IAC7D,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjC,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC1C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACzC,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC/F,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured error taxonomy for the `hikoutei setup` CLI.
|
|
3
|
+
*
|
|
4
|
+
* Every failure the setup flow can produce maps to a stable machine-readable
|
|
5
|
+
* code plus a human message. Callers (the CLI entry, tests, and any wrapper)
|
|
6
|
+
* branch on the code, never on message text. Codes are phase-level: all
|
|
7
|
+
* project-phase failures share one code, all service-account failures share
|
|
8
|
+
* another, and so on; the message carries the specific detail.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SETUP_ERROR_CODES: {
|
|
11
|
+
/** gcloud CLI is not installed or `gcloud --version` fails. */
|
|
12
|
+
readonly GCLOUD_MISSING: "gcloud_missing";
|
|
13
|
+
/** No active gcloud account, or `gcloud auth list` fails. */
|
|
14
|
+
readonly GCLOUD_NOT_LOGGED_IN: "gcloud_not_logged_in";
|
|
15
|
+
/** `gcloud projects create` failed for a reason other than "already exists". */
|
|
16
|
+
readonly PROJECT_CREATE_FAILED: "project_create_failed";
|
|
17
|
+
/** An explicitly requested `--project` could not be verified with `gcloud projects describe`. */
|
|
18
|
+
readonly PROJECT_NOT_FOUND: "project_not_found";
|
|
19
|
+
/** `gcloud config set project` failed. */
|
|
20
|
+
readonly PROJECT_SELECT_FAILED: "project_select_failed";
|
|
21
|
+
/** `gcloud services enable sheets.googleapis.com` failed. */
|
|
22
|
+
readonly API_ENABLE_FAILED: "api_enable_failed";
|
|
23
|
+
/** Service-account listing or creation failed. */
|
|
24
|
+
readonly SA_CREATE_FAILED: "sa_create_failed";
|
|
25
|
+
/** Service-account key creation or securing (chmod 600) failed. */
|
|
26
|
+
readonly KEY_CREATE_FAILED: "key_create_failed";
|
|
27
|
+
/** Spreadsheet creation through the Sheets API failed. */
|
|
28
|
+
readonly SHEET_CREATE_FAILED: "sheet_create_failed";
|
|
29
|
+
/** Writing/updating the .env output file failed. */
|
|
30
|
+
readonly OUTPUT_WRITE_FAILED: "output_write_failed";
|
|
31
|
+
/** Command-line arguments are malformed (unknown flag, missing value, ...). */
|
|
32
|
+
readonly INVALID_ARGS: "invalid_args";
|
|
33
|
+
};
|
|
34
|
+
/** Union of every machine-readable setup error code. */
|
|
35
|
+
export type SetupErrorCode = (typeof SETUP_ERROR_CODES)[keyof typeof SETUP_ERROR_CODES];
|
|
36
|
+
/** Exit code for usage/argument errors. */
|
|
37
|
+
export declare const SETUP_ARG_ERROR_EXIT_CODE = 2;
|
|
38
|
+
/** Exit code for runtime failures. */
|
|
39
|
+
export declare const SETUP_RUNTIME_ERROR_EXIT_CODE = 1;
|
|
40
|
+
/** A structured setup failure: stable code plus a human-readable message. */
|
|
41
|
+
export interface SetupFailure {
|
|
42
|
+
readonly code: SetupErrorCode;
|
|
43
|
+
readonly message: string;
|
|
44
|
+
}
|
|
45
|
+
/** Builds a structured failure value. */
|
|
46
|
+
export declare function setupFailure(code: SetupErrorCode, message: string): SetupFailure;
|
|
47
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,iBAAiB;IAC5B,+DAA+D;;IAE/D,6DAA6D;;IAE7D,gFAAgF;;IAEhF,iGAAiG;;IAEjG,0CAA0C;;IAE1C,6DAA6D;;IAE7D,kDAAkD;;IAElD,mEAAmE;;IAEnE,0DAA0D;;IAE1D,oDAAoD;;IAEpD,+EAA+E;;CAEvE,CAAC;AAEX,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,OAAO,iBAAiB,CAAC,CAAC;AAExF,2CAA2C;AAC3C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAE3C,sCAAsC;AACtC,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,yCAAyC;AACzC,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAEhF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured error taxonomy for the `hikoutei setup` CLI.
|
|
3
|
+
*
|
|
4
|
+
* Every failure the setup flow can produce maps to a stable machine-readable
|
|
5
|
+
* code plus a human message. Callers (the CLI entry, tests, and any wrapper)
|
|
6
|
+
* branch on the code, never on message text. Codes are phase-level: all
|
|
7
|
+
* project-phase failures share one code, all service-account failures share
|
|
8
|
+
* another, and so on; the message carries the specific detail.
|
|
9
|
+
*/
|
|
10
|
+
export const SETUP_ERROR_CODES = {
|
|
11
|
+
/** gcloud CLI is not installed or `gcloud --version` fails. */
|
|
12
|
+
GCLOUD_MISSING: "gcloud_missing",
|
|
13
|
+
/** No active gcloud account, or `gcloud auth list` fails. */
|
|
14
|
+
GCLOUD_NOT_LOGGED_IN: "gcloud_not_logged_in",
|
|
15
|
+
/** `gcloud projects create` failed for a reason other than "already exists". */
|
|
16
|
+
PROJECT_CREATE_FAILED: "project_create_failed",
|
|
17
|
+
/** An explicitly requested `--project` could not be verified with `gcloud projects describe`. */
|
|
18
|
+
PROJECT_NOT_FOUND: "project_not_found",
|
|
19
|
+
/** `gcloud config set project` failed. */
|
|
20
|
+
PROJECT_SELECT_FAILED: "project_select_failed",
|
|
21
|
+
/** `gcloud services enable sheets.googleapis.com` failed. */
|
|
22
|
+
API_ENABLE_FAILED: "api_enable_failed",
|
|
23
|
+
/** Service-account listing or creation failed. */
|
|
24
|
+
SA_CREATE_FAILED: "sa_create_failed",
|
|
25
|
+
/** Service-account key creation or securing (chmod 600) failed. */
|
|
26
|
+
KEY_CREATE_FAILED: "key_create_failed",
|
|
27
|
+
/** Spreadsheet creation through the Sheets API failed. */
|
|
28
|
+
SHEET_CREATE_FAILED: "sheet_create_failed",
|
|
29
|
+
/** Writing/updating the .env output file failed. */
|
|
30
|
+
OUTPUT_WRITE_FAILED: "output_write_failed",
|
|
31
|
+
/** Command-line arguments are malformed (unknown flag, missing value, ...). */
|
|
32
|
+
INVALID_ARGS: "invalid_args",
|
|
33
|
+
};
|
|
34
|
+
/** Exit code for usage/argument errors. */
|
|
35
|
+
export const SETUP_ARG_ERROR_EXIT_CODE = 2;
|
|
36
|
+
/** Exit code for runtime failures. */
|
|
37
|
+
export const SETUP_RUNTIME_ERROR_EXIT_CODE = 1;
|
|
38
|
+
/** Builds a structured failure value. */
|
|
39
|
+
export function setupFailure(code, message) {
|
|
40
|
+
return { code, message };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,+DAA+D;IAC/D,cAAc,EAAE,gBAAgB;IAChC,6DAA6D;IAC7D,oBAAoB,EAAE,sBAAsB;IAC5C,gFAAgF;IAChF,qBAAqB,EAAE,uBAAuB;IAC9C,iGAAiG;IACjG,iBAAiB,EAAE,mBAAmB;IACtC,0CAA0C;IAC1C,qBAAqB,EAAE,uBAAuB;IAC9C,6DAA6D;IAC7D,iBAAiB,EAAE,mBAAmB;IACtC,kDAAkD;IAClD,gBAAgB,EAAE,kBAAkB;IACpC,mEAAmE;IACnE,iBAAiB,EAAE,mBAAmB;IACtC,0DAA0D;IAC1D,mBAAmB,EAAE,qBAAqB;IAC1C,oDAAoD;IACpD,mBAAmB,EAAE,qBAAqB;IAC1C,+EAA+E;IAC/E,YAAY,EAAE,cAAc;CACpB,CAAC;AAKX,2CAA2C;AAC3C,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC;AAE3C,sCAAsC;AACtC,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC;AAQ/C,yCAAyC;AACzC,MAAM,UAAU,YAAY,CAAC,IAAoB,EAAE,OAAe;IAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gcloud subprocess runner for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* All gcloud invocations go through the `GcloudRunner` interface so unit
|
|
5
|
+
* tests can inject a fake runner that records commands and returns scripted
|
|
6
|
+
* results without touching the real CLI or the network. The production
|
|
7
|
+
* implementation shells out with `node:child_process` `execFile`; a missing
|
|
8
|
+
* binary is reported distinctly (`not_found`) from a failed invocation.
|
|
9
|
+
*/
|
|
10
|
+
/** Outcome of one gcloud invocation. */
|
|
11
|
+
export type GcloudRunResult = {
|
|
12
|
+
readonly status: "ok";
|
|
13
|
+
readonly stdout: string;
|
|
14
|
+
readonly stderr: string;
|
|
15
|
+
} | {
|
|
16
|
+
readonly status: "not_found";
|
|
17
|
+
} | {
|
|
18
|
+
readonly status: "failed";
|
|
19
|
+
/** Process exit code, or null when the process could not be spawned. */
|
|
20
|
+
readonly code: number | null;
|
|
21
|
+
readonly stdout: string;
|
|
22
|
+
readonly stderr: string;
|
|
23
|
+
};
|
|
24
|
+
/** Runs gcloud with the given arguments and returns the process outcome. */
|
|
25
|
+
export interface GcloudRunner {
|
|
26
|
+
run(args: readonly string[]): Promise<GcloudRunResult>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Production runner: executes `gcloud <args>` with `execFile`.
|
|
30
|
+
*
|
|
31
|
+
* `not_found` is returned when the binary is absent from PATH so the preflight
|
|
32
|
+
* can produce a clear "install gcloud" error instead of a generic failure.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createGcloudRunner(): GcloudRunner;
|
|
35
|
+
//# sourceMappingURL=gcloudRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcloudRunner.d.ts","sourceRoot":"","sources":["../../src/cli/gcloudRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,wCAAwC;AACxC,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3E;IAAE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAChC;IACA,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEJ,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACxD;AAKD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAyBjD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gcloud subprocess runner for `hikoutei setup`.
|
|
3
|
+
*
|
|
4
|
+
* All gcloud invocations go through the `GcloudRunner` interface so unit
|
|
5
|
+
* tests can inject a fake runner that records commands and returns scripted
|
|
6
|
+
* results without touching the real CLI or the network. The production
|
|
7
|
+
* implementation shells out with `node:child_process` `execFile`; a missing
|
|
8
|
+
* binary is reported distinctly (`not_found`) from a failed invocation.
|
|
9
|
+
*/
|
|
10
|
+
import { execFile } from "node:child_process";
|
|
11
|
+
const GCLOUD_BINARY = "gcloud";
|
|
12
|
+
const MAX_BUFFER_BYTES = 1024 * 1024;
|
|
13
|
+
/**
|
|
14
|
+
* Production runner: executes `gcloud <args>` with `execFile`.
|
|
15
|
+
*
|
|
16
|
+
* `not_found` is returned when the binary is absent from PATH so the preflight
|
|
17
|
+
* can produce a clear "install gcloud" error instead of a generic failure.
|
|
18
|
+
*/
|
|
19
|
+
export function createGcloudRunner() {
|
|
20
|
+
return {
|
|
21
|
+
run(args) {
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
execFile(GCLOUD_BINARY, [...args], { encoding: "utf8", maxBuffer: MAX_BUFFER_BYTES }, (error, stdout, stderr) => {
|
|
24
|
+
if (error === null) {
|
|
25
|
+
resolve({ status: "ok", stdout, stderr });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const errno = error;
|
|
29
|
+
if (errno.code === "ENOENT") {
|
|
30
|
+
resolve({ status: "not_found" });
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const code = typeof errno.code === "number" ? errno.code : null;
|
|
34
|
+
resolve({ status: "failed", code, stdout, stderr });
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=gcloudRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gcloudRunner.js","sourceRoot":"","sources":["../../src/cli/gcloudRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAmB9C,MAAM,aAAa,GAAG,QAAQ,CAAC;AAC/B,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAErC;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,GAAG,CAAC,IAAuB;YACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,QAAQ,CACN,aAAa,EACb,CAAC,GAAG,IAAI,CAAC,EACT,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,EACjD,CAAC,KAAc,EAAE,MAAc,EAAE,MAAc,EAAE,EAAE;oBACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;wBACnB,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;wBAC1C,OAAO;oBACT,CAAC;oBACD,MAAM,KAAK,GAAG,KAA8B,CAAC;oBAC7C,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;wBACjC,OAAO;oBACT,CAAC;oBACD,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;oBAChE,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;gBACtD,CAAC,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `hikoutei setup` CLI entry.
|
|
4
|
+
*
|
|
5
|
+
* Thin main: parse flags, resolve path defaults against the current
|
|
6
|
+
* directory, ask for confirmation (unless `--yes`/`--dry-run`), run the
|
|
7
|
+
* injected-runner setup flow, and print the summary or the dry-run plan.
|
|
8
|
+
* Exit codes: 0 success, 2 argument errors, 1 runtime failures. Errors are
|
|
9
|
+
* printed as `hikoutei-setup:<code>: <message>` for machine consumption, and
|
|
10
|
+
* key material is never printed.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `hikoutei setup` CLI entry.
|
|
4
|
+
*
|
|
5
|
+
* Thin main: parse flags, resolve path defaults against the current
|
|
6
|
+
* directory, ask for confirmation (unless `--yes`/`--dry-run`), run the
|
|
7
|
+
* injected-runner setup flow, and print the summary or the dry-run plan.
|
|
8
|
+
* Exit codes: 0 success, 2 argument errors, 1 runtime failures. Errors are
|
|
9
|
+
* printed as `hikoutei-setup:<code>: <message>` for machine consumption, and
|
|
10
|
+
* key material is never printed.
|
|
11
|
+
*/
|
|
12
|
+
import { resolve } from "node:path";
|
|
13
|
+
import { parseSetupArgs } from "./args.js";
|
|
14
|
+
import { confirmSetup } from "./confirm.js";
|
|
15
|
+
import { SETUP_ARG_ERROR_EXIT_CODE, SETUP_ERROR_CODES, SETUP_RUNTIME_ERROR_EXIT_CODE, } from "./errors.js";
|
|
16
|
+
import { createGcloudRunner } from "./gcloudRunner.js";
|
|
17
|
+
import { createGoogleSheetsSpreadsheetCreator } from "./sheetsFactory.js";
|
|
18
|
+
import { DEFAULT_KEY_FILE_NAME, formatPlan, formatSummary, runSetup, } from "./setupFlow.js";
|
|
19
|
+
async function main() {
|
|
20
|
+
const parsed = parseSetupArgs(process.argv.slice(2));
|
|
21
|
+
if (parsed.status === "help") {
|
|
22
|
+
process.stdout.write(`${parsed.helpText}\n`);
|
|
23
|
+
return 0;
|
|
24
|
+
}
|
|
25
|
+
if (parsed.status === "invalid") {
|
|
26
|
+
process.stderr.write(`hikoutei-setup:${parsed.failure.code}: ${parsed.failure.message}\n`);
|
|
27
|
+
process.stderr.write("Run `hikoutei setup --help` for usage.\n");
|
|
28
|
+
return parsed.failure.code === SETUP_ERROR_CODES.INVALID_ARGS
|
|
29
|
+
? SETUP_ARG_ERROR_EXIT_CODE
|
|
30
|
+
: SETUP_RUNTIME_ERROR_EXIT_CODE;
|
|
31
|
+
}
|
|
32
|
+
const options = parsed.options;
|
|
33
|
+
const cwd = process.cwd();
|
|
34
|
+
const confirmed = await confirmSetup({
|
|
35
|
+
yes: options.yes,
|
|
36
|
+
dryRun: options.dryRun,
|
|
37
|
+
input: process.stdin,
|
|
38
|
+
output: process.stdout,
|
|
39
|
+
});
|
|
40
|
+
if (confirmed.status === "declined") {
|
|
41
|
+
process.stdout.write("Setup aborted. Pass --yes to run without confirmation.\n");
|
|
42
|
+
return SETUP_RUNTIME_ERROR_EXIT_CODE;
|
|
43
|
+
}
|
|
44
|
+
const result = await runSetup({
|
|
45
|
+
runner: createGcloudRunner(),
|
|
46
|
+
createSpreadsheet: createGoogleSheetsSpreadsheetCreator(),
|
|
47
|
+
projectId: options.projectId,
|
|
48
|
+
saName: options.saName,
|
|
49
|
+
spreadsheetTitle: options.spreadsheetTitle,
|
|
50
|
+
keyPath: resolve(cwd, DEFAULT_KEY_FILE_NAME),
|
|
51
|
+
outputPath: resolve(cwd, options.output),
|
|
52
|
+
dryRun: options.dryRun,
|
|
53
|
+
});
|
|
54
|
+
if (result.status === "error") {
|
|
55
|
+
process.stderr.write(`hikoutei-setup:${result.code}: ${result.message}\n`);
|
|
56
|
+
return SETUP_RUNTIME_ERROR_EXIT_CODE;
|
|
57
|
+
}
|
|
58
|
+
if (result.dryRun) {
|
|
59
|
+
process.stdout.write("Hikoutei setup dry run (nothing was executed). Planned steps:\n");
|
|
60
|
+
process.stdout.write(`${formatPlan(result.commands)}\n`);
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
process.stdout.write(`${formatSummary(result.summary)}\n`);
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
main()
|
|
67
|
+
.then((code) => {
|
|
68
|
+
process.exitCode = code;
|
|
69
|
+
})
|
|
70
|
+
.catch((error) => {
|
|
71
|
+
process.stderr.write(`hikoutei-setup:unexpected: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
72
|
+
process.exitCode = SETUP_RUNTIME_ERROR_EXIT_CODE;
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"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"}
|