@uagents/syncenv-cli 0.1.1

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,333 @@
1
+ // src/config/index.ts
2
+ import fs from "fs/promises";
3
+ import path from "path";
4
+ import { SyncEnvClient, ApiError } from "@uagents/syncenv-client";
5
+ import chalk from "chalk";
6
+ import Conf from "conf";
7
+ import yaml from "js-yaml";
8
+ import { z } from "zod";
9
+ var ProjectConfigSchema = z.object({
10
+ project: z.object({
11
+ name: z.string(),
12
+ id: z.string()
13
+ }),
14
+ defaults: z.object({
15
+ environment: z.string().default("dev"),
16
+ pushOnChange: z.boolean().default(false),
17
+ confirmOverwrite: z.boolean().default(true)
18
+ }),
19
+ encryption: z.object({
20
+ algorithm: z.string().default("AES-256-GCM"),
21
+ keyDerivation: z.string().default("Argon2id")
22
+ }),
23
+ environments: z.record(
24
+ z.object({
25
+ file: z.string(),
26
+ requireConfirmation: z.boolean().optional()
27
+ })
28
+ )
29
+ });
30
+ var defaultConfig = {
31
+ apiUrl: process.env.SYNCENV_API_URL || "https://syncenv.uagents.app"
32
+ };
33
+ var conf;
34
+ try {
35
+ conf = new Conf({
36
+ projectName: "syncenv",
37
+ defaults: defaultConfig
38
+ });
39
+ } catch {
40
+ conf = {
41
+ get: (key) => defaultConfig[key],
42
+ set: () => {
43
+ },
44
+ delete: () => {
45
+ },
46
+ clear: () => {
47
+ },
48
+ path: ""
49
+ };
50
+ }
51
+ function getConfig(key) {
52
+ return conf.get(key);
53
+ }
54
+ function setConfig(key, value) {
55
+ conf.set(key, value);
56
+ }
57
+ function deleteConfig(key) {
58
+ conf.delete(key);
59
+ }
60
+ function getConfigPath() {
61
+ return conf.path;
62
+ }
63
+ function isAuthenticated() {
64
+ const cookieHeader = getCookieHeader();
65
+ return !!cookieHeader && cookieHeader.includes("better-auth");
66
+ }
67
+ async function loadProjectConfig(cwd = process.cwd()) {
68
+ const configPath = path.join(cwd, ".envsyncrc");
69
+ try {
70
+ const content = await fs.readFile(configPath, "utf-8");
71
+ const parsed = yaml.load(content);
72
+ return ProjectConfigSchema.parse(parsed);
73
+ } catch (error) {
74
+ if (error.code === "ENOENT") {
75
+ return null;
76
+ }
77
+ throw new Error(`Failed to parse .envsyncrc: ${error.message}`);
78
+ }
79
+ }
80
+ async function saveProjectConfig(config, cwd = process.cwd()) {
81
+ const configPath = path.join(cwd, ".envsyncrc");
82
+ const content = yaml.dump(config, { indent: 2 });
83
+ await fs.writeFile(configPath, content, "utf-8");
84
+ }
85
+ async function hasProjectConfig(cwd = process.cwd()) {
86
+ try {
87
+ await fs.access(path.join(cwd, ".envsyncrc"));
88
+ return true;
89
+ } catch {
90
+ return false;
91
+ }
92
+ }
93
+ async function loadConfig() {
94
+ return {
95
+ apiUrl: conf.get("apiUrl") || defaultConfig.apiUrl,
96
+ authToken: conf.get("authToken"),
97
+ userId: conf.get("userId"),
98
+ userEmail: conf.get("userEmail")
99
+ };
100
+ }
101
+ async function fetchWithCookies(input, init) {
102
+ if (input instanceof Request) {
103
+ const url2 = input.url;
104
+ const cookieHeader2 = getCookieHeader();
105
+ const headers2 = {};
106
+ input.headers.forEach((value, key) => {
107
+ headers2[key] = value;
108
+ });
109
+ if (cookieHeader2) {
110
+ headers2["Cookie"] = cookieHeader2;
111
+ }
112
+ const response2 = await fetch(url2, {
113
+ method: input.method,
114
+ headers: headers2,
115
+ body: input.body
116
+ });
117
+ const setCookie2 = response2.headers.getSetCookie?.() || (response2.headers.get("set-cookie") ? [response2.headers.get("set-cookie")] : []);
118
+ if (setCookie2.length > 0) {
119
+ storeCookies(setCookie2);
120
+ }
121
+ return response2;
122
+ }
123
+ const url = input.toString();
124
+ const cookieHeader = getCookieHeader();
125
+ const headers = {
126
+ ...init?.headers
127
+ };
128
+ if (cookieHeader) {
129
+ headers["Cookie"] = cookieHeader;
130
+ }
131
+ const response = await fetch(url, {
132
+ ...init,
133
+ headers
134
+ });
135
+ const setCookie = response.headers.getSetCookie?.() || (response.headers.get("set-cookie") ? [response.headers.get("set-cookie")] : []);
136
+ if (setCookie.length > 0) {
137
+ storeCookies(setCookie);
138
+ }
139
+ return response;
140
+ }
141
+ function createClient() {
142
+ const apiUrl = conf.get("apiUrl") || defaultConfig.apiUrl;
143
+ return new SyncEnvClient({
144
+ baseUrl: apiUrl,
145
+ token: "",
146
+ // Cookie-based auth, no token needed
147
+ fetch: fetchWithCookies
148
+ });
149
+ }
150
+ var client = createClient();
151
+ async function clearAuthState() {
152
+ const { clearCachedKEK, deleteKEKPassword, deleteEncryptedKEK } = await import("./secure-storage-UEK3LD5L.js");
153
+ clearCachedKEK();
154
+ await deleteKEKPassword();
155
+ deleteEncryptedKEK();
156
+ clearCookies();
157
+ deleteConfig("userId");
158
+ deleteConfig("userEmail");
159
+ deleteConfig("authToken");
160
+ deleteConfig("refreshToken");
161
+ deleteConfig("deviceId");
162
+ deleteConfig("deviceName");
163
+ deleteConfig("devicePublicKey");
164
+ deleteConfig("encryptedDevicePrivateKey");
165
+ client.setToken("");
166
+ }
167
+ function handleAuthError(_error) {
168
+ clearAuthState().catch(() => {
169
+ });
170
+ console.error(chalk.red("\n\u2717 Session expired or invalid"));
171
+ console.error(chalk.yellow("Your authentication session has expired or was revoked."));
172
+ console.error(chalk.yellow("This can happen when:"));
173
+ console.error(chalk.yellow(" \u2022 You changed your password"));
174
+ console.error(chalk.yellow(" \u2022 You logged out from another device"));
175
+ console.error(chalk.yellow(" \u2022 Your session expired"));
176
+ console.error(chalk.yellow(" \u2022 Your account was disabled"));
177
+ console.error();
178
+ console.error(chalk.cyan("Please login again:"));
179
+ console.error(chalk.bold(" syncenv auth login"));
180
+ console.error();
181
+ process.exit(1);
182
+ }
183
+ async function getOrUnlockUserKEK() {
184
+ const { getCachedKEK, cacheKEKInMemory, getKEKPassword, saveEncryptedKEK } = await import("./secure-storage-UEK3LD5L.js");
185
+ const cached = getCachedKEK();
186
+ if (cached) return cached;
187
+ const password = await getKEKPassword();
188
+ if (!password) return null;
189
+ try {
190
+ const userKeys = await withAuthGuard(() => client.userKeys.get());
191
+ const { unlockUserKEK } = await import("./crypto-X7MZU7DV.js");
192
+ const kek = await unlockUserKEK(
193
+ password,
194
+ userKeys.encryptedUserKek,
195
+ userKeys.kekIv,
196
+ userKeys.kekSalt
197
+ );
198
+ if (!kek) {
199
+ const { deleteKEKPassword } = await import("./secure-storage-UEK3LD5L.js");
200
+ await deleteKEKPassword();
201
+ return null;
202
+ }
203
+ saveEncryptedKEK({
204
+ encryptedUserKek: userKeys.encryptedUserKek,
205
+ kekIv: userKeys.kekIv,
206
+ kekSalt: userKeys.kekSalt,
207
+ version: userKeys.version
208
+ });
209
+ cacheKEKInMemory(kek);
210
+ return kek;
211
+ } catch (err) {
212
+ if (err instanceof ApiError && err.statusCode === 404) {
213
+ return null;
214
+ }
215
+ throw err;
216
+ }
217
+ }
218
+ async function withAuthGuard(apiCall) {
219
+ try {
220
+ return await apiCall();
221
+ } catch (error) {
222
+ if (error instanceof ApiError && error.statusCode === 401) {
223
+ handleAuthError(error);
224
+ }
225
+ throw error;
226
+ }
227
+ }
228
+
229
+ // src/cookie-store.ts
230
+ function parseSetCookie(setCookieValue) {
231
+ const parts = setCookieValue.split(";").map((p) => p.trim());
232
+ if (parts.length === 0) return null;
233
+ const [nameValue, ...attrParts] = parts;
234
+ const eqIndex = nameValue.indexOf("=");
235
+ if (eqIndex === -1) return null;
236
+ const name = nameValue.slice(0, eqIndex);
237
+ const value = nameValue.slice(eqIndex + 1);
238
+ const attributes = {};
239
+ for (const attr of attrParts) {
240
+ const [attrName, attrValue] = attr.split("=");
241
+ attributes[attrName.toLowerCase()] = attrValue ?? true;
242
+ }
243
+ return { name, value, attributes };
244
+ }
245
+ function loadCookies() {
246
+ const stored = getConfig("cookies");
247
+ if (!stored) return [];
248
+ try {
249
+ const parsed = JSON.parse(stored);
250
+ return parsed.map((c) => ({
251
+ ...c,
252
+ expires: c.expires ? new Date(c.expires) : void 0
253
+ }));
254
+ } catch {
255
+ return [];
256
+ }
257
+ }
258
+ function saveCookies(cookies) {
259
+ if (cookies.length === 0) {
260
+ deleteConfig("cookies");
261
+ return;
262
+ }
263
+ setConfig("cookies", JSON.stringify(cookies));
264
+ }
265
+ function storeCookies(setCookieHeaders) {
266
+ if (!setCookieHeaders) return;
267
+ const headers = Array.isArray(setCookieHeaders) ? setCookieHeaders : [setCookieHeaders];
268
+ const cookies = loadCookies();
269
+ for (const header of headers) {
270
+ const parsed = parseSetCookie(header);
271
+ if (!parsed) continue;
272
+ const existingIndex = cookies.findIndex((c) => c.name === parsed.name);
273
+ if (existingIndex !== -1) {
274
+ cookies.splice(existingIndex, 1);
275
+ }
276
+ const maxAge = parsed.attributes["max-age"];
277
+ if (parsed.value === "" || typeof maxAge === "string" && parseInt(maxAge, 10) <= 0) {
278
+ continue;
279
+ }
280
+ const cookie = {
281
+ name: parsed.name,
282
+ value: parsed.value,
283
+ path: typeof parsed.attributes.path === "string" ? parsed.attributes.path : "/",
284
+ httpOnly: parsed.attributes.httponly === true,
285
+ secure: parsed.attributes.secure === true,
286
+ sameSite: typeof parsed.attributes.samesite === "string" ? parsed.attributes.samesite : void 0
287
+ };
288
+ if (parsed.attributes.expires) {
289
+ cookie.expires = new Date(parsed.attributes.expires);
290
+ }
291
+ cookies.push(cookie);
292
+ }
293
+ saveCookies(cookies);
294
+ }
295
+ function getCookieHeader() {
296
+ const cookies = loadCookies();
297
+ const now = /* @__PURE__ */ new Date();
298
+ const validCookies = cookies.filter((c) => !c.expires || c.expires > now);
299
+ if (validCookies.length !== cookies.length) {
300
+ saveCookies(validCookies);
301
+ }
302
+ if (validCookies.length === 0) return void 0;
303
+ return validCookies.map((c) => `${c.name}=${c.value}`).join("; ");
304
+ }
305
+ function clearCookies() {
306
+ deleteConfig("cookies");
307
+ }
308
+ function hasValidSession() {
309
+ const header = getCookieHeader();
310
+ return !!header && header.includes("better-auth");
311
+ }
312
+
313
+ export {
314
+ loadCookies,
315
+ saveCookies,
316
+ storeCookies,
317
+ getCookieHeader,
318
+ clearCookies,
319
+ hasValidSession,
320
+ getConfig,
321
+ setConfig,
322
+ deleteConfig,
323
+ getConfigPath,
324
+ isAuthenticated,
325
+ loadProjectConfig,
326
+ saveProjectConfig,
327
+ hasProjectConfig,
328
+ loadConfig,
329
+ client,
330
+ clearAuthState,
331
+ getOrUnlockUserKEK,
332
+ withAuthGuard
333
+ };
@@ -0,0 +1,16 @@
1
+ import {
2
+ clearCookies,
3
+ getCookieHeader,
4
+ hasValidSession,
5
+ loadCookies,
6
+ saveCookies,
7
+ storeCookies
8
+ } from "./chunk-OVEYHV4C.js";
9
+ export {
10
+ clearCookies,
11
+ getCookieHeader,
12
+ hasValidSession,
13
+ loadCookies,
14
+ saveCookies,
15
+ storeCookies
16
+ };
@@ -0,0 +1,58 @@
1
+ import {
2
+ base64ToBuffer,
3
+ bufferToBase64,
4
+ decryptContent,
5
+ decryptDEK,
6
+ decryptDek,
7
+ decryptEnvFile,
8
+ decryptUserKEK,
9
+ deriveKEK,
10
+ deriveKeys,
11
+ encryptContent,
12
+ encryptDEK,
13
+ encryptDek,
14
+ encryptEnvFile,
15
+ encryptUserKEK,
16
+ exportDEK,
17
+ exportKEK,
18
+ generateContentHash,
19
+ generateDEK,
20
+ generateDek,
21
+ generateSalt,
22
+ generateUserKEK,
23
+ hashContent,
24
+ importDEK,
25
+ importKEK,
26
+ reencryptUserKEK,
27
+ setupUserKEK,
28
+ unlockUserKEK
29
+ } from "./chunk-NV6H5OGL.js";
30
+ export {
31
+ base64ToBuffer,
32
+ bufferToBase64,
33
+ decryptContent,
34
+ decryptDEK,
35
+ decryptDek,
36
+ decryptEnvFile,
37
+ decryptUserKEK,
38
+ deriveKEK,
39
+ deriveKeys,
40
+ encryptContent,
41
+ encryptDEK,
42
+ encryptDek,
43
+ encryptEnvFile,
44
+ encryptUserKEK,
45
+ exportDEK,
46
+ exportKEK,
47
+ generateContentHash,
48
+ generateDEK,
49
+ generateDek,
50
+ generateSalt,
51
+ generateUserKEK,
52
+ hashContent,
53
+ importDEK,
54
+ importKEK,
55
+ reencryptUserKEK,
56
+ setupUserKEK,
57
+ unlockUserKEK
58
+ };