@hs-x/cli 0.1.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.
Files changed (302) hide show
  1. package/README.md +1001 -0
  2. package/dist/account-store.d.ts +51 -0
  3. package/dist/account-store.d.ts.map +1 -0
  4. package/dist/account-store.js +138 -0
  5. package/dist/account-store.js.map +1 -0
  6. package/dist/bin/hs-x.d.ts +3 -0
  7. package/dist/bin/hs-x.d.ts.map +1 -0
  8. package/dist/bin/hs-x.js +47 -0
  9. package/dist/bin/hs-x.js.map +1 -0
  10. package/dist/cli/index.d.ts +3 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +595 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli-error.d.ts +36 -0
  15. package/dist/cli-error.d.ts.map +1 -0
  16. package/dist/cli-error.js +40 -0
  17. package/dist/cli-error.js.map +1 -0
  18. package/dist/cloudflare-auth.d.ts +25 -0
  19. package/dist/cloudflare-auth.d.ts.map +1 -0
  20. package/dist/cloudflare-auth.js +251 -0
  21. package/dist/cloudflare-auth.js.map +1 -0
  22. package/dist/cloudflare-kv.d.ts +23 -0
  23. package/dist/cloudflare-kv.d.ts.map +1 -0
  24. package/dist/cloudflare-kv.js +101 -0
  25. package/dist/cloudflare-kv.js.map +1 -0
  26. package/dist/cloudflare-oauth-store.d.ts +16 -0
  27. package/dist/cloudflare-oauth-store.d.ts.map +1 -0
  28. package/dist/cloudflare-oauth-store.js +80 -0
  29. package/dist/cloudflare-oauth-store.js.map +1 -0
  30. package/dist/cloudflare-oauth.d.ts +82 -0
  31. package/dist/cloudflare-oauth.d.ts.map +1 -0
  32. package/dist/cloudflare-oauth.js +336 -0
  33. package/dist/cloudflare-oauth.js.map +1 -0
  34. package/dist/cloudflare-pointer.d.ts +13 -0
  35. package/dist/cloudflare-pointer.d.ts.map +1 -0
  36. package/dist/cloudflare-pointer.js +46 -0
  37. package/dist/cloudflare-pointer.js.map +1 -0
  38. package/dist/command-history.d.ts +7 -0
  39. package/dist/command-history.d.ts.map +1 -0
  40. package/dist/command-history.js +34 -0
  41. package/dist/command-history.js.map +1 -0
  42. package/dist/commands/account.d.ts +7 -0
  43. package/dist/commands/account.d.ts.map +1 -0
  44. package/dist/commands/account.js +315 -0
  45. package/dist/commands/account.js.map +1 -0
  46. package/dist/commands/api.d.ts +36 -0
  47. package/dist/commands/api.d.ts.map +1 -0
  48. package/dist/commands/api.js +521 -0
  49. package/dist/commands/api.js.map +1 -0
  50. package/dist/commands/completion.d.ts +7 -0
  51. package/dist/commands/completion.d.ts.map +1 -0
  52. package/dist/commands/completion.js +121 -0
  53. package/dist/commands/completion.js.map +1 -0
  54. package/dist/commands/connect.d.ts +7 -0
  55. package/dist/commands/connect.d.ts.map +1 -0
  56. package/dist/commands/connect.js +1123 -0
  57. package/dist/commands/connect.js.map +1 -0
  58. package/dist/commands/control-plane-read.d.ts +22 -0
  59. package/dist/commands/control-plane-read.d.ts.map +1 -0
  60. package/dist/commands/control-plane-read.js +350 -0
  61. package/dist/commands/control-plane-read.js.map +1 -0
  62. package/dist/commands/deploy-promote.d.ts +14 -0
  63. package/dist/commands/deploy-promote.d.ts.map +1 -0
  64. package/dist/commands/deploy-promote.js +105 -0
  65. package/dist/commands/deploy-promote.js.map +1 -0
  66. package/dist/commands/deploy.d.ts +18 -0
  67. package/dist/commands/deploy.d.ts.map +1 -0
  68. package/dist/commands/deploy.js +2764 -0
  69. package/dist/commands/deploy.js.map +1 -0
  70. package/dist/commands/dev.d.ts +7 -0
  71. package/dist/commands/dev.d.ts.map +1 -0
  72. package/dist/commands/dev.js +913 -0
  73. package/dist/commands/dev.js.map +1 -0
  74. package/dist/commands/doctor.d.ts +8 -0
  75. package/dist/commands/doctor.d.ts.map +1 -0
  76. package/dist/commands/doctor.js +258 -0
  77. package/dist/commands/doctor.js.map +1 -0
  78. package/dist/commands/flags.d.ts +22 -0
  79. package/dist/commands/flags.d.ts.map +1 -0
  80. package/dist/commands/flags.js +185 -0
  81. package/dist/commands/flags.js.map +1 -0
  82. package/dist/commands/help-command.d.ts +13 -0
  83. package/dist/commands/help-command.d.ts.map +1 -0
  84. package/dist/commands/help-command.js +482 -0
  85. package/dist/commands/help-command.js.map +1 -0
  86. package/dist/commands/history.d.ts +6 -0
  87. package/dist/commands/history.d.ts.map +1 -0
  88. package/dist/commands/history.js +42 -0
  89. package/dist/commands/history.js.map +1 -0
  90. package/dist/commands/init.d.ts +8 -0
  91. package/dist/commands/init.d.ts.map +1 -0
  92. package/dist/commands/init.js +233 -0
  93. package/dist/commands/init.js.map +1 -0
  94. package/dist/commands/link.d.ts +26 -0
  95. package/dist/commands/link.d.ts.map +1 -0
  96. package/dist/commands/link.js +441 -0
  97. package/dist/commands/link.js.map +1 -0
  98. package/dist/commands/login.d.ts +8 -0
  99. package/dist/commands/login.d.ts.map +1 -0
  100. package/dist/commands/login.js +381 -0
  101. package/dist/commands/login.js.map +1 -0
  102. package/dist/commands/migrate.d.ts +8 -0
  103. package/dist/commands/migrate.d.ts.map +1 -0
  104. package/dist/commands/migrate.js +258 -0
  105. package/dist/commands/migrate.js.map +1 -0
  106. package/dist/commands/rollback.d.ts +21 -0
  107. package/dist/commands/rollback.d.ts.map +1 -0
  108. package/dist/commands/rollback.js +301 -0
  109. package/dist/commands/rollback.js.map +1 -0
  110. package/dist/commands/secrets.d.ts +7 -0
  111. package/dist/commands/secrets.d.ts.map +1 -0
  112. package/dist/commands/secrets.js +230 -0
  113. package/dist/commands/secrets.js.map +1 -0
  114. package/dist/commands/status.d.ts +7 -0
  115. package/dist/commands/status.d.ts.map +1 -0
  116. package/dist/commands/status.js +241 -0
  117. package/dist/commands/status.js.map +1 -0
  118. package/dist/commands/unlink.d.ts +21 -0
  119. package/dist/commands/unlink.d.ts.map +1 -0
  120. package/dist/commands/unlink.js +83 -0
  121. package/dist/commands/unlink.js.map +1 -0
  122. package/dist/commands/update.d.ts +11 -0
  123. package/dist/commands/update.d.ts.map +1 -0
  124. package/dist/commands/update.js +154 -0
  125. package/dist/commands/update.js.map +1 -0
  126. package/dist/commands/validate.d.ts +9 -0
  127. package/dist/commands/validate.d.ts.map +1 -0
  128. package/dist/commands/validate.js +39 -0
  129. package/dist/commands/validate.js.map +1 -0
  130. package/dist/config.d.ts +12 -0
  131. package/dist/config.d.ts.map +1 -0
  132. package/dist/config.js +64 -0
  133. package/dist/config.js.map +1 -0
  134. package/dist/constants.d.ts +4 -0
  135. package/dist/constants.d.ts.map +1 -0
  136. package/dist/constants.js +4 -0
  137. package/dist/constants.js.map +1 -0
  138. package/dist/control-plane-fetch.d.ts +34 -0
  139. package/dist/control-plane-fetch.d.ts.map +1 -0
  140. package/dist/control-plane-fetch.js +73 -0
  141. package/dist/control-plane-fetch.js.map +1 -0
  142. package/dist/control-plane-loader.d.ts +16 -0
  143. package/dist/control-plane-loader.d.ts.map +1 -0
  144. package/dist/control-plane-loader.js +24 -0
  145. package/dist/control-plane-loader.js.map +1 -0
  146. package/dist/dev/compat-shim.d.ts +40 -0
  147. package/dist/dev/compat-shim.d.ts.map +1 -0
  148. package/dist/dev/compat-shim.js +65 -0
  149. package/dist/dev/compat-shim.js.map +1 -0
  150. package/dist/dev/event-bus.d.ts +27 -0
  151. package/dist/dev/event-bus.d.ts.map +1 -0
  152. package/dist/dev/event-bus.js +32 -0
  153. package/dist/dev/event-bus.js.map +1 -0
  154. package/dist/dev/log-server.d.ts +52 -0
  155. package/dist/dev/log-server.d.ts.map +1 -0
  156. package/dist/dev/log-server.js +216 -0
  157. package/dist/dev/log-server.js.map +1 -0
  158. package/dist/dev/session-manager.d.ts +33 -0
  159. package/dist/dev/session-manager.d.ts.map +1 -0
  160. package/dist/dev/session-manager.js +132 -0
  161. package/dist/dev/session-manager.js.map +1 -0
  162. package/dist/dev/stream-renderer.d.ts +22 -0
  163. package/dist/dev/stream-renderer.d.ts.map +1 -0
  164. package/dist/dev/stream-renderer.js +65 -0
  165. package/dist/dev/stream-renderer.js.map +1 -0
  166. package/dist/dev/tunnel.d.ts +40 -0
  167. package/dist/dev/tunnel.d.ts.map +1 -0
  168. package/dist/dev/tunnel.js +139 -0
  169. package/dist/dev/tunnel.js.map +1 -0
  170. package/dist/effect-http.d.ts +10 -0
  171. package/dist/effect-http.d.ts.map +1 -0
  172. package/dist/effect-http.js +38 -0
  173. package/dist/effect-http.js.map +1 -0
  174. package/dist/errors-registry.d.ts +11 -0
  175. package/dist/errors-registry.d.ts.map +1 -0
  176. package/dist/errors-registry.js +554 -0
  177. package/dist/errors-registry.js.map +1 -0
  178. package/dist/errors.d.ts +58 -0
  179. package/dist/errors.d.ts.map +1 -0
  180. package/dist/errors.js +30 -0
  181. package/dist/errors.js.map +1 -0
  182. package/dist/help.d.ts +6 -0
  183. package/dist/help.d.ts.map +1 -0
  184. package/dist/help.js +100 -0
  185. package/dist/help.js.map +1 -0
  186. package/dist/history.d.ts +15 -0
  187. package/dist/history.d.ts.map +1 -0
  188. package/dist/history.js +69 -0
  189. package/dist/history.js.map +1 -0
  190. package/dist/hubspot-auth.d.ts +53 -0
  191. package/dist/hubspot-auth.d.ts.map +1 -0
  192. package/dist/hubspot-auth.js +301 -0
  193. package/dist/hubspot-auth.js.map +1 -0
  194. package/dist/hubspot-developer-client.d.ts +10 -0
  195. package/dist/hubspot-developer-client.d.ts.map +1 -0
  196. package/dist/hubspot-developer-client.js +212 -0
  197. package/dist/hubspot-developer-client.js.map +1 -0
  198. package/dist/index.d.ts +5 -0
  199. package/dist/index.d.ts.map +1 -0
  200. package/dist/index.js +4 -0
  201. package/dist/index.js.map +1 -0
  202. package/dist/init/templates.d.ts +18 -0
  203. package/dist/init/templates.d.ts.map +1 -0
  204. package/dist/init/templates.js +239 -0
  205. package/dist/init/templates.js.map +1 -0
  206. package/dist/load-env.d.ts +16 -0
  207. package/dist/load-env.d.ts.map +1 -0
  208. package/dist/load-env.js +69 -0
  209. package/dist/load-env.js.map +1 -0
  210. package/dist/machine-id.d.ts +3 -0
  211. package/dist/machine-id.d.ts.map +1 -0
  212. package/dist/machine-id.js +41 -0
  213. package/dist/machine-id.js.map +1 -0
  214. package/dist/paths.d.ts +4 -0
  215. package/dist/paths.d.ts.map +1 -0
  216. package/dist/paths.js +19 -0
  217. package/dist/paths.js.map +1 -0
  218. package/dist/prompt.d.ts +43 -0
  219. package/dist/prompt.d.ts.map +1 -0
  220. package/dist/prompt.js +379 -0
  221. package/dist/prompt.js.map +1 -0
  222. package/dist/reporter/human.d.ts +28 -0
  223. package/dist/reporter/human.d.ts.map +1 -0
  224. package/dist/reporter/human.js +126 -0
  225. package/dist/reporter/human.js.map +1 -0
  226. package/dist/reporter/index.d.ts +14 -0
  227. package/dist/reporter/index.d.ts.map +1 -0
  228. package/dist/reporter/index.js +37 -0
  229. package/dist/reporter/index.js.map +1 -0
  230. package/dist/reporter/json.d.ts +43 -0
  231. package/dist/reporter/json.d.ts.map +1 -0
  232. package/dist/reporter/json.js +146 -0
  233. package/dist/reporter/json.js.map +1 -0
  234. package/dist/reporter/style.d.ts +34 -0
  235. package/dist/reporter/style.d.ts.map +1 -0
  236. package/dist/reporter/style.js +97 -0
  237. package/dist/reporter/style.js.map +1 -0
  238. package/dist/reporter/types.d.ts +41 -0
  239. package/dist/reporter/types.d.ts.map +1 -0
  240. package/dist/reporter/types.js +2 -0
  241. package/dist/reporter/types.js.map +1 -0
  242. package/dist/result.d.ts +4 -0
  243. package/dist/result.d.ts.map +1 -0
  244. package/dist/result.js +2 -0
  245. package/dist/result.js.map +1 -0
  246. package/dist/services/account-store.d.ts +31 -0
  247. package/dist/services/account-store.d.ts.map +1 -0
  248. package/dist/services/account-store.js +135 -0
  249. package/dist/services/account-store.js.map +1 -0
  250. package/dist/services/app-paths.d.ts +25 -0
  251. package/dist/services/app-paths.d.ts.map +1 -0
  252. package/dist/services/app-paths.js +34 -0
  253. package/dist/services/app-paths.js.map +1 -0
  254. package/dist/services/cloudflare-auth.d.ts +83 -0
  255. package/dist/services/cloudflare-auth.d.ts.map +1 -0
  256. package/dist/services/cloudflare-auth.js +30 -0
  257. package/dist/services/cloudflare-auth.js.map +1 -0
  258. package/dist/services/cloudflare-kv.d.ts +45 -0
  259. package/dist/services/cloudflare-kv.d.ts.map +1 -0
  260. package/dist/services/cloudflare-kv.js +151 -0
  261. package/dist/services/cloudflare-kv.js.map +1 -0
  262. package/dist/services/command-history.d.ts +29 -0
  263. package/dist/services/command-history.d.ts.map +1 -0
  264. package/dist/services/command-history.js +62 -0
  265. package/dist/services/command-history.js.map +1 -0
  266. package/dist/services/control-plane.d.ts +32 -0
  267. package/dist/services/control-plane.d.ts.map +1 -0
  268. package/dist/services/control-plane.js +57 -0
  269. package/dist/services/control-plane.js.map +1 -0
  270. package/dist/services/env-loader.d.ts +18 -0
  271. package/dist/services/env-loader.d.ts.map +1 -0
  272. package/dist/services/env-loader.js +34 -0
  273. package/dist/services/env-loader.js.map +1 -0
  274. package/dist/services/http.d.ts +19 -0
  275. package/dist/services/http.d.ts.map +1 -0
  276. package/dist/services/http.js +9 -0
  277. package/dist/services/http.js.map +1 -0
  278. package/dist/services/live.d.ts +16 -0
  279. package/dist/services/live.d.ts.map +1 -0
  280. package/dist/services/live.js +26 -0
  281. package/dist/services/live.js.map +1 -0
  282. package/dist/services/machine-id.d.ts +18 -0
  283. package/dist/services/machine-id.d.ts.map +1 -0
  284. package/dist/services/machine-id.js +39 -0
  285. package/dist/services/machine-id.js.map +1 -0
  286. package/dist/services/reporter.d.ts +55 -0
  287. package/dist/services/reporter.d.ts.map +1 -0
  288. package/dist/services/reporter.js +49 -0
  289. package/dist/services/reporter.js.map +1 -0
  290. package/dist/state-store.d.ts +39 -0
  291. package/dist/state-store.d.ts.map +1 -0
  292. package/dist/state-store.js +89 -0
  293. package/dist/state-store.js.map +1 -0
  294. package/dist/telemetry.d.ts +13 -0
  295. package/dist/telemetry.d.ts.map +1 -0
  296. package/dist/telemetry.js +129 -0
  297. package/dist/telemetry.js.map +1 -0
  298. package/dist/tenant-state.d.ts +69 -0
  299. package/dist/tenant-state.d.ts.map +1 -0
  300. package/dist/tenant-state.js +161 -0
  301. package/dist/tenant-state.js.map +1 -0
  302. package/package.json +38 -0
@@ -0,0 +1,89 @@
1
+ import { Schema, schemas } from '@hs-x/types';
2
+ export function createStateStore(deps) {
3
+ const ownerId = deps.pointer.ownerId;
4
+ const kv = deps.kv;
5
+ const readUnknownJson = async (key) => {
6
+ const raw = await kv.get(key);
7
+ if (raw === undefined)
8
+ return undefined;
9
+ return JSON.parse(raw);
10
+ };
11
+ const writeJson = async (key, value) => {
12
+ await kv.put(key, JSON.stringify(value));
13
+ };
14
+ return {
15
+ async getOwnerMeta() {
16
+ const value = await readUnknownJson(ownerMetaKey(ownerId));
17
+ return value === undefined
18
+ ? undefined
19
+ : Schema.decodeUnknownSync(schemas.LocalOwnerMeta)(value);
20
+ },
21
+ putOwnerMeta(meta) {
22
+ return writeJson(ownerMetaKey(ownerId), meta);
23
+ },
24
+ recordDeploy(entry) {
25
+ return writeJson(deployKey(ownerId, entry.projectId, entry.deployId), entry);
26
+ },
27
+ async getDeploy(input) {
28
+ const value = await readUnknownJson(deployKey(ownerId, input.projectId, input.deployId));
29
+ return value === undefined
30
+ ? undefined
31
+ : Schema.decodeUnknownSync(schemas.LocalDeployEntry)(value);
32
+ },
33
+ async listDeploys(input) {
34
+ const prefix = `owners/${ownerId}/projects/${input.projectId}/deploys/`;
35
+ const keys = await kv.list(prefix);
36
+ const entries = await Promise.all(keys.map(async (key) => {
37
+ const value = await readUnknownJson(key);
38
+ return value === undefined
39
+ ? undefined
40
+ : Schema.decodeUnknownSync(schemas.LocalDeployEntry)(value);
41
+ }));
42
+ return entries
43
+ .filter((entry) => entry !== undefined)
44
+ .sort((a, b) => (a.createdAt < b.createdAt ? 1 : -1));
45
+ },
46
+ async getActive(input) {
47
+ const value = await readUnknownJson(activeDeployKey(ownerId, input.projectId, input.environment));
48
+ return value === undefined
49
+ ? undefined
50
+ : Schema.decodeUnknownSync(schemas.LocalActiveDeploy)(value);
51
+ },
52
+ setActive(active) {
53
+ return writeJson(activeDeployKey(ownerId, active.projectId, active.environment), active);
54
+ },
55
+ async getBinding(input) {
56
+ const value = await readUnknownJson(bindingKey(ownerId, input.projectId, input.environment, input.hubSpotAppId));
57
+ return value === undefined
58
+ ? undefined
59
+ : Schema.decodeUnknownSync(schemas.LocalAppRuntimeBinding)(value);
60
+ },
61
+ putBinding(binding) {
62
+ return writeJson(bindingKey(ownerId, binding.projectId, binding.environment, String(binding.hubSpotAppId)), binding);
63
+ },
64
+ async listOwners() {
65
+ const keys = await kv.list('owners/');
66
+ return [...new Set(keys.map((key) => key.split('/')[1]).filter(isPresent))].sort();
67
+ },
68
+ async listProjects() {
69
+ const keys = await kv.list(`owners/${ownerId}/projects/`);
70
+ return [...new Set(keys.map((key) => key.split('/')[3]).filter(isPresent))].sort();
71
+ },
72
+ };
73
+ }
74
+ function isPresent(value) {
75
+ return value !== undefined && value.length > 0;
76
+ }
77
+ function ownerMetaKey(ownerId) {
78
+ return `owners/${ownerId}/meta`;
79
+ }
80
+ function activeDeployKey(ownerId, projectId, environment) {
81
+ return `owners/${ownerId}/projects/${projectId}/active/${environment}`;
82
+ }
83
+ function deployKey(ownerId, projectId, deployId) {
84
+ return `owners/${ownerId}/projects/${projectId}/deploys/${deployId}`;
85
+ }
86
+ function bindingKey(ownerId, projectId, environment, hubSpotAppId) {
87
+ return `owners/${ownerId}/projects/${projectId}/bindings/${environment}/${hubSpotAppId}`;
88
+ }
89
+ //# sourceMappingURL=state-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store.js","sourceRoot":"","sources":["../src/state-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export declare function emitCliTelemetry(input: {
2
+ readonly argv: readonly string[];
3
+ readonly commandArgv: readonly string[];
4
+ readonly command: string;
5
+ readonly exitCode: number;
6
+ readonly durationMs: number;
7
+ }): Promise<void>;
8
+ export declare function maybePrintTelemetryNotice(input: {
9
+ readonly argv: readonly string[];
10
+ readonly command: string;
11
+ readonly json: boolean;
12
+ }): Promise<void>;
13
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AASA,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,GAAG,OAAO,CAAC,IAAI,CAAC,CAkChB;AAED,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhB"}
@@ -0,0 +1,129 @@
1
+ import { mkdir, stat, writeFile } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { resolveControlPlaneUrl } from './config.js';
4
+ import { CLI_VERSION } from './constants.js';
5
+ import { getMachineId } from './machine-id.js';
6
+ import { cachePath } from './paths.js';
7
+ export async function emitCliTelemetry(input) {
8
+ if (!shouldSendTelemetry(input.argv))
9
+ return;
10
+ const endpoint = resolveTelemetryUrl(input.argv);
11
+ if (!endpoint)
12
+ return;
13
+ const subcommand = telemetrySubcommand(input.commandArgv);
14
+ const machineId = await getMachineId().catch(() => undefined);
15
+ const controller = new AbortController();
16
+ const timeout = setTimeout(() => controller.abort(), 350);
17
+ try {
18
+ await fetch(endpoint, {
19
+ method: 'POST',
20
+ signal: controller.signal,
21
+ headers: { 'content-type': 'application/json', accept: 'application/json' },
22
+ body: JSON.stringify({
23
+ schema_version: 1,
24
+ event: 'cli.command',
25
+ cli_version: CLI_VERSION,
26
+ command: input.command,
27
+ ...(subcommand ? { subcommand } : {}),
28
+ ...(machineId ? { machine_id: machineId } : {}),
29
+ exit_code: input.exitCode,
30
+ duration_ms: input.durationMs,
31
+ mode: telemetryMode(input.argv),
32
+ os: process.platform,
33
+ arch: process.arch,
34
+ runtime: process.versions.bun ? 'bun' : 'node',
35
+ ci: process.env.CI === 'true' || process.env.CI === '1',
36
+ }),
37
+ });
38
+ }
39
+ catch {
40
+ // Telemetry is best-effort and must never affect CLI behavior.
41
+ }
42
+ finally {
43
+ clearTimeout(timeout);
44
+ }
45
+ }
46
+ export async function maybePrintTelemetryNotice(input) {
47
+ if (input.json || input.argv.includes('--json-stream'))
48
+ return;
49
+ if (!shouldSendTelemetry(input.argv))
50
+ return;
51
+ if (input.command === 'help' ||
52
+ input.command === '--help' ||
53
+ input.command === '-h' ||
54
+ input.command === '--version' ||
55
+ input.command === '-v') {
56
+ return;
57
+ }
58
+ try {
59
+ const stamp = telemetryNoticeStampPath();
60
+ if (await pathExists(stamp))
61
+ return;
62
+ const machineId = await getMachineId().catch(() => undefined);
63
+ process.stderr.write(`\nhs-x sends anonymous usage telemetry (command name, exit code, duration, os/arch, machine_id).\n${machineId
64
+ ? `Machine id ${machineId} lets \`hs-x link\` later claim this machine's deploy history.\n`
65
+ : ''}Opt out with --no-telemetry, HSX_TELEMETRY_OPTOUT=1, or DO_NOT_TRACK=1.\n\n`);
66
+ await mkdir(dirname(stamp), { recursive: true });
67
+ await writeFile(stamp, `${new Date().toISOString()}\n`, 'utf8');
68
+ }
69
+ catch {
70
+ // Notice is best-effort; never affect CLI behavior.
71
+ }
72
+ }
73
+ function telemetryNoticeStampPath() {
74
+ const override = process.env.HSX_TELEMETRY_NOTICE_PATH;
75
+ if (override && override.length > 0)
76
+ return override;
77
+ return cachePath('telemetry-notice.stamp');
78
+ }
79
+ async function pathExists(path) {
80
+ try {
81
+ await stat(path);
82
+ return true;
83
+ }
84
+ catch {
85
+ return false;
86
+ }
87
+ }
88
+ function shouldSendTelemetry(argv) {
89
+ if (argv.includes('--no-telemetry'))
90
+ return false;
91
+ if (truthyEnv(process.env.HSX_TELEMETRY_DISABLED))
92
+ return false;
93
+ if (truthyEnv(process.env.HSX_TELEMETRY_OPTOUT))
94
+ return false;
95
+ if (truthyEnv(process.env.DO_NOT_TRACK))
96
+ return false;
97
+ if (truthyEnv(process.env.HSX_TELEMETRY_FORCE))
98
+ return true;
99
+ return !isSourceTreeCliRun();
100
+ }
101
+ function isSourceTreeCliRun() {
102
+ return process.argv.some((arg) => arg.includes('/packages/cli/src/bin/'));
103
+ }
104
+ function resolveTelemetryUrl(argv) {
105
+ const explicit = process.env.HSX_TELEMETRY_URL;
106
+ if (explicit && explicit.length > 0)
107
+ return explicit;
108
+ return new URL('/v1/telemetry/cli', resolveControlPlaneUrl(argv)).toString();
109
+ }
110
+ function telemetryMode(argv) {
111
+ if (argv.includes('--json'))
112
+ return 'json';
113
+ if (argv.includes('--json-stream'))
114
+ return 'ndjson';
115
+ const stderrIsTty = Boolean(process.stderr.isTTY);
116
+ if (!stderrIsTty || process.env.NO_COLOR === '1' || process.env.CI === 'true')
117
+ return 'plain';
118
+ return 'human';
119
+ }
120
+ function telemetrySubcommand(argv) {
121
+ const subcommand = argv[1];
122
+ if (!subcommand || subcommand.startsWith('-') || subcommand === 'help')
123
+ return undefined;
124
+ return subcommand;
125
+ }
126
+ function truthyEnv(value) {
127
+ return value === '1' || value === 'true' || value === 'yes';
128
+ }
129
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { Schema, schemas } from '@hs-x/types';
2
+ import { type StateStore } from './state-store.js';
3
+ export interface TenantStateContext {
4
+ readonly pointer: Schema.Schema.Type<typeof schemas.CloudflarePointer>;
5
+ readonly stateStore: StateStore;
6
+ }
7
+ /**
8
+ * Ensure the tenant `hsx-state` KV namespace exists and return a state-store
9
+ * bound to this project's pointer. Provisions the namespace and writes
10
+ * `.hs-x/cloudflare.json` on first use. Cached per (root, cloudflareAccountId,
11
+ * apiToken, baseUrl) within a process.
12
+ *
13
+ * Requires CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (or the equivalent
14
+ * `--cloudflare-api-token` / `--cloudflare-account-id` flags) — same
15
+ * preconditions as a regular Cloudflare deploy.
16
+ */
17
+ export declare function ensureTenantStateStore(input: {
18
+ readonly argv: readonly string[];
19
+ readonly root: string;
20
+ }): Promise<TenantStateContext>;
21
+ /**
22
+ * Preflight the credentials `ensureTenantStateStore` needs, WITHOUT provisioning
23
+ * anything. Call this before a Cloudflare deploy so a missing API token / account
24
+ * id fails fast — before any Worker is deployed — rather than after, when the
25
+ * Worker would already be live but the tenant-state write fails on the account
26
+ * id. Respects the same `.hs-x/cloudflare.json` account-id fallback as
27
+ * `ensureTenantStateStore`, so repeat deploys without re-exporting the account
28
+ * id are not falsely rejected.
29
+ */
30
+ export declare function preflightTenantStateCredentials(input: {
31
+ readonly argv: readonly string[];
32
+ readonly root: string;
33
+ }): Promise<void>;
34
+ /**
35
+ * Read-only variant: returns undefined if `.hs-x/cloudflare.json` is missing,
36
+ * rather than provisioning a namespace. Use for commands like `rollback` that
37
+ * should fail clearly when there's no project state to operate on.
38
+ */
39
+ export declare function loadTenantStateStore(input: {
40
+ readonly argv: readonly string[];
41
+ readonly root: string;
42
+ }): Promise<TenantStateContext | undefined>;
43
+ /**
44
+ * Idempotent rewrite of an owner prefix in tenant KV.
45
+ *
46
+ * Reads every key under `owners/{from}/`, writes the value under
47
+ * `owners/{to}/...`, then deletes the source. Schema values that carry a
48
+ * top-level `ownerId` are rewritten to the destination owner. Each step is
49
+ * safe to re-run:
50
+ *
51
+ * - On retry after a crash between write and delete, both prefixes hold the
52
+ * same data; we re-write (idempotent) and re-delete.
53
+ * - If `to` already has a value at a given key (e.g. a partial prior run),
54
+ * the new write wins and the `from` source is still removed.
55
+ * - If `from` has no keys (e.g. the rewrite was already completed), this
56
+ * returns an empty result without error — calling it twice is a no-op.
57
+ *
58
+ * Returns the list of rewritten (oldKey → newKey) pairs so the caller can
59
+ * report or notify control-plane.
60
+ */
61
+ export declare function rewriteTenantOwnerPrefix(input: {
62
+ readonly kv: import('./cloudflare-kv.js').CloudflareKvClient;
63
+ readonly from: string;
64
+ readonly to: string;
65
+ }): Promise<readonly {
66
+ readonly fromKey: string;
67
+ readonly toKey: string;
68
+ }[]>;
69
+ //# sourceMappingURL=tenant-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-state.d.ts","sourceRoot":"","sources":["../src/tenant-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,kBAAkB,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACvE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAID;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,KAAK,EAAE;IAClD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgD9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,+BAA+B,CAAC,KAAK,EAAE;IAC3D,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE;IAChD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAsB1C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,wBAAwB,CAAC,KAAK,EAAE;IACpD,QAAQ,CAAC,EAAE,EAAE,OAAO,oBAAoB,EAAE,kBAAkB,CAAC;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,SAAS;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAoB3E"}
@@ -0,0 +1,161 @@
1
+ import { createCloudflareKvClient, resolveCloudflareCredentials } from './cloudflare-kv.js';
2
+ import { ensureCloudflarePointer, loadCloudflarePointer } from './cloudflare-pointer.js';
3
+ import { createStateStore } from './state-store.js';
4
+ const tenantStateStoreCache = new Map();
5
+ /**
6
+ * Ensure the tenant `hsx-state` KV namespace exists and return a state-store
7
+ * bound to this project's pointer. Provisions the namespace and writes
8
+ * `.hs-x/cloudflare.json` on first use. Cached per (root, cloudflareAccountId,
9
+ * apiToken, baseUrl) within a process.
10
+ *
11
+ * Requires CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID (or the equivalent
12
+ * `--cloudflare-api-token` / `--cloudflare-account-id` flags) — same
13
+ * preconditions as a regular Cloudflare deploy.
14
+ */
15
+ export async function ensureTenantStateStore(input) {
16
+ const creds = resolveCloudflareCredentials(input.argv);
17
+ const { apiToken } = creds;
18
+ // Fall back to the account id recorded in .hs-x/cloudflare.json so repeat
19
+ // deploys don't need CLOUDFLARE_ACCOUNT_ID re-exported every time.
20
+ const cloudflareAccountId = creds.accountId ?? (await loadCloudflarePointer(input.root))?.cloudflareAccountId;
21
+ if (!apiToken || !cloudflareAccountId) {
22
+ throw new Error('Tenant state requires a Cloudflare API token and account id. Set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID, or pass --cloudflare-api-token / --cloudflare-account-id.');
23
+ }
24
+ const baseUrl = process.env.HSX_CLOUDFLARE_API_BASE_URL;
25
+ const cacheKey = JSON.stringify({
26
+ root: input.root,
27
+ cloudflareAccountId,
28
+ apiToken,
29
+ baseUrl,
30
+ });
31
+ const cached = tenantStateStoreCache.get(cacheKey);
32
+ if (cached)
33
+ return cached;
34
+ const bootstrapKv = createCloudflareKvClient({
35
+ accountId: cloudflareAccountId,
36
+ apiToken,
37
+ ...(baseUrl ? { baseUrl } : {}),
38
+ });
39
+ const namespace = await bootstrapKv.ensureNamespace('hsx-state');
40
+ const pointer = await ensureCloudflarePointer({
41
+ root: input.root,
42
+ cloudflareAccountId,
43
+ stateKvNamespaceId: namespace.id,
44
+ stateKvNamespaceName: namespace.title,
45
+ });
46
+ const context = {
47
+ pointer,
48
+ stateStore: createStateStore({
49
+ pointer,
50
+ kv: createCloudflareKvClient({
51
+ accountId: pointer.cloudflareAccountId,
52
+ apiToken,
53
+ namespaceId: pointer.stateKvNamespaceId,
54
+ ...(baseUrl ? { baseUrl } : {}),
55
+ }),
56
+ }),
57
+ };
58
+ tenantStateStoreCache.set(cacheKey, context);
59
+ return context;
60
+ }
61
+ /**
62
+ * Preflight the credentials `ensureTenantStateStore` needs, WITHOUT provisioning
63
+ * anything. Call this before a Cloudflare deploy so a missing API token / account
64
+ * id fails fast — before any Worker is deployed — rather than after, when the
65
+ * Worker would already be live but the tenant-state write fails on the account
66
+ * id. Respects the same `.hs-x/cloudflare.json` account-id fallback as
67
+ * `ensureTenantStateStore`, so repeat deploys without re-exporting the account
68
+ * id are not falsely rejected.
69
+ */
70
+ export async function preflightTenantStateCredentials(input) {
71
+ const { apiToken, accountId } = resolveCloudflareCredentials(input.argv);
72
+ const cloudflareAccountId = accountId ?? (await loadCloudflarePointer(input.root))?.cloudflareAccountId;
73
+ if (!apiToken || !cloudflareAccountId) {
74
+ throw new Error('A Cloudflare deploy needs an API token and account id. Set CLOUDFLARE_API_TOKEN and ' +
75
+ 'CLOUDFLARE_ACCOUNT_ID, or pass --cloudflare-api-token / --cloudflare-account-id, before deploying.');
76
+ }
77
+ }
78
+ /**
79
+ * Read-only variant: returns undefined if `.hs-x/cloudflare.json` is missing,
80
+ * rather than provisioning a namespace. Use for commands like `rollback` that
81
+ * should fail clearly when there's no project state to operate on.
82
+ */
83
+ export async function loadTenantStateStore(input) {
84
+ const pointer = await loadCloudflarePointer(input.root);
85
+ if (!pointer)
86
+ return undefined;
87
+ const { apiToken } = resolveCloudflareCredentials(input.argv);
88
+ if (!apiToken) {
89
+ throw new Error('Reading tenant state requires CLOUDFLARE_API_TOKEN (or --cloudflare-api-token).');
90
+ }
91
+ const baseUrl = process.env.HSX_CLOUDFLARE_API_BASE_URL;
92
+ return {
93
+ pointer,
94
+ stateStore: createStateStore({
95
+ pointer,
96
+ kv: createCloudflareKvClient({
97
+ accountId: pointer.cloudflareAccountId,
98
+ apiToken,
99
+ namespaceId: pointer.stateKvNamespaceId,
100
+ ...(baseUrl ? { baseUrl } : {}),
101
+ }),
102
+ }),
103
+ };
104
+ }
105
+ /**
106
+ * Idempotent rewrite of an owner prefix in tenant KV.
107
+ *
108
+ * Reads every key under `owners/{from}/`, writes the value under
109
+ * `owners/{to}/...`, then deletes the source. Schema values that carry a
110
+ * top-level `ownerId` are rewritten to the destination owner. Each step is
111
+ * safe to re-run:
112
+ *
113
+ * - On retry after a crash between write and delete, both prefixes hold the
114
+ * same data; we re-write (idempotent) and re-delete.
115
+ * - If `to` already has a value at a given key (e.g. a partial prior run),
116
+ * the new write wins and the `from` source is still removed.
117
+ * - If `from` has no keys (e.g. the rewrite was already completed), this
118
+ * returns an empty result without error — calling it twice is a no-op.
119
+ *
120
+ * Returns the list of rewritten (oldKey → newKey) pairs so the caller can
121
+ * report or notify control-plane.
122
+ */
123
+ export async function rewriteTenantOwnerPrefix(input) {
124
+ const fromPrefix = `owners/${input.from}/`;
125
+ const toPrefix = `owners/${input.to}/`;
126
+ const fromKeys = await input.kv.list(fromPrefix);
127
+ if (fromKeys.length === 0)
128
+ return [];
129
+ const rewritten = [];
130
+ for (const fromKey of fromKeys) {
131
+ const value = await input.kv.get(fromKey);
132
+ if (value === undefined)
133
+ continue;
134
+ const toKey = `${toPrefix}${fromKey.slice(fromPrefix.length)}`;
135
+ await input.kv.put(toKey, rewriteOwnerIdValue(value, input.from, input.to));
136
+ rewritten.push({ fromKey, toKey });
137
+ }
138
+ // Delete sources only after every write succeeded, so a mid-loop crash
139
+ // leaves both prefixes populated rather than losing data.
140
+ for (const { fromKey } of rewritten) {
141
+ await input.kv.delete(fromKey);
142
+ }
143
+ return rewritten;
144
+ }
145
+ function rewriteOwnerIdValue(value, from, to) {
146
+ try {
147
+ const parsed = JSON.parse(value);
148
+ if (typeof parsed === 'object' &&
149
+ parsed !== null &&
150
+ !Array.isArray(parsed) &&
151
+ parsed.ownerId === from) {
152
+ return JSON.stringify({ ...parsed, ownerId: to });
153
+ }
154
+ }
155
+ catch {
156
+ // Non-JSON values should not exist for tenant state, but keep the rewrite
157
+ // byte-preserving rather than failing an otherwise recoverable link.
158
+ }
159
+ return value;
160
+ }
161
+ //# sourceMappingURL=tenant-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-state.js","sourceRoot":"","sources":["../src/tenant-state.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@hs-x/cli",
3
+ "version": "0.1.0",
4
+ "description": "HS-X CLI — init, validate, connect, dev, deploy, promote, rollback, doctor, sync. Installs the `hs-x` command.",
5
+ "type": "module",
6
+ "bin": {
7
+ "hs-x": "./dist/bin/hs-x.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc -b",
17
+ "clean": "tsc -b --clean"
18
+ },
19
+ "dependencies": {
20
+ "@effect/cli": "0.75.1",
21
+ "@effect/platform": "0.96.1",
22
+ "@effect/platform-bun": "0.89.0",
23
+ "@hs-x/codegen": "0.1.0",
24
+ "@hs-x/hubspot": "0.1.0",
25
+ "@hs-x/hubspot-cli": "0.1.0",
26
+ "@hs-x/types": "0.1.0",
27
+ "@hs-x/validator": "0.1.0",
28
+ "effect": "^3.10.19"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "devDependencies": {
34
+ "@hs-x/fixtures": "0.1.0",
35
+ "@types/node": "^25.8.0",
36
+ "@hs-x/control-plane": "0.1.0"
37
+ }
38
+ }