hikoutei 0.5.11 → 0.5.13

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.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Spreadsheet creation for `hikoutei setup`.
3
+ *
4
+ * The setup CLI creates the sync spreadsheet with the freshly provisioned
5
+ * service-account key, so the service account owns the spreadsheet and no
6
+ * sharing step is needed. The production implementation uses
7
+ * google-auth-library plus @googleapis/sheets (already root dependencies);
8
+ * tests inject a fake creator, so unit tests never touch the network.
9
+ *
10
+ * The API response is treated as untrusted input: it is validated by a
11
+ * runtime guard before it is promoted into the internal result shape.
12
+ */
13
+ import { GoogleAuth } from "google-auth-library";
14
+ import { sheets } from "@googleapis/sheets";
15
+ /** OAuth scope required to create and write spreadsheets. */
16
+ export const SPREADSHEETS_SCOPE = "https://www.googleapis.com/auth/spreadsheets";
17
+ /** Template for the human-facing spreadsheet edit URL. */
18
+ export const SPREADSHEET_EDIT_URL_TEMPLATE = "https://docs.google.com/spreadsheets/d/<id>/edit";
19
+ /**
20
+ * Production spreadsheet creator.
21
+ *
22
+ * Authenticates with the given service-account key file and calls
23
+ * `spreadsheets.create`. Throws on failure; the setup flow maps any throw to
24
+ * the `sheet_create_failed` error code. The key file path is never included
25
+ * in error output.
26
+ */
27
+ export function createGoogleSheetsSpreadsheetCreator() {
28
+ return async (request) => {
29
+ // google-auth-library may resolve to a version nested under googleapis-common
30
+ // that differs from the top-level one; the boundary cast keeps any SDK
31
+ // version mismatch contained in this module.
32
+ const auth = new GoogleAuth({
33
+ keyFile: request.keyPath,
34
+ scopes: [SPREADSHEETS_SCOPE],
35
+ });
36
+ const client = sheets({ version: "v4", auth });
37
+ const response = await client.spreadsheets.create({
38
+ requestBody: { properties: { title: request.title } },
39
+ });
40
+ return extractSpreadsheetCreateResult(response.data);
41
+ };
42
+ }
43
+ /** Builds the public edit URL for a spreadsheet id. */
44
+ export function spreadsheetEditUrl(spreadsheetId) {
45
+ return SPREADSHEET_EDIT_URL_TEMPLATE.replace("<id>", spreadsheetId);
46
+ }
47
+ function isRecord(value) {
48
+ return typeof value === "object" && value !== null && !Array.isArray(value);
49
+ }
50
+ /**
51
+ * Validates the raw `spreadsheets.create` payload and promotes it into the
52
+ * internal result shape.
53
+ *
54
+ * The response is untrusted SDK data, so `spreadsheetId` must be proven to be
55
+ * a non-empty string. When the API omits `spreadsheetUrl` (it can), the URL
56
+ * is derived from the id deterministically.
57
+ */
58
+ export function extractSpreadsheetCreateResult(data) {
59
+ if (!isRecord(data)) {
60
+ throw new Error("spreadsheets.create returned a non-object payload");
61
+ }
62
+ const { spreadsheetId, spreadsheetUrl } = data;
63
+ if (typeof spreadsheetId !== "string" || spreadsheetId === "") {
64
+ throw new Error("spreadsheets.create response is missing a spreadsheet id");
65
+ }
66
+ if (typeof spreadsheetUrl === "string" && spreadsheetUrl !== "") {
67
+ return { spreadsheetId, spreadsheetUrl };
68
+ }
69
+ return { spreadsheetId, spreadsheetUrl: spreadsheetEditUrl(spreadsheetId) };
70
+ }
71
+ //# sourceMappingURL=sheetsFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheetsFactory.js","sourceRoot":"","sources":["../../src/cli/sheetsFactory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,8CAA8C,CAAC;AAEjF,0DAA0D;AAC1D,MAAM,CAAC,MAAM,6BAA6B,GAAG,kDAAkD,CAAC;AAsBhG;;;;;;;GAOG;AACH,MAAM,UAAU,oCAAoC;IAClD,OAAO,KAAK,EAAE,OAAiC,EAAoC,EAAE;QACnF,8EAA8E;QAC9E,uEAAuE;QACvE,6CAA6C;QAC7C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,CAAC,kBAAkB,CAAC;SAC7B,CAA0B,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;YAChD,WAAW,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE;SACtD,CAAC,CAAC;QACH,OAAO,8BAA8B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC,CAAC;AACJ,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,kBAAkB,CAAC,aAAqB;IACtD,OAAO,6BAA6B,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,8BAA8B,CAAC,IAAa;IAC1D,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAC/C,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,KAAK,EAAE,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,KAAK,EAAE,EAAE,CAAC;QAChE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,CAAC,aAAa,CAAC,EAAE,CAAC;AAC9E,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hikoutei",
3
- "version": "0.5.11",
3
+ "version": "0.5.13",
4
4
  "description": "Typed repository and safe write layer for Google Sheets-backed MVPs. SQLite-authoritative entity lifecycle with asynchronous Google Sheets projection.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -16,6 +16,9 @@
16
16
  },
17
17
  "main": "./dist/index.js",
18
18
  "types": "./dist/index.d.ts",
19
+ "bin": {
20
+ "hikoutei": "./dist/cli/setup.js"
21
+ },
19
22
  "exports": {
20
23
  ".": {
21
24
  "types": "./dist/index.d.ts",